ThreeB 1.1
|
00001 #ifndef SPOT_WITH_BACKGROUND_H 00002 #define SPOT_WITH_BACKGROUND_H 00003 00004 #include <vector> 00005 #include <cvd/image_ref.h> 00006 #include <tr1/tuple> 00007 #include <TooN/TooN.h> 00008 00009 #include "drift.h" 00010 00011 typedef char State; 00012 00013 namespace SampledMultispot 00014 { 00015 00016 using namespace std; 00017 using namespace CVD; 00018 using namespace TooN; 00019 using namespace std::tr1; 00020 00021 00022 00023 //The changes to SpotWithBackground to operate with/without drift and masking are 00024 //irritatingly pervasive. I can't think of any other way of doing it. 00025 #define SWBG_NAME SpotWithBackground 00026 #include "spot_with_background.hh" 00027 00028 00029 #define SWBG_NAME SpotWithBackgroundMasked 00030 #define SWBG_HAVE_MASK 00031 #include "spot_with_background.hh" 00032 00033 //#define SWBG_NAME SpotWithBackgroundDrift 00034 //#define SWBG_HAVE_DRIFT 00035 //#include "spot_with_background.hh" 00036 00037 //#undef SWBG_NAME 00038 //#define SWBG_NAME SpotWithBackgroundDriftMasked 00039 //#define SWBG_HAVE_DRIFT 00040 //#define SWBG_HAVE_MASK 00041 //#include "spot_with_background.hh" 00042 00043 00044 00045 00046 inline double intensity(double i) 00047 { 00048 return i; 00049 } 00050 00051 inline double intensity(const pair<double, Vector<4> >& i) 00052 { 00053 return i.first; 00054 } 00055 00056 00057 //Add and remove a spot over the entire region 00058 template<class T> 00059 void remove_spot(vector<vector<double> >& current_sample_intensities, const vector<T>& spot_intensities, const vector<State>& spot_sample) 00060 { 00061 for(unsigned int frame=0; frame < current_sample_intensities.size(); frame++) 00062 if(spot_sample[frame] == 0) //Spot is on, so remove it 00063 for(unsigned int p=0; p < spot_intensities.size(); p++) 00064 current_sample_intensities[frame][p] -= intensity(spot_intensities[p]); 00065 } 00066 00067 template<class T> 00068 void add_spot(vector<vector<double> >& current_sample_intensities, const vector<T>& spot_intensities, const vector<State>& spot_sample) 00069 { 00070 for(unsigned int frame=0; frame < current_sample_intensities.size(); frame++) 00071 if(spot_sample[frame] == 0) //Spot is on, so add it 00072 for(unsigned int p=0; p < spot_intensities.size(); p++) 00073 current_sample_intensities[frame][p] += intensity(spot_intensities[p]); 00074 } 00075 00076 00077 //Add and remove a spot only over a mask. 00078 template<class T> 00079 void remove_spot(vector<vector<double> >& current_sample_intensities, const vector<T>& spot_intensities, const vector<State>& spot_sample, const vector<int>& mask) 00080 { 00081 for(unsigned int frame=0; frame < current_sample_intensities.size(); frame++) 00082 if(spot_sample[frame] == 0) //Spot is on, so remove it 00083 for(unsigned int p=0; p < mask.size(); p++) 00084 current_sample_intensities[frame][mask[p]] -= intensity(spot_intensities[mask[p]]); 00085 } 00086 00087 template<class T> 00088 void add_spot(vector<vector<double> >& current_sample_intensities, const vector<T>& spot_intensities, const vector<State>& spot_sample, const vector<int>& mask) 00089 { 00090 for(unsigned int frame=0; frame < current_sample_intensities.size(); frame++) 00091 if(spot_sample[frame] == 0) //Spot is on, so add it 00092 for(unsigned int p=0; p < mask.size(); p++) 00093 current_sample_intensities[frame][mask[p]] += intensity(spot_intensities[mask[p]]); 00094 } 00095 00096 00097 //Add and remove a drifty spot only over a mask. 00098 template<class T> 00099 void remove_spot(vector<vector<double> >& current_sample_intensities, const vector<vector<T> > & spot_intensities, const vector<State>& spot_sample, const vector<int>& mask) 00100 { 00101 const int steps = spot_intensities.size(); 00102 const int frames = current_sample_intensities.size(); 00103 00104 for(int frame=0; frame < frames; frame++) 00105 { 00106 int s = frame * steps / frames; 00107 00108 if(spot_sample[frame] == 0) //Spot is on, so remove it 00109 for(unsigned int p=0; p < mask.size(); p++) 00110 current_sample_intensities[frame][mask[p]] -= intensity(spot_intensities[s][mask[p]]); 00111 } 00112 } 00113 00114 template<class T> 00115 void add_spot(vector<vector<double> >& current_sample_intensities, const vector<vector<T> >& spot_intensities, const vector<State>& spot_sample, const vector<int>& mask) 00116 { 00117 const int steps = spot_intensities.size(); 00118 const int frames = current_sample_intensities.size(); 00119 00120 for(int frame=0; frame < frames; frame++) 00121 { 00122 int s = frame * steps / frames; 00123 00124 if(spot_sample[frame] == 0) //Spot is on, so add it 00125 for(unsigned int p=0; p < mask.size(); p++) 00126 current_sample_intensities[frame][mask[p]] += intensity(spot_intensities[s][mask[p]]); 00127 } 00128 } 00129 00130 00131 00132 //Compute the spot intensity for a given spot at each pixel 00133 inline vector<double> compute_spot_intensity(const vector<ImageRef>& pixels, const Vector<4>& params) 00134 { 00135 vector<double> intensities(pixels.size()); 00136 00137 for(unsigned int i=0; i < pixels.size(); i++) 00138 intensities[i] = spot_shape(vec(pixels[i]), params); 00139 00140 return intensities; 00141 } 00142 00143 //Compute the spot intensity derivatives for a given spot at each pixel 00144 inline vector<pair<double, Vector<4> > > compute_spot_intensity_derivatives(const vector<ImageRef>& pixels, const Vector<4>& params) 00145 { 00146 vector<pair<double, Vector<4> > > derivatives(pixels.size()); 00147 00148 for(unsigned int i=0; i < pixels.size(); i++) 00149 derivatives[i] = spot_shape_diff_position(vec(pixels[i]), params); 00150 return derivatives; 00151 } 00152 00153 inline vector<tuple<double, Vector<4>, Matrix<4> > > compute_spot_intensity_hessian(const vector<ImageRef>& pixels, const Vector<4>& params) 00154 { 00155 vector<tuple<double, Vector<4>, Matrix<4> > > hessian(pixels.size()); 00156 00157 for(unsigned int i=0; i < pixels.size(); i++) 00158 hessian[i] = spot_shape_hess_position(vec(pixels[i]), params); 00159 return hessian; 00160 } 00161 00162 00163 /** 00164 Create a sequence of integers. These can be used as observations 00165 in an observation class by forward_algorithm() and etc. 00166 @param n Length of sequence 00167 @ingroup gUtility 00168 */ 00169 inline vector<int> sequence(int n) 00170 { 00171 vector<int> v; 00172 for(int i=0; i < n; i++) 00173 v.push_back(i); 00174 return v; 00175 } 00176 00177 /*struct RndGrand48 00178 { 00179 double operator()() 00180 { 00181 return drand48(); 00182 } 00183 };*/ 00184 00185 ///Draw samples from the spot states given the spots positions and some data. 00186 ///Variable naming matches that in FitSpots. 00187 ///@ingroup gStorm 00188 class GibbsSampler 00189 { 00190 const vector<vector<double> >& pixel_intensities; 00191 const vector<vector<double> >& spot_intensities; 00192 const vector<Vector<4> > spots; 00193 const Matrix<3> A; 00194 const Vector<3> pi; 00195 const double base_variance; 00196 double variance; 00197 00198 const int sample_iterations; 00199 const int num_frames, num_pixels; 00200 const vector<int> O; 00201 00202 vector<vector<State> > current_sample; 00203 vector<vector<double> > current_sample_intensities; 00204 00205 public: 00206 00207 GibbsSampler(const vector<vector<double> >& pixel_intensities_, 00208 const vector<vector<double> >& spot_intensities_, 00209 const vector<Vector<4> >& spots_, 00210 const Matrix<3> A_, 00211 const Vector<3> pi_, 00212 double variance_, 00213 int sample_iterations_) 00214 :pixel_intensities(pixel_intensities_), //pixel_intensities: [frame][pixels] 00215 spot_intensities(spot_intensities_), //spot_intensities: [spot][pixel] 00216 spots(spots_), 00217 A(A_), 00218 pi(pi_), 00219 base_variance(variance_), 00220 variance(variance_), 00221 sample_iterations(sample_iterations_), 00222 num_frames(pixel_intensities.size()), 00223 num_pixels(pixel_intensities[0].size()), 00224 //Observations vector. As usual for this application, the observations are just 00225 //numbered integers which refer to data held elsewhere. 00226 O(sequence(num_frames)), 00227 //Start all spots OFF, so the intensity is 0. OFF is 1 or 2, not 0!!! 00228 //sample_list: [sample][spot][frame]: list of samples drawn using Gibbs sampling 00229 current_sample(spots.size(), vector<State>(num_frames, 2)), //current sample [spot][frame] 00230 //pixel intensities assosciated with the current sample [frame][pixel] 00231 current_sample_intensities(num_frames, vector<double>(num_pixels)) 00232 { 00233 //Check a bunch of stuff 00234 assert_same_size(pixel_intensities); 00235 assert_same_size(spot_intensities); 00236 00237 } 00238 00239 ///Update the noide variance. Used for adding thermal noise. 00240 ///@param v noise variance. 00241 void set_variance(double v) 00242 { 00243 variance = v; 00244 } 00245 00246 00247 ///Reset the gibbs sampler oro the initial state (all spots off) 00248 void reset() 00249 { 00250 vector<State> off(num_frames, 2); 00251 fill(current_sample.begin(), current_sample.end(), off); 00252 00253 vector<double> black(num_pixels); 00254 fill(current_sample_intensities.begin(), current_sample_intensities.end(), black); 00255 variance = base_variance; 00256 } 00257 00258 ///Get the next sample 00259 ///@param rng Random number generator 00260 template<class T> void next(T& rng) 00261 { 00262 for(int j=0; j < sample_iterations; j++) 00263 for(int k=0; k < (int) spots.size(); k++) 00264 { 00265 //Subtract off the spot we're interested in. 00266 remove_spot(current_sample_intensities, spot_intensities[k], current_sample[k]); 00267 00268 //Now current_sample_intensities is the image value for every spot in every frame, 00269 //except the current spot, which is always set to off. This allows us to add it in 00270 //easily. 00271 SpotWithBackground B(current_sample_intensities, spot_intensities[k], pixel_intensities, variance); 00272 vector<array<double, 3> > delta = forward_algorithm_delta(A, pi, B, O); 00273 current_sample[k] = backward_sampling<3,State, T>(A, delta, rng); 00274 00275 //Put the newly sampled spot in 00276 add_spot(current_sample_intensities, spot_intensities[k], current_sample[k]); 00277 } 00278 } 00279 /*void next() 00280 { 00281 RngDrand48 rng; 00282 next(rng); 00283 }*/ 00284 00285 ///Retrieve the current sample 00286 const vector<vector<State> >& sample() const 00287 { 00288 return current_sample; 00289 } 00290 ///Retrieve the intensities for the current sample 00291 const vector<vector<double> >& sample_intensities() const 00292 { 00293 return current_sample_intensities; 00294 } 00295 00296 }; 00297 00298 ///Gibbs sampling class which masks spots to reduce computation. 00299 /// 00300 ///This draws samples from, the spot states given the spots positions and some data. It is 00301 ///very similar to GibbsSampler, except that it only computes probabilities in a mask around each spot 00302 ///to save on computation. Variable naming matches that in FitSpots. 00303 ///@ingroup gStorm 00304 class GibbsSampler2 00305 { 00306 const vector<vector<double> >& pixel_intensities; 00307 const vector<vector<double> >& spot_intensities; 00308 const vector<Vector<4> > spots; 00309 const std::vector<std::vector<int> >& spot_pixels; 00310 const Matrix<3> A; 00311 const Vector<3> pi; 00312 const double base_variance; 00313 double variance; 00314 00315 const int sample_iterations; 00316 const int num_frames, num_pixels; 00317 const vector<int> O; 00318 00319 vector<vector<State> > current_sample; 00320 vector<vector<double> > current_sample_intensities; 00321 00322 vector<double> cutout_spot_intensities; 00323 vector<vector<double> > cutout_pixel_intensities; 00324 vector<vector<double> > cutout_current_sample_intensities; 00325 00326 public: 00327 00328 GibbsSampler2(const vector<vector<double> >& pixel_intensities_, 00329 const vector<vector<double> >& spot_intensities_, 00330 const vector<Vector<4> >& spots_, 00331 const vector<vector<int> >& spot_pixels_, 00332 const Matrix<3> A_, 00333 const Vector<3> pi_, 00334 double variance_, 00335 int sample_iterations_) 00336 :pixel_intensities(pixel_intensities_), //pixel_intensities: [frame][pixels] 00337 spot_intensities(spot_intensities_), //spot_intensities: [spot][pixel] 00338 spots(spots_), 00339 spot_pixels(spot_pixels_), 00340 A(A_), 00341 pi(pi_), 00342 base_variance(variance_), 00343 variance(variance_), 00344 sample_iterations(sample_iterations_), 00345 num_frames(pixel_intensities.size()), 00346 num_pixels(pixel_intensities[0].size()), 00347 //Observations vector. As usual for this application, the observations are just 00348 //numbered integers which refer to data held elsewhere. 00349 O(sequence(num_frames)), 00350 //Start all spots OFF, so the intensity is 0. OFF is 1 or 2, not 0!!! 00351 //sample_list: [sample][spot][frame]: list of samples drawn using Gibbs sampling 00352 current_sample(spots.size(), vector<State>(num_frames, 2)), //current sample [spot][frame] 00353 //pixel intensities assosciated with the current sample [frame][pixel] 00354 current_sample_intensities(num_frames, vector<double>(num_pixels)), 00355 cutout_pixel_intensities(num_frames), 00356 cutout_current_sample_intensities(num_frames) 00357 { 00358 //Check a bunch of stuff 00359 assert_same_size(pixel_intensities); 00360 assert_same_size(spot_intensities); 00361 } 00362 00363 ///Update the noide variance. Used for adding thermal noise. 00364 ///@param v noise variance. 00365 void set_variance(double v) 00366 { 00367 variance = v; 00368 } 00369 00370 00371 ///Reset the gibbs sampler oro the initial state (all spots off) 00372 void reset() 00373 { 00374 vector<State> off(num_frames, 2); 00375 fill(current_sample.begin(), current_sample.end(), off); 00376 00377 vector<double> black(num_pixels); 00378 fill(current_sample_intensities.begin(), current_sample_intensities.end(), black); 00379 variance = base_variance; 00380 } 00381 00382 ///Get the next sample 00383 ///@param rng Random number generator 00384 template<class T> void next(T& rng) 00385 { 00386 00387 //double remove=0; 00388 //double cut=0; 00389 //double swb=0; 00390 //double ff_masked=0; 00391 //double bs=0; 00392 //double add=0; 00393 //cvd_timer t; 00394 std::vector<array<double, 3> > delta3; 00395 for(int j=0; j < sample_iterations; j++) 00396 for(int k=0; k < (int) spots.size(); k++) 00397 { 00398 //t.reset(); 00399 //Subtract off the spot we're interested in. 00400 remove_spot(current_sample_intensities, spot_intensities[k], current_sample[k], spot_pixels[k]); 00401 //remove+=t.reset(); 00402 /* 00403 //Cut out 00404 //spot 00405 cutout_spot_intensities.resize(spot_pixels[k].size()); 00406 for(unsigned int i=0; i < spot_pixels[k].size(); i++) 00407 cutout_spot_intensities[i] = spot_intensities[k][spot_pixels[k][i]]; 00408 00409 //others 00410 for(int f=0; f < num_frames; f++) 00411 { 00412 cutout_current_sample_intensities[f].resize(spot_pixels[k].size()); 00413 cutout_pixel_intensities[f].resize(spot_pixels[k].size()); 00414 for(unsigned int i=0; i < spot_pixels[k].size();i++) 00415 { 00416 cutout_current_sample_intensities[f][i] = current_sample_intensities[f][spot_pixels[k][i]]; 00417 cutout_pixel_intensities[f][i] = pixel_intensities[f][spot_pixels[k][i]]; 00418 } 00419 }*/ 00420 //cut += t.reset(); 00421 //Now current_sample_intensities is the image value for every spot in every frame, 00422 //except the current spot, which is always set to off. This allows us to add it in 00423 //easily. 00424 00425 // SpotWithBackground B(current_sample_intensities, spot_intensities[k], pixel_intensities, variance); 00426 // vector<array<double, 3> > delta = forward_algorithm_delta(A, pi, B, O); 00427 00428 //ff+=t.reset(); 00429 00430 // SpotWithBackground B2(cutout_current_sample_intensities, cutout_spot_intensities, cutout_pixel_intensities, variance); 00431 // std::vector<array<double, 3> > delta2 = forward_algorithm_delta(A, pi, B2, O); 00432 //ff_cut+=t.reset(); 00433 00434 SpotWithBackgroundMasked B3(current_sample_intensities, spot_intensities[k], pixel_intensities, variance, spot_pixels[k]); 00435 //swb += t.reset(); 00436 forward_algorithm_delta2<3>(A, pi, B3, O, delta3); 00437 //f_masked+=t.reset(); 00438 /*for(unsigned int i=0; i < delta.size(); i++) 00439 { 00440 cout.precision(20); 00441 cout.setf(cout.scientific); 00442 std::cout << delta[i][0] << " " << delta[i][1] << " " <<delta[i][2] << std::endl; 00443 std::cout << delta2[i][0] << " " << delta2[i][1] << " " <<delta2[i][2] << std::endl; 00444 cout << endl; 00445 } 00446 std::exit(1); 00447 00448 */ 00449 00450 current_sample[k] = backward_sampling<3,State, T>(A, delta3, rng); 00451 //bs += t.reset(); 00452 //Put the newly sampled spot in 00453 add_spot(current_sample_intensities, spot_intensities[k], current_sample[k], spot_pixels[k]); 00454 //add += t.reset(); 00455 } 00456 // cout << "remove=" <<remove << " cut=" << cut << " swb=" << swb<< " ff_mask=" << ff_masked << " bs=" <<bs << " add="<<add << endl; 00457 } 00458 /* void next() 00459 { 00460 RngDrand48 rng; 00461 next(rng); 00462 } 00463 */ 00464 ///Retrieve the current sample 00465 const vector<vector<State> >& sample() const 00466 { 00467 return current_sample; 00468 } 00469 ///Retrieve the intensities for the current sample 00470 const vector<vector<double> >& sample_intensities() const 00471 { 00472 return current_sample_intensities; 00473 } 00474 00475 }; 00476 00477 #if 0 00478 ///Gibbs sampling class 00479 class GibbsSampler3 00480 { 00481 const vector<vector<double> >& pixel_intensities; 00482 const vector<vector<vector<double> > >& spot_intensities; 00483 const vector<Vector<4> > spots; 00484 const std::vector<std::vector<int> >& spot_pixels; 00485 const Matrix<3> A; 00486 const Vector<3> pi; 00487 const double base_variance; 00488 double variance; 00489 00490 const int sample_iterations; 00491 const int num_frames, num_pixels; 00492 const vector<int> O; 00493 00494 vector<vector<State> > current_sample; 00495 vector<vector<double> > current_sample_intensities; 00496 00497 public: 00498 00499 GibbsSampler3(const vector<vector<double> >& pixel_intensities_, 00500 const vector<vector<vector<double> > >& spot_intensities_, 00501 const vector<Vector<4> >& spots_, 00502 const vector<vector<int> >& spot_pixels_, 00503 const Matrix<3> A_, 00504 const Vector<3> pi_, 00505 double variance_, 00506 int sample_iterations_) 00507 :pixel_intensities(pixel_intensities_), //pixel_intensities: [frame][pixels] 00508 spot_intensities(spot_intensities_), //spot_intensities: [spot][frame][pixel] 00509 spots(spots_), 00510 spot_pixels(spot_pixels_), 00511 A(A_), 00512 pi(pi_), 00513 base_variance(variance_), 00514 variance(variance_), 00515 sample_iterations(sample_iterations_), 00516 num_frames(pixel_intensities.size()), 00517 num_pixels(pixel_intensities[0].size()), 00518 //Observations vector. As usual for this application, the observations are just 00519 //numbered integers which refer to data held elsewhere. 00520 O(sequence(num_frames)), 00521 //Start all spots OFF, so the intensity is 0. OFF is 1 or 2, not 0!!! 00522 //sample_list: [sample][spot][frame]: list of samples drawn using Gibbs sampling 00523 current_sample(spots.size(), vector<State>(num_frames, 2)), //current sample [spot][frame] 00524 //pixel intensities assosciated with the current sample [frame][pixel] 00525 current_sample_intensities(num_frames, vector<double>(num_pixels)) 00526 { 00527 //Check a bunch of stuff 00528 assert_same_size(pixel_intensities); 00529 assert_same_size(spot_intensities); 00530 } 00531 00532 ///Update the noide variance. Used for adding thermal noise. 00533 ///@param v noise variance. 00534 void set_variance(double v) 00535 { 00536 variance = v; 00537 } 00538 00539 ///Reset the gibbs sampler oro the initial state (all spots off) 00540 void reset() 00541 { 00542 vector<State> off(num_frames, 2); 00543 fill(current_sample.begin(), current_sample.end(), off); 00544 00545 vector<double> black(num_pixels); 00546 fill(current_sample_intensities.begin(), current_sample_intensities.end(), black); 00547 variance = base_variance; 00548 } 00549 00550 ///Get the next sample 00551 ///@param rng Random number generator 00552 template<class T> void next(T& rng) 00553 { 00554 00555 std::vector<array<double, 3> > delta3; 00556 for(int j=0; j < sample_iterations; j++) 00557 for(int k=0; k < (int) spots.size(); k++) 00558 { 00559 //Subtract off the spot we're interested in. 00560 remove_spot(current_sample_intensities, spot_intensities[k], current_sample[k], spot_pixels[k]); 00561 00562 //Now current_sample_intensities is the image value for every spot in every frame, 00563 //except the current spot, which is always set to off. This allows us to add it in 00564 //easily. 00565 00566 SpotWithBackgroundDriftMasked B3(current_sample_intensities, spot_intensities[k], pixel_intensities, variance, spot_pixels[k]); 00567 forward_algorithm_delta2<3>(A, pi, B3, O, delta3); 00568 00569 current_sample[k] = backward_sampling<3,State, T>(A, delta3, rng); 00570 //Put the newly sampled spot in 00571 add_spot(current_sample_intensities, spot_intensities[k], current_sample[k], spot_pixels[k]); 00572 } 00573 } 00574 /* void next() 00575 { 00576 RngDrand48 rng; 00577 next(rng); 00578 } 00579 */ 00580 ///Retrieve the current sample 00581 const vector<vector<State> >& sample() const 00582 { 00583 return current_sample; 00584 } 00585 ///Retrieve the intensities for the current sample 00586 const vector<vector<double> >& sample_intensities() const 00587 { 00588 return current_sample_intensities; 00589 } 00590 00591 }; 00592 #endif 00593 00594 } 00595 00596 using SampledMultispot::SpotWithBackground; 00597 using SampledMultispot::remove_spot; 00598 using SampledMultispot::add_spot; 00599 using SampledMultispot::compute_spot_intensity; 00600 using SampledMultispot::compute_spot_intensity_hessian; 00601 using SampledMultispot::compute_spot_intensity_derivatives; 00602 using SampledMultispot::sequence; 00603 using SampledMultispot::GibbsSampler; 00604 using SampledMultispot::GibbsSampler2; 00605 00606 #endif