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(); } }
void ParticlePolisherMpi::polishParticlesAllMicrographs() { if (!do_start_all_over && exists(fn_out + ".star")) { if (verb > 0) std::cout << std::endl << " + " << fn_out << ".star already exists: skipping polishing of the particles." << std::endl; return; } 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 << " + Write out polished particles for 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); polishParticlesOneMicrograph(i); } if (verb > 0) progress_bar(my_nr_micrographs); if (node->isMaster()) writeStarFilePolishedParticles(); MPI_Barrier(MPI_COMM_WORLD); }
// 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); } }