EMAN::FourierReconstructor Class Reference
[a function or class that is CUDA enabled]

Fourier space 3D reconstruction The Fourier reconstructor is designed to work in an iterative fashion, where similarity ("quality") metrics are used to determine if a slice should be inserted into the 3D in each subsequent iteration. More...

#include <reconstructor.h>

Inheritance diagram for EMAN::FourierReconstructor:

Inheritance graph
[legend]
Collaboration diagram for EMAN::FourierReconstructor:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 FourierReconstructor ()
 Default constructor calls load_default_settings().
virtual ~FourierReconstructor ()
 Deconstructor calls free_memory().
virtual void setup ()
 Setup the Fourier reconstructor
Exceptions:
InvalidValueException When one of the input parameters is invalid.

virtual void setup_seed (EMData *seed, float seed_weight)
 Initialize the reconstructor with a seed volume.
virtual EMDatapreprocess_slice (const EMData *const slice, const Transform &t=Transform())
 Preprocess the slice prior to insertion into the 3D volume this Fourier tranforms the slice and make sure all the pixels are in the right position it always returns a copy of the provided slice, so it should be deleted by someone eventually.
virtual int insert_slice (const EMData *const slice, const Transform &euler, const float weight=1.0)
 Insert a slice into a 3D volume, in a given orientation.
virtual int determine_slice_agreement (EMData *slice, const Transform &euler, const float weight=1.0, bool sub=true)
 Compares a slice to the current reconstruction volume and computes a normalization factor and quality.
virtual EMDatafinish (bool doift=true)
 Get the reconstructed volume Normally will return the volume in real-space with the requested size.
virtual void clear ()
 clear the volume and tmp_data for use in Monte Carlo reconstructions
virtual string get_name () const
 Get the unique name of the reconstructor.
virtual string get_desc () const
 Get the one line description of the reconstructor.
virtual TypeDict get_param_types () const
 Get the parameter types of this object.

Static Public Member Functions

static ReconstructorNEW ()
 Factory incorporation uses the pointer of this function.

Static Public Attributes

static const string NAME = "fourier"

Protected Member Functions

virtual void load_default_settings ()
 Load default settings.
virtual void free_memory ()
 Frees the memory owned by this object (but not parent objects) Deletes the FourierPixelInserter3D pointer.
virtual void load_inserter ()
 Load the pixel inserter based on the information in params.
virtual void do_insert_slice_work (const EMData *const input_slice, const Transform &euler, const float weight)
 A function to perform the nuts and bolts of inserting an image slice.
virtual void do_compare_slice_work (EMData *input_slice, const Transform &euler, float weight)
 A function to perform the nuts and bolts of comparing an image slice.
virtual bool pixel_at (const float &xx, const float &yy, const float &zz, float *dt)
 This is a mode-2 pixel extractor.

Protected Attributes

FourierPixelInserter3Dinserter
 A pixel inserter pointer which inserts pixels into the 3D volume using one of a variety of insertion methods.

Private Member Functions

 FourierReconstructor (const FourierReconstructor &that)
 Disallow copy construction.
FourierReconstructoroperator= (const FourierReconstructor &)
 Disallow assignment.

Detailed Description

Fourier space 3D reconstruction The Fourier reconstructor is designed to work in an iterative fashion, where similarity ("quality") metrics are used to determine if a slice should be inserted into the 3D in each subsequent iteration.

The client creates a Fourier reconstructor to insert real images into a 3D volume. The return image is a real space image

This reconstructor is based on EMAN1's Fourier reconstructor with a handful of modifications including 1. - Fourier ring correlation (FRC) as opposed to the mean phase residual is used to estimate slice quality. The FRC of the slice in the 3D volume is determined - but the slice is removed from the 3D volume before doing this so the score reflects the extent to which the slice agrees with the contribution of the other slices in the 3D volume. The FRC is converted to SNR using the relationship described by Penczek ( Three-dimensional spectral signal to noise ratio for a class of reconstruction algorithms, JSB 2002 138 (24-46) ) FRC = S/(sqrt(S+N1)sqrt(S+N2)) Where N1 is the noise in the slice of the 3D volume and N2 is the noise in the image slice being inserted. We make the assumption that the noise in the 3D volume is 0 (N1=0) to get FRC^2 = SNR/(1+SNR) which gives a spectral SNR plot - we then divide each SNR value by the number of particles in the class average (seeing as SNR should scale linearly with the number of particles) to get the estimated SNR per contributing particle in this class average. If the particles that have been averaged are not homogenous this score should be low etc. The scaled SNR curve is then converted back to a FRC curve and integrated. This integral is the similarity metric, and depends on how far information extends to in Fourier space - typical values range from 0.05 to 0.2, but can vary substantially depending on the data.

2 - Uses half of the memory used by EMAN1's equivalent reconstruction algorithm

        Reconstructor* r = Factory<Reconstructor>::get("fourier", params);
        r->setup();
        for k in 0:num_iterations-1
                // First do a round of slice quality (metric) determination - only possible if a 3D volume has
                // already been generated (k>0)
                if ( k  > 0 )
                        // Determine the agreement of the slices with the previous reconstructed volume (in memory)
                        for i in 0:num_slices-1
                                r->determine_slice_agreement(image[i], image[i].euler_orientation);

                // Insert the slices into the 3D volume
                // Will decide not to insert the slice if the its "quality" is not good enough
                for i in 0:num_slices-1
                        int failure = r->insert_slice(image[i], image[i].euler_orientation);
                        if ( failure ) cout << "Slice was not inserted due to poor quality" << endl;

        // Get the resulting volume
        EMData* result = r->finish();
        result->write_image("threed.mrc");

Definition at line 368 of file reconstructor.h.


Constructor & Destructor Documentation

EMAN::FourierReconstructor::FourierReconstructor (  )  [inline]

Default constructor calls load_default_settings().

Definition at line 374 of file reconstructor.h.

References load_default_settings().

Referenced by NEW().

00374 { load_default_settings(); }

virtual EMAN::FourierReconstructor::~FourierReconstructor (  )  [inline, virtual]

Deconstructor calls free_memory().

Definition at line 379 of file reconstructor.h.

References free_memory().

00379 { free_memory(); }

EMAN::FourierReconstructor::FourierReconstructor ( const FourierReconstructor that  )  [private]

Disallow copy construction.


Member Function Documentation

void FourierReconstructor::clear (  )  [virtual]

