00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef eman_reconstructor_h__
00037 #define eman_reconstructor_h__ 1
00038 #include <fstream>
00039 #include <boost/shared_ptr.hpp>
00040 #include "emdata.h"
00041 #include "exception.h"
00042 #include "emobject.h"
00043 #include "interp.h"
00044
00045 using std::vector;
00046 using std::map;
00047 using std::string;
00048 using boost::shared_ptr;
00049
00050 using std::cout;
00051 using std::cerr;
00052 using std::endl;
00053
00054 #include <utility>
00055 using std::pair;
00056
00057 #include "reconstructor_tools.h"
00058
00059 namespace EMAN
00060 {
00061
00062 class Transform3D;
00063 class EMData;
00064
00110 class Reconstructor : public FactoryBase
00111 {
00112 public:
00113 Reconstructor() {}
00114 virtual ~Reconstructor() {}
00117 virtual void setup() = 0;
00118
00126 virtual void setup_seed(EMData* seed,float seed_weight) {throw;}
00127
00136 virtual EMData* preprocess_slice( const EMData* const slice, const Transform& t = Transform() ) { EMData *ret=slice->copy(); ret->set_attr("reconstruct_preproc",(int)1); return ret; }
00137
00146 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0) {throw;}
00147
00161 virtual int determine_slice_agreement(EMData* slice, const Transform &euler, const float weight=1.0, bool sub=true ) { throw; }
00162
00167 virtual EMData *finish(bool doift=true) { throw; }
00168
00171 void print_params() const
00172 {
00173 std::cout << "Printing reconstructor params" << std::endl;
00174 for ( Dict::const_iterator it = params.begin(); it != params.end(); ++it )
00175 {
00176 std::cout << (it->first) << " " << (it->second).to_str() << std::endl;
00177 }
00178 std::cout << "Done printing reconstructor params" << std::endl;
00179 }
00180
00181
00182 EMObject& operator[]( const string& key ) { return params[key]; }
00183
00184 private:
00185
00186 Reconstructor(const Reconstructor& that);
00187 Reconstructor& operator=(const Reconstructor& );
00188
00189 };
00190
00202 class ReconstructorVolumeData
00203 {
00204 public:
00208 inline ReconstructorVolumeData() : image(0), tmp_data(0), nx(0), ny(0), nz(0), subnx(0), subny(0), subnz(0), subx0(0), suby0(0), subz0(0) {}
00209
00212 virtual ~ReconstructorVolumeData() { free_memory(); }
00213
00216 const EMData* const get_emdata() { return image; }
00217 protected:
00218
00220 EMData* image;
00222 EMData* tmp_data;
00223
00224
00225 int nx,nx2;
00226 int ny,ny2;
00227 int nz,nz2;
00228
00229 int subnx;
00230 int subny;
00231 int subnz;
00232
00233 int subx0;
00234 int suby0;
00235 int subz0;
00236
00237 protected:
00243 void free_memory()
00244 {
00245 if (image != 0) {delete image; image = 0;}
00246 if ( tmp_data != 0 ) { delete tmp_data; tmp_data = 0; }
00247 }
00248
00254 virtual void normalize_threed(const bool sqrt_damp=false,const bool wiener=false);
00255
00259 virtual void zero_memory()
00260 {
00261 if (tmp_data != 0 ) tmp_data->to_zero();
00262 if (image != 0 ) image->to_zero();
00263 }
00264
00265 private:
00267 ReconstructorVolumeData(const ReconstructorVolumeData& that);
00269 ReconstructorVolumeData& operator=(const ReconstructorVolumeData& );
00270
00271 };
00272
00278 class FourierReconstructorSimple2D : public Reconstructor, public ReconstructorVolumeData
00279 {
00280 public:
00281 FourierReconstructorSimple2D() {}
00282
00283 virtual ~FourierReconstructorSimple2D() { }
00284
00285 virtual void setup();
00286
00287 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00288
00289 virtual EMData *finish(bool doift=true);
00290
00291 virtual string get_name() const { return NAME; }
00292
00293 virtual string get_desc() const { return "performs 2D reconstruction"; }
00294
00295 static Reconstructor *NEW()
00296 {
00297 return new FourierReconstructorSimple2D();
00298 }
00299
00300
00301 virtual TypeDict get_param_types() const
00302 {
00303 TypeDict d;
00304 d.put("nx", EMObject::INT, "Necessary. The x dimension of the input images.");
00305
00306 return d;
00307 }
00308
00309 static const string NAME;
00310 };
00311
00312
00313
00363 class FourierReconstructor : public Reconstructor, public ReconstructorVolumeData
00364 {
00365 public:
00369 FourierReconstructor() { load_default_settings(); }
00370
00374 virtual ~FourierReconstructor() { free_memory(); }
00375
00379 virtual void setup();
00380
00389 virtual void setup_seed(EMData* seed,float seed_weight);
00390
00399 virtual EMData* preprocess_slice( const EMData* const slice, const Transform& t = Transform() );
00400
00410 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00411
00412
00429 virtual int determine_slice_agreement(EMData* slice, const Transform &euler, const float weight=1.0, bool sub=true );
00430
00437 virtual EMData *finish(bool doift=true);
00438
00441 virtual string get_name() const
00442 {
00443 return NAME;
00444 }
00445
00448 virtual string get_desc() const
00449 {
00450 return "Reconstruction via direct Fourier methods using one of a variety of different kernels, most of which are Gaussian based";
00451 }
00452
00456 static Reconstructor *NEW()
00457 {
00458 return new FourierReconstructor();
00459 }
00460
00464 virtual TypeDict get_param_types() const
00465 {
00466 TypeDict d;
00467 d.put("size", EMObject::INTARRAY, "Required. The dimensions of the real-space output volume, including any padding (must be handled by the calling application). Assumed that apix x/y/z identical.");
00468 d.put("sym", EMObject::STRING, "Optional. The symmetry of the reconstructed volume, c?, d?, oct, tet, icos, h?. Default is c1, ie - an asymmetric object");
00469 d.put("mode", EMObject::STRING, "Optional. Fourier pixel insertion mode name (nearest_neighbor, gauss_2, gauss_3, gauss_5, gauss_5_slow, gypergeom_5, experimental) gauss_2 is the default.");
00470 d.put("sqrtnorm", EMObject::BOOL, "Optional. When normalizing, additionally divides by the sqrt of the normalization factor to damp exaggerated features. Is this justifyable ? No idea (yet). Default is false.");
00471 d.put("verbose", EMObject::BOOL, "Optional. Toggles writing useful information to standard out. Default is false.");
00472 d.put("subvolume",EMObject::INTARRAY, "Optional. (xorigin,yorigin,zorigin,xsize,ysize,zsize) all in Fourier pixels. Useful for parallelism.");
00473 d.put("savenorm",EMObject::STRING, "Debug. Will cause the normalization volume to be written directly to the specified file when finish() is called.");
00474 return d;
00475 }
00476
00477 static const string NAME;
00478
00479 protected:
00482 virtual void load_default_settings();
00483
00487 virtual void free_memory();
00488
00491 virtual void load_inserter();
00492
00498 virtual void do_insert_slice_work(const EMData* const input_slice, const Transform & euler,const float weight);
00499
00504 virtual void do_compare_slice_work(EMData* input_slice, const Transform & euler,float weight);
00505
00510 virtual bool pixel_at(const float& xx, const float& yy, const float& zz, float *dt);
00511
00513 FourierPixelInserter3D* inserter;
00514
00515 private:
00518 FourierReconstructor( const FourierReconstructor& that );
00521 FourierReconstructor& operator=( const FourierReconstructor& );
00522
00523 };
00524
00525
00526
00537 class WienerFourierReconstructor : public FourierReconstructor
00538 {
00539 public:
00543 WienerFourierReconstructor() {};
00544
00548 virtual ~WienerFourierReconstructor() { }
00549
00550
00560 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00561
00562
00579 virtual int determine_slice_agreement(EMData* slice, const Transform &euler, const float weight=1.0, bool sub=true );
00580
00587 virtual EMData *finish(bool doift=true);
00588
00591 virtual string get_name() const
00592 {
00593 return NAME;
00594 }
00595
00598 virtual string get_desc() const
00599 {
00600 return "Reconstruction via direct Fourier methods using one of a variety of different kernels, most of which are Gaussian based. This version also incorporates a nonisotropic Wiener filter based on SNR estimates stored in the class-average headers by the ctf.auto averager.";
00601 }
00602
00606 static Reconstructor *NEW()
00607 {
00608 return new WienerFourierReconstructor();
00609 }
00610
00611 static const string NAME;
00612
00613 protected:
00614
00615 virtual void do_insert_slice_work(const EMData* const input_slice, const Transform & euler,const float weight);
00616
00621 virtual void do_compare_slice_work(EMData* input_slice, const Transform & euler,float weight);
00622
00627 virtual bool pixel_at(const float& xx, const float& yy, const float& zz, float *dt);
00628
00630
00631
00632 private:
00635 WienerFourierReconstructor( const WienerFourierReconstructor& that );
00638 WienerFourierReconstructor& operator=( const WienerFourierReconstructor& );
00639
00640 };
00641
00649 class BackProjectionReconstructor:public Reconstructor, public ReconstructorVolumeData
00650 {
00651 public:
00652 BackProjectionReconstructor() { load_default_settings(); }
00653
00654 virtual ~BackProjectionReconstructor() {}
00655
00656 virtual void setup();
00657
00666 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00667
00668 virtual EMData *finish(bool doift=true);
00669
00670 virtual string get_name() const
00671 {
00672 return NAME;
00673 }
00674
00675 virtual string get_desc() const
00676 {
00677 return "Simple (unfiltered) back-projection reconstruction. Weighting by contributing particles in the class average is optional and default behaviour";
00678 }
00679
00680 static Reconstructor *NEW()
00681 {
00682 return new BackProjectionReconstructor();
00683 }
00684
00685 virtual TypeDict get_param_types() const
00686 {
00687 TypeDict d;
00688 d.put("size", EMObject::INT, "Necessary. The x and y dimensions of the input images.");
00689 d.put("weight", EMObject::FLOAT, "Optional. A temporary value set prior to slice insertion, indicative of the inserted slice's weight. Default sis 1.");
00690 d.put("sym", EMObject::STRING, "Optional. The symmetry to impose on the final reconstruction. Default is c1");
00691 d.put("zsample", EMObject::INT, "Optional. The z dimensions of the reconstructed volume.");
00692 return d;
00693 }
00694
00695 static const string NAME;
00696
00697 private:
00698
00699 BackProjectionReconstructor( const BackProjectionReconstructor& that);
00700
00701 BackProjectionReconstructor& operator=( const BackProjectionReconstructor& );
00702
00703 void load_default_settings()
00704 {
00705 params["weight"] = 1.0;
00706 params["use_weights"] = true;
00707 params["size"] = 0;
00708 params["sym"] = "c1";
00709 params["zsample"] = 0;
00710 }
00711
00712 EMData* preprocess_slice(const EMData* const slice, const Transform& t);
00713 };
00714
00715
00719 EMData* padfft_slice( const EMData* const slice, const Transform& t, int npad );
00720
00721 class nn4Reconstructor:public Reconstructor
00722 {
00723 public:
00724 nn4Reconstructor();
00725
00726 nn4Reconstructor( const string& symmetry, int size, int npad );
00727
00728 virtual ~nn4Reconstructor();
00729
00730 virtual void setup();
00731
00740 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00741
00742 virtual EMData *finish(bool doift=true);
00743
00744 virtual string get_name() const
00745 {
00746 return NAME;
00747 }
00748
00749 virtual string get_desc() const
00750 {
00751 return "Direct Fourier inversion routine";
00752 }
00753
00754 static Reconstructor *NEW()
00755 {
00756 return new nn4Reconstructor();
00757 }
00758
00759 virtual TypeDict get_param_types() const
00760 {
00761 TypeDict d;
00762 d.put("size", EMObject::INT);
00763 d.put("npad", EMObject::INT);
00764 d.put("sign", EMObject::INT);
00765 d.put("ndim", EMObject::INT);
00766 d.put("snr", EMObject::FLOAT);
00767 d.put("symmetry", EMObject::STRING);
00768 d.put("snr", EMObject::FLOAT);
00769 d.put("fftvol", EMObject::EMDATA);
00770 d.put("weight", EMObject::EMDATA);
00771 d.put("weighting", EMObject::INT);
00772 return d;
00773 }
00774
00775 void setup( const string& symmetry, int size, int npad );
00776
00777 int insert_padfft_slice( EMData* padded, const Transform& trans, int mult=1 );
00778
00779 static const string NAME;
00780
00781 private:
00782 EMData* m_volume;
00783 EMData* m_wptr;
00784 EMData* m_result;
00785 bool m_delete_volume;
00786 bool m_delete_weight;
00787 string m_symmetry;
00788 int m_weighting;
00789 int m_vnx, m_vny, m_vnz;
00790 int m_npad;
00791 int m_nsym;
00792 int m_ndim;
00793 int m_vnzp, m_vnyp, m_vnxp;
00794 int m_vnzc, m_vnyc, m_vnxc;
00795 void buildFFTVolume();
00796 void buildNormVolume();
00797 float m_wghta;
00798 float m_wghtb;
00799 float m_osnr;
00800 void load_default_settings()
00801 {
00802
00803 }
00804 };
00805
00806
00807
00808
00809
00810
00811
00812 class nnSSNR_Reconstructor:public Reconstructor
00813 {
00814
00815 public:
00816 nnSSNR_Reconstructor();
00817
00818 nnSSNR_Reconstructor( const string& symmetry, int size, int npad);
00819
00820 ~nnSSNR_Reconstructor();
00821
00822 virtual void setup();
00823
00832 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00833
00834 virtual EMData *finish(bool doift=true);
00835
00836 virtual string get_name() const
00837 {
00838 return NAME;
00839 }
00840
00841 virtual string get_desc() const
00842 {
00843 return "Reconstruction by nearest neighbor with 3D SSNR";
00844 }
00845
00846 static Reconstructor *NEW()
00847 {
00848 return new nnSSNR_Reconstructor();
00849 }
00850
00851 virtual TypeDict get_param_types() const
00852 {
00853 TypeDict d;
00854 d.put("size", EMObject::INT);
00855 d.put("npad", EMObject::INT);
00856 d.put("symmetry", EMObject::STRING);
00857 d.put("fftvol", EMObject::EMDATA);
00858 d.put("weight", EMObject::EMDATA);
00859 d.put("weight2", EMObject::EMDATA);
00860 d.put("SSNR", EMObject::EMDATA);
00861 d.put("w", EMObject::FLOAT);
00862 return d;
00863 }
00864
00865 void setup( const string& symmetry, int size, int npad);
00866
00867 int insert_padfft_slice( EMData* padded, const Transform& trans, int mult=1 );
00868
00869 static const string NAME;
00870
00871 private:
00872 EMData* m_volume;
00873 EMData* m_wptr;
00874 EMData* m_wptr2;
00875 EMData* m_result;
00876 bool m_delete_volume;
00877 bool m_delete_weight;
00878 bool m_delete_weight2;
00879 string m_symmetry;
00880 int m_weighting;
00881 int m_vnx, m_vny, m_vnz;
00882 int m_npad;
00883 int m_nsym;
00884 int m_vnzp, m_vnyp, m_vnxp;
00885 int m_vnzc, m_vnyc, m_vnxc;
00886 void buildFFTVolume();
00887 void buildNormVolume();
00888 void buildNorm2Volume();
00889 float m_wghta;
00890 float m_wghtb;
00891 };
00892
00893
00897 class nn4_ctfReconstructor:public Reconstructor
00898 {
00899 public:
00900 nn4_ctfReconstructor();
00901
00902 nn4_ctfReconstructor( const string& symmetry, int size, int npad, float snr, int sign );
00903
00904 virtual ~nn4_ctfReconstructor();
00905
00906 virtual void setup();
00907
00917 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
00918
00919 virtual EMData *finish(bool doift=true);
00920
00921 virtual string get_name() const
00922 {
00923 return NAME;
00924 }
00925
00926 virtual string get_desc() const
00927 {
00928 return "Direct Fourier inversion reconstruction routine";
00929 }
00930
00931 static Reconstructor *NEW()
00932 {
00933 return new nn4_ctfReconstructor();
00934 }
00935
00936
00937 TypeDict get_param_types() const
00938 {
00939 TypeDict d;
00940 d.put("size", EMObject::INT);
00941 d.put("npad", EMObject::INT);
00942 d.put("sign", EMObject::INT);
00943 d.put("symmetry", EMObject::STRING);
00944 d.put("snr", EMObject::FLOAT);
00945 d.put("fftvol", EMObject::EMDATA);
00946 d.put("weight", EMObject::EMDATA);
00947 d.put("weighting", EMObject::INT);
00948 d.put("varsnr", EMObject::INT);
00949 return d;
00950 }
00951
00952 void setup( const string& symmetry, int size, int npad, float snr, int sign );
00953
00954 int insert_padfft_slice( EMData* padfft, const Transform& trans, int mult=1);
00955
00956 int insert_buffed_slice( const EMData* buffer, int mult );
00957
00958 static const string NAME;
00959
00960 private:
00961 EMData* m_volume;
00962 EMData* m_result;
00963 EMData* m_wptr;
00964 bool m_delete_volume;
00965 bool m_delete_weight;
00966 int m_vnx, m_vny, m_vnz;
00967 int m_vnzp, m_vnyp, m_vnxp;
00968 int m_vnxc, m_vnyc, m_vnzc;
00969 int m_npad;
00970 int m_sign;
00971 int m_varsnr;
00972 int m_weighting;
00973 float m_wghta, m_wghtb;
00974 float m_snr;
00975 string m_symmetry;
00976 int m_nsym;
00977
00978 void buildFFTVolume();
00979 void buildNormVolume();
00980
00981 };
00982
00983
00984
00985
00986
00987
00988 class nnSSNR_ctfReconstructor:public Reconstructor
00989 {
00990
00991 public:
00992 nnSSNR_ctfReconstructor();
00993
00994 nnSSNR_ctfReconstructor( const string& symmetry, int size, int npad, float snr, int sign);
00995
00996 ~nnSSNR_ctfReconstructor();
00997
00998 virtual void setup();
00999
01009 virtual int insert_slice(const EMData* const slice, const Transform & euler,const float weight=1.0);
01010
01011
01012 virtual EMData *finish(bool doift=true);
01013
01014 virtual string get_name() const
01015 {
01016 return NAME;
01017 }
01018
01019 virtual string get_desc() const
01020 {
01021 return "Reconstruction by nearest neighbor with 3D SSNR with CTF";
01022 }
01023
01024 static Reconstructor *NEW()
01025 {
01026 return new nnSSNR_ctfReconstructor();
01027 }
01028
01029 TypeDict get_param_types() const
01030 {
01031 TypeDict d;
01032 d.put("size", EMObject::INT);
01033 d.put("npad", EMObject::INT);
01034 d.put("symmetry", EMObject::STRING);
01035 d.put("fftvol", EMObject::EMDATA);
01036 d.put("fftwvol", EMObject::EMDATA);
01037 d.put("weight", EMObject::EMDATA);
01038 d.put("weight2", EMObject::EMDATA);
01039 d.put("weight3", EMObject::EMDATA);
01040 d.put("SSNR", EMObject::EMDATA);
01041 d.put("w", EMObject::FLOAT);
01042 d.put("sign", EMObject::INT);
01043 d.put("snr", EMObject::FLOAT);
01044 return d;
01045 }
01046 void setup( const string& symmetry, int size, int npad, float snr, int sign);
01047
01048 int insert_padfft_slice( EMData* padded, const Transform& trans, int mult=1 );
01049
01050 static const string NAME;
01051
01052 private:
01053 EMData* m_volume;
01054 EMData* m_wptr;
01055 EMData* m_wptr2;
01056 EMData* m_wptr3;
01057 EMData* m_result;
01058 bool m_delete_volume;
01059 bool m_delete_weight;
01060 bool m_delete_weight2;
01061 bool m_delete_weight3;
01062 string m_symmetry;
01063 int m_weighting;
01064 int m_vnx, m_vny, m_vnz;
01065 int m_npad;
01066 int m_nsym;
01067 int m_vnzp, m_vnyp, m_vnxp;
01068 int m_vnzc, m_vnyc, m_vnxc;
01069 void buildFFTVolume();
01070 void buildNormVolume();
01071 void buildNorm2Volume();
01072 void buildNorm3Volume();
01073 float m_wghta;
01074 float m_wghtb;
01075 int m_sign;
01076 float m_snr;
01077 int wiener;
01078 };
01079
01080 template <> Factory < Reconstructor >::Factory();
01081
01082 void dump_reconstructors();
01083 map<string, vector<string> > dump_reconstructors_list();
01084
01085
01086 struct point_t
01087 {
01088 int pos2;
01089 float real;
01090 float imag;
01091 float ctf2;
01092 };
01093
01094
01095 class newfile_store
01096 {
01097 public:
01098 newfile_store( const string& prefix, int npad, bool ctf );
01099
01100 virtual ~newfile_store();
01101
01102 void add_image( EMData* data, const Transform& tf );
01103
01104 void add_tovol( EMData* fftvol, EMData* wgtvol, const vector<int>& mults, int pbegin, int pend );
01105
01106 void get_image( int id, EMData* buf );
01107
01108 void read( int nprj );
01109
01110 void restart( );
01111
01112 private:
01113 int m_npad;
01114
01115 bool m_ctf;
01116
01117 string m_bin_file;
01118 string m_txt_file;
01119
01120 shared_ptr<std::ofstream> m_bin_of;
01121 shared_ptr<std::ofstream> m_txt_of;
01122 shared_ptr<std::ifstream> m_bin_if;
01123 vector< std::istream::off_type > m_offsets;
01124
01125 vector< point_t > m_points;
01126 };
01127
01128 class file_store
01129 {
01130 public:
01131 file_store(const string& filename, int npad, int write, bool CTF);
01132
01133 virtual ~file_store();
01134
01135 void add_image(EMData* data, const Transform& tf);
01136
01137 void get_image(int id, EMData* padfft);
01138
01139 void restart();
01140 private:
01141 shared_ptr<std::ifstream> m_ihandle;
01142 shared_ptr<std::ofstream> m_bin_ohandle;
01143 shared_ptr<std::ofstream> m_txt_ohandle;
01144 string m_bin_file;
01145 string m_txt_file;
01146 int m_ctf;
01147 int m_npad;
01148 int m_prev;
01149 int m_x_out;
01150 int m_y_out;
01151 int m_z_out;
01152 int m_write;
01153 std::istream::off_type m_totsize;
01154 float m_Cs;
01155 float m_pixel;
01156 float m_voltage;
01157 float m_ctf_applied;
01158 float m_amp_contrast;
01159 vector< float > m_defocuses;
01160 vector< float > m_phis;
01161 vector< float > m_thetas;
01162 vector< float > m_psis;
01163 };
01164
01165 }
01166
01167 #endif
01168
01169