EMAN2
Classes | Functions
a function or class that is CUDA enabled

Classes

class  EMAN::TranslationalAligner
 Translational 2D Alignment using cross correlation. More...
class  EMAN::RotationalAligner
 rotational alignment using angular correlation More...
class  EMAN::RotateTranslateAligner
 rotational, translational alignment More...
class  EMAN::RotateFlipAligner
 rotational and flip alignment More...
class  EMAN::Refine3DAlignerGrid
 Refine alignment. More...
class  EMAN::Refine3DAlignerQuaternion
 Refine alignment. More...
class  EMAN::RT3DGridAligner
 rotational and translational alignment using a square qrid of Altitude and Azimuth values (the phi range is specifiable) This aligner is ported from the original tomohunter.py - it is less efficient than searching on the sphere (RT3DSphereAligner). More...
class  EMAN::RT3DSphereAligner
 3D rotational and translational alignment using spherical sampling, can reduce the search space based on symmetry. More...
class  EMAN::RT3DSymmetryAligner
 3D rotational symmetry aligner. More...
class  EMAN::CccCmp
 Compute the cross-correlation coefficient between two images. More...
class  EMAN::DotCmp
 Use dot product of 2 same-size images to do the comparison. More...
class  EMAN::TomoCccCmp
 This implements the technique of Mike Schmid where by the cross correlation is normalized in an effort to remove the effects of the missing wedge. More...
class  EMAN::TomoFscCmp
 This is a FSC comparitor for tomography. More...
class  EMAN::Rotate180Processor
 Rotate by 180 using pixel swapping, works for 2D only. More...
class  EMAN::TransformProcessor
 Transform the image using a Transform object. More...
class  EMAN::IntTranslateProcessor
 Translate the image an integer amount Uses EMData::clip_inplace (inplace) and EMData::get_clip (out of place) to do the translation. More...
class  EMAN::StandardProjector
 Fast real-space 3D projection. More...
class  EMAN::FourierReconstructor
 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...
class  EMAN::FourierPlaneReconstructor
 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...

Functions

void EMAN::EMData::insert_clip (const EMData *const block, const IntPoint &origin)
 Insert a clip into this image.
 EMAN::EMData::EMData (int nx, int ny, int nz=1, bool is_real=true)
 # makes an image of the specified size, either real or complex.
 EMAN::EMData::EMData (float *data, float *cudadata, const int nx, const int ny, const int nz, const Dict &attr_dict=Dict())
 Construction from a data pointer for usage in cuda, dimensions must be supplied.
 EMAN::EMData::EMData (const EMData &that)
 Construct from an EMData (copy constructor).
EMDataEMAN::EMData::operator= (const EMData &that)
 EMData assignment operator Performs a deep copy.
