Xmipp  v3.23.11-Nereus
project_xray.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 #include "project_xray.h"
26 #include "core/transformations.h"
27 
29 {
30  addUsageLine("Generate projections as in a X-ray microscope from a 3D Xmipp volume.");
31  addSeeAlsoLine("phantom_create");
32  //Params
33  projParam.defineParams(this); // Projection parameters
34  addParamsLine("== Xray options == ");
35  addParamsLine(" [--sampling_rate <Ts>] : Sampling rate of the volume to be projected (nm).");
36  addParamsLine(" : If empty, same value as X-Y plane sampling from PSF.");
37  addParamsLine("alias -s;");
38  addParamsLine("[--psf <psf_param_file=\"\">] : XRay-Microscope parameters file. If not set, then default parameters are chosen.");
39  addParamsLine("[--focal_shift+ <delta_z=0.0>] : Shift along optical axis between the center of the phantom and the center of the psf in microns");
40  addParamsLine("alias -f;");
41  addParamsLine("[--threshold+ <thr=0.0>] : Normalized threshold relative to maximum of PSF to reduce the volume into slabs");
42  addParamsLine("[--std_proj] : Save also standard projections, adding _std suffix to filenames");
43  addParamsLine("[--thr <threads=1>] : Number of concurrent threads");
44  //Examples
45  //Example projection file
46  addExampleLine("In the following link you can find an example of projection parameter file:",false);
47  addExampleLine(" ",false);
48  addExampleLine("http://sourceforge.net/p/testxmipp/code/ci/master/tree/input/tomoProjection.param?format=raw",false);
49  addExampleLine(" ",false);
50  addExampleLine("In the following link you can find an example of X-ray microscope parameters file:",false);
51  addExampleLine(" ",false);
52  addExampleLine("http://sourceforge.net/p/testxmipp/code/ci/master/tree/input/xray_psf.xmd?format=raw",false);
53 
54 }
55 
56 /* Read from command line ================================================== */
58 {
59  // fn_proj_param = getParam("-i");
60  // fn_sel_file = getParam("-o");
61  projParam.readParams(this);
62 
63  fn_psf_xr = getParam("--psf");
64  dxo = (checkParam("-s"))? getDoubleParam("-s")*1e-9 : -1 ;
65  psfThr = getDoubleParam("--threshold");
66  nThr = getIntParam("--thr");
67  save_std_projs = checkParam("--std_proj");
68 
70  psf.setFocalShift(getDoubleParam("--focal_shift")*1e-6);
72  psf.nThr = nThr;
73 }
74 
75 //Some global threads management variables
79 
80 
82 {
84 
87  //Correct the rotation axis displacement in projectionParams from pixels to meters
89 
90  // Threads stuff
91 
92  barrier = new Barrier(nThr);
93 
94  //Create threads to start working
95  thMgr = new ThreadManager(nThr);
96 
97 }
98 
100 {
101  //Terminate threads and free memory
102  // if (td != NULL)
103  // delete td;
104  delete thMgr;
105  delete barrier;
106 }
107 
109 {
110  preRun();
111 
112  int expectedNumProjs = FLOOR((projParam.tiltF-projParam.tilt0)/projParam.tiltStep);
113  int numProjs=0;
114 
115  if (verbose > 0)
116  {
117  std::cerr << "Projecting ...\n";
118  if (!(projParam.show_angles))
119  init_progress_bar(expectedNumProjs);
120  }
121  projMD.setComment("True rot, tilt and psi; rot, tilt, psi, X and Y shifts applied");
122  double tRot,tTilt,tPsi,rot,tilt,psi;
123  FileName fn_proj; // Projection name
124  size_t idx = FIRST_IMAGE;
125 
126  // Project
127  for (double angle=projParam.tilt0; angle<=projParam.tiltF; angle+=projParam.tiltStep)
128  {
130  fn_proj = projParam.fnOut;
131  else
132  fn_proj.compose(idx, projParam.fnRoot + ".stk");
133 
134  // Choose Center displacement ........................................
137  Matrix1D<double> inPlaneShift(3);
138  VECTOR_R3(inPlaneShift,shiftX,shiftY,0);
139 
140  projParam.calculateProjectionAngles(proj,angle, 0,inPlaneShift);
141 
142  //Reset thread task distributor
143  // td->clear();
144 
145  // Really project ....................................................
148 
149  // Add noise in angles and voxels ....................................
150  proj.getEulerAngles(tRot, tTilt,tPsi);
151 
155 
156  proj.setEulerAngles(rot,tilt,psi);
157 
158  size_t objId = projMD.addObject();
160  {
161  // Here we subtract the differences to the background illumination (at this moment normalized to 1) //TODO
164 
165  if (save_std_projs)
167 
168  projMD.setValue(MDL_IMAGE,fn_proj,objId);
169  }
170 
171  projMD.setValue(MDL_ANGLE_ROT,rot,objId);
172  projMD.setValue(MDL_ANGLE_TILT,tilt,objId);
173  projMD.setValue(MDL_ANGLE_PSI,psi,objId);
174  projMD.setValue(MDL_ANGLE_ROT2,tRot,objId);
175  projMD.setValue(MDL_ANGLE_TILT2,tTilt,objId);
176  projMD.setValue(MDL_ANGLE_PSI2,tPsi,objId);
177  projMD.setValue(MDL_SHIFT_X,shiftX,objId);
178  projMD.setValue(MDL_SHIFT_Y,shiftY,objId);
179 
180  IMGMATRIX(proj).addNoise(projParam.Npixel_avg, projParam.Npixel_dev, "gaussian");
181 
182  // Save ..............................................................
184  {
185  std::cout << "N Rot Tilt Psi" <<std::endl;
186  std::cout << idx << "\t" << proj.rot() << "\t"
187  << proj.tilt() << "\t" << proj.psi() << std::endl;
188  }
189  else if ((expectedNumProjs % XMIPP_MAX(1, numProjs / 60)) == 0 && verbose > 0)
190  progress_bar(numProjs);
191 
192  numProjs++;
193  idx++;
194  }
195  if (!(projParam.show_angles))
196  progress_bar(expectedNumProjs);
197 
198  // Save metadata file with angles and shift info
200  {
201  projMD.setComment("Angles rot,tilt and psi contain noisy projection angles and rot2,tilt2 and psi2 contain actual projection angles");
202  projMD.write(projParam.fnRoot + ".xmd");
203  }
204 
205  postRun();
206 
207  return;
208 }
209 
211  int Ydim, int Xdim)
212 {
213 
214  int iniXdim, iniYdim, iniZdim, newXdim, newYdim, newZdim, rotXdim, rotZdim;
215 
216  iniXdim = XSIZE(MULTIDIM_ARRAY(phantom.iniVol));
217  iniYdim = YSIZE(MULTIDIM_ARRAY(phantom.iniVol));
218  iniZdim = ZSIZE(MULTIDIM_ARRAY(phantom.iniVol));
219 
220  // Projection offset in pixels
221  Matrix1D<double> offsetNV(3);
222  P.getShifts(XX(offsetNV), YY(offsetNV), ZZ(offsetNV));
223 
224  // xOffsetN = P.Xoff()/psf.dxo;
225  // yOffsetN = P.Yoff()/psf.dxo;
226 
227 
228  /* If Xdim is greater than Zdim, then as we rotate the volume the rotated Zdim must be
229  * great enough to cover all the volume.
230  */
231  /* By now, we are going to keep it unused */
232  // if (true)
233  // {
234  // double radi, theta0, theta, tilt;
235  //
236  // radi = sqrt(iniZdim*iniZdim + iniXdim*iniXdim);
237  // theta0 = atan2(iniZdim, iniXdim);
238  // tilt = ((P.tilt() < 90)? P.tilt(): 180 - P.tilt())* PI / 180;
239  //
240  // rotZdim = XMIPP_MAX(ROUND(radi * sin(ABS(tilt) + ABS(theta0))), iniZdim);
241  // rotXdim = XMIPP_MAX(ROUND(radi * cos(ABS(tilt) - ABS(theta0))), iniXdim);
242  // rotYdim = iniYdim;
243  //
244  // // rotZdim = iniZdim;
245  // // rotXdim = iniXdim;
246  //
247  // newXdim = rotXdim + 2*ABS(XX(offsetNV));
248  // newYdim = iniYdim + 2*ABS(YY(offsetNV));
249  // newZdim = rotZdim;
250  // }
251  // else
252  rotXdim = iniXdim;
253  rotZdim = iniZdim;
254 
255  newXdim = (int)(rotXdim + 2*fabs(XX(offsetNV)));
256  newYdim = (int)(iniYdim + 2*fabs(YY(offsetNV)));
257  newZdim = rotZdim;
258 
259  // We set the dimensions only to obtain the values of starting X,Y,Z
260  // phantom.rotVol.setDimensions(rotXdim, rotYdim, rotZdim, 1);
261  phantom.rotVol.setDimensions(newXdim, newYdim, newZdim, 1);
262  phantom.rotVol.setXmippOrigin();
263 
264  if (psf.verbose > 1)
265  {
266  if (newXdim != iniXdim || newYdim != iniYdim)
267  {
268  std::cout << std::endl;
269  std::cout << "--------------------------------" << std::endl;
270  std::cout << "XrayProject::Volume_offCentered:" << std::endl;
271  std::cout << "--------------------------------" << std::endl;
272  std::cout << "(X,Y,Z) shifts = (" << XX(offsetNV) << "," << YY(offsetNV) << ","
273  << ZZ(offsetNV) << ") um" << std::endl;
274  std::cout << "Image resize (Nx,Ny): (" << iniXdim << "," << iniYdim << ") --> ("
275  << newXdim << "," << newYdim << ") " << std::endl;
276  }
277 #ifdef DEBUG
278 
279  std::cout <<"yoffsetN "<< YY(offsetNV) <<std::endl;
280  std::cout <<"xoffsetN "<< XX(offsetNV) <<std::endl;
281  std::cout <<"yinit " << yinit <<std::endl;
282  std::cout <<"yend " << yend <<std::endl;
283  std::cout <<"xinit " << xinit <<std::endl;
284  std::cout <<"xend " << xend <<std::endl;
285  std::cout <<"zinit " << zinit <<std::endl;
286  std::cout <<"zend " << zend <<std::endl;
287 #endif
288 
289  }
290 
291 
292 
293  // phantom.rotVol.setMmap(true);
294  phantom.rotVol.resizeNoCopy(newZdim, newYdim, newXdim);
295  phantom.rotVol.setXmippOrigin();
296 
297  // Rotate volume ....................................................
298 
299  Matrix2D<double> R, T;
300 
301  ZZ(offsetNV) = 0; // We are not interested in apply this Zshift
302  translation3DMatrix(offsetNV, T);
303  Euler_angles2matrix(P.rot(), P.tilt(), P.psi(), R, true);
304 
305  double outside = 0; //phantom.iniVol.getPixel(0,0,0,0);
306  MULTIDIM_ARRAY(phantom.iniVol).setXmippOrigin();
307 
308  applyGeometry(xmipp_transformation::LINEAR, phantom.rotVol, MULTIDIM_ARRAY(phantom.iniVol), T*R, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP, outside);
309 
310  psf.adjustParam(phantom.rotVol);
311 
312 
314  MultidimArray<double> IgeoVol, IgeoZb;
315  IgeoZb.resize(1, 1, YSIZE(phantom.rotVol), XSIZE(phantom.rotVol),false);
316  IgeoZb.initConstant(1.);
317 
318  calculateIgeo(phantom.rotVol, psf.dzo, IgeoVol, MULTIDIM_ARRAY(standardP), IgeoZb, psf.nThr, thMgr);
319 
320 
321 
322  projectXrayVolume(phantom.rotVol, IgeoVol, psf, P, nullptr, thMgr);
323 
324  int outXDim = XMIPP_MIN(Xdim,iniXdim);
325  int outYDim = XMIPP_MIN(Ydim,iniYdim);
326 
327  P().selfWindow(-ROUND(outYDim/2),
328  -ROUND(outXDim/2),
329  -ROUND(outYDim/2) + outYDim -1,
330  -ROUND(outXDim/2) + outXDim -1);
331 
332 }//XrayRotateAndProjectVolumeOffCentered
333 
335  MultidimArray<double> &IgeoVol,
336  XRayPSF &psf, Projection &P, MultidimArray<double> * projNorm, ThreadManager * thMgr)
337 {
338 
339  /* Now we have to split the phantom rotated volume into slabs, taking into
340  * account the possible different resolution and Z size.
341  *
342  * PhantomSlabIdx are the indexes of rotVol defining the slabs according to
343  * the splitting done to PSFVol.
344  *
345  * psfSlicesIdx are the indexes of the z planes of rotVol whose psf are
346  * used for the slabs.
347  */
348  std::vector<int> phantomSlabIdx, psfSlicesIdx;
349 
350  // Search for the PSFslab of the beginning of the volume
351  auto firstSlab = (int)(STARTINGZ(muVol)*psf.dzo/psf.dzoPSF);
352 
353  if (!XMIPP_EQUAL_ZERO(psf.slabThr))
354  {
355  for (size_t kk = 0; kk < psf.slabIndex.size(); ++kk)
356  {
357  if (firstSlab < psf.slabIndex[kk])
358  {
359  firstSlab = kk-1;
360  break;
361  }
362  }
363 
364  // Searching the equivalent index in rotvol for the indexes for the Slabs of PSFVol
365  phantomSlabIdx.push_back(STARTINGZ(muVol));
366 
367  for (size_t kk = firstSlab+1; kk < psf.slabIndex.size(); ++kk)
368  {
369  auto tempK = (int)(psf.slabIndex[kk] * psf.dzoPSF / psf.dzo);
370 
371  if (tempK <= FINISHINGZ(muVol))
372  {
373  phantomSlabIdx.push_back(tempK);
374  int tempKK = psf.slabIndex[kk-1];
375  auto psfMeanSlice = (int)((tempK + tempKK)*0.5 * psf.dzoPSF / psf.dzo);
376  psfSlicesIdx.push_back(psfMeanSlice);
377  }
378  else
379  {
380  phantomSlabIdx.push_back(FINISHINGZ(muVol));
381  int psfMeanSlice = (tempK + phantomSlabIdx[kk-1])/2;
382  psfSlicesIdx.push_back(psfMeanSlice);
383  continue;
384  }
385  }
386  }
387  else
388  {
389  for (int k = STARTINGZ(muVol); k <= FINISHINGZ(muVol); ++k)
390  {
391  phantomSlabIdx.push_back(k);
392  psfSlicesIdx.push_back(k);
393  }
394  // To define the last range
395  phantomSlabIdx.push_back(FINISHINGZ(muVol)+1);
396  }
397 
398  XrayThreadArgument projThrData;
399  Barrier barrier(thMgr->threads);
400 
401  projThrData.psf = &psf;
402  projThrData.muVol = &muVol;
403  projThrData.IgeoVol = &IgeoVol;
404  projThrData.projOut = &P;
405  projThrData.projNorm = projNorm;
406  projThrData.phantomSlabIdx = & phantomSlabIdx;
407  projThrData.psfSlicesIdx = & psfSlicesIdx;
408 
409  //Create the job handler to distribute thread jobs
410  size_t blockSize, numberOfJobs = psfSlicesIdx.size() ;
411  blockSize = 1;
412  ThreadTaskDistributor td(numberOfJobs, blockSize);
413  projThrData.td = &td;
414  projThrData.barrier = &barrier;
415 
416  //the really really final project routine, I swear by Snoopy.
417  // project_xr(psf,side.rotPhantomVol,P, idxSlice);
418 
419  thMgr->run(threadXrayProject,(void*) &projThrData);
420  // P.write("projection_after_threads.spi");
421 }
422 
423 /* Produce Side Information ================================================ */
426 {
427  read(prm.fnPhantom);
428 }
429 
430 void XrayProjPhantom::read(const FileName &fnVol)
431 {
432  // iniVol.readMapped(prm.fnPhantom);
433  iniVol.read(fnVol);
434  // MULTIDIM_ARRAY(iniVol).setXmippOrigin();
435  // rotVol.resizeNoCopy(MULTIDIM_ARRAY(iniVol));
436 
437 }
438 
441 {
442 
443  int thread_id = thArg.thread_id;
444 
445  auto *dataThread = (XrayThreadArgument*) thArg.data;
446  const XRayPSF &psf = *(dataThread->psf);
447  MultidimArray<double> &muVol = *(dataThread->muVol);
448  MultidimArray<double> &IgeoVol = *(dataThread->IgeoVol);
449  Image<double> &imOutGlobal = *(dataThread->projOut);
450  MultidimArray<double> * projNorm = dataThread->projNorm;
451  std::vector<int> &phantomSlabIdx = *(dataThread->phantomSlabIdx);
452  std::vector<int> &psfSlicesIdx = *(dataThread->psfSlicesIdx);
453  ParallelTaskDistributor * td = dataThread->td;
454  Barrier * barrier = dataThread->barrier;
455 
456  size_t first = 0, last = 0;
457 
458  if (thread_id == 0)
459  {
460  muVol.setXmippOrigin();
461  MULTIDIM_ARRAY(imOutGlobal).resizeNoCopy(psf.Niy, psf.Nix);
462  MULTIDIM_ARRAY(imOutGlobal).initZeros();
463  MULTIDIM_ARRAY(imOutGlobal).setXmippOrigin();
464  }
465 
466  barrier->wait();
467 
468  MultidimArray<double> imOut(psf.Niy, psf.Nix), projNormTemp(psf.Niy, psf.Nix);
469  imOut.setXmippOrigin();
470  projNormTemp.setXmippOrigin();
471 
472  MultidimArray<double> imTemp(psf.Noy, psf.Nox),intExp(psf.Noy, psf.Nox),imTempSc(imOut),*imTempP=nullptr;
473  intExp.setXmippOrigin();
474  imTemp.setXmippOrigin();
475  imTempSc.setXmippOrigin();
476 
477  // Parallel thread jobs
478  while (td->getTasks(first, last))
479  {
480  //#define DEBUG
481 #ifdef DEBUG
482  Image<double> _Im;
483 #endif
484 
485  int kini = phantomSlabIdx[first];
486  int kend = phantomSlabIdx[last + 1] - 1 ;
487 
488  // double deltaZSlab = psf.dzo*(kend-kini+1);
489 
490  intExp.initZeros();
491 
493  {
494  for (int k = kini; k <= kend; k++)
495  {
496  double tempValue = A3D_ELEM(muVol,k,i,j);
497  A2D_ELEM(intExp,i,j) += tempValue;
498  }
499  A2D_ELEM(imTemp,i,j) = A3D_ELEM(IgeoVol,kini,i,j)*(1 - exp( -A2D_ELEM(intExp,i,j) * psf.dzo));
500  }
501 #ifdef DEBUG
502  _Im().alias(intExp);
503  _Im.write("projectXR-intExp.spi");
504 
505  _Im().alias(imTemp);
506  _Im.write("projectXR-imTemp.spi");
507 #endif
508 
509  switch (psf.AdjustType)
510  {
511  case PSFXR_INT:
512  imTempP = &imTempSc;
514  break;
515 
516  case PSFXR_STD:
517  imTempP = &imTemp;
518  break;
519 
520  case PSFXR_ZPAD:
521  // (*imTempSc).resize(imTemp);
522  imTempP = &imTempSc;
523  imTemp.window(*imTempP,-ROUND(psf.Niy/2)+1,-ROUND(psf.Nix/2)+1,ROUND(psf.Niy/2)-1,ROUND(psf.Nix/2)-1);
524  break;
525  }
526 
527 #ifdef DEBUG
528  _Im().alias(*imTempP);
529  _Im.write("projectXR-imTempEsc_before.spi");
530 #endif
531 
532  psf.applyOTF(*imTempP, imOutGlobal.Zoff()- psfSlicesIdx[first]*psf.dzo);
533 
534 #ifdef DEBUG
535 
536  _Im.write("projectXR-imTempEsc_after.spi");
537 #endif
538 
539  // Adding to the thread temporal imOut
541  dAij(imOut,i,j) += dAij(*imTempP,i,j);
542 
543 #ifdef DEBUG
544 
545  _Im().alias(imOut);
546  _Im.write("projectXR-imout.spi");
547 #endif
548 
550 
551  if (projNorm != nullptr)
552  {
553 
555  A2D_ELEM(imTemp,i,j) = A3D_ELEM(IgeoVol,kini,i,j) * psf.dzo;
556 
557  // IgeoVol.getSlice(kini, imTemp);
558  psf.applyOTF(imTemp, imOutGlobal.Zoff()- psfSlicesIdx[first]*psf.dzo);
559 
561  dAij(projNormTemp,i,j) += dAij(imTemp,i,j)*dAij(imTemp,i,j);
562  }
563 
564 
565  }
566 
567  //Lock to update the total addition and multiply for the pixel width (to avoid multiply several times)
568  mutex.lock();
570  dAij(MULTIDIM_ARRAY(imOutGlobal),i,j) += dAij(imOut,i,j);
571 
572  if (projNorm != nullptr)
573  {
575  dAij(*projNorm,i,j) += dAij(projNormTemp,i,j);
576  }
577  mutex.unlock();
578 #ifdef DEBUG
579 
580  imOutGlobal.write("projectXR-imoutGlobal.spi");
581 #endif
582 
583  barrier->wait();
584 
585  if (thread_id==0)
586  {
587  // The output is the addition of the accumulated differences, the real projection is background illumination minus this
588  // MULTIDIM_ARRAY(imOutGlobal) = 1.0- MULTIDIM_ARRAY(imOutGlobal);
589 
590  switch (psf.AdjustType)
591  {
592  case PSFXR_STD:
593  // Do nothing;
594  break;
595  case PSFXR_INT:
597  break;
598  case PSFXR_ZPAD:
599  MULTIDIM_ARRAY(imOutGlobal).selfWindow(-ROUND(psf.Noy/2)+1,-ROUND(psf.Nox/2)+1,ROUND(psf.Noy/2)-1,ROUND(psf.Nox/2)-1);
600  break;
601  }
602 
603  MULTIDIM_ARRAY(imOutGlobal).setXmippOrigin();
604 
605 #ifdef DEBUG
606 
607  imOutGlobal.write("projectXR-imoutGlobal_negative.spi");
608 #endif
609 
610  }
611  // std::cerr << "th" << thread_id << ": Thread Finished" <<std::endl;
612 
613 #undef DEBUG
614 }
615 
618  MultidimArray<double> &IgeoZb, int nThreads, ThreadManager * ThrMgr)
619 {
620  // Checking sizes
621  if ( (XSIZE(muVol) != XSIZE(IgeoZb)) || (YSIZE(muVol) != YSIZE(IgeoZb)) )
622  REPORT_ERROR(ERR_MULTIDIM_SIZE, "CalculateIgeo: IgeoZb size does not match muVol size.");
623 
624  IgeoVol.initZeros(muVol);
625  cumMu.initZeros(YSIZE(muVol), XSIZE(muVol));
626 
627  ThreadManager * myThMgr;
628 
629  if (ThrMgr == nullptr)
630  myThMgr = new ThreadManager(nThreads);
631  else
632  myThMgr = ThrMgr;
633 
634  CIGTArgument iGeoArgs;
635  iGeoArgs.samplingZ = sampling;
636  iGeoArgs.muVol = &muVol;
637  iGeoArgs.IgeoVol = &IgeoVol;
638  iGeoArgs.cumMu = &cumMu;
639  iGeoArgs.IgeoZb = & IgeoZb;
640  iGeoArgs.td = new ThreadTaskDistributor(YSIZE(muVol),YSIZE(muVol)/nThreads/2);
641 
642  myThMgr->run(calculateIgeoThread,&iGeoArgs);
643 
644  delete iGeoArgs.td;
645 
646  if (ThrMgr == nullptr)
647  delete myThMgr;
648 }
649 
651 {
652  auto *dataThread = (CIGTArgument*) thArg.data;
653 
654  double sampling = dataThread->samplingZ;
655  MultidimArray<double> &muVol = *(dataThread->muVol);
656  MultidimArray<double> &IgeoVol = *(dataThread->IgeoVol);
657  MultidimArray<double> &cumMu = *(dataThread->cumMu);
658  MultidimArray<double> &IgeoZb = *(dataThread->IgeoZb);
659  ParallelTaskDistributor * td = dataThread->td;
660 
661  // Resizing
662  // IgeoVol.resize(muVol, false);
663 
664  size_t first, last;
665  while (td->getTasks(first, last))
666  {
667  // first--;
668  // last--;
669  for (size_t i = first; i <= last; ++i)
670  {
671  // for (int j=0; j<XSIZE(muVol); ++j)
672  // dAkij(IgeoVol,0,i,j) = dAij(IgeoZb,i,j)*exp(-dAkij(muVol,0,i,j)*sampling);
673  //
674  // for (int k = 1; k < ZSIZE(muVol); ++k)
675  // for (int j=0; j<XSIZE(muVol); ++j)
676  // dAkij(IgeoVol,k,i,j) = dAkij(IgeoVol,k-1,i,j)*exp(-dAkij(muVol,k,i,j)*sampling);
677 
678  for (size_t k = 0; k < ZSIZE(muVol); ++k)
679  for (size_t j=0; j<XSIZE(muVol); ++j)
680  {
681  dAij(cumMu,i,j) += dAkij(muVol,k,i,j)*sampling;
682  dAkij(IgeoVol,k,i,j) = dAij(IgeoZb,i,j)*exp(-dAij(cumMu,i,j));
683  }
684  }
685  }
686 }
687 
689  MultidimArray<double> &muVol, // Volume
690  XRayPSF &psf, // Basis
691  MultidimArray<double> &IgeoVol,
692  Projection &proj, // Projection
693  MultidimArray<double> *projNorm, // Projection of a unitary volume
694  int FORW, // 1 if we are projecting a volume
695  // norm_proj is calculated
696  // 0 if we are backprojecting
697  // norm_proj must be valid
698  ThreadManager * thMgr)
699 {
700  XrayThreadArgument projThrData;
701  Barrier barrier(thMgr->threads);
702 
703  projThrData.psf = &psf;
704  projThrData.muVol = &muVol;
705  projThrData.IgeoVol = &IgeoVol;
706  projThrData.projOut = &proj;
707  projThrData.projNorm = projNorm;
708  projThrData.forw = FORW;
709  projThrData.phantomSlabIdx = nullptr;
710  projThrData.psfSlicesIdx = nullptr;
711 
712  // //Create the job handler to distribute thread jobs
713  // size_t blockSize, numberOfJobs = psfSlicesIdx.size() ;
714  // blockSize = 1;
715  // ThreadTaskDistributor td(numberOfJobs, blockSize);
716  // projThrData.td = &td;
717  // projThrData.barrier = &barrier;
718 
719  //the really really final project routine, I swear by Snoopy.
720  // project_xr(psf,side.rotPhantomVol,P, idxSlice);
721 
722  thMgr->run(projectXraySimpleGridThread,(void*) &projThrData);
723 
724 }
725 
727 {
728 
729  int threadId = thArg.thread_id;
730 
731  auto *dataThread = (XrayThreadArgument*) thArg.data;
732  const XRayPSF &psf = *(dataThread->psf);
733  MultidimArray<double> *muVol = (dataThread->muVol);
734  MultidimArray<double> *IgeoVol = (dataThread->IgeoVol);
735  Projection *proj = (dataThread->projOut);
736  MultidimArray<double> &projNorm = *(dataThread->projNorm);
737  int forw = dataThread->forw;
738 
739  projectXraySimpleGrid(muVol, psf, IgeoVol, proj, projNorm , forw,
740  threadId, thArg.threads);
741 
742 
743 
744 
745 }
746 
748  MultidimArray<double> *IgeoVol,
749  Projection *proj, MultidimArray<double> &projNorm , int FORW,
750  int threadId, int numthreads)
751 {
752 
753  MultidimArray<double> psfVol;
754  psfVol.alias(psf.psfVol());
755 
756 
757  Matrix1D<double> zero(3); // Origin (0,0,0)
758  Matrix1D<double> prjPix(3); // Position of the pixel within the projection
759  Matrix1D<double> prjX(3); // Coordinate: Projection of the
760  Matrix1D<double> prjY(3); // 3 grid vectors
761  Matrix1D<double> prjZ(3);
762  Matrix1D<double> prjOrigin(3); // Coordinate: Where in the 2D
763  // projection plane the origin of
764  // the grid projects
765  Matrix1D<double> prjDir(3); // Projection direction
766 
767  Matrix1D<double> actprj(3); // Coord: Actual position inside
768  // the projection plane
769  Matrix1D<double> beginZ(3); // Coord: Plane coordinates of the
770  // projection of the 3D point
771  // (z0,YY(lowest),XX(lowest))
772  Matrix1D<double> univ_beginY(3); // Coord: coordinates of the
773  // grid point
774  // (z0,y0,XX(lowest))
775  Matrix1D<double> univ_beginZ(3); // Coord: coordinates of the
776  // grid point
777  // (z0,YY(lowest),XX(lowest))
778  Matrix1D<double> beginY(3); // Coord: Plane coordinates of the
779  // projection of the 3D point
780  // (z0,y0,XX(lowest))
781  double XX_footprint_size; // The footprint is supposed
782  double YY_footprint_size; // to be defined between
783  // (-vmax,+vmax) in the Y axis,
784  // and (-umax,+umax) in the X axis
785  // This footprint size is the
786  // R2 vector (umax,vmax).
787 
788  int XX_corner2, XX_corner1; // Coord: Corners of the
789  int YY_corner2, YY_corner1; // footprint when it is projected
790  // onto the projection plane
791  // directions respectively
792  // inside the blobprint
793  double vol_corr=0.; // Correction for a volume element
794  int N_eq; // Number of equations in which
795  // a blob is involved
796  int i, j, k; // volume element indexes
797 
798  // Project grid axis ....................................................
799  // These vectors ((1,0,0),(0,1,0),...) are referred to the grid
800  // coord. system and the result is a 2D vector in the image plane
801  // The unit size within the image plane is 1, ie, the same as for
802  // the universal grid.
803  // actprj is reused with a different purpose
804  // VECTOR_R3(actprj, 1, 0, 0);
805  // Uproject_to_plane(actprj, proj->euler, prjX);
806  // VECTOR_R3(actprj, 0, 1, 0);
807  // Uproject_to_plane(actprj, proj->euler, prjY);
808  // VECTOR_R3(actprj, 0, 0, 1);
809  // Uproject_to_plane(actprj, proj->euler, prjZ);
810  proj->euler.getCol(0, prjX);
811  proj->euler.getCol(1, prjY);
812  proj->euler.getCol(2, prjZ);
813 
814  // This time the origin of the grid is in the universal coord system
815  // Uproject_to_plane(grid->origin, proj->euler, prjOrigin);
816  prjOrigin.initZeros();
817 
818  // Get the projection direction .........................................
819  proj->euler.getRow(2, prjDir);
820 
821  // Footprint size .......................................................
822  // The following vectors are integer valued vectors, but they are
823  // stored as real ones to make easier operations with other vectors
824  XX_footprint_size = FINISHINGX(psfVol) + XMIPP_EQUAL_ACCURACY;
825  YY_footprint_size = FINISHINGY(psfVol) + XMIPP_EQUAL_ACCURACY;
826 
827  // Project the whole grid ...............................................
828  // Corner of the plane defined by Z. These coordinates try to be within
829  // the valid indexes of the projection (defined between STARTING and
830  // FINISHING values, but it could be that they may lie outside.
831  // These coordinates need not to be integer, in general, they are
832  // real vectors.
833  // The vectors returned by the projection routines are R3 but we
834  // are only interested in their first 2 components, ie, in the
835  // in-plane components
836 
837  // This type conversion gives more speed
838 
839  int ZZ_lowest = STARTINGZ(*vol);
840  if( threadId != -1 )
841  ZZ_lowest += threadId;
842  int YY_lowest = STARTINGY(*vol);
843  int XX_lowest = STARTINGX(*vol);
844  int ZZ_highest = FINISHINGZ(*vol);
845  int YY_highest = FINISHINGY(*vol);
846  int XX_highest = FINISHINGX(*vol);
847 
848  beginZ = (double)XX_lowest * prjX + (double)YY_lowest * prjY + (double)ZZ_lowest * prjZ + prjOrigin;
849 
850 
851 #ifdef DEBUG_LITTLE
852 
853  int condition;
854  condition = threadId==1;
855  if (condition || numthreads==1)
856  {
857  std::cout << "Equation mode " << eq_mode << std::endl;
858  std::cout << "Footprint size " << YY_footprint_size << "x"
859  << XX_footprint_size << std::endl;
860  std::cout << "rot=" << proj->rot() << " tilt=" << proj->tilt()
861  << " psi=" << proj->psi() << std::endl;
862  std::cout << "Euler matrix " << proj->euler;
863  std::cout << "Projection direction " << prjDir << std::endl;
864  std::cout << *grid;
865  std::cout << "image limits (" << x0 << "," << y0 << ") (" << xF << ","
866  << yF << ")\n";
867  std::cout << "prjX " << prjX.transpose() << std::endl;
868  std::cout << "prjY " << prjY.transpose() << std::endl;
869  std::cout << "prjZ " << prjZ.transpose() << std::endl;
870  std::cout << "prjOrigin " << prjOrigin.transpose() << std::endl;
871  std::cout << "beginZ(coord) " << beginZ.transpose() << std::endl;
872  std::cout << "lowest " << XX_lowest << " " << YY_lowest
873  << " " << XX_lowest << std::endl;
874  std::cout << "highest " << XX_highest << " " << YY_highest
875  << " " << XX_highest << std::endl;
876  std::cout << "Stats of input basis volume ";
877  (*vol)().printStats();
878  std::cout << std::endl;
879  std::cout.flush();
880  }
881 #endif
882 
883  for (k = ZZ_lowest; k <= ZZ_highest; k += numthreads)
884  {
885  // Corner of the row defined by Y
886  beginY = beginZ;
887  for (i = YY_lowest; i <= YY_highest; i++)
888  {
889  // First point in the row
890  actprj = beginY;
891  for (j = XX_lowest; j <= XX_highest; j++)
892  {
893  // Ray length interesting
894  bool ray_length_interesting = true;
895 
896  // // Points out of 3DPSF
897  // ray_length_interesting = (ABS(zCenterDist) <= ZZ_footprint_size);
898  // // There is still missing the shift of the volume from focal plane
899 
900  if (ray_length_interesting)
901  {
902  // Be careful that you cannot skip any basis, although its
903  // value be 0, because it is useful for norm_proj
904 #ifdef DEBUG
905  condition = threadId == 1;
906  if (condition)
907  {
908  printf("\nProjecting grid coord (%d,%d,%d) ", j, i, k);
909  std::cout << "Vol there = " << A3D_ELEM(*vol, k, i, j) << std::endl;
910  printf(" 3D universal position (%f,%f,%f) \n",
911  XX(univ_position), YY(univ_position), ZZ(univ_position));
912  std::cout << " Center of the basis proj (2D) " << XX(actprj) << "," << YY(actprj) << std::endl;
913  Matrix1D<double> aux;
914  Uproject_to_plane(univ_position, proj->euler, aux);
915  std::cout << " Center of the basis proj (more accurate) " << aux.transpose() << std::endl;
916  }
917 #endif
918 
919  // Search for integer corners for this basis
920  XX_corner1 = CEIL(XMIPP_MAX(STARTINGX(IMGMATRIX(*proj)), XX(actprj) - XX_footprint_size));
921  YY_corner1 = CEIL(XMIPP_MAX(STARTINGY(IMGMATRIX(*proj)), YY(actprj) - YY_footprint_size));
922  XX_corner2 = FLOOR(XMIPP_MIN(FINISHINGX(IMGMATRIX(*proj)), XX(actprj) + XX_footprint_size));
923  YY_corner2 = FLOOR(XMIPP_MIN(FINISHINGY(IMGMATRIX(*proj)), YY(actprj) + YY_footprint_size));
924 
925 #ifdef DEBUG
926 
927  if (condition)
928  {
929  std::cout << "Clipped and rounded Corner 1 " << XX_corner1
930  << " " << YY_corner1 << " " << std::endl;
931  std::cout << "Clipped and rounded Corner 2 " << XX_corner2
932  << " " << YY_corner2 << " " << std::endl;
933  }
934 #endif
935 
936  // Check if the voxel falls outside the projection plane
937  // COSS: I have changed here
938  if (XX_corner1 <= XX_corner2 && YY_corner1 <= YY_corner2
939  && INSIDEZ(*IgeoVol,ZZ(actprj)))
940  {
941 
942  double IgeoValue = A3D_ELEM(*IgeoVol, (int)ZZ(actprj), (int)YY(actprj), (int)XX(actprj));
943 
944  if (!FORW)
945  vol_corr = 0;
946 
947  N_eq = 0;
948  for (int y = YY_corner1; y <= YY_corner2; y++)
949  {
950  for (int x = XX_corner1; x <= XX_corner2; x++)
951  {
952  // if (!((mask != NULL) && A2D_ELEM(*mask,y,x)<0.5))
953  {
954 #ifdef DEBUG
955  if (condition)
956  {
957  std::cout << "Position in projection (" << x << ","
958  << y << ") ";
959  double y, x;
960  if (basis->type == Basis::blobs)
961  {
962  std::cout << "in footprint ("
963  << foot_U << "," << foot_V << ")";
964  IMG2OVER(basis->blobprint, foot_V, foot_U, y, x);
965  std::cout << " (d= " << sqrt(y*y + x*x) << ") ";
966  fflush(stdout);
967  }
968  }
969 #endif
970 
971  double a, a2;
972 
973  a = A3D_ELEM(psfVol, (int)ZZ(actprj), y, x) * IgeoValue;
974  a2 = a * a;
975 
976 #ifdef DEBUG
977 
978  if (condition)
979  std::cout << "=" << a << " , " << a2;
980 #endif
981 
982  if (FORW)
983  {
985  IMGPIXEL(*proj, y, x) += A3D_ELEM(*vol, k, i, j) * a;
986  A2D_ELEM(projNorm , y, x) += a2;
987 
988 #ifdef DEBUG
989 
990  if (condition)
991  {
992  std::cout << " proj= " << IMGPIXEL(*proj, y, x)
993  << " norm_proj=" << A2D_ELEM(projNorm , y, x) << std::endl;
994  std::cout.flush();
995  }
996 #endif
997 
998  }
999  else
1000  {
1001  vol_corr += A2D_ELEM(projNorm , y, x) * a;
1002  if (a != 0)
1003  N_eq++;
1004 #ifdef DEBUG
1005 
1006  if (condition)
1007  {
1008  std::cout << " corr_img= " << A2D_ELEM(projNorm , y, x)
1009  << " correction=" << vol_corr << std::endl;
1010  std::cout.flush();
1011  }
1012 #endif
1013 
1014  }
1015  }// close possible mask constraint
1016  }
1017  } // Project this basis
1018 
1019  if (!FORW)
1020  {
1021  A3D_ELEM(*vol, k, i, j) += vol_corr;
1022 
1023 #ifdef DEBUG
1024 
1025  if (condition)
1026  {
1027  printf("\nFinal value at (%d,%d,%d) ", j, i, k);
1028  std::cout << " = " << A3D_ELEM(*vol, k, i, j) << std::endl;
1029  std::cout.flush();
1030  }
1031 #endif
1032 
1033  }
1034  } // If not collapsed
1035  // number_of_basis++;
1036  } // If interesting
1037 
1038  // Prepare for next iteration
1039  V3_PLUS_V3(actprj, actprj, prjX);
1040  }
1041  V3_PLUS_V3(beginY, beginY, prjY);
1042  }
1043  V3_PLUS_V3(beginZ, beginZ, prjZ * numthreads );
1044  }
1045 }
1046 
1047 
void run(ThreadFunction function, void *data=NULL)
bool only_create_angles
Only create angles, do not project.
Definition: projection.h:81
void threadXrayProject(ThreadArgument &thArg)
Generate an X-ray microscope projection for volume vol using the microscope configuration psf...
void init_progress_bar(long total)
void defineParams(XmippProgram *program)
Definition: projection.cpp:74
Mutex mutex
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
double Npixel_dev
Standard deviation of the noise to be added to each pixel grey value.
Definition: projection.h:101
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
Tilting angle of an image (double,degrees)
FileName fnOut
Output filename (used for a singleProjection)
Definition: projection.h:67
ParametersProjectionTomography projParam
Definition: project_xray.h:93
double getDoubleParam(const char *param, int arg=0)
virtual void read(int argc, const char **argv, bool reportErrors=true)
virtual void run()
double samplingZ
Definition: project_xray.h:158
Projection stdProj
Definition: project_xray.h:106
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double psi(const size_t n=0) const
void projectXraySimpleGridThread(ThreadArgument &thArg)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
Data struct to be passed to threads.
Definition: project_xray.h:41
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
double Zoff(const size_t n=0) const
ThreadManager * thMgr
void resizeNoCopy(const MultidimArray< T1 > &v)
#define dAij(M, i, j)
void applyOTF(MultidimArray< double > &Im, const double sliceOffset) const
Apply the OTF to the image, by means of the convolution.
Definition: psf_xr.cpp:384
MultidimArray< double > * IgeoVol
Definition: project_xray.h:45
double tilt0
Minimum tilt around this axis.
Definition: projection.h:92
void sqrt(Image< double > &op)
Tilting angle of an image (double,degrees)
static double * y
virtual void defineParams()
Shift for the image in the X axis (double)
FileName insertBeforeExtension(const String &str) const
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
bool getTasks(size_t &first, size_t &last)
Matrix2D< double > euler
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
int threads
number of working threads.
#define MULTIDIM_ARRAY(v)
void projectXrayVolume(MultidimArray< double > &muVol, MultidimArray< double > &IgeoVol, XRayPSF &psf, Projection &P, MultidimArray< double > *projNorm, ThreadManager *thMgr)
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.
void initConstant(T val)
void readParams(XmippProgram *program)
Definition: projection.cpp:97
Image< double > iniVol
Phantom Xmipp volume.
Definition: project_xray.h:65
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
Image< double > psfVol
3D PSF read from file
Definition: psf_xr.h:123
void setFocalShift(double zShift)
Add focal shift to previously read psf zshift.
Definition: psf_xr.cpp:273
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
double rot(const size_t n=0) const
#define FINISHINGZ(v)
ParallelTaskDistributor * td
Definition: project_xray.h:52
MultidimArray< double > * projNorm
Definition: project_xray.h:48
#define IMGMATRIX(I)
int nThr
Definition: psf_xr.h:215
#define STARTINGX(v)
double dxo
object space XY-plane sampling rate
Definition: psf_xr.h:197
double tiltF
Maximum tilt around this axis.
Definition: projection.h:94
doublereal * x
#define i
void selfScaleToSize(int SplineDegree, MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
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
virtual void setComment(const String &newComment="No comment")
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
void addSeeAlsoLine(const char *seeAlso)
double tilt(const size_t n=0) const
std::vector< int > * phantomSlabIdx
Definition: project_xray.h:50
#define STARTINGY(v)
std::vector< int > * psfSlicesIdx
Definition: project_xray.h:51
Matrix1D< double > raxis
Offset of the tilt axis.
Definition: projection.h:90
#define A3D_ELEM(V, k, i, j)
MetaDataVec projMD
Definition: project_xray.h:107
Rotation angle of an image (double,degrees)
Standard mode, image size does not changes.
Definition: psf_xr.h:44
void projectXrayGridVolume(MultidimArray< double > &muVol, XRayPSF &psf, MultidimArray< double > &IgeoVol, Projection &proj, MultidimArray< double > *projNorm, int FORW, ThreadManager *thMgr)
Project as in an X-ray microscope using a grids and blobs.
glob_log first
Barrier * barrier
double Npixel_avg
Bias to be applied to each pixel grey value */.
Definition: projection.h:99
int proj_Ydim
Projection Ydim.
Definition: projection.h:78
#define FLOOR(x)
Definition: xmipp_macros.h:240
FileName fn_psf_xr
Filename with the Microscope Parameters.
Definition: project_xray.h:91
void window(MultidimArray< T1 > &result, int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T1 init_value=0) const
#define y0
const char * getParam(const char *param, int arg=0)
#define x0
std::vector< int > slabIndex
Z positions in the original PSF Volume to determine de slabs.
Definition: psf_xr.h:131
#define XX(v)
Definition: matrix1d.h:85
void wait()
ParallelTaskDistributor * td
Intensity in the beginning of the volume to project.
Definition: project_xray.h:163
void read(const FileName &fn, bool readVolume=true)
Definition: psf_xr.cpp:82
bool save_std_projs
Save standard projections.
Definition: project_xray.h:103
template void translation3DMatrix(const Matrix1D< float > &translation, Matrix2D< float > &resMatrix, bool inverse)
ParallelTaskDistributor * td
Definition: project_xray.h:108
double Ncenter_avg
Bias to apply to the image center.
Definition: projection.h:104
bool setValue(const MDObject &mdValueIn, size_t id)
#define CEIL(x)
Definition: xmipp_macros.h:225
size_t addObject() override
double Ncenter_dev
Standard deviation of the image center.
Definition: projection.h:106
size_t Nix
Size of the image in image plane, to be rescaled if needed.
Definition: psf_xr.h:203
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
double psfThr
threshold for psfSlabs
Definition: project_xray.h:97
#define IMG2OVER(IO, iv, iu, v, u)
#define sampling
#define XSIZE(v)
void progress_bar(long rlen)
Projection * projOut
Definition: project_xray.h:47
void getEulerAngles(double &rot, double &tilt, double &psi, const size_t n=0) const
void projectXraySimpleGrid(MultidimArray< double > *vol, const XRayPSF &psf, MultidimArray< double > *IgeoVol, Projection *proj, MultidimArray< double > &projNorm, int FORW, int threadId, int numthreads)
#define dAkij(V, k, i, j)
int threads
Number of threads.
MultidimArray< double > * muVol
Definition: project_xray.h:159
#define ZSIZE(v)
void addExampleLine(const char *example, bool verbatim=true)
virtual void readParams()
double Nangle_dev
Standard deviation of the angles.
Definition: projection.h:111
#define ROUND(x)
Definition: xmipp_macros.h:210
int verbose
Switch to control verbose mode.
Definition: psf_xr.h:212
double slabThr
Threshold to separate The volume into slabs to use the same PSF.
Definition: psf_xr.h:129
void calculateIgeoThread(ThreadArgument &thArg)
#define XMIPP_EQUAL_ZERO(x)
Definition: xmipp_macros.h:123
int verbose
Verbosity level.
int proj_Xdim
Projection Xdim.
Definition: projection.h:76
Projection proj
Definition: project_xray.h:106
void alias(const MultidimArray< T > &m)
#define xF
void calculateProjectionAngles(Projection &P, double angle, double inplaneRot, const Matrix1D< double > &sinplane)
Definition: projection.cpp:277
void initZeros()
Definition: matrix1d.h:592
void calculateParams(double _dxo, double _dzo=-1, double threshold=0.)
Produce Side information.
Definition: psf_xr.cpp:279
Psi angle of an image (double,degrees)
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
FileName fnRoot
Root filename (used for a stack)
Definition: projection.h:65
void setDimensions(int Xdim, int Ydim, int Zdim, size_t Ndim)
#define j
void scaleToSize(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
XrayProjPhantom phantom
Definition: project_xray.h:105
#define YY(v)
Definition: matrix1d.h:93
void getCol(size_t j, Matrix1D< T > &v) const
Definition: matrix2d.cpp:890
MultidimArray< double > * IgeoVol
Accumulated Mu == Standard EM projection used as reference for reconstruction.
Definition: project_xray.h:161
int nThr
Number of threads;.
Definition: project_xray.h:101
void adjustParam()
Calculate if a resize of the X-Y plane is needed to avoid the Nyquist Limit.
Definition: psf_xr.cpp:673
size_t Niy
Definition: psf_xr.h:204
void setEulerAngles(double rot, double tilt, double psi, const size_t n=0)
#define FINISHINGY(v)
size_t Nox
X size of the input image (object plane size)
Definition: psf_xr.h:152
void read(const ParametersProjectionTomography &prm)
Increasing the image size by Interpolating.
Definition: psf_xr.h:45
MultidimArray< double > * muVol
Definition: project_xray.h:44
bool singleProjection
Only project a single image.
Definition: projection.h:69
double psi(const double x)
double rnd_gaus()
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
#define ALL_IMAGES
double dzo
object space Z sampling rate
Definition: psf_xr.h:201
int thread_id
The thread id.
virtual void unlock()
double dzoPSF
object space Z sampling rate of the PSF Volume
Definition: psf_xr.h:209
bool checkParam(const char *param)
#define FIRST_IMAGE
ProgClassifyCL2D * prm
MultidimArray< double > * IgeoZb
Igeo accumulated along Z axis.
Definition: project_xray.h:162
PsfxrAdjust AdjustType
Parameters to change image size to avoid Nyquist limit.
Definition: psf_xr.h:171
double tiltStep
Step in tilt.
Definition: projection.h:96
MultidimArray< double > * cumMu
Phantom volume.
Definition: project_xray.h:160
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
unsigned int randomize_random_generator()
MultidimArray< double > rotVol
Definition: project_xray.h:66
void calculateIgeo(MultidimArray< double > &muVol, double sampling, MultidimArray< double > &IgeoVol, MultidimArray< double > &cumMu, MultidimArray< double > &IgeoZb, int nThreads, ThreadManager *ThrMgr)
Calculate the volume of the information of Igeometric at each plane of the phantom.
int getIntParam(const char *param, int arg=0)
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
void Uproject_to_plane(const Matrix1D< double > &point, const Matrix1D< double > &direction, double distance, Matrix1D< double > &result)
Definition: geometry.cpp:39
#define yF
#define STARTINGZ(v)
Name of an image (std::string)
#define ZZ(v)
Definition: matrix1d.h:101
size_t Noy
Y size of the input image (object plane size)
Definition: psf_xr.h:154
doublereal * a
void addParamsLine(const String &line)
double Nangle_avg
Bias to apply to the angles.
Definition: projection.h:109
ql0001_ & zero(ctemp+1),(cvec+1),(a+1),(b+1),(bl+1),(bu+1),(x+1),(w+1), &iout, ifail, &zero,(w+3), &lwar2,(iw+1), &leniw, &glob_grd.epsmac
virtual void lock()
#define V3_PLUS_V3(a, b, c)
Definition: matrix1d.h:190
#define IMGPIXEL(I, i, j)
void getShifts(double &xoff, double &yoff, double &zoff, const size_t n=0) const
#define INSIDEZ(v, z)