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 <iomanip> 00052 #include <fstream> 00053 #include <sstream> 00054 #include <list> 00055 #include <vector> 00056 #include <algorithm> 00057 #include <stdexcept> 00058 00059 #include <inttypes.h> 00060 00061 #include <jwsc/config.h> 00062 #include <jwsc/base/limits.h> 00063 #include <jwsc/prob/pmf.h> 00064 #include <jwsc/prob/pdf.h> 00065 #include <jwsc/matblock/matblock.h> 00066 #include <jwsc/matblock/matblock_conv.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 "structure.h" 00075 #include "spore.h" 00076 #include "hypha.h" 00077 #include "psf_model.h" 00078 #include "imaging_model.h" 00079 #include "alternaria_model.h" 00080 00081 00082 #define NUM_LEVELS_P 0.7f 00083 00084 #define SPORE_P 0.3f 00085 #define APICAL_HYPHA_P 0.6f 00086 #define LATERAL_HYPHA_1_P 0.1f 00087 #define LATERAL_HYPHA_N_P 0.1f 00088 00089 #define C_1_MIN 0.0f 00090 #define C_1_MAX 0.0f 00091 00092 00093 using std::isinf; 00094 using std::isnan; 00095 using std::log; 00096 using std::sqrt; 00097 using std::fabs; 00098 using std::list; 00099 using std::vector; 00100 using std::ifstream; 00101 using std::ofstream; 00102 using std::ostringstream; 00103 using std::istringstream; 00104 using namespace jwsc; 00105 using jwscxx::base::IO_error; 00106 using jwscxx::base::Arg_error; 00107 using jwscxx::base::Result_error; 00108 00109 00110 /* ------------------------- Alternaria_density --------------------------- */ 00111 00117 Alternaria_density::Alternaria_density() throw (Arg_error) 00118 { 00119 set_num_levels_p(NUM_LEVELS_P); 00120 set_structure_p(SPORE_P, APICAL_HYPHA_P, LATERAL_HYPHA_1_P, 00121 LATERAL_HYPHA_N_P); 00122 set_c_1(C_1_MIN, C_1_MAX); 00123 } 00124 00125 00131 void Alternaria_density::set_num_levels_p(float p) throw (Arg_error) 00132 { 00133 if (p <= 0 || p >= 1) 00134 { 00135 throw Arg_error("Must be in (0,1)"); 00136 } 00137 num_levels_p = p; 00138 } 00139 00140 00151 void Alternaria_density::set_structure_p 00152 ( 00153 float spore_p, 00154 float apical_hypha_p, 00155 float lateral_hypha_1_p, 00156 float lateral_hypha_n_p 00157 ) 00158 throw (Arg_error) 00159 { 00160 if (spore_p < 0 || spore_p > 1 || 00161 apical_hypha_p < 0 || apical_hypha_p > 1 || 00162 lateral_hypha_1_p < 0 || lateral_hypha_1_p > 1 || 00163 lateral_hypha_n_p < 0 || lateral_hypha_n_p > 1) 00164 { 00165 throw Arg_error("Must be in [0,1]"); 00166 } 00167 this->spore_p = spore_p; 00168 this->apical_hypha_p = apical_hypha_p; 00169 this->lateral_hypha_1_p = lateral_hypha_1_p; 00170 this->lateral_hypha_n_p = lateral_hypha_n_p; 00171 } 00172 00173 00180 void Alternaria_density::set_c_1(float min, float max) throw (Arg_error) 00181 { 00182 if (min < 0) 00183 { 00184 throw Arg_error("Minimum must be >= 0"); 00185 } 00186 c_1.set(min, max); 00187 } 00188 00189 00191 float Alternaria_density::sample_c_1() const 00192 { 00193 return (float)sample_uniform_pdf_d(c_1.get_min(), c_1.get_max()); 00194 } 00195 00196 00215 Alternaria* Alternaria_density::sample 00216 ( 00217 size_t N, 00218 float centroid_x, 00219 float centroid_y, 00220 float centroid_z, 00221 float theta, 00222 float psi, 00223 size_t base_level, 00224 const Spore_density* spore_d, 00225 const Apical_hypha_density* apical_hypha_d, 00226 const Lateral_hypha_density* lateral_hypha_1_d, 00227 const Lateral_hypha_density* lateral_hypha_n_d 00228 ) 00229 const throw (Arg_error) 00230 { 00231 Alternaria* alternaria = new Alternaria(sample_c_1(), theta, 00232 psi, base_level, this, spore_d, apical_hypha_d, lateral_hypha_1_d, 00233 lateral_hypha_n_d); 00234 00235 try 00236 { 00237 generate_structure(alternaria, N, centroid_x, centroid_y, centroid_z); 00238 } 00239 catch (Arg_error e) 00240 { 00241 delete alternaria; 00242 throw e; 00243 } 00244 00245 return alternaria; 00246 } 00247 00248 00259 void Alternaria_density::generate_structure 00260 ( 00261 Alternaria* alternaria, 00262 size_t N, 00263 float centroid_x, 00264 float centroid_y, 00265 float centroid_z 00266 ) 00267 const throw (Arg_error) 00268 { 00269 if (N == 0) 00270 return; 00271 00272 const Spore_density* spore_d = alternaria->get_spore_d(); 00273 const Apical_hypha_density* apical_hypha_d 00274 = alternaria->get_apical_hypha_d(); 00275 const Lateral_hypha_density* lateral_hypha_1_d 00276 = alternaria->get_lateral_hypha_1_d(); 00277 const Lateral_hypha_density* lateral_hypha_n_d 00278 = alternaria->get_lateral_hypha_n_d(); 00279 00280 Apical_hypha* apical = apical_hypha_d->sample(centroid_x, centroid_y, 00281 centroid_z, alternaria->get_theta(), alternaria->get_psi(), 00282 alternaria->get_base_level()); 00283 alternaria->add_apical_hypha(apical); 00284 00285 Structure* s; 00286 00287 for (size_t n = 1; n < N; n++) 00288 { 00289 size_t level = alternaria->get_uniform_random_level(); 00290 00291 double u = sample_uniform_pdf_d(0, 1); 00292 00293 if (level == 0) 00294 { 00295 //double lat_prob = lateral_hypha_1_p / (lat_prob + apical_hypha_p); 00296 double lat_prob = lateral_hypha_1_p*geometric_pmf_d(num_levels_p,level); 00297 00298 if (u <= lat_prob) 00299 { 00300 s = alternaria->get_random_structure(level); 00301 alternaria->add_lateral_hypha(lateral_hypha_1_d->sample(s)); 00302 } 00303 else 00304 { 00305 s = alternaria->get_random_terminal(level); 00306 alternaria->add_apical_hypha(apical_hypha_d->sample(s)); 00307 } 00308 } 00309 else 00310 { 00311 //double lat_prob = lateral_hypha_n_p*geometric_pmf_d(num_levels_p,level-1); 00312 double lat_prob = lateral_hypha_n_p*geometric_pmf_d(num_levels_p,level); 00313 double spore_prob = spore_p; 00314 00315 lat_prob /= (lat_prob + spore_p + apical_hypha_p); 00316 spore_prob /= (lat_prob + spore_p + apical_hypha_p); 00317 00318 if (u <= lat_prob) 00319 { 00320 s = alternaria->get_random_structure(level); 00321 alternaria->add_lateral_hypha(lateral_hypha_n_d->sample(s)); 00322 } 00323 else if (u <= spore_prob) 00324 { 00325 s = alternaria->get_random_terminal(level); 00326 alternaria->add_spore(spore_d->sample(s)); 00327 } 00328 else 00329 { 00330 s = alternaria->get_random_terminal(level); 00331 alternaria->add_apical_hypha(apical_hypha_d->sample(s)); 00332 } 00333 } 00334 } 00335 } 00336 00337 /* -------------------------------------------------------------------------- */ 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 /* ----------------------------- Alternaria ------------------------------- */ 00350 00364 Alternaria::Alternaria 00365 ( 00366 float c_1, 00367 float theta, 00368 float psi, 00369 size_t base_level, 00370 const Alternaria_density* alt_d, 00371 const Spore_density* spore_d, 00372 const Apical_hypha_density* apical_hypha_d, 00373 const Lateral_hypha_density* lateral_hypha_1_d, 00374 const Lateral_hypha_density* lateral_hypha_n_d 00375 ) 00376 throw (Arg_error) 00377 { 00378 this->alt_d = alt_d; 00379 this->spore_d = spore_d; 00380 this->apical_hypha_d = apical_hypha_d; 00381 this->lateral_hypha_1_d = lateral_hypha_1_d; 00382 this->lateral_hypha_n_d = lateral_hypha_n_d; 00383 this->root = 0; 00384 this->log_prob = 0; 00385 this->c_1 = c_1; 00386 this->theta = theta; 00387 this->psi = psi; 00388 this->base_level = base_level; 00389 00390 check_c_1(); 00391 00392 level_structs.reserve(10); 00393 level_apical_hypha.reserve(10); 00394 level_lateral_hypha.reserve(10); 00395 level_spores.reserve(10); 00396 level_terminals.reserve(10); 00397 } 00398 00399 00401 Alternaria::Alternaria(const Alternaria& alt) 00402 { 00403 alt_d = alt.alt_d; 00404 spore_d = alt.spore_d; 00405 apical_hypha_d = alt.apical_hypha_d; 00406 lateral_hypha_1_d = alt.lateral_hypha_1_d; 00407 lateral_hypha_n_d = alt.lateral_hypha_n_d; 00408 log_prob = alt.log_prob; 00409 c_1 = alt.c_1; 00410 theta = alt.theta; 00411 psi = alt.psi; 00412 base_level = alt.base_level; 00413 00414 level_structs.reserve(10); 00415 level_apical_hypha.reserve(10); 00416 level_lateral_hypha.reserve(10); 00417 level_spores.reserve(10); 00418 level_terminals.reserve(10); 00419 00420 root = 0; 00421 if (alt.root) 00422 { 00423 root = alt.root->recursively_clone(); 00424 assert(base_level == root->get_level()); 00425 build_levels(root); 00426 } 00427 } 00428 00429 00443 Alternaria::Alternaria 00444 ( 00445 const char* fname, 00446 const Alternaria_density* alt_d, 00447 const Spore_density* spore_d, 00448 const Apical_hypha_density* apical_hypha_d, 00449 const Lateral_hypha_density* lateral_hypha_1_d, 00450 const Lateral_hypha_density* lateral_hypha_n_d 00451 ) 00452 throw (IO_error, Arg_error) 00453 { 00454 istringstream ist; 00455 ostringstream ost; 00456 ifstream in; 00457 00458 this->alt_d = alt_d; 00459 this->spore_d = spore_d; 00460 this->apical_hypha_d = apical_hypha_d; 00461 this->lateral_hypha_1_d = lateral_hypha_1_d; 00462 this->lateral_hypha_n_d = lateral_hypha_n_d; 00463 this->root = 0; 00464 00465 in.open(fname); 00466 if (in.fail()) 00467 { 00468 ost << fname << ": Could not open file"; 00469 throw IO_error(ost.str()); 00470 } 00471 00472 const char* member_value; 00473 00474 if (!(member_value = get_member_value("C_1", in))) 00475 { 00476 ost << fname << ": Missing C_1"; 00477 throw Arg_error(ost.str()); 00478 } 00479 ist.str(member_value); 00480 ist >> c_1; 00481 if (ist.fail()) 00482 { 00483 ost << fname << ": Invalid C_1"; 00484 throw Arg_error(ost.str()); 00485 } 00486 ist.clear(std::ios_base::goodbit); 00487 00488 check_c_1(); 00489 00490 if (!(member_value = get_member_value("Theta", in))) 00491 { 00492 ost << fname << ": Missing theta"; 00493 throw Arg_error(ost.str()); 00494 } 00495 ist.str(member_value); 00496 ist >> theta; 00497 if (ist.fail()) 00498 { 00499 ost << fname << ": Invalid theta"; 00500 throw Arg_error(ost.str()); 00501 } 00502 ist.clear(std::ios_base::goodbit); 00503 00504 if (!(member_value = get_member_value("Psi", in))) 00505 { 00506 ost << fname << ": Missing psi"; 00507 throw Arg_error(ost.str()); 00508 } 00509 ist.str(member_value); 00510 ist >> psi; 00511 if (ist.fail()) 00512 { 00513 ost << fname << ": Invalid psi"; 00514 throw Arg_error(ost.str()); 00515 } 00516 ist.clear(std::ios_base::goodbit); 00517 00518 if (!(member_value = get_member_value("Level", in))) 00519 { 00520 ost << fname << ": Missing base level"; 00521 throw Arg_error(ost.str()); 00522 } 00523 ist.str(member_value); 00524 ist >> base_level; 00525 if (ist.fail()) 00526 { 00527 ost << fname << ": Invalid base level"; 00528 throw Arg_error(ost.str()); 00529 } 00530 ist.clear(std::ios_base::goodbit); 00531 00532 if (!(member_value = get_member_value("Log Prob", in))) 00533 { 00534 ost << fname << ": Missing log probability"; 00535 throw Arg_error(ost.str()); 00536 } 00537 ist.str(member_value); 00538 ist >> log_prob; 00539 if (ist.fail()) 00540 { 00541 ost << fname << ": Invalid log probability"; 00542 throw Arg_error(ost.str()); 00543 } 00544 00545 try 00546 { 00547 read(in); 00548 } 00549 catch (Arg_error e) 00550 { 00551 ost << fname << ": " << e.get_msg(); 00552 throw Arg_error(ost.str()); 00553 } 00554 catch (IO_error e) 00555 { 00556 ost << fname << ": " << e.get_msg(); 00557 throw IO_error(ost.str()); 00558 } 00559 00560 in.close(); 00561 if (in.fail()) 00562 { 00563 ost << fname << ": Could not close file"; 00564 throw IO_error(ost.str()); 00565 } 00566 00567 level_structs.reserve(10); 00568 level_apical_hypha.reserve(10); 00569 level_lateral_hypha.reserve(10); 00570 level_spores.reserve(10); 00571 level_terminals.reserve(10); 00572 } 00573 00574 00576 Alternaria::~Alternaria() 00577 { 00578 delete root; 00579 for (size_t i = 0; i < level_structs.size(); i++) 00580 { 00581 delete level_structs[ i ]; 00582 delete level_apical_hypha[ i ]; 00583 delete level_lateral_hypha[ i ]; 00584 delete level_spores[ i ]; 00585 delete level_terminals[ i ]; 00586 } 00587 } 00588 00589 00591 Alternaria* Alternaria::clone() const 00592 { 00593 return new Alternaria(*this); 00594 } 00595 00596 00602 Alternaria& Alternaria::operator= (const Alternaria& alternaria) 00603 { 00604 alt_d = alternaria.alt_d; 00605 spore_d = alternaria.spore_d; 00606 apical_hypha_d = alternaria.apical_hypha_d; 00607 lateral_hypha_1_d = alternaria.lateral_hypha_1_d; 00608 lateral_hypha_n_d = alternaria.lateral_hypha_n_d; 00609 log_prob = alternaria.log_prob; 00610 c_1 = alternaria.c_1; 00611 theta = alternaria.theta; 00612 psi = alternaria.psi; 00613 base_level = alternaria.base_level; 00614 00615 for (size_t i = 0; i < level_structs.size(); i++) 00616 { 00617 delete level_structs[ i ]; 00618 delete level_apical_hypha[ i ]; 00619 delete level_lateral_hypha[ i ]; 00620 delete level_spores[ i ]; 00621 delete level_terminals[ i ]; 00622 } 00623 00624 level_structs.clear(); 00625 level_apical_hypha.clear(); 00626 level_lateral_hypha.clear(); 00627 level_spores.clear(); 00628 level_terminals.clear(); 00629 00630 level_structs.reserve(10); 00631 level_apical_hypha.reserve(10); 00632 level_lateral_hypha.reserve(10); 00633 level_spores.reserve(10); 00634 level_terminals.reserve(10); 00635 00636 delete root; 00637 root = 0; 00638 if (alternaria.root) 00639 { 00640 root = alternaria.root->recursively_clone(); 00641 assert(base_level == root->get_level()); 00642 build_levels(root); 00643 } 00644 00645 return *this; 00646 } 00647 00648 00650 double Alternaria::get_log_prob() const 00651 { 00652 #if defined ALTERNARIA_HAVE_ISINF && defined ALTERNARIA_HAVE_ISNAN 00653 assert(!isinf(log_prob) && !isnan(log_prob)); 00654 #endif 00655 00656 assert(log_prob <= 0); 00657 00658 if (root) 00659 { 00660 assert(root->get_log_prob_descend() <= 0); 00661 return log_prob + root->get_log_prob_descend(); 00662 } 00663 00664 return log_prob; 00665 } 00666 00667 00669 void Alternaria::set_root(Structure* root) throw (Arg_error) 00670 { 00671 assert(this->root==0); 00672 assert(base_level == root->get_level()); 00673 root->set_base_orientation(theta, psi); 00674 this->root = root; 00675 } 00676 00677 00679 void Alternaria::set_c_1(float c_1) throw (Arg_error) 00680 { 00681 float old_c_1 = this->c_1; 00682 00683 try 00684 { 00685 this->c_1 = c_1; 00686 check_c_1(); 00687 } 00688 catch (Arg_error e) 00689 { 00690 set_c_1(old_c_1); 00691 throw e; 00692 } 00693 } 00694 00695 00714 void Alternaria::print(const char* fname) const throw (IO_error) 00715 { 00716 ofstream out; 00717 00718 out.open(fname); 00719 if (out.fail()) 00720 { 00721 ostringstream ost; 00722 ost << fname << ": Could not open file"; 00723 throw IO_error(ost.str()); 00724 } 00725 00726 print(out); 00727 00728 out.close(); 00729 if (out.fail()) 00730 { 00731 ostringstream ost; 00732 ost << fname << ": Could not close file"; 00733 throw IO_error(ost.str()); 00734 } 00735 } 00736 00737 00754 void Alternaria::print(std::ostream& out) const 00755 { 00756 out << " C_1: " << c_1 << '\n' 00757 << " Theta: " << theta << '\n' 00758 << " Psi: " << psi << '\n' 00759 << " Level: " << base_level << '\n' 00760 << " Log Prob: " << log_prob << '\n'; 00761 00762 if (root) 00763 { 00764 root->recursively_print(out); 00765 } 00766 } 00767 00768 00770 size_t Alternaria::get_num_structures() const 00771 { 00772 size_t n = 0; 00773 00774 for (size_t i = 0; i < level_structs.size(); i++) 00775 { 00776 n += level_structs.at(i)->size(); 00777 } 00778 00779 return n; 00780 } 00781 00782 00784 size_t Alternaria::get_num_apical_hypha() const 00785 { 00786 size_t n = 0; 00787 00788 for (size_t i = 0; i < level_apical_hypha.size(); i++) 00789 { 00790 n += level_apical_hypha.at(i)->size(); 00791 } 00792 00793 return n; 00794 } 00795 00796 00798 size_t Alternaria::get_num_lateral_hypha() const 00799 { 00800 size_t n = 0; 00801 00802 for (size_t i = 0; i < level_lateral_hypha.size(); i++) 00803 { 00804 n += level_lateral_hypha.at(i)->size(); 00805 } 00806 00807 return n; 00808 } 00809 00810 00812 size_t Alternaria::get_num_spores() const 00813 { 00814 size_t n = 0; 00815 00816 for (size_t i = 0; i < level_spores.size(); i++) 00817 { 00818 n += level_spores.at(i)->size(); 00819 } 00820 00821 return n; 00822 } 00823 00824 00826 size_t Alternaria::get_uniform_random_level() const throw (Result_error) 00827 { 00828 if (level_structs.size() == 0) 00829 { 00830 throw Result_error("No levels in Alternaria"); 00831 } 00832 00833 size_t level = static_cast<size_t>(floor(sample_uniform_pdf_d( 00834 base_level, 0.9999*level_structs.size()))); 00835 00836 return level; 00837 } 00838 00839 00841 size_t Alternaria::get_geometric_random_level() const throw (Result_error) 00842 { 00843 if (level_structs.size() == 0) 00844 { 00845 throw Result_error("No levels in Alternaria"); 00846 } 00847 00848 size_t level = level_structs.size(); 00849 while (level >= level_structs.size()) 00850 { 00851 level = sample_geometric_pmf_d(alt_d->get_num_levels_p()); 00852 } 00853 00854 return level; 00855 } 00856 00857 00862 Structure* Alternaria::get_random_structure(size_t level) const 00863 throw (Arg_error, Result_error) 00864 { 00865 try 00866 { 00867 if (level_structs.at(level)->size() == 0) 00868 { 00869 ostringstream ost; 00870 ost << "No structures at level " << level; 00871 throw Result_error(ost.str()); 00872 } 00873 } 00874 catch (std::out_of_range e) 00875 { 00876 ostringstream ost; 00877 ost << "No level " << level << " in Alternaria"; 00878 throw Arg_error(ost.str()); 00879 } 00880 00881 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 00882 0.9999 * level_structs.at(level)->size()))); 00883 return level_structs.at(level)->at(i); 00884 } 00885 00886 00891 Apical_hypha* Alternaria::get_random_apical_hypha(size_t level) const 00892 throw (Arg_error, Result_error) 00893 { 00894 try 00895 { 00896 if (level_apical_hypha.at(level)->size() == 0) 00897 { 00898 ostringstream ost; 00899 ost << "No apical hypha at level " << level; 00900 throw Result_error(ost.str()); 00901 } 00902 } 00903 catch (std::out_of_range e) 00904 { 00905 ostringstream ost; 00906 ost << "No level " << level << " in Alternaria"; 00907 throw Arg_error(ost.str()); 00908 } 00909 00910 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 00911 0.9999 * level_apical_hypha.at(level)->size()))); 00912 return level_apical_hypha.at(level)->at(i); 00913 } 00914 00915 00920 Lateral_hypha* Alternaria::get_random_lateral_hypha(size_t level) const 00921 throw (Arg_error, Result_error) 00922 { 00923 try 00924 { 00925 if (level_lateral_hypha.at(level)->size() == 0) 00926 { 00927 ostringstream ost; 00928 ost << "No lateral hypha at level " << level; 00929 throw Result_error(ost.str()); 00930 } 00931 } 00932 catch (std::out_of_range e) 00933 { 00934 ostringstream ost; 00935 ost << "No level " << level << " in Alternaria"; 00936 throw Arg_error(ost.str()); 00937 } 00938 00939 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 00940 0.9999 * level_lateral_hypha.at(level)->size()))); 00941 return level_lateral_hypha.at(level)->at(i); 00942 } 00943 00944 00948 Spore* Alternaria::get_random_spore(size_t level) const 00949 throw (Arg_error, Result_error) 00950 { 00951 try 00952 { 00953 if (level_spores.at(level)->size() == 0) 00954 { 00955 ostringstream ost; 00956 ost << "No spores at level " << level; 00957 throw Result_error(ost.str()); 00958 } 00959 } 00960 catch (std::out_of_range e) 00961 { 00962 ostringstream ost; 00963 ost << "No level " << level << " in Alternaria"; 00964 throw Arg_error(ost.str()); 00965 } 00966 00967 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 00968 0.9999 * level_spores.at(level)->size()))); 00969 return level_spores.at(level)->at(i); 00970 } 00971 00972 00977 Structure* Alternaria::get_random_terminal(size_t level) const 00978 throw (Arg_error, Result_error) 00979 { 00980 try 00981 { 00982 if (level_terminals.at(level)->size() == 0) 00983 { 00984 ostringstream ost; 00985 ost << "No terminals at level " << level; 00986 throw Result_error(ost.str()); 00987 } 00988 } 00989 catch (std::out_of_range e) 00990 { 00991 ostringstream ost; 00992 ost << "No level " << level << " in Alternaria"; 00993 throw Arg_error(ost.str()); 00994 } 00995 00996 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 00997 0.9999 * level_terminals.at(level)->size()))); 00998 return level_terminals.at(level)->at(i); 00999 } 01000 01001 01006 Apical_hypha* Alternaria::get_random_terminal_apical_hypha(size_t level) const 01007 throw (Arg_error, Result_error) 01008 { 01009 try 01010 { 01011 if (level_apical_hypha.at(level)->size() == 0) 01012 { 01013 ostringstream ost; 01014 ost << "No apical hypha at level " << level; 01015 throw Result_error(ost.str()); 01016 } 01017 size_t n = 0; 01018 for (size_t i = 0; i < level_apical_hypha.at(level)->size(); i++) 01019 { 01020 if (level_apical_hypha.at(level)->at(i)->get_apical() == 0) 01021 { 01022 n++; 01023 } 01024 } 01025 if (n == 0) 01026 { 01027 ostringstream ost; 01028 ost << "No terminal apical hypha at level " << level; 01029 throw Result_error(ost.str()); 01030 } 01031 } 01032 catch (std::out_of_range e) 01033 { 01034 ostringstream ost; 01035 ost << "No level " << level << " in Alternaria"; 01036 throw Arg_error(ost.str()); 01037 } 01038 01039 Apical_hypha* hypha = 0; 01040 while (!hypha) 01041 { 01042 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 01043 0.9999 * level_apical_hypha.at(level)->size()))); 01044 if (level_apical_hypha.at(level)->at(i)->get_apical() == 0) 01045 { 01046 hypha = level_apical_hypha.at(level)->at(i); 01047 } 01048 } 01049 01050 return hypha; 01051 } 01052 01053 01057 Spore* Alternaria::get_random_terminal_spore(size_t level) const 01058 throw (Arg_error, Result_error) 01059 { 01060 try 01061 { 01062 if (level_spores.at(level)->size() == 0) 01063 { 01064 ostringstream ost; 01065 ost << "No spores at level " << level; 01066 throw Result_error(ost.str()); 01067 } 01068 size_t n = 0; 01069 for (size_t i = 0; i < level_spores.at(level)->size(); i++) 01070 { 01071 if (level_spores.at(level)->at(i)->get_apical() == 0) 01072 { 01073 n++; 01074 } 01075 } 01076 if (n == 0) 01077 { 01078 ostringstream ost; 01079 ost << "No terminal spores at level " << level; 01080 throw Result_error(ost.str()); 01081 } 01082 } 01083 catch (std::out_of_range e) 01084 { 01085 ostringstream ost; 01086 ost << "No level " << level << " in Alternaria"; 01087 throw Arg_error(ost.str()); 01088 } 01089 01090 Spore* spore = 0; 01091 while (!spore) 01092 { 01093 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 01094 0.9999 * level_spores.at(level)->size()))); 01095 if (level_spores.at(level)->at(i)->get_apical() == 0) 01096 { 01097 spore = level_spores.at(level)->at(i); 01098 } 01099 } 01100 01101 return spore; 01102 } 01103 01104 01109 Lateral_hypha* Alternaria::get_random_terminal_lateral_hypha(size_t level) const 01110 throw (Arg_error, Result_error) 01111 { 01112 try 01113 { 01114 if (level_lateral_hypha.at(level)->size() == 0) 01115 { 01116 ostringstream ost; 01117 ost << "No lateral hypha at level " << level; 01118 throw Result_error(ost.str()); 01119 } 01120 size_t n = 0; 01121 for (size_t i = 0; i < level_lateral_hypha.at(level)->size(); i++) 01122 { 01123 if (level_lateral_hypha.at(level)->at(i)->get_apical() == 0) 01124 { 01125 n++; 01126 } 01127 } 01128 if (n == 0) 01129 { 01130 ostringstream ost; 01131 ost << "No terminal apical hypha at level " << level; 01132 throw Result_error(ost.str()); 01133 } 01134 } 01135 catch (std::out_of_range e) 01136 { 01137 ostringstream ost; 01138 ost << "No level " << level << " in Alternaria"; 01139 throw Arg_error(ost.str()); 01140 } 01141 01142 Lateral_hypha* hypha = 0; 01143 while (!hypha) 01144 { 01145 size_t i = static_cast<size_t>(floor(sample_uniform_pdf_d(0, 01146 0.9999 * level_lateral_hypha.at(level)->size()))); 01147 if (level_lateral_hypha.at(level)->at(i)->get_apical() == 0) 01148 { 01149 hypha = level_lateral_hypha.at(level)->at(i); 01150 } 01151 } 01152 01153 return hypha; 01154 } 01155 01156 01158 void Alternaria::add_lateral_hypha(Lateral_hypha* h) throw (Arg_error) 01159 { 01160 size_t level = h->get_level(); 01161 01162 ensure_level_space(level); 01163 01164 if (!h->get_parent()) 01165 { 01166 set_root(h); 01167 } 01168 01169 level_terminals[ level ]->push_back(h); 01170 level_structs[ level ]->push_back(h); 01171 level_lateral_hypha[ level ]->push_back(h); 01172 01173 double p; 01174 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 01175 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 01176 double spore_p = alt_d->get_spore_p(); 01177 double apical_hypha_p = alt_d->get_apical_hypha_p(); 01178 double num_levels_p = alt_d->get_num_levels_p(); 01179 01180 // Note that the level must be > 0. 01181 if (level == 1) 01182 { 01183 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 01184 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, level-1); 01185 p /= p + apical_hypha_p; 01186 } 01187 else 01188 { 01189 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-2); 01190 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-1); 01191 p /= p + spore_p + apical_hypha_p; 01192 } 01193 01194 log_prob += (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 01195 01196 check_levels(); 01197 } 01198 01199 01206 void Alternaria::remove_lateral_hypha(Lateral_hypha* h) throw (Arg_error) 01207 { 01208 size_t level = h->get_level(); 01209 01210 ensure_level_space(level); 01211 01212 if (find(level_terminals[ level ]->begin(), 01213 level_terminals[ level ]->end(), h) 01214 == level_terminals[ level ]->end()) 01215 { 01216 throw Arg_error("Cannot remove a non-terminal lateral hypha"); 01217 } 01218 01219 Structure* parent = h->get_parent(); 01220 01221 if (parent) 01222 { 01223 parent->remove_lateral(h); 01224 } 01225 else 01226 { 01227 root = 0; 01228 } 01229 01230 level_structs[ level ]->erase( 01231 find(level_structs[ level ]->begin(), 01232 level_structs[ level ]->end(), (Structure*)h)); 01233 level_terminals[ level ]->erase( 01234 find(level_terminals[ level ]->begin(), 01235 level_terminals[ level ]->end(), (Structure*)h)); 01236 level_lateral_hypha[ level ]->erase( 01237 find(level_lateral_hypha[ level ]->begin(), 01238 level_lateral_hypha[ level ]->end(), h)); 01239 01240 double p; 01241 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 01242 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 01243 double spore_p = alt_d->get_spore_p(); 01244 double apical_hypha_p = alt_d->get_apical_hypha_p(); 01245 double num_levels_p = alt_d->get_num_levels_p(); 01246 01247 // Note that the level must be > 0. 01248 if (level == 1) 01249 { 01250 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 01251 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, level-1); 01252 p /= p + apical_hypha_p; 01253 } 01254 else 01255 { 01256 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-2); 01257 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-1); 01258 p /= p + spore_p + apical_hypha_p; 01259 } 01260 01261 log_prob -= (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 01262 01263 delete h; 01264 01265 check_levels(); 01266 } 01267 01268 01270 void Alternaria::add_apical_hypha(Apical_hypha* h) throw (Arg_error) 01271 { 01272 size_t level = h->get_level(); 01273 01274 ensure_level_space(level); 01275 01276 if (h->get_parent()) 01277 { 01278 replace(level_terminals[ level ]->begin(), 01279 level_terminals[ level ]->end(), 01280 h->get_parent(), (Structure*)h); 01281 } 01282 else 01283 { 01284 set_root(h); 01285 level_terminals[ level ]->push_back(h); 01286 } 01287 01288 level_structs[ level ]->push_back(h); 01289 level_apical_hypha[ level ]->push_back(h); 01290 01291 log_prob += log(alt_d->get_apical_hypha_p()); 01292 01293 check_levels(); 01294 } 01295 01296 01303 void Alternaria::remove_apical_hypha(Apical_hypha* h) throw (Arg_error) 01304 { 01305 size_t level = h->get_level(); 01306 01307 ensure_level_space(level); 01308 01309 if (find(level_terminals[ level ]->begin(), 01310 level_terminals[ level ]->end(), h) 01311 == level_terminals[ level ]->end()) 01312 { 01313 throw Arg_error("Cannot remove a non-terminal apical hypha"); 01314 } 01315 01316 Structure* parent = h->get_parent(); 01317 01318 if (parent) 01319 { 01320 replace(level_terminals[ level ]->begin(), 01321 level_terminals[ level ]->end(), 01322 (Structure*)h, parent); 01323 parent->set_apical(0); 01324 } 01325 else 01326 { 01327 level_terminals[ level ]->erase( 01328 find(level_terminals[ level ]->begin(), 01329 level_terminals[ level ]->end(), (Structure*)h)); 01330 root = 0; 01331 } 01332 01333 level_structs[ level ]->erase( 01334 find(level_structs[ level ]->begin(), 01335 level_structs[ level ]->end(), (Structure*)h)); 01336 level_apical_hypha[ level ]->erase( 01337 find(level_apical_hypha[ level ]->begin(), 01338 level_apical_hypha[ level ]->end(), h)); 01339 01340 log_prob -= log(alt_d->get_apical_hypha_p()); 01341 01342 delete h; 01343 01344 check_levels(); 01345 } 01346 01347 01356 void Alternaria::merge_2_apical_with_spore 01357 ( 01358 Apical_hypha* hypha_1, 01359 const Spore* rvals 01360 ) 01361 throw (Arg_error) 01362 { 01363 size_t level = hypha_1->get_level(); 01364 01365 ensure_level_space(level); 01366 01367 if (find(level_structs[ level ]->begin(), 01368 level_structs[ level ]->end(), hypha_1) 01369 == level_structs[ level ]->end()) 01370 { 01371 throw Arg_error("Cannot find apical hypha to merge"); 01372 } 01373 01374 Spore* merged = 0; 01375 01376 Apical_hypha* hypha_2 = hypha_1->merge_with_apical(&merged, rvals); 01377 01378 if (!(merged->get_apical())) 01379 { 01380 replace(level_terminals[ level ]->begin(), 01381 level_terminals[ level ]->end(), 01382 (Structure*)merged, (Structure*)hypha_2); 01383 } 01384 level_structs[ level ]->erase( 01385 find(level_structs[ level ]->begin(), 01386 level_structs[ level ]->end(), (Structure*)hypha_1)); 01387 level_structs[ level ]->erase( 01388 find(level_structs[ level ]->begin(), 01389 level_structs[ level ]->end(), (Structure*)hypha_2)); 01390 level_apical_hypha[ level ]->erase( 01391 find(level_apical_hypha[ level ]->begin(), 01392 level_apical_hypha[ level ]->end(), (Structure*)hypha_1)); 01393 level_apical_hypha[ level ]->erase( 01394 find(level_apical_hypha[ level ]->begin(), 01395 level_apical_hypha[ level ]->end(), (Structure*)hypha_2)); 01396 01397 log_prob -= log(alt_d->get_apical_hypha_p()); 01398 log_prob -= log(alt_d->get_apical_hypha_p()); 01399 01400 delete hypha_1; 01401 delete hypha_2; 01402 01403 if (!(merged->get_parent())) 01404 { 01405 root = 0; 01406 set_root(merged); 01407 } 01408 01409 level_structs[ level ]->push_back(merged); 01410 level_spores[ level ]->push_back(merged); 01411 01412 log_prob += log(alt_d->get_spore_p()); 01413 01414 check_levels(); 01415 } 01416 01417 01425 void Alternaria::split_apical_hypha_into_apical 01426 ( 01427 Apical_hypha* h, 01428 const Apical_hypha* rvals_1, 01429 const Apical_hypha* rvals_2 01430 ) 01431 throw (Arg_error) 01432 { 01433 size_t level = h->get_level(); 01434 01435 ensure_level_space(level); 01436 01437 if (find(level_structs[ level ]->begin(), 01438 level_structs[ level ]->end(), h) 01439 == level_structs[ level ]->end()) 01440 { 01441 throw Arg_error("Cannot find apical hypha to split"); 01442 } 01443 01444 Apical_hypha* split = h->split_into_apical(rvals_1, rvals_2); 01445 if (!(split->get_apical())) 01446 { 01447 replace(level_terminals[ level ]->begin(), 01448 level_terminals[ level ]->end(), 01449 (Structure*)h, (Structure*)split); 01450 } 01451 01452 level_structs[ level ]->push_back(split); 01453 level_apical_hypha[ level ]->push_back(split); 01454 01455 log_prob += log(alt_d->get_apical_hypha_p()); 01456 01457 check_levels(); 01458 } 01459 01460 01469 void Alternaria::merge_apical_hypha_with_apical 01470 ( 01471 Apical_hypha* h, 01472 const Apical_hypha* rvals 01473 ) 01474 throw (Arg_error) 01475 { 01476 size_t level = h->get_level(); 01477 01478 ensure_level_space(level); 01479 01480 if (find(level_structs[ level ]->begin(), 01481 level_structs[ level ]->end(), h) 01482 == level_structs[ level ]->end()) 01483 { 01484 throw Arg_error("Cannot find apical hypha to merge"); 01485 } 01486 01487 Apical_hypha* merged = h->merge_with_apical(rvals); 01488 01489 if (!(h->get_apical())) 01490 { 01491 replace(level_terminals[ level ]->begin(), 01492 level_terminals[ level ]->end(), 01493 (Structure*)merged, (Structure*)h); 01494 } 01495 level_structs[ level ]->erase( 01496 find(level_structs[ level ]->begin(), 01497 level_structs[ level ]->end(), (Structure*)merged)); 01498 level_apical_hypha[ level ]->erase( 01499 find(level_apical_hypha[ level ]->begin(), 01500 level_apical_hypha[ level ]->end(), (Structure*)merged)); 01501 01502 log_prob -= log(alt_d->get_apical_hypha_p()); 01503 01504 delete merged; 01505 01506 check_levels(); 01507 } 01508 01509 01517 void Alternaria::split_apical_hypha_into_lateral 01518 ( 01519 Apical_hypha* h, 01520 const Apical_hypha* rvals_1, 01521 const Lateral_hypha* rvals_2 01522 ) 01523 throw (Arg_error) 01524 { 01525 size_t level = h->get_level(); 01526 01527 ensure_level_space(level+1); 01528 01529 if (find(level_structs[ level ]->begin(), 01530 level_structs[ level ]->end(), h) 01531 == level_structs[ level ]->end()) 01532 { 01533 throw Arg_error("Cannot find apical hypha to split"); 01534 } 01535 01536 Lateral_hypha* split = h->split_into_lateral(rvals_1, rvals_2); 01537 if (split->get_apical()) 01538 { 01539 level_terminals[ level ]->push_back(h); 01540 recursively_update_level(split->get_apical(), level); 01541 } 01542 else 01543 { 01544 level_terminals[ level+1 ]->push_back(split); 01545 } 01546 01547 for (list<Lateral_structure*>::iterator it = split->get_laterals().begin(); 01548 it != split->get_laterals().end(); it++) 01549 { 01550 recursively_update_level(*it, level+1); 01551 } 01552 01553 level_structs[ level+1 ]->push_back(split); 01554 level_lateral_hypha[ level+1 ]->push_back(split); 01555 01556 double p; 01557 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 01558 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 01559 double spore_p = alt_d->get_spore_p(); 01560 double apical_hypha_p = alt_d->get_apical_hypha_p(); 01561 double num_levels_p = alt_d->get_num_levels_p(); 01562 01563 // Note that the level must be >= 0. 01564 if (level == 0) 01565 { 01566 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 01567 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, level); 01568 p /= p + apical_hypha_p; 01569 } 01570 else 01571 { 01572 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-1); 01573 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level); 01574 p /= p + spore_p + apical_hypha_p; 01575 } 01576 01577 log_prob += (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 01578 01579 check_levels(); 01580 } 01581 01582 01592 void Alternaria::merge_apical_hypha_with_lateral 01593 ( 01594 Apical_hypha* h, 01595 Lateral_hypha* lat, 01596 const Apical_hypha* rvals 01597 ) 01598 throw (Arg_error) 01599 { 01600 size_t level = h->get_level(); 01601 01602 ensure_level_space(level+1); 01603 01604 if (find(level_terminals[ level ]->begin(), 01605 level_terminals[ level ]->end(), h) 01606 == level_terminals[ level ]->end()) 01607 { 01608 throw Arg_error("Cannot find terminal apical hypha to merge"); 01609 } 01610 01611 Lateral_hypha* merged = h->merge_with_lateral(lat, rvals); 01612 01613 if (h->get_apical()) 01614 { 01615 recursively_update_level(h->get_apical(), level+1); 01616 01617 level_terminals[ level ]->erase( 01618 find(level_terminals[ level ]->begin(), 01619 level_terminals[ level ]->end(), (Structure*)h)); 01620 } 01621 else 01622 { 01623 level_terminals[ level+1 ]->erase( 01624 find(level_terminals[ level+1 ]->begin(), 01625 level_terminals[ level+1 ]->end(), (Structure*)merged)); 01626 } 01627 01628 for (list<Lateral_structure*>::iterator it = h->get_laterals().begin(); 01629 it != h->get_laterals().end(); it++) 01630 { 01631 try 01632 { 01633 recursively_update_level(*it, level+2); 01634 } 01635 catch (Arg_error e) 01636 { 01637 // Ignore, didn't need updating. 01638 } 01639 } 01640 01641 level_structs[ level+1 ]->erase( 01642 find(level_structs[ level+1 ]->begin(), 01643 level_structs[ level+1 ]->end(), (Structure*)merged)); 01644 level_lateral_hypha[ level+1 ]->erase( 01645 find(level_lateral_hypha[ level+1 ]->begin(), 01646 level_lateral_hypha[ level+1 ]->end(), (Structure*)merged)); 01647 01648 double p; 01649 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 01650 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 01651 double spore_p = alt_d->get_spore_p(); 01652 double apical_hypha_p = alt_d->get_apical_hypha_p(); 01653 double num_levels_p = alt_d->get_num_levels_p(); 01654 01655 // Note that the level must be >= 0. 01656 if (level == 0) 01657 { 01658 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 01659 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, level); 01660 p /= p + apical_hypha_p; 01661 } 01662 else 01663 { 01664 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-1); 01665 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level); 01666 p /= p + spore_p + apical_hypha_p; 01667 } 01668 01669 log_prob -= (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 01670 01671 delete merged; 01672 01673 check_levels(); 01674 } 01675 01676 01683 void Alternaria::replace_apical_hypha_with_spore 01684 ( 01685 Apical_hypha* hypha, 01686 Spore* spore 01687 ) 01688 throw (Arg_error) 01689 { 01690 size_t level = hypha->get_level(); 01691 01692 ensure_level_space(level); 01693 01694 if (find(level_structs[ level ]->begin(), 01695 level_structs[ level ]->end(), hypha) 01696 == level_structs[ level ]->end()) 01697 { 01698 throw Arg_error("Cannot find apical hypha to replace"); 01699 } 01700 01701 hypha->replace(spore); 01702 01703 if (!(spore->get_apical())) 01704 { 01705 replace(level_terminals[ level ]->begin(), 01706 level_terminals[ level ]->end(), 01707 (Structure*)hypha, (Structure*)spore); 01708 } 01709 level_structs[ level ]->erase( 01710 find(level_structs[ level ]->begin(), 01711 level_structs[ level ]->end(), (Structure*)hypha)); 01712 level_apical_hypha[ level ]->erase( 01713 find(level_apical_hypha[ level ]->begin(), 01714 level_apical_hypha[ level ]->end(), (Structure*)hypha)); 01715 01716 log_prob -= log(alt_d->get_apical_hypha_p()); 01717 01718 delete hypha; 01719 01720 if (!(spore->get_parent())) 01721 { 01722 root = 0; 01723 set_root(spore); 01724 } 01725 01726 level_structs[ level ]->push_back(spore); 01727 level_spores[ level ]->push_back(spore); 01728 01729 log_prob += log(alt_d->get_spore_p()); 01730 01731 check_levels(); 01732 } 01733 01734 01736 void Alternaria::add_spore(Spore* s) throw (Arg_error) 01737 { 01738 size_t level = s->get_level(); 01739 01740 ensure_level_space(level); 01741 01742 if (s->get_parent()) 01743 { 01744 replace(level_terminals[ level ]->begin(), 01745 level_terminals[ level ]->end(), 01746 s->get_parent(), (Structure*)s); 01747 } 01748 else 01749 { 01750 set_root(s); 01751 level_terminals[ level ]->push_back(s); 01752 } 01753 01754 level_structs[ level ]->push_back(s); 01755 level_spores[ level ]->push_back(s); 01756 01757 log_prob += log(alt_d->get_spore_p()); 01758 01759 check_levels(); 01760 } 01761 01762 01768 void Alternaria::remove_spore(Spore* s) throw (Arg_error) 01769 { 01770 size_t level = s->get_level(); 01771 01772 ensure_level_space(level); 01773 01774 if (find(level_terminals[ level ]->begin(), 01775 level_terminals[ level ]->end(), s) 01776 == level_terminals[ level ]->end()) 01777 { 01778 throw Arg_error("Cannot remove a non-terminal spore"); 01779 } 01780 01781 Structure* parent = s->get_parent(); 01782 01783 if (parent) 01784 { 01785 replace(level_terminals[ level ]->begin(), 01786 level_terminals[ level ]->end(), 01787 (Structure*)s, parent); 01788 parent->set_apical(0); 01789 } 01790 else 01791 { 01792 level_terminals[ level ]->erase( 01793 find(level_terminals[ level ]->begin(), 01794 level_terminals[ level ]->end(), (Structure*)s)); 01795 root = 0; 01796 } 01797 01798 level_structs[ level ]->erase( 01799 find(level_structs[ level ]->begin(), 01800 level_structs[ level ]->end(), (Structure*)s)); 01801 level_spores[ level ]->erase( 01802 find(level_spores[ level ]->begin(), 01803 level_spores[ level ]->end(), s)); 01804 01805 log_prob -= log(alt_d->get_spore_p()); 01806 01807 delete s; 01808 01809 check_levels(); 01810 } 01811 01812 01819 void Alternaria::replace_spore_with_apical_hypha 01820 ( 01821 Spore* spore, 01822 Apical_hypha* hypha 01823 ) 01824 throw (Arg_error) 01825 { 01826 size_t level = spore->get_level(); 01827 01828 ensure_level_space(level); 01829 01830 if (find(level_structs[ level ]->begin(), 01831 level_structs[ level ]->end(), spore) 01832 == level_structs[ level ]->end()) 01833 { 01834 throw Arg_error("Cannot find spore to replace"); 01835 } 01836 01837 spore->replace(hypha); 01838 01839 if (!(hypha->get_apical())) 01840 { 01841 replace(level_terminals[ level ]->begin(), 01842 level_terminals[ level ]->end(), 01843 (Structure*)spore, (Structure*)hypha); 01844 } 01845 level_structs[ level ]->erase( 01846 find(level_structs[ level ]->begin(), 01847 level_structs[ level ]->end(), (Structure*)spore)); 01848 level_spores[ level ]->erase( 01849 find(level_spores[ level ]->begin(), 01850 level_spores[ level ]->end(), (Structure*)spore)); 01851 01852 log_prob -= log(alt_d->get_spore_p()); 01853 01854 delete spore; 01855 01856 if (!(hypha->get_parent())) 01857 { 01858 root = 0; 01859 set_root(hypha); 01860 } 01861 01862 level_structs[ level ]->push_back(hypha); 01863 level_apical_hypha[ level ]->push_back(hypha); 01864 01865 log_prob += log(alt_d->get_apical_hypha_p()); 01866 01867 check_levels(); 01868 } 01869 01870 01878 void Alternaria::split_spore_into_2_apical 01879 ( 01880 Spore* spore, 01881 const Apical_hypha* rvals_1, 01882 const Apical_hypha* rvals_2 01883 ) 01884 throw (Arg_error) 01885 { 01886 size_t level = spore->get_level(); 01887 01888 ensure_level_space(level); 01889 01890 if (find(level_structs[ level ]->begin(), 01891 level_structs[ level ]->end(), spore) 01892 == level_structs[ level ]->end()) 01893 { 01894 throw Arg_error("Cannot find spore to split"); 01895 } 01896 01897 Apical_hypha* split_1 = spore->split_into_apical(rvals_1, rvals_2); 01898 Apical_hypha* split_2 = dynamic_cast<Apical_hypha*>(split_1->get_apical()); 01899 assert(split_2); 01900 01901 if (!(split_2->get_apical())) 01902 { 01903 replace(level_terminals[ level ]->begin(), 01904 level_terminals[ level ]->end(), 01905 (Structure*)spore, (Structure*)split_2); 01906 } 01907 level_structs[ level ]->erase( 01908 find(level_structs[ level ]->begin(), 01909 level_structs[ level ]->end(), (Structure*)spore)); 01910 level_spores[ level ]->erase( 01911 find(level_spores[ level ]->begin(), 01912 level_spores[ level ]->end(), (Structure*)spore)); 01913 01914 log_prob -= log(alt_d->get_spore_p()); 01915 01916 delete spore; 01917 01918 if (!(split_1->get_parent())) 01919 { 01920 root = 0; 01921 set_root(split_1); 01922 } 01923 01924 level_structs[ level ]->push_back(split_1); 01925 level_structs[ level ]->push_back(split_2); 01926 level_apical_hypha[ level ]->push_back(split_1); 01927 level_apical_hypha[ level ]->push_back(split_2); 01928 01929 log_prob += log(alt_d->get_apical_hypha_p()); 01930 log_prob += log(alt_d->get_apical_hypha_p()); 01931 01932 check_levels(); 01933 } 01934 01935 01943 void Alternaria::split_spore_into_spore 01944 ( 01945 Spore* s, 01946 const Spore* rvals_1, 01947 const Spore* rvals_2 01948 ) 01949 throw (Arg_error) 01950 { 01951 size_t level = s->get_level(); 01952 01953 ensure_level_space(level); 01954 01955 if (find(level_structs[ level ]->begin(), 01956 level_structs[ level ]->end(), s) 01957 == level_structs[ level ]->end()) 01958 { 01959 throw Arg_error("Cannot find spore to split"); 01960 } 01961 01962 Spore* split = s->split_into_apical(rvals_1, rvals_2); 01963 if (!(split->get_apical())) 01964 { 01965 replace(level_terminals[ level ]->begin(), 01966 level_terminals[ level ]->end(), 01967 (Structure*)s, (Structure*)split); 01968 } 01969 01970 level_structs[ level ]->push_back(split); 01971 level_spores[ level ]->push_back(split); 01972 01973 log_prob += log(alt_d->get_spore_p()); 01974 01975 check_levels(); 01976 } 01977 01978 01987 void Alternaria::merge_spore_with_spore 01988 ( 01989 Spore* s, 01990 const Spore* rvals 01991 ) 01992 throw (Arg_error) 01993 { 01994 size_t level = s->get_level(); 01995 01996 ensure_level_space(level); 01997 01998 if (find(level_structs[ level ]->begin(), 01999 level_structs[ level ]->end(), s) 02000 == level_structs[ level ]->end()) 02001 { 02002 throw Arg_error("Cannot find spore to merge"); 02003 } 02004 02005 Spore* merged = s->merge_with_apical(rvals); 02006 02007 if (!(s->get_apical())) 02008 { 02009 replace(level_terminals[ level ]->begin(), 02010 level_terminals[ level ]->end(), 02011 (Structure*)merged, (Structure*)s); 02012 } 02013 level_structs[ level ]->erase( 02014 find(level_structs[ level ]->begin(), 02015 level_structs[ level ]->end(), (Structure*)merged)); 02016 level_spores[ level ]->erase( 02017 find(level_spores[ level ]->begin(), 02018 level_spores[ level ]->end(), (Structure*)merged)); 02019 02020 log_prob -= log(alt_d->get_spore_p()); 02021 02022 delete merged; 02023 02024 check_levels(); 02025 } 02026 02027 02036 void Alternaria::read(std::istream& in) throw (IO_error, Arg_error) 02037 { 02038 list<Printed_structure*> printed_structs; 02039 list<Printed_apical_structure*> printed_apicals; 02040 list<Printed_lateral_structure*> printed_laterals; 02041 02042 log_prob = 0; 02043 02044 while (in.peek() != EOF) 02045 { 02046 Printed_apical_structure* apical; 02047 Printed_lateral_structure* lateral; 02048 02049 if (Printed_structure::is_on_istream(in, Apical_hypha::type_str())) 02050 { 02051 apical = new Printed_apical_hypha(in, apical_hypha_d); 02052 printed_structs.push_back(apical); 02053 printed_apicals.push_back(apical); 02054 02055 log_prob += log(alt_d->get_apical_hypha_p()); 02056 } 02057 else if (Printed_structure::is_on_istream(in, 02058 Lateral_hypha::type_str())) 02059 { 02060 lateral = new Printed_lateral_hypha(in, lateral_hypha_1_d, 02061 lateral_hypha_n_d); 02062 printed_structs.push_back(lateral); 02063 printed_laterals.push_back(lateral); 02064 02065 double p; 02066 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 02067 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 02068 double spore_p = alt_d->get_spore_p(); 02069 double apical_hypha_p = alt_d->get_apical_hypha_p(); 02070 double num_levels_p = alt_d->get_num_levels_p(); 02071 02072 size_t level = lateral->get_level(); 02073 02074 // Note that the level must be > 0. 02075 if (level == 1) 02076 { 02077 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 02078 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, level-1); 02079 p /= p + apical_hypha_p; 02080 } 02081 else 02082 { 02083 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-2); 02084 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, level-1); 02085 p /= p + spore_p + apical_hypha_p; 02086 } 02087 02088 log_prob += (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 02089 } 02090 else if (Printed_structure::is_on_istream(in, Spore::type_str())) 02091 { 02092 apical = new Printed_spore(in, spore_d); 02093 printed_structs.push_back(apical); 02094 printed_apicals.push_back(apical); 02095 02096 log_prob += log(alt_d->get_spore_p()); 02097 } 02098 else 02099 { 02100 throw Arg_error("Contains an unknown structure type"); 02101 } 02102 } 02103 02104 Printed_structure* printed_root = 0; 02105 list<Printed_structure*>::const_iterator it; 02106 02107 for (it = printed_structs.begin(); it != printed_structs.end(); it++) 02108 { 02109 if ((*it)->get_parent() == 0) 02110 { 02111 printed_root = (*it); 02112 break; 02113 } 02114 } 02115 02116 if (!printed_root) 02117 { 02118 throw Arg_error("No root in structures to read"); 02119 } 02120 02121 try 02122 { 02123 root = printed_root->recursively_convert(0, printed_apicals.begin(), 02124 printed_apicals.end(), printed_laterals.begin(), 02125 printed_laterals.end()); 02126 if (root) 02127 { 02128 build_levels(root); 02129 } 02130 } 02131 catch (Arg_error e) 02132 { 02133 delete root; 02134 for (it = printed_structs.begin(); it != printed_structs.end(); it++) 02135 { 02136 delete *it; 02137 } 02138 throw e; 02139 } 02140 02141 for (it = printed_structs.begin(); it != printed_structs.end(); it++) 02142 { 02143 delete *it; 02144 } 02145 } 02146 02147 02155 void Alternaria::build_levels(Structure* s) 02156 { 02157 size_t level = s->get_level(); 02158 02159 ensure_level_space(level); 02160 02161 level_structs[ level ]->push_back(s); 02162 02163 if (dynamic_cast<Apical_hypha*>(s)) 02164 { 02165 level_apical_hypha[ level ]->push_back((Apical_hypha*)s); 02166 } 02167 else if (dynamic_cast<Lateral_hypha*>(s)) 02168 { 02169 level_lateral_hypha[ level ]->push_back((Lateral_hypha*)s); 02170 } 02171 else if (dynamic_cast<Spore*>(s)) 02172 { 02173 level_spores[ level ]->push_back((Spore*)s); 02174 } 02175 02176 Structure* apical = s->get_apical(); 02177 if (apical) 02178 { 02179 assert(level == s->get_apical()->get_level()); 02180 build_levels(s->get_apical()); 02181 } 02182 else 02183 { 02184 level_terminals[ level ]->push_back(s); 02185 } 02186 02187 list<Lateral_structure*> laterals = s->get_laterals(); 02188 for (list<Lateral_structure*>::iterator it = laterals.begin(); 02189 it != laterals.end(); it++) 02190 { 02191 assert((level+1) == (*it)->get_level()); 02192 build_levels(*it); 02193 } 02194 } 02195 02196 02198 void Alternaria::check_levels() 02199 { 02200 for (size_t i = 0; i < level_structs.size(); i++) 02201 { 02202 for (size_t j = 0; j < level_structs.at(i)->size(); j++) 02203 { 02204 assert(level_structs.at(i)->at(j)->get_level() == i); 02205 } 02206 } 02207 for (size_t i = 0; i < level_lateral_hypha.size(); i++) 02208 { 02209 for (size_t j = 0; j < level_lateral_hypha.at(i)->size(); j++) 02210 { 02211 assert(level_lateral_hypha.at(i)->at(j)->get_level() == i); 02212 } 02213 } 02214 for (size_t i = 0; i < level_apical_hypha.size(); i++) 02215 { 02216 for (size_t j = 0; j < level_apical_hypha.at(i)->size(); j++) 02217 { 02218 assert(level_apical_hypha.at(i)->at(j)->get_level() == i); 02219 } 02220 } 02221 } 02222 02223 02225 void Alternaria::check_c_1() const throw (Arg_error) 02226 { 02227 if (c_1 < 0) 02228 { 02229 throw Arg_error("C_1 < 0"); 02230 } 02231 } 02232 02233 02235 void Alternaria::ensure_level_space(size_t level) 02236 { 02237 while (level_structs.size() <= level) 02238 { 02239 vector<Structure*>* structs = new vector<Structure*>(); 02240 structs->reserve(200); 02241 level_structs.push_back(structs); 02242 02243 vector<Apical_hypha*>* a_hypha = new vector<Apical_hypha*>(); 02244 a_hypha->reserve(200); 02245 level_apical_hypha.push_back(a_hypha); 02246 02247 vector<Lateral_hypha*>* l_hypha = new vector<Lateral_hypha*>(); 02248 l_hypha->reserve(200); 02249 level_lateral_hypha.push_back(l_hypha); 02250 02251 vector<Spore*>* spores = new vector<Spore*>(); 02252 spores->reserve(200); 02253 level_spores.push_back(spores); 02254 02255 structs = new vector<Structure*>(); 02256 structs->reserve(200); 02257 level_terminals.push_back(structs); 02258 } 02259 } 02260 02261 02268 void Alternaria::recursively_update_level(Structure* s, size_t old_level) 02269 throw (Arg_error) 02270 { 02271 size_t new_level = s->get_level(); 02272 02273 if (old_level == new_level) 02274 return; 02275 02276 ensure_level_space((old_level > new_level) ? old_level : new_level); 02277 02278 if (find(level_structs[ old_level ]->begin(), 02279 level_structs[ old_level ]->end(), s) 02280 == level_structs[ old_level ]->end()) 02281 { 02282 ostringstream ost; 02283 ost << "Structure " << s->get_id() << " not in level " << old_level; 02284 throw Arg_error(ost.str()); 02285 } 02286 02287 level_structs[ old_level ]->erase( 02288 find(level_structs[ old_level ]->begin(), 02289 level_structs[ old_level ]->end(), s)); 02290 level_structs[ new_level ]->push_back(s); 02291 02292 if (level_terminals[ old_level ]->size() > 0 && 02293 find(level_terminals[ old_level ]->begin(), 02294 level_terminals[ old_level ]->end(), s) 02295 != level_terminals[ old_level ]->end()) 02296 { 02297 level_terminals[ old_level ]->erase( 02298 find(level_terminals[ old_level ]->begin(), 02299 level_terminals[ old_level ]->end(), s)); 02300 level_terminals[ new_level ]->push_back(s); 02301 } 02302 02303 if (dynamic_cast<Apical_hypha*>(s)) 02304 { 02305 level_apical_hypha[ old_level ]->erase( 02306 find(level_apical_hypha[ old_level ]->begin(), 02307 level_apical_hypha[ old_level ]->end(), (Apical_hypha*)s)); 02308 level_apical_hypha[ new_level ]->push_back((Apical_hypha*)s); 02309 } 02310 else if (dynamic_cast<Lateral_hypha*>(s)) 02311 { 02312 level_lateral_hypha[ old_level ]->erase( 02313 find(level_lateral_hypha[ old_level ]->begin(), 02314 level_lateral_hypha[ old_level ]->end(), (Lateral_hypha*)s)); 02315 level_lateral_hypha[ new_level ]->push_back((Lateral_hypha*)s); 02316 02317 double p; 02318 double lateral_hypha_1_p = alt_d->get_lateral_hypha_1_p(); 02319 double lateral_hypha_n_p = alt_d->get_lateral_hypha_n_p(); 02320 double spore_p = alt_d->get_spore_p(); 02321 double apical_hypha_p = alt_d->get_apical_hypha_p(); 02322 double num_levels_p = alt_d->get_num_levels_p(); 02323 02324 // Note that the old_level must be > 0. 02325 if (old_level == 1) 02326 { 02327 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 02328 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, old_level-1); 02329 p /= p + apical_hypha_p; 02330 } 02331 else 02332 { 02333 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, old_level-2); 02334 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, old_level-1); 02335 p /= p + spore_p + apical_hypha_p; 02336 } 02337 log_prob -= (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 02338 02339 // Note that the new_level must be > 0. 02340 if (new_level == 1) 02341 { 02342 //p = lateral_hypha_1_p / (lateral_hypha_1_p + apical_hypha_p); 02343 p = lateral_hypha_1_p*geometric_pmf_d(num_levels_p, new_level-1); 02344 p /= p + apical_hypha_p; 02345 } 02346 else 02347 { 02348 //p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, new_level-2); 02349 p = lateral_hypha_n_p*geometric_pmf_d(num_levels_p, new_level-1); 02350 p /= p + spore_p + apical_hypha_p; 02351 } 02352 log_prob += (p < JWSC_MIN_LOG_ARG) ? log(JWSC_MIN_LOG_ARG) : log(p); 02353 } 02354 else if (dynamic_cast<Spore*>(s)) 02355 { 02356 level_spores[ old_level ]->erase( 02357 find(level_spores[ old_level ]->begin(), 02358 level_spores[ old_level ]->end(), (Spore*)s)); 02359 level_spores[ new_level ]->push_back((Spore*)s); 02360 } 02361 else 02362 { 02363 ostringstream ost; 02364 ost << "Structure " << s->get_id() << " is unknown type"; 02365 std::cerr << "BUG: Alternaria::recursively_update_level: " 02366 << ost.str() << '\n'; 02367 assert(0); 02368 } 02369 02370 if (s->get_apical()) 02371 { 02372 recursively_update_level(s->get_apical(), old_level); 02373 } 02374 for (list<Lateral_structure*>::iterator it = s->get_laterals().begin(); 02375 it != s->get_laterals().end(); it++) 02376 { 02377 recursively_update_level(*it, old_level+1); 02378 } 02379 } 02380 02381 /* -------------------------------------------------------------------------- */ 02382 02383 02384 02385 02386 02387 02388 02389 02390 02391 02392 02393 /* ----------------------- Alternaria_model_density ----------------------- */ 02394 02415 #if defined ALTERNARIA_HAVE_FFTW3F 02416 Alternaria_model* Alternaria_model_density::sample 02417 ( 02418 size_t N, 02419 float centroid_x, 02420 float centroid_y, 02421 float centroid_z, 02422 float theta, 02423 float psi, 02424 size_t base_level, 02425 const Spore_density* spore_d, 02426 const Apical_hypha_density* apical_hypha_d, 02427 const Lateral_hypha_density* lateral_hypha_1_d, 02428 const Lateral_hypha_density* lateral_hypha_n_d, 02429 const PSF_model* psf, 02430 const Imaging_model* imaging 02431 ) 02432 const throw (Arg_error) 02433 { 02434 Alternaria_model* alternaria = new Alternaria_model(sample_c_1(), theta, 02435 psi, base_level, this, spore_d, apical_hypha_d, lateral_hypha_1_d, 02436 lateral_hypha_n_d, psf, imaging); 02437 02438 try 02439 { 02440 generate_structure(alternaria, N, centroid_x, centroid_y, centroid_z); 02441 } 02442 catch (Arg_error e) 02443 { 02444 delete alternaria; 02445 throw e; 02446 } 02447 02448 alternaria->update_scene(psf, imaging); 02449 02450 return alternaria; 02451 } 02452 #endif 02453 02454 /* -------------------------------------------------------------------------- */ 02455 02456 02457 02458 02459 02460 02461 02462 02463 02464 02465 /* ---------------------------- Alternaria_model -------------------------- */ 02466 02482 #if defined ALTERNARIA_HAVE_FFTW3F 02483 Alternaria_model::Alternaria_model 02484 ( 02485 float c_1, 02486 float theta, 02487 float psi, 02488 size_t base_level, 02489 const Alternaria_density* alt_d, 02490 const Spore_density* spore_d, 02491 const Apical_hypha_density* apical_hypha_d, 02492 const Lateral_hypha_density* lateral_hypha_1_d, 02493 const Lateral_hypha_density* lateral_hypha_n_d, 02494 const PSF_model* psf, 02495 const Imaging_model* imaging 02496 ) 02497 throw (Arg_error) 02498 : Alternaria(c_1, theta, psi, base_level, alt_d, spore_d, apical_hypha_d, 02499 lateral_hypha_1_d, lateral_hypha_n_d) 02500 { 02501 scene = 0; 02502 s_1 = 0; 02503 s_2 = 0; 02504 s_3 = 0; 02505 s_4 = 0; 02506 02507 update_scene(psf, imaging); 02508 } 02509 #endif 02510 02511 02513 #if defined ALTERNARIA_HAVE_FFTW3F 02514 Alternaria_model::Alternaria_model(const Alternaria_model& model) 02515 : Alternaria(model) 02516 { 02517 scene = 0; 02518 if (model.scene) 02519 { 02520 copy_matblock_f(&scene, model.scene); 02521 } 02522 s_1 = 0; 02523 if (model.s_1) 02524 { 02525 copy_matblock_cf(&s_1, model.s_1); 02526 } 02527 s_2 = 0; 02528 if (model.s_2) 02529 { 02530 copy_matblock_cf(&s_2, model.s_2); 02531 } 02532 s_3 = 0; 02533 if (model.s_3) 02534 { 02535 copy_matblock_f(&s_3, model.s_3); 02536 } 02537 s_4 = 0; 02538 if (model.s_4) 02539 { 02540 copy_matblock_cf(&s_4, model.s_4); 02541 } 02542 } 02543 #endif 02544 02545 02551 #if defined ALTERNARIA_HAVE_FFTW3F 02552 Alternaria_model::Alternaria_model 02553 ( 02554 const Alternaria& alt, 02555 const PSF_model* psf, 02556 const Imaging_model* imaging 02557 ) 02558 : Alternaria(alt) 02559 { 02560 scene = 0; 02561 s_1 = 0; 02562 s_2 = 0; 02563 s_3 = 0; 02564 s_4 = 0; 02565 02566 update_scene(psf, imaging); 02567 } 02568 #endif 02569 02570 02587 #if defined ALTERNARIA_HAVE_FFTW3F 02588 Alternaria_model::Alternaria_model 02589 ( 02590 const char* fname, 02591 const Alternaria_density* alt_d, 02592 const Spore_density* spore_d, 02593 const Apical_hypha_density* apical_hypha_d, 02594 const Lateral_hypha_density* lateral_hypha_1_d, 02595 const Lateral_hypha_density* lateral_hypha_n_d, 02596 const PSF_model* psf, 02597 const Imaging_model* imaging 02598 ) 02599 throw (IO_error, Arg_error) 02600 : Alternaria(0.0f, 0, 0, 0, alt_d, spore_d, apical_hypha_d, lateral_hypha_1_d, 02601 lateral_hypha_n_d) 02602 { 02603 ostringstream ost; 02604 istringstream ist; 02605 ifstream in; 02606 02607 scene = 0; 02608 s_1 = 0; 02609 s_2 = 0; 02610 s_3 = 0; 02611 s_4 = 0; 02612 02613 in.open(fname); 02614 if (in.fail()) 02615 { 02616 ost << fname << ": Could not open file"; 02617 throw IO_error(ost.str()); 02618 } 02619 02620 const char* member_value; 02621 02622 if (!(member_value = get_member_value("C_1", in))) 02623 { 02624 ost << fname << ": Missing C_1"; 02625 throw Arg_error(ost.str()); 02626 } 02627 ist.str(member_value); 02628 ist >> c_1; 02629 if (ist.fail()) 02630 { 02631 ost << fname << ": Invalid C_1"; 02632 throw Arg_error(ost.str()); 02633 } 02634 ist.clear(std::ios_base::goodbit); 02635 02636 check_c_1(); 02637 02638 if (!(member_value = get_member_value("Theta", in))) 02639 { 02640 ost << fname << ": Missing theta"; 02641 throw Arg_error(ost.str()); 02642 } 02643 ist.str(member_value); 02644 ist >> theta; 02645 if (ist.fail()) 02646 { 02647 ost << fname << ": Invalid theta"; 02648 throw Arg_error(ost.str()); 02649 } 02650 ist.clear(std::ios_base::goodbit); 02651 02652 if (!(member_value = get_member_value("Psi", in))) 02653 { 02654 ost << fname << ": Missing psi"; 02655 throw Arg_error(ost.str()); 02656 } 02657 ist.str(member_value); 02658 ist >> psi; 02659 if (ist.fail()) 02660 { 02661 ost << fname << ": Invalid psi"; 02662 throw Arg_error(ost.str()); 02663 } 02664 ist.clear(std::ios_base::goodbit); 02665 02666 if (!(member_value = get_member_value("Level", in))) 02667 { 02668 ost << fname << ": Missing base level"; 02669 throw Arg_error(ost.str()); 02670 } 02671 ist.str(member_value); 02672 ist >> base_level; 02673 if (ist.fail()) 02674 { 02675 ost << fname << ": Invalid base level"; 02676 throw Arg_error(ost.str()); 02677 } 02678 ist.clear(std::ios_base::goodbit); 02679 02680 if (!(member_value = get_member_value("Log Prob", in))) 02681 { 02682 ost << fname << ": Missing log probability"; 02683 throw Arg_error(ost.str()); 02684 } 02685 ist.str(member_value); 02686 ist >> log_prob; 02687 if (ist.fail()) 02688 { 02689 ost << fname << ": Invalid log probability"; 02690 throw Arg_error(ost.str()); 02691 } 02692 02693 try 02694 { 02695 read(in); 02696 } 02697 catch (Arg_error e) 02698 { 02699 ost << fname << ": " << e.get_msg(); 02700 throw Arg_error(ost.str()); 02701 } 02702 catch (IO_error e) 02703 { 02704 ost << fname << ": " << e.get_msg(); 02705 throw IO_error(ost.str()); 02706 } 02707 02708 in.close(); 02709 if (in.fail()) 02710 { 02711 ost << fname << ": Could not close file"; 02712 throw IO_error(ost.str()); 02713 } 02714 02715 update_scene(psf, imaging); 02716 } 02717 #endif 02718 02719 02721 #if defined ALTERNARIA_HAVE_FFTW3F 02722 Alternaria_model::~Alternaria_model() 02723 { 02724 free_matblock_f(scene); 02725 free_matblock_cf(s_1); 02726 free_matblock_cf(s_2); 02727 free_matblock_f(s_3); 02728 free_matblock_cf(s_4); 02729 } 02730 #endif 02731 02732 02734 #if defined ALTERNARIA_HAVE_FFTW3F 02735 Alternaria_model* Alternaria_model::clone() const 02736 { 02737 return new Alternaria_model(*this); 02738 } 02739 #endif 02740 02741 02748 #if defined ALTERNARIA_HAVE_FFTW3F 02749 Alternaria_model& Alternaria_model::operator= 02750 ( 02751 const Alternaria_model& alternaria 02752 ) 02753 { 02754 Alternaria::operator=(alternaria); 02755 02756 if (alternaria.scene) 02757 { 02758 copy_matblock_f(&scene, alternaria.scene); 02759 } 02760 if (alternaria.s_1) 02761 { 02762 copy_matblock_cf(&s_1, alternaria.s_1); 02763 } 02764 if (alternaria.s_2) 02765 { 02766 copy_matblock_cf(&s_2, alternaria.s_2); 02767 } 02768 if (alternaria.s_3) 02769 { 02770 copy_matblock_f(&s_3, alternaria.s_3); 02771 } 02772 if (alternaria.s_4) 02773 { 02774 copy_matblock_cf(&s_4, alternaria.s_4); 02775 } 02776 02777 return *this; 02778 } 02779 #endif 02780 02781 02792 #if defined ALTERNARIA_HAVE_FFTW3F 02793 double Alternaria_model::calc_log_likelihood 02794 ( 02795 const PSF_model* psf, 02796 const Imaging_model* imaging, 02797 const jwsc::Matblock_f* data, 02798 float data_avg 02799 ) 02800 const throw (Arg_error) 02801 { 02802 static const double log_c = -0.91893853321; 02803 02804 uint32_t num_mats = imaging->get_window()->get_num_imgs(); 02805 uint32_t num_rows = imaging->get_window()->get_num_rows(); 02806 uint32_t num_cols = imaging->get_window()->get_num_cols(); 02807 02808 uint32_t fft_padding = psf->get_padding()->fft; 02809 uint32_t conv_padding = psf->get_padding()->conv; 02810 02811 uint32_t scene_start_mat = fft_padding + conv_padding; 02812 uint32_t scene_start_row = fft_padding + conv_padding; 02813 uint32_t scene_start_col = fft_padding + conv_padding; 02814 02815 uint32_t data_start_mat = imaging->get_window()->get_img(); 02816 uint32_t data_start_row = imaging->get_window()->get_row(); 02817 uint32_t data_start_col = imaging->get_window()->get_col(); 02818 02819 double ll = 0; 02820 double c_2 = imaging->get_c_2(); 02821 02822 uint32_t scene_mat = scene_start_mat; 02823 uint32_t data_mat = data_start_mat; 02824 while (scene_mat < (num_mats+scene_start_mat)) 02825 { 02826 uint32_t scene_row = scene_start_row; 02827 uint32_t data_row = data_start_row; 02828 while (scene_row < (num_rows+scene_start_row)) 02829 { 02830 uint32_t scene_col = scene_start_col; 02831 uint32_t data_col = data_start_col; 02832 while (scene_col < (num_cols+scene_start_col)) 02833 { 02834 if (data_mat >= data->num_mats || 02835 data_row >= data->num_rows || 02836 data_col >= data->num_cols) 02837 { 02838 throw Arg_error("Data not large enough for window"); 02839 } 02840 02841 double x = data->elts[data_mat][data_row][data_col]; 02842 double mu = scene->elts[scene_mat][scene_row][scene_col]; 02843 double sigma = sqrt(c_1*fabs(x - data_avg) + c_2*x); 02844 02845 if (sigma < 1.0e-10) 02846 { 02847 std::cerr << "calc_log_likelihood: Sigma too small: " 02848 << sigma << '\n'; 02849 sigma = 1.0e-10; 02850 } 02851 02852 ll += log_c - log(sigma) - 0.5*(x - mu)*(x - mu)/(sigma*sigma); 02853 02854 scene_col++; 02855 data_col++; 02856 } 02857 02858 scene_row++; 02859 data_row++; 02860 } 02861 02862 scene_mat++; 02863 data_mat++; 02864 } 02865 02866 #if defined ALTERNARIA_HAVE_ISNAN && defined ALTERNARIA_HAVE_ISINF 02867 assert(!isnan(ll) && !isinf(ll)); 02868 #endif 02869 02870 return ll; 02871 } 02872 #endif 02873 02874 02884 #if defined ALTERNARIA_HAVE_FFTW3F 02885 bool Alternaria_model::update_scene 02886 ( 02887 const PSF_model* psf, 02888 const Imaging_model* imaging 02889 ) 02890 { 02891 float x_scale = imaging->get_scale()->get_x(); 02892 float y_scale = imaging->get_scale()->get_y(); 02893 float z_scale = imaging->get_scale()->get_z(); 02894 02895 const Imaging_window* window = imaging->get_window(); 02896 const PSF_padding* padding = psf->get_padding(); 02897 02898 uint32_t num_mats = window->get_num_imgs() 02899 + 2*(padding->conv + padding->fft); 02900 uint32_t num_rows = window->get_num_rows() 02901 + 2*(padding->conv + padding->fft); 02902 uint32_t num_cols = window->get_num_cols() 02903 + 2*(padding->conv + padding->fft); 02904 02905 create_zero_matblock_f(&scene, num_mats, num_rows, num_cols); 02906 02907 float x = x_scale*((float)window->get_col() - padding->conv - padding->fft); 02908 float y = y_scale*((float)window->get_row() - padding->conv - padding->fft); 02909 float z = z_scale*((float)window->get_img() - padding->conv - padding->fft); 02910 02911 bool intersect = false; 02912 02913 if (root) 02914 { 02915 intersect = root->recursively_draw_in_matblock_f(scene, x, y, z, 02916 x_scale, y_scale, z_scale); 02917 } 02918 02919 float bg = imaging->get_bg(); 02920 02921 for (uint32_t mat = 0; mat < num_mats; mat++) 02922 { 02923 for (uint32_t row = 0; row < num_rows; row++) 02924 { 02925 for (uint32_t col = 0; col < num_cols; col++) 02926 { 02927 if ((mat < padding->fft) || (mat > num_mats-padding->fft-1) || 02928 (row < padding->fft) || (row > num_rows-padding->fft-1) || 02929 (col < padding->fft) || (col > num_cols-padding->fft-1)) 02930 { 02931 scene->elts[ mat ][ row ][ col ] = bg; 02932 } 02933 else 02934 { 02935 float id = floor(scene->elts[ mat ][ row ][ col ]); 02936 float opacity = scene->elts[ mat ][ row ][ col ] - id; 02937 02938 scene->elts[ mat ][ row ][ col ] = bg * (1 - opacity); 02939 } 02940 } 02941 } 02942 } 02943 02944 if (root && psf->get_h()) 02945 { 02946 assert(convolve_matblock_fft_scratch_f(&scene, scene, psf->get_h(), 02947 &s_1, &s_2, &s_3, &s_4) == 0); 02948 } 02949 02950 return intersect; 02951 } 02952 #endif 02953 02954 02963 #if defined ALTERNARIA_HAVE_FFTW3F 02964 void Alternaria_model::write_scene 02965 ( 02966 const char* fname_fmt, 02967 const PSF_model* psf 02968 ) 02969 const throw (IO_error) 02970 { 02971 if (scene == 0) 02972 return; 02973 02974 uint32_t scene_num_mats = scene->num_mats; 02975 uint32_t scene_num_rows = scene->num_rows; 02976 uint32_t scene_num_cols = scene->num_cols; 02977 02978 const PSF_padding* padding = psf->get_padding(); 02979 02980 uint32_t num_mats = scene_num_mats - 2*(padding->fft + padding->conv); 02981 uint32_t num_rows = scene_num_rows - 2*(padding->fft + padding->conv); 02982 uint32_t num_cols = scene_num_cols - 2*(padding->fft + padding->conv); 02983 02984 uint32_t start_mat = padding->fft + padding->conv; 02985 uint32_t start_row = padding->fft + padding->conv; 02986 uint32_t start_col = padding->fft + padding->conv; 02987 02988 Matblock_f* scene_no_pad = 0; 02989 copy_matblock_block_f(&scene_no_pad, scene, start_mat, start_row, start_col, 02990 num_mats, num_rows, num_cols); 02991 02992 Imgblock_f* imgs = 0; 02993 create_imgblock_from_matblock_f(&imgs, scene_no_pad); 02994 free_matblock_f(scene_no_pad); 02995 02996 Error* e; 02997 if ((e = write_imgblock_numbered_f(imgs, fname_fmt)) != 0) 02998 { 02999 IO_error ex(e->msg); 03000 free_error(e); 03001 throw ex; 03002 } 03003 free_imgblock_f(imgs); 03004 } 03005 #endif 03006 /* -------------------------------------------------------------------------- */