Alternaria
fit cylinders and ellipsoids to fungus
psf_model.cpp
Go to the documentation of this file.
00001 /*
00002  * This work is licensed under a Creative Commons 
00003  * Attribution-Noncommercial-Share Alike 3.0 United States License.
00004  * 
00005  *    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
00006  * 
00007  * You are free:
00008  * 
00009  *    to Share - to copy, distribute, display, and perform the work
00010  *    to Remix - to make derivative works
00011  * 
00012  * Under the following conditions:
00013  * 
00014  *    Attribution. You must attribute the work in the manner specified by the
00015  *    author or licensor (but not in any way that suggests that they endorse you
00016  *    or your use of the work).
00017  * 
00018  *    Noncommercial. You may not use this work for commercial purposes.
00019  * 
00020  *    Share Alike. If you alter, transform, or build upon this work, you may
00021  *    distribute the resulting work only under the same or similar license to
00022  *    this one.
00023  * 
00024  * For any reuse or distribution, you must make clear to others the license
00025  * terms of this work. The best way to do this is by including this header.
00026  * 
00027  * Any of the above conditions can be waived if you get permission from the
00028  * copyright holder.
00029  * 
00030  * Apart from the remix rights granted under this license, nothing in this
00031  * license impairs or restricts the author's moral rights.
00032  */
00033 
00034 
00046 #include <config.h>
00047 
00048 #include <cassert>
00049 #include <cmath>
00050 #include <iostream>
00051 #include <fstream>
00052 #include <sstream>
00053 
00054 #include <inttypes.h>
00055 
00056 #include <jwsc/config.h>
00057 #include <jwsc/base/error.h>
00058 #include <jwsc/base/limits.h>
00059 #include <jwsc/prob/pdf.h>
00060 #include <jwsc/vector/vector.h>
00061 #include <jwsc/vector/vector_math.h>
00062 #include <jwsc/matrix/matrix.h>
00063 #include <jwsc/matrix/matrix_math.h>
00064 #include <jwsc/matblock/matblock.h>
00065 #include <jwsc/matblock/matblock_math.h>
00066 #include <jwsc/matblock/matblock_fft.h>
00067 #include <jwsc/imgblock/imgblock.h>
00068 #include <jwsc/imgblock/imgblock_io.h>
00069 
00070 #include <jwsc++/base/exception.h>
00071 
00072 #include "density.h"
00073 #include "printable.h"
00074 #include "imaging_model.h"
00075 #include "psf_model.h"
00076 
00077 
00078 #define  PADDING_CONV       8
00079 #define  PADDING_FFT        16
00080 
00081 #define  ALPHA_MU           0.88f
00082 #define  ALPHA_SIGMA        0.1f
00083 #define  ALPHA_MIN          1.0e-3f
00084 #define  ALPHA_MAX          0.99f
00085 
00086 #define  BETA_MU            0.5f
00087 #define  BETA_SIGMA         0.1f
00088 #define  BETA_MIN           0
00089 #define  BETA_MAX           10.0f
00090 
00091 #define  GAMMA_MU           0.8f
00092 #define  GAMMA_SIGMA        0.1f
00093 #define  GAMMA_MIN          1.0e-3f
00094 #define  GAMMA_MAX          1.0f
00095 
00096 
00097 using std::isinf;
00098 using std::isnan;
00099 using std::sqrt;
00100 using std::log;
00101 using std::ceil;
00102 using std::ostream;
00103 using std::istream;
00104 using std::ofstream;
00105 using std::ifstream;
00106 using std::ostringstream;
00107 using std::istringstream;
00108 using namespace jwsc;
00109 using jwscxx::base::IO_error;
00110 using jwscxx::base::Arg_error;
00111 
00112 
00113 /* ----------------------------  PSF_padding  ------------------------------- */
00114 
00116 PSF_padding::PSF_padding()
00117 {
00118     conv = PADDING_CONV;
00119     fft  = PADDING_FFT;
00120 }
00121 
00122 /* -------------------------------------------------------------------------- */
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 /* --------------------------------  PSF  ----------------------------------- */
00134 
00140 PSF::PSF(const PSF_padding* padding)
00141 {
00142     this->padding = padding;
00143     this->h       = 0;
00144 }
00145 
00146 
00148 PSF::~PSF()
00149 {
00150     free_matblock_f(h);
00151 }
00152 
00153 
00159 PSF& PSF::operator= (const PSF& psf)
00160 {
00161     padding = psf.padding;
00162 
00163     copy_matblock_f(&h, psf.h);
00164 
00165     return *this;
00166 }
00167 
00168 
00176 void PSF::write_h(const char* fname_fmt) const throw (IO_error)
00177 {
00178     if (h == 0)
00179         return;
00180 
00181     uint32_t num_mats = h->num_mats - 2*(padding->fft + padding->conv);
00182     uint32_t num_rows = h->num_rows - 2*(padding->fft + padding->conv);
00183     uint32_t num_cols = h->num_cols - 2*(padding->fft + padding->conv);
00184 
00185     Matblock_f* h_unshifted = 0;
00186     unshift_matblock_f(&h_unshifted, h);
00187 
00188     uint32_t start_mat = padding->fft + padding->conv;
00189     uint32_t start_row = padding->fft + padding->conv;
00190     uint32_t start_col = padding->fft + padding->conv;
00191 
00192     Matblock_f* h_no_pad = 0;
00193     copy_matblock_block_f(&h_no_pad, h_unshifted, start_mat, start_row, 
00194             start_col, num_mats, num_rows, num_cols);
00195     free_matblock_f(h_unshifted);
00196 
00197     float max = h_no_pad->elts[0][0][0];
00198     for (uint32_t mat = 0; mat < num_mats; mat++)
00199     {
00200         for (uint32_t row = 0; row < num_rows; row++)
00201         {
00202             for (uint32_t col = 0; col < num_cols; col++)
00203             {
00204                 if (max < h_no_pad->elts[ mat ][ row ][ col ])
00205                 {
00206                     max = h_no_pad->elts[ mat ][ row ][ col ];
00207                 }
00208             }
00209         }
00210     }
00211 
00212     if (max > 1.0e-8)
00213     {
00214         multiply_matblock_by_scalar_f(&h_no_pad, h_no_pad, 1.0f / max);
00215     }
00216 
00217     Imgblock_f* imgs = 0;
00218     create_imgblock_from_matblock_f(&imgs, h_no_pad);
00219     free_matblock_f(h_no_pad);
00220 
00221     Error* e;
00222     if ((e = write_imgblock_numbered_f(imgs, fname_fmt)) != 0)
00223     {
00224         IO_error ex(e->msg);
00225         free_error(e);
00226         throw ex;
00227     }
00228     free_imgblock_f(imgs);
00229 }
00230 
00231 /* -------------------------------------------------------------------------- */
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 /* -----------------------  PSF_model_density  ------------------------------ */
00243 
00249 PSF_model_density::PSF_model_density() throw (Arg_error)
00250 {
00251     float mu, sigma;
00252     float min, max;
00253 
00254     mu    = ALPHA_MU;
00255     sigma = ALPHA_SIGMA;
00256     min   = ALPHA_MIN;
00257     max   = ALPHA_MAX;
00258     set_alpha(mu, sigma, min, max);
00259 
00260     mu    = BETA_MU;
00261     sigma = BETA_SIGMA;
00262     min   = BETA_MIN;
00263     max   = BETA_MAX;
00264     set_beta(mu, sigma, min, max);
00265 
00266     mu    = GAMMA_MU;
00267     sigma = GAMMA_SIGMA;
00268     min   = GAMMA_MIN;
00269     max   = GAMMA_MAX;
00270     set_gamma(mu, sigma, min, max);
00271 }
00272 
00273 
00275 PSF_model_density* PSF_model_density::clone() const
00276 {
00277     float mu, sigma;
00278     float min, max;
00279 
00280     PSF_model_density* d = new PSF_model_density();
00281 
00282     mu    = alpha.get_mu();
00283     sigma = alpha.get_sigma();
00284     min   = alpha.get_min();
00285     max   = alpha.get_max();
00286     d->set_alpha(mu, sigma, min, max);
00287 
00288     mu    = beta.get_mu();
00289     sigma = beta.get_sigma();
00290     min   = beta.get_min();
00291     max   = beta.get_max();
00292     d->set_beta(mu, sigma, min, max);
00293 
00294     mu    = gamma.get_mu();
00295     sigma = gamma.get_sigma();
00296     min   = gamma.get_min();
00297     max   = gamma.get_max();
00298     d->set_gamma(mu, sigma, min, max);
00299 
00300     return d;
00301 }
00302 
00303 
00313 void PSF_model_density::set_alpha(float mu, float sigma, float min, float max) 
00314     throw (Arg_error)
00315 {
00316     if (min <= 0)
00317     {
00318         throw Arg_error("Minimum must be > 0");
00319     }
00320     if (max >= 1)
00321     {
00322         throw Arg_error("Maximum must be < 1");
00323     }
00324     alpha.set(mu, sigma, min, max);
00325 }
00326 
00327 
00337 void PSF_model_density::set_beta(float mu, float sigma, float min, float max) 
00338     throw (Arg_error)
00339 {
00340     if (min < 0)
00341     {
00342         throw Arg_error("Minimum must be >= 0");
00343     }
00344     beta.set(mu, sigma, min, max);
00345 }
00346 
00347 
00357 void PSF_model_density::set_gamma(float mu, float sigma, float min, float max) 
00358     throw (Arg_error)
00359 {
00360     if (min <= 0)
00361     {
00362         throw Arg_error("Minimum must be > 0");
00363     }
00364     if (max > 1)
00365     {
00366         throw Arg_error("Maximum must be <= 1");
00367     }
00368     gamma.set(mu, sigma, min, max);
00369 }
00370 
00371 
00373 float PSF_model_density::sample_alpha() const
00374 {
00375     return (float)sample_gaussian_pdf_d(alpha.get_mu(), alpha.get_sigma(), 
00376             alpha.get_min(), alpha.get_max());
00377 }
00378 
00379 
00381 float PSF_model_density::sample_beta() const
00382 {
00383     return (float)sample_gaussian_pdf_d(beta.get_mu(), beta.get_sigma(), 
00384             beta.get_min(), beta.get_max());
00385 }
00386 
00387 
00389 float PSF_model_density::sample_gamma() const
00390 {
00391     return (float)sample_gaussian_pdf_d(gamma.get_mu(), gamma.get_sigma(), 
00392             gamma.get_min(), gamma.get_max());
00393 }
00394 
00395 
00402 PSF_model* PSF_model_density::sample
00403 (
00404     const PSF_padding*   padding,
00405     const Imaging_model* imaging
00406 )
00407 const
00408 {
00409     return new PSF_model(sample_alpha(), sample_beta(), sample_gamma(), 
00410             padding, this, imaging);
00411 }
00412 
00413 /* -------------------------------------------------------------------------- */
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 /* --------------------------  PSF_model  ----------------------------------- */
00425 
00437 PSF_model::PSF_model
00438 (
00439     float                    alpha,
00440     float                    beta,
00441     float                    gamma,
00442     const PSF_padding*       padding,
00443     const PSF_model_density* density,
00444     const Imaging_model*     imaging
00445 ) 
00446 throw (Arg_error) : PSF(padding) 
00447 {
00448     this->alpha   = alpha;
00449     this->beta    = beta;
00450     this->gamma   = gamma;
00451     this->density = density;
00452 
00453     check_alpha();
00454     check_beta();
00455     check_gamma();
00456 
00457     update_log_prob();
00458 
00459     update_h(imaging);
00460 }
00461 
00462 
00464 PSF_model::PSF_model(const PSF_model& model) : PSF(model.padding)
00465 {
00466     alpha    = model.alpha;
00467     beta     = model.beta;
00468     gamma    = model.gamma;
00469     density  = model.density;
00470     log_prob = model.log_prob;
00471 
00472     if (model.h)
00473     {
00474         copy_matblock_f(&h, model.h);
00475     }
00476 }
00477 
00478 
00490 PSF_model::PSF_model
00491 (
00492     const char*              fname, 
00493     const PSF_padding*       padding,
00494     const PSF_model_density* density,
00495     const Imaging_model*     imaging
00496 )
00497 throw (IO_error, Arg_error) : PSF(padding)
00498 {
00499     ostringstream ost;
00500     istringstream ist;
00501     ifstream      in;
00502 
00503     this->density = density;
00504 
00505     in.open(fname);
00506     if (in.fail())
00507     {
00508         ost << fname << ": Could not open file";
00509         throw IO_error(ost.str());
00510     }
00511 
00512     const char* member_value;
00513 
00514     if (!(member_value = get_member_value("Alpha", in)))
00515     {
00516         ost << fname << ": Missing alpha";
00517         throw Arg_error(ost.str());
00518     }
00519     ist.str(member_value);
00520     ist >> alpha;
00521     if (ist.fail())
00522     {
00523         ost << fname << ": Invalid alpha";
00524         throw Arg_error(ost.str());
00525     }
00526     ist.clear(std::ios_base::goodbit);
00527 
00528     if (!(member_value = get_member_value("Beta", in)))
00529     {
00530         ost << fname << ": Missing beta";
00531         throw Arg_error(ost.str());
00532     }
00533     ist.str(member_value);
00534     ist >> beta;
00535     if (ist.fail())
00536     {
00537         ost << fname << ": Invalid beta";
00538         throw Arg_error(ost.str());
00539     }
00540     ist.clear(std::ios_base::goodbit);
00541 
00542     if (!(member_value = get_member_value("Gamma", in)))
00543     {
00544         ost << fname << ": Missing gamma";
00545         throw Arg_error(ost.str());
00546     }
00547     ist.str(member_value);
00548     ist >> gamma;
00549     if (ist.fail())
00550     {
00551         ost << fname << ": Invalid gamma";
00552         throw Arg_error(ost.str());
00553     }
00554     ist.clear(std::ios_base::goodbit);
00555 
00556     if (!(member_value = get_member_value("Log Prob", in)))
00557     {
00558         ost << fname << ": Missing log probability";
00559         throw Arg_error(ost.str());
00560     }
00561     ist.str(member_value);
00562     ist >> log_prob;
00563     if (ist.fail())
00564     {
00565         ost << fname << ": Invalid log probability";
00566         throw Arg_error(ost.str());
00567     }
00568     ist.clear(std::ios_base::goodbit);
00569 
00570     in.close();
00571     if (in.fail())
00572     {
00573         ost << fname << ": Could not close file";
00574         throw IO_error(ost.str());
00575     }
00576 
00577     check_alpha();
00578     check_beta();
00579     check_gamma();
00580 
00581     update_log_prob();
00582 
00583     update_h(imaging);
00584 }
00585 
00586 
00588 PSF_model* PSF_model::clone()
00589 {
00590     return new PSF_model(*this);
00591 }
00592 
00593 
00599 PSF_model& PSF_model::operator= (const PSF_model& psf)
00600 {
00601     PSF::operator=(psf);
00602 
00603     alpha    = psf.alpha;
00604     beta     = psf.beta;
00605     gamma    = psf.gamma;
00606     log_prob = psf.log_prob;
00607     density  = psf.density;
00608 
00609     return *this;
00610 }
00611 
00612 
00622 void PSF_model::update_h(const Imaging_model* imaging)
00623 {
00624     float x_scale = imaging->get_scale()->get_x();
00625     float y_scale = imaging->get_scale()->get_y();
00626     float z_scale = imaging->get_scale()->get_z();
00627 
00628     const Imaging_window* window = imaging->get_window();
00629 
00630     uint32_t num_mats, num_rows, num_cols;
00631     uint32_t mat, row, col;
00632     num_mats = window->get_num_imgs() + 2*(padding->conv + padding->fft);
00633     num_rows = window->get_num_rows() + 2*(padding->conv + padding->fft);
00634     num_cols = window->get_num_cols() + 2*(padding->conv + padding->fft);
00635 
00636     create_zero_matblock_f(&h, num_mats, num_rows, num_cols);
00637 
00638     /* Calculate the weights for (1/2) the Gaussians. */
00639     Vector_f* gauss_weight = 0;
00640     create_vector_f(&gauss_weight, static_cast<uint32_t>(ceil(num_mats / 2.0)));
00641     double gauss_weight_sum = 0.0;
00642     for (mat = 0; mat < (num_mats / 2); mat++)
00643     {
00644         gauss_weight->elts[ mat ] = pow(alpha, ceil(num_mats / 2.0) - mat);
00645         gauss_weight_sum += 2*gauss_weight->elts[ mat ];
00646     }
00647     if (num_mats % 2 == 1)
00648     {
00649         gauss_weight->elts[ mat ] = alpha;
00650         gauss_weight_sum += gauss_weight->elts[ mat ];
00651     }
00652 
00653     multiply_vector_by_scalar_f(&gauss_weight, gauss_weight, 
00654             1.0 / gauss_weight_sum);
00655 
00656     Matrix_f* m = 0;
00657     create_zero_matrix_f(&m, num_rows, num_cols);
00658 
00659     double sigma;
00660     double x_gauss, y_gauss;
00661     double gauss;
00662     double gauss_sum;
00663     double x, y, z;
00664 
00665     uint32_t start_mat = (uint32_t)ceil(num_mats / 2.0) - padding->fft;
00666     uint32_t start_row = (uint32_t)ceil(num_rows / 2.0) - padding->fft;
00667     uint32_t start_col = (uint32_t)ceil(num_cols / 2.0) - padding->fft;
00668 
00669     /* Compute the Gaussians in (1/8) the matrices of h. */
00670     for (mat = start_mat; mat < ceil(num_mats / 2.0); mat++)
00671     {
00672         z         = (ceil(num_mats / 2.0) - mat - 1)*z_scale;
00673         sigma     = sqrt(beta*fabs(z) + gamma*gamma);
00674         gauss_sum = 0.0;
00675 
00676         for (row = start_row; row < ceil(num_rows / 2.0); row++)
00677         {
00678             y       = (ceil(num_rows / 2.0) - row - 1)*y_scale;
00679 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
00680             y_gauss = integrate_gaussian_pdf_d(0, sigma, y, y+y_scale);
00681 #else
00682             y_gauss = gaussian_pdf_d(0, sigma, y+(y_scale*0.5));
00683 #endif
00684 
00685             for (col = start_col; col < ceil(num_cols / 2.0); col++)
00686             {
00687                 x       = (ceil(num_cols / 2.0) - col - 1)*x_scale;
00688 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
00689                 x_gauss = integrate_gaussian_pdf_d(0, sigma, x, x+x_scale);
00690 #else
00691                 x_gauss = gaussian_pdf_d(0, sigma, x+(x_scale*0.5));
00692 #endif
00693                 gauss   = x_gauss*y_gauss;
00694 
00695                 uint32_t r = row; uint32_t c = col;
00696                 m->elts[ r ][ c ] = gauss;
00697 
00698                 r = row; c = num_cols-col-1;
00699                 m->elts[ r ][ c ] = gauss;
00700 
00701                 r = num_rows-row-1; c = col; 
00702                 m->elts[ r ][ c ] = gauss;
00703 
00704                 r = num_rows-row-1; c = num_cols-col-1; 
00705                 m->elts[ r ][ c ] = gauss;
00706 
00707                 if ((row == num_rows-row-1) && (col == num_cols-col-1))
00708                 {
00709                     gauss_sum += gauss;
00710                 }
00711                 else
00712                 {
00713                     if (row != num_rows-row-1) 
00714                         gauss_sum += 2*gauss;
00715                     if (col != num_cols-col-1) 
00716                         gauss_sum += 2*gauss;
00717                 }
00718             }
00719         }
00720 
00721         multiply_matrix_by_scalar_f(&m, m, gauss_weight->elts[mat] / gauss_sum);
00722 
00723         copy_matrix_into_matblock_f(&h, h, m, MATBLOCK_MAT_MATRIX, mat);
00724 
00725         if (mat != num_mats-mat-1)
00726         {
00727             copy_matrix_into_matblock_f(&h, h, m, MATBLOCK_MAT_MATRIX, 
00728                     num_mats-mat-1);
00729         }
00730     }
00731 
00732     float sum = 0;
00733 
00734     for (mat = 0; mat < num_mats; mat++)
00735     {
00736         for (row = 0; row < num_rows; row++)
00737         {
00738             for (col = 0; col < num_cols; col++)
00739             {
00740                 sum += h->elts[ mat ][ row ][ col ];
00741             }
00742         }
00743     }
00744 
00745     assert(sum >= 1.0e-12);
00746     multiply_matblock_by_scalar_f(&h, h, 1.0f/sum);
00747 
00748     shift_matblock_f(&h, h);
00749 
00750     free_vector_f(gauss_weight);
00751     free_matrix_f(m);
00752 }
00753 
00754 
00765 void PSF_model::set
00766 (
00767     float                alpha, 
00768     float                beta, 
00769     float                gamma, 
00770     const Imaging_model* imaging
00771 )
00772 throw (Arg_error)
00773 {
00774     float old_alpha = this->alpha;
00775     float old_beta  = this->beta;
00776     float old_gamma = this->gamma;
00777 
00778     try
00779     {
00780         this->alpha = alpha;
00781         this->beta  = beta;
00782         this->gamma = gamma;
00783 
00784         check_alpha();
00785         check_beta();
00786         check_gamma();
00787 
00788         update_log_prob();
00789         update_h(imaging);
00790     }
00791     catch (Arg_error e)
00792     {
00793         set(old_alpha, old_beta, old_gamma, imaging);
00794         throw e;
00795     }
00796 }
00797 
00798 
00807 void PSF_model::set_alpha(float alpha, const Imaging_model* imaging) 
00808     throw (Arg_error)
00809 {
00810     float old_alpha = this->alpha;
00811 
00812     try
00813     {
00814         this->alpha = alpha;
00815         check_alpha();
00816 
00817         update_log_prob();
00818         update_h(imaging);
00819     }
00820     catch (Arg_error e)
00821     {
00822         set_alpha(old_alpha, imaging);
00823         throw e;
00824     }
00825 }
00826 
00827 
00836 void PSF_model::set_beta(float beta, const Imaging_model* imaging) 
00837     throw (Arg_error)
00838 {
00839     float old_beta = this->beta;
00840 
00841     try
00842     {
00843         this->beta = beta;
00844         check_beta();
00845 
00846         update_log_prob();
00847         update_h(imaging);
00848     }
00849     catch (Arg_error e)
00850     {
00851         set_beta(old_beta, imaging);
00852         throw e;
00853     }
00854 }
00855 
00856 
00865 void PSF_model::set_gamma(float gamma, const Imaging_model* imaging) 
00866     throw (Arg_error)
00867 {
00868     float old_gamma = this->gamma;
00869 
00870     try
00871     {
00872         this->gamma = gamma;
00873         check_gamma();
00874 
00875         update_log_prob();
00876         update_h(imaging);
00877     }
00878     catch (Arg_error e)
00879     {
00880         set_gamma(old_gamma, imaging);
00881         throw e;
00882     }
00883 }
00884 
00885 
00900 void PSF_model::print(const char* fname) const throw (IO_error)
00901 {
00902     ofstream out;
00903 
00904     out.open(fname);
00905     if (out.fail())
00906     {
00907         ostringstream ost;
00908         ost << fname << ": Could not open file";
00909         throw IO_error(ost.str());
00910     }
00911 
00912     print(out);
00913 
00914     out.close();
00915     if (out.fail())
00916     {
00917         ostringstream ost;
00918         ost << fname << ": Could not close file";
00919         throw IO_error(ost.str());
00920     }
00921 }
00922 
00923 
00936 void PSF_model::print(std::ostream& out) const
00937 {
00938     out << "    Alpha: " << alpha << '\n'
00939         << "     Beta: " << beta << '\n'
00940         << "    Gamma: " << gamma << '\n'
00941         << " Log Prob: " << log_prob << '\n';
00942 }
00943 
00944 
00946 void PSF_model::update_log_prob()
00947 {
00948     float  mu, sigma;
00949     float  min, max;
00950     double delta;
00951     double p_1, p_2;
00952 
00953     log_prob = 0;
00954 
00955     mu        = density->get_alpha().get_mu();
00956     sigma     = density->get_alpha().get_sigma();
00957     min       = density->get_alpha().get_min();
00958     max       = density->get_alpha().get_max();
00959     delta     = (max - min) / 1000.0;
00960     p_1       = integrate_gaussian_pdf_d(mu, sigma, alpha, alpha+delta); 
00961     p_2       = integrate_gaussian_pdf_d(mu, sigma, min, max);
00962     log_prob += log((p_1 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_1);
00963     log_prob -= log((p_2 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_2);
00964 
00965     mu        = density->get_beta().get_mu();
00966     sigma     = density->get_beta().get_sigma();
00967     min       = density->get_beta().get_min();
00968     max       = density->get_beta().get_max();
00969     delta     = (max - min) / 1000.0;
00970     p_1       = integrate_gaussian_pdf_d(mu, sigma, beta, beta+delta); 
00971     p_2       = integrate_gaussian_pdf_d(mu, sigma, min, max);
00972     log_prob += log((p_1 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_1);
00973     log_prob -= log((p_2 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_2);
00974 
00975     mu        = density->get_gamma().get_mu();
00976     sigma     = density->get_gamma().get_sigma();
00977     min       = density->get_gamma().get_min();
00978     max       = density->get_gamma().get_max();
00979     delta     = (max - min) / 1000.0;
00980     p_1       = integrate_gaussian_pdf_d(mu, sigma, gamma, gamma+delta); 
00981     p_2       = integrate_gaussian_pdf_d(mu, sigma, min, max);
00982     log_prob += log((p_1 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_1);
00983     log_prob -= log((p_2 < JWSC_MIN_LOG_ARG) ? JWSC_MIN_LOG_ARG : p_2);
00984 
00985 #if defined ALTERNARIA_HAVE_ISINF && defined ALTERNARIA_HAVE_ISNAN
00986     assert(!isinf(log_prob) && !isnan(log_prob));
00987 #endif
00988 }
00989 
00990 
00995 void PSF_model::check_alpha() const throw (Arg_error)
00996 {
00997     if (density->get_alpha().get_min() > alpha || 
00998         density->get_alpha().get_max() < alpha)
00999     {
01000         ostringstream ost;
01001         ost << "Alpha " << alpha << " outside density range ["
01002             << density->get_alpha().get_min() << ','
01003             << density->get_alpha().get_max() << ']';
01004         throw Arg_error(ost.str());
01005     }
01006 }
01007 
01008 
01013 void PSF_model::check_beta() const throw (Arg_error)
01014 {
01015     if (density->get_beta().get_min() > beta || 
01016         density->get_beta().get_max() < beta)
01017     {
01018         ostringstream ost;
01019         ost << "Beta " << beta << " outside density range ["
01020             << density->get_beta().get_min() << ','
01021             << density->get_beta().get_max() << ']';
01022         throw Arg_error(ost.str());
01023     }
01024 }
01025 
01026 
01031 void PSF_model::check_gamma() const throw (Arg_error)
01032 {
01033     if (density->get_gamma().get_min() > gamma || 
01034         density->get_gamma().get_max() < gamma)
01035     {
01036         ostringstream ost;
01037         ost << "Gamma " << gamma << " outside density range ["
01038             << density->get_gamma().get_min() << ','
01039             << density->get_gamma().get_max() << ']';
01040         throw Arg_error(ost.str());
01041     }
01042 }
01043 
01044 /* -------------------------------------------------------------------------- */
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 
01056 
01057 /* -----------------------  PSF_delta_model  -------------------------------- */
01058 
01063 PSF_delta_model::PSF_delta_model
01064 (
01065     const PSF_padding*   padding,
01066     const Imaging_model* imaging
01067 )
01068 : PSF(padding)
01069 {
01070     update_h(imaging);
01071 }
01072 
01073 
01083 void PSF_delta_model::update_h(const Imaging_model* imaging)
01084 {
01085     const Imaging_window* window = imaging->get_window();
01086 
01087     uint32_t num_mats, num_rows, num_cols;
01088     num_mats = window->get_num_imgs() + 2*(padding->conv + padding->fft);
01089     num_rows = window->get_num_rows() + 2*(padding->conv + padding->fft);
01090     num_cols = window->get_num_cols() + 2*(padding->conv + padding->fft);
01091 
01092     create_zero_matblock_f(&h, num_mats, num_rows, num_cols);
01093 
01094     double h_val = 1.0;
01095 
01096     if (num_mats % 2 == 0) h_val *= 0.5;
01097     if (num_rows % 2 == 0) h_val *= 0.5;
01098     if (num_cols % 2 == 0) h_val *= 0.5;
01099 
01100     for (uint32_t mat = static_cast<uint32_t>(ceil(num_mats / 2.0) - 1.0); 
01101             mat <= (num_mats / 2); mat++)
01102     {
01103         for (uint32_t row = static_cast<uint32_t>(ceil(num_rows / 2.0) - 1.0); 
01104                 row <= (num_rows / 2); row++)
01105         {
01106             for (uint32_t col = static_cast<uint32_t>(ceil(num_cols / 2.0) - 1.0); 
01107                     col <= (num_cols / 2); col++)
01108             {
01109                 h->elts[ mat ][ row ][ col ] = h_val;
01110             }
01111         }
01112     }
01113 
01114     /* debug. */
01115     double delta_sum = 0;
01116     for (uint32_t mat = 0; mat < num_mats; mat++)
01117     {
01118         for (uint32_t row = 0; row < num_rows; row++)
01119         {
01120             for (uint32_t col = 0; col < num_cols; col++)
01121             {
01122                 delta_sum += h->elts[ mat ][ row ][ col ];
01123             }
01124         }
01125     }
01126     assert(fabs(1.0 - delta_sum) < 1.0e-16);
01127 
01128     shift_matblock_f(&h, h);
01129 }
01130 
01131 /* -------------------------------------------------------------------------- */
01132 
01133 
01134 
01135 
01136 
01137 
01138 
01139 
01140 
01141 
01142 
01143 
01144 /* ------------------------  PSF_gauss_model  ------------------------------- */
01145 
01153 PSF_gauss_model::PSF_gauss_model
01154 (
01155     float                sigma,
01156     const PSF_padding*   padding,
01157     const Imaging_model* imaging
01158 )
01159 throw (Arg_error) : PSF(padding)
01160 {
01161     this->sigma = sigma;
01162     if (sigma < 1.0e-8)
01163     {
01164         throw Arg_error("Sigma is too small");
01165     }
01166 
01167     update_h(imaging);
01168 }
01169 
01170 
01176 PSF_gauss_model& PSF_gauss_model::operator= (const PSF_gauss_model& psf)
01177 {
01178     PSF::operator=(psf);
01179 
01180     sigma = psf.sigma;
01181 
01182     return *this;
01183 }
01184 
01185 
01195 void PSF_gauss_model::update_h(const Imaging_model* imaging)
01196 {
01197     float x_scale = imaging->get_scale()->get_x();
01198     float y_scale = imaging->get_scale()->get_y();
01199     float z_scale = imaging->get_scale()->get_z();
01200 
01201     const Imaging_window* window = imaging->get_window();
01202 
01203     uint32_t num_mats, num_rows, num_cols;
01204     num_mats = window->get_num_imgs() + 2*(padding->conv + padding->fft);
01205     num_rows = window->get_num_rows() + 2*(padding->conv + padding->fft);
01206     num_cols = window->get_num_cols() + 2*(padding->conv + padding->fft);
01207 
01208     create_zero_matblock_f(&h, num_mats, num_rows, num_cols);
01209 
01210     Matrix_f* m = 0;
01211     create_zero_matrix_f(&m, num_rows, num_cols);
01212 
01213     double x, y, z;
01214     double x_gauss, y_gauss, z_gauss;
01215     double gauss;
01216 
01217     uint32_t start_mat = (uint32_t)ceil(num_mats / 2.0) - padding->fft;
01218     uint32_t start_row = (uint32_t)ceil(num_rows / 2.0) - padding->fft;
01219     uint32_t start_col = (uint32_t)ceil(num_cols / 2.0) - padding->fft;
01220 
01221     /* Compute the Gaussian in (1/8) the matrices of h. */
01222     for (uint32_t mat = start_mat; mat < ceil(num_mats / 2.0); mat++)
01223     {
01224         z         = (ceil(num_mats / 2.0) - mat - 1)*z_scale;
01225 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
01226         z_gauss = integrate_gaussian_pdf_d(0, sigma, z, z+z_scale);
01227 #else
01228         z_gauss = gaussian_pdf_d(0, sigma, z+(z_scale*0.5));
01229 #endif
01230 
01231         for (uint32_t row = start_row; row < ceil(num_rows / 2.0); row++)
01232         {
01233             y       = (ceil(num_rows / 2.0) - row - 1)*y_scale;
01234 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
01235             y_gauss = integrate_gaussian_pdf_d(0, sigma, y, y+y_scale);
01236 #else
01237             y_gauss = gaussian_pdf_d(0, sigma, y+(y_scale*0.5));
01238 #endif
01239 
01240             for (uint32_t col = start_col; col < ceil(num_cols / 2.0); col++)
01241             {
01242                 x       = (ceil(num_cols / 2.0) - col - 1)*x_scale;
01243 #if defined JWSC_HAVE_SLATEC || defined JWSC_HAVE_ERF
01244                 x_gauss = integrate_gaussian_pdf_d(0, sigma, x, x+x_scale);
01245 #else
01246                 x_gauss = gaussian_pdf_d(0, sigma, x+(x_scale*0.5));
01247 #endif
01248                 gauss   = x_gauss*y_gauss*z_gauss;
01249 
01250                 uint32_t r = row; uint32_t c = col;
01251                 m->elts[ r ][ c ] = gauss;
01252 
01253                 r = row; c = num_cols-col-1;
01254                 m->elts[ r ][ c ] = gauss;
01255 
01256                 r = num_rows-row-1; c = col; 
01257                 m->elts[ r ][ c ] = gauss;
01258 
01259                 r = num_rows-row-1; c = num_cols-col-1; 
01260                 m->elts[ r ][ c ] = gauss;
01261             }
01262         }
01263 
01264         copy_matrix_into_matblock_f(&h, h, m, MATBLOCK_MAT_MATRIX, mat);
01265 
01266         if (mat != num_mats-mat-1)
01267         {
01268             copy_matrix_into_matblock_f(&h, h, m, MATBLOCK_MAT_MATRIX, 
01269                     num_mats-mat-1);
01270         }
01271     }
01272 
01273     float sum = 0;
01274 
01275     for (uint32_t mat = 0; mat < num_mats; mat++)
01276     {
01277         for (uint32_t row = 0; row < num_rows; row++)
01278         {
01279             for (uint32_t col = 0; col < num_cols; col++)
01280             {
01281                 sum += h->elts[ mat ][ row ][ col ];
01282             }
01283         }
01284     }
01285 
01286     assert(sum >= 1.0e-12);
01287     multiply_matblock_by_scalar_f(&h, h, 1.0f/sum);
01288 
01289     shift_matblock_f(&h, h);
01290 }
01291 
01292 /* -------------------------------------------------------------------------- */