EMDataEMAN::EMData::calc_ccf (EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
 Calculate Cross-Correlation Function (CCF).
EMDataEMAN::EMData::calc_ccfx (EMData *const with, int y0=0, int y1=-1, bool nosum=false, bool flip=false, bool usez=false)
 Calculate Cross-Correlation Function (CCF) in the x-direction and adds them up, result in 1D.
EMDataEMAN::EMData::make_rotational_footprint (bool unwrap=true)
 Makes a 'rotational footprint', which is an 'unwound' autocorrelation function.
EMDataEMAN::EMData::unwrap (int r1=-1, int r2=-1, int xs=-1, int dx=0, int dy=0, bool do360=false, bool weight_radial=true) const
 Maps to polar coordinates from Cartesian coordinates.
void insert_clip (const EMData *const block, const IntPoint &origin)
 Insert a clip into this image.

Function Documentation

EMData * EMData::calc_ccf ( EMData with = 0,
fp_flag  fpflag = CIRCULANT,
bool  center = false 
)

Calculate Cross-Correlation Function (CCF).

Calculate the correlation of two 1-, 2-, or 3-dimensional images. Note: this method internally just calls the correlation function from fundamentals.h.

Parameters:
[in]withThe image used to calculate the CCF. If 'with' is NULL, the autocorrelation function is computed instead.
[in]fpflagSpecify how periodicity (or normalization) should be handled. See fundamentals.h The default is "CIRCULANT". for specific flags.
centerwhether or not to center the image (bring bottom left corner to center)
Returns:
Real-space image.
Exceptions:
ImageDimensionExceptionif nx > 1 and nx < 2*radius + 1

Definition at line 1489 of file emdata.cpp.

References calc_ccf_cuda(), calc_conv_cuda(), EMAN::EMData::clip_inplace(), EMAN::convolution(), EMAN::correlation(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::is_complex(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, and EMAN::EMData::update().

Referenced by EMAN::Refine3DAlignerGrid::align(), EMAN::TranslationalAligner::align(), EMAN::EMData::calc_flcf(), EMAN::TomoCccCmp::cmp(), EMAN::EMData::make_rotational_footprint(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().

{
        ENTERFUNC;

        if( with == 0 ) {
#ifdef EMAN2_USING_CUDA //CUDA 
        if(EMData::usecuda == 1 && cudarwdata) {
                //cout << "calc ccf" << endl;
                EMData* ifft = 0;
                bool delifft = false;
                int offset = 0;
                
                //do fft if not alreay done
                if(!is_complex()){
                        ifft = do_fft_cuda();
                        delifft = true;
                        offset = 2 - nx%2;
                }else{
                        ifft = this;
                }
                calc_conv_cuda(ifft->cudarwdata,ifft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft
                
                EMData * conv = ifft->do_ift_cuda();
                if(delifft) delete ifft;
                conv->update();
                        
                return conv;
        }
#endif
                EXITFUNC;
                return convolution(this,this,fpflag, center);
        }
        else if ( with == this ){ // this if statement is not necessary, the correlation function tests to see if with == this
                EXITFUNC;
                return correlation(this, this, fpflag,center);
        }
        else {

#ifdef EMAN2_USING_CUDA //CUDA 
                // assume always get rw data (makes life a lot easier!!! 
                // also assume that both images are the same size. When using CUDA we are only interested in speed, not flexibility!!
                // P.S. (I feel like I am pounding square pegs into a round holes with CUDA)
                if(EMData::usecuda == 1 && cudarwdata && with->cudarwdata) {
                        //cout << "using CUDA for ccf" << endl;
                        EMData* afft = 0;
                        EMData* bfft = 0;
                        bool delafft = false, delbfft = false;
                        int offset = 0;
                        
                        //do ffts if not alreay done
                        if(!is_complex()){
                                afft = do_fft_cuda();
                                delafft = true;
                                offset = 2 - nx%2;
                                //cout << "Do cuda FFT A" << endl;
                        }else{
                                afft = this;
                        }
                        if(!with->is_complex()){
                                bfft = with->do_fft_cuda();
                                //cout << "Do cuda FFT B" << endl;
                                delbfft = true;
                        }else{
                                bfft = with;
                        }

                        calc_ccf_cuda(afft->cudarwdata,bfft->cudarwdata,nx + offset, ny, nz); //this is the business end, results go in afft
                        
                        if(delbfft) delete bfft;
                        
                        EMData * corr = afft->do_ift_cuda();
                        if(delafft) delete afft;
                        //cor->do_ift_inplace_cuda();//a bit faster, but I'll alos need to rearrnage the mem structure for it to work, BUT this is very SLOW.
                        corr->update();
                        
                        return corr;
                }
#endif
                
                // If the argument EMData pointer is not the same size we automatically resize it
                bool undoresize = false;
                int wnx = with->get_xsize(); int wny = with->get_ysize(); int wnz = with->get_zsize();
                if (!(is_complex()^with->is_complex()) && (wnx != nx || wny != ny || wnz != nz) ) {
                        Region r((wnx-nx)/2, (wny-ny)/2, (wnz-nz)/2,nx,ny,nz);
                        with->clip_inplace(r);
                        undoresize = true;
                }

                EMData* cor = correlation(this, with, fpflag, center);

                // If the argument EMData pointer was resized, it is returned to its original dimensions
                if ( undoresize ) {
                        Region r((nx-wnx)/2, (ny-wny)/2,(nz-wnz)/2,wnx,wny,wnz);
                        with->clip_inplace(r);
                }

                EXITFUNC;
                return cor;
        }
}
EMData * EMData::calc_ccfx ( EMData *const  with,
int  y0 = 0,
int  y1 = -1,
bool  nosum = false,
bool  flip = false,
bool  usez = false 
)

Calculate Cross-Correlation Function (CCF) in the x-direction and adds them up, result in 1D.

WARNING: this routine will modify the 'this' and 'with' to contain 1D fft's without setting some flags. This is an optimization for rotational alignment.

Parameters:
withThe image used to calculate CCF.
y0Starting position in x-direction.
y1Ending position in x-direction. '-1' means the end of the row.
nosumIf true, returns an image y1-y0+1 pixels high.
usezIf true, will convert each line in the CCF stack to a Z value, indicating its relative strength as a predictor of alignment
See also:
calc_ccf()
Exceptions:
NullPointerExceptionIf input image 'with' is NULL.
ImageFormatExceptionIf 'with' and 'this' are not same size.
ImageDimensionExceptionIf 'this' image is 3D.
Returns:
The result image containing the CCF.

Definition at line 1590 of file emdata.cpp.

References calc_ccf_cuda(), cuda_dd_fft_complex_to_real_nd(), cuda_dd_fft_real_to_complex_nd(), EMAN::EMData::EMData(), emdata_column_sum(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, ImageFormatException, EMAN::EMData::is_complex_x(), EMAN::EMUtil::is_same_size(), LOGERR, NullPointerException, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::set_size(), EMAN::EMData::sqrt(), EMAN::EMData::to_zero(), EMAN::EMData::update(), x, and y.

Referenced by EMAN::RTFExhaustiveAligner::align(), EMAN::RotateTranslateFlipAlignerPawel::align(), EMAN::RotateTranslateAlignerPawel::align(), EMAN::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::RotationalAligner::align_180_ambiguous(), and EMAN::EMData::make_footprint().

{
        ENTERFUNC;

        if (!with) {
                LOGERR("NULL 'with' image. ");
                throw NullPointerException("NULL input image");
        }

        if (!EMUtil::is_same_size(this, with)) {
                LOGERR("images not same size: (%d,%d,%d) != (%d,%d,%d)",
                           nx, ny, nz,
                           with->get_xsize(), with->get_ysize(), with->get_zsize());
                throw ImageFormatException("images not same size");
        }
        if (get_ndim() > 2) {
                LOGERR("2D images only");
                throw ImageDimensionException("2D images only");
        }

        if (y1 <= y0) {
                y1 = ny;
        }

        if (y0 >= y1) {
                y0 = 0;
        }

        if (y0 < 0) {
                y0 = 0;
        }

        if (y1 > ny) {
                y1 = ny;
        }
        if (is_complex_x() || with->is_complex_x() ) throw; // Woops don't support this anymore!

        static int nx_fft = 0;
        static int ny_fft = 0;
        static EMData f1;
        static EMData f2;
        static EMData rslt;

        int height = y1-y0;
        int width = (nx+2-(nx%2));
        int wpad = ((width+3)/4)*4;                     // This is for 128 bit alignment of rows to prevent SSE crashes
        if (wpad != nx_fft || height != ny_fft ) {      // Seems meaningless, but due to static definitions above. f1,f2 are cached to prevent multiple reallocations
                f1.set_size(wpad,height);
                f2.set_size(wpad,height);
                rslt.set_size(nx,height);
                nx_fft = wpad;
                ny_fft = height;
        }

#ifdef EMAN2_USING_CUDA
        // FIXME : Not tested with new wpad change
        if (EMData::usecuda == 1 && cudarwdata && with->cudarwdata) {
                //cout << "calc_ccfx CUDA" << endl;
                if(!f1.cudarwdata) f1.rw_alloc();
                if(!f2.cudarwdata) f2.rw_alloc();
                if(!rslt.cudarwdata) rslt.rw_alloc();
                cuda_dd_fft_real_to_complex_nd(cudarwdata, f1.cudarwdata, nx, 1, 1, height);
                cuda_dd_fft_real_to_complex_nd(with->cudarwdata, f2.cudarwdata, nx, 1, 1, height);
                calc_ccf_cuda(f1.cudarwdata, f2.cudarwdata, nx, ny, nz);
                cuda_dd_fft_complex_to_real_nd(f1.cudarwdata, rslt.cudarwdata, nx, 1, 1, height);
                if(no_sum){
                        EMData* result = new EMData(rslt);
                        return result;
                }
                EMData* cf = new EMData(0,0,nx,1,1); //cuda constructor
                cf->runcuda(emdata_column_sum(rslt.cudarwdata, nx, ny));
                cf->update();
                
                EXITFUNC;
                return cf;
        }
#endif

//      printf("%d %d %d\n",(int)get_attr("nx"),(int)f2.get_attr("nx"),width);

        float *d1 = get_data();
        float *d2 = with->get_data();
        float *f1d = f1.get_data();
        float *f2d = f2.get_data();
        for (int j = 0; j < height; j++) {
                EMfft::real_to_complex_1d(d1 + j * nx, f1d+j*wpad, nx);
                EMfft::real_to_complex_1d(d2 + j * nx, f2d+j*wpad, nx);
        }

        if(flip == false) {
                for (int j = 0; j < height; j++) {
                        float *f1a = f1d + j * wpad;
                        float *f2a = f2d + j * wpad;

                        for (int i = 0; i < width / 2; i++) {
                                float re1 = f1a[2*i];
                                float re2 = f2a[2*i];
                                float im1 = f1a[2*i+1];
                                float im2 = f2a[2*i+1];

                                f1d[j*wpad+i*2] = re1 * re2 + im1 * im2;
                                f1d[j*wpad+i*2+1] = im1 * re2 - re1 * im2;
                        }
                }
        } else {
                for (int j = 0; j < height; j++) {
                        float *f1a = f1d + j * wpad;
                        float *f2a = f2d + j * wpad;

                        for (int i = 0; i < width / 2; i++) {
                                float re1 = f1a[2*i];
                                float re2 = f2a[2*i];
                                float im1 = f1a[2*i+1];
                                float im2 = f2a[2*i+1];

                                f1d[j*wpad+i*2] = re1 * re2 - im1 * im2;
                                f1d[j*wpad+i*2+1] = im1 * re2 + re1 * im2;
                        }
                }
        }

        float* rd = rslt.get_data();
        for (int j = y0; j < y1; j++) {
                EMfft::complex_to_real_1d(f1d+j*wpad, rd+j*nx, nx);
        }

        // This converts the CCF values to Z values (in terms of standard deviations above the mean), on a per-row basis
        // The theory is that this should better weight the radii that contribute most strongly to the orientation determination
        if (usez) {
                for (int y=0; y<height; y++) {
                        float mn=0,sg=0;
                        for (int x=0; x<nx; x++) {
                                mn+=rd[x+y*nx];
                                sg+=rd[x+y*nx]*rd[x+y*nx];
                        }
                        mn/=(float)nx;                                          //mean
                        sg=std::sqrt(sg/(float)nx-mn*mn);       //sigma
                        
                        for (int x=0; x<nx; x++) rd[x+y*nx]=(rd[x+y*nx]-mn)/sg;
                }
        }

        if (no_sum) {
                rslt.update(); // This is important in terms of the copy - the returned object won't have the correct flags unless we do this
                EXITFUNC;
                return new EMData(rslt);
        } else {
                EMData *cf = new EMData(nx,1,1);
                cf->to_zero();
                float *c = cf->get_data();
                for (int j = 0; j < height; j++) {
                        for(int i = 0; i < nx; ++i) {
                                c[i] += rd[i+j*nx];
                        }
                }
                cf->update();
                EXITFUNC;
                return cf;
        }
}
EMData::EMData ( const EMData that)

Construct from an EMData (copy constructor).

Performs a deep copy

Parameters:
thatthe EMData to copy

Definition at line 138 of file emdata.cpp.

References data, EMAN::EMUtil::em_malloc(), EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), ENTERFUNC, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::rdata, EMAN::EMData::rot_fp, EMAN::EMData::totalalloc, and UnexpectedBehaviorException.

                                 :
#ifdef EMAN2_USING_CUDA
                cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), cudadirtybit(0),
#endif //EMAN2_USING_CUDA
#ifdef FFT_CACHING
        fftcache(0),
#endif //FFT_CACHING
                attr_dict(that.attr_dict), rdata(0), supp(0), flags(that.flags), changecount(that.changecount), nx(that.nx), ny(that.ny), nz(that.nz),
                nxy(that.nx*that.ny), nxyz((size_t)that.nx*that.ny*that.nz), xoff(that.xoff), yoff(that.yoff), zoff(that.zoff),all_translation(that.all_translation),   path(that.path),
                pathnum(that.pathnum), rot_fp(0)
{
        ENTERFUNC;
        
        float* data = that.rdata;
        size_t num_bytes = (size_t)nx*ny*nz*sizeof(float);
        if (data && num_bytes != 0)
        {
                rdata = (float*)EMUtil::em_malloc(num_bytes);
                EMUtil::em_memcpy(rdata, data, num_bytes);
        }
#ifdef EMAN2_USING_CUDA
        if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) {
                //cout << "That copy constructor" << endl;
                if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");
                cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
                if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
        }
#endif //EMAN2_USING_CUDA

        if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));

        EMData::totalalloc++;
#ifdef MEMDEBUG2
        printf("EMDATA+  %4d    %p\n",EMData::totalalloc,this);
#endif

        ENTERFUNC;
}
EMAN::EMData::EMData ( float *  data,
float *  cudadata,
const int  nx,
const int  ny,
const int  nz,
const Dict attr_dict = Dict() 
)

Construction from a data pointer for usage in cuda, dimensions must be supplied.

Takes possession of the pointer. data pointer must be allocated using malloc!

Parameters:
dataa pointer to the pixel data which is stored in memory. Takes possession
cudadataa pointer to the pixel data which is stored in cudamemory. Takes possession
nxthe number of pixels in the x direction
nythe number of pixels in the y direction
nzthe number of pixels in the z direction
EMData::EMData ( int  nx,
int  ny,
int  nz = 1,
bool  is_real = true 
)

# makes an image of the specified size, either real or complex.

For complex image, the user would specify the real-space dimensions.

Parameters:
nxsize for x dimension
nysize for y dimension
nzsize for z dimension, default 1
is_realboolean to specify real(true) or complex(false) image, default real

Definition at line 225 of file emdata.cpp.

References EMAN::EMData::attr_dict, ENTERFUNC, EXITFUNC, EMAN::EMData::set_size(), EMAN::EMData::to_zero(), EMAN::EMData::totalalloc, and EMAN::EMData::update().

                                                   :
#ifdef EMAN2_USING_CUDA
                cudarwdata(0), cudarodata(0), num_bytes(0), nextlistitem(0), prevlistitem(0), roneedsupdate(0), cudadirtybit(0),
#endif //EMAN2_USING_CUDA
#ifdef FFT_CACHING
        fftcache(0),
#endif //FFT_CACHING
                attr_dict(), rdata(0), supp(0), flags(0), changecount(0), nx(0), ny(0), nz(0), nxy(0), nxyz(0), xoff(0), yoff(0), zoff(0),
                all_translation(),      path(""), pathnum(0), rot_fp(0)
{
        ENTERFUNC;

        // used to replace cube 'pixel'
        attr_dict["apix_x"] = 1.0f;
        attr_dict["apix_y"] = 1.0f;
        attr_dict["apix_z"] = 1.0f;

        if(is_real) {   // create a real image [nx, ny, nz]
                attr_dict["is_complex"] = int(0);
                attr_dict["is_complex_x"] = int(0);
                attr_dict["is_complex_ri"] = int(1);
                set_size(nx, ny, nz);
        }
        else {  //create a complex image which real dimension is [ny, ny, nz]
                int new_nx = nx + 2 - nx%2;
                set_size(new_nx, ny, nz);

                attr_dict["is_complex"] = int(1);

                if(ny==1 && nz ==1)     {
                        attr_dict["is_complex_x"] = int(1);
                }
                else {
                        attr_dict["is_complex_x"] = int(0);
                }

                attr_dict["is_complex_ri"] = int(1);
                attr_dict["is_fftpad"] = int(1);

                if(nx%2 == 1) {
                        attr_dict["is_fftodd"] = 1;
                }
        }

        this->to_zero();
        update();
        EMData::totalalloc++;
#ifdef MEMDEBUG2
        printf("EMDATA+  %4d    %p\n",EMData::totalalloc,this);
#endif

        EXITFUNC;
}
void EMData::insert_clip ( const EMData *const  block,
const IntPoint origin 
)

Insert a clip into this image.

Very robust clip insertion code works in all way you might think possible

Parameters:
blockAn image block.
originThe origin location to insert the clip. ( )

Definition at line 1766 of file emdata_transform.cpp.

References EMAN::EMUtil::em_memcpy(), EXITFUNC, get_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), nx, ny, EMAN::Region::origin, EMAN::Region::size, and update().

