Xmipp  v3.23.11-Nereus
phantom.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
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 //Fri Nov 19 13:22:15 EST 1999 subsampling strategy modified (R.Marabini)
26 /* ------------------------------------------------------------------------- */
27 /* PHANTOMS */
28 /* ------------------------------------------------------------------------- */
29 
30 #include "phantom.h"
31 #include "core/geometry.h"
32 #include "core/metadata_label.h"
33 #include "core/metadata_vec.h"
34 #include "core/xmipp_error.h"
35 #include "data/blobs.h"
37 
38 /* ######################################################################### */
39 /* Features */
40 /* ######################################################################### */
41 /* ------------------------------------------------------------------------- */
42 /* Prepare */
43 /* ------------------------------------------------------------------------- */
45 {
47 }
48 
50 {
52 }
53 
55 {
56  max_distance = 4*sigma;
57 }
58 
60 {
61  prepare_Euler();
62  max_distance = sqrt(height * height / 4 + XMIPP_MAX(xradius * xradius, yradius * yradius));
63 }
64 
66 {
67  prepare_Euler();
68  max_distance = sqrt((height + separation) * (height + separation) / 4 + radius * radius);
69 }
70 
72 {
73  prepare_Euler();
74  max_distance = sqrt(xdim * xdim + ydim * ydim + zdim * zdim);
75 }
76 
78 {
79  prepare_Euler();
80  max_distance = XMIPP_MAX(XMIPP_MAX(xradius, yradius), zradius);
81 }
82 
84 {
85  prepare_Euler();
86  max_distance = sqrt(height * height / 4 + radius * radius);
87 }
88 
89 /* ------------------------------------------------------------------------- */
90 /* Assignment */
91 /* ------------------------------------------------------------------------- */
92 void Feature::assign(const Feature &F)
93 {
94  *this = F;
95 }
96 
98 {
99  *this = OF;
100 }
101 
103 {
104  Euler_angles2matrix(rot, tilt, psi, euler);
105  eulert = euler.transpose();
106 }
107 
108 void Sphere::assign(const Sphere &F)
109 {
110  *this = F;
111 }
112 
113 void Blob::assign(const Blob &F)
114 {
115  *this = F;
116 }
117 
119 {
120  *this = F;
121 }
122 
124 {
125  *this = F;
126 }
127 
129 {
130  *this = F;
131 }
132 
133 void Cube::assign(const Cube &F)
134 {
135  *this = F;
136 }
137 
139 {
140  *this = F;
141 }
142 
143 void Cone::assign(const Cone &F)
144 {
145  *this = F;
146 }
147 
148 /* ------------------------------------------------------------------------- */
149 /* Rotation */
150 /* ------------------------------------------------------------------------- */
152 {
153  Matrix2D<double> inverse_angles_matrix;
154  inverse_angles_matrix = E.inv();
155  center = inverse_angles_matrix * center;
156  //center=E*center;
157 }
158 
160 {
161  rotate_center(E);
162 }
163 
165 {
166  rotate_center(E);
167  prepare();
168  euler = euler * E;
169  eulert = E.transpose() * eulert;
170  Euler_matrix2angles(euler, rot, tilt, psi);
171 }
172 
173 /* ------------------------------------------------------------------------- */
174 /* I/O functions */
175 /* ------------------------------------------------------------------------- */
176 /* Read common part of features -------------------------------------------- */
177 void Feature::readCommon(char *line)
178 {
179  int stat;
180  char straux[6];
181  center.resize(3);
182  stat = sscanf(line, "%s %c %lf %lf %lf %lf",
183  straux,
184  &add_assign,
185  &density,
186  &(XX(center)),
187  &(YY(center)),
188  &(ZZ(center)));
189  if (stat != 6)
191  (std::string)"Error when reading common part of feature: " + line);
192  type = straux;
193 }
194 
195 // Read the common parameters for a feature
197 {
198  center.resize(3);
199  std::vector <double> VecFeatureCenter; // Keep the center of the feature
200  std::string s_op; // As no label for char in MD_TYPE (for add/assign)
204  !row.getValue(MDL_PHANTOM_FEATURE_CENTER,VecFeatureCenter))
205  REPORT_ERROR(ERR_ARG_MISSING, (std::string)"Error when reading common part of feature");
206  XX(center) = VecFeatureCenter[0];
207  YY(center) = VecFeatureCenter[1];
208  ZZ(center) = VecFeatureCenter[2];
209  add_assign = s_op[0];
210 }
211 
212 // Read all the related parameters of the feature
213 void Feature::read(MDRow & row)
214 {
215  readCommon(row);
216  std::vector<double> VectSpecific; // Vector for specific parameters of feature
217  row.getValue(MDL_PHANTOM_FEATURE_SPECIFIC, VectSpecific);
218  read_specific(VectSpecific);
219 }
220 
221 /* Read a sphere ----------------------------------------------------------- */
222 void Sphere::read_specific(char *line)
223 {
224  int stat;
225  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf", &radius);
226  if (stat != 1)
227  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a sphere:" + line);
228  prepare();
229 }
230 /* Read a sphere from MetaData -------------------------------------------- */
231 void Sphere::read_specific(const std::vector<double> &vect)
232 {
233  if (vect.size() != 1)
234  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_PHANTOM_FEATURE_SPECIFIC) + "Error when reading a sphere: empty Feature vector");
235  radius = vect[0];
236  prepare();
237 }
238 /* Read a blob ----------------------------------------------------------- */
239 void Blob::read_specific(char *line)
240 {
241  int stat;
242  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %d", &radius, &alpha, &m);
243  if (stat != 3)
244  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a blob:" + line);
245  prepare();
246 }
247 /* Read a Blob from MetaData --------------------------------------------- */
248 void Blob::read_specific(const std::vector<double> &vect)
249 {
250  if (vect.size() != 3)
252  radius = vect[0];
253  alpha = vect[1];
254  m = (int)vect[2];
255  prepare();
256 }
257 
258 double Blob::volume() const
259 {
260  return basvolume(radius, alpha, m, 3);
261 }
262 
263 /* Read a Gaussian --------------------------------------------------------- */
264 void Gaussian::read_specific(char *line)
265 {
266  int stat;
267  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf", &sigma);
268  if (stat != 1)
269  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a Gaussian:" + line);
270  prepare();
271 }
272 
273 /* Read a Gaussian from MetaData --------------------------------------------- */
274 void Gaussian::read_specific(const std::vector<double> &vect)
275 {
276  if (vect.size() != 1)
277  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_PHANTOM_FEATURE_SPECIFIC) + "Error when reading a Gaussian");
278  sigma = vect[0];
279  prepare();
280 }
281 
282 /* Read a Cylinder --------------------------------------------------------- */
283 void Cylinder::read_specific(char *line)
284 {
285  int stat;
286  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %lf %lf %lf %lf", &xradius,
287  &yradius, &height, &rot, &tilt, &psi);
288  if (stat != 6)
289  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a cylinder:" + line);
290  prepare();
291 }
292 
293 /* Read a Cylinder from MetaData --------------------------------------------- */
294 void Cylinder::read_specific(const std::vector<double> &vect)
295 {
296  if (vect.size() != 6)
297  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_PHANTOM_FEATURE_SPECIFIC) + "Error when reading a cylinder");
298  xradius = vect[0];
299  yradius = vect[1];
300  height = vect[2];
301  rot = vect[3];
302  tilt = vect[4];
303  psi = vect[5];
304  prepare();
305 }
306 
307 /* Read a Double Cylinder -------------------------------------------------- */
308 void DCylinder::read_specific(char *line)
309 {
310  int stat;
311  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %lf %lf %lf %lf",
312  &radius, &height, &separation, &rot, &tilt, &psi);
313  if (stat != 6)
314  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a double cylinder:" + line);
315  prepare();
316 }
317 
318 /* Read a DCylinder from MetaData ------------------------------------------- */
319 void DCylinder::read_specific(const std::vector<double> &vect)
320 {
321  if (vect.size() != 6)
322  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_PHANTOM_FEATURE_SPECIFIC) + "Error when reading a double cylinder");
323  radius = vect[0];
324  height = vect[1];
325  separation = vect[2];
326  rot = vect[3];
327  tilt = vect[4];
328  psi = vect[5];
329  prepare();
330 }
331 /* Read a Cube ------------------------------------------------------------- */
332 void Cube::read_specific(char *line)
333 {
334  int stat;
335  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %lf %lf %lf %lf",
336  &xdim, &ydim, &zdim, &rot, &tilt, &psi);
337  if (stat != 6)
338  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a cube" + line);
339  prepare();
340 }
341 
342 /* Read a Cube from MetaData ---------------------------------------------- */
343 void Cube::read_specific(const std::vector<double> &vect)
344 {
345  if (vect.size() != 6)
346  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a cube");
347  xdim = vect[0];
348  ydim = vect[1];
349  zdim = vect[2];
350  rot = vect[3];
351  tilt = vect[4];
352  psi = vect[5];
353  prepare();
354 }
355 
356 /* Read an Ellipsoid ------------------------------------------------------- */
357 void Ellipsoid::read_specific(char *line)
358 {
359  int stat;
360  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %lf %lf %lf %lf",
361  &xradius, &yradius, &zradius, &rot, &tilt, &psi);
362  if (stat != 6)
363  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading an ellipsoid" + line);
364  prepare();
365 }
366 
367 /* Read a Ellipsoid from MetaData ---------------------------------------------- */
368 void Ellipsoid::read_specific(const std::vector<double> &vect)
369 {
370  if (vect.size() != 6)
371  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a ellipsoid");
372  xradius = vect[0];
373  yradius = vect[1];
374  zradius = vect[2];
375  rot = vect[3];
376  tilt = vect[4];
377  psi = vect[5];
378  prepare();
379 }
380 
381 /* Read a Cone ------------------------------------------------------------- */
382 void Cone::read_specific(char *line)
383 {
384  int stat;
385  stat = sscanf(line, "%*s %*c %*f %*f %*f %*f %lf %lf %lf %lf %lf", &radius, &height,
386  &rot, &tilt, &psi);
387  if (stat != 5)
388  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a cone" + line);
389  prepare();
390 }
391 
392 /* Read a Cone from MetaData ---------------------------------------------- */
393 void Cone::read_specific(const std::vector<double> &vect)
394 {
395  if (vect.size() != 5)
396  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Error when reading a cone");
397  radius = vect[0];
398  height = vect[1];
399  rot = vect[2];
400  tilt = vect[3];
401  psi = vect[4];
402  prepare();
403 }
404 /* Show an sphere ---------------------------------------------------------- */
405 void Sphere::feat_printf(FILE *fh) const
406 {
407  fprintf(fh, "sph %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f\n",
409  radius);
410 }
411 
412 /* Write specific parameters of a Sphere in MetaData ---------------------- */
413 void Sphere::feat_printm(MetaData &MD, size_t id)
414 {
415  std::vector<double> FSVect;
416  FSVect.push_back(radius);
417  MD.setValue(MDL_PHANTOM_FEATURE_SPECIFIC,FSVect, id);
418 }
419 
420 /* Show a Blob ---------------------------------------------------------- */
421 void Blob::feat_printf(FILE *fh) const
422 {
423  fprintf(fh, "blo %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f"
424  " % 7.2f %1d\n",
426  radius, alpha, m);
427 }
428 
429 /* Write specific parameters of a Blob in MetaData ---------------------- */
430 void Blob::feat_printm(MetaData &MD, size_t id)
431 {
432  std::vector<double> FSVect;
433  FSVect.push_back(radius);
434  FSVect.push_back(alpha);
435  FSVect.push_back(m);
437 }
438 
439 /* Show a Gaussian --------------------------------------------------------- */
440 void Gaussian::feat_printf(FILE *fh) const
441 {
442  fprintf(fh, "blo %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f\n",
444  sigma);
445 }
446 
447 /* Write specific parameters of a Gaussian in MetaData ---------------------- */
448 void Gaussian::feat_printm(MetaData &MD, size_t id)
449 {
450  std::vector<double> FSVect;
451  FSVect.push_back(sigma);
453 }
454 
455 /* Show a cylinder --------------------------------------------------------- */
456 void Cylinder::feat_printf(FILE *fh) const
457 {
458  fprintf(fh, "cyl %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f "
459  "% 7.2f % 7.2f % 7.2f % 7.2f % 7.2f\n",
461  xradius, yradius, height,
462  rot, tilt, psi);
463 }
464 
465 /* Write specific parameters of a Cylinder in MetaData ---------------------- */
466 void Cylinder::feat_printm(MetaData &MD, size_t id)
467 {
468  std::vector<double> FSVect;
469  FSVect.push_back(xradius);
470  FSVect.push_back(yradius);
471  FSVect.push_back(height);
472  FSVect.push_back(rot);
473  FSVect.push_back(tilt);
474  FSVect.push_back(psi);
476 }
477 /* Show a double cylinder -------------------------------------------------- */
478 void DCylinder::feat_printf(FILE *fh) const
479 {
480  fprintf(fh, "dcy %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f "
481  "% 7.2f % 7.2f % 7.2f % 7.2f % 7.2f\n",
483  radius, height, separation,
484  rot, tilt, psi);
485 }
486 
487 /* Write specific parameters of a DCylinder in MetaData ---------------------- */
488 void DCylinder::feat_printm(MetaData &MD, size_t id)
489 {
490  std::vector<double> FSVect;
491  FSVect.push_back(radius);
492  FSVect.push_back(height);
493  FSVect.push_back(separation);
494  FSVect.push_back(rot);
495  FSVect.push_back(tilt);
496  FSVect.push_back(psi);
498 }
499 /* Show a cube ------------------------------------------------------------- */
500 void Cube::feat_printf(FILE *fh) const
501 {
502  fprintf(fh, "cub %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f "
503  "% 7.2f % 7.2f % 7.2f % 7.2f % 7.2f\n",
505  xdim, ydim, zdim,
506  rot, tilt, psi);
507 }
508 
509 /* Write specific parameters of a Cube in MetaData ---------------------- */
510 void Cube::feat_printm(MetaData &MD, size_t id)
511 {
512  std::vector<double> FSVect;
513  FSVect.push_back(xdim);
514  FSVect.push_back(ydim);
515  FSVect.push_back(zdim);
516  FSVect.push_back(rot);
517  FSVect.push_back(tilt);
518  FSVect.push_back(psi);
520 }
521 
522 /* Show an ellipsoid ------------------------------------------------------- */
523 void Ellipsoid::feat_printf(FILE *fh) const
524 {
525  fprintf(fh, "ell %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f "
526  "% 7.2f % 7.2f % 7.2f % 7.2f % 7.2f\n",
528  xradius, yradius, zradius,
529  rot, tilt, psi);
530 }
531 
532 /* Write specific parameters of a Ellipsoid in MetaData ---------------------- */
533 void Ellipsoid::feat_printm(MetaData &MD, size_t id)
534 {
535  std::vector<double> FSVect;
536  FSVect.push_back(xradius);
537  FSVect.push_back(yradius);
538  FSVect.push_back(zradius);
539  FSVect.push_back(rot);
540  FSVect.push_back(tilt);
541  FSVect.push_back(psi);
543 }
544 
545 /* Show a cone ------------------------------------------------------------- */
546 void Cone::feat_printf(FILE *fh) const
547 {
548  fprintf(fh, "con %c %1.4f % 7.2f % 7.2f % 7.2f % 7.2f "
549  "% 7.2f % 7.2f % 7.2f % 7.2f\n",
551  radius, height,
552  rot, tilt, psi);
553 }
554 
555 /* Write specific parameters of a Cone in MetaData ---------------------- */
556 void Cone::feat_printm(MetaData &MD, size_t id)
557 {
558  std::vector<double> FSVect;
559  FSVect.push_back(radius);
560  FSVect.push_back(height);
561  FSVect.push_back(rot);
562  FSVect.push_back(tilt);
563  FSVect.push_back(psi);
565 }
566 
567 
568 /* Show feat --------------------------------------------------------------- */
569 std::ostream& operator << (std::ostream &o, const Feature *F)
570 {
571  if (F != nullptr)
572  {
573  o << "Feature --------" << std::endl;
574  o << " type: " << F->type << std::endl;
575  o << " add_assign: " << F->add_assign << std::endl;
576  o << " density: " << F->density << std::endl;
577  o << " center: " << F->center.transpose() << std::endl;
578  if (F->type == "sph")
579  o << *((Sphere *) F);
580  else if (F->type == "blo")
581  o << *((Blob *) F);
582  else if (F->type == "gau")
583  o << *((Gaussian *) F);
584  else if (F->type == "cyl")
585  o << *((Cylinder *) F);
586  else if (F->type == "dcy")
587  o << *((DCylinder *) F);
588  else if (F->type == "cub")
589  o << *((Cube *) F);
590  else if (F->type == "ell")
591  o << *((Ellipsoid *) F);
592  else if (F->type == "con")
593  o << *((Cone *) F);
594  }
595  return o;
596 }
597 
598 /* Show sphere ------------------------------------------------------------- */
599 std::ostream& operator << (std::ostream &o, const Sphere &f)
600 {
601  o << " Radius: " << f.radius << std::endl;
602  return o;
603 }
604 
605 /* Show Blob ------------------------------------------------------------- */
606 std::ostream& operator << (std::ostream &o, const Blob &f)
607 {
608  o << " Radius: " << f.radius << std::endl;
609  o << " Alpha: " << f.alpha << std::endl;
610  o << " m: " << f.m << std::endl;
611  return o;
612 }
613 
614 /* Show Gaussian ----------------------------------------------------------- */
615 std::ostream& operator << (std::ostream &o, const Gaussian &f)
616 {
617  o << " Sigma: " << f.sigma << std::endl;
618  return o;
619 }
620 
621 /* Show cylinder ----------------------------------------------------------- */
622 std::ostream& operator << (std::ostream &o, const Cylinder &f)
623 {
624  o << " XRadius: " << f.xradius << std::endl;
625  o << " YRadius: " << f.yradius << std::endl;
626  o << " Height: " << f.height << std::endl;
627  o << " Rot: " << f.rot << std::endl;
628  o << " Tilt: " << f.tilt << std::endl;
629  o << " Psi: " << f.psi << std::endl;
630  return o;
631 }
632 
633 /* Show double cylinder ---------------------------------------------------- */
634 std::ostream& operator << (std::ostream &o, const DCylinder &f)
635 {
636  o << " Radius: " << f.radius << std::endl;
637  o << " Height: " << f.height << std::endl;
638  o << " Separ.: " << f.separation << std::endl;
639  o << " Rot: " << f.rot << std::endl;
640  o << " Tilt: " << f.tilt << std::endl;
641  o << " Psi: " << f.psi << std::endl;
642  return o;
643 }
644 
645 /* Show cube --------------------------------------------------------------- */
646 std::ostream& operator << (std::ostream &o, const Cube &f)
647 {
648  o << " Xdim: " << f.xdim << std::endl;
649  o << " Ydim: " << f.ydim << std::endl;
650  o << " Zdim: " << f.zdim << std::endl;
651  o << " Rot: " << f.rot << std::endl;
652  o << " Tilt: " << f.tilt << std::endl;
653  o << " Psi: " << f.psi << std::endl;
654  return o;
655 }
656 
657 /* Show ellipsoid ---------------------------------------------------------- */
658 std::ostream& operator << (std::ostream &o, const Ellipsoid &f)
659 {
660  o << " Xradius: " << f.xradius << std::endl;
661  o << " Yradius: " << f.yradius << std::endl;
662  o << " Zradius: " << f.zradius << std::endl;
663  o << " Rot: " << f.rot << std::endl;
664  o << " Tilt: " << f.tilt << std::endl;
665  o << " Psi: " << f.psi << std::endl;
666  return o;
667 }
668 
669 /* Show cone --------------------------------------------------------------- */
670 std::ostream& operator << (std::ostream &o, const Cone &f)
671 {
672  o << " Radius: " << f.radius << std::endl;
673  o << " Height: " << f.height << std::endl;
674  o << " Rot: " << f.rot << std::endl;
675  o << " Tilt: " << f.tilt << std::endl;
676  o << " Psi: " << f.psi << std::endl;
677  return o;
678 }
679 
680 /* ------------------------------------------------------------------------- */
681 /* Point Inside */
682 /* ------------------------------------------------------------------------- */
683 // For speed reasons an auxiliar vector of length 3 must be supplied to each
684 // function
685 
686 #define DEF_Sph_Blob_point_inside {\
687  /*Express r in the feature coord. system*/\
688  V3_MINUS_V3(aux,r,center);\
689  /*Check if it is inside*/\
690  if (XX(aux)*XX(aux) + YY(aux)*YY(aux) +ZZ(aux)*ZZ(aux) <= radius*radius)\
691  return 1;\
692  return 0;}
693 
694 /* Point inside a sphere --------------------------------------------------- */
696 {
698 }
699 
700 /* Point inside a Blob ----------------------------------------------------- */
702 {
704 }
705 #undef DEF_Sph_Blob_point_inside
706 
707 /* density inside a Blob --------------------------------------------------- */
709 {
710  /*Express r in the feature coord. system*/
711  V3_MINUS_V3(aux, r, center);
712  /*Calculate density*/
713  return (kaiser_value(aux.module(), radius, alpha, m));
714 }
715 
716 /* Point inside a Gaussian ------------------------------------------------- */
718 {
719  V3_MINUS_V3(aux,r,center);
720  if (XX(aux)*XX(aux) + YY(aux)*YY(aux) +ZZ(aux)*ZZ(aux) <= 16*sigma*sigma)
721  return 1;
722  return 0;
723 }
724 
725 /* density inside a Gaussian ----------------------------------------------- */
727 {
728  /*Express r in the feature coord. system*/
729  V3_MINUS_V3(aux, r, center);
730  /*Calculate density*/
731  const double norm=1.0/sqrt(2.0*PI);
732  double rmod=aux.module();
733  double sigma2=sigma*sigma;
734  return norm/(sigma2*sigma)*exp(-0.5*rmod*rmod/sigma2);
735 }
736 
737 /* Point inside a cylinder ------------------------------------------------- */
739 {
741  double tx;
742  double ty;
743 
744  // Express r in the feature coord. system
745  V3_MINUS_V3(aux, r, center);
746  M3x3_BY_V3x1(aux, euler, aux);
747 
748  // Check if it is inside
749  tx = XX(aux) / xradius;
750  ty = YY(aux) / yradius;
751  if (tx*tx + ty*ty <= 1.0 && fabs(ZZ(aux)) <= height / 2)
752  return 1;
753  return 0;
754 }
755 
756 /* Point inside a Double cylinder ------------------------------------------ */
758 {
760 
761  // Express r in the feature coord. system
762  V3_MINUS_V3(aux, r, center);
763  M3x3_BY_V3x1(aux, euler, aux);
764 
765  // Check if inside
766  if (XX(aux)*XX(aux) + YY(aux)*YY(aux) <= radius*radius)
767  {
768  double cyl_center = separation / 2 + height / 2;
769  if (ABS(ZZ(aux) - cyl_center) <= height / 2)
770  return 1;
771  else if (ABS(ZZ(aux) + cyl_center) <= height / 2)
772  return 1;
773  }
774  return 0;
775 }
776 
777 /* Point inside a cube ----------------------------------------------------- */
779 {
781 
782  // Express r in the feature coord. system
783  V3_MINUS_V3(aux, r, center);
784  M3x3_BY_V3x1(aux, euler, aux);
785 
786  // Check if inside
787  if (ABS(XX(aux)) <= xdim / 2 && ABS(YY(aux)) <= ydim / 2 &&
788  ABS(ZZ(aux)) <= zdim / 2)
789  return 1;
790  return 0;
791 }
792 
793 /* Point inside an ellipsoid ----------------------------------------------- */
795 {
797  double tx;
798  double ty;
799  double tz;
800 
801  // Express r in the feature coord. system
802  V3_MINUS_V3(aux, r, center);
803  M3x3_BY_V3x1(aux, euler, aux);
804 
805  // Check if inside
806  tx = XX(aux) / xradius;
807  ty = YY(aux) / yradius;
808  tz = ZZ(aux) / zradius;
809  if (tx*tx + ty*ty + tz*tz <= 1.0)
810  return 1;
811  return 0;
812 }
813 
814 /* Point inside a cone ----------------------------------------------------- */
816 {
818  double Zradius;
819 
820  // Express r in the feature coord. system
821  V3_MINUS_V3(aux, r, center);
822  M3x3_BY_V3x1(aux, euler, aux);
823 
824  // Check if inside
825  if (ABS(ZZ(aux)) <= height / 2)
826  {
827  Zradius = radius * (1 - (ZZ(aux) + height / 2) / height);
828  if (XX(aux)*XX(aux) + YY(aux)*YY(aux) <= Zradius*Zradius)
829  return 1;
830  }
831  return 0;
832 }
833 
834 /* Voxel inside ------------------------------------------------------------ */
835 // In all functions the voxelside is supposed to be 1
836 //#define DEBUG
837 #ifdef DEBUG
838 #define DEBUG_SHOW \
839  if (ZZ(r)==0 && YY(r)==0) \
840  std::cout << "Point (z=" << ZZ(aux1) << ",y=" << YY(aux1) << ",x=" \
841  << XX(aux1) << ") inside=" << inside << std::endl;
842 #else
843 #define DEBUG_SHOW
844 #endif
846  Matrix1D<double> &aux2) const
847 {
848 
849  // The subvoxels are visited following a Gray code, so the number
850  // of operations is minimized
851  XX(aux1) = XX(r) + 0.25;
852  YY(aux1) = YY(r) + 0.25;
853  ZZ(aux1) = ZZ(r) + 0.25; // 000
854  int inside = point_inside(aux1, aux2);
855  DEBUG_SHOW;
856  ZZ(aux1) -= 0.5;
857  inside += point_inside(aux1, aux2); // 001
858  DEBUG_SHOW;
859  YY(aux1) -= 0.5;
860  inside += point_inside(aux1, aux2); // 011
861  DEBUG_SHOW;
862  ZZ(aux1) += 0.5;
863  inside += point_inside(aux1, aux2); // 010
864  DEBUG_SHOW;
865  XX(aux1) -= 0.5;
866  inside += point_inside(aux1, aux2); // 110
867  DEBUG_SHOW;
868  ZZ(aux1) -= 0.5;
869  inside += point_inside(aux1, aux2); // 111
870  DEBUG_SHOW;
871  YY(aux1) += 0.5;
872  inside += point_inside(aux1, aux2); // 101
873  DEBUG_SHOW;
874  ZZ(aux1) += 0.5;
875  inside += point_inside(aux1, aux2); // 100
876  DEBUG_SHOW;
877  return inside;
878 }
879 /* voxel_inside_by_normalized_density ------------------------------------*/
881  const Matrix1D<double> &r,
882  Matrix1D<double> &aux1,
883  Matrix1D<double> &aux2) const
884 {
885 #ifdef NEVER
886  if (type == "blo")
887  {
888  std::cout << "den=" << density_inside(r, aux2) << std::endl;
889  return(density_inside(r, aux2));
890  }
891  else
892  return((double)voxel_inside(r, aux1, aux2));
893 #endif
894  // The subvoxels are visited following a Gray code, so the number
895  // of operations is minimized
896  XX(aux1) = XX(r) + 0.25;
897  YY(aux1) = YY(r) + 0.25;
898  ZZ(aux1) = ZZ(r) + 0.25; // 000
899  double inside = (double)point_inside(aux1, aux2)
900  * density_inside(r, aux2);
901  DEBUG_SHOW;
902  ZZ(aux1) -= 0.5;
903  inside += (double)point_inside(aux1, aux2)
904  * density_inside(r, aux2); // 001
905  DEBUG_SHOW;
906  YY(aux1) -= 0.5;
907  inside += (double)point_inside(aux1, aux2)
908  * density_inside(r, aux2); // 011
909  DEBUG_SHOW;
910  ZZ(aux1) += 0.5;
911  inside += (double)point_inside(aux1, aux2)
912  * density_inside(r, aux2); // 010
913  DEBUG_SHOW;
914  XX(aux1) -= 0.5;
915  inside += (double)point_inside(aux1, aux2)
916  * density_inside(r, aux2); // 110
917  DEBUG_SHOW;
918  ZZ(aux1) -= 0.5;
919  inside += (double)point_inside(aux1, aux2)
920  * density_inside(r, aux2); // 111
921  DEBUG_SHOW;
922  YY(aux1) += 0.5;
923  inside += (double)point_inside(aux1, aux2)
924  * density_inside(r, aux2); // 101
925  DEBUG_SHOW;
926  ZZ(aux1) += 0.5;
927  inside += (double)point_inside(aux1, aux2)
928  * density_inside(r, aux2); // 100
929  DEBUG_SHOW;
930  return inside;
931 
932 }
933 #undef DEBUG
934 
935 /* Intersects sphere ------------------------------------------------------- */
938 const
939 {
940  double radius2 = radius * radius;
941  bool intersects = false;
942  for (int k = FLOOR(ZZ(r) - radius); k <= CEIL(ZZ(r) + radius) && !intersects; k++)
943  {
944  auto dk=(double) k;
945  double distk2=(dk - ZZ(r))*(dk - ZZ(r));
946  for (int i = FLOOR(YY(r) - radius); i <= CEIL(YY(r) + radius) && !intersects; i++)
947  {
948  auto di=(double) i;
949  double distki2=distk2+(di - YY(r))*(di - YY(r));
950  for (int j = FLOOR(XX(r) - radius); j <= CEIL(XX(r) + radius) && !intersects; j++)
951  {
952  auto dj=(double) j;
953  if (distki2+(dj - XX(r))*(dj - XX(r))>radius2)
954  continue;
955  VECTOR_R3(aux3, j, i, k);
956  intersects = voxel_inside(aux3, aux1, aux2);
957  }
958  }
959  }
960  return intersects;
961 }
962 
963 /* ------------------------------------------------------------------------- */
964 /* Draw in */
965 /* ------------------------------------------------------------------------- */
966 /* Corners ----------------------------------------------------------------- */
968  Matrix1D<double> &corner2)
969 {
970  corner1.resize(3);
971  corner2.resize(3);
972  XX(corner1) = XMIPP_MAX(FLOOR(XX(center) - max_distance), STARTINGX(V));
973  YY(corner1) = XMIPP_MAX(FLOOR(YY(center) - max_distance), STARTINGY(V));
974  ZZ(corner1) = XMIPP_MAX(FLOOR(ZZ(center) - max_distance), STARTINGZ(V));
975  XX(corner2) = XMIPP_MIN(CEIL(XX(center) + max_distance), FINISHINGX(V));
976  YY(corner2) = XMIPP_MIN(CEIL(YY(center) + max_distance), FINISHINGY(V));
977  ZZ(corner2) = XMIPP_MIN(CEIL(ZZ(center) + max_distance), FINISHINGZ(V));
978 }
979 
980 /* Draw a feature ---------------------------------------------------------- */
981 //#define DEBUG
982 #define Vr A3D_ELEM(V,(int)ZZ(r),(int)YY(r),(int)XX(r))
983 void Feature::draw_in(MultidimArray<double> &V, int colour_mode, double colour)
984 {
985  Matrix1D<double> aux1(3);
986  Matrix1D<double> aux2(3);
987  Matrix1D<double> corner1(3);
988  Matrix1D<double> corner2(3);
989  Matrix1D<double> r(3);
990  int add;
991  double inside;
992  double final_colour;
993 
994  if (colour_mode == INTERNAL)
995  {
996  final_colour = density;
997  add = add_assign == '+';
998  }
999  else
1000  {
1001  final_colour = colour;
1002  add = 0;
1003  }
1004 
1005  corners(V, corner1, corner2);
1006 #ifdef DEBUG
1007 
1008  std::cout << "Drawing \n";
1009  std::cout << this;
1010  std::cout << "colour_mode=" << colour_mode << std::endl;
1011  std::cout << "add_assign= " << add_assign << std::endl;
1012  std::cout << "add= " << add << std::endl;
1013  std::cout << " Corner 1" << corner1.transpose() << std::endl;
1014  std::cout << " Corner 2" << corner2.transpose() << std::endl;
1015 #endif
1016 
1017  FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
1018  {
1019  inside = voxel_inside_by_normalized_density(r, aux1, aux2);
1020 #ifdef DEBUG
1021  //int condition=(ZZ(r)==-12) && (YY(r)==1);
1022  int condition = 1;
1023  if (condition)
1024  std::cout << " r=" << r.transpose() << " inside= " << inside;
1025 #endif
1026 
1027  if (inside != 0)
1028  {
1029  double drawing_colour = final_colour * inside / 8;
1030  if (add)
1031  Vr += drawing_colour;
1032  else
1033  Vr = drawing_colour; // It does not select the maximum between Vr and drawing_colour anymore -> it fails when adding less dense features
1034 #ifdef DEBUG
1035 
1036  if (condition)
1037  std::cout << " V(r)=" << VOLVOXEL(V, (int)ZZ(r), (int)YY(r), (int)XX(r));
1038 #endif
1039 
1040  }
1041 #ifdef DEBUG
1042  if (condition)
1043  std::cout << std::endl;
1044 #endif
1045 
1046  }
1047 }
1048 #undef DEBUG
1049 
1050 /* Sketch a feature -------------------------------------------------------- */
1052 {
1053  Matrix1D<double> aux1(3);
1054  Matrix1D<double> aux2(3);
1055  Matrix1D<double> corner1(3);
1056  Matrix1D<double> corner2(3);
1057  Matrix1D<double> r(3);
1058  int inside;
1059 
1060  corners(V, corner1, corner2);
1061  FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
1062  {
1063  inside = voxel_inside(r, aux1, aux2);
1064  if (inside != 0 && inside != 8)
1065  A3D_ELEM(V, (int)ZZ(r), (int)YY(r), (int)XX(r)) = colour;
1066  }
1067 }
1068 
1069 /* Shift a feature --------------------------------------------------------- */
1070 void Feature::shift(double shiftX, double shiftY, double shiftZ)
1071 {
1072  XX(center) += shiftX;
1073  YY(center) += shiftY;
1074  ZZ(center) += shiftZ;
1075 }
1076 
1077 /* Apply a general transformation to a feature ------------------------------ */
1079 {
1080  Matrix1D<double> r(4);
1081  XX(r) = XX(center);
1082  YY(r) = YY(center);
1083  ZZ(r) = ZZ(center);
1084  r(3) = 1;
1085  r = A * r;
1086  XX(center) = XX(r);
1087  YY(center) = YY(r);
1088  ZZ(center) = ZZ(r);
1089 }
1090 
1091 /* ------------------------------------------------------------------------- */
1092 /* Intersection */
1093 /* ------------------------------------------------------------------------- */
1094 // A line is supposed to be defined as a direction vector and a passing point
1095 // this way the parametric equation of the line is
1096 // (x,y,z)=(x1,y1,z1)+t(dx,dy,dz)
1097 // where (x,y,z) is the generic point belonging to this line
1098 // (x1,y1,z1) is the passing point
1099 // (dx,dy,dz) is the direction vector
1100 // t is a free parameter
1101 
1103  const Matrix1D<double> &direction,
1104  const Matrix1D<double> &passing_point,
1105  Matrix1D<double> &r,
1106  Matrix1D<double> &u) const
1107 {
1108  // This is done in order to correct the different lengths seen by
1109  // rays with different "speed". It is related to the jacobian of
1110  // the transformation from a non-unit direction to a unit one.
1111  double norm = direction.module();
1112 
1113  // Set the passing point in the ellipsoid coordinate system
1114  // and normalise to a unit sphere
1115  V3_MINUS_V3(r, passing_point, center);
1116  V3_BY_CT(r, r, 1 / radius);
1117  V3_BY_CT(u, direction, 1 / radius);
1118  return intersection_unit_sphere(u, r) / norm;
1119 }
1120 
1122  const Matrix1D<double> &direction,
1123  const Matrix1D<double> &passing_point,
1124  Matrix1D<double> &r,
1125  Matrix1D<double> &u) const
1126 {
1127  return(kaiser_proj(point_line_distance_3D(center, passing_point, direction),
1128  radius, alpha, m));
1129 }
1130 
1132  const Matrix1D<double> &direction,
1133  const Matrix1D<double> &passing_point,
1134  Matrix1D<double> &r,
1135  Matrix1D<double> &u) const
1136 {
1137  double rmod=point_line_distance_3D(center, passing_point, direction);
1138  double sigma2=sigma*sigma;
1139  return 1.0/sigma2*exp(-0.5*rmod*rmod/sigma2);
1140 }
1141 
1142 //#define DEBUG
1144  const Matrix1D<double> &direction,
1145  const Matrix1D<double> &passing_point,
1146  Matrix1D<double> &r,
1147  Matrix1D<double> &u) const
1148 {
1149  double norm = direction.module();
1151 
1152  // Set the passing point in the cylinder coordinate system
1153  // and normalise to a unit cylinder
1154  V3_MINUS_V3(r, passing_point, center);
1155  M3x3_BY_V3x1(r, euler, r);
1156  XX(r) /= xradius;
1157  YY(r) /= yradius;
1158  ZZ(r) /= height;
1159 
1160  // Express also the direction in the cyilinder coordinate system
1161  // and normalise to a unit cylinder
1162  M3x3_BY_V3x1(u, euler, direction);
1163  XX(u) /= xradius;
1164  YY(u) /= yradius;
1165  ZZ(u) /= height;
1166 
1167 #ifdef DEBUG
1168 
1169  std::cout << "Intersecting .-.-.-.-.-.-.\n";
1170  std::cout << *this;
1171  std::cout << " direction(Univ) = " << direction.transpose() << std::endl;
1172  std::cout << " passing (Univ) = " << passing_point.transpose() << std::endl;
1173  std::cout << " direction(Obj.) = " << u.transpose() << std::endl;
1174  std::cout << " passing (Obj.) = " << r.transpose() << std::endl;
1175  std::cout << " intersection = " << intersection_unit_cylinder(u, r) << std::endl;
1176 #endif
1177 
1178  return intersection_unit_cylinder(u, r) / norm;
1179 }
1180 #undef DEBUG
1181 
1183  const Matrix1D<double> &direction,
1184  const Matrix1D<double> &passing_point,
1185  Matrix1D<double> &r,
1186  Matrix1D<double> &u) const
1187 {
1188  double norm = direction.module();
1190 
1191  // Express also the direction in the cylinder coordinate system
1192  // and normalise to a unit cylinder
1193  M3x3_BY_V3x1(u, euler, direction);
1194  XX(u) /= radius;
1195  YY(u) /= radius;
1196  ZZ(u) /= height;
1197 
1198  // Top cylinder
1199  // Set the passing point in the cylinder coordinate system
1200  // and normalise to a unit cylinder
1201  V3_MINUS_V3(r, passing_point, center);
1202  M3x3_BY_V3x1(r, euler, r);
1203  ZZ(r) -= (separation / 2 + height / 2);
1204  XX(r) /= radius;
1205  YY(r) /= radius;
1206  ZZ(r) /= height;
1207  double i1 = intersection_unit_cylinder(u, r);
1208 
1209  // Bottom cylinder
1210  // Set the passing point in the cylinder coordinate system
1211  // and normalise to a unit cylinder
1212  V3_MINUS_V3(r, passing_point, center);
1213  M3x3_BY_V3x1(r, euler, r);
1214  ZZ(r) += (separation / 2 + height / 2);
1215  XX(r) /= radius;
1216  YY(r) /= radius;
1217  ZZ(r) /= height;
1218  double i2 = intersection_unit_cylinder(u, r);
1219 
1220  return (i1 + i2) / norm;
1221 }
1222 
1224  const Matrix1D<double> &direction,
1225  const Matrix1D<double> &passing_point,
1226  Matrix1D<double> &r,
1227  Matrix1D<double> &u) const
1228 {
1229  double norm = direction.module();
1231 
1232  // Set the passing point in the cube coordinate system
1233  // and normalise to a unit cube
1234  V3_MINUS_V3(r, passing_point, center);
1235  M3x3_BY_V3x1(r, euler, r);
1236  XX(r) /= xdim;
1237  YY(r) /= ydim;
1238  ZZ(r) /= zdim;
1239 
1240  // Express also the direction in the cube coordinate system
1241  // and normalise to a unit cube
1242  M3x3_BY_V3x1(u, euler, direction);
1243  XX(u) /= xdim;
1244  YY(u) /= ydim;
1245  ZZ(u) /= zdim;
1246 
1247  return intersection_unit_cube(u, r) / norm;
1248 }
1249 
1251  const Matrix1D<double> &direction,
1252  const Matrix1D<double> &passing_point,
1253  Matrix1D<double> &r,
1254  Matrix1D<double> &u) const
1255 {
1256  double norm = direction.module();
1258 
1259  // Set the passing point in the ellipsoid coordinate system
1260  // and normalise to a unit sphere
1261  V3_MINUS_V3(r, passing_point, center);
1262  M3x3_BY_V3x1(r, euler, r);
1263  XX(r) /= xradius;
1264  YY(r) /= yradius;
1265  ZZ(r) /= zradius;
1266 
1267  // Express also the direction in the ellipsoid coordinate system
1268  // and normalise to a unit sphere
1269  M3x3_BY_V3x1(u, euler, direction);
1270  XX(u) /= xradius;
1271  YY(u) /= yradius;
1272  ZZ(u) /= zradius;
1273 
1274  return intersection_unit_sphere(u, r) / norm;
1275 }
1276 
1278  const Matrix1D<double> &direction,
1279  const Matrix1D<double> &passing_point,
1280  Matrix1D<double> &r,
1281  Matrix1D<double> &u) const
1282 {
1283  return 0;
1284 }
1285 
1286 /* ------------------------------------------------------------------------- */
1287 /* Projecting */
1288 /* ------------------------------------------------------------------------- */
1289 /* Project a feature to a plane -------------------------------------------- */
1290 //#define DEBUG_LITTLE
1291 //#define DEBUG
1292 //#define DEBUG_EVEN_MORE
1294  const Matrix2D<double> &PV) const
1295 {
1296 constexpr float SUBSAMPLING = 2; // for every measure 2x2 line
1297  // integrals will be taken to
1298  // avoid numerical errors
1299 constexpr float SUBSTEP = 1/(SUBSAMPLING*2.0);
1300 
1301  Matrix1D<double> origin(3);
1303  VP.getRow(2, direction);
1304  direction.selfTranspose();
1305  Matrix1D<double> corner1(3);
1306  Matrix1D<double> corner2(3);
1307  Matrix1D<double> act(3);
1309 
1310  // Find center of the feature in the projection plane ...................
1311  // Step 1). Project the center to the plane, the result is in the
1312  // universal coord system
1313  M3x3_BY_V3x1(origin, VP, center);
1314 
1315  // Matrix1D<double> origin_debug(3);
1316  // Uproject_to_plane(center,P.direction,0,origin_debug);
1317 
1318  //#define DEBUG_LITTLE
1319 #ifdef DEBUG_LITTLE
1320 
1321  std::cout << "Actual feature\n" << this << std::endl;
1322  std::cout << "center " << center.transpose() << std::endl;
1323  std::cout << "VP matrix\n" << VP << std::endl;
1324  std::cout << "P.direction " << P.direction.transpose() << std::endl;
1325  std::cout << "direction " << direction.transpose() << std::endl;
1326  std::cout << "P.euler matrix " << P.euler << std::endl;
1327  std::cout << "max_distance " << max_distance << std::endl;
1328  std::cout << "origin " << origin.transpose() << std::endl;
1329  // std::cout << "origin_debug (Univ.coord) " << origin_debug.transpose() << std::endl;
1330 #endif
1331  /*
1332  // Step 2). Express this projected center in the projection coord system
1333  M3x3_BY_V3x1(origin_debug,P.euler,origin_debug);
1334  // if (A!=NULL) M2x2_BY_V2x1(origin,*A,origin_);
1335  #ifdef DEBUG_LITTLE
1336  std::cout << "origin (Proj.coord) " << origin_debug.transpose() << std::endl;
1337  #endif
1338  */
1339 
1340  // Find limits for projection ...........................................
1341  // Choose corners for the projection of this feature. It is supposed
1342  // to have at the worst case a projection of size max_distance
1345 #ifdef DEBUG_LITTLE
1346 
1347  std::cout << "Corner1 : " << corner1.transpose() << std::endl
1348  << "Corner2 : " << corner2.transpose() << std::endl;
1349 #endif
1350 
1351  box_enclosing(corner1, corner2, VP, corner1, corner2);
1352  // if (A!=NULL) {
1353  // rectangle_enclosing(corner1,corner2,*A,corner1,corner2);
1354 #ifdef DEBUG_LITTLE
1355 
1356  std::cout << "Corner1 moves to : " << corner1.transpose() << std::endl
1357  << "Corner2 moves to : " << corner2.transpose() << std::endl;
1358 #endif
1359  // }
1360 
1361  V3_PLUS_V3(corner1, origin, corner1);
1362  V3_PLUS_V3(corner2, origin, corner2);
1363 #ifdef DEBUG_LITTLE
1364 
1365  std::cout << "Corner1 finally is : " << corner1.transpose() << std::endl
1366  << "Corner2 finally is : " << corner2.transpose() << std::endl;
1367 #endif
1368  /*
1369  Matrix1D<double> corner1_debug(2),corner2_debug(2);
1370  VECTOR_R2(corner1_debug, max_distance, max_distance);
1371  VECTOR_R2(corner2_debug,-max_distance,-max_distance);
1372  #ifdef DEBUG_LITTLE
1373  std::cout << "Corner1_debug : " << corner1_debug.transpose() << std::endl
1374  << "Corner2_debug : " << corner2_debug.transpose() << std::endl;
1375  #endif
1376  V2_PLUS_V2(corner1_debug,origin_debug,corner1_debug);
1377  V2_PLUS_V2(corner2_debug,origin_debug,corner2_debug);
1378  #ifdef DEBUG_LITTLE
1379  std::cout << "Corner1_debug finally is : " << corner1_debug.transpose() << std::endl
1380  << "Corner2_debug finally is : " << corner2_debug.transpose() << std::endl;
1381  #endif
1382  */
1383  // Discard not necessary components
1384  corner1.resize(2);
1385  corner2.resize(2);
1386 
1387  // Clip to image size
1388  sortTwoVectors(corner1, corner2);
1389  XX(corner1) = CLIP(ROUND(XX(corner1)), STARTINGX(P()), FINISHINGX(P()));
1390  YY(corner1) = CLIP(ROUND(YY(corner1)), STARTINGY(P()), FINISHINGY(P()));
1391  XX(corner2) = CLIP(ROUND(XX(corner2)), STARTINGX(P()), FINISHINGX(P()));
1392  YY(corner2) = CLIP(ROUND(YY(corner2)), STARTINGY(P()), FINISHINGY(P()));
1393 
1394 #ifdef DEBUG_LITTLE
1395 
1396  std::cout << "corner1 " << corner1.transpose() << std::endl;
1397  std::cout << "corner2 " << corner2.transpose() << std::endl;
1398  std::cout.flush();
1399 #endif
1400 
1401  // Check if there is something to project
1402  if (XX(corner1) == XX(corner2))
1403  return;
1404  if (YY(corner1) == YY(corner2))
1405  return;
1406 
1407  // Study the projection for each point in the projection plane ..........
1408  // (u,v) are in the deformed projection plane (if any deformation)
1409  for (auto v = (int)YY(corner1); v <= (int)YY(corner2); v++)
1410  for (auto u = (int)XX(corner1); u <= (int)XX(corner2); u++)
1411  {
1412  double length = 0;
1413 #ifdef DEBUG_EVEN_MORE
1414 
1415  std::cout << "Studying point (" << u << "," << v << ")\n";
1416  std::cout.flush();
1417 #endif
1418 
1419  // Perform subsampling ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1420  double u0 = u - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1421  double v0 = v - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1422  double actv = v0;
1423  for (int subv = 0; subv < SUBSAMPLING; subv++)
1424  {
1425  double actu = u0;
1426  for (int subu = 0; subu < SUBSAMPLING; subu++)
1427  {
1428  // Compute the coordinates of point (subu,subv) which is
1429  // within the plane in the universal coordinate system
1430  XX(act) = actu;
1431  YY(act) = actv;
1432  ZZ(act) = 0;
1433  // if (Ainv!=NULL) M2x2_BY_V2x1(act,*Ainv,act);
1434  // M3x3_BY_V3x1(act,P.eulert,act);
1435  M3x3_BY_V3x1(act, PV, act);
1436 
1437  // Compute the intersection of a ray which passes through
1438  // this point and its direction is perpendicular to the
1439  // projection plane
1440  double possible_length = intersection(direction, act);
1441  if (possible_length > 0)
1442  length += possible_length;
1443 
1444 #ifdef DEBUG_EVEN_MORE
1445 
1446  std::cout << "Averaging at (" << actu << "," << actv << ")\n";
1447  std::cout << " which in univ. coords is " << act.transpose() << std::endl;
1448  std::cout << " intersection there " << possible_length << std::endl;
1449 #endif
1450  // Prepare for next iteration
1451  actu += SUBSTEP * 2.0;
1452  }
1453  actv += SUBSTEP * 2.0;
1454  }
1455  length /= (SUBSAMPLING * SUBSAMPLING);
1456 #ifdef DEBUG
1457 
1458  std::cout << "Final value added at position (" << u << "," << v << ")="
1459  << length << std::endl;
1460 #endif
1461 
1462  // Add at the correspondent pixel the found intersection ,,,,,,,,,,
1463  IMGPIXEL(P, v, u) += length * density;
1464  }
1465 }
1466 #undef DEBUG_LITTLE
1467 #undef DEBUG
1468 #undef DEBUG_EVEN_MORE
1469 
1470 /* ------------------------------------------------------------------------- */
1471 /* Scaling by a factor */
1472 /* ------------------------------------------------------------------------- */
1473 #define COPY_COMMON_PART \
1474  f->type = type; \
1475  f->add_assign = add_assign; \
1476  f->density = density; \
1477  f->center = center;
1478 
1479 #define COPY_ANGLES \
1480  f->rot = rot; \
1481  f->tilt = tilt; \
1482  f->psi = psi;
1483 
1484 /* Scale a sphere ---------------------------------------------------------- */
1485 Feature * Sphere::scale(double factor) const
1486 {
1487  Sphere *f;
1488  f = new Sphere;
1490 
1491  f->radius = factor * radius;
1492  f->prepare();
1493  return (Feature *)f;
1494 }
1495 
1496 void Sphere::scale(double factor, Feature **_f) const
1497 {
1498  *_f = scale(factor);
1499 }
1500 
1501 /* Scale a blob ---------------------------------------------------------- */
1502 Feature * Blob::scale(double factor) const
1503 {
1504  Blob *f;
1505  f = new Blob;
1507 
1508  f->radius = factor * radius;
1509  f->alpha = alpha;
1510  f->m = m;
1511  f->prepare();
1512  return (Feature *)f;
1513 }
1514 
1515 void Blob::scale(double factor, Feature **_f) const
1516 {
1517  *_f = scale(factor);
1518 }
1519 
1520 /* Scale a Gaussian -------------------------------------------------------- */
1521 Feature * Gaussian::scale(double factor) const
1522 {
1523  Gaussian *f;
1524  f = new Gaussian;
1526 
1527  f->sigma = factor * sigma;
1528  f->prepare();
1529  return (Feature *)f;
1530 }
1531 
1532 void Gaussian::scale(double factor, Feature **_f) const
1533 {
1534  *_f = scale(factor);
1535 }
1536 
1537 /* Scale a cylinder -------------------------------------------------------- */
1538 Feature * Cylinder::scale(double factor) const
1539 {
1540  Cylinder *f;
1541  f = new Cylinder;
1543  COPY_ANGLES;
1544 
1545  f->xradius = factor * xradius;
1546  f->yradius = factor * yradius;
1547  f->height = factor * height;
1548  f->prepare();
1549  return (Feature *)f;
1550 }
1551 
1552 void Cylinder::scale(double factor, Feature **_f) const
1553 {
1554  *_f = scale(factor);
1555 }
1556 
1557 /* Scale a double cylinder ------------------------------------------------- */
1558 Feature * DCylinder::scale(double factor) const
1559 {
1560  DCylinder *f;
1561  f = new DCylinder;
1563  COPY_ANGLES;
1564 
1565  f->radius = factor * radius;
1566  f->height = factor * height;
1567  f->separation = separation - 2 * (factor - 1) * height;
1568  f->prepare();
1569 
1570  return (Feature *)f;
1571 }
1572 
1573 void DCylinder::scale(double factor, Feature **_f) const
1574 {
1575  *_f = scale(factor);
1576 }
1577 
1578 /* Scale a cube ------------------------------------------------------------ */
1579 Feature * Cube::scale(double factor) const
1580 {
1581  Cube *f;
1582  f = new Cube;
1584  COPY_ANGLES;
1585 
1586  f->xdim = factor * xdim;
1587  f->ydim = factor * ydim;
1588  f->zdim = factor * zdim;
1589  f->prepare();
1590  return (Feature *)f;
1591 }
1592 
1593 void Cube::scale(double factor, Feature **_f) const
1594 {
1595  *_f = scale(factor);
1596 }
1597 
1598 /* Scale an ellipsoid ------------------------------------------------------ */
1599 Feature * Ellipsoid::scale(double factor) const
1600 {
1601  Ellipsoid *f;
1602  f = new Ellipsoid;
1604  COPY_ANGLES;
1605 
1606  f->xradius = factor * xradius;
1607  f->yradius = factor * yradius;
1608  f->zradius = factor * zradius;
1609  f->prepare();
1610  return (Feature *)f;
1611 }
1612 
1613 void Ellipsoid::scale(double factor, Feature **_f) const
1614 {
1615  *_f = scale(factor);
1616 }
1617 
1618 /* Scale a cone ------------------------------------------------------------ */
1619 Feature * Cone::scale(double factor) const
1620 {
1621  Cone *f;
1622  f = new Cone;
1624  COPY_ANGLES;
1625 
1626  f->radius = factor * radius;
1627  f->height = factor * height;
1628  f->prepare();
1629  return (Feature *)f;
1630 }
1631 
1632 void Cone::scale(double factor, Feature **_f) const
1633 {
1634  *_f = scale(factor);
1635 }
1636 
1637 #undef COPY_COMMON_PART
1638 #undef COPY_ANGLES
1639 
1640 /* ------------------------------------------------------------------------- */
1641 /* Backgrounds */
1642 /* ------------------------------------------------------------------------- */
1643 /* Encircle any feature ---------------------------------------------------- */
1645 {
1646  Sphere *f;
1647  f = new Sphere;
1648 
1649  if (radius == 0)
1650  radius = 1.5 * max_distance;
1651 
1652  f->type = "sph";
1653  f->add_assign = add_assign;
1654  f->density = density;
1655  f->center = center;
1656  f->max_distance = radius;
1657  f->radius = radius;
1658 
1659  return (Feature *)f;
1660 }
1661 
1662 Feature *Feature::background(int back_mode, double back_param) const
1663 {
1664  switch (back_mode)
1665  {
1666  case ENLARGE_MODE:
1667  return scale(back_param);
1668  break;
1669  case SPHERE_MODE:
1670  return encircle(back_param);
1671  break;
1672  default:
1673  REPORT_ERROR(ERR_VALUE_INCORRECT, "Feature::background: mode not supported");
1674  break;
1675  }
1676 }
1677 
1678 /* ------------------------------------------------------------------------- */
1679 /* Init random */
1680 /* ------------------------------------------------------------------------- */
1682  double minradius, double maxradius,
1683  double minden, double maxden,
1684  double minx0, double maxx0,
1685  double miny0, double maxy0,
1686  double minz0, double maxz0)
1687 {
1689  center.resize(3);
1690  type = "sph";
1691  add_assign = '+';
1692  density = rnd_unif(minden, maxden);
1693  XX(center) = rnd_unif(minx0, maxx0);
1694  YY(center) = rnd_unif(miny0, maxy0);
1695  ZZ(center) = rnd_unif(minz0, maxz0);
1696 
1697  radius = rnd_unif(minradius, maxradius);
1698 
1699  max_distance = radius;
1700 }
1701 
1703  double minradius, double maxradius,
1704  double minalpha, double maxalpha,
1705  double minorder, double maxorder,
1706  double minden, double maxden,
1707  double minx0, double maxx0,
1708  double miny0, double maxy0,
1709  double minz0, double maxz0)
1710 {
1712  center.resize(3);
1713  type = "blo";
1714  add_assign = '+';
1715  density = rnd_unif(minden, maxden);
1716  XX(center) = rnd_unif(minx0, maxx0);
1717  YY(center) = rnd_unif(miny0, maxy0);
1718  ZZ(center) = rnd_unif(minz0, maxz0);
1719 
1720  radius = rnd_unif(minradius, maxradius);
1721  alpha = rnd_unif(minalpha, maxalpha);
1722  m = (int)(rnd_unif(minorder, maxorder) + 0.5);
1723  max_distance = radius;
1724 }
1725 
1727  double minsigma, double maxsigma,
1728  double minden, double maxden,
1729  double minx0, double maxx0,
1730  double miny0, double maxy0,
1731  double minz0, double maxz0)
1732 {
1734  center.resize(3);
1735  type = "gau";
1736  add_assign = '+';
1737  density = rnd_unif(minden, maxden);
1738  XX(center) = rnd_unif(minx0, maxx0);
1739  YY(center) = rnd_unif(miny0, maxy0);
1740  ZZ(center) = rnd_unif(minz0, maxz0);
1741 
1742  sigma = rnd_unif(minsigma, maxsigma);
1743  max_distance = 4*sigma;
1744 }
1745 
1747  double minxradius, double maxxradius,
1748  double minyradius, double maxyradius,
1749  double minheight, double maxheight,
1750  double minden, double maxden,
1751  double minx0, double maxx0,
1752  double miny0, double maxy0,
1753  double minz0, double maxz0,
1754  double minrot, double maxrot,
1755  double mintilt, double maxtilt,
1756  double minpsi, double maxpsi)
1757 {
1759  center.resize(3);
1760  type = "cyl";
1761  add_assign = '+';
1762  density = rnd_unif(minden, maxden);
1763  XX(center) = rnd_unif(minx0, maxx0);
1764  YY(center) = rnd_unif(miny0, maxy0);
1765  ZZ(center) = rnd_unif(minz0, maxz0);
1766 
1767  xradius = rnd_unif(minxradius, maxxradius);
1768  yradius = rnd_unif(minyradius, maxyradius);
1769  height = rnd_unif(minheight, maxheight);
1770  rot = rnd_unif(minrot, maxrot);
1771  tilt = rnd_unif(mintilt, maxtilt);
1772  psi = rnd_unif(minpsi, maxpsi);
1773  Euler_angles2matrix(rot, tilt, psi, euler);
1774  eulert = euler.transpose();
1775 
1776  max_distance = sqrt(height * height + XMIPP_MAX(xradius * xradius, yradius * yradius));
1777 }
1778 
1780  double minradius, double maxradius,
1781  double minheight, double maxheight,
1782  double minsep, double maxsep,
1783  double minden, double maxden,
1784  double minx0, double maxx0,
1785  double miny0, double maxy0,
1786  double minz0, double maxz0,
1787  double minrot, double maxrot,
1788  double mintilt, double maxtilt,
1789  double minpsi, double maxpsi)
1790 {
1792  center.resize(3);
1793  type = "dcy";
1794  add_assign = '+';
1795  density = rnd_unif(minden, maxden);
1796  XX(center) = rnd_unif(minx0, maxx0);
1797  YY(center) = rnd_unif(miny0, maxy0);
1798  ZZ(center) = rnd_unif(minz0, maxz0);
1799 
1800  radius = rnd_unif(minradius, maxradius);
1801  height = rnd_unif(minheight, maxheight);
1802  separation = rnd_unif(minsep, maxsep);
1803  rot = rnd_unif(minrot, maxrot);
1804  tilt = rnd_unif(mintilt, maxtilt);
1805  psi = rnd_unif(minpsi, maxpsi);
1806  Euler_angles2matrix(rot, tilt, psi, euler);
1807  eulert = euler.transpose();
1808 
1809  max_distance = sqrt((height + separation) * (height + separation) / 4
1810  + radius * radius);
1811 }
1812 
1814  double minXdim, double maxXdim,
1815  double minYdim, double maxYdim,
1816  double minZdim, double maxZdim,
1817  double minden, double maxden,
1818  double minx0, double maxx0,
1819  double miny0, double maxy0,
1820  double minz0, double maxz0,
1821  double minrot, double maxrot,
1822  double mintilt, double maxtilt,
1823  double minpsi, double maxpsi)
1824 {
1826  center.resize(3);
1827  type = "cub";
1828  add_assign = '+';
1829  density = rnd_unif(minden, maxden);
1830  XX(center) = rnd_unif(minx0, maxx0);
1831  YY(center) = rnd_unif(miny0, maxy0);
1832  ZZ(center) = rnd_unif(minz0, maxz0);
1833 
1834  if (minYdim == 0)
1835  minYdim = minXdim;
1836  if (minZdim == 0)
1837  minZdim = minXdim;
1838  if (maxYdim == 0)
1839  maxYdim = maxXdim;
1840  if (maxZdim == 0)
1841  maxZdim = maxXdim;
1842  xdim = rnd_unif(minXdim, maxXdim);
1843  ydim = rnd_unif(minYdim, maxYdim);
1844  zdim = rnd_unif(minZdim, maxZdim);
1845  rot = rnd_unif(minrot, maxrot);
1846  tilt = rnd_unif(mintilt, maxtilt);
1847  psi = rnd_unif(minpsi, maxpsi);
1848  Euler_angles2matrix(rot, tilt, psi, euler);
1849  eulert = euler.transpose();
1850 
1851  max_distance = sqrt(xdim * xdim + ydim * ydim + zdim * zdim);
1852 }
1853 
1855  double minXradius, double maxXradius,
1856  double minYradius, double maxYradius,
1857  double minZradius, double maxZradius,
1858  double minden, double maxden,
1859  double minx0, double maxx0,
1860  double miny0, double maxy0,
1861  double minz0, double maxz0,
1862  double minrot, double maxrot,
1863  double mintilt, double maxtilt,
1864  double minpsi, double maxpsi)
1865 {
1867  center.resize(3);
1868  type = "ell";
1869  add_assign = '+';
1870  density = rnd_unif(minden, maxden);
1871  XX(center) = rnd_unif(minx0, maxx0);
1872  YY(center) = rnd_unif(miny0, maxy0);
1873  ZZ(center) = rnd_unif(minz0, maxz0);
1874 
1875  if (minYradius == 0)
1876  minYradius = minXradius;
1877  if (minZradius == 0)
1878  minZradius = minXradius;
1879  if (maxYradius == 0)
1880  maxYradius = maxXradius;
1881  if (maxZradius == 0)
1882  maxZradius = maxXradius;
1883  xradius = rnd_unif(minXradius, maxXradius);
1884  yradius = rnd_unif(minYradius, maxYradius);
1885  zradius = rnd_unif(minZradius, maxZradius);
1886  rot = rnd_unif(minrot, maxrot);
1887  tilt = rnd_unif(mintilt, maxtilt);
1888  psi = rnd_unif(minpsi, maxpsi);
1889  Euler_angles2matrix(rot, tilt, psi, euler);
1890  eulert = euler.transpose();
1891 
1892  max_distance = XMIPP_MAX(XMIPP_MAX(xradius, yradius), zradius);
1893 }
1894 
1896  double minradius, double maxradius,
1897  double minheight, double maxheight,
1898  double minden, double maxden,
1899  double minx0, double maxx0,
1900  double miny0, double maxy0,
1901  double minz0, double maxz0,
1902  double minrot, double maxrot,
1903  double mintilt, double maxtilt,
1904  double minpsi, double maxpsi)
1905 {
1907  center.resize(3);
1908  type = "con";
1909  add_assign = '+';
1910  density = rnd_unif(minden, maxden);
1911  XX(center) = rnd_unif(minx0, maxx0);
1912  YY(center) = rnd_unif(miny0, maxy0);
1913  ZZ(center) = rnd_unif(minz0, maxz0);
1914 
1915  radius = rnd_unif(minradius, maxradius);
1916  height = rnd_unif(minheight, maxheight);
1917  rot = rnd_unif(minrot, maxrot);
1918  tilt = rnd_unif(mintilt, maxtilt);
1919  psi = rnd_unif(minpsi, maxpsi);
1920  Euler_angles2matrix(rot, tilt, psi, euler);
1921  eulert = euler.transpose();
1922 
1923  max_distance = XMIPP_MAX(radius, height);
1924 }
1925 
1926 /* ------------------------------------------------------------------------- */
1927 /* Mean and Variance in a plane */
1928 /* ------------------------------------------------------------------------- */
1929 void Feature::mean_variance_in_plane(Image<double> *V, double z, double &mean,
1930  double &var)
1931 {
1932  double sum1 = 0;
1933  double sum2 = 0;
1934  double no_points = 0;
1935  Matrix1D<double> r(3);
1936  Matrix1D<double> aux1(3);
1937  Matrix1D<double> aux2(3);
1938 
1939  mean = 0;
1940  var = 0;
1941  if (z < STARTINGZ(VOLMATRIX(*V)) || z > FINISHINGZ(VOLMATRIX(*V)))
1942  return;
1943 
1944  ZZ(r) = z;
1945  for (YY(r) = STARTINGY(VOLMATRIX(*V)); YY(r) <= FINISHINGY(VOLMATRIX(*V)); YY(r)++)
1946  for (XX(r) = STARTINGX(VOLMATRIX(*V)); XX(r) <= FINISHINGX(VOLMATRIX(*V)); XX(r)++)
1947  {
1948  if (voxel_inside(r, aux1, aux2) == 8)
1949  {
1950  double voxel = VOLVOXEL(*V, (int)ZZ(r), (int)YY(r), (int)XX(r));
1951  sum1 += voxel;
1952  sum2 += voxel * voxel;
1953  no_points++;
1954  }
1955  }
1956  if (no_points != 0)
1957  {
1958  mean = sum1 / no_points;
1959  var = sum2 / no_points - mean * mean;
1960  }
1961 }
1962 
1963 /* ######################################################################### */
1964 /* Phantoms */
1965 /* ######################################################################### */
1966 /* Constructors ------------------------------------------------------------ */
1968 {
1969  xdim = ydim = zdim = 0;
1970  Background_Density = 0;
1971  fn = "";
1972  current_scale = 1;
1973  phantom_scale = 1.;
1974 }
1975 
1977 {
1978  *this = other;
1979 }
1980 
1982 {
1983  xdim = ydim = zdim = 0;
1984  Background_Density = 0;
1985  fn = "";
1986  for (size_t i = 0; i < VF.size(); i++)
1987  delete VF[i];
1988  VF.clear();
1989 }
1990 
1992 {
1993  if (&P == this)
1994  return *this;
1995  clear();
1996  fn = P.fn;
1997  xdim = P.xdim;
1998  ydim = P.ydim;
1999  zdim = P.zdim;
2000  phantom_scale = P.phantom_scale;
2001  Background_Density = P.Background_Density;
2002  Sphere *sph;
2003  Blob *blo;
2004  Gaussian *gau;
2005  Cylinder *cyl;
2006  DCylinder *dcy;
2007  Cube *cub;
2008  Ellipsoid *ell;
2009  Cone *con;
2010  for (size_t i = 0; i < P.VF.size(); i++)
2011  if (P.VF[i]->type == "sph")
2012  {
2013  sph = new Sphere;
2014  *sph = *((Sphere *) P.VF[i]);
2015  add(sph);
2016  }
2017  else if (P.VF[i]->type == "blo")
2018  {
2019  blo = new Blob;
2020  *blo = *((Blob *) P.VF[i]);
2021  add(blo);
2022  }
2023  else if (P.VF[i]->type == "gau")
2024  {
2025  gau = new Gaussian;
2026  *gau = *((Gaussian *) P.VF[i]);
2027  add(gau);
2028  }
2029  else if (P.VF[i]->type == "cyl")
2030  {
2031  cyl = new Cylinder;
2032  *cyl = *((Cylinder *) P.VF[i]);
2033  add(cyl);
2034  }
2035  else if (P.VF[i]->type == "dcy")
2036  {
2037  dcy = new DCylinder;
2038  *dcy = *((DCylinder *) P.VF[i]);
2039  add(dcy);
2040  }
2041  else if (P.VF[i]->type == "cub")
2042  {
2043  cub = new Cube;
2044  *cub = *((Cube *) P.VF[i]);
2045  add(cub);
2046  }
2047  else if (P.VF[i]->type == "ell")
2048  {
2049  ell = new Ellipsoid;
2050  *ell = *((Ellipsoid *) P.VF[i]);
2051  add(ell);
2052  }
2053  else if (P.VF[i]->type == "con")
2054  {
2055  con = new Cone;
2056  *con = *((Cone *) P.VF[i]);
2057  add(con);
2058  }
2059  return *this;
2060 }
2061 
2062 /* Prepare for work -------------------------------------------------------- */
2064 {
2065  for (size_t i = 0; i < VF.size(); i++)
2066  VF[i]->prepare();
2067 }
2068 
2069 /* Maximum distance -------------------------------------------------------- */
2071 {
2072  double retval = 0;
2073  for (size_t i = 0; i < VF.size(); i++)
2074  retval = XMIPP_MAX(retval, VF[i]->max_distance + VF[i]->center.module());
2075  return retval;
2076 }
2077 
2078 /* Volume ------------------------------------------------------------------ */
2079 double Phantom::volume() const
2080 {
2081  double retval = 0;
2082  for (size_t i = 0; i < VF.size(); i++)
2083  retval += VF[i]->volume();
2084  return retval;
2085 }
2086 
2087 /* Read Volume Description ------------------------------------------------- */
2088 void Phantom::read(const FileName &fn_phantom, bool apply_scale)
2089 {
2090 
2091  FILE *fh_phantom;
2092  char line[256];
2093  int Global_Feature_Read = 0; // Indicates if the line with volume dimensions
2094  // has been already read
2095  int stat;
2096  Sphere *sph;
2097  Blob *blo;
2098  Gaussian *gau;
2099  Cylinder *cyl;
2100  DCylinder *dcy;
2101  Cube *cub;
2102  Ellipsoid *ell;
2103  Cone *con;
2104  Feature *feat;
2105  Feature *scaled_feat;
2106  std::string feat_type;
2107  double scale = 1.; // The scale factor is not stored
2108  char straux[6];
2109 
2110  // Clear actual phantom
2111  clear();
2112 
2113  if (fn_phantom.isMetaData())
2114  {
2115  MetaDataVec MD1; //MetaData for the first block (phantom parameters)
2116  MetaDataVec MD2; //MetaData for the second block (phantom parameters)
2117  std::vector <double> TempVec; // A temporary vector for reading vector data
2118  size_t objId;
2119 
2120  // Assign different blocks to different MetaDatas
2121  MD1.read((std::string)"block1@"+fn_phantom.c_str());
2122  MD2.read((std::string)"block2@"+fn_phantom.c_str());
2123 
2124  // Read the first block containing parameters of phantom
2125  objId = MD1.firstRowId();
2126  MD1.getValue(MDL_DIMENSIONS_3D, TempVec, objId);
2127  if (TempVec.size()<3)
2128  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_DIMENSIONS_3D) + " problems with project dimensions");
2129  xdim = (int)TempVec[0];
2130  ydim = (int)TempVec[1];
2131  zdim = (int)TempVec[2];
2132  if (!MD1.getValue(MDL_PHANTOM_BGDENSITY, Background_Density, objId))
2133  Background_Density = 0;
2134  if (!MD1.getValue(MDL_SCALE, scale, objId))
2135  scale = 1;
2136  if (apply_scale)
2137  {
2138  xdim = (int) CEIL(scale * xdim);
2139  ydim = (int) CEIL(scale * ydim);
2140  zdim = (int) CEIL(scale * zdim);
2141  current_scale = 1;
2142  }
2143  else
2144  current_scale = scale;
2145 
2146  // Read the second block
2147  for (auto& FeatureRow: MD2)
2148  {
2149  if(!FeatureRow.getValue(MDL_PHANTOM_FEATURE_TYPE, feat_type))
2150  REPORT_ERROR(ERR_ARG_MISSING, MDL::label2Str(MDL_PHANTOM_FEATURE_TYPE) + " feature type not present");
2151  if (feat_type == "sph")
2152  {
2153  sph = new Sphere;
2154  feat = sph;
2155  sph->read(FeatureRow);
2156  }
2157  else if (feat_type == "blo")
2158  {
2159  blo = new Blob;
2160  feat = blo;
2161  blo->read(FeatureRow);
2162  }
2163  else if (feat_type == "gau")
2164  {
2165  gau = new Gaussian;
2166  feat = gau;
2167  gau->read(FeatureRow);
2168  }
2169  else if (feat_type == "cyl")
2170  {
2171  cyl = new Cylinder;
2172  feat = cyl;
2173  cyl->read(FeatureRow);
2174  }
2175  else if (feat_type == "dcy")
2176  {
2177  dcy = new DCylinder;
2178  feat = dcy;
2179  dcy->read(FeatureRow);
2180  }
2181  else if (feat_type == "cub")
2182  {
2183  cub = new Cube;
2184  feat = cub;
2185  cub->read(FeatureRow);
2186  }
2187  else if (feat_type == "ell")
2188  {
2189  ell = new Ellipsoid;
2190  feat = ell;
2191  ell->read(FeatureRow);
2192  }
2193  else if (feat_type == "con")
2194  {
2195  con = new Cone;
2196  feat = con;
2197  con->read(FeatureRow);
2198  }
2199  else
2201  if (apply_scale)
2202  {
2203  scaled_feat = feat->scale(scale);
2204  scaled_feat->center = scaled_feat->center * scale;
2205  delete feat;
2206 
2207  // Store feature
2208  VF.push_back(scaled_feat);
2209  }
2210  else
2211  VF.push_back(feat);
2212  }
2213  }
2214  else
2215  {
2216  // Open Volume Description File
2217  if ((fh_phantom = fopen(fn_phantom.c_str(), "r")) == nullptr)
2218  REPORT_ERROR(ERR_IO_NOTOPEN, (std::string)"Phantom::read: Cannot open the phantom file: "
2219  + fn_phantom);
2220  fn = fn_phantom;
2221 
2222  size_t lineNumber = 0;
2223  // Read the file
2224  while (fgets(line, 256, fh_phantom) != nullptr)
2225  {
2226  ++lineNumber;
2227  if (line[0] == 0)
2228  continue;
2229  if (line[0] == '#')
2230  continue;
2231  if (line[0] == '\n')
2232  continue;
2233 
2234  // Read volume dimensions and global density .........................
2235  if (Global_Feature_Read == 0)
2236  {
2237  Global_Feature_Read = 1;
2238  stat = sscanf(line, "%d %d %d %lf %lf", &xdim, &ydim, &zdim,
2239  &Background_Density, &scale);
2240  if (stat < 3)
2241  REPORT_ERROR(ERR_IO_NOREAD, "Phantom::read: check the volume"
2242  " dimensions and global density in volume description file");
2243  if (stat <= 3)
2244  Background_Density = 0;
2245  if (stat <= 4)
2246  scale = 1;
2247  if (apply_scale)
2248  {
2249  xdim = (int) CEIL(scale * xdim);
2250  ydim = (int) CEIL(scale * ydim);
2251  zdim = (int) CEIL(scale * zdim);
2252  current_scale = 1;
2253  }
2254  else
2255  current_scale = scale;
2256  continue;
2257  }
2258 
2259  // Read feature description ..........................................
2260  stat = sscanf(line, "%s", straux);
2261  feat_type = straux;
2262  if (stat != 1)
2263  REPORT_ERROR(ERR_IO_NOREAD, formatString("Phantom::read: Not correct feature type in line number %ld : \n%s",lineNumber, line));
2264 
2265  if (feat_type == "sph")
2266  {
2267  sph = new Sphere;
2268  feat = sph;
2269  sph->readCommon(line);
2270  sph->read_specific(line);
2271  }
2272  else if (feat_type == "blo")
2273  {
2274  blo = new Blob;
2275  feat = blo;
2276  blo->readCommon(line);
2277  blo->read_specific(line);
2278  }
2279  else if (feat_type == "gau")
2280  {
2281  gau = new Gaussian;
2282  feat = gau;
2283  gau->readCommon(line);
2284  gau->read_specific(line);
2285  }
2286  else if (feat_type == "cyl")
2287  {
2288  cyl = new Cylinder;
2289  feat = cyl;
2290  cyl->readCommon(line);
2291  cyl->read_specific(line);
2292  }
2293  else if (feat_type == "dcy")
2294  {
2295  dcy = new DCylinder;
2296  feat = dcy;
2297  dcy->readCommon(line);
2298  dcy->read_specific(line);
2299  }
2300  else if (feat_type == "cub")
2301  {
2302  cub = new Cube;
2303  feat = cub;
2304  cub->readCommon(line);
2305  cub->read_specific(line);
2306  }
2307  else if (feat_type == "ell")
2308  {
2309  ell = new Ellipsoid;
2310  feat = ell;
2311  ell->readCommon(line);
2312  ell->read_specific(line);
2313  }
2314  else if (feat_type == "con")
2315  {
2316  con = new Cone;
2317  feat = con;
2318  con->readCommon(line);
2319  con->read_specific(line);
2320  }
2321  else
2322  REPORT_ERROR(ERR_IO_NOREAD, (std::string)"Phantom::read: Unknown feature type: " + line);
2323 
2324  // Scale and Store feature
2325  if (apply_scale)
2326  {
2327  scaled_feat = feat->scale(scale);
2328  scaled_feat->center = scaled_feat->center * scale;
2329  delete feat;
2330 
2331  // Store feature
2332  VF.push_back(scaled_feat);
2333  }
2334  else
2335  VF.push_back(feat);
2336  }
2337  fclose(fh_phantom);
2338  phantom_scale = scale;
2339  }
2340 }
2341 
2342 /* Show whole phantom ------------------------------------------------------ */
2343 std::ostream& operator << (std::ostream &o, const Phantom &P)
2344 {
2345  std::cout << "Phantom ---------------------------------------\n";
2346  std::cout << "Dimensions: " << P.xdim << " x " << P.ydim << " x " << P.zdim << std::endl;
2347  std::cout << "Background density: " << P.Background_Density << std::endl;
2348  std::cout << "phantom_scale : " << P.phantom_scale << std::endl;
2349  for (size_t i = 0; i < P.VF.size(); i++)
2350  o << P.VF[i];
2351  return o;
2352 }
2353 
2354 /* Write Volume Description ------------------------------------------------ */
2355 void Phantom::write(const FileName &fn_phantom)
2356 {
2357  MetaDataVec MD1; //MetaData for phanto global parameters
2358  MetaDataVec MD2; //MetaData for Feature parameters
2359  std::vector<double> FCVect(3); //For the center of feature
2360  size_t id;
2361  // Write global parameters to the first block
2362  std::vector<double> PCVector; //For the center of Phantom
2363  MD1.setColumnFormat(false);
2364  id = MD1.addObject();
2365  PCVector.push_back(xdim);
2366  PCVector.push_back(ydim);
2367  PCVector.push_back(zdim);
2368  MD1.setValue(MDL_DIMENSIONS_3D, PCVector, id);
2369  MD1.setValue(MDL_PHANTOM_BGDENSITY, Background_Density, id);
2370  if (current_scale != 1)
2371  MD1.setValue(MDL_SCALE, current_scale, id);
2372  else
2373  MD1.setValue(MDL_SCALE, 1.0, id);
2374  MD1.write((std::string)"block1@"+fn_phantom.c_str(), MD_OVERWRITE);
2375 
2376  // Write specific parameters
2377  std::string SAddAssign; // string variab for feature operation (+/=)
2378  for (size_t i = 0; i < VF.size(); i++)
2379  {
2380  id = MD2.addObject();
2381  SAddAssign = VF[i]->add_assign;
2382  MD2.setValue(MDL_PHANTOM_FEATURE_TYPE,VF[i]->type, id);
2383  MD2.setValue(MDL_PHANTOM_FEATURE_OPERATION, SAddAssign, id);
2385  FCVect[0] = XX(VF[i]->center);
2386  FCVect[1] = YY(VF[i]->center);
2387  FCVect[2] = ZZ(VF[i]->center);
2388  MD2.setValue(MDL_PHANTOM_FEATURE_CENTER, FCVect, id);
2389  VF[i]->feat_printm(MD2, id);
2390  }
2391  MD2.write((std::string)"block2@"+fn_phantom.c_str(), MD_APPEND);
2392 }
2393 
2394 /* Voxel Inside any feature ------------------------------------------------ */
2396  Matrix1D<double> &aux1, Matrix1D<double> &aux2) const
2397 {
2398  int inside;
2399  int current_i;
2400  double current_density;
2401  current_i = 0;
2402  current_density = Background_Density;
2403  for (size_t i = 0; i < VF.size(); i++)
2404  {
2405  inside = VF[i]->voxel_inside(r, aux1, aux2);
2406  if (inside != 0 && VF[i]->density > current_density)
2407  {
2408  current_i = i + 1;
2409  current_density = VF[i]->density;
2410  }
2411  }
2412  return current_i;
2413 }
2414 
2415 /* Any feature intersects sphere ------------------------------------------- */
2417  double radius, Matrix1D<double> &aux1, Matrix1D<double> &aux2,
2418  Matrix1D<double> &aux3) const
2419 {
2420  bool intersects;
2421  for (size_t i = 0; i < VF.size(); i++)
2422  {
2423  intersects = VF[i]->intersects_sphere(r, radius, aux1, aux2, aux3);
2424  if (intersects)
2425  return i + 1;
2426  }
2427  return 0;
2428 }
2429 
2430 /* Draw a Phantom ---------------------------------------------------------- */
2431 // Always suppose CC grid
2433 {
2434  V.resize(zdim, ydim, xdim);
2435  V.setXmippOrigin();
2436  V.initConstant(Background_Density);
2437  for (size_t i = 0; i < VF.size(); i++)
2438  VF[i]->draw_in(V);
2439 }
2440 
2441 /* Label a Phantom --------------------------------------------------------- */
2442 // Always suppose CC grid
2444 {
2445  Matrix1D<double> r(3);
2446  Matrix1D<double> aux1(3);
2447  Matrix1D<double> aux2(3);
2448  V.resize(zdim, ydim, xdim);
2449  V.setXmippOrigin();
2451  {
2452  ZZ(r) = k;
2453  YY(r) = i;
2454  XX(r) = j;
2455  int sel_feat = voxel_inside_any_feat(r, aux1, aux2);
2456  // If it is not in the background, check that it is completely
2457  // inside the feature, if not set it to border.
2458  if (sel_feat != 0)
2459  if (VF[sel_feat-1]->voxel_inside(r, aux1, aux2) != 8)
2460  sel_feat = -sel_feat;
2461  A3D_ELEM(V, k, i, j) = sel_feat;
2462  }
2463 }
2464 
2465 /* Sketch a Phantom -------------------------------------------------------- */
2466 // Always suppose CC grid
2467 void Phantom::sketch_in(MultidimArray<double> &V, int clean, double colour)
2468 {
2469  if (clean)
2470  {
2471  V.resize(zdim, ydim, xdim);
2472  V.setXmippOrigin();
2473  }
2474  for (size_t i = 0; i < VF.size(); i++)
2475  VF[i]->sketch_in(V, colour);
2476 }
2477 
2478 /* Shift a phantom --------------------------------------------------------- */
2479 void Phantom::shift(double shiftX, double shiftY, double shiftZ)
2480 {
2481  for (size_t i = 0; i < VF.size(); i++)
2482  VF[i]->shift(shiftX, shiftY, shiftZ);
2483 }
2484 
2485 /* Rotate a phantom -------------------------------------------------------- */
2487 {
2488  for (size_t i = 0; i < VF.size(); i++)
2489  VF[i]->rotate(E);
2490 }
2491 
2492 /* Apply geometrical transformatio to a phantom ---------------------------- */
2494 {
2495  if ((MAT_XSIZE(A) != 4) || (MAT_YSIZE(A) != 4))
2496  REPORT_ERROR(ERR_MATRIX_SIZE, "Apply_geom3D: geometrical transformation is not 4x4");
2497  if (A.isIdentity())
2498  return;
2499  Matrix2D<double> T;
2500  if (inv == xmipp_transformation::IS_INV)
2501  T = A.inv();
2502  else
2503  T = A;
2504 
2505  for (size_t i = 0; i < VF.size(); i++)
2506  VF[i]->selfApplyGeometry(T);
2507 }
2508 
2509 /* Projecting a phantom ---------------------------------------------------- */
2510 //#define DEBUG
2511 void Phantom::project_to(Projection &P, int Ydim, int Xdim,
2512  double rot, double tilt, double psi, const Matrix2D<double> *A) const
2513 {
2514 #ifdef DEBUG
2515  std::cout << "Ydim=" << Ydim << " Xdim=" << Xdim << std::endl
2516  << "rot=" << rot << " tilt=" << tilt << " psi=" << psi << std::endl
2517  << "A\n" << A;
2518 #endif
2519  // Initialise projection
2520  P().initZeros(Ydim, Xdim);
2521  P().setXmippOrigin();
2522  P.setAngles(rot, tilt, psi);
2523 
2524  // Compute volume to Projection matrix
2525  Matrix2D<double> VP = P.euler;
2526  if (A != nullptr)
2527  VP = (*A) * VP;
2528  Matrix2D<double> PV = VP.inv();
2529  // Project all features
2530  for (size_t i = 0; i < VF.size(); i++)
2531  VF[i]->project_to(P, VP, PV);
2532 }
2533 #undef DEBUG
2534 
2536  double rot, double tilt, double psi, const Matrix2D<double> *A) const
2537 {
2538  P.setAngles(rot, tilt, psi);
2539 
2540  // Compute volume to Projection matrix
2541  Matrix2D<double> VP = P.euler;
2542  if (A != nullptr)
2543  VP = (*A) * VP;
2544  Matrix2D<double> PV = VP.inv();
2545 
2546  // Project all features
2547  for (size_t i = 0; i < VF.size(); i++)
2548  VF[i]->project_to(P, VP, PV);
2549 }
2550 
2551 void Phantom::project_to(Projection &P, const Matrix2D<double> &VP, double disappearing_th) const
2552 {
2553  Matrix2D<double> PV = VP.inv();
2554 
2555  // Project all features
2556  for (size_t i = 0; i < VF.size(); i++)
2557  {
2558  if (rnd_unif(0, 1) < disappearing_th)
2559  VF[i]->project_to(P, VP, PV);
2560  }
2561 }
2562 
2563 /* Surface ----------------------------------------------------------------- */
2564 //#define DEBUG
2565 void Phantom::surface(double z0, double radius, int direction, Image<double> *P)
2566 const
2567 {
2568  if (z0 != zdim)
2569  if (z0 < FIRST_XMIPP_INDEX(zdim) || z0 > LAST_XMIPP_INDEX(zdim))
2570  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, "Phantom::surface: z0 outside phantom");
2571 #ifdef DEBUG
2572 
2573  std::cout << "Direction: " << direction << std::endl;
2574  std::cout << "z0: " << z0 << std::endl;
2575  std::cout << "zdim: " << zdim << std::endl;
2576 #endif
2577 
2578  Matrix1D<double> aux1(3);
2579  Matrix1D<double> aux2(3);
2580  Matrix1D<double> aux3(3);
2581  Matrix1D<double> r(3);
2582  if (XSIZE((*P)()) == 0)
2583  {
2584  (*P)().resize(ydim, xdim);
2585  (*P)().setXmippOrigin();
2586  }
2588  {
2589 #ifdef DEBUG
2590  std::cout << "Processing (" << i << "," << j << ")" << std::endl;
2591 #endif
2592  // Init ray
2593  int k;
2594  if (direction == POS_NEG)
2595  k = LAST_XMIPP_INDEX(zdim) + 1;
2596  else
2597  k = FIRST_XMIPP_INDEX(zdim) - 1;
2598  bool finished;
2599  finished = false;
2600 
2601 #ifdef DEBUG
2602 
2603  std::cout << "Initial k=" << k << std::endl;
2604 #endif
2605  // Check that it is not inside and move ray
2606  // at the end k takes the right value for the image
2607  while (!finished)
2608  {
2609  VECTOR_R3(r, j, i, k);
2610 #ifdef DEBUG
2611 
2612  std::cout << "Checking " << r.transpose() << std::endl;
2613 #endif
2614  // If it is inside move a step backward and finish
2615  if (any_feature_intersects_sphere(r, radius, aux1, aux2, aux3))
2616  {
2617  finished = true;
2618  if (direction == POS_NEG)
2619  k++;
2620  else
2621  k--;
2622  }
2623  else
2624  {
2625  // Else, move until you find z0
2626  if (z0 != zdim)
2627  if (direction == POS_NEG)
2628  {
2629  k--;
2630  if (k < z0)
2631  {
2632  finished = true;
2633  k = CEIL(z0);
2634  }
2635  }
2636  else
2637  {
2638  k++;
2639  if (k > z0)
2640  {
2641  finished = true;
2642  k = FLOOR(z0);
2643  }
2644  }
2645  // or you reach the end of the volume
2646  else
2647  if (direction == POS_NEG)
2648  {
2649  k--;
2650  if (k < FIRST_XMIPP_INDEX(zdim))
2651  {
2652  finished = true;
2653  }
2654  }
2655  else
2656  {
2657  k++;
2658  if (k > LAST_XMIPP_INDEX(zdim))
2659  {
2660  finished = true;
2661  }
2662  }
2663  }
2664  }
2665 
2666  IMGPIXEL(*P, i, j) = k;
2667  }
2668 }
2669 #undef DEBUG
void label(MultidimArray< double > &V)
Definition: phantom.cpp:2443
double kaiser_value(double r, double a, double alpha, int m)
Definition: blobs.cpp:37
virtual void rotate(const Matrix2D< double > &E)
Definition: phantom.cpp:164
void assign(const Cube &F)
Definition: phantom.cpp:133
double density_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:708
#define DEBUG_SHOW
Definition: phantom.cpp:843
Argument missing.
Definition: xmipp_error.h:114
Index out of bounds.
Definition: xmipp_error.h:132
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
double volume() const
Return the volume of all the features.
Definition: phantom.cpp:2079
double height
Each cylinder height.
Definition: phantom.h:897
void init_rnd(double minXdim, double maxXdim, double minYdim=0, double maxYdim=0, double minZdim=0, double maxZdim=0, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0, double minrot=0, double maxrot=360, double mintilt=0, double maxtilt=180, double minpsi=0, double maxpsi=360)
Definition: phantom.cpp:1813
bool isIdentity() const
Definition: matrix2d.cpp:1323
#define VOLVOXEL(V, k, i, j)
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
Definition: phantom.h:1244
double module() const
Definition: matrix1d.h:983
Definition: phantom.h:563
double phantom_scale
Param file scale.
Definition: phantom.h:1377
void prepare()
Definition: phantom.cpp:83
int ydim
Final volume Y dimension.
Definition: phantom.h:1362
double point_line_distance_3D(const Matrix1D< double > &p, const Matrix1D< double > &a, const Matrix1D< double > &v)
Definition: geometry.cpp:85
void prepare()
Definition: phantom.cpp:59
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:695
void sortTwoVectors(Matrix1D< T > &v1, Matrix1D< T > &v2)
Definition: matrix1d.h:1206
double radius
Sphere radius.
Definition: phantom.h:471
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1143
Problem with matrix size.
Definition: xmipp_error.h:152
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:466
void readCommon(char *line)
Definition: phantom.cpp:177
void corners(const MultidimArray< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: phantom.cpp:967
double voxel_inside_by_normalized_density(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:880
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
#define DEF_Sph_Blob_point_inside
Definition: phantom.cpp:686
double tilt
Second Euler angle.
Definition: phantom.h:430
void project_to(Projection &P, const Matrix2D< double > &VP, const Matrix2D< double > &PV) const
Definition: phantom.cpp:1293
double xradius
X radius before rotating.
Definition: phantom.h:1131
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:430
#define VOLMATRIX(V)
void read_specific(char *line)
Definition: phantom.cpp:264
double sigma
Sigma.
Definition: phantom.h:666
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:794
void sqrt(Image< double > &op)
void rotate(const Matrix2D< double > &E)
Definition: phantom.cpp:2486
void draw_in(MultidimArray< double > &V, int color_mode=INTERNAL, double colour=-1)
Definition: phantom.cpp:983
void prepare()
Definition: phantom.cpp:77
void init_rnd(double minXradius, double maxXradius, double minYradius, double maxYradius, double minZradius, double maxZradius, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0, double minrot=0, double maxrot=360, double mintilt=0, double maxtilt=180, double minpsi=0, double maxpsi=360)
Definition: phantom.cpp:1854
void sketch_in(MultidimArray< double > &V, double colour=2)
Definition: phantom.cpp:1051
#define ENLARGE_MODE
Definition: phantom.h:248
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:717
void sketch_in(MultidimArray< double > &V, int clean=DONT_CLEAN, double colour=2)
Definition: phantom.cpp:2467
void prepare()
Definition: phantom.cpp:54
int voxel_inside_any_feat(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:2395
void read(MDRow &row)
Definition: phantom.cpp:213
Matrix2D< double > euler
#define V3_MINUS_V3(a, b, c)
Definition: matrix1d.h:202
void feat_printf(FILE *fh) const
Definition: phantom.cpp:440
void read_specific(char *line)
Definition: phantom.cpp:222
int intersects_sphere(const Matrix1D< double > &r, double radius, Matrix1D< double > &aux1, Matrix1D< double > &aux2, Matrix1D< double > &aux3) const
Definition: phantom.cpp:936
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
void initConstant(T val)
void feat_printf(FILE *fh) const
Definition: phantom.cpp:421
Matrix1D< double > center
Definition: phantom.h:119
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
double density
Definition: phantom.h:114
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1250
#define z0
void init_rnd(double minradius, double maxradius, double minalpha, double maxalpha, double minorder, double maxorder, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0)
Definition: phantom.cpp:1702
double intersection_unit_cylinder(const Matrix1D< double > &u, const Matrix1D< double > &r)
Definition: geometry.cpp:1151
void shift(double shiftX, double shiftY, double shiftZ)
Definition: phantom.cpp:2479
#define FINISHINGZ(v)
void feat_printf(FILE *fh) const
Definition: phantom.cpp:456
T norm(const std::vector< T > &v)
Definition: vector_ops.h:399
void prepare()
Definition: phantom.cpp:65
char add_assign
Definition: phantom.h:108
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1102
void assign(const Gaussian &F)
Definition: phantom.cpp:118
double volume() const
Definition: phantom.h:512
void selfTranspose()
Definition: matrix1d.h:944
#define IMGMATRIX(I)
void shift(double shiftX, double shiftY, double shiftZ)
Definition: phantom.cpp:1070
double * di
#define STARTINGX(v)
void read_specific(char *line)
Definition: phantom.cpp:332
Feature * scale(double factor) const
Definition: phantom.cpp:1579
FileName fn
Filename.
Definition: phantom.h:1356
#define i
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
void read_specific(char *line)
Definition: phantom.cpp:382
The density of the feature (double)
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
virtual void rotate_center(const Matrix2D< double > &E)
Definition: phantom.cpp:151
int m
Definition: phantom.h:574
#define STARTINGY(v)
void prepare()
Definition: phantom.cpp:71
#define CLIP(x, x0, xF)
Definition: xmipp_macros.h:260
void init_rnd(double minsigma, double maxsigma, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0)
Definition: phantom.cpp:1726
#define COPY_COMMON_PART
Definition: phantom.cpp:1473
double rnd_unif()
#define A3D_ELEM(V, k, i, j)
int any_feature_intersects_sphere(const Matrix1D< double > &r, double radius, Matrix1D< double > &aux1, Matrix1D< double > &aux2, Matrix1D< double > &aux3) const
Definition: phantom.cpp:2416
int voxel_inside(const Matrix1D< double > &r, Matrix1D< double > &aux1, Matrix1D< double > &aux2) const
Definition: phantom.cpp:845
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
double radius
Blob radius.
Definition: phantom.h:570
#define V3_BY_CT(a, b, c)
Definition: matrix1d.h:238
void box_enclosing(const Matrix1D< double > &v0, const Matrix1D< double > &vF, const Matrix2D< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: geometry.cpp:366
double density_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:726
T & getValue(MDLabel label)
#define FLOOR(x)
Definition: xmipp_macros.h:240
void feat_printf(FILE *fh) const
Definition: phantom.cpp:523
Feature * scale(double factor) const
Definition: phantom.cpp:1599
#define XX(v)
Definition: matrix1d.h:85
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:556
void assign(const Cylinder &F)
Definition: phantom.cpp:123
double intersection_unit_sphere(const Matrix1D< double > &u, const Matrix1D< double > &r)
Definition: geometry.cpp:1122
bool setValue(const MDObject &mdValueIn, size_t id)
#define CEIL(x)
Definition: xmipp_macros.h:225
size_t addObject() override
virtual void rotate(const Matrix2D< double > &E)
Definition: phantom.cpp:159
double * f
#define Vr
Definition: phantom.cpp:982
Incorrect argument received.
Definition: xmipp_error.h:113
size_t firstRowId() const override
void write(const FileName &fn_phantom="")
Definition: phantom.cpp:2355
void init_rnd(double minradius, double maxradius, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0)
Definition: phantom.cpp:1681
double height
Cone height.
Definition: phantom.h:1251
void draw_in(MultidimArray< double > &V)
Definition: phantom.cpp:2432
Definition: phantom.h:1010
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
virtual Feature * scale(double factor) const =0
#define XSIZE(v)
double height
Cylinder height.
Definition: phantom.h:772
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1223
double Background_Density
Final volume background density.
Definition: phantom.h:1368
Feature * scale(double factor) const
Definition: phantom.cpp:1619
void assign(const Ellipsoid &F)
Definition: phantom.cpp:138
void assign(const Blob &F)
Definition: phantom.cpp:113
void surface(double z0, double radius, int direction, Image< double > *P) const
Definition: phantom.cpp:2565
#define ABS(x)
Definition: xmipp_macros.h:142
double z
void read_specific(char *line)
Definition: phantom.cpp:308
__host__ __device__ float length(float2 v)
#define ROUND(x)
Definition: xmipp_macros.h:210
double volume() const
Definition: phantom.cpp:258
Couldn&#39;t read from file.
Definition: xmipp_error.h:139
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:533
void direction(const MultidimArray< double > &orMap, MultidimArray< double > &qualityMap, double lambda, int size, MultidimArray< double > &dirMap, int x, int y)
scaling factor for an image or volume (double)
void read(const FileName &fn_phantom, bool apply_scale=true)
Definition: phantom.cpp:2088
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:738
double intersection_unit_cube(const Matrix1D< double > &u, const Matrix1D< double > &r)
Definition: geometry.cpp:1190
double separation
Separation between cylinders.
Definition: phantom.h:900
void feat_printf(FILE *fh) const
Definition: phantom.cpp:500
Phantom background density (double)
void read_specific(char *line)
Definition: phantom.cpp:239
Type of the feature (Sphere, Blob, ...) (std::string)
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1182
void read_specific(char *line)
Definition: phantom.cpp:283
Matrix1D< double > direction
Phantom & operator=(const Phantom &P)
Assignment.
Definition: phantom.cpp:1991
Feature * scale(double factor) const
Definition: phantom.cpp:1502
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1131
void prepare()
Definition: phantom.cpp:49
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:778
void init_rnd(double minradius, double maxradius, double minheight, double maxheight, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0, double minrot=0, double maxrot=360, double mintilt=0, double maxtilt=180, double minpsi=0, double maxpsi=360)
Definition: phantom.cpp:1895
double ydim
Y dimension before rotating.
Definition: phantom.h:1017
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1277
double max_distance
Definition: phantom.h:126
#define j
#define POS_NEG
Definition: phantom.h:1604
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
void assign(const Oriented_Feature &OF)
Definition: phantom.cpp:97
#define YY(v)
Definition: matrix1d.h:93
#define SPHERE_MODE
Definition: phantom.h:249
double max_distance() const
Return the maximum distance of any feature to the volume center.
Definition: phantom.cpp:2070
int m
Operation in case of overlapping features (+,-)
bool getValue(MDObject &mdValueOut, size_t id) const override
Specific parameters for a feature (vector double)
double density_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.h:488
Feature * scale(double factor) const
Definition: phantom.cpp:1521
bool setValue(const MDLabel label, const T &valueIn, size_t id)
File cannot be open.
Definition: xmipp_error.h:137
Center of the feature (vector double)
double yradius
Cylinder Y radius.
Definition: phantom.h:769
Feature * scale(double factor) const
Definition: phantom.cpp:1558
int zdim
Final volume Z dimension.
Definition: phantom.h:1365
virtual void setColumnFormat(bool column)
#define FINISHINGY(v)
double alpha
Blob alpha.
Definition: phantom.h:572
std::string type
Definition: phantom.h:101
bool isMetaData(bool failIfNotExists=true) const
Feature * background(int back_mode, double back_param) const
Definition: phantom.cpp:1662
void feat_printf(FILE *fh) const
Definition: phantom.cpp:405
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:413
void prepare()
Prepare for work.
Definition: phantom.cpp:2063
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
void init_rnd(double minradius, double maxradius, double minheight, double maxheight, double minsep, double maxsep, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0, double minrot=0, double maxrot=360, double mintilt=0, double maxtilt=180, double minpsi=0, double maxpsi=360)
Definition: phantom.cpp:1779
#define FIRST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:439
void feat_printf(FILE *fh) const
Definition: phantom.cpp:478
double rot
First Euler angle.
Definition: phantom.h:427
double psi(const double x)
double zdim
Z dimension before rotating.
Definition: phantom.h:1020
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
int xdim
Final volume X dimension.
Definition: phantom.h:1359
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:510
void init_rnd(double minxradius, double maxxradius, double minyradius, double maxyradius, double minheight, double maxheight, double minden=1.0, double maxden=1.0, double minx0=0, double maxx0=0, double miny0=0, double maxy0=0, double minz0=0, double maxz0=0, double minrot=0, double maxrot=360, double mintilt=0, double maxtilt=180, double minpsi=0, double maxpsi=360)
Definition: phantom.cpp:1746
String formatString(const char *format,...)
double radius
Cylinder radius.
Definition: phantom.h:894
void mean_variance_in_plane(Image< double > *V, double z, double &mean, double &var)
Definition: phantom.cpp:1929
doublereal * u
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:488
void prepare_Euler()
Definition: phantom.cpp:102
void assign(const Cone &F)
Definition: phantom.cpp:143
#define COPY_ANGLES
Definition: phantom.cpp:1479
double psi
Third Euler angle.
Definition: phantom.h:433
fprintf(glob_prnt.io, "\)
void assign(const Sphere &F)
Definition: phantom.cpp:108
static String label2Str(const MDLabel &label)
friend std::ostream & operator<<(std::ostream &o, const Sphere &f)
Definition: phantom.cpp:599
double kaiser_proj(double s, double a, double alpha, int m)
Definition: blobs.cpp:94
void setAngles(double _rot, double _tilt, double _psi)
unsigned int randomize_random_generator()
void assign(const DCylinder &F)
Definition: phantom.cpp:128
#define LAST_XMIPP_INDEX(size)
Definition: xmipp_macros.h:448
void project_to(Projection &P, int Ydim, int Xdim, double rot, double tilt, double psi, const Matrix2D< double > *A=nullptr) const
Definition: phantom.cpp:2511
void assign(const Feature &F)
Definition: phantom.cpp:92
double zradius
Z radius before rotating.
Definition: phantom.h:1137
double yradius
Y radius before rotating.
Definition: phantom.h:1134
void prepare()
Definition: phantom.cpp:44
#define PI
Definition: tools.h:43
void selfApplyGeometry(const Matrix2D< double > &A, int inv)
Definition: phantom.cpp:2493
double v0
Incorrect value received.
Definition: xmipp_error.h:195
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
#define STARTINGZ(v)
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:815
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:757
#define ZZ(v)
Definition: matrix1d.h:101
double radius
Cone base radius.
Definition: phantom.h:1248
void feat_printf(FILE *fh) const
Definition: phantom.cpp:546
void read_specific(char *line)
Definition: phantom.cpp:357
Feature * scale(double factor) const
Definition: phantom.cpp:1538
double xradius
Cylinder X radius.
Definition: phantom.h:766
Feature * scale(double factor) const
Definition: phantom.cpp:1485
std::vector< Feature * > VF
List with the features.
Definition: phantom.h:1380
void feat_printm(MetaData &MD, size_t id)
Definition: phantom.cpp:448
#define FOR_ALL_ELEMENTS_IN_ARRAY3D_BETWEEN(corner1, corner2)
void clear()
Definition: phantom.cpp:1981
#define V3_PLUS_V3(a, b, c)
Definition: matrix1d.h:190
double basvolume(double a, double alpha, int m, int n)
Definition: blobs.cpp:215
Feature * encircle(double radius=0) const
Definition: phantom.cpp:1644
#define IMGPIXEL(I, i, j)
double xdim
X dimension before rotating.
Definition: phantom.h:1014
void selfApplyGeometry(const Matrix2D< double > &A)
Definition: phantom.cpp:1078
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403
int point_inside(const Matrix1D< double > &r, Matrix1D< double > &aux) const
Definition: phantom.cpp:701
#define INTERNAL
Definition: phantom.h:330
double intersection(const Matrix1D< double > &direction, const Matrix1D< double > &passing_point, Matrix1D< double > &r, Matrix1D< double > &u) const
Definition: phantom.cpp:1121