clear the volume and tmp_data for use in Monte Carlo reconstructions

Reimplemented from EMAN::Reconstructor.

Definition at line 517 of file reconstructor.cpp.

References EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::ReconstructorVolumeData::image, EMAN::ReconstructorVolumeData::tmp_data, EMAN::EMData::to_zero(), and to_zero_cuda().

00518 {
00519         bool zeroimage = true;
00520         bool zerotmpimg = true;
00521         
00522 #ifdef EMAN2_USING_CUDA
00523         if(EMData::usecuda == 1) {
00524                 if(image->cudarwdata) {
00525                         to_zero_cuda(image->cudarwdata,image->get_xsize(),image->get_ysize(),image->get_zsize());
00526                         zeroimage = false;
00527                 }
00528                 if(tmp_data->cudarwdata) {
00529                         //to_zero_cuda(tmp_data->cudarwdata,image->get_xsize(),image->get_ysize(),image->get_zsize());
00530                         zerotmpimg = false;
00531                 }
00532         }
00533 #endif
00534 
00535         if(zeroimage) image->to_zero();
00536         if(zerotmpimg) tmp_data->to_zero();
00537         
00538 }

int FourierReconstructor::determine_slice_agreement ( EMData slice,
const Transform euler,
const float  weight = 1.0,
bool  sub = true 
) [virtual]

Compares a slice to the current reconstruction volume and computes a normalization factor and quality.

Normalization and quality are returned via attributes set in the passed slice. You may freely mix calls to determine_slice_agreement with calls to insert_slice, but note that determine_slice_agreement can only use information from slices that have already been inserted. Attributes set in the slice are: reconstruct_norm the relative normalization factor which should be applied before inserting the slice reconstruct_qual a scaled quality factor (larger better) for this slice as compared to the existing reconstruction reconstruct_absqual the absolute (not scaled based on weight) quality factor comparing this slice to the existing reconstruction reconstruct_weight the summed weights from all voxels intersecting with the inserted slice, larger -> more overlap with other slices

Parameters:
input_slice The EMData slice to be compared
euler The orientation of the slice as a Transform object
weight A weighting factor for this slice, generally the number of particles in a class-average. May be ignored by some reconstructors
sub Flag indicating whether to subtract the slice from the volume before comparing. May be ignored by some reconstructors
Returns:
0 if OK. 1 if error.
Exceptions:
NullPointerException if the input EMData pointer is null
ImageFormatException if the image is complex as opposed to real

Reimplemented from EMAN::Reconstructor.

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 689 of file reconstructor.cpp.

References EMAN::EMData::copy(), do_compare_slice_work(), do_insert_slice_work(), EMAN::EMData::get_attr_default(), NullPointerException, preprocess_slice(), EMAN::EMData::set_attr(), EMAN::Transform::set_mirror(), EMAN::Transform::set_scale(), and EMAN::Transform::set_trans().

00690 {
00691         // Are these exceptions really necessary? (d.woolford)
00692         if (!input_slice) throw NullPointerException("EMData pointer (input image) is NULL");
00693 
00694 #ifdef EMAN2_USING_CUDA
00695         if(EMData::usecuda == 1) {
00696                 if(!input_slice->cudarwdata) input_slice->copy_to_cuda(); //copy slice to cuda using the const version
00697         }
00698 #endif
00699 
00700         Transform * rotation;
00701         rotation = new Transform(arg); // assignment operator
00702 
00703         EMData *slice;
00704         if (input_slice->get_attr_default("reconstruct_preproc",(int) 0)) slice=input_slice->copy();
00705         else slice = preprocess_slice( input_slice, *rotation);
00706 
00707 
00708         // We must use only the rotational component of the transform, scaling, translation and mirroring
00709         // are not implemented in Fourier space, but are in preprocess_slice
00710         rotation->set_scale(1.0);
00711         rotation->set_mirror(false);
00712         rotation->set_trans(0,0,0);
00713         if (sub) do_insert_slice_work(slice, *rotation, -weight);
00714         // Remove the current slice first (not threadsafe, but otherwise performance would be awful)
00715         
00716         // Compare
00717         do_compare_slice_work(slice, *rotation,weight);
00718 
00719         input_slice->set_attr("reconstruct_norm",slice->get_attr("reconstruct_norm"));
00720         input_slice->set_attr("reconstruct_absqual",slice->get_attr("reconstruct_absqual"));
00721 //      input_slice->set_attr("reconstruct_qual",slice->get_attr("reconstruct_qual"));
00722         input_slice->set_attr("reconstruct_weight",slice->get_attr("reconstruct_weight"));
00723 
00724         // Now put the slice back
00725         if (sub) do_insert_slice_work(slice, *rotation, weight);
00726 
00727         delete rotation;
00728         delete slice;
00729 
00730 //      image->update();
00731         return 0;
00732 
00733 }

void FourierReconstructor::do_compare_slice_work ( EMData input_slice,
const Transform euler,
float  weight 
) [protected, virtual]

A function to perform the nuts and bolts of comparing an image slice.

Parameters:
input_slice the slice to insert into the 3D volume
euler a transform storing the slice euler angle

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 735 of file reconstructor.cpp.

