void symmetriseMap(MultidimArray<DOUBLE> &img, FileName &fn_sym, bool do_wrap) { if (img.getDim() != 3) REPORT_ERROR("symmetriseMap ERROR: symmetriseMap can only be run on 3D maps!"); img.setXmippOrigin(); SymList SL; SL.read_sym_file(fn_sym); Matrix2D<DOUBLE> L(4, 4), R(4, 4); // A matrix from the list MultidimArray<DOUBLE> sum, aux; sum = img; aux.resize(img); for (int isym = 0; isym < SL.SymsNo(); isym++) { SL.get_matrices(isym, L, R); applyGeometry(img, aux, R, IS_INV, do_wrap); sum += aux; } // Overwrite the input img = sum / (SL.SymsNo() + 1); }
/* Constructor */ PyObject * FourierProjector_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { FourierProjectorObject *self = (FourierProjectorObject*) type->tp_alloc(type, 0); XMIPP_TRY if (self != NULL) { PyObject *image = NULL; double padding_factor, max_freq, spline_degree; if (PyArg_ParseTuple(args, "O|ddd", &image, &padding_factor, &max_freq, &spline_degree)) { Image_Value(image).getDimensions(self->dims); MultidimArray<double> *pdata; Image_Value(image).data->getMultidimArrayPointer(pdata); pdata->setXmippOrigin(); self->fourier_projector = new FourierProjector(*(pdata), padding_factor, max_freq, spline_degree); } } XMIPP_CATCH return (PyObject *) self; }
TEST_F( FftwTest, directFourierTransformComplex) { MultidimArray< std::complex< double > > FFT1, complxDouble; FourierTransformer transformer1; typeCast(mulDouble, complxDouble); transformer1.FourierTransform(complxDouble, FFT1, false); transformer1.inverseFourierTransform(); transformer1.inverseFourierTransform(); MultidimArray<std::complex<double> > auxFFT; auxFFT.resize(3,3); DIRECT_A2D_ELEM(auxFFT,0,0) = std::complex<double>(2.77778,0); DIRECT_A2D_ELEM(auxFFT,0,1) = std::complex<double>(-0.0555556,0.096225); DIRECT_A2D_ELEM(auxFFT,0,2) = std::complex<double>(-0.0555556,-0.096225); DIRECT_A2D_ELEM(auxFFT,1,0) = std::complex<double>(-0.388889,0.673575) ; DIRECT_A2D_ELEM(auxFFT,1,1) = std::complex<double>(-0.388889,-0.096225); DIRECT_A2D_ELEM(auxFFT,1,2) = std::complex<double>(-0.0555556,-0.288675); DIRECT_A2D_ELEM(auxFFT,2,0) = std::complex<double>(-0.388889,-0.673575) ; DIRECT_A2D_ELEM(auxFFT,2,1) = std::complex<double>(-0.0555556,0.288675) ; DIRECT_A2D_ELEM(auxFFT,2,2) = std::complex<double>(-0.388889,0.096225) ; EXPECT_EQ(FFT1,auxFFT); transformer1.cleanup(); }
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 Steerable::generate3DFilter(MultidimArray<double>& h3D, std::vector< MultidimArray<double> > &hx1, std::vector< MultidimArray<double> > &hy1, std::vector< MultidimArray<double> > &hz1) { h3D.initZeros(XSIZE(hz1[0]),XSIZE(hy1[0]),XSIZE(hx1[0])); h3D.setXmippOrigin(); FOR_ALL_ELEMENTS_IN_ARRAY3D(h3D) for (int n=0; n<6; n++) h3D(k,i,j)+=(hz1[n](k)*hy1[n](i)*hx1[n](j)); }
// MORE INFO HERE: http://code.google.com/p/googletest/wiki/AdvancedGuide // Modify this test so it uses Fixures as test_image and test_metadata TEST( MultidimTest, Size) { MultidimArray<int> md; md.resize(2,3); size_t x,y,z, n; md.getDimensions(x,y,z,n); EXPECT_EQ((size_t)1, n) << "MultidimArray: wrong n size"; EXPECT_EQ((size_t)1, z) << "MultidimArray: wrong y size"; EXPECT_EQ((size_t)2, y) << "MultidimArray: wrong z size"; EXPECT_EQ((size_t)3, x) << "MultidimArray: wrong x size"; }
void getSpectrum(MultidimArray<double>& Min, MultidimArray<double>& spectrum, int spectrum_type) { MultidimArray<Complex > Faux; int xsize = XSIZE(Min); Matrix1D<double> f(3); MultidimArray<double> count(xsize); FourierTransformer transformer; spectrum.initZeros(xsize); count.initZeros(); transformer.FourierTransform(Min, Faux, false); FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux) { long int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp)); if (spectrum_type == AMPLITUDE_SPECTRUM) { spectrum(idx) += abs(dAkij(Faux, k, i, j)); } else { spectrum(idx) += norm(dAkij(Faux, k, i, j)); } count(idx) += 1.; } for (long int i = 0; i < xsize; i++) if (count(i) > 0.) { spectrum(i) /= count(i); } }
// Computes the average of a number of frames in movies void computeAvg(const FileName &movieFile, int begin, int end, MultidimArray<double> &avgImg) { ImageGeneric movieStack; MultidimArray<double> frameImage, shiftedFrame; Matrix1D<double> shiftMatrix(2); int N=end-begin+1; for (size_t i=begin;i<=end;i++) { movieStack.readMapped(movieFile,i); movieStack().getImage(frameImage); if (i==begin) avgImg.initZeros(YSIZE(frameImage), XSIZE(frameImage)); if (darkImageCorr) frameImage-=darkImage; if (gainImageCorr) frameImage/=gainImage; if (globalShiftCorr) { XX(shiftMatrix)=XX(shiftVector[i-1]); YY(shiftMatrix)=YY(shiftVector[i-1]); translate(LINEAR, shiftedFrame, frameImage, shiftMatrix, WRAP); avgImg+=shiftedFrame; } else avgImg+=frameImage; } avgImg/=double(N); frameImage.clear(); movieStack.clear(); }
void Projector::griddingCorrect(MultidimArray<DOUBLE> &vol_in) { // Correct real-space map by dividing it by the Fourier transform of the interpolator(s) vol_in.setXmippOrigin(); FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_in) { DOUBLE r = sqrt((DOUBLE)(k*k+i*i+j*j)); // if r==0: do nothing (i.e. divide by 1) if (r > 0.) { DOUBLE rval = r / (ori_size * padding_factor); DOUBLE sinc = sin(PI * rval) / ( PI * rval); //DOUBLE ftblob = blob_Fourier_val(rval, blob) / blob_Fourier_val(0., blob); // Interpolation (goes with "interpolator") to go from arbitrary to fine grid if (interpolator==NEAREST_NEIGHBOUR && r_min_nn == 0) { // NN interpolation is convolution with a rectangular pulse, which FT is a sinc function A3D_ELEM(vol_in, k, i, j) /= sinc; } else if (interpolator==TRILINEAR || (interpolator==NEAREST_NEIGHBOUR && r_min_nn > 0) ) { // trilinear interpolation is convolution with a triangular pulse, which FT is a sinc^2 function A3D_ELEM(vol_in, k, i, j) /= sinc * sinc; } else REPORT_ERROR("BUG Projector::griddingCorrect: unrecognised interpolator scheme."); //#define DEBUG_GRIDDING_CORRECT #ifdef DEBUG_GRIDDING_CORRECT if (k==0 && i==0 && j > 0) std::cerr << " j= " << j << " sinc= " << sinc << std::endl; #endif } } }
// Converts an OpenCV matrix to XMIPP MultidimArray void opencv2Xmipp(const cv::Mat &opencvMat, MultidimArray<double> &xmippArray) { int h = opencvMat.rows; int w = opencvMat.cols; xmippArray.initZeros(h, w); FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(xmippArray) DIRECT_A2D_ELEM(xmippArray,i,j) = opencvMat.at<float>(i,j); }
/* Normalizations ---------------------------------------------------------- */ void normalize_OldXmipp(MultidimArray<double> &I) { double mean,std; I.computeAvgStdev(mean,std); double istd=1.0/std; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(I) DIRECT_MULTIDIM_ELEM(I,n)=(DIRECT_MULTIDIM_ELEM(I,n)-mean)*istd; }
void resizeMap(MultidimArray<double >& img, int newsize) { FourierTransformer transformer; MultidimArray<Complex > FT, FT2; transformer.FourierTransform(img, FT, false); windowFourierTransform(FT, FT2, newsize); if (img.getDim() == 2) { img.resize(newsize, newsize); } else if (img.getDim() == 3) { img.resize(newsize, newsize, newsize); } transformer.inverseFourierTransform(FT2, img); }
void normalize_Near_OldXmipp(MultidimArray<double> &I, const MultidimArray<int> &bg_mask) { double avg=0., stddev, min, max; double avgbg, stddevbg, minbg, maxbg; I.computeStats(avg, stddev, min, max); computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg, stddevbg); I -= avg; I /= stddevbg; }
/* 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; } }
/* Do inference ------------------------------------------------------------ */ int EnsembleNaiveBayes::doInference(const Matrix1D<double> &newFeatures, double &cost, MultidimArray<int> &votes, Matrix1D<double> &classesProbs, Matrix1D<double> &allCosts) { int nmax=ensemble.size(); MultidimArray<double> minCost, maxCost; votes.initZeros(K); minCost.initZeros(K); minCost.initConstant(1); maxCost.initZeros(K); maxCost.initConstant(1); double bestMinCost=0; int bestClass=0; MultidimArray<double> newFeaturesn; for (int n=0; n<nmax; n++) { double costn; newFeaturesn.initZeros(XSIZE(ensembleFeatures[n])); FOR_ALL_ELEMENTS_IN_ARRAY1D(newFeaturesn) newFeaturesn(i)=newFeatures(ensembleFeatures[n](i)); int k=ensemble[n]->doInference(newFeaturesn, costn, classesProbs, allCosts); votes(k)++; if (minCost(k)>0 || minCost(k)>costn) minCost(k)=costn; if (maxCost(k)>0 || maxCost(k)<costn) maxCost(k)=costn; if (minCost(k)<bestMinCost) { bestMinCost=minCost(k); bestClass=k; } } if (judgeCombination[bestClass]=='m') cost=minCost(bestClass); else if (judgeCombination[bestClass]=='M') cost=maxCost(bestClass); else cost=minCost(bestClass); return bestClass; }
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); }
// Fourier ring correlation ----------------------------------------------- // from precalculated Fourier Transforms, and without sampling rate etc. void getFSC(MultidimArray< Complex >& FT1, MultidimArray< Complex >& FT2, MultidimArray< double >& fsc) { if (!FT1.sameShape(FT2)) { REPORT_ERROR("fourierShellCorrelation ERROR: MultidimArrays have different shapes!"); } MultidimArray< int > radial_count(XSIZE(FT1)); MultidimArray<double> num, den1, den2; Matrix1D<double> f(3); num.initZeros(radial_count); den1.initZeros(radial_count); den2.initZeros(radial_count); fsc.initZeros(radial_count); FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(FT1) { int idx = ROUND(sqrt(kp * kp + ip * ip + jp * jp)); if (idx >= XSIZE(FT1)) { continue; } Complex z1 = DIRECT_A3D_ELEM(FT1, k, i, j); Complex z2 = DIRECT_A3D_ELEM(FT2, k, i, j); double absz1 = abs(z1); double absz2 = abs(z2); num(idx) += (conj(z1) * z2).real; den1(idx) += absz1 * absz1; den2(idx) += absz2 * absz2; radial_count(idx)++; } FOR_ALL_ELEMENTS_IN_ARRAY1D(fsc) { fsc(i) = num(i) / sqrt(den1(i) * den2(i)); } }
void MlModel::initialise() { // Auxiliary vector with relevant size in Fourier space MultidimArray<double > aux; aux.initZeros(ori_size / 2 + 1); // Now resize all relevant vectors Iref.resize(nr_classes); pdf_class.resize(nr_classes, 1. / (double)nr_classes); pdf_direction.resize(nr_classes); group_names.resize(nr_groups, ""); sigma2_noise.resize(nr_groups, aux); nr_particles_group.resize(nr_groups); tau2_class.resize(nr_classes, aux); fsc_halves_class.resize(nr_classes, aux); sigma2_class.resize(nr_classes, aux); data_vs_prior_class.resize(nr_classes, aux); // TODO handle these two correctly. bfactor_correction.resize(nr_groups, 0.); scale_correction.resize(nr_groups, 1.); acc_rot.resize(nr_classes, 0); acc_trans.resize(nr_classes, 0); if (ref_dim == 2) { Matrix1D<double> empty(2); prior_offset_class.resize(nr_classes, empty); } // These arrays will be resized when they are filled orientability_contrib.resize(nr_classes); Projector ref(ori_size, interpolator, padding_factor, r_min_nn); PPref.clear(); // Now fill the entire vector with instances of "ref" PPref.resize(nr_classes, ref); }
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 run() { // Get angles ============================================================== MetaData angles; angles.read(fnIn); size_t AngleNo = angles.size(); if (AngleNo == 0 || !angles.containsLabel(MDL_ANGLE_ROT)) REPORT_ERROR(ERR_MD_BADLABEL, "Input file doesn't contain angular information"); double maxWeight = -99.e99; MultidimArray<double> weight; weight.initZeros(AngleNo); if (angles.containsLabel(MDL_WEIGHT)) { // Find maximum weight int i=0; FOR_ALL_OBJECTS_IN_METADATA(angles) { double w; angles.getValue(MDL_WEIGHT,w,__iter.objId); DIRECT_A1D_ELEM(weight,i++)=w; maxWeight=XMIPP_MAX(w,maxWeight); } }
/* Do inference for class ------------------------------------------------- */ int EnsembleNaiveBayes::doInferenceForClass(int classNumber, const Matrix1D<double> &newFeatures, double &cost, Matrix1D<double> &classesProbs, Matrix1D<double> &allCosts) { int nmax=ensemble.size(); double minCost=1, maxCost=1; int votes=0; MultidimArray<double> newFeaturesn; for (int n=0; n<nmax; n++) { double costn; const MultidimArray<int> &ensembleFeatures_n=ensembleFeatures[n]; newFeaturesn.resizeNoCopy(XSIZE(ensembleFeatures_n)); FOR_ALL_ELEMENTS_IN_ARRAY1D(newFeaturesn) { int idx=A1D_ELEM(ensembleFeatures_n,i); A1D_ELEM(newFeaturesn,i)=VEC_ELEM(newFeatures,idx); } int k=ensemble[n]->doInference(newFeaturesn, costn, classesProbs, allCosts); if (k==classNumber) { votes++; if (minCost>0 || minCost>costn) minCost=costn; if (maxCost>0 || maxCost<costn) maxCost=costn; } } if (judgeCombination[classNumber]=='m') cost=minCost; else if (judgeCombination[classNumber]=='M') cost=maxCost; else cost=minCost; return votes; }
/** Kullback-Leibner divergence */ double getKullbackLeibnerDivergence(MultidimArray<Complex >& Fimg, MultidimArray<Complex >& Fref, MultidimArray<double>& sigma2, MultidimArray<double>& p_i, MultidimArray<double>& q_i, int highshell, int lowshell) { // First check dimensions are OK if (!Fimg.sameShape(Fref)) { REPORT_ERROR("getKullbackLeibnerDivergence ERROR: Fimg and Fref are not of the same shape."); } if (highshell < 0) { highshell = XSIZE(Fimg) - 1; } if (lowshell < 0) { lowshell = 0; } if (highshell > XSIZE(sigma2)) { REPORT_ERROR("getKullbackLeibnerDivergence ERROR: highshell is larger than size of sigma2 array."); } if (highshell < lowshell) { REPORT_ERROR("getKullbackLeibnerDivergence ERROR: highshell is smaller than lowshell."); } // Initialize the histogram MultidimArray<int> histogram; int histogram_size = 101; int histogram_origin = histogram_size / 2; double sigma_max = 10.; double histogram_factor = histogram_origin / sigma_max; histogram.initZeros(histogram_size); // This way this will work in both 2D and 3D FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Fimg) { int ires = ROUND(sqrt(kp * kp + ip * ip + jp * jp)); if (ires >= lowshell && ires <= highshell) { // Use FT of masked image for noise estimation! double diff_real = (DIRECT_A3D_ELEM(Fref, k, i, j)).real - (DIRECT_A3D_ELEM(Fimg, k, i, j)).real; double diff_imag = (DIRECT_A3D_ELEM(Fref, k, i, j)).imag - (DIRECT_A3D_ELEM(Fimg, k, i, j)).imag; double sigma = sqrt(DIRECT_A1D_ELEM(sigma2, ires)); // Divide by standard deviation to normalise all the difference diff_real /= sigma; diff_imag /= sigma; // Histogram runs from -10 sigma to +10 sigma diff_real += sigma_max; diff_imag += sigma_max; // Make histogram on-the-fly; // Real part int ihis = ROUND(diff_real * histogram_factor); if (ihis < 0) { ihis = 0; } else if (ihis >= histogram_size) { ihis = histogram_size - 1; } histogram(ihis)++; // Imaginary part ihis = ROUND(diff_imag * histogram_factor); if (ihis < 0) { ihis = 0; } else if (ihis > histogram_size) { ihis = histogram_size; } histogram(ihis)++; } } // Normalise the histogram and the discretised analytical Gaussian double norm = (double)histogram.sum(); double gaussnorm = 0.; for (int i = 0; i < histogram_size; i++) { double x = (double)i / histogram_factor; gaussnorm += gaussian1D(x - sigma_max, 1. , 0.); } // Now calculate the actual Kullback-Leibner divergence double kl_divergence = 0.; p_i.resize(histogram_size); q_i.resize(histogram_size); for (int i = 0; i < histogram_size; i++) { // Data distribution p_i(i) = (double)histogram(i) / norm; // Theoretical distribution double x = (double)i / histogram_factor; q_i(i) = gaussian1D(x - sigma_max, 1. , 0.) / gaussnorm; if (p_i(i) > 0.) { kl_divergence += p_i(i) * log(p_i(i) / q_i(i)); } } kl_divergence /= (double)histogram_size; return kl_divergence; }
//#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); }
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(); }
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); } }
//#define DEBUG void normalize_tomography(MultidimArray<double> &I, double tilt, double &mui, double &sigmai, bool tiltMask, bool tomography0, double mu0, double sigma0) { // Tilt series are always 2D I.checkDimension(2); const int L=2; // Build a mask using the tilt angle I.setXmippOrigin(); MultidimArray<int> mask; mask.initZeros(I); int Xdimtilt=(int)XMIPP_MIN(FLOOR(0.5*(XSIZE(I)*cos(DEG2RAD(tilt)))), 0.5*(XSIZE(I)-(2*L+1))); int N=0; for (int i=STARTINGY(I); i<=FINISHINGY(I); i++) for (int j=-Xdimtilt; j<=Xdimtilt;j++) { A2D_ELEM(mask,i,j)=1; N++; } // Estimate the local variance MultidimArray<double> localVariance; localVariance.initZeros(I); double meanVariance=0; FOR_ALL_ELEMENTS_IN_ARRAY2D(I) { // Center a mask of size 5x5 and estimate the variance within the mask double meanPiece=0, variancePiece=0; double Npiece=0; for (int ii=i-L; ii<=i+L; ii++) { if (INSIDEY(I,ii)) for (int jj=j-L; jj<=j+L; jj++) { if (INSIDEX(I,jj)) { double pixval=A2D_ELEM(I,ii,jj); meanPiece+=pixval; variancePiece+=pixval*pixval; ++Npiece; } } } meanPiece/=Npiece; variancePiece=variancePiece/(Npiece-1)- Npiece/(Npiece-1)*meanPiece*meanPiece; A2D_ELEM(localVariance,i,j)=variancePiece; meanVariance+=variancePiece; } meanVariance*=1.0/N; // Test the hypothesis that the variance in this piece is // the same as the variance in the whole image double iFu=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.975); double iFl=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.025); double iMeanVariance=1.0/meanVariance; FOR_ALL_ELEMENTS_IN_ARRAY2D(localVariance) { if (A2D_ELEM(localVariance,i,j)==0) A2D_ELEM(mask,i,j)=-2; if (A2D_ELEM(mask,i,j)==1) { double ratio=A2D_ELEM(localVariance,i,j)*iMeanVariance; double thl=ratio*iFu; double thu=ratio*iFl; if (thl>1 || thu<1) A2D_ELEM(mask,i,j)=-1; } } #ifdef DEBUG Image<double> save; save()=I; save.write("PPP.xmp"); save()=localVariance; save.write("PPPLocalVariance.xmp"); Image<int> savemask; savemask()=mask; savemask.write("PPPmask.xmp"); #endif // Compute the statistics again in the reduced mask double avg, stddev, min, max; computeStats_within_binary_mask(mask, I, min, max, avg, stddev); double cosTilt=cos(DEG2RAD(tilt)); double iCosTilt=1.0/cosTilt; if (tomography0) { double iadjustedStddev=1.0/(sigma0*cosTilt); FOR_ALL_ELEMENTS_IN_ARRAY2D(I) switch (A2D_ELEM(mask,i,j)) { case -2: A2D_ELEM(I,i,j)=0; break; case 0: if (tiltMask) A2D_ELEM(I,i,j)=0; else A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev; break; case -1: case 1: A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev; break; } } else {
// Fill data array with oversampled Fourier transform, and calculate its power spectrum void Projector::computeFourierTransformMap(MultidimArray<DOUBLE> &vol_in, MultidimArray<DOUBLE> &power_spectrum, int current_size, int nr_threads, bool do_gridding) { MultidimArray<DOUBLE> Mpad; MultidimArray<Complex > Faux; FourierTransformer transformer; // DEBUGGING: multi-threaded FFTWs are giving me a headache? // For a long while: switch them off! //transformer.setThreadsNumber(nr_threads); DOUBLE normfft; // Size of padded real-space volume int padoridim = padding_factor * ori_size; // Initialize data array of the oversampled transform ref_dim = vol_in.getDim(); // Make Mpad switch (ref_dim) { case 2: Mpad.initZeros(padoridim, padoridim); normfft = (DOUBLE)(padding_factor * padding_factor); break; case 3: Mpad.initZeros(padoridim, padoridim, padoridim); if (data_dim ==3) normfft = (DOUBLE)(padding_factor * padding_factor * padding_factor); else normfft = (DOUBLE)(padding_factor * padding_factor * padding_factor * ori_size); break; default: REPORT_ERROR("Projector::computeFourierTransformMap%%ERROR: Dimension of the data array should be 2 or 3"); } // First do a gridding pre-correction on the real-space map: // Divide by the inverse Fourier transform of the interpolator in Fourier-space // 10feb11: at least in 2D case, this seems to be the wrong thing to do!!! // TODO: check what is best for subtomo! if (do_gridding)// && data_dim != 3) griddingCorrect(vol_in); // Pad translated map with zeros vol_in.setXmippOrigin(); Mpad.setXmippOrigin(); FOR_ALL_ELEMENTS_IN_ARRAY3D(vol_in) // This will also work for 2D A3D_ELEM(Mpad, k, i, j) = A3D_ELEM(vol_in, k, i, j); // Translate padded map to put origin of FT in the center CenterFFT(Mpad, true); // Calculate the oversampled Fourier transform transformer.FourierTransform(Mpad, Faux, false); // Free memory: Mpad no longer needed Mpad.clear(); // Resize data array to the right size and initialise to zero initZeros(current_size); // Fill data only for those points with distance to origin less than max_r // (other points will be zero because of initZeros() call above // Also calculate radial power spectrum power_spectrum.initZeros(ori_size / 2 + 1); MultidimArray<DOUBLE> counter(power_spectrum); counter.initZeros(); int max_r2 = r_max * r_max * padding_factor * padding_factor; FOR_ALL_ELEMENTS_IN_FFTW_TRANSFORM(Faux) // This will also work for 2D { int r2 = kp*kp + ip*ip + jp*jp; // The Fourier Transforms are all "normalised" for 2D transforms of size = ori_size x ori_size if (r2 <= max_r2) { // Set data array A3D_ELEM(data, kp, ip, jp) = DIRECT_A3D_ELEM(Faux, k, i, j) * normfft; // Calculate power spectrum int ires = ROUND( sqrt((DOUBLE)r2) / padding_factor ); // Factor two because of two-dimensionality of the complex plane DIRECT_A1D_ELEM(power_spectrum, ires) += norm(A3D_ELEM(data, kp, ip, jp)) / 2.; DIRECT_A1D_ELEM(counter, ires) += 1.; } } // Calculate radial average of power spectrum FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(power_spectrum) { if (DIRECT_A1D_ELEM(counter, i) < 1.) DIRECT_A1D_ELEM(power_spectrum, i) = 0.; else DIRECT_A1D_ELEM(power_spectrum, i) /= DIRECT_A1D_ELEM(counter, i); } transformer.cleanup(); }
bool checkImageCorners(const FileName &name) { const int windowSize=11; const int windowSize_2=windowSize/2; const double Flower=0.4871; // MATLAB: N=11*11-1; finv(0.00005,N,N) // const double Fupper=2.0530; // MATLAB: N=11*11-1; finv(0.99995,N,N) ImageGeneric I; I.readMapped(name); size_t Xdim, Ydim, Zdim; I.getDimensions(Xdim,Ydim,Zdim); if (Zdim>1) return true; if (Xdim<=2*windowSize || Ydim<=2*windowSize) return true; MultidimArray<double> window; size_t i=Ydim/2; size_t j=Xdim/2; I().window(window,0,0,i-windowSize_2,j-windowSize_2,0,0,i+windowSize_2,j+windowSize_2); double stddev0=window.computeStddev(); double var0=stddev0*stddev0; i=windowSize_2; j=windowSize_2; I().window(window,0,0,i-windowSize_2,j-windowSize_2,0,0,i+windowSize_2,j+windowSize_2); double stddev1=window.computeStddev(); double var1=stddev1*stddev1; double F=var1/var0; if (F<Flower)//|| F>Fupper) return false; i=Ydim-1-windowSize_2; j=windowSize_2; I().window(window,0,0,i-windowSize_2,j-windowSize_2,0,0,i+windowSize_2,j+windowSize_2); stddev1=window.computeStddev(); var1=stddev1*stddev1; F=var1/var0; if (F<Flower)//|| F>Fupper) return false; i=windowSize_2; j=Xdim-1-windowSize_2; I().window(window,0,0,i-windowSize_2,j-windowSize_2,0,0,i+windowSize_2,j+windowSize_2); stddev1=window.computeStddev(); var1=stddev1*stddev1; F=var1/var0; if (F<Flower)//|| F>Fupper) return false; i=Ydim-1-windowSize_2; j=Xdim-1-windowSize_2; I().window(window,0,0,i-windowSize_2,j-windowSize_2,0,0,i+windowSize_2,j+windowSize_2); stddev1=window.computeStddev(); var1=stddev1*stddev1; F=var1/var0; if (F<Flower)//|| F>Fupper) return false; return true; }
// 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 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); }