void actualPhaseFlip(MultidimArray<double> &I, CTFDescription ctf) { // Perform the Fourier transform FourierTransformer transformer; MultidimArray< std::complex<double> > M_inFourier; transformer.FourierTransform(I,M_inFourier,false); Matrix1D<double> freq(2); // Frequencies for Fourier plane int yDim=YSIZE(I); int xDim=XSIZE(I); double iTm=1.0/ctf.Tm; for (size_t i=0; i<YSIZE(M_inFourier); ++i) { FFT_IDX2DIGFREQ(i, yDim, YY(freq)); YY(freq) *= iTm; for (size_t j=0; j<XSIZE(M_inFourier); ++j) { FFT_IDX2DIGFREQ(j, xDim, XX(freq)); XX(freq) *= iTm; ctf.precomputeValues(XX(freq),YY(freq)); if (ctf.getValuePureWithoutDampingAt()<0) DIRECT_A2D_ELEM(M_inFourier,i,j)*=-1; } } // Perform inverse Fourier transform and finish transformer.inverseFourierTransform(); }
// Inforce Hermitian symmetry --------------------------------------------- void FourierTransformer::enforceHermitianSymmetry() { int ndim = 3; if (ZSIZE(*fReal) == 1) { ndim = 2; if (YSIZE(*fReal) == 1) { ndim = 1; } } long int yHalf = YSIZE(*fReal) / 2; if (YSIZE(*fReal) % 2 == 0) { yHalf--; } long int zHalf = ZSIZE(*fReal) / 2; if (ZSIZE(*fReal) % 2 == 0) { zHalf--; } switch (ndim) { case 2: for (long int i = 1; i <= yHalf; i++) { long int isym = intWRAP(-i, 0, YSIZE(*fReal) - 1); Complex mean = 0.5 * ( DIRECT_A2D_ELEM(fFourier, i, 0) + conj(DIRECT_A2D_ELEM(fFourier, isym, 0))); DIRECT_A2D_ELEM(fFourier, i, 0) = mean; DIRECT_A2D_ELEM(fFourier, isym, 0) = conj(mean); } break; case 3: for (long int k = 0; k < ZSIZE(*fReal); k++) { long int ksym = intWRAP(-k, 0, ZSIZE(*fReal) - 1); for (long int i = 1; i <= yHalf; i++) { long int isym = intWRAP(-i, 0, YSIZE(*fReal) - 1); Complex mean = 0.5 * ( DIRECT_A3D_ELEM(fFourier, k, i, 0) + conj(DIRECT_A3D_ELEM(fFourier, ksym, isym, 0))); DIRECT_A3D_ELEM(fFourier, k, i, 0) = mean; DIRECT_A3D_ELEM(fFourier, ksym, isym, 0) = conj(mean); } } for (long int k = 1; k <= zHalf; k++) { long int ksym = intWRAP(-k, 0, ZSIZE(*fReal) - 1); Complex mean = 0.5 * ( DIRECT_A3D_ELEM(fFourier, k, 0, 0) + conj(DIRECT_A3D_ELEM(fFourier, ksym, 0, 0))); DIRECT_A3D_ELEM(fFourier, k, 0, 0) = mean; DIRECT_A3D_ELEM(fFourier, ksym, 0, 0) = conj(mean); } break; } }
void FourierProjector::produceSideInfo() { // Zero padding MultidimArray<double> Vpadded; int paddedDim=(int)(paddingFactor*volumeSize); // JMRT: TODO: I think it is a very poor design to modify the volume passed // in the construct, it will be padded anyway, so new memory should be allocated volume->window(Vpadded,FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim), LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim)); volume->clear(); // Make Fourier transform, shift the volume origin to the volume center and center it MultidimArray< std::complex<double> > Vfourier; transformer3D.completeFourierTransform(Vpadded,Vfourier); ShiftFFT(Vfourier, FIRST_XMIPP_INDEX(XSIZE(Vpadded)), FIRST_XMIPP_INDEX(YSIZE(Vpadded)), FIRST_XMIPP_INDEX(ZSIZE(Vpadded))); CenterFFT(Vfourier,true); Vfourier.setXmippOrigin(); // Compensate for the Fourier normalization factor double K=(double)(XSIZE(Vpadded)*XSIZE(Vpadded)*XSIZE(Vpadded))/(double)(volumeSize*volumeSize); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vfourier) DIRECT_MULTIDIM_ELEM(Vfourier,n)*=K; Vpadded.clear(); // Compute Bspline coefficients if (BSplineDeg==3) { MultidimArray< double > VfourierRealAux, VfourierImagAux; Complex2RealImag(Vfourier, VfourierRealAux, VfourierImagAux); Vfourier.clear(); produceSplineCoefficients(BSPLINE3,VfourierRealCoefs,VfourierRealAux); produceSplineCoefficients(BSPLINE3,VfourierImagCoefs,VfourierImagAux); //VfourierRealAux.clear(); //VfourierImagAux.clear(); } else Complex2RealImag(Vfourier, VfourierRealCoefs, VfourierImagCoefs); // Allocate memory for the 2D Fourier transform projection().initZeros(volumeSize,volumeSize); projection().setXmippOrigin(); transformer2D.FourierTransform(projection(),projectionFourier,false); // Calculate phase shift terms phaseShiftImgA.initZeros(projectionFourier); phaseShiftImgB.initZeros(projectionFourier); double shift=-FIRST_XMIPP_INDEX(volumeSize); double xxshift = -2 * PI * shift / volumeSize; for (size_t i=0; i<YSIZE(projectionFourier); ++i) { double phasey=(double)(i) * xxshift; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // Phase shift to move the origin of the image to the corner double dotp = (double)(j) * xxshift + phasey; sincos(dotp,&DIRECT_A2D_ELEM(phaseShiftImgB,i,j),&DIRECT_A2D_ELEM(phaseShiftImgA,i,j)); } } }
void FourierTransformer::setReal(MultidimArray<std::complex<double> > &input) { bool recomputePlan=false; if (fComplex==NULL) recomputePlan=true; else if (complexDataPtr!=MULTIDIM_ARRAY(input)) recomputePlan=true; else recomputePlan=!(fComplex->sameShape(input)); fFourier.resizeNoCopy(input); fComplex=&input; if (recomputePlan) { int ndim=3; if (ZSIZE(input)==1) { ndim=2; if (YSIZE(input)==1) ndim=1; } int *N = new int[ndim]; switch (ndim) { case 1: N[0]=XSIZE(input); break; case 2: N[0]=YSIZE(input); N[1]=XSIZE(input); break; case 3: N[0]=ZSIZE(input); N[1]=YSIZE(input); N[2]=XSIZE(input); break; } pthread_mutex_lock(&fftw_plan_mutex); if (fPlanForward!=NULL) fftw_destroy_plan(fPlanForward); fPlanForward=NULL; fPlanForward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(*fComplex), (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_FORWARD, FFTW_ESTIMATE); if (fPlanBackward!=NULL) fftw_destroy_plan(fPlanBackward); fPlanBackward=NULL; fPlanBackward = fftw_plan_dft(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(fFourier), (fftw_complex*) MULTIDIM_ARRAY(*fComplex), FFTW_BACKWARD, FFTW_ESTIMATE); if (fPlanForward == NULL || fPlanBackward == NULL) REPORT_ERROR(ERR_PLANS_NOCREATE, "FFTW plans cannot be created"); delete [] N; complexDataPtr=MULTIDIM_ARRAY(*fComplex); pthread_mutex_unlock(&fftw_plan_mutex); } }
void FourierTransformer::setReal(MultidimArray<double> &input) { bool recomputePlan=false; if (fReal==NULL) recomputePlan=true; else if (dataPtr!=MULTIDIM_ARRAY(input)) recomputePlan=true; else recomputePlan=!(fReal->sameShape(input)); fFourier.resizeNoCopy(ZSIZE(input),YSIZE(input),XSIZE(input)/2+1); fReal=&input; if (recomputePlan) { int ndim=3; if (ZSIZE(input)==1) { ndim=2; if (YSIZE(input)==1) ndim=1; } int N[3]; switch (ndim) { case 1: N[0]=XSIZE(input); break; case 2: N[0]=YSIZE(input); N[1]=XSIZE(input); break; case 3: N[0]=ZSIZE(input); N[1]=YSIZE(input); N[2]=XSIZE(input); break; } pthread_mutex_lock(&fftw_plan_mutex); if (fPlanForward!=NULL) fftw_destroy_plan(fPlanForward); fPlanForward=NULL; fPlanForward = fftw_plan_dft_r2c(ndim, N, MULTIDIM_ARRAY(*fReal), (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_ESTIMATE); if (fPlanBackward!=NULL) fftw_destroy_plan(fPlanBackward); fPlanBackward=NULL; fPlanBackward = fftw_plan_dft_c2r(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(fFourier), MULTIDIM_ARRAY(*fReal), FFTW_ESTIMATE); if (fPlanForward == NULL || fPlanBackward == NULL) REPORT_ERROR(ERR_PLANS_NOCREATE, "FFTW plans cannot be created"); dataPtr=MULTIDIM_ARRAY(*fReal); pthread_mutex_unlock(&fftw_plan_mutex); } }
void multiplyBySpectrum(MultidimArray<double>& Min, MultidimArray<double>& spectrum, bool leave_origin_intact) { MultidimArray<Complex > Faux; Matrix1D<double> f(3); MultidimArray<double> lspectrum; FourierTransformer transformer; double dim3 = XSIZE(Min) * YSIZE(Min) * ZSIZE(Min); transformer.FourierTransform(Min, Faux, false); lspectrum = spectrum; if (leave_origin_intact) { lspectrum(0) = 1.; } FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux) { long int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp)); dAkij(Faux, k, i, j) *= lspectrum(idx) * dim3; } transformer.inverseFourierTransform(); }
/* FUNCTION: InitNewFont(LOGFONT, COLORREF) PURPOSE: Prepares a new font for use in the terminal screen PARAMETERS: LogFont - New logical font for the screen rgbColour - New colour for screen painting */ void InitNewFont(LOGFONT LogFont, COLORREF rgbColour) { TEXTMETRIC tm; HDC hDC; // If an old font exits, delete it if (HSCREENFONT(TermInfo)) { DeleteObject(HSCREENFONT(TermInfo)); } LFSCREENFONT(TermInfo) = LogFont; HSCREENFONT(TermInfo) = CreateFontIndirect(&(LFSCREENFONT(TermInfo))); FGCOLOUR(TermInfo) = rgbColour; hDC = GetDC(ghWndMain); SelectObject(hDC, HSCREENFONT(TermInfo)); GetTextMetrics(hDC, &tm); ReleaseDC(ghWndMain, hDC); // Character width and height XCHAR(TermInfo) = tm.tmAveCharWidth; YCHAR(TermInfo) = tm.tmHeight + tm.tmExternalLeading; // Set the terminal height and width based on the current font XSIZE(TermInfo) = tm.tmAveCharWidth * MAXCOLS; YSIZE(TermInfo) = (tm.tmHeight + tm.tmExternalLeading) * MAXROWS; }
static void game_compute_size(const game_params *params, int tilesize, int *x, int *y) { struct bbox bb = find_bbox(params); *x = XSIZE(tilesize, bb, solids[params->solid]); *y = YSIZE(tilesize, bb, solids[params->solid]); }
// Really import ========================================================== void ProgXrayImport::readAndCrop(const FileName &fn, Image<double> &I, int xCropSize, int yCropSize) const { I.read(fn); I().selfWindow(yCropSize,xCropSize, (int)(YSIZE(I())-yCropSize-1),(int)(XSIZE(I())-xCropSize-1)); I().resetOrigin(); }
/* Filter generation ------------------------------------------------------- */ void Steerable::generate1DFilters(double sigma, const MultidimArray<double> &Vtomograph, std::vector< MultidimArray<double> > &hx1, std::vector< MultidimArray<double> > &hy1, std::vector< MultidimArray<double> > &hz1){ // Initialization MultidimArray<double> aux; aux.initZeros(XSIZE(Vtomograph)); aux.setXmippOrigin(); for (int i=0; i<6; i++) hx1.push_back(aux); aux.initZeros(YSIZE(Vtomograph)); aux.setXmippOrigin(); for (int i=0; i<6; i++) hy1.push_back(aux); aux.initZeros(ZSIZE(Vtomograph)); aux.setXmippOrigin(); for (int i=0; i<6; i++) hz1.push_back(aux); double sigma2=sigma*sigma; double k1 = 1.0/pow((2.0*PI*sigma),(3.0/2.0)); double k2 = -1.0/(sigma2); FOR_ALL_ELEMENTS_IN_ARRAY1D(hx1[0]) { double i2=i*i; double g = -exp(-i2/(2.0*sigma2)); hx1[0](i) = k1*k2*g*(1.0-(i2/sigma2)); hx1[1](i) = k1*k2*g; hx1[2](i) = k1*k2*g; hx1[3](i) = k1*k2*k2*g*i; hx1[4](i) = k1*k2*k2*g*i; hx1[5](i) = k1*k2*k2*g; } FOR_ALL_ELEMENTS_IN_ARRAY1D(hy1[0]) { double i2=i*i; double g = -exp(-i2/(2.0*sigma2)); hy1[0](i) = g; hy1[1](i) = g*(1.0-(i2/sigma2)); hy1[2](i) = g; hy1[3](i) = g*i; hy1[4](i) = g; hy1[5](i) = g*i; } FOR_ALL_ELEMENTS_IN_ARRAY1D(hz1[0]) { double i2=i*i; double g = -exp(-i2/(2.0*sigma2)); hz1[0](i) = g; hz1[1](i) = g; hz1[2](i) = g*(1.0-(i2/sigma2)); hz1[3](i) = g; hz1[4](i) = g*i; hz1[5](i) = g*i; } }
void CTF::getCenteredImage(MultidimArray<DOUBLE> &result, DOUBLE Tm, bool do_abs, bool do_only_flip_phases, bool do_intact_until_first_peak, bool do_damping) { result.setXmippOrigin(); DOUBLE xs = (DOUBLE)XSIZE(result) * Tm; DOUBLE ys = (DOUBLE)YSIZE(result) * Tm; FOR_ALL_ELEMENTS_IN_ARRAY2D(result) { DOUBLE x = (DOUBLE)j / xs; DOUBLE y = (DOUBLE)i / ys; A2D_ELEM(result, i, j) = getCTF(x, y, do_abs, do_only_flip_phases, do_intact_until_first_peak, do_damping); } }
void FourierProjector::produceSideInfo() { // Zero padding MultidimArray<double> Vpadded; int paddedDim=(int)(paddingFactor*volumeSize); volume->window(Vpadded,FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim),FIRST_XMIPP_INDEX(paddedDim), LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim),LAST_XMIPP_INDEX(paddedDim)); volume->clear(); // Make Fourier transform, shift the volume origin to the volume center and center it MultidimArray< std::complex<double> > Vfourier; transformer3D.completeFourierTransform(Vpadded,Vfourier); ShiftFFT(Vfourier, FIRST_XMIPP_INDEX(XSIZE(Vpadded)), FIRST_XMIPP_INDEX(YSIZE(Vpadded)), FIRST_XMIPP_INDEX(ZSIZE(Vpadded))); CenterFFT(Vfourier,true); Vfourier.setXmippOrigin(); // Compensate for the Fourier normalization factor double K=(double)(XSIZE(Vpadded)*XSIZE(Vpadded)*XSIZE(Vpadded))/(double)(volumeSize*volumeSize); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vfourier) DIRECT_MULTIDIM_ELEM(Vfourier,n)*=K; Vpadded.clear(); // Compute Bspline coefficients if (BSplineDeg==3) { MultidimArray< double > VfourierRealAux, VfourierImagAux; Complex2RealImag(Vfourier, VfourierRealAux, VfourierImagAux); Vfourier.clear(); produceSplineCoefficients(BSPLINE3,VfourierRealCoefs,VfourierRealAux); produceSplineCoefficients(BSPLINE3,VfourierImagCoefs,VfourierImagAux); //VfourierRealAux.clear(); //VfourierImagAux.clear(); } else Complex2RealImag(Vfourier, VfourierRealCoefs, VfourierImagCoefs); // Allocate memory for the 2D Fourier transform projection().initZeros(volumeSize,volumeSize); projection().setXmippOrigin(); transformer2D.FourierTransform(projection(),projectionFourier,false); }
void FourierProjector::project(double rot, double tilt, double psi) { double freqy, freqx; std::complex< double > f; Euler_angles2matrix(rot,tilt,psi,E); projectionFourier.initZeros(); double shift=-FIRST_XMIPP_INDEX(volumeSize); double xxshift = -2 * PI * shift / volumeSize; double maxFreq2=maxFrequency*maxFrequency; double volumePaddedSize=XSIZE(VfourierRealCoefs); for (size_t i=0; i<YSIZE(projectionFourier); ++i) { FFT_IDX2DIGFREQ(i,volumeSize,freqy); double freqy2=freqy*freqy; double phasey=(double)(i) * xxshift; double freqYvol_X=MAT_ELEM(E,1,0)*freqy; double freqYvol_Y=MAT_ELEM(E,1,1)*freqy; double freqYvol_Z=MAT_ELEM(E,1,2)*freqy; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // The frequency of pairs (i,j) in 2D FFT_IDX2DIGFREQ(j,volumeSize,freqx); // Do not consider pixels with high frequency if ((freqy2+freqx*freqx)>maxFreq2) continue; // Compute corresponding frequency in the volume double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx; double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx; double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx; double c,d; if (BSplineDeg==0) { // 0 order interpolation // Compute corresponding index in the volume int kVolume=(int)round(freqvol_Z*volumePaddedSize); int iVolume=(int)round(freqvol_Y*volumePaddedSize); int jVolume=(int)round(freqvol_X*volumePaddedSize); c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume); d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume); } else if (BSplineDeg==1) { // B-spline linear interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); } else { // B-spline cubic interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); } // Phase shift to move the origin of the image to the corner double dotp = (double)(j) * xxshift + phasey; double a,b; sincos(dotp,&b,&a); // Multiply Fourier coefficient in volume times phase shift double ac = a * c; double bd = b * d; double ab_cd = (a + b) * (c + d); // And store the multiplication double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j); *ptrI_ij = ac - bd; *(ptrI_ij+1) = ab_cd - ac - bd; } } //VfourierRealCoefs.clear(); //VfourierImagCoefs.clear(); transformer2D.inverseFourierTransform(); }
void Steerable::singleFilter(const MultidimArray<double>& Vin, MultidimArray<double> &hx1, MultidimArray<double> &hy1, MultidimArray<double> &hz1, MultidimArray<double> &Vout){ MultidimArray< std::complex<double> > H, Aux; Vout.initZeros(Vin); // Filter in X #define MINUS_ONE_POWER(n) (((n)%2==0)? 1:-1) FourierTransformer transformer; transformer.FourierTransform(hx1,H); FOR_ALL_ELEMENTS_IN_ARRAY1D(H) H(i)*= MINUS_ONE_POWER(i); FourierTransformer transformer2; MultidimArray<double> aux(XSIZE(Vin)); transformer2.setReal(aux); for (size_t k=0; k<ZSIZE(Vin); k++) for (size_t i=0; i<YSIZE(Vin); i++) { for (size_t j=0; j<XSIZE(Vin); j++) DIRECT_A1D_ELEM(aux,j)=DIRECT_A3D_ELEM(Vin,k,i,j); transformer2.FourierTransform( ); transformer2.getFourierAlias( Aux ); Aux*=H; transformer2.inverseFourierTransform( ); for (size_t j=0; j<XSIZE(Vin); j++) DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,j); } // Filter in Y transformer.FourierTransform(hy1,H); FOR_ALL_ELEMENTS_IN_ARRAY1D(H) H(i)*= MINUS_ONE_POWER(i); aux.initZeros(YSIZE(Vin)); transformer2.setReal(aux); for (size_t k=0; k<ZSIZE(Vin); k++) for (size_t j=0; j<XSIZE(Vin); j++) { for (size_t i=0; i<YSIZE(Vin); i++) DIRECT_A1D_ELEM(aux,i)=DIRECT_A3D_ELEM(Vout,k,i,j); transformer2.FourierTransform( ); transformer2.getFourierAlias( Aux ); Aux*=H; transformer2.inverseFourierTransform( ); for (size_t i=0; i<YSIZE(Vin); i++) DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,i); } // Filter in Z transformer.FourierTransform(hz1,H); FOR_ALL_ELEMENTS_IN_ARRAY1D(H) H(i)*= MINUS_ONE_POWER(i); aux.initZeros(ZSIZE(Vin)); transformer2.setReal(aux); for (size_t i=0; i<YSIZE(Vin); i++) for (size_t j=0; j<XSIZE(Vin); j++) { for (size_t k=0; k<ZSIZE(Vin); k++) DIRECT_A1D_ELEM(aux,k)=DIRECT_A3D_ELEM(Vout,k,i,j); transformer2.FourierTransform( ); transformer2.getFourierAlias( Aux ); Aux*=H; transformer2.inverseFourierTransform( ); for (size_t k=0; k<ZSIZE(Vin); k++) DIRECT_A3D_ELEM(Vout,k,i,j)=XSIZE(aux)*DIRECT_A1D_ELEM(aux,k); } // If Missing wedge if (MW!=NULL) MW->removeWedge(Vout); }
void run() { MD.read(fn_star); // Check for rlnImageName label if (!MD.containsLabel(EMDL_IMAGE_NAME)) REPORT_ERROR("ERROR: Input STAR file does not contain the rlnImageName label"); if (do_split_per_micrograph && !MD.containsLabel(EMDL_MICROGRAPH_NAME)) REPORT_ERROR("ERROR: Input STAR file does not contain the rlnMicrographName label"); Image<DOUBLE> in; FileName fn_img, fn_mic; std::vector<FileName> fn_mics; std::vector<int> mics_ndims; // First get number of images and their size int ndim=0; bool is_first=true; int xdim, ydim, zdim; FOR_ALL_OBJECTS_IN_METADATA_TABLE(MD) { if (is_first) { MD.getValue(EMDL_IMAGE_NAME, fn_img); in.read(fn_img); xdim=XSIZE(in()); ydim=YSIZE(in()); zdim=ZSIZE(in()); is_first=false; } if (do_split_per_micrograph) { MD.getValue(EMDL_MICROGRAPH_NAME, fn_mic); bool have_found = false; for (int m = 0; m < fn_mics.size(); m++) { if (fn_mic == fn_mics[m]) { have_found = true; mics_ndims[m]++; break; } } if (!have_found) { fn_mics.push_back(fn_mic); mics_ndims.push_back(1); } } ndim++; } // If not splitting, just fill fn_mics and mics_ndim with one entry (to re-use loop below) if (!do_split_per_micrograph) { fn_mics.push_back(""); mics_ndims.push_back(ndim); } // Loop over all micrographs for (int m = 0; m < fn_mics.size(); m++) { ndim = mics_ndims[m]; fn_mic = fn_mics[m]; // Resize the output image std::cout << "Resizing the output stack to "<< ndim<<" images of size: "<<xdim<<"x"<<ydim<<"x"<<zdim << std::endl; DOUBLE Gb = ndim*zdim*ydim*xdim*8./1024./1024./1024.; std::cout << "This will require " << Gb << "Gb of memory...."<< std::endl; Image<DOUBLE> out(xdim, ydim, zdim, ndim); int n = 0; init_progress_bar(ndim); FOR_ALL_OBJECTS_IN_METADATA_TABLE(MD) { FileName fn_mymic; if (do_split_per_micrograph) MD.getValue(EMDL_MICROGRAPH_NAME, fn_mymic); else fn_mymic=""; if (fn_mymic == fn_mic) { MD.getValue(EMDL_IMAGE_NAME, fn_img); in.read(fn_img); if (do_apply_trans) { DOUBLE xoff = 0.; DOUBLE yoff = 0.; DOUBLE psi = 0.; MD.getValue(EMDL_ORIENT_ORIGIN_X, xoff); MD.getValue(EMDL_ORIENT_ORIGIN_Y, yoff); MD.getValue(EMDL_ORIENT_PSI, psi); // Apply the actual transformation Matrix2D<DOUBLE> A; rotation2DMatrix(psi, A); MAT_ELEM(A,0, 2) = xoff; MAT_ELEM(A,1, 2) = yoff; selfApplyGeometry(in(), A, IS_NOT_INV, DONT_WRAP); } out().setImage(n, in()); n++; if (n%100==0) progress_bar(n); } } progress_bar(ndim); FileName fn_out; if (do_split_per_micrograph) { // Remove any extensions from micrograph names.... fn_out = fn_root + "_" + fn_mic.withoutExtension() + fn_ext; } else fn_out = fn_root + fn_ext; out.write(fn_out); std::cout << "Written out: " << fn_out << std::endl; } std::cout << "Done!" <<std::endl; }
EnsembleNaiveBayes::EnsembleNaiveBayes( const std::vector < MultidimArray<double> > &features, const Matrix1D<double> &priorProbs, int discreteLevels, int numberOfClassifiers, double samplingFeatures, double samplingIndividuals, const std::string &newJudgeCombination) { int NFeatures=XSIZE(features[0]); int NsubFeatures=CEIL(NFeatures*samplingFeatures); K=features.size(); judgeCombination=newJudgeCombination; #ifdef WEIGHTED_SAMPLING // Measure the classification power of each variable NaiveBayes *nb_weights=new NaiveBayes(features, priorProbs, discreteLevels); MultidimArray<double> weights=nb_weights->__weights; delete nb_weights; double sumWeights=weights.sum(); #endif for (int n=0; n<numberOfClassifiers; n++) { // Produce the set of features for this subclassifier MultidimArray<int> subFeatures(NsubFeatures); FOR_ALL_ELEMENTS_IN_ARRAY1D(subFeatures) { #ifdef WEIGHTED_SAMPLING double random_sum_weight=rnd_unif(0,sumWeights); int j=0; do { double wj=DIRECT_A1D_ELEM(weights,j); if (wj<random_sum_weight) { random_sum_weight-=wj; j++; if (j==NFeatures) { j=NFeatures-1; break; } } else break; } while (true); DIRECT_A1D_ELEM(subFeatures,i)=j; #else DIRECT_A1D_ELEM(subFeatures,i)=round(rnd_unif(0,NFeatures-1)); #endif } // Container for the new training sample std::vector< MultidimArray<double> > newFeatures; // Produce the data set for each class for (int k=0; k<K; k++) { int NIndividuals=YSIZE(features[k]); int NsubIndividuals=CEIL(NIndividuals*samplingIndividuals); MultidimArray<int> subIndividuals(NsubIndividuals); FOR_ALL_ELEMENTS_IN_ARRAY1D(subIndividuals) subIndividuals(i)=ROUND(rnd_unif(0,NsubIndividuals-1)); MultidimArray<double> newFeaturesK; newFeaturesK.initZeros(NsubIndividuals,NsubFeatures); const MultidimArray<double>& features_k=features[k]; FOR_ALL_ELEMENTS_IN_ARRAY2D(newFeaturesK) DIRECT_A2D_ELEM(newFeaturesK,i,j)=DIRECT_A2D_ELEM(features_k, DIRECT_A1D_ELEM(subIndividuals,i), DIRECT_A1D_ELEM(subFeatures,j)); newFeatures.push_back(newFeaturesK); } // Create a Naive Bayes classifier with this data NaiveBayes *nb=new NaiveBayes(newFeatures, priorProbs, discreteLevels); ensemble.push_back(nb); ensembleFeatures.push_back(subFeatures); } }
// Shift an image through phase-shifts in its Fourier Transform (without pretabulated sine and cosine) void shiftImageInFourierTransform(MultidimArray<Complex >& in, MultidimArray<Complex >& out, double oridim, Matrix1D<double> shift) { out.resize(in); shift /= -oridim; double dotp, a, b, c, d, ac, bd, ab_cd, x, y, z, xshift, yshift, zshift; switch (in.getDim()) { case 1: xshift = XX(shift); if (ABS(xshift) < XMIPP_EQUAL_ACCURACY) { out = in; return; } for (long int j = 0; j < XSIZE(in); j++) { x = j; dotp = 2 * PI * (x * xshift); a = cos(dotp); b = sin(dotp); c = DIRECT_A1D_ELEM(in, j).real; d = DIRECT_A1D_ELEM(in, j).imag; ac = a * c; bd = b * d; ab_cd = (a + b) * (c + d); // (ab_cd-ac-bd = ad+bc : but needs 4 multiplications) DIRECT_A1D_ELEM(out, j) = Complex(ac - bd, ab_cd - ac - bd); } break; case 2: xshift = XX(shift); yshift = YY(shift); if (ABS(xshift) < XMIPP_EQUAL_ACCURACY && ABS(yshift) < XMIPP_EQUAL_ACCURACY) { out = in; return; } for (long int i = 0; i < XSIZE(in); i++) for (long int j = 0; j < XSIZE(in); j++) { x = j; y = i; dotp = 2 * PI * (x * xshift + y * yshift); a = cos(dotp); b = sin(dotp); c = DIRECT_A2D_ELEM(in, i, j).real; d = DIRECT_A2D_ELEM(in, i, j).imag; ac = a * c; bd = b * d; ab_cd = (a + b) * (c + d); DIRECT_A2D_ELEM(out, i, j) = Complex(ac - bd, ab_cd - ac - bd); } for (long int i = YSIZE(in) - 1; i >= XSIZE(in); i--) { y = i - YSIZE(in); for (long int j = 0; j < XSIZE(in); j++) { x = j; dotp = 2 * PI * (x * xshift + y * yshift); a = cos(dotp); b = sin(dotp); c = DIRECT_A2D_ELEM(in, i, j).real; d = DIRECT_A2D_ELEM(in, i, j).imag; ac = a * c; bd = b * d; ab_cd = (a + b) * (c + d); DIRECT_A2D_ELEM(out, i, j) = Complex(ac - bd, ab_cd - ac - bd); } } break; case 3: xshift = XX(shift); yshift = YY(shift); zshift = ZZ(shift); if (ABS(xshift) < XMIPP_EQUAL_ACCURACY && ABS(yshift) < XMIPP_EQUAL_ACCURACY && ABS(zshift) < XMIPP_EQUAL_ACCURACY) { out = in; return; } for (long int k = 0; k < ZSIZE(in); k++) { z = (k < XSIZE(in)) ? k : k - ZSIZE(in); for (long int i = 0; i < YSIZE(in); i++) { y = (i < XSIZE(in)) ? i : i - YSIZE(in); for (long int j = 0; j < XSIZE(in); j++) { x = j; dotp = 2 * PI * (x * xshift + y * yshift + z * zshift); a = cos(dotp); b = sin(dotp); c = DIRECT_A3D_ELEM(in, k, i, j).real; d = DIRECT_A3D_ELEM(in, k, i, j).imag; ac = a * c; bd = b * d; ab_cd = (a + b) * (c + d); DIRECT_A3D_ELEM(out, k, i, j) = Complex(ac - bd, ab_cd - ac - bd); } } } break; default: REPORT_ERROR("shiftImageInFourierTransform ERROR: dimension should be 1, 2 or 3!"); } }
void ProgSSNR::estimateSSNR(int dim, Matrix2D<double> &output) { // These vectors are for 1D Matrix1D<double> S_S21D((int)(XSIZE(S()) / 2 - ring_width)), S_N21D((int)(XSIZE(S()) / 2 - ring_width)), K1D((int)(XSIZE(S()) / 2 - ring_width)), S_SSNR1D; Matrix1D<double> N_S21D((int)(XSIZE(S()) / 2 - ring_width)), N_N21D((int)(XSIZE(S()) / 2 - ring_width)), N_SSNR1D; // Selfile of the 2D images MetaData SF_individual; std::cerr << "Computing the SSNR ...\n"; init_progress_bar(SF_S.size()); int imgno = 1; Image<double> Is, In; Projection Iths, Ithn; MultidimArray< std::complex<double> > FFT_Is, FFT_Iths, FFT_In, FFT_Ithn; MultidimArray<double> S2s, N2s, S2n, N2n; FileName fn_img; FourierTransformer FT(FFTW_BACKWARD); FourierProjector *Sprojector=NULL; FourierProjector *Nprojector=NULL; if (fourierProjections) { Sprojector=new FourierProjector(S(),2,0.5,LINEAR); Nprojector=new FourierProjector(N(),2,0.5,LINEAR); } FOR_ALL_OBJECTS_IN_METADATA2(SF_S, SF_N) { double rot, tilt, psi; SF_S.getValue(MDL_ANGLE_ROT,rot, __iter.objId); SF_S.getValue(MDL_ANGLE_TILT,tilt,__iter.objId); SF_S.getValue(MDL_ANGLE_PSI,psi,__iter.objId); SF_S.getValue(MDL_IMAGE,fn_img,__iter.objId); Is.read(fn_img); Is().setXmippOrigin(); SF_N.getValue(MDL_IMAGE,fn_img,__iter2.objId); In.read(fn_img); In().setXmippOrigin(); if (fourierProjections) { projectVolume(*Sprojector, Iths, YSIZE(Is()), XSIZE(Is()), rot, tilt, psi); projectVolume(*Nprojector, Ithn, YSIZE(Is()), XSIZE(Is()), rot, tilt, psi); } else { projectVolume(S(), Iths, YSIZE(Is()), XSIZE(Is()), rot, tilt, psi); projectVolume(N(), Ithn, YSIZE(Is()), XSIZE(Is()), rot, tilt, psi); } #ifdef DEBUG Image<double> save; save() = Is(); save.write("PPPread_signal.xmp"); save() = In(); save.write("PPPread_noise.xmp"); save() = Iths(); save.write("PPPtheo_signal.xmp"); save() = Ithn(); save.write("PPPtheo_noise.xmp"); #endif Is() -= Iths(); In() -= Ithn(); // According to the article: should we not subtract here (simply remove this line) // "...except that there is no subtraction in the denominator because the // underlying signal is zero by definition." if (dim == 2) { FT.completeFourierTransform(Is(), FFT_Is); FT.completeFourierTransform(Iths(), FFT_Iths); FT.completeFourierTransform(In(), FFT_In); FT.completeFourierTransform(Ithn(), FFT_Ithn); } else { FT.FourierTransform(Is(), FFT_Is); FT.FourierTransform(Iths(), FFT_Iths); FT.FourierTransform(In(), FFT_In); FT.FourierTransform(Ithn(), FFT_Ithn); } #ifdef DEBUG Image< std::complex<double> > savec; savec() = FFT_Is; savec.write("PPPFFTread_signal.xmp"); savec() = FFT_In; savec.write("PPPFFTread_noise.xmp"); savec() = FFT_Iths; savec.write("PPPFFTtheo_signal.xmp"); savec() = FFT_Ithn; savec.write("PPPFFTtheo_noise.xmp"); #endif // Compute the amplitudes S2s.resizeNoCopy(FFT_Iths); N2s.resizeNoCopy(FFT_Iths); S2n.resizeNoCopy(FFT_Iths); N2n.resizeNoCopy(FFT_Iths); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(FFT_Iths) { DIRECT_MULTIDIM_ELEM(S2s, n) = abs(DIRECT_MULTIDIM_ELEM(FFT_Iths, n)); DIRECT_MULTIDIM_ELEM(S2s, n) *= DIRECT_MULTIDIM_ELEM(S2s, n); DIRECT_MULTIDIM_ELEM(N2s, n) = abs(DIRECT_MULTIDIM_ELEM(FFT_Is, n)); DIRECT_MULTIDIM_ELEM(N2s, n) *= DIRECT_MULTIDIM_ELEM(N2s, n); DIRECT_MULTIDIM_ELEM(S2n, n) = abs(DIRECT_MULTIDIM_ELEM(FFT_Ithn, n)); DIRECT_MULTIDIM_ELEM(S2n, n) *= DIRECT_MULTIDIM_ELEM(S2n, n); DIRECT_MULTIDIM_ELEM(N2n, n) = abs(DIRECT_MULTIDIM_ELEM(FFT_In, n)); DIRECT_MULTIDIM_ELEM(N2n, n) *= DIRECT_MULTIDIM_ELEM(N2n, n); } #ifdef DEBUG save() = S2s(); save.write("PPPS2s.xmp"); save() = N2s(); save.write("PPPN2s.xmp"); save() = S2n(); save.write("PPPS2n.xmp"); save() = N2n(); save.write("PPPN2n.xmp"); #endif if (dim == 2) { // Compute the SSNR image Image<double> SSNR2D; SSNR2D().initZeros(S2s); const MultidimArray<double> & SSNR2Dmatrix=SSNR2D(); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(S2s) { double ISSNR = 0, alpha = 0, SSNR = 0; double aux = DIRECT_MULTIDIM_ELEM(N2s,n); if (aux > min_power) ISSNR = DIRECT_MULTIDIM_ELEM(S2s,n) / aux; aux = DIRECT_MULTIDIM_ELEM(N2n,n); if (aux > min_power) alpha = DIRECT_MULTIDIM_ELEM(S2n,n) / aux; if (alpha > min_power) { aux = ISSNR / alpha - 1.0; SSNR = XMIPP_MAX(aux, 0.0); } if (SSNR > min_power) DIRECT_MULTIDIM_ELEM(SSNR2Dmatrix,n) = 10.0 * log10(SSNR + 1.0); } CenterFFT(SSNR2D(), true); #ifdef DEBUG save() = SSNR2Dmatrix; save.write("PPPSSNR2D.xmp"); #endif // Save image FileName fn_img_out; fn_img_out.compose(imgno, fn_out_images, "stk"); SSNR2D.write(fn_img_out); size_t objId = SF_individual.addObject(); SF_individual.setValue(MDL_IMAGE,fn_img_out,objId); SF_individual.setValue(MDL_ANGLE_ROT,rot,objId); SF_individual.setValue(MDL_ANGLE_TILT,tilt,objId); SF_individual.setValue(MDL_ANGLE_PSI,psi,objId); }
static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldstate, const game_state *state, int dir, const game_ui *ui, float animtime, float flashtime) { int i, j; struct bbox bb = find_bbox(&state->params); struct solid *poly; const int *pkey, *gkey; float t[3]; float angle; int square; draw_rect(dr, 0, 0, XSIZE(GRID_SCALE, bb, state->solid), YSIZE(GRID_SCALE, bb, state->solid), COL_BACKGROUND); if (dir < 0) { const game_state *t; /* * This is an Undo. So reverse the order of the states, and * run the roll timer backwards. */ assert(oldstate); t = oldstate; oldstate = state; state = t; animtime = ROLLTIME - animtime; } if (!oldstate) { oldstate = state; angle = 0.0; square = state->current; pkey = state->dpkey; gkey = state->dgkey; } else { angle = state->angle * animtime / ROLLTIME; square = state->previous; pkey = state->spkey; gkey = state->sgkey; } state = oldstate; for (i = 0; i < state->grid->nsquares; i++) { int coords[8]; for (j = 0; j < state->grid->squares[i].npoints; j++) { coords[2*j] = ((int)(state->grid->squares[i].points[2*j] * GRID_SCALE) + ds->ox); coords[2*j+1] = ((int)(state->grid->squares[i].points[2*j+1]*GRID_SCALE) + ds->oy); } draw_polygon(dr, coords, state->grid->squares[i].npoints, GET_SQUARE(state, i) ? COL_BLUE : COL_BACKGROUND, COL_BORDER); } /* * Now compute and draw the polyhedron. */ poly = transform_poly(state->solid, state->grid->squares[square].flip, pkey[0], pkey[1], angle); /* * Compute the translation required to align the two key points * on the polyhedron with the same key points on the current * face. */ for (i = 0; i < 3; i++) { float tc = 0.0; for (j = 0; j < 2; j++) { float grid_coord; if (i < 2) { grid_coord = state->grid->squares[square].points[gkey[j]*2+i]; } else { grid_coord = 0.0; } tc += (grid_coord - poly->vertices[pkey[j]*3+i]); } t[i] = tc / 2; } for (i = 0; i < poly->nvertices; i++) for (j = 0; j < 3; j++) poly->vertices[i*3+j] += t[j]; /* * Now actually draw each face. */ for (i = 0; i < poly->nfaces; i++) { float points[8]; int coords[8]; for (j = 0; j < poly->order; j++) { int f = poly->faces[i*poly->order + j]; points[j*2] = (poly->vertices[f*3+0] - poly->vertices[f*3+2] * poly->shear); points[j*2+1] = (poly->vertices[f*3+1] - poly->vertices[f*3+2] * poly->shear); } for (j = 0; j < poly->order; j++) { coords[j*2] = (int)floor(points[j*2] * GRID_SCALE) + ds->ox; coords[j*2+1] = (int)floor(points[j*2+1] * GRID_SCALE) + ds->oy; } /* * Find out whether these points are in a clockwise or * anticlockwise arrangement. If the latter, discard the * face because it's facing away from the viewer. * * This would involve fiddly winding-number stuff for a * general polygon, but for the simple parallelograms we'll * be seeing here, all we have to do is check whether the * corners turn right or left. So we'll take the vector * from point 0 to point 1, turn it right 90 degrees, * and check the sign of the dot product with that and the * next vector (point 1 to point 2). */ { float v1x = points[2]-points[0]; float v1y = points[3]-points[1]; float v2x = points[4]-points[2]; float v2y = points[5]-points[3]; float dp = v1x * v2y - v1y * v2x; if (dp <= 0) continue; } draw_polygon(dr, coords, poly->order, state->facecolours[i] ? COL_BLUE : COL_BACKGROUND, COL_BORDER); } sfree(poly); draw_update(dr, 0, 0, XSIZE(GRID_SCALE, bb, state->solid), YSIZE(GRID_SCALE, bb, state->solid)); /* * Update the status bar. */ { char statusbuf[256]; if (state->completed) { strcpy(statusbuf, _("COMPLETED!")); strcpy(statusbuf+strlen(statusbuf), " "); } else statusbuf[0] = '\0'; sprintf(statusbuf+strlen(statusbuf), _("Moves: %d"), (state->completed ? state->completed : state->movecount)); status_bar(dr, statusbuf); } }
void PolyZernikes::fit(const Matrix1D<int> & coef, MultidimArray<double> & im, MultidimArray<double> &weight, MultidimArray<bool> & ROI, int verbose) { this->create(coef); size_t xdim = XSIZE(im); size_t ydim = YSIZE(im); //int numZer = (size_t)coef.sum(); int numZer = (size_t)coef.sum(); //Actually polOrder corresponds to the polynomial order +1 int polOrder=(int)ZERNIKE_ORDER(coef.size()); im.setXmippOrigin(); Matrix2D<double> polValue(polOrder,polOrder); //First argument means number of images //Second argument means number of pixels WeightedLeastSquaresHelper weightedLeastSquaresHelper; Matrix2D<double>& zerMat=weightedLeastSquaresHelper.A; zerMat.resizeNoCopy((size_t)ROI.sum(), numZer); double iMaxDim2 = 2./std::max(xdim,ydim); size_t pixel_idx=0; weightedLeastSquaresHelper.b.resizeNoCopy((size_t)ROI.sum()); weightedLeastSquaresHelper.w.resizeNoCopy(weightedLeastSquaresHelper.b); FOR_ALL_ELEMENTS_IN_ARRAY2D(im) { if ( (A2D_ELEM(ROI,i,j))) { //For one i we swap the different j double y=i*iMaxDim2; double x=j*iMaxDim2; //polValue = [ 0 y y2 y3 ... // x xy xy2 xy3 ... // x2 x2y x2y2 x2y3 ] //dMij(polValue,py,px) py es fila, px es columna for (int py = 0; py < polOrder; ++py) { double ypy=std::pow(y,py); for (int px = 0; px < polOrder; ++px) dMij(polValue,px,py) = ypy*std::pow(x,px); } Matrix2D<int> *fMat; //We generate the representation of the Zernike polynomials for (int k=0; k < numZer; ++k) { fMat = &fMatV[k]; if (fMat == NULL) continue; double temp = 0; for (size_t px = 0; px < (*fMat).Xdim(); ++px) for (size_t py = 0; py < (*fMat).Ydim(); ++py) temp += dMij(*fMat,py,px)*dMij(polValue,py,px); dMij(zerMat,pixel_idx,k) = temp; } VEC_ELEM(weightedLeastSquaresHelper.b,pixel_idx)=A2D_ELEM(im,i,j); VEC_ELEM(weightedLeastSquaresHelper.w,pixel_idx)=std::abs(A2D_ELEM(weight,i,j)); ++pixel_idx; } } Matrix1D<double> zernikeCoefficients; weightedLeastSquares(weightedLeastSquaresHelper, zernikeCoefficients); fittedCoeffs = zernikeCoefficients; // Pointer to the image to be fitted MultidimArray<double> reconstructed; reconstructed.resizeNoCopy(im); pixel_idx=0; FOR_ALL_ELEMENTS_IN_ARRAY2D(im) if (A2D_ELEM(ROI,i,j)) { double temp=0; for (int k=0; k < numZer; ++k) temp+=dMij(zerMat,pixel_idx,k)*VEC_ELEM(fittedCoeffs,k); A2D_ELEM(reconstructed,i,j)=temp; if ( fabs(A2D_ELEM(reconstructed,i,j)-A2D_ELEM(im,i,j)) > PI) A2D_ELEM(ROI,i,j) = false; ++pixel_idx; } pixel_idx=0; if (verbose > 0) { Image<double> save; save()=reconstructed; save.write("reconstructedZernikes.xmp"); ROI.write("ROI.txt"); } }
void Projector::rotate3D(MultidimArray<Complex > &f3d, Matrix2D<DOUBLE> &A, bool inv) { DOUBLE fx, fy, fz, xp, yp, zp; int x0, x1, y0, y1, z0, z1, y, z, y2, z2, r2; bool is_neg_x; Complex d000, d010, d100, d110, d001, d011, d101, d111, dx00, dx10, dxy0, dx01, dx11, dxy1; Matrix2D<DOUBLE> Ainv; // f3d should already be in the right size (ori_size,orihalfdim) // AND the points outside max_r should already be zero... // f3d.initZeros(); // Use the inverse matrix if (inv) Ainv = A; else Ainv = A.transpose(); // The f3d image may be smaller than r_max, in that case also make sure not to fill the corners! int my_r_max = XMIPP_MIN(r_max, XSIZE(f3d) - 1); // Go from the 3D rotated coordinates to the original map coordinates Ainv *= (DOUBLE)padding_factor; // take scaling into account directly int max_r2 = my_r_max * my_r_max; int min_r2_nn = r_min_nn * r_min_nn; #ifdef DEBUG std::cerr << " XSIZE(f3d)= "<< XSIZE(f3d) << std::endl; std::cerr << " YSIZE(f3d)= "<< YSIZE(f3d) << std::endl; std::cerr << " XSIZE(data)= "<< XSIZE(data) << std::endl; std::cerr << " YSIZE(data)= "<< YSIZE(data) << std::endl; std::cerr << " STARTINGX(data)= "<< STARTINGX(data) << std::endl; std::cerr << " STARTINGY(data)= "<< STARTINGY(data) << std::endl; std::cerr << " STARTINGZ(data)= "<< STARTINGZ(data) << std::endl; std::cerr << " max_r= "<< r_max << std::endl; std::cerr << " Ainv= " << Ainv << std::endl; #endif for (int k=0; k < ZSIZE(f3d); k++) { // Don't search beyond square with side max_r if (k <= my_r_max) { z = k; } else if (k >= ZSIZE(f3d) - my_r_max) { z = k - ZSIZE(f3d); } else continue; z2 = z * z; for (int i=0; i < YSIZE(f3d); i++) { // Don't search beyond square with side max_r if (i <= my_r_max) { y = i; } else if (i >= YSIZE(f3d) - my_r_max) { y = i - YSIZE(f3d); } else continue; y2 = y * y; for (int x=0; x <= my_r_max; x++) { // Only include points with radius < max_r (exclude points outside circle in square) r2 = x * x + y2 + z2; if (r2 > max_r2) continue; // Get logical coordinates in the 3D map xp = Ainv(0,0) * x + Ainv(0,1) * y + Ainv(0,2) * z; yp = Ainv(1,0) * x + Ainv(1,1) * y + Ainv(1,2) * z; zp = Ainv(2,0) * x + Ainv(2,1) * y + Ainv(2,2) * z; if (interpolator == TRILINEAR || r2 < min_r2_nn) { // Only asymmetric half is stored if (xp < 0) { // Get complex conjugated hermitian symmetry pair xp = -xp; yp = -yp; zp = -zp; is_neg_x = true; } else { is_neg_x = false; } // Trilinear interpolation (with physical coords) // Subtract STARTINGY to accelerate access to data (STARTINGX=0) // In that way use DIRECT_A3D_ELEM, rather than A3D_ELEM x0 = FLOOR(xp); fx = xp - x0; x1 = x0 + 1; y0 = FLOOR(yp); fy = yp - y0; y0 -= STARTINGY(data); y1 = y0 + 1; z0 = FLOOR(zp); fz = zp - z0; z0 -= STARTINGZ(data); z1 = z0 + 1; // Matrix access can be accelerated through pre-calculation of z0*xydim etc. d000 = DIRECT_A3D_ELEM(data, z0, y0, x0); d001 = DIRECT_A3D_ELEM(data, z0, y0, x1); d010 = DIRECT_A3D_ELEM(data, z0, y1, x0); d011 = DIRECT_A3D_ELEM(data, z0, y1, x1); d100 = DIRECT_A3D_ELEM(data, z1, y0, x0); d101 = DIRECT_A3D_ELEM(data, z1, y0, x1); d110 = DIRECT_A3D_ELEM(data, z1, y1, x0); d111 = DIRECT_A3D_ELEM(data, z1, y1, x1); // Set the interpolated value in the 2D output array // interpolate in x #ifndef FLOAT_PRECISION __m256d __fx = _mm256_set1_pd(fx); __m256d __interpx1 = LIN_INTERP_AVX(_mm256_setr_pd(d000.real, d000.imag, d100.real, d100.imag), _mm256_setr_pd(d001.real, d001.imag, d101.real, d101.imag), __fx); __m256d __interpx2 = LIN_INTERP_AVX(_mm256_setr_pd(d010.real, d010.imag, d110.real, d110.imag), _mm256_setr_pd(d011.real, d011.imag, d111.real, d111.imag), __fx); // interpolate in y __m256d __fy = _mm256_set1_pd(fy); __m256d __interpy = LIN_INTERP_AVX(__interpx1, __interpx2, __fy); #else __m128 __fx = _mm_set1_ps(fx); __m128 __interpx1 = LIN_INTERP_AVX(_mm_setr_ps(d000.real, d000.imag, d100.real, d100.imag), _mm_setr_ps(d001.real, d001.imag, d101.real, d101.imag), __fx); __m128 __interpx2 = LIN_INTERP_AVX(_mm_setr_ps(d010.real, d010.imag, d110.real, d110.imag), _mm_setr_ps(d011.real, d011.imag, d111.real, d111.imag), __fx); // interpolate in y __m128 __fy = _mm_set1_ps(fy); __m128 __interpy = LIN_INTERP_AVX(__interpx1, __interpx2, __fy); #endif Complex* interpy = (Complex*)&__interpy; //interpolate in z DIRECT_A3D_ELEM(f3d, k, i, x) = LIN_INTERP(fz, interpy[0], interpy[1]); // Take complex conjugated for half with negative x if (is_neg_x) DIRECT_A3D_ELEM(f3d, k, i, x) = conj(DIRECT_A3D_ELEM(f3d, k, i, x)); } // endif TRILINEAR else if (interpolator == NEAREST_NEIGHBOUR ) { x0 = ROUND(xp); y0 = ROUND(yp); z0 = ROUND(zp); if (x0 < 0) DIRECT_A3D_ELEM(f3d, k, i, x) = conj(A3D_ELEM(data, -z0, -y0, -x0)); else DIRECT_A3D_ELEM(f3d, k, i, x) = A3D_ELEM(data, z0, y0, x0); } // endif NEAREST_NEIGHBOUR else REPORT_ERROR("Unrecognized interpolator in Projector::project"); } // endif x-loop } // endif y-loop } // endif z-loop }
void FourierProjector::project(double rot, double tilt, double psi, const MultidimArray<double> *ctf) { double freqy, freqx; std::complex< double > f; Euler_angles2matrix(rot,tilt,psi,E); projectionFourier.initZeros(); double maxFreq2=maxFrequency*maxFrequency; int Xdim=(int)XSIZE(VfourierRealCoefs); int Ydim=(int)YSIZE(VfourierRealCoefs); int Zdim=(int)ZSIZE(VfourierRealCoefs); for (size_t i=0; i<YSIZE(projectionFourier); ++i) { FFT_IDX2DIGFREQ(i,volumeSize,freqy); double freqy2=freqy*freqy; double freqYvol_X=MAT_ELEM(E,1,0)*freqy; double freqYvol_Y=MAT_ELEM(E,1,1)*freqy; double freqYvol_Z=MAT_ELEM(E,1,2)*freqy; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // The frequency of pairs (i,j) in 2D FFT_IDX2DIGFREQ(j,volumeSize,freqx); // Do not consider pixels with high frequency if ((freqy2+freqx*freqx)>maxFreq2) continue; // Compute corresponding frequency in the volume double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx; double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx; double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx; double c,d; if (BSplineDeg==0) { // 0 order interpolation // Compute corresponding index in the volume int kVolume=(int)round(freqvol_Z*volumePaddedSize); int iVolume=(int)round(freqvol_Y*volumePaddedSize); int jVolume=(int)round(freqvol_X*volumePaddedSize); c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume); d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume); } else if (BSplineDeg==1) { // B-spline linear interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); } else { // B-spline cubic interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; // Commented for speed-up, the corresponding code is below // c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); // d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); // The code below is a replicate for speed reasons of interpolatedElementBSpline3D double z=kVolume; double y=iVolume; double x=jVolume; // Logical to physical z -= STARTINGZ(VfourierRealCoefs); y -= STARTINGY(VfourierRealCoefs); x -= STARTINGX(VfourierRealCoefs); int l1 = (int)ceil(x - 2); int l2 = l1 + 3; int m1 = (int)ceil(y - 2); int m2 = m1 + 3; int n1 = (int)ceil(z - 2); int n2 = n1 + 3; c = d = 0.0; double aux; for (int nn = n1; nn <= n2; nn++) { int equivalent_nn=nn; if (nn<0) equivalent_nn=-nn-1; else if (nn>=Zdim) equivalent_nn=2*Zdim-nn-1; double yxsumRe = 0.0, yxsumIm = 0.0; for (int m = m1; m <= m2; m++) { int equivalent_m=m; if (m<0) equivalent_m=-m-1; else if (m>=Ydim) equivalent_m=2*Ydim-m-1; double xsumRe = 0.0, xsumIm = 0.0; for (int l = l1; l <= l2; l++) { double xminusl = x - (double) l; int equivalent_l=l; if (l<0) equivalent_l=-l-1; else if (l>=Xdim) equivalent_l=2*Xdim-l-1; double CoeffRe = (double) DIRECT_A3D_ELEM(VfourierRealCoefs,equivalent_nn,equivalent_m,equivalent_l); double CoeffIm = (double) DIRECT_A3D_ELEM(VfourierImagCoefs,equivalent_nn,equivalent_m,equivalent_l); BSPLINE03(aux,xminusl); xsumRe += CoeffRe * aux; xsumIm += CoeffIm * aux; } double yminusm = y - (double) m; BSPLINE03(aux,yminusm); yxsumRe += xsumRe * aux; yxsumIm += xsumIm * aux; } double zminusn = z - (double) nn; BSPLINE03(aux,zminusn); c += yxsumRe * aux; d += yxsumIm * aux; } } // Phase shift to move the origin of the image to the corner double a=DIRECT_A2D_ELEM(phaseShiftImgA,i,j); double b=DIRECT_A2D_ELEM(phaseShiftImgB,i,j); if (ctf!=NULL) { double ctfij=DIRECT_A2D_ELEM(*ctf,i,j); a*=ctfij; b*=ctfij; } // Multiply Fourier coefficient in volume times phase shift double ac = a * c; double bd = b * d; double ab_cd = (a + b) * (c + d); // And store the multiplication double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j); *ptrI_ij = ac - bd; *(ptrI_ij+1) = ab_cd - ac - bd; } } transformer2D.inverseFourierTransform(); }
void runThread(ThreadArgument &thArg) { int thread_id = thArg.thread_id; ProgXrayImport * ptrProg= (ProgXrayImport *)thArg.workClass; MetaData localMD; Image<double> Iaux; FileName fnImgIn, fnImgOut; size_t first = 0, last = 0; MultidimArray<char> mask; while (ptrProg->td->getTasks(first, last)) { for (size_t i=first; i<=last; i++) { ptrProg->inMD.getValue(MDL_IMAGE, fnImgIn, ptrProg->objIds[i]); MDRow rowGeo; ptrProg->readGeoInfo(fnImgIn, rowGeo); // ptrProg->readAndCrop(fnImgIn, Iaux, ptrProg->cropSizeX, ptrProg->cropSizeY); Iaux.read(fnImgIn); Iaux().selfWindow(ptrProg->cropSizeYi,ptrProg->cropSizeXi, (int)(YSIZE(Iaux())-ptrProg->cropSizeYe-1),(int)(XSIZE(Iaux())-ptrProg->cropSizeXe-1)); Iaux().resetOrigin(); if (XSIZE(ptrProg->IavgDark())!=0) { Iaux()-=ptrProg->IavgDark(); forcePositive(Iaux()); } double currentBeam = 1; double expTime = 1; double slitWidth = 1; if ( ptrProg->dSource == ptrProg->MISTRAL ) { size_t idx = fnImgIn.getPrefixNumber(); currentBeam = dMi(ptrProg->cBeamArray, idx-1); expTime = dMi(ptrProg->expTimeArray, idx-1); slitWidth = dMi(ptrProg->slitWidthArray, idx-1); } else ptrProg->readCorrectionInfo(fnImgIn, currentBeam, expTime, slitWidth); Iaux() *= 1.0/(currentBeam*expTime*slitWidth); if (XSIZE(ptrProg->IavgFlat())!=0) Iaux()/=ptrProg->IavgFlat(); // Assign median filter to zero valued pixels to avoid -inf when applying log10 Iaux().equal(0,mask); mask.resizeNoCopy(Iaux()); if (XSIZE(ptrProg->bpMask()) != 0) mask += ptrProg->bpMask(); boundMedianFilter(Iaux(), mask); if (ptrProg->logFix) { Iaux().selfLog(); if (ptrProg->selfAttFix) Iaux() *= -1.; } fnImgOut.compose(i+1, ptrProg->fnOut); size_t objId = localMD.addObject(); localMD.setValue(MDL_IMAGE,fnImgOut,objId); localMD.setRow(rowGeo, objId); // // localMD.setValue(MDL_ANGLE_TILT,Iaux.tilt(),objId); Iaux.write(fnImgOut); if (thread_id==0) progress_bar(i); } } //Lock for update the total counter ptrProg->mutex.lock(); ptrProg->outMD.unionAll(localMD); ptrProg->mutex.unlock(); }
void PolyZernikes::zernikePols(const Matrix1D<int> coef, MultidimArray<double> & im, MultidimArray<bool> & ROI, int verbose) { this->create(coef); int polOrder=(int)ZERNIKE_ORDER(coef.size()); int numZer = coef.size(); int xdim = XSIZE(im); int ydim = YSIZE(im); im.setXmippOrigin(); Matrix2D<double> polValue(polOrder,polOrder); double iMaxDim2 = 2./std::max(xdim,ydim); double temp = 0; FOR_ALL_ELEMENTS_IN_ARRAY2D(im) { if (A2D_ELEM(ROI,i,j)) { //For one i we swap the different j double y=i*iMaxDim2; double x=j*iMaxDim2; //polValue = [ 0 y y2 y3 ... // x xy xy2 xy3 ... // x2 x2y x2y2 x2y3 ] //dMij(polValue,py,px) py es fila, px es columna for (int py = 0; py < polOrder; ++py) { double ypy=std::pow(y,py); for (int px = 0; px < polOrder; ++px) dMij(polValue,px,py) = ypy*std::pow(x,px); } Matrix2D<int> *fMat; //We generate the representation of the Zernike polynomials for (int k=0; k < numZer; ++k) { fMat = &fMatV[k]; if ( (dMij(*fMat,0,0) == 0) && MAT_SIZE(*fMat) == 1 ) continue; for (size_t px = 0; px < (*fMat).Xdim(); ++px) for (size_t py = 0; py < (*fMat).Ydim(); ++py) temp += dMij(*fMat,py,px)*dMij(polValue,py,px)*VEC_ELEM(coef,k); } A2D_ELEM(im,i,j) = temp; temp = 0; } } STARTINGX(im)=STARTINGY(im)=0; if (verbose == 1) { Image<double> save; save()=im; save.write("PPP1.xmp"); } }
void ProgXrayImport::run() { // Delete output stack if it exists fnOut = fnRoot + ".mrc"; fnOut.deleteFile(); /* Turn off error handling */ H5Eset_auto(H5E_DEFAULT, NULL, NULL); if (dSource == MISTRAL) H5File.openFile(fnInput, H5F_ACC_RDONLY); // Reading bad pixels mask if ( !fnBPMask.empty() ) { std::cerr << "Reading bad pixels mask from "+fnBPMask << "." << std::endl; bpMask.read(fnBPMask); if ( (cropSizeX + cropSizeY ) > 0 ) bpMask().selfWindow(cropSizeY,cropSizeX, (int)(YSIZE(bpMask())-cropSizeY-1),(int)(XSIZE(bpMask())-cropSizeX-1)); STARTINGX(bpMask()) = STARTINGY(bpMask()) = 0; } // Setting the image projections list switch (dSource) { case MISTRAL: { inMD.read(fnInput); H5File.getDataset("NXtomo/data/rotation_angle", anglesArray, false); H5File.getDataset("NXtomo/instrument/sample/ExpTimes", expTimeArray, false); H5File.getDataset("NXtomo/instrument/sample/current", cBeamArray); /* In case there is no angles information we set them to to an increasing sequence * just to be able to continue importing data */ if ( anglesArray.size() != inMD.size() ) { reportWarning("Input file does not contains angle information. Default sequence used."); anglesArray.resizeNoCopy(inMD.size()); anglesArray.enumerate(); } // If expTime is empty or only one single value in nexus file then we fill with 1 if (expTimeArray.size() < 2) { reportWarning("Input file does not contains tomogram exposition time information."); expTimeArray.initConstant(anglesArray.size(), 1.); } // If current is empty or only one single value in nexus file then we fill with 1 if (cBeamArray.size() < 2) { reportWarning("Input file does not contains tomogram current beam information."); cBeamArray.initConstant(anglesArray.size(), 1.); } // Since Alba does not provide slit width, we set to ones slitWidthArray.initConstant(anglesArray.size(), 1.); } break; case BESSY: { size_t objId; for (size_t i = tIni; i <= tEnd; ++i) { objId = inMD.addObject(); inMD.setValue(MDL_IMAGE, fnInput + formatString("/img%d.spe", i), objId); } break; } case GENERIC: { // Get Darkfield std::cerr << "Getting darkfield from "+fnInput << " ..." << std::endl; getDarkfield(fnInput, IavgDark); if (XSIZE(IavgDark())!=0) IavgDark.write(fnRoot+"_darkfield.xmp"); std::vector<FileName> listDir; fnInput.getFiles(listDir); size_t objId; for (size_t i = 0; i < listDir.size(); ++i) { if (!listDir[i].hasImageExtension()) continue; objId = inMD.addObject(); inMD.setValue(MDL_IMAGE, fnInput+"/"+listDir[i], objId); } } break; } inMD.findObjects(objIds); size_t nIm = inMD.size(); // Create empty output stack file getImageInfo(inMD, imgInfo); /* Get the flatfield:: We get the FF after the image list because we need the image size to adapt the FF * in case they were already cropped. */ if (!fnFlat.empty()) { std::cout << "Getting flatfield from "+fnFlat << " ..." << std::endl; getFlatfield(fnFlat,IavgFlat); if ( XSIZE(IavgFlat()) != 0 ) { FileName ffName = fnRoot+"_flatfield_avg.xmp"; IavgFlat.write(ffName); fMD.setValue(MDL_IMAGE, ffName, fMD.addObject()); } } createEmptyFile(fnOut, imgInfo.adim.xdim-cropSizeXi-cropSizeXe, imgInfo.adim.ydim-cropSizeYi-cropSizeYe, 1, nIm); // Process images td = new ThreadTaskDistributor(nIm, XMIPP_MAX(1, nIm/30)); tm = new ThreadManager(thrNum, this); std::cerr << "Getting data from " << fnInput << " ...\n"; init_progress_bar(nIm); tm->run(runThread); progress_bar(nIm); // Write Metadata and angles MetaData MDSorted; MDSorted.sort(outMD,MDL_ANGLE_TILT); MDSorted.write("tomo@"+fnRoot + ".xmd"); if ( fMD.size() > 0 ) fMD.write("flatfield@"+fnRoot + ".xmd", MD_APPEND); // We also reference initial and final images at 0 degrees for Mistral tomograms if ( dSource == MISTRAL ) { fMD.clear(); FileName degree0Fn = "NXtomo/instrument/sample/0_degrees_initial_image"; if ( H5File.checkDataset(degree0Fn.c_str())) fMD.setValue(MDL_IMAGE, degree0Fn + "@" + fnInput, fMD.addObject()); degree0Fn = "NXtomo/instrument/sample/0_degrees_final_image"; if ( H5File.checkDataset(degree0Fn.c_str())) fMD.setValue(MDL_IMAGE, degree0Fn + "@" + fnInput, fMD.addObject()); if ( fMD.size() > 0 ) fMD.write("degree0@"+fnRoot + ".xmd", MD_APPEND); } // Write tlt file for IMOD std::ofstream fhTlt; fhTlt.open((fnRoot+".tlt").c_str()); if (!fhTlt) REPORT_ERROR(ERR_IO_NOWRITE,fnRoot+".tlt"); FOR_ALL_OBJECTS_IN_METADATA(MDSorted) { double tilt; MDSorted.getValue(MDL_ANGLE_TILT,tilt,__iter.objId); fhTlt << tilt << std::endl; } fhTlt.close(); delete td; delete tm; }
// Evaluate plane ---------------------------------------------------------- double evaluatePlane(double rot, double tilt, const MultidimArray<double> *V, const MultidimArray<double> *Vmag, double maxFreq, double planeWidth, int direction, MultidimArray<double> *Vdraw=NULL, bool setPos=false, double rotPos=0, double tiltPos=0) { if (rot<0 || rot>360 || tilt<-90 || tilt>90) return 0; Matrix2D<double> E, Einv; Euler_angles2matrix(rot,tilt,0,E); Einv=E.transpose(); if (setPos) { Matrix2D<double> Epos; Euler_angles2matrix(rotPos,tiltPos,0,Epos); double angle=acos(E(2,0)*Epos(2,0)+E(2,1)*Epos(2,1)+E(2,2)*Epos(2,2)); angle=RAD2DEG(angle); if (fabs(angle)<20 || fabs(180-angle)<20) return 0; } size_t N=XMIPP_MAX(XSIZE(*Vmag),YSIZE(*Vmag)/2); N=XMIPP_MAX(N,ZSIZE(*Vmag)/2); double df=0.5/N; Matrix1D<double> freq(3), freqp(3); Matrix1D<int> idx(3); double sumNeg=0, sumPos=0; int Nneg=0, Npos=0; double maxFreq2=maxFreq*maxFreq; int iPlaneWidth=(int)ceil(planeWidth); for (double ix=0; ix<=N; ix++) { XX(freq)=ix*df; double fx2=XX(freq)*XX(freq); if (fx2>maxFreq2) continue; for (double iy=-(int)N; iy<=N; iy++) { YY(freq)=iy*df; double fx2fy2=fx2+YY(freq)*YY(freq); if (fx2fy2>maxFreq2) continue; for (int iz=-iPlaneWidth; iz<=iPlaneWidth; iz++) { if (iz==0 || ix==0 || iy==0) continue; // Frequency in the coordinate system of the plane ZZ(freq)=iz*df; // Frequency in the coordinate system of the volume SPEED_UP_temps012; M3x3_BY_V3x1(freqp,Einv,freq); bool inverted=false; if (XX(freqp)<0) { XX(freqp)=-XX(freqp); YY(freqp)=-YY(freqp); ZZ(freqp)=-ZZ(freqp); inverted=true; } // Get the corresponding index DIGFREQ2FFT_IDX(ZZ(freqp), ZSIZE(*V), ZZ(idx)); DIGFREQ2FFT_IDX(YY(freqp), YSIZE(*V), YY(idx)); DIGFREQ2FFT_IDX(XX(freqp), XSIZE(*V), XX(idx)); if (XX(idx) < STARTINGX(*Vmag) || XX(idx) > FINISHINGX(*Vmag) || YY(idx) < STARTINGY(*Vmag) || YY(idx) > FINISHINGY(*Vmag) || ZZ(idx) < STARTINGZ(*Vmag) || ZZ(idx) > FINISHINGZ(*Vmag)) continue; // Make the corresponding sums bool negativeSum; if (direction==1) negativeSum=iz<0; else negativeSum=iz>0; double val=A3D_ELEM(*Vmag,ZZ(idx),YY(idx),XX(idx)); if ((negativeSum && !inverted) || (!negativeSum && inverted)) // XOR { sumNeg+=val; Nneg++; if (Vdraw!=NULL) (*Vdraw)(idx)=2*direction*val; } else { sumPos+=val; Npos++; if (Vdraw!=NULL) (*Vdraw)(idx)=1.0/2.0*direction*val; } } } } if (fabs(Nneg-Npos)/(0.5*(Nneg+Npos))>0.5) // If there is a difference of more than 50% return 1e38; if (Nneg!=0) sumNeg/=Nneg; else return 1e38; if (Npos!=0) sumPos/=Npos; else return 1e38; return -(sumPos-sumNeg); }
void FourierTransformer::setReal(MultidimArray<double>& input) { bool recomputePlan = false; if (fReal == NULL) { recomputePlan = true; } else if (dataPtr != MULTIDIM_ARRAY(input)) { recomputePlan = true; } else { recomputePlan = !(fReal->sameShape(input)); } fFourier.resize(ZSIZE(input), YSIZE(input), XSIZE(input) / 2 + 1); fReal = &input; if (recomputePlan) { int ndim = 3; if (ZSIZE(input) == 1) { ndim = 2; if (YSIZE(input) == 1) { ndim = 1; } } int* N = new int[ndim]; switch (ndim) { case 1: N[0] = XSIZE(input); break; case 2: N[0] = YSIZE(input); N[1] = XSIZE(input); break; case 3: N[0] = ZSIZE(input); N[1] = YSIZE(input); N[2] = XSIZE(input); break; } // Destroy both forward and backward plans if they already exist destroyPlans(); // Make new plans pthread_mutex_lock(&fftw_plan_mutex); fPlanForward = fftw_plan_dft_r2c(ndim, N, MULTIDIM_ARRAY(*fReal), (fftw_complex*) MULTIDIM_ARRAY(fFourier), FFTW_ESTIMATE); fPlanBackward = fftw_plan_dft_c2r(ndim, N, (fftw_complex*) MULTIDIM_ARRAY(fFourier), MULTIDIM_ARRAY(*fReal), FFTW_ESTIMATE); pthread_mutex_unlock(&fftw_plan_mutex); if (fPlanForward == NULL || fPlanBackward == NULL) { REPORT_ERROR("FFTW plans cannot be created"); } #ifdef DEBUG_PLANS std::cerr << " SETREAL fPlanForward= " << fPlanForward << " fPlanBackward= " << fPlanBackward << " this= " << this << std::endl; #endif delete [] N; dataPtr = MULTIDIM_ARRAY(*fReal); } }
//#define DEBUG void ProgResolutionIBW::run() { V.read(fnVol); //Mask generation Image<double> aux; double bg_mean; MultidimArray<double> Vmask; detectBackground(V(),aux(),0.1,bg_mean); #ifdef DEBUG aux.write("PPPmask_no_ero_03.vol"); #endif //Mask volume erosion to expand the mask boundaries Vmask.initZeros(V()); erode3D(aux(),Vmask, 18,0,2); //Correction of some flaws produced in the edges of the mask volume FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(Vmask) if (k<=4 || i<=4 || j<=4 || k>=ZSIZE(Vmask)-4 || i>=YSIZE(Vmask)-4 || j>=XSIZE(Vmask)-4) DIRECT_A3D_ELEM(Vmask,k,i,j)=1; aux()=Vmask; #ifdef DEBUG aux.write("PPPmask_ero_03.vol"); #endif //Sobel edge detection applied to original volume Image<double> Vedge; computeEdges(V(),Vedge()); #ifdef DEBUG Vedge.write("PPPvolume_sobel_unmask_03.vol"); #endif //Masked volume generation const MultidimArray<double> &mVedge=Vedge(); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mVedge) if (DIRECT_MULTIDIM_ELEM(Vmask,n)==1) DIRECT_MULTIDIM_ELEM(mVedge,n)=0; #ifdef DEBUG Vedge.write("volume_sobel_mask_03.vol"); #endif double minval, maxval, avg, stddev; //Invert the mask to meet computeStats_within_binary_mask requirements FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vmask) if (DIRECT_MULTIDIM_ELEM(Vmask,n)==1) DIRECT_MULTIDIM_ELEM(Vmask,n)=0; else DIRECT_MULTIDIM_ELEM(Vmask,n)=1; //Threshold is 3 times the standard deviation of unmasked pixel values double thresh; computeStats_within_binary_mask(Vmask,mVedge,minval, maxval, avg, stddev); thresh=3*stddev; //Final edge volume generated by setting to 1 positions with values > threshold Image<double> Vaux; Vaux().initZeros(mVedge); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mVedge) if (DIRECT_MULTIDIM_ELEM(mVedge,n)>=thresh) DIRECT_MULTIDIM_ELEM(Vaux(),n)=1; #ifdef DEBUG Vaux.write("volumen_bordes_definitivo_03.vol"); #endif const MultidimArray<double> &mVaux=Vaux(); //Spline coefficient volume from original volume, to allow <1 step sizes MultidimArray<double> Volcoeffs; Volcoeffs.initZeros(V()); produceSplineCoefficients(3,Volcoeffs,V()); //Width parameter volume initialization Image<double> widths; widths().resizeNoCopy(V()); widths().initConstant(1e5); double step=0.25; Matrix1D<double> direction(3); //Calculation of edge width for 10 different directions, if a smaller value is found for a different //direction on a given position the former value is overwritten //Direction (1,0,0) VECTOR_R3(direction,1,0,0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,1,0) VECTOR_R3(direction,0,1,0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,0,1) VECTOR_R3(direction,0,0,1); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,0) VECTOR_R3(direction,(1/sqrt(2)),(1/sqrt(2)),0); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,0,1) VECTOR_R3(direction,(1/sqrt(2)),0,(1/sqrt(2))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (0,1,1) VECTOR_R3(direction,0,(1/sqrt(2)),(1/sqrt(2))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,1) VECTOR_R3(direction,(1/sqrt(3)),(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (-1,1,1) VECTOR_R3(direction,-(1/sqrt(3)),(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,1,-1) VECTOR_R3(direction,(1/sqrt(3)),(1/sqrt(3)),-(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); //Direction (1,-1,1) VECTOR_R3(direction,(1/sqrt(3)),-(1/sqrt(3)),(1/sqrt(3))); edgeWidth(Volcoeffs, mVaux, widths(), direction, step); #ifdef DEBUG std::cout << "width stats: "; widths().printStats(); std::cout << std::endl; widths.write("PPPwidths.vol"); #endif double ibw=calculateIBW(widths()); std::cout << "Resolution ibw= " << ibw << std::endl; if (fnOut!="") widths.write(fnOut); }
/* Run --------------------------------------------------------------------- */ void ProgAngularProjectLibrary::run() { ///////////////////////////// // PreRun for all nodes but not for all works ///////////////////////////// //only rank 0 mysampling.verbose=verbose; show(); //all ranks mysampling.setSampling(sampling); srand ( time(NULL) ); //process the symmetry file //only checks symmetry and set pg_order and pg_group, no memory allocation if (!mysampling.SL.isSymmetryGroup(fn_sym, symmetry, sym_order)) REPORT_ERROR(ERR_VALUE_INCORRECT, (std::string)"Invalid symmetry" + fn_sym); if(perturb_projection_vector!=0) { int my_seed; my_seed=rand(); // set noise deviation and seed mysampling.setNoise(perturb_projection_vector,my_seed); } if(angular_distance_bool!=0) mysampling.setNeighborhoodRadius(angular_distance);//irrelevant //true -> half_sphere mysampling.computeSamplingPoints(false,max_tilt_angle,min_tilt_angle); //only rank 0 //mysampling.createSymFile(fn_sym,symmetry, sym_order); //all nodes mysampling.SL.readSymmetryFile(fn_sym); //store symmetry matrices, this is faster than computing them each time mysampling.fillLRRepository(); //mpi_barrier here //all working nodes must read symmetry file //and experimental docfile if apropiate //symmetry_file = symmetry + ".sym"; //SL.readSymmetryFile(symmetry_file) // We first sample The whole sphere // Then we remove point redundant due to sampling symmetry // use old symmetry, this is geometric does not use L_R mysampling.removeRedundantPoints(symmetry, sym_order); //========================= //====================== //recompute symmetry with neigh symmetry // If uncomment neighbour are not OK. BE CAREFULL #define BREAKSIMMETRY #ifdef BREAKSIMMETRY if (!mysampling.SL.isSymmetryGroup(fn_sym_neigh, symmetry, sym_order)) REPORT_ERROR(ERR_VALUE_INCORRECT, (std::string)"Invalid neig symmetry" + fn_sym_neigh); mysampling.SL.readSymmetryFile(fn_sym_neigh); mysampling.fillLRRepository(); #endif #undef BREAKSIMMETRY //precompute product between symmetry matrices and experimental data if (FnexperimentalImages.size() > 0) mysampling.fillExpDataProjectionDirectionByLR(FnexperimentalImages); //remove points not close to experimental points, only for no symmetric cases if (FnexperimentalImages.size() > 0 && remove_points_far_away_from_experimental_data_bool) { // here we remove points no close to experimental data, neight symmetry must be use mysampling.removePointsFarAwayFromExperimentalData(); } if(compute_closer_sampling_point_bool) { //find sampling point closer to experimental point (only 0) and bool //and save docfile with this information // use neight symmetry mysampling.findClosestSamplingPoint(FnexperimentalImages,output_file_root); } //only rank 0 //write docfile with vectors and angles mysampling.createAsymUnitFile(output_file_root); //all nodes //If there is no reference available exit try { inputVol.read(input_volume); } catch (XmippError XE) { std::cout << XE; exit(0); } inputVol().setXmippOrigin(); Xdim = XSIZE(inputVol()); Ydim = YSIZE(inputVol()); if (compute_neighbors_bool) { // new symmetry mysampling.computeNeighbors(only_winner); mysampling.saveSamplingFile(output_file_root,false); } //release some memory mysampling.exp_data_projection_direction_by_L_R.clear(); unlink(output_file.c_str()); //mpi master should divide doc in chuncks //in this serial program there is a unique chunck //angle information is in //mysampling.no_redundant_sampling_points_vector[i] //Run for all works project_angle_vector(0, mysampling.no_redundant_sampling_points_angles.size()-1,verbose); //only rank 0 create sel file MetaData mySFin, mySFout; FileName fn_temp; mySFin.read(output_file_root+"_angles.doc"); size_t myCounter=0; size_t id; int ref; for (double mypsi=0;mypsi<360;mypsi += psi_sampling) { FOR_ALL_OBJECTS_IN_METADATA(mySFin) { double x,y,z, rot, tilt, psi; mySFin.getValue(MDL_ANGLE_ROT,rot,__iter.objId); mySFin.getValue(MDL_ANGLE_TILT,tilt,__iter.objId); mySFin.getValue(MDL_ANGLE_PSI,psi,__iter.objId); mySFin.getValue(MDL_X,x,__iter.objId); mySFin.getValue(MDL_Y,y,__iter.objId); mySFin.getValue(MDL_Z,z,__iter.objId); mySFin.getValue(MDL_REF,ref,__iter.objId); fn_temp.compose( ++myCounter,output_file); id = mySFout.addObject(); mySFout.setValue(MDL_IMAGE,fn_temp,id); mySFout.setValue(MDL_ENABLED,1,id); mySFout.setValue(MDL_ANGLE_ROT,rot,id); mySFout.setValue(MDL_ANGLE_TILT,tilt,id); mySFout.setValue(MDL_ANGLE_PSI,psi+mypsi,id); mySFout.setValue(MDL_X,x,id); mySFout.setValue(MDL_Y,y,id); mySFout.setValue(MDL_Z,z,id); mySFout.setValue(MDL_SCALE,1.0,id); mySFout.setValue(MDL_REF,ref,id); } } mySFout.setComment("x,y,z refer to the coordinates of the unitary vector at direction given by the euler angles"); mySFout.write(output_file_root+".doc"); unlink((output_file_root+"_angles.doc").c_str()); if (fn_groups!="") createGroupSamplingFiles(); }
void ProgVolumePCA::run() { show(); produce_side_info(); const MultidimArray<int> &imask=mask.imask; size_t Nvoxels=imask.sum(); MultidimArray<float> v; v.initZeros(Nvoxels); // Add all volumes to the analyzer FileName fnVol; FOR_ALL_OBJECTS_IN_METADATA(mdVols) { mdVols.getValue(MDL_IMAGE,fnVol,__iter.objId); V.read(fnVol); // Construct vector const MultidimArray<double> &mV=V(); size_t idx=0; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mV) { if (DIRECT_MULTIDIM_ELEM(imask,n)) DIRECT_MULTIDIM_ELEM(v,idx++)=DIRECT_MULTIDIM_ELEM(mV,n); } analyzer.addVector(v); } // Construct PCA basis analyzer.subtractAvg(); analyzer.learnPCABasis(NPCA,100); // Project onto the PCA basis Matrix2D<double> proj; analyzer.projectOnPCABasis(proj); std::vector<double> dimredProj; dimredProj.resize(NPCA); int i=0; FOR_ALL_OBJECTS_IN_METADATA(mdVols) { memcpy(&dimredProj[0],&MAT_ELEM(proj,i,0),NPCA*sizeof(double)); mdVols.setValue(MDL_DIMRED,dimredProj,__iter.objId); i++; } if (fnVolsOut!="") mdVols.write(fnVolsOut); else mdVols.write(fnVols); // Save the basis const MultidimArray<double> &mV=V(); for (int i=NPCA-1; i>=0; --i) { V().initZeros(); size_t idx=0; const MultidimArray<double> &mPCA=analyzer.PCAbasis[i]; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mV) { if (DIRECT_MULTIDIM_ELEM(imask,n)) DIRECT_MULTIDIM_ELEM(mV,n)=DIRECT_MULTIDIM_ELEM(mPCA,idx++); } if (fnBasis!="") V.write(fnBasis,i+1,true,WRITE_OVERWRITE); } // Generate the PCA volumes if (listOfPercentiles.size()>0 && fnOutStack!="" && fnAvgVol!="") { Image<double> Vavg; if (fnAvgVol!="") Vavg.read(fnAvgVol); else Vavg().initZeros(V()); Matrix1D<double> p; proj.toVector(p); Matrix1D<double> psorted=p.sort(); Image<double> Vpca; Vpca()=Vavg(); createEmptyFile(fnOutStack,(int)XSIZE(Vavg()),(int)YSIZE(Vavg()),(int)ZSIZE(Vavg()),listOfPercentiles.size()); std::cout << "listOfPercentiles.size()=" << listOfPercentiles.size() << std::endl; for (size_t i=0; i<listOfPercentiles.size(); i++) { int idx=(int)round(textToFloat(listOfPercentiles[i].c_str())/100.0*VEC_XSIZE(p)); std::cout << "Percentile " << listOfPercentiles[i] << " -> idx=" << idx << " p(idx)=" << psorted(idx) << std::endl; Vpca()+=psorted(idx)*V(); Vpca.write(fnOutStack,i+1,true,WRITE_REPLACE); } } }