Referenced by EMAN::EMData::get_clip(), and EMAN::EMData::make_rotational_footprint_e1().

                                                                           {
        int nx1 = block->get_xsize();
        int ny1 = block->get_ysize();
        int nz1 = block->get_zsize();

        Region area(origin[0], origin[1], origin[2],nx1, ny1, nz1);

        //make sure the block fits in EMData 
        int x0 = (int) area.origin[0];
        x0 = x0 < 0 ? 0 : x0;

        int y0 = (int) area.origin[1];
        y0 = y0 < 0 ? 0 : y0;

        int z0 = (int) area.origin[2];
        z0 = z0 < 0 ? 0 : z0;

        int x1 = (int) (area.origin[0] + area.size[0]);
        x1 = x1 > nx ? nx : x1;

        int y1 = (int) (area.origin[1] + area.size[1]);
        y1 = y1 > ny ? ny : y1;

        int z1 = (int) (area.origin[2] + area.size[2]);
        z1 = z1 > nz ? nz : z1;
        if (z1 <= 0) {
                z1 = 1;
        }

        int xd0 = (int) (area.origin[0] < 0 ? -area.origin[0] : 0);
        int yd0 = (int) (area.origin[1] < 0 ? -area.origin[1] : 0);
        int zd0 = (int) (area.origin[2] < 0 ? -area.origin[2] : 0);

        if (x1 < x0 || y1 < y0 || z1 < z0) return; // out of bounds, this is fine, nothing happens

        size_t clipped_row_size = (x1-x0) * sizeof(float);
        size_t src_secsize =  (size_t)(nx1 * ny1);
        size_t dst_secsize = (size_t)(nx * ny);

/*
#ifdef EMAN2_USING_CUDA
        if(block->cudarwdata){
                // this is VERY slow.....
                float *cudasrc = block->cudarwdata + zd0 * src_secsize + yd0 * nx1 + xd0;
                if(!cudarwdata) rw_alloc();
                float *cudadst = cudarwdata + z0 * dst_secsize + y0 * nx + x0;
                for (int i = z0; i < z1; i++) {
                        for (int j = y0; j < y1; j++) {
                                //printf("%x %x %d\n", cudadst, cudasrc, clipped_row_size);
                                cudaMemcpy(cudadst,cudasrc,clipped_row_size,cudaMemcpyDeviceToDevice);
                                cudasrc += nx1;
                                cudadst += nx;
                        }
                        cudasrc += src_gap;
                        cudadst += dst_gap;
                }
                return;
        }
#endif
*/
        float *src = block->get_data() + zd0 * src_secsize + yd0 * nx1 + xd0;
        float *dst = get_data() + z0 * dst_secsize + y0 * nx + x0;
        
        size_t src_gap = src_secsize - (y1-y0) * nx1;
        size_t dst_gap = dst_secsize - (y1-y0) * nx;
        
        for (int i = z0; i < z1; i++) {
                for (int j = y0; j < y1; j++) {
                        EMUtil::em_memcpy(dst, src, clipped_row_size);
                        src += nx1;
                        dst += nx;
                }
                src += src_gap;
                dst += dst_gap;
        }
        
#ifdef EMAN2_USING_CUDA 
        if(block->cudarwdata){
                copy_to_cuda(); // copy back to device as padding is faster on the host
        }
#endif

        update();
        EXITFUNC;
}
void insert_clip ( const EMData *const  block,
const IntPoint &  origin 
)

