ThreeB 1.1
sampled_multispot.h
Go to the documentation of this file.
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