// Apply transformation --------------------------------------------------- void applyTransformation(const MultidimArray<double> &V2, MultidimArray<double> &Vaux, double *p) { Matrix1D<double> r(3); Matrix2D<double> A, Aaux; double greyScale = p[0]; double greyShift = p[1]; double rot = p[2]; double tilt = p[3]; double psi = p[4]; double scale = p[5]; ZZ(r) = p[6]; YY(r) = p[7]; XX(r) = p[8]; Euler_angles2matrix(rot, tilt, psi, A, true); translation3DMatrix(r,Aaux); A = A * Aaux; scale3DMatrix(vectorR3(scale, scale, scale),Aaux); A = A * Aaux; applyGeometry(LINEAR, Vaux, V2, A, IS_NOT_INV, WRAP); if (greyScale!=1 || greyShift!=0) FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Vaux) DIRECT_MULTIDIM_ELEM(Vaux,n)=DIRECT_MULTIDIM_ELEM(Vaux,n)*greyScale+greyShift; }
/* 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; }
TEST( MultidimTest, Copy) { MultidimArray<int> mdtarget,mdsource; mdsource.resize(2,3); DIRECT_MULTIDIM_ELEM(mdsource,0)=1; mdtarget=mdsource; DIRECT_MULTIDIM_ELEM(mdsource,0)=1; EXPECT_EQ(mdtarget,mdsource) << "MultidimArray: copy operator failed"; }
TEST( MultidimTest, CopyFromMatrix2D) { MultidimArray<double> mdTarget; Matrix2D<double> mSource(2,2); mSource(0,0) = 1; mSource(0,1) = 2; mSource(1,0) = 3; mSource(1,1) = 4; mdTarget=mSource; EXPECT_EQ(dMn(mSource, 0),DIRECT_MULTIDIM_ELEM(mdTarget,0)) << "MultidimArray: copy from Matrix2D operator failed"; EXPECT_EQ(dMn(mSource, 1),DIRECT_MULTIDIM_ELEM(mdTarget,1)) << "MultidimArray: copy from Matrix2D operator failed"; EXPECT_EQ(dMn(mSource, 2),DIRECT_MULTIDIM_ELEM(mdTarget,2)) << "MultidimArray: copy from Matrix2D operator failed"; EXPECT_EQ(dMn(mSource, 3),DIRECT_MULTIDIM_ELEM(mdTarget,3)) << "MultidimArray: copy from Matrix2D operator failed"; }
// Transform --------------------------------------------------------------- void FourierTransformer::Transform(int sign) { if (sign == FFTW_FORWARD) { fftw_execute(fPlanForward); // Normalisation of the transform unsigned long int size = 0; if (fReal != NULL) { size = MULTIDIM_SIZE(*fReal); } else if (fComplex != NULL) { size = MULTIDIM_SIZE(*fComplex); } else { REPORT_ERROR("No complex nor real data defined"); } FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(fFourier) DIRECT_MULTIDIM_ELEM(fFourier, n) /= size; } else if (sign == FFTW_BACKWARD) { fftw_execute(fPlanBackward); } }
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)); } } }
// Some image-specific operations void normalise(Image<DOUBLE> &I, int bg_radius, DOUBLE white_dust_stddev, DOUBLE black_dust_stddev, bool do_ramp) { int bg_radius2 = bg_radius * bg_radius; DOUBLE avg, stddev; if (2*bg_radius > XSIZE(I())) REPORT_ERROR("normalise ERROR: 2*bg_radius is larger than image size!"); if (white_dust_stddev > 0. || black_dust_stddev > 0.) { // Calculate initial avg and stddev values calculateBackgroundAvgStddev(I, avg, stddev, bg_radius); // Remove white and black noise if (white_dust_stddev > 0.) removeDust(I, true, white_dust_stddev, avg, stddev); if (black_dust_stddev > 0.) removeDust(I, false, black_dust_stddev, avg, stddev); } if (do_ramp) subtractBackgroundRamp(I, bg_radius); // Calculate avg and stddev (also redo if dust was removed!) calculateBackgroundAvgStddev(I, avg, stddev, bg_radius); if (stddev < 1e-10) { std::cerr << " WARNING! Stddev of image " << I.name() << " is zero! Skipping normalisation..." << std::endl; } else { // Subtract avg and divide by stddev for all pixels FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(I()) DIRECT_MULTIDIM_ELEM(I(), n) = (DIRECT_MULTIDIM_ELEM(I(), n) - avg) / stddev; } }
TEST( MultidimTest, getRealFromComplex) { MultidimArray<std::complex <double> > mSource(2,2); MultidimArray<double> mdTarget; A2D_ELEM(mSource,0,0) = (std::complex<double>(0,0)); A2D_ELEM(mSource,1,0) = (std::complex<double>(1,0)); A2D_ELEM(mSource,0,1) = (std::complex<double>(2,0)); A2D_ELEM(mSource,1,1) = (std::complex<double>(3,0)); mSource.getReal(mdTarget); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 0).real(),DIRECT_MULTIDIM_ELEM(mdTarget,0)); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 1).real(),DIRECT_MULTIDIM_ELEM(mdTarget,1)); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 2).real(),DIRECT_MULTIDIM_ELEM(mdTarget,2)); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 3).real(),DIRECT_MULTIDIM_ELEM(mdTarget,3)); }
void run() { FileName fn_out; FileName fn_ext = fn_in.getExtension(); Image<double> I, label; I.read(fn_in); int object_no; if (ZSIZE(I())==1) object_no=labelImage2D(I(), label()); else object_no=labelImage3D(I(), label()); for (int o = 0; o <= object_no; o++) { I() = label(); MultidimArray<double> &Im=MULTIDIM_ARRAY(I); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(Im) { DIRECT_MULTIDIM_ELEM(Im,n) = (DIRECT_MULTIDIM_ELEM(Im,n) == o); if (invert) DIRECT_MULTIDIM_ELEM(Im,n) = 1 - DIRECT_MULTIDIM_ELEM(Im,n); } double number_elements = I().sum(); if (number_elements > min_size) { fn_out.compose(fn_root, o+1, fn_ext); I.write(fn_out); } if (ZSIZE(I())==1) std::cout << "Image number " << o+1 << " contains " << number_elements << " pixels set to 1\n"; else std::cout << "Volume number " << o+1 << " contains " << number_elements << " voxels set to 1\n"; } }
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); }
TEST( MultidimTest, typeCastComplex) { MultidimArray<std::complex <double> > mdTarget; MultidimArray<double> mSource(2,2); mSource(0,0) = 1; mSource(0,1) = 2; mSource(1,0) = 3; mSource(1,1) = 4; typeCast(mSource,mdTarget); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 0),DIRECT_MULTIDIM_ELEM(mdTarget,0).real()); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 1),DIRECT_MULTIDIM_ELEM(mdTarget,1).real()); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 2),DIRECT_MULTIDIM_ELEM(mdTarget,2).real()); EXPECT_EQ(DIRECT_MULTIDIM_ELEM(mSource, 3),DIRECT_MULTIDIM_ELEM(mdTarget,3).real()); EXPECT_EQ(0,DIRECT_MULTIDIM_ELEM(mdTarget,0).imag()) ; EXPECT_EQ(0,DIRECT_MULTIDIM_ELEM(mdTarget,1).imag()) ; EXPECT_EQ(0,DIRECT_MULTIDIM_ELEM(mdTarget,2).imag()) ; EXPECT_EQ(0,DIRECT_MULTIDIM_ELEM(mdTarget,3).imag()) ; }
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); }
//#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 ProgSortByStatistics::processInputPrepare(MetaData &SF) { PCAMahalanobisAnalyzer tempPcaAnalyzer; tempPcaAnalyzer.clear(); Image<double> img; MultidimArray<double> img2; MultidimArray<int> radial_count; MultidimArray<double> radial_avg; Matrix1D<int> center(2); center.initZeros(); if (verbose>0) std::cout << " Processing training set ..." << std::endl; int nr_imgs = SF.size(); if (verbose>0) init_progress_bar(nr_imgs); int c = XMIPP_MAX(1, nr_imgs / 60); int imgno = 0, imgnoPCA=0; MultidimArray<float> v; MultidimArray<int> distance; int dim; bool thereIsEnable=SF.containsLabel(MDL_ENABLED); bool first=true; FOR_ALL_OBJECTS_IN_METADATA(SF) { if (thereIsEnable) { int enabled; SF.getValue(MDL_ENABLED,enabled,__iter.objId); if (enabled==-1) continue; } img.readApplyGeo(SF,__iter.objId); if (targetXdim!=-1 && targetXdim!=XSIZE(img())) selfScaleToSize(LINEAR,img(),targetXdim,targetXdim,1); MultidimArray<double> &mI=img(); mI.setXmippOrigin(); mI.statisticsAdjust(0,1); // Overall statistics Histogram1D hist; compute_hist(mI,hist,-4,4,31); // Radial profile img2.resizeNoCopy(mI); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(img2) { double val=DIRECT_MULTIDIM_ELEM(mI,n); DIRECT_MULTIDIM_ELEM(img2,n)=val*val; } if (first) { radialAveragePrecomputeDistance(img2, center, distance, dim); first=false; } fastRadialAverage(img2, distance, dim, radial_avg, radial_count); // Build vector v.initZeros(XSIZE(hist)+XSIZE(img2)/2); int idx=0; FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY1D(hist) v(idx++)=(float)DIRECT_A1D_ELEM(hist,i); for (size_t i=0; i<XSIZE(img2)/2; i++) v(idx++)=(float)DIRECT_A1D_ELEM(radial_avg,i); tempPcaAnalyzer.addVector(v); if (imgno % c == 0 && verbose>0) progress_bar(imgno); imgno++; imgnoPCA++; } if (verbose>0) progress_bar(nr_imgs); MultidimArray<double> vavg,vstddev; tempPcaAnalyzer.computeStatistics(vavg,vstddev); tempPcaAnalyzer.evaluateZScore(2,20,false); pcaAnalyzer.insert(pcaAnalyzer.begin(), tempPcaAnalyzer); }
// Transform --------------------------------------------------------------- void FourierTransformer::Transform(int sign) { if (sign == FFTW_FORWARD) { fftw_execute(fPlanForward); if (sign == normSign) { unsigned long int size=0; if(fReal!=NULL) size = MULTIDIM_SIZE(*fReal); else if (fComplex!= NULL) size = MULTIDIM_SIZE(*fComplex); else REPORT_ERROR(ERR_UNCLASSIFIED,"No complex nor real data defined"); double isize=1.0/size; double *ptr=(double*)MULTIDIM_ARRAY(fFourier); size_t nmax=(fFourier.nzyxdim/4)*4; for (size_t n=0; n<nmax; n+=4) { *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; *ptr++ *= isize; } for (size_t n=nmax; n<fFourier.nzyxdim; ++n) { *ptr++ *= isize; *ptr++ *= isize; } } } else if (sign == FFTW_BACKWARD) { fftw_execute(fPlanBackward); if (sign == normSign) { unsigned long int size=0; if(fReal!=NULL) { size = MULTIDIM_SIZE(*fReal); double isize=1.0/size; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(*fReal) DIRECT_MULTIDIM_ELEM(*fReal,n) *= isize; } else if (fComplex!= NULL) { size = MULTIDIM_SIZE(*fComplex); double isize=1.0/size; double *ptr=(double*)MULTIDIM_ARRAY(*fComplex); FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(*fComplex) { *ptr++ *= isize; *ptr++ *= isize; } }
// Split several histograms within the indexes l0 and lF so that // the entropy after division is maximized int splitHistogramsUsingEntropy(const std::vector<Histogram1D> &hist, size_t l0, size_t lF) { // Number of classes int K = hist.size(); // Set everything outside l0 and lF to zero, and make it a PDF std::vector<Histogram1D> histNorm; for (int k = 0; k < K; k++) { Histogram1D histaux = hist[k]; for (size_t l = 0; l < XSIZE(histaux); l++) if (l < l0 || l > lF) DIRECT_A1D_ELEM(histaux,l) = 0; histaux *= 1.0/histaux.sum(); histNorm.push_back(histaux); } // Compute for each class the probability of being l<=l0 and l>l0 MultidimArray<double> p(K, 2); for (int k = 0; k < K; k++) { const Histogram1D& histogram=histNorm[k]; DIRECT_A2D_ELEM(p,k, 0) = DIRECT_A1D_ELEM(histogram,l0); DIRECT_A2D_ELEM(p,k, 1) = 0; for (size_t l = l0 + 1; l <= lF; l++) DIRECT_A2D_ELEM(p,k, 1) += DIRECT_A1D_ELEM(histogram,l); } // Compute the splitting l giving maximum entropy double maxEntropy = 0; int lmaxEntropy = -1; size_t l = l0; while (l < lF) { // Compute the entropy of the classes if we split by l double entropy = 0; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(p) { double aux=DIRECT_MULTIDIM_ELEM(p,n); if (aux != 0) entropy -= aux * log10(aux); } #ifdef DEBUG_SPLITTING_USING_ENTROPY std::cout << "Splitting at " << l << " entropy=" << entropy << std::endl; #endif // Check if this is the maximum if (entropy > maxEntropy) { maxEntropy = entropy; lmaxEntropy = l; } // Move to next split point ++l; // Update probabilities of being l<=l0 and l>l0 for (int k = 0; k < K; k++) { const Histogram1D& histogram=histNorm[k]; double aux=DIRECT_A1D_ELEM(histogram,l); DIRECT_A2D_ELEM(p,k, 0) += aux; DIRECT_A2D_ELEM(p,k, 1) -= aux; } } #ifdef DEBUG_SPLITTING_USING_ENTROPY std::cout << "Finally in l=[" << l0 << "," << lF << " Max Entropy:" << maxEntropy << " lmax=" << lmaxEntropy << std::endl; #endif // If the point giving the maximum entropy is too much on the extreme, // substitute it by the middle point if (lmaxEntropy<=2 || lmaxEntropy>=(int)lF-2) lmaxEntropy = (int)ceil((lF + l0)/2.0); return lmaxEntropy; }
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); } } }