Alternaria
fit cylinders and ellipsoids to fungus
|
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 /* -------------------------------------------------------------------------- */