References EMAN::Transform::copy_matrix_into_array(), determine_slice_agreement_cuda(), EMAN::dot(), dt, EMAN::EMData::get_data(), EMAN::Symmetry3D::get_symmetries(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::ReconstructorVolumeData::image, EMAN::ReconstructorVolumeData::nx, EMAN::ReconstructorVolumeData::ny, EMAN::ReconstructorVolumeData::nz, EMAN::FactoryBase::params, pixel_at(), power(), EMAN::EMData::set_attr(), sqrt(), EMAN::ReconstructorVolumeData::subnx, EMAN::ReconstructorVolumeData::subny, EMAN::ReconstructorVolumeData::subnz, EMAN::ReconstructorVolumeData::tmp_data, x, and y.

Referenced by determine_slice_agreement().

00736 {
00737 
00738         float dt[3];    // This stores the complex and weight from the volume
00739         float dt2[2];   // This stores the local image complex
00740         float *dat = input_slice->get_data();
00741         vector<Transform> syms = Symmetry3D::get_symmetries((string)params["sym"]);
00742 
00743         float inx=(float)(input_slice->get_xsize());            // x/y dimensions of the input image
00744         float iny=(float)(input_slice->get_ysize());
00745 
00746         double dot=0;           // summed pixel*weight dot product
00747         double vweight=0;               // sum of weights
00748         double power=0;         // sum of inten*weight from volume
00749         double power2=0;                // sum of inten*weight from image
00750         bool use_cpu = true;
00751         
00752 #ifdef EMAN2_USING_CUDA
00753         if(EMData::usecuda == 1) {
00754                 if(!input_slice->cudarwdata) input_slice->copy_to_cuda();
00755                 if(!image->cudarwdata){
00756                         image->copy_to_cuda();
00757                         tmp_data->copy_to_cuda();
00758                 }
00759                 for ( vector<Transform>::const_iterator it = syms.begin(); it != syms.end(); ++it ) {
00760                         Transform t3d = arg*(*it);
00761                         float * m = new float[12];
00762                         t3d.copy_matrix_into_array(m);
00763                         float4 stats = determine_slice_agreement_cuda(m,input_slice->cudarwdata,image->cudarwdata,tmp_data->cudarwdata,inx,iny,image->get_xsize(),image->get_ysize(),image->get_zsize(), weight);
00764                         dot = stats.x;
00765                         vweight = stats.y;
00766                         power = stats.z;
00767                         power2 = stats.w;
00768                         //cout << "CUDA stats " << stats.x << " " << stats.y << " " << stats.z << " " << stats.w << endl;
00769                         use_cpu = false;
00770                 }
00771         }
00772 #endif
00773         if(use_cpu) {
00774                 for ( vector<Transform>::const_iterator it = syms.begin(); it != syms.end(); ++it ) {
00775                         Transform t3d = arg*(*it);
00776                         for (int y = -iny/2; y < iny/2; y++) {
00777                                 for (int x = 0; x <=  inx/2; x++) {
00778                                         if (x==0 && y==0) continue;             // We don't want to use the Fourier origin
00779 
00780                                         float rx = (float) x/(inx-2);   // coords relative to Nyquist=.5
00781                                         float ry = (float) y/iny;
00782 
00783 //                                      if ((rx * rx + Util::square(ry - max_input_dim "xform.projection"/ 2)) > rl)
00784 //                                      continue;
00785 
00786                                         Vec3f coord(rx,ry,0);
00787                                         coord = coord*t3d; // transpose multiplication
00788                                         float xx = coord[0]; // transformed coordinates in terms of Nyquist
00789                                         float yy = coord[1];
00790                                         float zz = coord[2];
00791 
00792 
00793                                         if (fabs(xx)>0.5 || fabs(yy)>=0.5 || fabs(zz)>=0.5) continue;
00794 
00795                                         // Map back to actual pixel coordinates in output volume
00796                                         xx=xx*(nx-2);
00797                                         yy=yy*ny;
00798                                         zz=zz*nz;
00799 
00800 
00801                                         int idx = (int)(x * 2 + inx*(y<0?iny+y:y));
00802                                         dt2[0] = dat[idx];
00803                                         dt2[1] = dat[idx+1];
00804 
00805                                         // value returned indirectly in dt
00806                                         if (!pixel_at(xx,yy,zz,dt) || dt[2]==0) continue;
00807 
00808 //                                      printf("%f\t%f\t%f\t%f\t%f\n",dt[0],dt[1],dt[2],dt2[0],dt2[1]);
00809                                         dot+=(dt[0]*dt2[0]+dt[1]*dt2[1])*dt[2];
00810                                         vweight+=dt[2];
00811                                         power+=(dt[0]*dt[0]+dt[1]*dt[1])*dt[2];
00812                                         power2+=(dt2[0]*dt2[0]+dt2[1]*dt2[1])*dt[2];
00813                                 }
00814                         }
00815                         //cout << dot << " " << vweight << " " << power << " " << power2 << endl;
00816                 }
00817         }
00818         
00819         dot/=sqrt(power*power2);                // normalize the dot product
00820 //      input_slice->set_attr("reconstruct_norm",(float)(power2<=0?1.0:sqrt(power/power2)/(inx*iny)));
00821         input_slice->set_attr("reconstruct_norm",(float)(power2<=0?1.0:sqrt(power/power2)));
00822         input_slice->set_attr("reconstruct_absqual",(float)dot);
00823         float rw=weight<=0?1.0f:1.0f/weight;
00824         input_slice->set_attr("reconstruct_qual",(float)(dot*rw/((rw-1.0)*dot+1.0)));   // here weight is a proxy for SNR
00825         input_slice->set_attr("reconstruct_weight",(float)vweight/(float)(subnx*subny*subnz));
00826 //      printf("** %g\t%g\t%g\t%g ##\n",dot,vweight,power,power2);
00827         //printf("** %f %f %f ##\n",(float)(power2<=0?1.0:sqrt(power/power2)/(inx*iny)),(float)dot,(float)(dot*weight/((weight-1.0)*dot+1.0)));
00828 }

void FourierReconstructor::do_insert_slice_work ( const EMData *const   input_slice,
const Transform euler,
const float  weight 
) [protected, virtual]

A function to perform the nuts and bolts of inserting an image slice.

Parameters:
input_slice the slice to insert into the 3D volume
euler a transform storing the slice euler angle
weight weighting factor for this slice (usually number of particles in a class-average)

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 622 of file reconstructor.cpp.

References EMAN::Transform::copy_matrix_into_array(), EMAN::EMData::get_complex_at(), EMAN::Symmetry3D::get_symmetries(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::ReconstructorVolumeData::image, EMAN::FourierPixelInserter3D::insert_pixel(), insert_slice_cuda(), inserter, EMAN::ReconstructorVolumeData::nx, EMAN::ReconstructorVolumeData::ny, EMAN::ReconstructorVolumeData::nz, EMAN::FactoryBase::params, EMAN::ReconstructorVolumeData::tmp_data, x, and y.

Referenced by determine_slice_agreement(), and insert_slice().

00623 {
00624         // Reload the inserter if the mode has changed
00625 //      string mode = (string) params["mode"];
00626 //      if ( mode != inserter->get_name() )     load_inserter();
00627 
00628 //      int y_in = input_slice->get_ysize();
00629 //      int x_in = input_slice->get_xsize();
00630 //      // Adjust the dimensions to account for odd and even ffts
00631 //      if (input_slice->is_fftodd()) x_in -= 1;
00632 //      else x_in -= 2;
00633 
00634         vector<Transform> syms = Symmetry3D::get_symmetries((string)params["sym"]);
00635 
00636         float inx=(float)(input_slice->get_xsize());            // x/y dimensions of the input image
00637         float iny=(float)(input_slice->get_ysize());
00638 
00639 #ifdef EMAN2_USING_CUDA
00640         if(EMData::usecuda == 1) {
00641                 if(!image->cudarwdata){
00642                         image->copy_to_cuda();
00643                         tmp_data->copy_to_cuda();
00644                 }
00645                 float * m = new float[12];
00646                 for ( vector<Transform>::const_iterator it = syms.begin(); it != syms.end(); ++it ) {
00647                         Transform t3d = arg*(*it);
00648                         t3d.copy_matrix_into_array(m);
00649                         //cout << "using CUDA " << image->cudarwdata << endl;
00650                         insert_slice_cuda(m,input_slice->cudarwdata,image->cudarwdata,tmp_data->cudarwdata,inx,iny,image->get_xsize(),image->get_ysize(),image->get_zsize(), weight);
00651                 }
00652                 delete m;
00653                 return;
00654         }
00655 #endif
00656         for ( vector<Transform>::const_iterator it = syms.begin(); it != syms.end(); ++it ) {
00657                 Transform t3d = arg*(*it);
00658                 for (int y = -iny/2; y < iny/2; y++) {
00659                         for (int x = 0; x <=  inx/2; x++) {
00660 
00661                                 float rx = (float) x/(inx-2.0f);        // coords relative to Nyquist=.5
00662                                 float ry = (float) y/iny;
00663 
00664                                 Vec3f coord(rx,ry,0);
00665                                 coord = coord*t3d; // transpose multiplication
00666                                 float xx = coord[0]; // transformed coordinates in terms of Nyquist
00667                                 float yy = coord[1];
00668                                 float zz = coord[2];
00669 
00670                                 // Map back to real pixel coordinates in output volume
00671                                 xx=xx*(nx-2);
00672                                 yy=yy*ny;
00673                                 zz=zz*nz;
00674 
00675 //                              if (x==10 && y==0) printf("10,0 -> %1.2f,%1.2f,%1.2f\t(%5.2f %5.2f %5.2f   %5.2f %5.2f %5.2f   %5.2f %5.2f %5.2f) %1.0f %d\n",
00676 //                                      xx,yy,zz,t3d.at(0,0),t3d.at(0,1),t3d.at(0,2),t3d.at(1,0),t3d.at(1,1),t3d.at(1,2),t3d.at(2,0),t3d.at(2,1),t3d.at(2,2),inx,nx);
00677 //                              if (x==0 && y==10 FourierReconstructor:) printf("0,10 -> %1.2f,%1.2f,%1.2f\t(%5.2f %5.2f %5.2f   %5.2f %5.2f %5.2f   %5.2f %5.2f %5.2f)\n",
00678 //                                      xx,yy,zz,t3d.at(0,0),t3d.at(0,1),t3d.at(0,2),t3d.at(1,0),t3d.at(1,1),t3d.at(1,2),t3d.at(2,0),t3d.at(2,1),t3d.at(2,2));
00679 
00680                                 //printf("%3.1f %3.1f %3.1f\t %1.4f %1.4f\t%1.4f\n",xx,yy,zz,input_slice->get_complex_at(x,y).real(),input_slice->get_complex_at(x,y).imag(),weight);
00681 //                              if (floor(xx)==45 && floor(yy)==45 &&floor(zz)==0) printf("%d. 45 45 0\t %d %d\t %1.4f %1.4f\t%1.4f\n",(int)input_slice->get_attr("n"),x,y,input_slice->get_complex_at(x,y).real(),input_slice->get_complex_at(x,y).imag(),weight);
00682 //                              if (floor(xx)==21 && floor(yy)==21 &&floor(zz)==0) printf("%d. 21 21 0\t %d %d\t %1.4f %1.4f\t%1.4f\n",(int)input_slice->get_attr("n"),x,y,input_slice->get_complex_at(x,y).real(),input_slice->get_complex_at(x,y).imag(),weight);
00683                                 inserter->insert_pixel(xx,yy,zz,input_slice->get_complex_at(x,y),weight);
00684                         }
00685                 }
00686         }
00687 }

EMData * FourierReconstructor::finish ( bool  doift = true  )  [virtual]

Get the reconstructed volume Normally will return the volume in real-space with the requested size.

The calling application is responsible for removing any padding.

Parameters:
doift A flag indicating whether the returned object should be guaranteed to be in real-space (true) or should be left in whatever space the reconstructor generated
Returns:
The real space reconstructed volume

Reimplemented from EMAN::Reconstructor.

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 904 of file reconstructor.cpp.

References EMAN::EMData::depad(), EMAN::EMData::do_ift_inplace(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), EMAN::ReconstructorVolumeData::image, EMAN::ReconstructorVolumeData::normalize_threed(), EMAN::FactoryBase::params, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::ReconstructorVolumeData::tmp_data, EMAN::EMData::update(), and EMAN::EMData::write_image().

00905 {
00906 //      float *norm = tmp_data->get_data();
00907 //      float *rdata = image->get_data();
00908 #ifdef EMAN2_USING_CUDA
00909         if(image->cudarwdata){
00910                 cout << "copy back from CUDA" << endl;
00911                 image->copy_from_device();
00912                 tmp_data->copy_from_device();
00913         }
00914 #endif
00915         
00916         bool sqrtnorm=params.set_default("sqrtnorm",false);
00917         normalize_threed(sqrtnorm);
00918         
00919 //      tmp_data->write_image("density.mrc");
00920 
00921         // we may as well delete the tmp data now... it saves memory and the calling program might
00922         // need memory after it gets the return volume.
00923         // If this delete didn't happen now, it would happen when the deconstructor was called --david
00924         // no longer a good idea with the new iterative scheme -- steve
00925 //      if ( tmp_data != 0 )
00926 //      {
00927 //              delete tmp_data;
00928 //              tmp_data = 0;
00929 //      }
00930 
00931 /*      image->process_inplace("xform.fourierorigin.tocorner");*/
00932 
00933         if (doift) {
00934                 image->do_ift_inplace();
00935                 image->depad();
00936                 image->process_inplace("xform.phaseorigin.tocenter");
00937         }
00938         // If the image was padded it should be the original size, as the client would expect
00939         //  I blocked the rest, it is almost certainly incorrect  PAP 07/31/08
00940         // No, it's not incorrect. You are wrong. You have the meaning of nx mixed up. DSAW 09/23/cd
00941         // This should now be handled in the calling program --steve 11/03/09
00942 //      bool is_fftodd = (nx % 2 == 1);
00943 //      if ( (nx-2*(!is_fftodd)) != output_x || ny != output_y || nz != output_z )
00944 //      {
00945 //              FloatPoint origin( (nx-output_x)/2, (ny-output_y)/2, (nz-output_z)/2 );
00946 //              FloatSize region_size( output_x, output_y, output_z);
00947 //              Region clip_region( origin, region_size );
00948 //              image->clip_inplace( clip_region );
00949 //      }
00950 
00951         // Should be an "if (verbose)" here or something
00952         //print_stats(quality_scores);
00953 
00954         image->update();
00955         
00956         if (params.has_key("savenorm") && strlen((const char *)params["savenorm"])>0) {
00957                 if (tmp_data->get_ysize()%2==0 && tmp_data->get_zsize()%2==0) tmp_data->process_inplace("xform.fourierorigin.tocenter");
00958                 tmp_data->write_image((const char *)params["savenorm"]);
00959         }
00960 
00961         delete tmp_data;
00962         tmp_data=0;
00963         EMData *ret=image;
00964         image=0;
00965         
00966         return ret;
00967 }

void FourierReconstructor::free_memory (  )  [protected, virtual]

Frees the memory owned by this object (but not parent objects) Deletes the FourierPixelInserter3D pointer.

Reimplemented from EMAN::ReconstructorVolumeData.

Definition at line 331 of file reconstructor.cpp.

References EMAN::ReconstructorVolumeData::image, inserter, and EMAN::ReconstructorVolumeData::tmp_data.

Referenced by ~FourierReconstructor().

00332 {
00333         if (image) { delete image; image=0; }
00334         if (tmp_data) { delete tmp_data; tmp_data=0; }
00335         if ( inserter != 0 )
00336         {
00337                 delete inserter;
00338                 inserter = 0;
00339         }
00340 }

virtual string EMAN::FourierReconstructor::get_desc (  )  const [inline, virtual]

Get the one line description of the reconstructor.

Implements EMAN::FactoryBase.

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 457 of file reconstructor.h.

00458                 {
00459                         return "Reconstruction via direct Fourier methods using one of a variety of different kernels, most of which are Gaussian based";
00460                 }

virtual string EMAN::FourierReconstructor::get_name (  )  const [inline, virtual]

Get the unique name of the reconstructor.

Implements EMAN::FactoryBase.

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 450 of file reconstructor.h.

References NAME.

00451                 {
00452                         return NAME;
00453                 }

virtual TypeDict EMAN::FourierReconstructor::get_param_types (  )  const [inline, virtual]

Get the parameter types of this object.

Returns:
a TypeDict detailing all of the acceptable (and necessary) parameters

Implements EMAN::FactoryBase.

Definition at line 473 of file reconstructor.h.

References EMAN::EMObject::BOOL, EMAN::EMObject::INTARRAY, EMAN::TypeDict::put(), and EMAN::EMObject::STRING.

00474                 {
00475                         TypeDict d;
00476                         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.");
00477                         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");
00478                         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.");
00479                         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.");
00480                         d.put("verbose", EMObject::BOOL, "Optional. Toggles writing useful information to standard out. Default is false.");
00481                         d.put("subvolume",EMObject::INTARRAY, "Optional. (xorigin,yorigin,zorigin,xsize,ysize,zsize) all in Fourier pixels. Useful for parallelism.");
00482                         d.put("savenorm",EMObject::STRING, "Debug. Will cause the normalization volume to be written directly to the specified file when finish() is called.");
00483                         return d;
00484                 }

int FourierReconstructor::insert_slice ( const EMData *const   slice,
const Transform euler,
const float  weight = 1.0 
) [virtual]

Insert a slice into a 3D volume, in a given orientation.

Returns:
0 if successful, 1 otherwise
Parameters:
slice the image slice to be inserted into the 3D volume
euler Euler angle of this image slice.
weight A weighting factor for this slice, generally the number of particles in a class-average. May be ignored by some reconstructors
Returns:
0 if OK. 1 if error.
Exceptions:
NullPointerException if the input EMData pointer is null
ImageFormatException if the image is complex as opposed to real

Reimplemented from EMAN::Reconstructor.

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 582 of file reconstructor.cpp.

References EMAN::EMData::copy(), do_insert_slice_work(), EMAN::EMData::get_attr_default(), NullPointerException, preprocess_slice(), EMAN::Transform::set_mirror(), EMAN::Transform::set_scale(), and EMAN::Transform::set_trans().

00583 {
00584         // Are these exceptions really necessary? (d.woolford)
00585         if (!input_slice) throw NullPointerException("EMData pointer (input image) is NULL");
00586 
00587 #ifdef EMAN2_USING_CUDA
00588         if(EMData::usecuda == 1) {
00589                 if(!input_slice->cudarwdata) input_slice->copy_to_cuda(); //copy slice to cuda using the const version
00590         }
00591 #endif
00592 
00593         Transform * rotation;
00594 /*      if ( input_slice->has_attr("xform.projection") ) {
00595                 rotation = (Transform*) (input_slice->get_attr("xform.projection")); // assignment operator
00596         } else {*/
00597         rotation = new Transform(arg); // assignment operator
00598 //      }
00599 
00600         EMData *slice;
00601         if (input_slice->get_attr_default("reconstruct_preproc",(int) 0)) slice=input_slice->copy();
00602         else slice = preprocess_slice( input_slice, *rotation);
00603 
00604 
00605         // We must use only the rotational component of the transform, scaling, translation and mirroring
00606         // are not implemented in Fourier space, but are in preprocess_slice
00607         rotation->set_scale(1.0);
00608         rotation->set_mirror(false);
00609         rotation->set_trans(0,0,0);
00610 
00611         // Finally to the pixel wise slice insertion
00612         //slice->copy_to_cuda();
00613         do_insert_slice_work(slice, *rotation, weight);
00614         
00615         delete rotation; rotation=0;
00616         delete slice;
00617 
00618 //      image->update();
00619         return 0;
00620 }

void FourierReconstructor::load_default_settings (  )  [protected, virtual]

Load default settings.

Definition at line 324 of file reconstructor.cpp.

References EMAN::ReconstructorVolumeData::image, inserter, and EMAN::ReconstructorVolumeData::tmp_data.

Referenced by FourierReconstructor().

00325 {
00326         inserter=0;
00327         image=0;
00328         tmp_data=0;
00329 }

void FourierReconstructor::load_inserter (  )  [protected, virtual]

Load the pixel inserter based on the information in params.

Definition at line 344 of file reconstructor.cpp.

References EMAN::EMData::get_data(), EMAN::ReconstructorVolumeData::image, EMAN::FourierPixelInserter3D::init(), inserter, EMAN::FactoryBase::params, and EMAN::ReconstructorVolumeData::tmp_data.

Referenced by setup(), and setup_seed().

00345 {
00346 //      ss
00347 //      string mode = (string)params["mode"];
00348         Dict parms;
00349         parms["data"] = image;
00350         parms["norm"] = tmp_data->get_data();
00351         // These aren't necessary because we deal with them before calling the inserter
00352 //      parms["subnx"] = nx;
00353 //      parms["subny"] = ny;
00354 //      parms["subnx"] = nz;
00355 //      parms["subx0"] = x0;
00356 //      parms["suby0"] = y0;
00357 //      parms["subz0"] = z0;
00358 
00359         if ( inserter != 0 )
00360         {
00361                 delete inserter;
00362         }
00363 
00364         inserter = Factory<FourierPixelInserter3D>::get((string)params["mode"], parms);
00365         inserter->init();
00366 }

static Reconstructor* EMAN::FourierReconstructor::NEW (  )  [inline, static]

Factory incorporation uses the pointer of this function.

Returns:
a Reconstructor pointer to a newly allocated FourierReconstructor

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 465 of file reconstructor.h.

References FourierReconstructor().

00466                 {
00467                         return new FourierReconstructor();
00468                 }

FourierReconstructor& EMAN::FourierReconstructor::operator= ( const FourierReconstructor  )  [private]

Disallow assignment.

bool FourierReconstructor::pixel_at ( const float &  xx,
const float &  yy,
const float &  zz,
float *  dt 
) [protected, virtual]

This is a mode-2 pixel extractor.

Parameters:
xx,yy,zz voxel coordinates (need not be integers)
dt float pointer with 3 floats allocated for returned complex value and weight sum

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 830 of file reconstructor.cpp.

References EMAN::Util::fast_exp(), EMAN::EMData::get_complex_index(), EMAN::EMData::get_complex_index_fast(), EMAN::EMData::get_data(), EMAN::Util::hypot3sq(), EMAN::EMConsts::I2G, EMAN::ReconstructorVolumeData::image, norm(), EMAN::ReconstructorVolumeData::nx, EMAN::ReconstructorVolumeData::nx2, EMAN::ReconstructorVolumeData::ny, EMAN::ReconstructorVolumeData::ny2, EMAN::ReconstructorVolumeData::nz, EMAN::ReconstructorVolumeData::nz2, rdata, EMAN::ReconstructorVolumeData::subnx, EMAN::ReconstructorVolumeData::subx0, EMAN::ReconstructorVolumeData::suby0, EMAN::ReconstructorVolumeData::subz0, and EMAN::ReconstructorVolumeData::tmp_data.

Referenced by do_compare_slice_work().

00831 {
00832         int x0 = (int) floor(xx);
00833         int y0 = (int) floor(yy);
00834         int z0 = (int) floor(zz);
00835         
00836         float *rdata=image->get_data();
00837         float *norm=tmp_data->get_data();
00838         float normsum=0,normsum2=0;
00839 
00840         dt[0]=dt[1]=dt[2]=0.0;
00841 
00842         if (nx==subnx) {                        // normal full reconstruction
00843                 if (x0<-nx2-1 || y0<-ny2-1 || z0<-nz2-1 || x0>nx2 || y0>ny2 || z0>nz2 ) return false;
00844 
00845                 // no error checking on add_complex_fast, so we need to be careful here
00846                 int x1=x0+1;
00847                 int y1=y0+1;
00848                 int z1=z0+1;
00849                 if (x0<-nx2) x0=-nx2;
00850                 if (x1>nx2) x1=nx2;
00851                 if (y0<-ny2) y0=-ny2;
00852                 if (y1>ny2) y1=ny2;
00853                 if (z0<-nz2) z0=-nz2;
00854                 if (z1>nz2) z1=nz2;
00855                 
00856                 size_t idx=0;
00857                 float r, gg;
00858                 for (int k = z0 ; k <= z1; k++) {
00859                         for (int j = y0 ; j <= y1; j++) {
00860                                 for (int i = x0; i <= x1; i ++) {
00861                                         r = Util::hypot3sq((float) i - xx, j - yy, k - zz);
00862                                         idx=image->get_complex_index_fast(i,j,k);
00863                                         gg = Util::fast_exp(-r / EMConsts::I2G);
00864                                         
00865                                         dt[0]+=gg*rdata[idx];
00866                                         dt[1]+=(i<0?-1.0f:1.0f)*gg*rdata[idx+1];
00867                                         dt[2]+=norm[idx/2]*gg;
00868                                         normsum2+=gg;
00869                                         normsum+=gg*norm[idx/2];                                
00870                                 }
00871                         }
00872                 }
00873                 if (normsum==0) return false;
00874                 dt[0]/=normsum;
00875                 dt[1]/=normsum;
00876                 dt[2]/=normsum2;
00877 //              printf("%1.2f,%1.2f,%1.2f\t%1.3f\t%1.3f\t%1.3f\t%1.3f\t%1.3f\n",xx,yy,zz,dt[0],dt[1],dt[2],rdata[idx],rdata[idx+1]);
00878                 return true;
00879         } 
00880         else {                                  // for subvolumes, not optimized yet
00881                 size_t idx;
00882                 float r, gg;
00883                 for (int k = z0 ; k <= z0 + 1; k++) {
00884                         for (int j = y0 ; j <= y0 + 1; j++) {
00885                                 for (int i = x0; i <= x0 + 1; i ++) {
00886                                         r = Util::hypot3sq((float) i - xx, j - yy, k - zz);
00887                                         idx=image->get_complex_index(i,j,k,subx0,suby0,subz0,nx,ny,nz);
00888                                         gg = Util::fast_exp(-r / EMConsts::I2G)*norm[idx/2];
00889                                         
00890                                         dt[0]+=gg*rdata[idx];
00891                                         dt[1]+=(i<0?-1.0f:1.0f)*gg*rdata[idx+1];
00892                                         dt[2]+=norm[idx/2];
00893                                         normsum+=gg;                            
00894                                 }
00895                         }
00896                 }
00897                 
00898                 if (normsum==0)  return false;
00899                 return true;
00900         }
00901 }

EMData * FourierReconstructor::preprocess_slice ( const EMData *const   slice,
const Transform t = Transform() 
) [virtual]

Preprocess the slice prior to insertion into the 3D volume this Fourier tranforms the slice and make sure all the pixels are in the right position it always returns a copy of the provided slice, so it should be deleted by someone eventually.

Returns:
the processed slice
Parameters:
slice the slice to be prepocessed
t transform to be used for insertion
Exceptions:
InvalidValueException when the specified padding value is less than the size of the images

Reimplemented from EMAN::Reconstructor.

Definition at line 540 of file reconstructor.cpp.

References EMAN::EMData::copy(), EMAN::EMData::do_fft_inplace(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::Transform::is_identity(), EMAN::EMData::mult(), EMAN::EMData::process(), EMAN::EMData::process_inplace(), EMAN::EMData::set_attr(), EMAN::Transform::set_rotation(), sqrt(), and t.

Referenced by EMAN::WienerFourierReconstructor::determine_slice_agreement(), determine_slice_agreement(), EMAN::WienerFourierReconstructor::insert_slice(), and insert_slice().

00541 {
00542 #ifdef EMAN2_USING_CUDA
00543         if(EMData::usecuda == 1) {
00544                 if(!slice->cudarwdata) slice->copy_to_cuda(); //copy slice to cuda using the const version
00545         }
00546 #endif
00547         // Shift the image pixels so the real space origin is now located at the phase origin (at the bottom left of the image)
00548         EMData* return_slice = 0;
00549         Transform tmp(t);
00550         tmp.set_rotation(Dict("type","eman")); // resets the rotation to 0 implicitly, this way we only do 2d translation,scaling and mirroring
00551 
00552         if (tmp.is_identity()) return_slice=slice->copy();
00553         else return_slice = slice->process("xform",Dict("transform",&tmp));
00554 
00555         return_slice->process_inplace("xform.phaseorigin.tocorner");
00556 
00557 //      printf("@@@ %d\n",(int)return_slice->get_attr("nx"));
00558         // Fourier transform the slice
00559         
00560 #ifdef EMAN2_USING_CUDA
00561         if(return_slice->cudarwdata) {
00562                 return_slice->do_fft_inplace_cuda(); //a CUDA FFT inplace is quite slow as there is a lot of mem copying.
00563         }else{
00564                 return_slice->do_fft_inplace();
00565         }
00566 #else
00567         return_slice->do_fft_inplace();
00568 #endif
00569 
00570 //      printf("%d\n",(int)return_slice->get_attr("nx"));
00571 
00572         return_slice->mult((float)sqrt(1.0f/(return_slice->get_ysize())*return_slice->get_xsize()));
00573 
00574         // Shift the Fourier transform so that it's origin is in the center (bottom) of the image.
00575 //      return_slice->process_inplace("xform.fourierorigin.tocenter");
00576 
00577         return_slice->set_attr("reconstruct_preproc",(int)1);
00578         return return_slice;
00579 }

void FourierReconstructor::setup (  )  [virtual]

Setup the Fourier reconstructor

Exceptions:
InvalidValueException When one of the input parameters is invalid.

Implements EMAN::Reconstructor.

Definition at line 368 of file reconstructor.cpp.

References EMAN::Dict::has_key(), EMAN::ReconstructorVolumeData::image, ImageDimensionException, is_fftodd(), load_inserter(), EMAN::ReconstructorVolumeData::nx, EMAN::ReconstructorVolumeData::nx2, EMAN::ReconstructorVolumeData::ny, EMAN::ReconstructorVolumeData::ny2, EMAN::ReconstructorVolumeData::nz, EMAN::ReconstructorVolumeData::nz2, EMAN::FactoryBase::params, EMAN::EMData::set_attr(), EMAN::EMData::set_complex(), EMAN::Dict::set_default(), EMAN::EMData::set_fftodd(), EMAN::EMData::set_ri(), EMAN::EMData::set_size(), sub(), EMAN::ReconstructorVolumeData::subnx, EMAN::ReconstructorVolumeData::subny, EMAN::ReconstructorVolumeData::subnz, EMAN::ReconstructorVolumeData::subx0, EMAN::ReconstructorVolumeData::suby0, EMAN::ReconstructorVolumeData::subz0, EMAN::ReconstructorVolumeData::tmp_data, EMAN::EMData::to_zero(), and EMAN::EMData::update().

00369 {
00370         // default setting behavior - does not override if the parameter is already set
00371         params.set_default("mode","gauss_2");
00372 
00373         vector<int> size=params["size"];
00374 
00375         nx = size[0];
00376         ny = size[1];
00377         nz = size[2];
00378         nx2=nx/2-1;
00379         ny2=ny/2;
00380         nz2=nz/2;
00381 
00382 
00383         // Adjust nx if for Fourier transform even odd issues
00384         bool is_fftodd = (nx % 2 == 1);
00385         // The Fourier transform requires one extra pixel in the x direction,
00386         // which is two spaces in memory, one each for the complex and the
00387         // real components
00388         nx += 2-is_fftodd;
00389 
00390         if (params.has_key("subvolume")) {
00391                 vector<int> sub=params["subvolume"];
00392                 subx0=sub[0];
00393                 suby0=sub[1];
00394                 subz0=sub[2];
00395                 subnx=sub[3];
00396                 subny=sub[4];
00397                 subnz=sub[5];
00398 
00399                 if (subx0<0 || suby0<0 || subz0<0 || subx0+subnx>nx || suby0+subny>ny || subz0+subnz>nz)
00400                         throw ImageDimensionException("The subvolume cannot extend outside the reconstructed volume");
00401 
00402         }
00403         else {
00404                 subx0=suby0=subz0=0;
00405                 subnx=nx;
00406                 subny=ny;
00407                 subnz=nz;
00408         }
00409 
00410 
00411         // Odd dimension support is here atm, but not above.
00412         if (image) delete image;
00413         image = new EMData();
00414         image->set_size(subnx, subny, subnz);
00415         image->set_complex(true);
00416         image->set_fftodd(is_fftodd);
00417         image->set_ri(true);
00418 //      printf("%d %d %d\n\n",subnx,subny,subnz);
00419         image->to_zero();
00420 
00421         if (params.has_key("subvolume")) {
00422                 image->set_attr("subvolume_x0",subx0);
00423                 image->set_attr("subvolume_y0",suby0);
00424                 image->set_attr("subvolume_z0",subz0);
00425                 image->set_attr("subvolume_full_nx",nx);
00426                 image->set_attr("subvolume_full_ny",ny);
00427                 image->set_attr("subvolume_full_nz",nz);
00428         }
00429         
00430         if (tmp_data) delete tmp_data;
00431         tmp_data = new EMData();
00432         tmp_data->set_size(subnx/2, subny, subnz);
00433         tmp_data->to_zero();
00434         tmp_data->update();
00435 
00436         load_inserter();
00437 
00438         if ( (bool) params["quiet"] == false )
00439         {
00440                 cout << "3D Fourier dimensions are " << nx << " " << ny << " " << nz << endl;
00441                 cout << "3D Fourier subvolume is " << subnx << " " << subny << " " << subnz << endl;
00442                 printf ("You will require approximately %1.3g GB of memory to reconstruct this volume\n",((float)subnx*subny*subnz*sizeof(float)*1.5)/1000000000.0);
00443         }
00444 }

void FourierReconstructor::setup_seed ( EMData seed,
float  seed_weight 
) [virtual]

Initialize the reconstructor with a seed volume.

This can be used to provide some 'default' value when there is missing data in Fourier space. The passed 'seed' must be of the appropriate padded size, must be in Fourier space, and the same EMData* object will be returned by finish(), meaning the Reconstructor is implicitly taking ownership of the object. However, in Python, this means the seed may be passed in without copying, as the same EMData will be coming back out at the end. The seed_weight determines how 'strong' the seed volume should be as compared to other inserted slices in Fourier space.

Exceptions:
InvalidValueException When one of the input parameters is invalid

Reimplemented from EMAN::Reconstructor.

Definition at line 446 of file reconstructor.cpp.

References EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), EMAN::ReconstructorVolumeData::image, ImageDimensionException, EMAN::EMData::is_complex(), is_fftodd(), load_inserter(), EMAN::ReconstructorVolumeData::nx, EMAN::ReconstructorVolumeData::nx2, EMAN::ReconstructorVolumeData::ny, EMAN::ReconstructorVolumeData::ny2, EMAN::ReconstructorVolumeData::nz, EMAN::ReconstructorVolumeData::nz2, EMAN::FactoryBase::params, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), sub(), EMAN::ReconstructorVolumeData::subnx, EMAN::ReconstructorVolumeData::subny, EMAN::ReconstructorVolumeData::subnz, EMAN::ReconstructorVolumeData::subx0, EMAN::ReconstructorVolumeData::suby0, EMAN::ReconstructorVolumeData::subz0, EMAN::ReconstructorVolumeData::tmp_data, and EMAN::EMData::to_value().

00446                                                                     {
00447         // default setting behavior - does not override if the parameter is already set
00448         params.set_default("mode","gauss_2");
00449 
00450         vector<int> size=params["size"];
00451 
00452         nx = size[0];
00453         ny = size[1];
00454         nz = size[2];
00455         nx2=nx/2-1;
00456         ny2=ny/2;
00457         nz2=nz/2;
00458 
00459 
00460         // Adjust nx if for Fourier transform even odd issues
00461         bool is_fftodd = (nx % 2 == 1);
00462         // The Fourier transform requires one extra pixel in the x direction,
00463         // which is two spaces in memory, one each for the complex and the
00464         // real components
00465         nx += 2-is_fftodd;
00466 
00467         if (params.has_key("subvolume")) {
00468                 vector<int> sub=params["subvolume"];
00469                 subx0=sub[0];
00470                 suby0=sub[1];
00471                 subz0=sub[2];
00472                 subnx=sub[3];
00473                 subny=sub[4];
00474                 subnz=sub[5];
00475 
00476                 if (subx0<0 || suby0<0 || subz0<0 || subx0+subnx>nx || suby0+subny>ny || subz0+subnz>nz)
00477                         throw ImageDimensionException("The subvolume cannot extend outside the reconstructed volume");
00478 
00479         }
00480         else {
00481                 subx0=suby0=subz0=0;
00482                 subnx=nx;
00483                 subny=ny;
00484                 subnz=nz;
00485         }
00486 
00487         if (seed->get_xsize()!=subnx || seed->get_ysize()!=subny || seed->get_zsize()!=subnz || !seed->is_complex())
00488                 throw ImageDimensionException("The dimensions of the seed volume do not match the reconstruction size");
00489 
00490         // Odd dimension support is here atm, but not above.
00491         image = seed;
00492         if (params.has_key("subvolume")) {
00493                 image->set_attr("subvolume_x0",subx0);
00494                 image->set_attr("subvolume_y0",suby0);
00495                 image->set_attr("subvolume_z0",subz0);
00496                 image->set_attr("subvolume_full_nx",nx);
00497                 image->set_attr("subvolume_full_ny",ny);
00498                 image->set_attr("subvolume_full_nz",nz);
00499         }
00500 
00501         if (tmp_data) delete tmp_data;
00502         tmp_data = new EMData();
00503         tmp_data->set_size(subnx/2, subny, subnz);
00504         tmp_data->to_value(seed_weight);
00505 
00506         load_inserter();
00507 
00508         if ( (bool) params["quiet"] == false )
00509         {
00510                 cout << "Seeded direct Fourier inversion";
00511                 cout << "3D Fourier dimensions are " << nx << " " << ny << " " << nz << endl;
00512                 cout << "3D Fourier subvolume is " << subnx << " " << subny << " " << subnz << endl;
00513                 cout << "You will require approximately " << setprecision(3) << (subnx*subny*subnz*sizeof(float)*1.5)/1000000000.0 << "GB of memory to reconstruct this volume" << endl;
00514         }
00515 }


Member Data Documentation

FourierPixelInserter3D* EMAN::FourierReconstructor::inserter [protected]

A pixel inserter pointer which inserts pixels into the 3D volume using one of a variety of insertion methods.

Definition at line 522 of file reconstructor.h.

Referenced by EMAN::WienerFourierReconstructor::do_insert_slice_work(), do_insert_slice_work(), free_memory(), load_default_settings(), and load_inserter().

const string FourierReconstructor::NAME = "fourier" [static]

Reimplemented in EMAN::WienerFourierReconstructor.

Definition at line 486 of file reconstructor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Thu Mar 10 23:01:28 2011 for EMAN2 by  doxygen 1.4.7