void ParticleSorterMpi::run() { int total_nr_images = MDin.numberOfObjects(); features.resize(total_nr_images, NR_FEATURES); // Each node does part of the work long int my_first_image, my_last_image, my_nr_images; divide_equally(total_nr_images, node->size, node->rank, my_first_image, my_last_image); my_nr_images = my_last_image - my_first_image + 1; int barstep; if (verb > 0) { std::cout << "Calculating sorting features for all input particles..." << std::endl; init_progress_bar(my_nr_images); barstep = XMIPP_MAX(1, my_nr_images/ 60); } long int ipart = 0; FOR_ALL_OBJECTS_IN_METADATA_TABLE(MDin) { if (ipart >= my_first_image && ipart <= my_last_image) { if (verb > 0 && ipart % barstep == 0) progress_bar(ipart); calculateFeaturesOneParticle(ipart); } ipart++; } if (verb > 0) progress_bar(my_nr_images); // Combine results from all nodes MultidimArray<double> allnodes_features; allnodes_features.resize(features); MPI_Allreduce(MULTIDIM_ARRAY(features), MULTIDIM_ARRAY(allnodes_features), MULTIDIM_SIZE(features), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); features = allnodes_features; // Only the master writes out files if (verb > 0) { normaliseFeatures(); writeFeatures(); } }
/* projectVolumeDouble */ PyObject * Image_projectVolumeDouble(PyObject *obj, PyObject *args, PyObject *kwargs) { ImageObject *self = (ImageObject*) obj; double rot, tilt, psi; if (PyArg_ParseTuple(args, "ddd", &rot,&tilt,&psi)) { try { Projection P; MultidimArray<double> * pVolume; self->image->data->getMultidimArrayPointer(pVolume); ArrayDim aDim; pVolume->getDimensions(aDim); pVolume->setXmippOrigin(); projectVolume(*pVolume, P, aDim.xdim, aDim.ydim,rot, tilt, psi); ImageObject * result = PyObject_New(ImageObject, &ImageType); Image <double> I; result->image = new ImageGeneric(); result->image->setDatatype(DT_Double); result->image->data->setImage(MULTIDIM_ARRAY(P)); return (PyObject *)result; } catch (XmippError &xe) { PyErr_SetString(PyXmippError, xe.msg.c_str()); } } return NULL; }//function Image_projectVolumeDouble
// Produce side info ------------------------------------------------------- void ProgDetectMissingWedge::produceSideInfo() { V.read(fn_vol); FourierTransformer transformer; MultidimArray< std::complex<double> > Vfft; transformer.FourierTransform(MULTIDIM_ARRAY(V),Vfft,false); Vmag = new MultidimArray<double>(); Vmag->resize(Vfft); FOR_ALL_ELEMENTS_IN_ARRAY3D(*Vmag) (*Vmag)(k,i,j)=20*log10(abs(Vfft(k,i,j))); }
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 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); } }
// Run --------------------------------------------------------------------- void ProgDetectMissingWedge::run() { produceSideInfo(); FileName fn_root=V.name().withoutExtension(); MultidimArray<double> * mdaV = &MULTIDIM_ARRAY(V); // Detect one of the planes lookForPlane(mdaV, Vmag, maxFreq, planeWidth, 1, rotPos, tiltPos); Image<double> * Vdraw = new Image<double>(); if (saveMarks) { (*Vdraw)()=(*Vmag); evaluatePlane(rotPos, tiltPos, mdaV, Vmag, maxFreq, planeWidth, 1, &(*Vdraw)()); } // Detect the other plane lookForPlane(mdaV, Vmag, maxFreq, planeWidth, -1, rotNeg, tiltNeg, true, rotPos, tiltPos); if (saveMarks) { evaluatePlane(rotNeg, tiltNeg, mdaV, Vmag, maxFreq, planeWidth, -1, &(*Vdraw)()); Vdraw->write(fn_root+"_marks.vol"); } if (saveMask) { Vdraw->clear(); drawWedge(rotPos, tiltPos, rotNeg, tiltNeg, mdaV, Vmag, &(*Vdraw)()); Vdraw->write(fn_root+"_mask.vol"); } std::cout << "Plane1: " << rotPos << " " << tiltPos << std::endl; std::cout << "Plane2: " << rotNeg << " " << tiltNeg << std::endl; delete Vdraw; delete Vmag; }
PyObject * FourierProjector_projectVolume(PyObject * obj, PyObject *args, PyObject *kwargs) { FourierProjectorObject *self = (FourierProjectorObject*) obj; double rot, tilt, psi; PyObject *projection_image = NULL; if (self != NULL && PyArg_ParseTuple(args, "O|ddd", &projection_image, &rot, &tilt, &psi)) { try { Projection P; projectVolume(FourierProjector_Value(self), P, self->dims.xdim, self->dims.ydim, rot, tilt, psi); Image_Value(projection_image).data->setImage(MULTIDIM_ARRAY(P)); } catch (XmippError &xe) { PyErr_SetString(PyXmippError, xe.msg.c_str()); } Py_RETURN_NONE; } }
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"; } }
// Fit the beam-induced translations for all average micrographs void ParticlePolisherMpi::fitMovementsAllMicrographs() { int total_nr_micrographs = exp_model.average_micrographs.size(); // Each node does part of the work long int my_first_micrograph, my_last_micrograph, my_nr_micrographs; divide_equally(total_nr_micrographs, node->size, node->rank, my_first_micrograph, my_last_micrograph); my_nr_micrographs = my_last_micrograph - my_first_micrograph + 1; // Loop over all average micrographs int barstep; if (verb > 0) { std::cout << " + Fitting straight paths for beam-induced movements in all micrographs ... " << std::endl; init_progress_bar(my_nr_micrographs); barstep = XMIPP_MAX(1, my_nr_micrographs/ 60); } for (long int i = my_first_micrograph; i <= my_last_micrograph; i++) { if (verb > 0 && i % barstep == 0) progress_bar(i); fitMovementsOneMicrograph(i); } // Wait until all micrographs have been done MPI_Barrier(MPI_COMM_WORLD); if (verb > 0) { progress_bar(my_nr_micrographs); } // Combine results from all nodes MultidimArray<DOUBLE> allnodes_fitted_movements; allnodes_fitted_movements.resize(fitted_movements); MPI_Allreduce(MULTIDIM_ARRAY(fitted_movements), MULTIDIM_ARRAY(allnodes_fitted_movements), MULTIDIM_SIZE(fitted_movements), MY_MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); fitted_movements = allnodes_fitted_movements; // Set the fitted movements in the xoff and yoff columns of the exp_model.MDimg for (long int ipart = 0; ipart < exp_model.numberOfParticles(); ipart++) { long int part_id = exp_model.particles[ipart].id; DOUBLE xoff = DIRECT_A2D_ELEM(fitted_movements, part_id, 0); DOUBLE yoff = DIRECT_A2D_ELEM(fitted_movements, part_id, 1); exp_model.MDimg.setValue(EMDL_ORIENT_ORIGIN_X, xoff, part_id); exp_model.MDimg.setValue(EMDL_ORIENT_ORIGIN_Y, yoff, part_id); } if (node->isMaster()) { // Write out the STAR file with all the fitted movements FileName fn_tmp = fn_in.withoutExtension() + "_" + fn_out + ".star"; exp_model.MDimg.write(fn_tmp); std::cout << " + Written out all fitted movements in STAR file: " << fn_tmp << std::endl; } }
void ParticlePolisherMpi::optimiseBeamTilt() { // This function assumes the shiny particles are in exp_mdel.MDimg!! if (beamtilt_max <= 0. && defocus_shift_max <= 0.) return; if (minres_beamtilt < maxres_model) { if (verb > 0) std::cout << " Skipping beamtilt correction, as the resolution of the shiny reconstruction does not go beyond minres_beamtilt of " << minres_beamtilt << " Ang." << std::endl; return; } getBeamTiltGroups(); initialiseSquaredDifferenceVectors(); int total_nr_micrographs = exp_model.micrographs.size(); // Each node does part of the work long int my_first_micrograph, my_last_micrograph, my_nr_micrographs; divide_equally(total_nr_micrographs, node->size, node->rank, my_first_micrograph, my_last_micrograph); my_nr_micrographs = my_last_micrograph - my_first_micrograph + 1; // Loop over all average micrographs int barstep; if (verb > 0) { std::cout << " + Optimising beamtilts and/or defocus values in all micrographs ... " << std::endl; init_progress_bar(my_nr_micrographs); barstep = XMIPP_MAX(1, my_nr_micrographs/ 60); } for (long int i = my_first_micrograph; i <= my_last_micrograph; i++) { if (verb > 0 && i % barstep == 0) progress_bar(i); optimiseBeamTiltAndDefocusOneMicrograph(i); } if (verb > 0) progress_bar(my_nr_micrographs); // Combine results from all nodes if (beamtilt_max > 0.) { MultidimArray<DOUBLE> allnodes_diff2_beamtilt; allnodes_diff2_beamtilt.initZeros(diff2_beamtilt); MPI_Allreduce(MULTIDIM_ARRAY(diff2_beamtilt), MULTIDIM_ARRAY(allnodes_diff2_beamtilt), MULTIDIM_SIZE(diff2_beamtilt), MY_MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); diff2_beamtilt = allnodes_diff2_beamtilt; } if (defocus_shift_max > 0.) { MultidimArray<DOUBLE> allnodes_defocus_shift_allmics; allnodes_defocus_shift_allmics.initZeros(defocus_shift_allmics); MPI_Allreduce(MULTIDIM_ARRAY(defocus_shift_allmics), MULTIDIM_ARRAY(allnodes_defocus_shift_allmics), MULTIDIM_SIZE(defocus_shift_allmics), MY_MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); defocus_shift_allmics = allnodes_defocus_shift_allmics; } // Now get the final optimised beamtilts and defocus shifts, and write results to the MetadataTable applyOptimisedBeamTiltsAndDefocus(); // Write the new MDTable to disc if (verb > 0) exp_model.MDimg.write(fn_out + ".star"); }
void ParticlePolisherMpi::calculateAllSingleFrameReconstructionsAndBfactors() { FileName fn_star = fn_in.withoutExtension() + "_" + fn_out + "_bfactors.star"; if (!do_start_all_over && readStarFileBfactors(fn_star)) { if (verb > 0) std::cout << " + " << fn_star << " already exists: skipping calculation average of per-frame B-factors." <<std::endl; return; } DOUBLE bfactor, offset, corr_coeff; int total_nr_frames = last_frame - first_frame + 1; long int my_first_frame, my_last_frame, my_nr_frames; // Loop over all frames (two halves for each frame!) to be included in the reconstruction // Each node does part of the work divide_equally(2*total_nr_frames, node->size, node->rank, my_first_frame, my_last_frame); my_nr_frames = my_last_frame - my_first_frame + 1; if (verb > 0) { std::cout << " + Calculating per-frame reconstructions ... " << std::endl; init_progress_bar(my_nr_frames); } for (long int i = my_first_frame; i <= my_last_frame; i++) { int iframe = (i >= total_nr_frames) ? i - total_nr_frames : i; iframe += first_frame; int ihalf = (i >= total_nr_frames) ? 2 : 1; calculateSingleFrameReconstruction(iframe, ihalf); if (verb > 0) progress_bar(i - my_first_frame + 1); } if (verb > 0) { progress_bar(my_nr_frames); } MPI_Barrier(MPI_COMM_WORLD); // Also calculate the average of all single-frames for both halves if (node->rank == 0) calculateAverageAllSingleFrameReconstructions(1); else if (node->rank == 1) calculateAverageAllSingleFrameReconstructions(2); // Wait until all reconstructions have been done, and calculate the B-factors per-frame MPI_Barrier(MPI_COMM_WORLD); calculateBfactorSingleFrameReconstruction(-1, bfactor, offset, corr_coeff); // FSC between the two averages, also reads mask MPI_Barrier(MPI_COMM_WORLD); // Loop over all frames (two halves for each frame!) to be included in the reconstruction // Each node does part of the work divide_equally(total_nr_frames, node->size, node->rank, my_first_frame, my_last_frame); my_nr_frames = my_last_frame - my_first_frame + 1; if (verb > 0) { std::cout << " + Calculating per-frame B-factors ... " << std::endl; init_progress_bar(my_nr_frames); } for (long int i = first_frame+my_first_frame; i <= first_frame+my_last_frame; i++) { calculateBfactorSingleFrameReconstruction(i, bfactor, offset, corr_coeff); int iframe = i - first_frame; DIRECT_A1D_ELEM(perframe_bfactors, iframe * 3 + 0) = bfactor; DIRECT_A1D_ELEM(perframe_bfactors, iframe * 3 + 1) = offset; DIRECT_A1D_ELEM(perframe_bfactors, iframe * 3 + 2) = corr_coeff; if (verb > 0) progress_bar(i - first_frame - my_first_frame + 1); } // Combine results from all nodes MultidimArray<DOUBLE> allnodes_perframe_bfactors; allnodes_perframe_bfactors.resize(perframe_bfactors); MPI_Allreduce(MULTIDIM_ARRAY(perframe_bfactors), MULTIDIM_ARRAY(allnodes_perframe_bfactors), MULTIDIM_SIZE(perframe_bfactors), MY_MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); perframe_bfactors = allnodes_perframe_bfactors; if (verb > 0) { progress_bar(my_nr_frames); writeStarFileBfactors(fn_star); // Also write a STAR file with the relative contributions of each frame to all frequencies fn_star = fn_in.withoutExtension() + "_" + fn_out + "_relweights.star"; writeStarFileRelativeWeights(fn_star); } }
void FourierTransformer::setFourier(MultidimArray<Complex >& inputFourier) { memcpy(MULTIDIM_ARRAY(fFourier), MULTIDIM_ARRAY(inputFourier), MULTIDIM_SIZE(inputFourier) * 2 * sizeof(double)); }
// 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; } }
void FourierTransformer::setFourier(const MultidimArray<std::complex<double> > &inputFourier) { memcpy(MULTIDIM_ARRAY(fFourier),MULTIDIM_ARRAY(inputFourier), MULTIDIM_SIZE(inputFourier)*2*sizeof(double)); }
void MpiProgReconstructADMM::shareVolume(MultidimArray<double> &V) { MPI_Allreduce(MPI_IN_PLACE, MULTIDIM_ARRAY(V), MULTIDIM_SIZE(V), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); synchronize(); }
void ProgXrayImport::getFlatfield(const FileName &fnFFinput, Image<double> &Iavg) { // Process the flatfield images MultidimArray<double> &mdaIavg = Iavg(); Matrix1D<double> expTimeArray, cBeamArray, slitWidthArray; // Local vectors DataSource ldSource = dSource; // Checking if fnFFinput is a single file to obtain the flatfield avg from if (extFlat && isImage(fnFFinput)) { fMD.read(fnFFinput); ldSource = NONE; } else { switch (ldSource) { case MISTRAL: if (!H5File.checkDataset(fnFFinput.getBlockName().c_str())) break; { fMD.read(fnFFinput); H5File.getDataset("NXtomo/instrument/bright_field/ExpTimes", expTimeArray, false); H5File.getDataset("NXtomo/instrument/bright_field/current", cBeamArray, false); // 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 flatfields' exposition time information."); expTimeArray.initConstant(fMD.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 flatfields' current beam information."); cBeamArray.initConstant(fMD.size(), 1.); } } // Since Alba does not provide slit width, we set to ones slitWidthArray.initConstant(fMD.size(), 1.); break; case BESSY: { size_t objId; for (size_t i = fIni; i <= fEnd; ++i) { objId = fMD.addObject(); fMD.setValue(MDL_IMAGE, fnFFinput + formatString("/img%d.spe", i), objId); } break; } case GENERIC: { // Get Darkfield std::cout << "Getting darkfield from "+fnFFinput << " ..." << std::endl; getDarkfield(fnFFinput, IavgDark); if (darkFix) IavgDark.write(fnRoot+"_"+fnFFinput.removeDirectories()+"_darkfield.xmp"); std::vector<FileName> listDir; fnFFinput.getFiles(listDir); size_t objId; for (size_t i = 0; i < listDir.size(); ++i) { if (!listDir[i].hasImageExtension()) continue; objId = fMD.addObject(); fMD.setValue(MDL_IMAGE, fnFFinput+"/"+listDir[i], objId); } } break; } } if ( fMD.size() == 0 ) { reportWarning("XrayImport::getFlatfield: No images to process"); return; } ImageInfo imFFInfo; getImageInfo(fMD, imFFInfo); if ( (imFFInfo.adim.xdim != imgInfo.adim.xdim) || (imFFInfo.adim.ydim != imgInfo.adim.ydim) ) { reportWarning(formatString("XrayImport:: Flatfield images size %dx%d different from Tomogram images size %dx%d", imFFInfo.adim.xdim,imFFInfo.adim.ydim,imgInfo.adim.xdim,imgInfo.adim.ydim)); std::cout << "Setting crop values to fit the smallest dimensions." <<std::endl; // This shift in the crop sizes is exclusive of Mistral data cropSizeXi = (imgInfo.adim.xdim - std::min(imgInfo.adim.xdim-cropSizeX*2, imFFInfo.adim.xdim))/2 + 1; cropSizeYi = (imgInfo.adim.ydim - std::min(imgInfo.adim.ydim-cropSizeY*2, imFFInfo.adim.ydim))/2 + 1; cropSizeXe = cropSizeXi - 2; cropSizeYe = cropSizeYi - 2; } int cropX = (imFFInfo.adim.xdim - (imgInfo.adim.xdim-cropSizeXi-cropSizeXe))/2;// - 1; int cropY = (imFFInfo.adim.ydim - (imgInfo.adim.ydim-cropSizeYi-cropSizeYe))/2;// - 1; int N = 0; Image<double> Iaux; FileName fnImg; FOR_ALL_OBJECTS_IN_METADATA(fMD) { fMD.getValue(MDL_IMAGE, fnImg, __iter.objId); readAndCrop(fnImg, Iaux, cropX, cropY); if ( darkFix ) { Iaux() -= IavgDark(); forcePositive(Iaux()); } double currentBeam = 1; double expTime = 1; double slitWidth = 1; switch (ldSource) { case MISTRAL: { size_t idx = fnImg.getPrefixNumber(); currentBeam = dMi(cBeamArray, idx-1); expTime = dMi(expTimeArray, idx-1); slitWidth = dMi(slitWidthArray, idx-1); } break; case BESSY: case GENERIC: readCorrectionInfo(fnImg, currentBeam, expTime, slitWidth); break; default: break; } Iaux() *= 1.0/(currentBeam*expTime*slitWidth); if ( N == 0 ) mdaIavg = Iaux(); else mdaIavg += Iaux(); N++; } darkFix = false; // We reset just in case there is no dark field for tomo images mdaIavg*=1.0/N; /* Create a mask with zero valued pixels to apply boundaries median filter * to avoid dividing by zero when normalizing */ MultidimArray<char> &mdaMask = MULTIDIM_ARRAY(bpMask); if ( !fnBPMask.empty() && !mdaIavg.sameShape(mdaMask) ) REPORT_ERROR(ERR_MULTIDIM_SIZE, "XrayImport: Mask size does not match flat fields size."); if (BPFactor > 0) { double avg, std; mdaIavg.computeAvgStdev(avg, std); mdaMask.resize(mdaIavg, false); double th = avg - std*BPFactor; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mdaMask) dAi(mdaMask, n) = dAi(mdaIavg, n) < th; } else if (fnBPMask.empty()) mdaIavg.equal(0,mdaMask); MultidimArray<char> mask = mdaMask; boundMedianFilter(mdaIavg,mask); }
/* MAIN -------------------------------------------------------------------- */ int main(int argc, char **argv) { // For parallelization int rank, size, num_img_tot; int c,nn,imgno,opt_refno,iaux; double LL,sumw_allrefs,sumcorr; double aux,wsum_sigma_noise2, wsum_sigma_offset; std::vector<Matrix3D<double > > wsum_Mref; std::vector<Matrix3D<double > > wsum_Mwedge; std::vector<double> sumw; Matrix3D<double> Maux, Mauxbig; FileName fn_img,fn_tmp; Matrix1D<double> oneline(0); DocFile DFo,DFf; SelFile SFo,SFa; Prog_MLalign3D_prm prm; // Init Parallel interface MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); // Get input parameters try { // Read command line prm.read(argc,argv); // Select only relevant part of selfile for this rank mpiSelectPart(prm.SF, rank,size,num_img_tot); prm.produce_Side_info(); if (rank==0) prm.show(); else prm.verb=0; } catch (XmippError XE) {if (rank==0) {std::cout << XE; prm.usage();} MPI_Finalize(); exit(1);} try { Maux.resize(prm.dim,prm.dim,prm.dim); Maux.setXmippOrigin(); Mauxbig.resize(prm.bigdim,prm.bigdim,prm.bigdim); Mauxbig.setXmippOrigin(); DFo.reserve(2*prm.SF.ImgNo()+1); DFf.reserve(2*prm.SFr.ImgNo()+4); SFa.reserve(prm.Niter*prm.nr_ref); SFa.clear(); // Loop over all iterations for (int iter=prm.istart; iter<=prm.Niter; iter++) { if (prm.verb>0) std::cerr << " multi-reference refinement: iteration " << iter <<" of "<< prm.Niter<<std::endl; DFo.clear(); if (rank==0) DFo.append_comment("Headerinfo columns: rot (1), tilt (2), psi (3), Xoff (4), Yoff (5), Zoff (6), WedNo (7) Ref (8), Pmax/sumP (9)"); // Integrate over all images prm.ML_sum_over_all_images(prm.SF,prm.Iref,LL,sumcorr,DFo, wsum_Mref,wsum_Mwedge, wsum_sigma_noise2,wsum_sigma_offset,sumw); // Here MPI_allreduce of all wsums,LL and sumcorr !!! MPI_Allreduce(&LL,&aux,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); LL=aux; MPI_Allreduce(&sumcorr,&aux,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); sumcorr=aux; MPI_Allreduce(&wsum_sigma_offset,&aux,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); wsum_sigma_offset=aux; MPI_Allreduce(&wsum_sigma_noise2,&aux,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); wsum_sigma_noise2=aux; for (int refno=0;refno<prm.nr_ref; refno++) { MPI_Allreduce(MULTIDIM_ARRAY(wsum_Mref[refno]),MULTIDIM_ARRAY(Maux), MULTIDIM_SIZE(wsum_Mref[refno]),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); wsum_Mref[refno]=Maux; MPI_Allreduce(MULTIDIM_ARRAY(wsum_Mwedge[refno]),MULTIDIM_ARRAY(Mauxbig), MULTIDIM_SIZE(wsum_Mwedge[refno]),MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); wsum_Mwedge[refno]=Mauxbig; MPI_Allreduce(&sumw[refno],&aux,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); sumw[refno]=aux; } // Update model parameters prm.update_parameters(wsum_Mref,wsum_Mwedge, wsum_sigma_noise2,wsum_sigma_offset, sumw,sumcorr,sumw_allrefs,iter); // All nodes write out temporary DFo fn_img.compose(prm.fn_root,rank,"tmpdoc"); DFo.write(fn_img); MPI_Barrier(MPI_COMM_WORLD); if (rank==0) { prm.write_output_files(iter,SFa,DFf,sumw_allrefs,sumw,LL,sumcorr); // Write out docfile with optimal transformation & references DFo.clear(); for (int rank2=0; rank2<size; rank2++) { fn_img.compose(prm.fn_root,rank2,"tmpdoc"); int ln=DFo.LineNo(); DFo.append(fn_img); DFo.locate(DFo.get_last_key()); DFo.next(); DFo.remove_current(); system(((std::string)"rm -f "+fn_img).c_str()); } fn_tmp=prm.fn_root+"_it"; fn_tmp.compose(fn_tmp,iter,"doc"); DFo.write(fn_tmp); } } // end loop iterations } catch (XmippError XE) {if (rank==0) {std::cout << XE; prm.usage();} MPI_Finalize(); exit(1);} MPI_Finalize(); return 0; }
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); } }