Insert a clip into this image.

Very robust clip insertion code works in all way you might think possible

Parameters:
blockAn image block.
originThe origin location to insert the clip. ( )
EMData * EMData::make_rotational_footprint ( bool  unwrap = true)

Makes a 'rotational footprint', which is an 'unwound' autocorrelation function.

generally the image should be edge-normalized and masked before using this.

Parameters:
unwrapRFP undergoes polar->cartesian x-form
Exceptions:
ImageFormatExceptionIf image size is not even.
Returns:
The rotaional footprint image.

Definition at line 1803 of file emdata.cpp.

References EMAN::EMData::calc_ccf(), EMAN::CIRCULANT, EMAN::EMData::EMData(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_edge_mean(), EMAN::EMData::rot_fp, EMAN::EMData::sub(), EMAN::EMData::unwrap(), and EMAN::EMData::update_stat().

Referenced by EMAN::RotationalAligner::align_180_ambiguous(), and main().

                                                      {
        ENTERFUNC;
        update_stat();
        // Note that rotational_footprint caching saves a large amount of time
        // but this is at the expense of memory. Note that a policy is hardcoded here,
        // that is that caching is only employed when premasked is false and unwrap
        // is true - this is probably going to be what is used in most scenarios
        // as advised by Steve Ludtke - In terms of performance this caching doubles the metric
        // generated by e2speedtest.
        if ( rot_fp != 0 && unwrap == true) {
                return new EMData(*rot_fp);
        }

        EMData* ccf = this->calc_ccf(this,CIRCULANT,true);
//      EMData* ccf = this->calc_ccf(this,PADDED,true);         # this would probably be a bit better, but takes 4x longer  :^/
        ccf->sub(ccf->get_edge_mean());
        //ccf->process_inplace("xform.phaseorigin.tocenter"); ccf did the centering
        EMData *result = ccf->unwrap();
        delete ccf; ccf = 0;

        EXITFUNC;
        if ( unwrap == true)
        { // this if statement reflects a strict policy of caching in only one scenario see comments at beginning of function block

// Note that the if statement at the beginning of this function ensures that rot_fp is not zero, so there is no need
// to throw any exception
// if ( rot_fp != 0 ) throw UnexpectedBehaviorException("The rotational foot print is only expected to be cached if it is not NULL");

// Here is where the caching occurs - the rot_fp takes ownsherhip of the pointer, and a deep copied EMData object is returned.
// The deep copy invokes a cost in terms of CPU cycles and memory, but prevents the need for complicated memory management (reference counting)
                rot_fp = result;
                return new EMData(*rot_fp);
        }
        else return result;
}
EMData & EMData::operator= ( const EMData that)

EMData assignment operator Performs a deep copy.

Parameters:
thatthe EMData to copy

Definition at line 177 of file emdata.cpp.

References EMAN::EMData::all_translation, EMAN::EMData::attr_dict, EMAN::EMData::changecount, data, EMAN::EMUtil::em_memcpy(), EMAN::EMData::EMData(), ENTERFUNC, EXITFUNC, EMAN::EMData::flags, EMAN::EMData::free_memory(), EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::nz, EMAN::EMData::path, EMAN::EMData::pathnum, EMAN::EMData::rdata, EMAN::EMData::rot_fp, EMAN::EMData::set_size(), UnexpectedBehaviorException, EMAN::EMData::xoff, EMAN::EMData::yoff, and EMAN::EMData::zoff.

{
        ENTERFUNC;

        if ( this != &that )
        {
                free_memory(); // Free memory sets nx,ny and nz to 0

                // Only copy the rdata if it exists, we could be in a scenario where only the header has been read
                float* data = that.rdata;
                size_t num_bytes = that.nx*that.ny*that.nz*sizeof(float);
                if (data && num_bytes != 0)
                {
                        nx = 1; // This prevents a memset in set_size
                        set_size(that.nx,that.ny,that.nz);
                        EMUtil::em_memcpy(rdata, data, num_bytes);
                }

                flags = that.flags;

                all_translation = that.all_translation;

                path = that.path;
                pathnum = that.pathnum;
                attr_dict = that.attr_dict;

                xoff = that.xoff;
                yoff = that.yoff;
                zoff = that.zoff;

#ifdef EMAN2_USING_CUDA
                if (EMData::usecuda == 1 && num_bytes != 0 && that.cudarwdata != 0) {
                        if(cudarwdata){rw_free();}
                        if(!rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");;
                        cudaError_t error = cudaMemcpy(cudarwdata,that.cudarwdata,num_bytes,cudaMemcpyDeviceToDevice);
                        if ( error != cudaSuccess ) throw UnexpectedBehaviorException("cudaMemcpy failed in EMData copy construction with error: " + string(cudaGetErrorString(error)));
                }
#endif //EMAN2_USING_CUDA

                changecount = that.changecount;

                if (that.rot_fp != 0) rot_fp = new EMData(*(that.rot_fp));
                else rot_fp = 0;
        }
        EXITFUNC;
        return *this;
}
EMData * EMData::unwrap ( int  r1 = -1,
int  r2 = -1,
int  xs = -1,
int  dx = 0,
int  dy = 0,
bool  do360 = false,
bool  weight_radial = true 
) const

Maps to polar coordinates from Cartesian coordinates.

Optionaly radially weighted. When used with RFP, this provides roughly 1 pixel accuracy at 50% radius. 2D only.

Parameters:
r1inner ring (all rings less than r1 are discarded) Default = 4
r2outer ring (all rings > r2 are discarded) Default = ny/2 - 2 - floor(hyp(dx,dy))
xsNumber of angular bins. Default = (2 if do360) PI * ny/4 - xs % 8
dxorigin offset in x
dyorigin offest in y
do360If true, do 0-360 degree mapping. Otherwise, do 0-180 degree mapping.
weight_radialif true (default) reights the pixel value by its radius
Exceptions:
ImageDimensionExceptionIf 'this' image is not 2D.
UnexpectedBehaviorExceptionif the dimension of this image and the function arguments are incompatibale - i.e. the return image is less than 0 in some dimension.
Returns:
The image in Cartesian coordinates.

Definition at line 2530 of file emdata.cpp.

References EMAN::Util::bilinear_interpolate(), EMAN::Util::calc_best_fft_size(), EMAN::EMData::EMData(), emdata_unwrap(), ENTERFUNC, EXITFUNC, EMAN::Util::fast_floor(), EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), ImageDimensionException, EMAN::EMData::nx, EMAN::EMData::ny, EMAN::EMData::set_size(), t, UnexpectedBehaviorException, EMAN::EMData::update(), x, and y.

Referenced by EMAN::RTFExhaustiveAligner::align(), EMAN::RotateTranslateFlipAlignerPawel::align(), EMAN::RotateTranslateAlignerPawel::align(), EMAN::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::EMData::make_rotational_footprint(), EMAN::EMData::make_rotational_footprint_cmc(), and EMAN::EMData::make_rotational_footprint_e1().

{
        ENTERFUNC;

        if (get_ndim() != 2) {
                throw ImageDimensionException("2D image only");
        }

        int p = 1;
        if (do360) {
                p = 2;
        }

        if (xs < 1) {
                xs = (int) Util::fast_floor(p * M_PI * ny / 3.0);
                xs-=xs%4;                       // 128 bit alignment, though best_fft_size may override
                xs = Util::calc_best_fft_size(xs);
                if (xs<=8) xs=16;
        }

        if (r1 < 0) {
                r1 = 4;
        }

#ifdef  _WIN32
        int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(_hypot(dx, dy)));
#else
        int rr = ny / 2 - 2 - (int) Util::fast_floor(static_cast<float>(hypot(dx, dy)));
#endif  //_WIN32
        rr-=rr%2;
        if (r2 <= r1 || r2 > rr) {
                r2 = rr;
        }

        if ( (r2-r1) < 0 ) throw UnexpectedBehaviorException("The combination of function the arguments and the image dimensions causes unexpected behavior internally. Use a larger image, or a smaller value of r1, or a combination of both");

#ifdef EMAN2_USING_CUDA
        if (EMData::usecuda == 1 && isrodataongpu()){
                //cout << " CUDA unwrap" << endl;
                EMData* result = new EMData(0,0,xs,(r2-r1),1);
                if(!result->rw_alloc()) throw UnexpectedBehaviorException("Bad alloc");
                bindcudaarrayA(true);
                emdata_unwrap(result->cudarwdata, r1, r2, xs, p, dx, dy, weight_radial, nx, ny);
                unbindcudaarryA();
                result->update();
                return result;
        }
#endif

        EMData *ret = new EMData();
        ret->set_size(xs, r2 - r1, 1);
        const float *const d = get_const_data();
        float *dd = ret->get_data();
        float pfac = (float)p/(float)xs;
        int nxon2 = nx/2;
        int nyon2 = ny/2;
        for (int x = 0; x < xs; x++) {
                float ang = x * M_PI * pfac;
                float si = sin(ang);
                float co = cos(ang);

                for (int y = 0; y < r2 - r1; y++) {
                        float ypr1 = (float)y + r1;
                        float xx = ypr1 * co + nxon2 + dx;
                        float yy = ypr1 * si + nyon2 + dy;
//                      float t = xx - Util::fast_floor(xx);
//                      float u = yy - Util::fast_floor(yy);
                        float t = xx - (int)xx;
                        float u = yy - (int)yy;
//                      int k = (int) Util::fast_floor(xx) + (int) (Util::fast_floor(yy)) * nx;
                        int k = (int) xx + ((int) yy) * nx;
                        float val = Util::bilinear_interpolate(d[k], d[k + 1], d[k + nx], d[k + nx+1], t,u);
                        if (weight_radial) val *=  ypr1;
                        dd[x + y * xs] = val;
                }

        }
        ret->update();

        EXITFUNC;
        return ret;
}