Xmipp  v3.23.11-Nereus
mpi_project_XR.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Joaquin Oton (joton@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 
27 #include "mpi_project_XR.h"
28 
29 /* Structure with the information about the different
30  * projections to be distributed among nodes */
32 {
34  double rot, tRot;
35  double tilt, tTilt;
36  double psi, tPsi;
37  double xShift;
38  double yShift;
39  double zShift;
40 };
41 
43 {
45  clearUsage();
46  addUsageLine("MPI Generate projections as in a X-ray microscope from a 3D Xmipp volume.");
47 
48 }
49 void ProgMPIXrayProject::read(int argc, char** argv)
50 {
51  node = std::make_shared<MpiNode>(argc, argv);
52  if (!node->isMaster())
53  verbose = 0;
54  ProgXrayProject::read(argc, (const char **)argv);
55 }
56 
58 {
59  preRun();
60 
61  // Project
62  projMD.setComment("True rot, tilt and psi; rot, tilt, psi, X and Y shifts applied");
63 
64  // // Assign mpi node information
65  // MpiNode & node = *node;
66 
67  // Calculation of data to be distributed in nodes -----------------------------------------
68  std::vector<mpiProjData> mpiData;
69  mpiProjData data;
70 
71  size_t idx = FIRST_IMAGE;
72  size_t id;
73 
74  double angle=projParam.tilt0;
75  while (angle <= projParam.tiltF)
76  {
77  if (projParam.singleProjection)
78  data.fn_proj = projParam.fnOut;
79  else
80  data.fn_proj.compose(idx, projParam.fnRoot + ".stk");
81 
82  // Choose Center displacement ........................................
83  double shiftX = rnd_gaus(projParam.Ncenter_avg, projParam.Ncenter_dev);
84  double shiftY = rnd_gaus(projParam.Ncenter_avg, projParam.Ncenter_dev);
85  Matrix1D<double> inPlaneShift(3);
86  VECTOR_R3(inPlaneShift,shiftX,shiftY,0);
87 
88  projParam.calculateProjectionAngles(proj,angle, 0,inPlaneShift);
89  proj.getEulerAngles(data.tRot, data.tTilt,data.tPsi);
90  proj.getShifts(data.xShift, data.yShift, data.zShift);
91 
92  // Add noise in angles and voxels ....................................
93 
94  data.rot = data.tRot + rnd_gaus(projParam.Nangle_avg, projParam.Nangle_dev);
95  data.tilt = data.tTilt + rnd_gaus(projParam.Nangle_avg, projParam.Nangle_dev);
96  data.psi = data.tPsi + rnd_gaus(projParam.Nangle_avg, projParam.Nangle_dev);
97 
98  //MPI proj.setEulerAngles(rot,tilt,psi);
99 
100  if (node->isMaster())
101  {
102  id = projMD.addObject();
103  projMD.setValue(MDL_IMAGE,data.fn_proj, id);
104 
105  projMD.setValue(MDL_ANGLE_ROT,data.tRot, id);
106  projMD.setValue(MDL_ANGLE_TILT,data.tTilt, id);
107  projMD.setValue(MDL_ANGLE_PSI,data.tPsi, id);
108  projMD.setValue(MDL_ANGLE_ROT2,data.rot, id);
109  projMD.setValue(MDL_ANGLE_TILT2,data.tilt, id);
110  projMD.setValue(MDL_ANGLE_PSI2,data.psi, id);
111  projMD.setValue(MDL_SHIFT_X,shiftX, id);
112  projMD.setValue(MDL_SHIFT_Y,shiftY, id);
113  }
114 
115  mpiData.push_back(data);
116  idx++;
117  angle += projParam.tiltStep;
118  }
119 
120  // Creation of MPI Job Handler file
121 
122  long long int nodeBlockSize = 1;
123  std::unique_ptr<MpiTaskDistributor>jobHandler = std::make_unique<MpiTaskDistributor>(mpiData.size(), nodeBlockSize, node);
124 
125  size_t first = 0, last = 0;
126 
127  if (node->isMaster())
128  {
129  // Save metadata file with angles and shift info
130  if (!projParam.singleProjection)
131  projMD.write(projParam.fnRoot + ".sel");
132 
133  if (!(projParam.show_angles))
134  init_progress_bar(mpiData.size());
135 
136  // Creation of output file to reserve space
137  createEmptyFile(mpiData[mpiData.size()-1].fn_proj,
138  XMIPP_MIN(XSIZE(MULTIDIM_ARRAY(phantom.iniVol)),(size_t)projParam.proj_Xdim),
139  XMIPP_MIN(YSIZE(MULTIDIM_ARRAY(phantom.iniVol)),(size_t)projParam.proj_Ydim));
140 
141  std::cout << "Projecting ...\n";
142  }
143 
144  node->barrierWait();
145 
146  MPI_Barrier(MPI_COMM_WORLD);
147 
148  // Parallel node jobs
149  while (jobHandler->getTasks(first, last))
150  {
151  for (size_t k = first; k <= last; k++)
152  {
153  std::cout << "Node: " << node->rank << " - Task: " << k <<std::endl;
154  proj.setEulerAngles(mpiData[k].tRot, mpiData[k].tTilt,mpiData[k].tPsi);
155  proj.setShifts(mpiData[k].xShift, mpiData[k].yShift, mpiData[k].zShift);
156 
157  //Reset thread task distributor
158  td->clear();
159 
160  // Really project ....................................................
161  if (!projParam.only_create_angles)
162  {
163  XrayRotateAndProjectVolumeOffCentered(phantom, psf, proj, stdProj, projParam.proj_Ydim, projParam.proj_Xdim);
164  proj.write(mpiData[k].fn_proj);
165  }
166 
167  // Add noise in angles and voxels ....................................
168  // proj.setEulerAngles(mpiData[k].rot,mpiData[k].tilt,mpiData[k].psi); // Geo info is not stored in header file
169  IMGMATRIX(proj).addNoise(projParam.Npixel_avg, projParam.Npixel_dev, "gaussian");
170 
171  if (projParam.show_angles)
172  std::cout << "Node: " << node->rank << "\t" << proj.rot() << "\t"
173  << proj.tilt() << "\t" << proj.psi() << std::endl;
174 
175  if (node->isMaster() && !(projParam.show_angles))
176  progress_bar(k+1);
177  }
178  }
179  jobHandler->wait();
180 
181  postRun();
182 
183  return;
184 }
185 
187 //int PROJECT_mpi_XR_Effectively_project(
188 // ParametersXrayProjectMPI &prm,
189 // XrayProjPhantom &side,
190 // Projection &proj,
191 // XRayPSF &psf,
192 // MetaData &SF)
193 //{
194 // // Threads stuff
195 //
196 // XrayThread *dataThread = new XrayThread;
197 //
198 // dataThread->psf= &psf;
199 // dataThread->vol = &side.rotVol;
200 // dataThread->imOut = &proj;
201 //
202 // size_t threadBlockSize, numberOfJobs= side.iniVol().zdim;
203 // numberOfThreads = psf.nThr;
204 //
205 // threadBlockSize = (numberOfThreads == 1) ? numberOfJobs : numberOfJobs/numberOfThreads/2;
206 //
207 // //Create the job handler to distribute thread jobs
208 // td = new ThreadTaskDistributor(numberOfJobs, threadBlockSize);
209 // barrier = new Barrier(numberOfThreads-1);
210 //
211 // //Create threads to start working
212 // thMgr = new ThreadManager(numberOfThreads,(void*) dataThread);
213 //
214 // int numProjs=0;
215 // SF.clear();
216 // MpiNode & node = *prm.node;
217 // MetaData DF_movements;
218 // DF_movements.setComment("True rot, tilt and psi; rot, tilt, psi, X and Y shifts applied");
219 // double tRot,tTilt,tPsi,rot,tilt,psi;
220 //
221 // // Calculation of data to be distributed in nodes
222 // std::vector<mpiProjData> mpiData;
223 // mpiProjData data;
224 //
225 // int idx=prm.starting;
226 // size_t id;
227 // for (double angle=prm.tilt0; angle<=prm.tiltF; angle+=prm.tiltStep)
228 // {
229 // data.fn_proj.compose(prm.fnOut, idx,
230 // prm.fn_projection_extension);
231 //
232 // // Choose Center displacement ........................................
233 // double shiftX = rnd_gaus(prm.Ncenter_avg, prm.Ncenter_dev);
234 // double shiftY = rnd_gaus(prm.Ncenter_avg, prm.Ncenter_dev);
235 // Matrix1D<double> inPlaneShift(3);
236 // VECTOR_R3(inPlaneShift,shiftX,shiftY,0);
237 //
238 // prm.calculateProjectionAngles(proj,angle, 0,inPlaneShift);
239 // proj.getEulerAngles(data.tRot, data.tTilt,data.tPsi);
240 // proj.getShifts(data.xShift, data.yShift, data.zShift);
241 //
242 // // Add noise in angles and voxels ....................................
243 //
244 // data.rot = data.tRot + rnd_gaus(prm.Nangle_avg, prm.Nangle_dev);
245 // data.tilt = data.tTilt + rnd_gaus(prm.Nangle_avg, prm.Nangle_dev);
246 // data.psi = data.tPsi + rnd_gaus(prm.Nangle_avg, prm.Nangle_dev);
247 //
248 // //MPI proj.setEulerAngles(rot,tilt,psi);
249 //
250 // if (node.isMaster())
251 // {
252 // id = DF_movements.addObject();
253 // DF_movements.setValue(MDL_ANGLE_ROT,data.tRot, id);
254 // DF_movements.setValue(MDL_ANGLE_TILT,data.tTilt, id);
255 // DF_movements.setValue(MDL_ANGLE_PSI,data.tPsi, id);
256 // DF_movements.setValue(MDL_ANGLE_ROT2,data.rot, id);
257 // DF_movements.setValue(MDL_ANGLE_TILT2,data.tilt, id);
258 // DF_movements.setValue(MDL_ANGLE_PSI2,data.psi, id);
259 // DF_movements.setValue(MDL_SHIFT_X,shiftX, id);
260 // DF_movements.setValue(MDL_SHIFT_Y,shiftY, id);
261 //
262 // id = SF.addObject();
263 // SF.setValue(MDL_IMAGE,data.fn_proj, id);
264 // SF.setValue(MDL_ENABLED,1, id);
265 // }
266 // mpiData.push_back(data);
267 // idx++;
268 // }
269 //
270 // MPI_Barrier(MPI_COMM_WORLD);
271 //
272 // // Creation of Job Handler file
273 //
274 // FileTaskDistributor *jobHandler;
275 // long long int nodeBlockSize = 1;
276 // jobHandler = new FileTaskDistributor(mpiData.size(), nodeBlockSize, &node);
277 //
278 //
279 // if (node.isMaster())
280 // {
281 // DF_movements.write(prm.fnOut + "_movements.txt");
282 // std::cerr << "Projecting ...\n";
283 // }
284 //
285 //
286 // long long int first = -1, last = -1;
287 //
288 // if (!(prm.show_angles))
289 // init_progress_bar(mpiData.size());
290 //
291 // // Parallel node jobs
292 // while (jobHandler->getTasks(first, last))
293 // {
294 // for (long long int k = first; k <= last; k++)
295 // {
296 // std::cout << "Node: " << node.rank << " - Task: " << k <<std::endl;
297 // proj.setEulerAngles(mpiData[k].tRot, mpiData[k].tTilt,mpiData[k].tPsi);
298 // proj.setShifts(mpiData[k].xShift, mpiData[k].yShift, mpiData[k].zShift);
299 //
300 // //Reset thread task distributor
301 // td->clear();
302 // // Really project ....................................................
303 // XrayProjectVolumeOffCentered(side, psf, proj,prm.proj_Ydim, prm.proj_Xdim);
304 //
305 //
306 // // Add noise in angles and voxels ....................................
307 // proj.setEulerAngles(mpiData[k].rot,mpiData[k].tilt,mpiData[k].psi);
308 // IMGMATRIX(proj).addNoise(prm.Npixel_avg, prm.Npixel_dev, "gaussian");
309 //
310 // // Save ..............................................................
311 // if (prm.show_angles)
312 // std::cout << "Node: " << node.rank << "\t" << proj.rot() << "\t"
313 // << proj.tilt() << "\t" << proj.psi() << std::endl;
314 //
315 // proj.write(mpiData[k].fn_proj);
316 //
317 // progress_bar(k+1);
318 // numProjs++;
319 // }
320 // }
321 // delete jobHandler;
322 // //Terminate threads and free memory
323 // delete td;
324 // delete thMgr;
325 // delete barrier;
326 //
327 // return numProjs;
328 //}
void init_progress_bar(long total)
Rotation angle of an image (double,degrees)
#define YSIZE(v)
Tilting angle of an image (double,degrees)
virtual void read(int argc, const char **argv, bool reportErrors=true)
Tilting angle of an image (double,degrees)
virtual void defineParams()
Shift for the image in the X axis (double)
#define MULTIDIM_ARRAY(v)
void compose(const String &str, const size_t no, const String &ext="")
void XrayRotateAndProjectVolumeOffCentered(XrayProjPhantom &phantom, XRayPSF &psf, Projection &P, Projection &standardP, int Ydim, int Xdim)
Special label to be used when gathering MDs in MpiMetadataPrograms.
#define IMGMATRIX(I)
void barrierWait()
Definition: xmipp_mpi.cpp:171
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
Rotation angle of an image (double,degrees)
glob_log first
double psf
MpiNode * node
#define XSIZE(v)
void progress_bar(long rlen)
void createEmptyFile(const FileName &filename, int xdim, int ydim, int Zdim, size_t select_img, bool isStack, int mode, int _swapWrite, const MDRowVec *md)
Psi angle of an image (double,degrees)
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
size_t rank
Definition: xmipp_mpi.h:52
FileName fn_proj
double rnd_gaus()
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
bool isMaster() const
Definition: xmipp_mpi.cpp:166
#define FIRST_IMAGE
Shift for the image in the Y axis (double)
Name of an image (std::string)
void read(int argc, char **argv)