Alternaria
fit cylinders and ellipsoids to fungus
alternaria_model.cpp
Go to the documentation of this file.
00001 /*
00002  * This work is licensed under a Creative Commons 
00003  * Attribution-Noncommercial-Share Alike 3.0 United States License.
00004  * 
00005  *    http://creativecommons.org/licenses/by-nc-sa/3.0/us/
00006  * 
00007  * You are free:
00008  * 
00009  *    to Share - to copy, distribute, display, and perform the work
00010  *    to Remix - to make derivative works
00011  * 
00012  * Under the following conditions:
00013  * 
00014  *    Attribution. You must attribute the work in the manner specified by the
00015  *    author or licensor (but not in any way that suggests that they endorse you
00016  *    or your use of the work).
00017  * 
00018  *    Noncommercial. You may not use this work for commercial purposes.
00019  * 
00020  *    Share Alike. If you alter, transform, or build upon this work, you may
00021  *    distribute the resulting work only under the same or similar license to
00022  *    this one.
00023  * 
00024  * For any reuse or distribution, you must make clear to others the license
00025  * terms of this work. The best way to do this is by including this header.
00026  * 
00027  * Any of the above conditions can be waived if you get permission from the
00028  * copyright holder.
00029  * 
00030  * Apart from the remix rights granted under this license, nothing in this
00031  * license impairs or restricts the author's moral rights.
00032  */
00033 
00034 
00046 #include <config.h>
00047 
00048 #include <cassert>
00049 #include <cmath>
00050 #include <iostream>
00051 #include <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 /* -------------------------------------------------------------------------- */