Alternaria
fit cylinders and ellipsoids to fungus
alternaria.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 
00240 #include <config.h>
00241 
00242 #include <iostream>
00243 #include <sstream>
00244 #include <cstdlib>
00245 #include <cstdio>
00246 #include <cmath>
00247 
00248 #include <inttypes.h>
00249 
00250 #include <jwsc/config.h>
00251 #include <jwsc/math/constants.h>
00252 #include <jwsc/matblock/matblock.h>
00253 #include <jwsc/imgblock/imgblock.h>
00254 #include <jwsc/imgblock/imgblock_io.h>
00255 #include <jwsc/imgblock/imgblock_util.h>
00256 
00257 #ifdef JWSC_HAVE_FFTW3_H
00258 #include <fftw3.h>
00259 #endif
00260 
00261 #include <jwsc++/base/exception.h>
00262 #include <jwsc++/base/option.h>
00263 
00264 #include "imaging_model.h"
00265 #include "psf_model.h"
00266 #include "structure.h"
00267 #include "spore.h"
00268 #include "hypha.h"
00269 #include "alternaria_model.h"
00270 #include "sampler.h"
00271 #include "imaging_moves.h"
00272 #include "psf_moves.h"
00273 #include "alternaria_moves.h"
00274 #include "dd_spore.h"
00275 
00276 
00277 /* Program defaults. */
00278 #define  SEED              2537984
00279 #define  MOVE_INFO_FNAME   "move.info"
00280 #define  BEST_INFO_FNAME   "best.info"
00281 #define  ITERATIONS        10
00282 #define  RES_IMG           1.0f
00283 #define  RES_ROW           1.0f
00284 #define  RES_COL           1.0f
00285 #define  DATA_IMGS_NAMED   false
00286 #define  IMG_IN_FNAME      0
00287 #define  IMG_OUT_FNAME     "imaging.model"
00288 #define  PSF_IN_FNAME      0
00289 #define  PSF_OUT_FNAME     "psf.model"
00290 #define  ALT_IN_FNAME      0
00291 #define  ALT_OUT_FNAME     "alternaria.model"
00292 #define  ALT_PRO_FMT       0
00293 #define  ALT_SCENE_FMT     0
00294 #define  PSF_H_FMT         0
00295 #define  BASE_LEVEL        0
00296 #define  DD_SPORES_FNAME   0
00297 
00298 
00299 using std::cout;
00300 using std::cerr;
00301 using std::ostringstream;
00302 using std::sscanf;
00303 using namespace jwsc;
00304 using jwscxx::base::Options;
00305 using jwscxx::base::Exception;
00306 using jwscxx::base::Arg_error;
00307 using jwscxx::base::IO_error;
00308 
00309 
00311 Options* opts = 0;
00312 
00314 uint32_t seed = SEED;
00315 
00317 const char* move_info_fname = MOVE_INFO_FNAME;
00318 
00320 const char* best_info_fname = BEST_INFO_FNAME;
00321 
00323 uint32_t iterations = ITERATIONS;
00324 
00329 float res_img = RES_IMG;
00330 
00335 float res_row = RES_ROW;
00336 
00341 float res_col = RES_COL;
00342 
00347 bool data_imgs_named = DATA_IMGS_NAMED;
00348 
00350 const char* img_in_fname = IMG_IN_FNAME;
00351 
00353 const char* img_out_fname = IMG_OUT_FNAME;
00354 
00356 const char* psf_in_fname = PSF_IN_FNAME;
00357 
00359 const char* psf_out_fname = PSF_OUT_FNAME;
00360 
00362 const char* alt_in_fname = ALT_IN_FNAME;
00363 
00365 const char* alt_out_fname = ALT_OUT_FNAME;
00366 
00368 const char* alt_pro_fmt = ALT_PRO_FMT;
00369 
00374 const char* alt_scene_fmt = ALT_SCENE_FMT;
00375 
00377 const char* psf_h_fmt = PSF_H_FMT;
00378 
00380 uint32_t base_level = BASE_LEVEL;
00381 
00383 const char* dd_spores_fname = DD_SPORES_FNAME;
00384 
00386 Imaging_window* img_window = 0;
00387 
00389 Imaging_scale* img_scale = 0;
00390 
00392 PSF_padding* padding = 0;
00393 
00395 Imaging_model_density* imaging_d = 0;
00396 
00398 PSF_model_density* psf_d = 0;
00399 
00401 Apical_hypha_density* apical_hypha_d = 0;
00402 
00404 Lateral_hypha_density* lateral_hypha_1_d = 0;
00405 
00407 Lateral_hypha_density* lateral_hypha_n_d = 0;
00408 
00410 Spore_density* spore_d = 0;
00411 
00413 Alternaria_model_density* alt_d = 0;
00414 
00418 bool img_window_set = false;
00419 
00420 
00422 void read_data
00423 (
00424     Matblock_f** data_out, 
00425     int          argc, 
00426     const char** argv, 
00427     int          argi
00428 )
00429 throw (Arg_error)
00430 {
00431     uint32_t    num_imgs;
00432     Imgblock_f* imgs = NULL;
00433     Error*      err;
00434 
00435     /* Read the input Alternaria images. */
00436     if (data_imgs_named)
00437     {
00438         num_imgs = argc - argi;
00439 
00440         if (num_imgs < 1)
00441         {
00442             throw Arg_error("No input images");
00443         }
00444 
00445         if ((err = read_imgblock_named_f(&imgs, &(argv[ argi ]), num_imgs)) 
00446                 != 0)
00447         {
00448             Arg_error ex = Arg_error(err->msg);
00449             delete err;
00450             throw ex;
00451         }
00452     }
00453     else
00454     {
00455         if ((argc - argi) < 2)
00456         {
00457             throw Arg_error("No input image format and count");
00458         }
00459         
00460         const char* input_fname = argv[ argi ];
00461 
00462         if (sscanf(argv[ argi+1 ], "%u", &num_imgs) != 1 || num_imgs <= 0)
00463         {
00464             throw Arg_error("No input image count");
00465         }       
00466 
00467         if ((err = read_imgblock_numbered_f(&imgs, input_fname, num_imgs)) != 0)
00468         {
00469             Arg_error ex = Arg_error(err->msg);
00470             delete err;
00471             throw ex;
00472         }
00473 
00474     }
00475 
00476     assert(down_sample_imgblock_f(&imgs, imgs, res_img, res_row, res_col) == 0);
00477     create_matblock_from_imgblock_f(data_out, imgs, 0.3f, 0.59f, 0.11f);
00478     free_imgblock_f(imgs);
00479 }
00480 
00482 void init_density_centroids() throw (Arg_error)
00483 {
00484     float x_min = img_scale->get_x() * img_window->get_col();
00485     float x_max = x_min + img_scale->get_x()*(img_window->get_num_cols()-1);
00486     float y_min = img_scale->get_y() * img_window->get_row();
00487     float y_max = y_min + img_scale->get_y()*(img_window->get_num_rows()-1);
00488     float z_min = img_scale->get_z() * img_window->get_img();
00489     float z_max = z_min + img_scale->get_z()*(img_window->get_num_imgs()-1);
00490 
00491     spore_d->set_centroid_x(x_min, x_max);
00492     spore_d->set_centroid_y(y_min, y_max);
00493     spore_d->set_centroid_z(z_min, z_max);
00494 
00495     apical_hypha_d->set_centroid_x(x_min, x_max);
00496     apical_hypha_d->set_centroid_y(y_min, y_max);
00497     apical_hypha_d->set_centroid_z(z_min, z_max);
00498 
00499     lateral_hypha_1_d->set_centroid_x(x_min, x_max);
00500     lateral_hypha_1_d->set_centroid_y(y_min, y_max);
00501     lateral_hypha_1_d->set_centroid_z(z_min, z_max);
00502 
00503     lateral_hypha_n_d->set_centroid_x(x_min, x_max);
00504     lateral_hypha_n_d->set_centroid_y(y_min, y_max);
00505     lateral_hypha_n_d->set_centroid_z(z_min, z_max);
00506 }
00507 
00509 void init_sampler_moves(Sampler* sampler) throw (Arg_error)
00510 {
00511     sampler->add_move(new Imaging_bg_move("Bg"));
00512     sampler->add_move(new PSF_move("PSF"));
00513     sampler->add_move(new Apical_hypha_birth_death_move("ApiBirth", 
00514                 "ApiDeath"));
00515     sampler->add_move(new Spore_birth_death_move("SprBirth", "SprDeath"));
00516     sampler->add_move(new Spore_split_merge_spore_move("SprSplit", "SprMerge"));
00517     sampler->add_move(new Spore_transition_apical_move("ApiToSpr", "SprToApi"));
00518     sampler->add_move(new Spore_split_merge_2_apical_move("Spr2Api", "Api2Spr"));
00519     sampler->add_move(new Lateral_hypha_birth_death_move("LatBirth", 
00520                 "LatDeath"));
00521     sampler->add_move(new Apical_hypha_split_merge_apical_move("ApiSplit", 
00522                 "ApiMerge"));
00523     sampler->add_move(new Apical_hypha_split_merge_lateral_move("LatSplit", 
00524                 "LatMerge"));
00525     sampler->add_move(new Structure_resize_move("Resize"));
00526     sampler->add_move(new Structure_rotate_move("Rotate"));
00527     sampler->add_move(new Structure_opacity_move("Opacity"));
00528     sampler->add_move(new Apical_structure_position_move("ApiPosn"));
00529     sampler->add_move(new Lateral_structure_lat_dist_move("LatDist"));
00530 
00531     sampler->normalize_move_probs();
00532 }
00533 
00535 void print_usage(void)
00536 {
00537     cerr << "usage: alternaria OPTIONS [img-%%d num_imgs | img-1 ... img-n]\n";
00538     cerr << "where OPTIONS is one or more of the following:\n";
00539     opts->print(cerr, 33);
00540 }
00541 
00543 void process_help_opt(void)
00544 {   
00545     print_usage();
00546     exit(EXIT_SUCCESS);
00547 }
00548 
00550 void process_version_opt(void)
00551 {
00552     cout << ALTERNARIA_PACKAGE_STRING << "\n";
00553     exit(EXIT_SUCCESS);
00554 }
00555 
00557 void process_options_opt(const char* arg) throw (Arg_error)
00558 {
00559     if (!arg)
00560     {
00561         throw Arg_error("Option 'options' requires an argument");
00562     }
00563     try
00564     {
00565         opts->process(arg);
00566     }
00567     catch (IO_error e)
00568     {
00569         throw Arg_error(e.get_msg());
00570     }
00571 }
00572 
00574 void process_move_info_opt(const char* arg) throw (Arg_error)
00575 {
00576     if (!arg)
00577     {
00578         throw Arg_error("Option 'move-info' requires an argument");
00579     }
00580     move_info_fname = arg;
00581 }
00582 
00584 void process_best_info_opt(const char* arg) throw (Arg_error)
00585 {
00586     if (!arg)
00587     {
00588         throw Arg_error("Option 'best-info' requires an argument");
00589     }
00590     best_info_fname = arg;
00591 }
00592 
00594 #ifdef JWSC_HAVE_FFTW3F_THREADS
00595 void process_threads_opt(const char* arg) throw (Arg_error)
00596 {
00597     uint32_t threads;
00598 
00599     if (!arg)
00600     {
00601         throw Arg_error("Option 'threads' requires an argument");
00602     }
00603     if (sscanf(arg, "%u", &threads) != 1 || threads < 1)
00604     {
00605         throw Arg_error("Option 'threads' must be an integer > 0");
00606     }
00607     if (fftwf_init_threads() == 0)
00608     {
00609         throw Arg_error("Could not initialize FFTW threads");
00610     }
00611     fftwf_plan_with_nthreads(threads);
00612 }
00613 #endif
00614 
00616 void process_iterations_opt(const char* arg) throw (Arg_error)
00617 {
00618     if (!arg)
00619     {
00620         throw Arg_error("Option 'iterations' requires an argument");
00621     }
00622     if (sscanf(arg, "%u", &iterations) != 1)
00623     {
00624         throw Arg_error("Option 'iterations' must be a non-negative integer");
00625     }
00626 }
00627 
00629 void process_resolution_opt(const char* arg) throw (Arg_error)
00630 {
00631     if (!arg)
00632     {
00633         throw Arg_error("Option 'resolution' requires an argument");
00634     }
00635     if (sscanf(arg, "%f,%f,%f", &res_col, &res_row, &res_img) != 3)
00636     {
00637         throw Arg_error("Option 'resolution' has format col,row,img");
00638     }
00639     if (res_col <= 0 || res_col > 1 || res_row <= 0 || res_row > 1
00640             || res_img <= 0 || res_img > 1)
00641     {
00642         throw Arg_error("Option 'resolution' must be in (0,1]");
00643     }
00644 }
00645 
00647 void process_seed_opt(const char* arg) throw (Arg_error)
00648 {
00649     if (!arg)
00650     {
00651         throw Arg_error("Option 'seed' requires an argument");
00652     }
00653     if (sscanf(arg, "%u", &seed) != 1)
00654     {
00655         throw Arg_error("Option 'seed' must be a non-negative integer");
00656     }
00657 }
00658 
00660 void process_img_in_opt(const char* arg) throw (Arg_error)
00661 {
00662     if (!arg)
00663     {
00664         throw Arg_error("Option 'img-in' requires an argument");
00665     }
00666     img_in_fname = arg;
00667 }
00668 
00670 void process_img_out_opt(const char* arg) throw (Arg_error)
00671 {
00672     if (!arg)
00673     {
00674         throw Arg_error("Option 'img-out' requires an argument");
00675     }
00676     img_out_fname = arg;
00677 }
00678 
00680 void process_psf_in_opt(const char* arg) throw (Arg_error)
00681 {
00682     if (!arg)
00683     {
00684         throw Arg_error("Option 'psf-in' requires an argument");
00685     }
00686     psf_in_fname = arg;
00687 }
00688 
00690 void process_psf_out_opt(const char* arg) throw (Arg_error)
00691 {
00692     if (!arg)
00693     {
00694         throw Arg_error("Option 'psf-out' requires an argument");
00695     }
00696     psf_out_fname = arg;
00697 }
00698 
00700 void process_alt_in_opt(const char* arg) throw (Arg_error)
00701 {
00702     if (!arg)
00703     {
00704         throw Arg_error("Option 'alt-in' requires an argument");
00705     }
00706     alt_in_fname = arg;
00707 }
00708 
00710 void process_alt_out_opt(const char* arg) throw (Arg_error)
00711 {
00712     if (!arg)
00713     {
00714         throw Arg_error("Option 'alt-out' requires an argument");
00715     }
00716     alt_out_fname = arg;
00717 }
00718 
00720 void process_alt_pro_opt(const char* arg) throw (Arg_error)
00721 {
00722     if (!arg)
00723     {
00724         throw Arg_error("Option 'alt-pro' requires an argument");
00725     }
00726     alt_pro_fmt = arg;
00727 }
00728 
00730 void process_dd_spores_opt(const char* arg) throw (Arg_error)
00731 {
00732     if (!arg)
00733     {
00734         throw Arg_error("Option 'dd-spores' requires an argument");
00735     }
00736     dd_spores_fname = arg;
00737 }
00738 
00740 void process_scene_fmt_opt(const char* arg) throw (Arg_error)
00741 {
00742     if (!arg)
00743     {
00744         throw Arg_error("Option 'scene-fmt' requires an argument");
00745     }
00746     alt_scene_fmt = arg;
00747 }
00748 
00750 void process_scene_scale_opt(const char* arg) throw (Arg_error)
00751 {
00752     float x, y, z;
00753 
00754     if (!arg)
00755     {
00756         throw Arg_error("Option 'scene-scale' requires an argument");
00757     }
00758     if (sscanf(arg, "%f,%f,%f", &x, &y, &z) != 3)
00759     {
00760         throw Arg_error("Option 'scene-scale' has format x,y,z");
00761     }
00762     try
00763     {
00764         img_scale->set(x, y, z);
00765     }
00766     catch (Arg_error e)
00767     {
00768         ostringstream ost;
00769         ost << "Option 'scene-scale': " << e.get_msg();
00770         throw Arg_error(ost.str());
00771     }
00772 }
00773 
00775 void process_scene_window_opt(const char* arg) throw (Arg_error)
00776 {
00777     uint32_t col, row, img, ncols, nrows, nimgs;
00778 
00779     if (!arg)
00780     {
00781         throw Arg_error("Option 'scene-window' requires an argument");
00782     }
00783     if (sscanf(arg, "%u,%u,%u,%u,%u,%u", &col, &row, &img, &ncols, &nrows, &nimgs) != 6)
00784     {
00785         throw Arg_error("Option 'scene-window' has format col,row,img,ncols,nrows,nimgs");
00786     }
00787     try
00788     {
00789         img_window->set(col, row, img, ncols, nrows, nimgs);
00790     }
00791     catch (Arg_error e)
00792     {
00793         ostringstream ost;
00794         ost << "Option 'scene-window': " << e.get_msg();
00795         throw Arg_error(ost.str());
00796     }
00797 
00798     img_window_set = true;
00799 }
00800 
00802 void process_psf_fmt_opt(const char* arg) throw (Arg_error)
00803 {
00804     if (!arg)
00805     {
00806         throw Arg_error("Option 'psf-fmt' requires an argument");
00807     }
00808     psf_h_fmt = arg;
00809 }
00810 
00812 void process_apical_hypha_length_opt(const char* arg) throw (Arg_error)
00813 {
00814     float mu, sigma, min, max;
00815 
00816     if (!arg)
00817     {
00818         throw Arg_error("Option 'apical-hypha-length' requires an argument");
00819     }
00820     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00821     {
00822         throw Arg_error("Option 'apical-hypha-length' has format mu,sigma,min,max");
00823     }
00824     try
00825     {
00826         apical_hypha_d->set_length(mu, sigma, min, max);
00827     }
00828     catch (Arg_error e)
00829     {
00830         ostringstream ost;
00831         ost << "Option 'apical-hypha-length': " << e.get_msg();
00832         throw Arg_error(ost.str());
00833     }
00834 }
00835 
00837 void process_lateral_hypha_length_opt(const char* arg) throw (Arg_error)
00838 {
00839     float mu, sigma, min, max;
00840 
00841     if (!arg)
00842     {
00843         throw Arg_error("Option 'lateral-hypha-length' requires an argument");
00844     }
00845     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00846     {
00847         throw Arg_error("Option 'lateral-hypha-length' has format mu,sigma,min,max");
00848     }
00849     try
00850     {
00851         lateral_hypha_1_d->set_length(mu, sigma, min, max);
00852         lateral_hypha_n_d->set_length(mu, sigma, min, max);
00853     }
00854     catch (Arg_error e)
00855     {
00856         ostringstream ost;
00857         ost << "Option 'lateral-hypha-length': " << e.get_msg();
00858         throw Arg_error(ost.str());
00859     }
00860 }
00861 
00863 void process_apical_hypha_width_opt(const char* arg) throw (Arg_error)
00864 {
00865     float mu, sigma, min, max;
00866 
00867     if (!arg)
00868     {
00869         throw Arg_error("Option 'apical-hypha-width' requires an argument");
00870     }
00871     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00872     {
00873         throw Arg_error("Option 'apical-hypha-width' has format mu,sigma,min,max");
00874     }
00875     try
00876     {
00877         apical_hypha_d->set_width(mu, sigma, min, max);
00878     }
00879     catch (Arg_error e)
00880     {
00881         ostringstream ost;
00882         ost << "Option 'apical-hypha-width': " << e.get_msg();
00883         throw Arg_error(ost.str());
00884     }
00885 }
00886 
00888 void process_apical_hypha_dwidth_opt(const char* arg) throw (Arg_error)
00889 {
00890     float sigma, min, max;
00891 
00892     if (!arg)
00893     {
00894         throw Arg_error("Option 'apical-hypha-dwidth' requires an argument");
00895     }
00896     if (sscanf(arg, "%f,%f,%f", &sigma, &min, &max) != 3)
00897     {
00898         throw Arg_error("Option 'apical-hypha-dwidth' has format sigma,min,max");
00899     }
00900     try
00901     {
00902         apical_hypha_d->set_dwidth(sigma, min, max);
00903     }
00904     catch (Arg_error e)
00905     {
00906         ostringstream ost;
00907         ost << "Option 'apical-hypha-dwidth': " << e.get_msg();
00908         throw Arg_error(ost.str());
00909     }
00910 }
00911 
00913 void process_lateral_hypha_width_opt(const char* arg) throw (Arg_error)
00914 {
00915     float mu, sigma, min, max;
00916 
00917     if (!arg)
00918     {
00919         throw Arg_error("Option 'lateral-hypha-width' requires an argument");
00920     }
00921     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00922     {
00923         throw Arg_error("Option 'lateral-hypha-width' has format mu,sigma,min,max");
00924     }
00925     try
00926     {
00927         lateral_hypha_1_d->set_width(mu, sigma, min, max);
00928         lateral_hypha_n_d->set_width(mu, sigma, min, max);
00929     }
00930     catch (Arg_error e)
00931     {
00932         ostringstream ost;
00933         ost << "Option 'lateral-hypha-width': " << e.get_msg();
00934         throw Arg_error(ost.str());
00935     }
00936 }
00937 
00939 void process_apical_hypha_theta_opt(const char* arg) throw (Arg_error)
00940 {
00941     float mu, sigma, min, max;
00942 
00943     if (!arg)
00944     {
00945         throw Arg_error("Option 'apical-hypha-theta' requires an argument");
00946     }
00947     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00948     {
00949         throw Arg_error("Option 'apical-hypha-theta' has format mu,sigma,min,max");
00950     }
00951     try
00952     {
00953         apical_hypha_d->set_theta(mu, sigma, min, max);
00954     }
00955     catch (Arg_error e)
00956     {
00957         ostringstream ost;
00958         ost << "Option 'apical-hypha-theta': " << e.get_msg();
00959         throw Arg_error(ost.str());
00960     }
00961 }
00962 
00964 void process_lateral_hypha_1_theta_opt(const char* arg) throw (Arg_error)
00965 {
00966     float mu, sigma, min, max;
00967 
00968     if (!arg)
00969     {
00970         throw Arg_error("Option 'lateral-hypha-1-theta' requires an argument");
00971     }
00972     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00973     {
00974         throw Arg_error("Option 'lateral-hypha-1-theta' has format mu,sigma,min,max");
00975     }
00976     try
00977     {
00978         lateral_hypha_1_d->set_theta(mu, sigma, min, max);
00979     }
00980     catch (Arg_error e)
00981     {
00982         ostringstream ost;
00983         ost << "Option 'lateral-hypha-1-theta': " << e.get_msg();
00984         throw Arg_error(ost.str());
00985     }
00986 }
00987 
00989 void process_lateral_hypha_n_theta_opt(const char* arg) throw (Arg_error)
00990 {
00991     float mu, sigma, min, max;
00992 
00993     if (!arg)
00994     {
00995         throw Arg_error("Option 'lateral-hypha-n-theta' requires an argument");
00996     }
00997     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
00998     {
00999         throw Arg_error("Option 'lateral-hypha-n-theta' has format mu,sigma,min,max");
01000     }
01001     try
01002     {
01003         lateral_hypha_n_d->set_theta(mu, sigma, min, max);
01004     }
01005     catch (Arg_error e)
01006     {
01007         ostringstream ost;
01008         ost << "Option 'lateral-hypha-n-theta': " << e.get_msg();
01009         throw Arg_error(ost.str());
01010     }
01011 }
01012 
01014 void process_hypha_psi_opt(const char* arg) throw (Arg_error)
01015 {
01016     float min, max;
01017 
01018     if (!arg)
01019     {
01020         throw Arg_error("Option 'hypha-psi' requires an argument");
01021     }
01022     if (sscanf(arg, "%f,%f", &min, &max) != 2)
01023     {
01024         throw Arg_error("Option 'hypha-psi' has format min,max");
01025     }
01026     try
01027     {
01028         apical_hypha_d->set_psi(min, max);
01029         lateral_hypha_1_d->set_psi(min, max);
01030         lateral_hypha_n_d->set_psi(min, max);
01031     }
01032     catch (Arg_error e)
01033     {
01034         ostringstream ost;
01035         ost << "Option 'hypha-psi': " << e.get_msg();
01036         throw Arg_error(ost.str());
01037     }
01038 }
01039 
01041 void process_hypha_opacity_opt(const char* arg) throw (Arg_error)
01042 {
01043     float mu, sigma, min, max;
01044 
01045     if (!arg)
01046     {
01047         throw Arg_error("Option 'hypha-opacity' requires an argument");
01048     }
01049     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01050     {
01051         throw Arg_error("Option 'hypha-opacity' has format mu,sigma,min,max");
01052     }
01053     try
01054     {
01055         apical_hypha_d->set_opacity(mu, sigma, min, max);
01056         lateral_hypha_1_d->set_opacity(mu, sigma, min, max);
01057         lateral_hypha_n_d->set_opacity(mu, sigma, min, max);
01058     }
01059     catch (Arg_error e)
01060     {
01061         ostringstream ost;
01062         ost << "Option 'hypha-opacity': " << e.get_msg();
01063         throw Arg_error(ost.str());
01064     }
01065 }
01066 
01068 void process_lateral_hypha_dist_opt(const char* arg) throw (Arg_error)
01069 {
01070     float mu, sigma, min, max;
01071 
01072     if (!arg)
01073     {
01074         throw Arg_error("Option 'lateral-hypha-dist' requires an argument");
01075     }
01076     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01077     {
01078         throw Arg_error("Option 'lateral-hypha-dist' has format mu,sigma,min,max");
01079     }
01080     try
01081     {
01082         lateral_hypha_1_d->set_lat_dist(mu, sigma, min, max);
01083         lateral_hypha_n_d->set_lat_dist(mu, sigma, min, max);
01084     }
01085     catch (Arg_error e)
01086     {
01087         ostringstream ost;
01088         ost << "Option 'lateral-hypha-dist': " << e.get_msg();
01089         throw Arg_error(ost.str());
01090     }
01091 }
01092 
01094 void process_spore_length_opt(const char* arg) throw (Arg_error)
01095 {
01096     float mu, sigma, min, max;
01097 
01098     if (!arg)
01099     {
01100         throw Arg_error("Option 'spore-length' requires an argument");
01101     }
01102     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01103     {
01104         throw Arg_error("Option 'spore-length' has format mu,sigma,min,max");
01105     }
01106     try
01107     {
01108         spore_d->set_length(mu, sigma, min, max);
01109     }
01110     catch (Arg_error e)
01111     {
01112         ostringstream ost;
01113         ost << "Option 'spore-length': " << e.get_msg();
01114         throw Arg_error(ost.str());
01115     }
01116 }
01117 
01119 void process_spore_width_opt(const char* arg) throw (Arg_error)
01120 {
01121     float mu, sigma, min, max;
01122 
01123     if (!arg)
01124     {
01125         throw Arg_error("Option 'spore-width' requires an argument");
01126     }
01127     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01128     {
01129         throw Arg_error("Option 'spore-width' has format mu,sigma,min,max");
01130     }
01131     try
01132     {
01133         spore_d->set_width(mu, sigma, min, max);
01134     }
01135     catch (Arg_error e)
01136     {
01137         ostringstream ost;
01138         ost << "Option 'spore-width': " << e.get_msg();
01139         throw Arg_error(ost.str());
01140     }
01141 }
01142 
01144 void process_spore_theta_opt(const char* arg) throw (Arg_error)
01145 {
01146     float mu, sigma, min, max;
01147 
01148     if (!arg)
01149     {
01150         throw Arg_error("Option 'spore-theta' requires an argument");
01151     }
01152     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01153     {
01154         throw Arg_error("Option 'spore-theta' has format mu,sigma,min,max");
01155     }
01156     try
01157     {
01158         spore_d->set_theta(mu, sigma, min, max);
01159     }
01160     catch (Arg_error e)
01161     {
01162         ostringstream ost;
01163         ost << "Option 'spore-theta': " << e.get_msg();
01164         throw Arg_error(ost.str());
01165     }
01166 }
01167 
01169 void process_spore_psi_opt(const char* arg) throw (Arg_error)
01170 {
01171     float min, max;
01172 
01173     if (!arg)
01174     {
01175         throw Arg_error("Option 'spore-psi' requires an argument");
01176     }
01177     if (sscanf(arg, "%f,%f", &min, &max) != 2)
01178     {
01179         throw Arg_error("Option 'spore-psi' has format min,max");
01180     }
01181     try
01182     {
01183         spore_d->set_psi(min, max);
01184     }
01185     catch (Arg_error e)
01186     {
01187         ostringstream ost;
01188         ost << "Option 'spore-psi': " << e.get_msg();
01189         throw Arg_error(ost.str());
01190     }
01191 }
01192 
01194 void process_spore_opacity_opt(const char* arg) throw (Arg_error)
01195 {
01196     float mu, sigma, min, max;
01197 
01198     if (!arg)
01199     {
01200         throw Arg_error("Option 'spore-opacity' requires an argument");
01201     }
01202     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01203     {
01204         throw Arg_error("Option 'spore-opacity' has format mu,sigma,min,max");
01205     }
01206     try
01207     {
01208         spore_d->set_opacity(mu, sigma, min, max);
01209     }
01210     catch (Arg_error e)
01211     {
01212         ostringstream ost;
01213         ost << "Option 'spore-opacity': " << e.get_msg();
01214         throw Arg_error(ost.str());
01215     }
01216 }
01217 
01219 void process_psf_alpha_opt(const char* arg) throw (Arg_error)
01220 {
01221     float mu, sigma, min, max;
01222 
01223     if (!arg)
01224     {
01225         throw Arg_error("Option 'psf-alpha' requires an argument");
01226     }
01227     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01228     {
01229         throw Arg_error("Option 'psf-alpha' has format mu,sigma,min,max");
01230     }
01231     try
01232     {
01233         psf_d->set_alpha(mu, sigma, min, max);
01234     }
01235     catch (Arg_error e)
01236     {
01237         ostringstream ost;
01238         ost << "Option 'psf-alpha': " << e.get_msg();
01239         throw Arg_error(ost.str());
01240     }
01241 }
01242 
01244 void process_psf_beta_opt(const char* arg) throw (Arg_error)
01245 {
01246     float mu, sigma, min, max;
01247 
01248     if (!arg)
01249     {
01250         throw Arg_error("Option 'psf-beta' requires an argument");
01251     }
01252     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01253     {
01254         throw Arg_error("Option 'psf-beta' has format mu,sigma,min,max");
01255     }
01256     try
01257     {
01258         psf_d->set_beta(mu, sigma, min, max);
01259     }
01260     catch (Arg_error e)
01261     {
01262         ostringstream ost;
01263         ost << "Option 'psf-beta': " << e.get_msg();
01264         throw Arg_error(ost.str());
01265     }
01266 }
01267 
01269 void process_psf_gamma_opt(const char* arg) throw (Arg_error)
01270 {
01271     float mu, sigma, min, max;
01272 
01273     if (!arg)
01274     {
01275         throw Arg_error("Option 'psf-gamma' requires an argument");
01276     }
01277     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01278     {
01279         throw Arg_error("Option 'psf-gamma' has format mu,sigma,min,max");
01280     }
01281     try
01282     {
01283         psf_d->set_gamma(mu, sigma, min, max);
01284     }
01285     catch (Arg_error e)
01286     {
01287         ostringstream ost;
01288         ost << "Option 'psf-gamma': " << e.get_msg();
01289         throw Arg_error(ost.str());
01290     }
01291 }
01292 
01294 void process_img_bg_opt(const char* arg) throw (Arg_error)
01295 {
01296     float mu, sigma, min, max;
01297 
01298     if (!arg)
01299     {
01300         throw Arg_error("Option 'img-bg' requires an argument");
01301     }
01302     if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4)
01303     {
01304         throw Arg_error("Option 'img-bg' has format mu,sigma,min,max");
01305     }
01306     try
01307     {
01308         imaging_d->set_bg(mu, sigma, min, max);
01309     }
01310     catch (Arg_error e)
01311     {
01312         ostringstream ost;
01313         ost << "Option 'img-bg': " << e.get_msg();
01314         throw Arg_error(ost.str());
01315     }
01316 }
01317 
01319 void process_levels_p_opt(const char* arg) throw (Arg_error)
01320 {
01321     float p;
01322 
01323     if (!arg)
01324     {
01325         throw Arg_error("Option 'levels-p' requires an argument");
01326     }
01327     if (sscanf(arg, "%f", &p) != 1)
01328     {
01329         throw Arg_error("Option 'levels-p' must be in a number in (0,1)");
01330     }
01331     try
01332     {
01333         alt_d->set_num_levels_p(p);
01334     }
01335     catch (Arg_error e)
01336     {
01337         ostringstream ost;
01338         ost << "Option 'levels-p': " << e.get_msg();
01339         throw Arg_error(ost.str());
01340     }
01341 }
01342 
01344 void process_structs_p_opt(const char* arg) throw (Arg_error)
01345 {
01346     float spore_p, apical_hypha_p, lateral_hypha_1_p, lateral_hypha_n_p;
01347 
01348     if (!arg)
01349     {
01350         throw Arg_error("Option 'structs-p' requires an argument");
01351     }
01352     if (sscanf(arg, "%f,%f,%f,%f", &spore_p, &apical_hypha_p, &lateral_hypha_1_p, &lateral_hypha_n_p) != 4)
01353     {
01354         throw Arg_error("Option 'structs-p' has format spore,apical-hypha,lateral-hypha-1, lateral-hypha-n");
01355     }
01356     try
01357     {
01358         alt_d->set_structure_p(spore_p, apical_hypha_p, lateral_hypha_1_p,
01359                 lateral_hypha_n_p);
01360     }
01361     catch (Arg_error e)
01362     {
01363         ostringstream ost;
01364         ost << "Option 'structs-p': " << e.get_msg();
01365         throw Arg_error(ost.str());
01366     }
01367 }
01368 
01370 void process_base_level_opt(const char* arg) throw (Arg_error)
01371 {
01372     if (!arg)
01373     {
01374         throw Arg_error("Option 'base-level' requires an argument");
01375     }
01376     if (sscanf(arg, "%u", &base_level) != 1)
01377     {
01378         throw Arg_error("Option 'base-level' must be >= 0");
01379     }
01380 }
01381 
01383 void init_options()
01384 {
01385     using jwscxx::base::Option_no_arg;
01386     using jwscxx::base::Option_with_arg;
01387 
01388     const char* l_name;
01389     const char* desc;
01390 
01391     opts = new Options();
01392 
01393     l_name = "help";
01394     desc   = "Program usage";
01395     opts->add(new Option_no_arg('h', l_name, desc, process_help_opt));
01396 
01397     l_name = "version";
01398     desc   = "Program version.";
01399     opts->add(new Option_no_arg('v', l_name, desc, process_version_opt));
01400 
01401     l_name = "options";
01402     desc   = "Process a file of program options.";
01403     opts->add(new Option_with_arg(0, l_name, desc, process_options_opt));
01404 
01405     l_name = "move-info";
01406     desc   = "File to print sampler move information to. Stdout by default.";
01407     opts->add(new Option_with_arg(0, l_name, desc, process_move_info_opt));
01408 
01409     l_name = "best-info";
01410     desc   = "File to print sampler best move information to. Stdout by default.";
01411     opts->add(new Option_with_arg(0, l_name, desc, process_best_info_opt));
01412 
01413 #ifdef JWSC_HAVE_FFTW3F_THREADS
01414     l_name = "threads";
01415     desc   = "Number of threads to use.";
01416     opts->add(new Option_with_arg(0, l_name, desc, process_threads_opt));
01417 #endif
01418 
01419     l_name = "iterations";
01420     desc   = "Number of iterations to run the sampler.";
01421     opts->add(new Option_with_arg(0, l_name, desc, process_iterations_opt));
01422 
01423     l_name = "resolution";
01424     desc   = "Fraction of the data to down sample to. Has format x,y,z. Must be in (0,1].";
01425     opts->add(new Option_with_arg(0, l_name, desc, process_resolution_opt));
01426 
01427     l_name = "seed";
01428     desc   = "Random seed to use in srand(). Must be a non-negative integer.";
01429     opts->add(new Option_with_arg(0, l_name, desc, process_seed_opt));
01430 
01431     l_name = "img-in";
01432     desc   = "Imaging input file to read from.";
01433     opts->add(new Option_with_arg(0, l_name, desc, process_img_in_opt));
01434 
01435     l_name = "img-out";
01436     desc   = "Imaging output file to write to.";
01437     opts->add(new Option_with_arg(0, l_name, desc, process_img_out_opt));
01438 
01439     l_name = "psf-in";
01440     desc   = "PSF input file to read from.";
01441     opts->add(new Option_with_arg(0, l_name, desc, process_psf_in_opt));
01442 
01443     l_name = "psf-out";
01444     desc   = "PSF output file to write to.";
01445     opts->add(new Option_with_arg(0, l_name, desc, process_psf_out_opt));
01446 
01447     l_name = "alt-in";
01448     desc   = "Alternaria input file to read from.";
01449     opts->add(new Option_with_arg(0, l_name, desc, process_alt_in_opt));
01450 
01451     l_name = "alt-out";
01452     desc   = "Alternaria output file to write to.";
01453     opts->add(new Option_with_arg(0, l_name, desc, process_alt_out_opt));
01454 
01455     l_name = "alt-pro";
01456     desc   = "Printf-fomatted file name for Alternaria propsals.";
01457     opts->add(new Option_with_arg(0, l_name, desc, process_alt_pro_opt));
01458 
01459     l_name = "dd-spores";
01460     desc   = "Data-driven spores file name.";
01461     opts->add(new Option_with_arg(0, l_name, desc, process_dd_spores_opt));
01462 
01463     l_name = "scene-fmt";
01464     desc   = "Printf-formatted file name for the optically sectioned scene. Must contain one integer conversion";
01465     opts->add(new Option_with_arg(0, l_name, desc, process_scene_fmt_opt));
01466 
01467     l_name = "scene-scale";
01468     desc   = "Number of alternaria world units per image pixel. Has format x,y,z.";
01469     opts->add(new Option_with_arg(0, l_name, desc, process_scene_scale_opt));
01470 
01471     l_name = "scene-window";
01472     desc   = "Window over the data to do the analysis on. Has format col,row,img,ncols,nrows,nimgs.";
01473     opts->add(new Option_with_arg(0, l_name, desc, process_scene_window_opt));
01474 
01475     l_name = "psf-fmt";
01476     desc   = "Printf-formatted file name for the optically sectioned PSF. Must contain one integer conversion.";
01477     opts->add(new Option_with_arg(0, l_name, desc, process_psf_fmt_opt));
01478 
01479     l_name = "apical-hypha-length";
01480     desc   = "Length of an apical hypha. Has argument format mu,sigma,min,max.";
01481     opts->add(new Option_with_arg(0, l_name, desc, 
01482                 process_apical_hypha_length_opt));
01483 
01484     l_name = "lateral-hypha-length";
01485     desc   = "Length of a lateral hypha. Has argument format mu,sigma,min,max.";
01486     opts->add(new Option_with_arg(0, l_name, desc, 
01487                 process_lateral_hypha_length_opt));
01488 
01489     l_name = "apical-hypha-width";
01490     desc   = "Width of an apical hypha. Has argument format mu,sigma,min,max.";
01491     opts->add(new Option_with_arg(0, l_name, desc, 
01492                 process_apical_hypha_width_opt));
01493 
01494     l_name = "apical-hypha-dwidth";
01495     desc   = "Width difference between adjacent apical hypha. Has argument format sigma,min,max.";
01496     opts->add(new Option_with_arg(0, l_name, desc, 
01497                 process_apical_hypha_dwidth_opt));
01498 
01499     l_name = "lateral-hypha-width";
01500     desc   = "Width of a lateral hypha. Has argument format mu,sigma,min,max.";
01501     opts->add(new Option_with_arg(0, l_name, desc, 
01502                 process_lateral_hypha_width_opt));
01503 
01504     l_name = "apical-hypha-theta";
01505     desc   = "Theta Euler angle of an apical hypha. Has argument format mu,sigma,min,max.";
01506     opts->add(new Option_with_arg(0, l_name, desc, 
01507                 process_apical_hypha_theta_opt));
01508 
01509     l_name = "lateral-hypha-1-theta";
01510     desc   = "Theta Euler angle of a lateral hypha at level 1. Has argument format mu,sigma,min,max.";
01511     opts->add(new Option_with_arg(0, l_name, desc, 
01512                 process_lateral_hypha_1_theta_opt));
01513 
01514     l_name = "lateral-hypha-n-theta";
01515     desc   = "Theta Euler angle of a lateral hypha at level > 1. Has argument format mu,sigma,min,max.";
01516     opts->add(new Option_with_arg(0, l_name, desc, 
01517                 process_lateral_hypha_n_theta_opt));
01518 
01519     l_name = "hypha-psi";
01520     desc   = "Psi Euler angle of a hypha. Has argument format mu,sigma,min,max.";
01521     opts->add(new Option_with_arg(0, l_name, desc, process_hypha_psi_opt));
01522 
01523     l_name = "hypha-opacity";
01524     desc   = "Opacity of a hypha. Has argument format mu,sigma,min,max.";
01525     opts->add(new Option_with_arg(0, l_name, desc, process_hypha_opacity_opt));
01526 
01527     l_name = "lateral-hypha-dist";
01528     desc   = "Distance of a lateral hypha from its parent. Has argument format mu,sigma,min,max.";
01529     opts->add(new Option_with_arg(0, l_name, desc, 
01530                 process_lateral_hypha_dist_opt));
01531 
01532     l_name = "spore-width";
01533     desc   = "Width of a spore. Has argument format mu,sigma,min,max.";
01534     opts->add(new Option_with_arg(0, l_name, desc, process_spore_width_opt));
01535 
01536     l_name = "spore-length";
01537     desc   = "Length of a spore. Has argument format mu,sigma,min,max.";
01538     opts->add(new Option_with_arg(0, l_name, desc, process_spore_length_opt));
01539 
01540     l_name = "spore-theta";
01541     desc   = "Theta Euler angle of a spore. Has argument format mu,sigma,min,max.";
01542     opts->add(new Option_with_arg(0, l_name, desc, process_spore_theta_opt));
01543 
01544     l_name = "spore-psi";
01545     desc   = "Psi Euler angle of a spore. Has argument format min,max.";
01546     opts->add(new Option_with_arg(0, l_name, desc, process_spore_psi_opt));
01547 
01548     l_name = "spore-opacity";
01549     desc   = "Opacity of a spore. Has argument format mu,sigma,min,max.";
01550     opts->add(new Option_with_arg(0, l_name, desc, process_spore_opacity_opt));
01551 
01552     l_name = "psf-alpha";
01553     desc   = "PSF alpha parameter. Has argument format mu,sigma,min,max.";
01554     opts->add(new Option_with_arg(0, l_name, desc, process_psf_alpha_opt));
01555 
01556     l_name = "psf-beta";
01557     desc   = "PSF beta parameter. Has argument format mu,sigma,min,max.";
01558     opts->add(new Option_with_arg(0, l_name, desc, process_psf_beta_opt));
01559 
01560     l_name = "psf-gamma";
01561     desc   = "PSF gamma parameter. Has argument format mu,sigma,min,max.";
01562     opts->add(new Option_with_arg(0, l_name, desc, process_psf_gamma_opt));
01563 
01564     l_name = "img-bg";
01565     desc   = "Image background parameter. Has argument format mu,sigma,min,max.";
01566     opts->add(new Option_with_arg(0, l_name, desc, process_img_bg_opt));
01567 
01568     l_name = "levels-p";
01569     desc   = "Geometric distribution parameter over growth levels. Must be in (0,1)";
01570     opts->add(new Option_with_arg(0, l_name, desc, process_levels_p_opt));
01571 
01572     l_name = "structs-p";
01573     desc   = "Distribution over structure type. Has argument format spore,apical-hypha,lateral-hypha. All must sum to 1.";
01574     opts->add(new Option_with_arg(0, l_name, desc, process_structs_p_opt));
01575 
01576     l_name = "base-level";
01577     desc   = "Base level for the root Structure. Must be >= 0.";
01578     opts->add(new Option_with_arg(0, l_name, desc, process_base_level_opt));
01579 }
01580 
01581 void* operator new (size_t s) throw (std::bad_alloc)
01582 {
01583     return malloc(s);
01584 }
01585 
01586 void operator delete (void* ptr) throw ()
01587 {
01588     if (ptr)
01589         free(ptr);
01590 }
01591 
01592 
01593 
01594 
01596 int main(int argc, char** argv)
01597 {
01598     Sampler*          sampler         = 0;
01599     Alternaria_model* alternaria      = 0;
01600     Alternaria_model* best_alternaria = 0;
01601     PSF_model*        psf             = 0;
01602     PSF_model*        best_psf        = 0;
01603     Imaging_model*    imaging         = 0;
01604     Imaging_model*    best_imaging    = 0;
01605     Matblock_f*       data            = 0;
01606     Sampler_move_parameters* params   = 0;
01607     DD_spore_set*     dd_spores       = 0;
01608 
01609     init_options();
01610 
01611     try
01612     {
01613         // Read data-driven.
01614         if (dd_spores_fname)
01615         {
01616             dd_spores = new DD_spore_set(dd_spores_fname);
01617         }
01618 
01619         sampler           = new Sampler();
01620         img_window        = new Imaging_window();
01621         img_scale         = new Imaging_scale();
01622         padding           = new PSF_padding();
01623         imaging_d         = new Imaging_model_density();
01624         psf_d             = new PSF_model_density();
01625         spore_d           = new Spore_density(dd_spores);
01626         apical_hypha_d    = new Apical_hypha_density();
01627         lateral_hypha_1_d = new Lateral_hypha_density();
01628         lateral_hypha_n_d = new Lateral_hypha_density();
01629         alt_d             = new Alternaria_model_density();
01630 
01631         int argi = argc - opts->process(argc, argv) + 1; 
01632 
01633         std::srand(seed);
01634         std::rand();
01635         std::rand();
01636 
01637         read_data(&data, argc, (const char**)argv, argi);
01638 
01639         // Update the image scale by the resolution.
01640         float x_scale = img_scale->get_x() / res_col;
01641         float y_scale = img_scale->get_y() / res_row;
01642         float z_scale = img_scale->get_z() / res_img;
01643         img_scale->set(x_scale, y_scale, z_scale);
01644 
01645         // Set the imaging window to the size of the data if not already set by 
01646         // an option.
01647         if (!img_window_set)
01648         {
01649             img_window->set(0, 0, 0, data->num_cols, data->num_rows, 
01650                     data->num_mats);
01651         }
01652         else
01653         {
01654             uint32_t img   = (uint32_t)ceil(res_img*img_window->get_img());
01655             uint32_t row   = (uint32_t)ceil(res_row*img_window->get_row());
01656             uint32_t col   = (uint32_t)ceil(res_col*img_window->get_col());
01657             uint32_t nimgs = (uint32_t)floor(res_img*
01658                                              img_window->get_num_imgs());
01659             uint32_t nrows = (uint32_t)floor(res_row*
01660                                              img_window->get_num_rows());
01661             uint32_t ncols = (uint32_t)floor(res_col*
01662                                              img_window->get_num_cols());
01663             img_window->set(col, row, img, ncols, nrows, nimgs);
01664         }
01665 
01666         // TEMPORARY
01667         Matblock_f* windowed_data = 0;
01668         copy_matblock_block_f(&windowed_data, data, 
01669                 img_window->get_img(),
01670                 img_window->get_row(),
01671                 img_window->get_col(),
01672                 img_window->get_num_imgs(),
01673                 img_window->get_num_rows(),
01674                 img_window->get_num_cols());
01675         Imgblock_f* imgs = 0;
01676         create_imgblock_from_matblock_f(&imgs, windowed_data);
01677         free_matblock_f(windowed_data);
01678         write_imgblock_numbered_f(imgs, "/tmp/data-%04u.tiff");
01679         free_imgblock_f(imgs);
01680 
01681         init_sampler_moves(sampler);
01682         init_density_centroids();
01683 
01684         // Read input models.
01685         if (img_in_fname)
01686         {
01687             imaging = new Imaging_model(img_in_fname, img_window, img_scale, 
01688                     imaging_d);
01689         }
01690         else
01691         {
01692             imaging = imaging_d->sample(img_window, img_scale);
01693         }
01694         if (psf_in_fname)
01695         {
01696             psf = new PSF_model(psf_in_fname, padding, psf_d, imaging);
01697         }
01698         else
01699         {
01700             psf = psf_d->sample(padding, imaging);
01701         }
01702         if (alt_in_fname)
01703         {
01704             alternaria = new Alternaria_model(alt_in_fname, alt_d, spore_d, 
01705                     apical_hypha_d, lateral_hypha_1_d, lateral_hypha_n_d, psf, 
01706                     imaging);
01707         }
01708         else
01709         {
01710             alternaria = alt_d->sample(0, 0, 0, 0, JWSC_PI_2, 0, base_level, 
01711                     spore_d, apical_hypha_d, lateral_hypha_1_d, 
01712                     lateral_hypha_n_d, psf, imaging);
01713         }
01714 
01715         params = new Sampler_move_parameters(alternaria, psf, imaging, data);
01716 
01717         // Run the sampler.
01718         sampler->run(&best_alternaria, &best_psf, &best_imaging, params, 
01719                 iterations, move_info_fname, best_info_fname, alt_pro_fmt);
01720 
01721 
01722         // Write output models.
01723         if (img_out_fname)
01724         {
01725             best_imaging->print(img_out_fname);
01726         }
01727         if (psf_out_fname)
01728         {
01729             best_psf->print(psf_out_fname);
01730         }
01731         if (alt_out_fname)
01732         {
01733             best_alternaria->print(alt_out_fname);
01734         }
01735         if (psf_h_fmt)
01736         {
01737             best_psf->write_h(psf_h_fmt);
01738         }
01739         if (alt_scene_fmt)
01740         {
01741             best_alternaria->write_scene(alt_scene_fmt, best_psf);
01742         }
01743     }
01744     catch (Exception e)
01745     {
01746         cerr << "alternaria: ";
01747         e.print();
01748     }
01749 
01750     delete best_alternaria;
01751     delete best_psf;
01752     delete best_imaging;
01753     delete params;
01754     delete sampler;
01755     delete img_window;
01756     delete img_scale;
01757     delete padding;
01758     delete imaging_d;
01759     delete psf_d;
01760     delete spore_d;
01761     delete apical_hypha_d;
01762     delete lateral_hypha_1_d;
01763     delete lateral_hypha_n_d;
01764     delete alt_d;
01765     delete dd_spores;
01766     delete opts;
01767     free_matblock_f(data);
01768 
01769     return EXIT_SUCCESS;
01770 }