Xmipp  v3.23.11-Nereus
grids.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 #include "grids.h"
26 #include "numerical_tools.h"
27 
28 #include <stdio.h>
29 #include <string.h> // for memcpy
30 
31 /*****************************************************************************/
32 /* Simple Grids */
33 /*****************************************************************************/
34 // Constructor -------------------------------------------------------------
36 {
39  origin = vectorR3(0., 0., 0.);
40  lowest = vectorR3(-5., -5., -5.);
41  highest = -lowest;
42  relative_size = 1;
43  R2 = -1;
44 }
45 
46 // std::cout --------------------------------------------------------------------
47 std::ostream& operator <<(std::ostream& o, const SimpleGrid &grid)
48 {
49  o << " Simple Grid -----" << std::endl;
50  Matrix1D<double> aux;
51  (grid.basis).getCol(0,aux); o << " Vector 1: " << aux.transpose() << std::endl;
52  (grid.basis).getCol(1,aux); o << " Vector 2: " << aux.transpose() << std::endl;
53  (grid.basis).getCol(2,aux); o << " Vector 3: " << aux.transpose() << std::endl;
54  o << " Relative size: " << grid.relative_size << std::endl;
55  o << " Interest radius: " << grid.R2 << std::endl;
56  o << " Origin (univ.coords) " << grid.origin.transpose() << std::endl;
57  o << " Highest (grid. coord) " << grid.highest.transpose() << std::endl;
58  o << " Lowest (grid. coord) " << grid.lowest.transpose() << std::endl;
59  return o;
60 }
61 
62 // Another function for assignment -----------------------------------------
64 {
65  *this = SG;
66 }
67 
68 // Number of samples -------------------------------------------------------
70 {
71  if (R2 == -1)
72  {
73  int Zdim;
74  int Ydim;
75  int Xdim;
76  getSize(Zdim, Ydim, Xdim);
77  return Zdim*Ydim*Xdim;
78  }
79  else
80  {
81  auto ZZ_lowest = (int) ZZ(lowest);
82  auto YY_lowest = (int) YY(lowest);
83  auto XX_lowest = (int) XX(lowest);
84  auto ZZ_highest = (int) ZZ(highest);
85  auto YY_highest = (int) YY(highest);
86  auto XX_highest = (int) XX(highest);
87  Matrix1D<double> grid_index(3);
88  Matrix1D<double> univ_position(3);
89  int N = 0;
90  for (int k = ZZ_lowest; k <= ZZ_highest; k++)
91  for (int i = YY_lowest; i <= YY_highest; i++)
92  for (int j = XX_lowest; j <= XX_highest; j++)
93  {
94  VECTOR_R3(grid_index, j, i, k);
95  grid2universe(grid_index, univ_position);
96  if (is_interesting(univ_position)) N++;
97  }
98  return N;
99  }
100 }
101 
102 // Prepare Grid ------------------------------------------------------------
104 {
105  // Compute matrix for inverse basis conversion
106  try
107  {
108  inv_basis = basis.inv();
109  }
110  catch (XmippError &error)
111  {
112  REPORT_ERROR(ERR_UNCLASSIFIED, "The grid vectors are not a true 3D coordinate system");
113  }
114  lowest.setCol();
115  highest.setCol();
116  origin.setCol();
117 }
118 
119 // Minimum size ------------------------------------------------------------
121  const Matrix2D<double> *V) const
122 {
123  Matrix1D<double> SGcorner1(3); // Subgrid corners
124  Matrix1D<double> SGcorner2(3); // Subgrid corners
126 
127  // Look for the lowest and highest volume coordinate
128  Gcorner1.resize(3); // lowest and highest coord.
129  Gcorner2.resize(3);
130  for (size_t n = 0; n < GridsNo(); n++)
131  {
132  // Find box for this grid
133  bool first;
134  first = true;
135  for (auto k = (int)ZZ(LG[n].lowest); k <= ZZ(LG[n].highest); k++)
136  for (auto i = (int)YY(LG[n].lowest); i <= YY(LG[n].highest); i++)
137  for (auto j = (int)XX(LG[n].lowest); j <= XX(LG[n].highest); j++)
138  {
139  Matrix1D<double> grid_index(3);
140  Matrix1D<double> univ_position(3);
141  VECTOR_R3(grid_index, j, i, k);
142  LG[n].grid2universe(grid_index, univ_position);
143  if (V != nullptr)
144  {
145  M3x3_BY_V3x1(univ_position, *V, univ_position);
146  }
147  if (!LG[n].is_interesting(univ_position)) continue;
148  if (!first)
149  {
150  XX(SGcorner1) = XMIPP_MIN(XX(SGcorner1), XX(univ_position));
151  YY(SGcorner1) = XMIPP_MIN(YY(SGcorner1), YY(univ_position));
152  ZZ(SGcorner1) = XMIPP_MIN(ZZ(SGcorner1), ZZ(univ_position));
153 
154  XX(SGcorner2) = XMIPP_MAX(XX(SGcorner2), XX(univ_position));
155  YY(SGcorner2) = XMIPP_MAX(YY(SGcorner2), YY(univ_position));
156  ZZ(SGcorner2) = XMIPP_MAX(ZZ(SGcorner2), ZZ(univ_position));
157  }
158  else
159  {
160  SGcorner2 = SGcorner1 = univ_position;
161  first = false;
162  }
163  }
164 
165  // Compare with the rest of the grids
166  if (n != 0)
167  {
168  XX(Gcorner1) = XMIPP_MIN(XX(Gcorner1), XX(SGcorner1));
169  YY(Gcorner1) = XMIPP_MIN(YY(Gcorner1), YY(SGcorner1));
170  ZZ(Gcorner1) = XMIPP_MIN(ZZ(Gcorner1), ZZ(SGcorner1));
171 
172  XX(Gcorner2) = XMIPP_MAX(XX(Gcorner2), XX(SGcorner2));
173  YY(Gcorner2) = XMIPP_MAX(YY(Gcorner2), YY(SGcorner2));
174  ZZ(Gcorner2) = XMIPP_MAX(ZZ(Gcorner2), ZZ(SGcorner2));
175  }
176  else
177  {
178  Gcorner1 = SGcorner1;
179  Gcorner2 = SGcorner2;
180  }
181 
182 #ifdef DEBUG
183  std::cout << LG[n];
184  std::cout << "SGcorner1 " << SGcorner1.transpose() << std::endl;
185  std::cout << "SGcorner2 " << SGcorner2.transpose() << std::endl;
186  std::cout << "Gcorner1 " << Gcorner1.transpose() << std::endl;
187  std::cout << "Gcorner2 " << Gcorner2.transpose() << std::endl;
188 #endif
189  }
190 }
191 
192 /*****************************************************************************/
193 /* Some useful Grids */
194 /*****************************************************************************/
195 /* Create CC Simple grid with a given origin ------------------------------- */
197  const Matrix1D<double> &corner2, const Matrix1D<double> &origin)
198 {
199  SimpleGrid grid;
200 
201  // The vectors of the grid are the default ones of (1,0,0), (0,1,0),
202  // and (0,0,1), and its inverse matrix is already computed
204  grid.origin = origin;
205 
206  // Compute the lowest and highest indexes inside the grid
207  grid.universe2grid(corner1, grid.lowest);
208  grid.lowest.selfFLOOR();
209  grid.universe2grid(corner2, grid.highest);
210  grid.highest.selfCEIL();
211 
212  grid.R2 = -1;
213  return grid;
214 }
215 
216 /* Create CC grid ---------------------------------------------------------- */
218  const Matrix1D<double> &corner2)
219 {
220  Grid result;
221  SimpleGrid aux_grid;
222 
223  Matrix1D<double> origin = (corner1 + corner2) / 2;
225  if (ABS(ROUND(origin(i))-origin(i))<0.45)
226  origin(i)=ROUND(origin(i));
227  else
228  origin(i)=CEIL(origin(i));
229  aux_grid = Create_CC_grid(relative_size, corner1, corner2, origin);
230  result.add_grid(aux_grid);
231  return result;
232 }
233 
234 Grid Create_CC_grid(double relative_size, int Zdim, int Ydim, int Xdim)
235 {
236  Grid result;
237  SimpleGrid aux_grid;
238 
240  vectorR3((double)FLOOR(Xdim / 2.0), (double)FLOOR(Ydim / 2.0),
241  (double)FLOOR(Zdim / 2.0));
242  aux_grid = Create_CC_grid(relative_size, -origin,
243  vectorR3((double)Xdim, (double)Ydim, (double)Zdim) - origin - 1,
244  vectorR3(0.0,0.0,0.0));
245  result.add_grid(aux_grid);
246 
247  return result;
248 }
249 
250 /* Create BCC grid --------------------------------------------------------- */
252  const Matrix1D<double> &corner2)
253 {
254  Grid result;
255  SimpleGrid aux_grid;
256  Matrix1D<double> origin = (corner1 + corner2) / 2;
257  origin.selfROUND();
258 
259  //Even Slice
260  // 0 1 2 3 4 5 6 7 8 9 10 11 12 (Col)
261  // 0 A A A A A A A
262  // 1
263  // 2 A A A A A A A
264  // 3
265  // 4 A A A A A A A
266  // 5
267  // 6 A A A A A A A
268  // 7
269  // 8 A A A A A A A
270  // 9
271  // 10 A A A A A A A
272  // 11
273  // 12 A A A A A A A
274  //(Row)
275  //
276  //Odd Slice
277  // 0 1 2 3 4 5 6 7 8 9 10 11 12 (Col)
278  // 0
279  // 1 B B B B B B
280  // 2
281  // 3 B B B B B B
282  // 4
283  // 5 B B B B B B
284  // 6
285  // 7 B B B B B B
286  // 8
287  // 9 B B B B B B
288  // 10
289  // 11 B B B B B B
290  // 12
291  //(Row)
292 
293  // Grid A
294  aux_grid = Create_CC_grid(relative_size, corner1, corner2, origin);
295  result.add_grid(aux_grid);
296 
297  // Grid B
298  origin = origin + relative_size / 2 * vectorR3(1., 1., 1.);
299  aux_grid = Create_CC_grid(relative_size, corner1, corner2, origin);
300  result.add_grid(aux_grid);
301 
302  return result;
303 }
304 
305 /* Create FCC grid --------------------------------------------------------- */
307  const Matrix1D<double> &corner2)
308 {
309 
310  Grid result;
311  SimpleGrid aux_grid;
312  Matrix1D<double> aux_origin;
313  Matrix1D<double> cornerb;
314  Matrix1D<double> origin = (corner1 + corner2) / 2;
315  origin.selfROUND();
316 
317  //Even Slice
318  // 0 1 2 3 4 5 6 7 8 9 10 11 12 (Col)
319  // 0 A A A A A A A
320  // 1 B B B B B B
321  // 2 A A A A A A A
322  // 3 B B B B B B
323  // 4 A A A A A A A
324  // 5 B B B B B B
325  // 6 A A A A A A A
326  // 7 B B B B B B
327  // 8 A A A A A A A
328  // 9 B B B B B B
329  // 10 A A A A A A A
330  // 11 B B B B B B
331  // 12 A A A A A A A
332  //(Row)
333  //
334  //Odd Slice
335  // 0 1 2 3 4 5 6 7 8 9 10 11 12 (Col)
336  // 0 C C C C C C
337  // 1 D D D D D D D
338  // 2 C C C C C C
339  // 3 D D D D D D D
340  // 4 C C C C C C
341  // 5 D D D D D D D
342  // 6 C C C C C C
343  // 7 D D D D D D D
344  // 8 C C C C C C
345  // 9 D D D D D D D
346  // 10 C C C C C C
347  // 11 D D D D D D D
348  // 12 C C C C C C
349  //(Row)
350 
351  // Grid A
352  aux_grid = Create_CC_grid(relative_size, corner1, corner2, origin);
353  result.add_grid(aux_grid);
354  // Grid D
355  aux_origin = origin + relative_size / 2 * vectorR3(0., 1., 1.);
356  aux_grid = Create_CC_grid(relative_size, corner1, corner2, aux_origin);
357  result.add_grid(aux_grid);
358  // Grid C
359  aux_origin = origin + relative_size / 2 * vectorR3(1., 0., 1.);
360  aux_grid = Create_CC_grid(relative_size, corner1, corner2, aux_origin);
361  result.add_grid(aux_grid);
362  // Grid B
363  cornerb = corner2;
364  cornerb(0) = cornerb(0) - 1;
365  cornerb(1) = cornerb(1) - 1;
366  aux_origin = origin + relative_size / 2 * vectorR3(1., 1., 0.);
367  aux_grid = Create_CC_grid(relative_size, corner1, cornerb, aux_origin);
368  result.add_grid(aux_grid);
369 
370  return result;
371 }
372 #undef MULTIPLY_CC_GRID_BY_TWO
373 
374 /* CC grid with region of interest ----------------------------------------- */
375 //#define DEBUG
377  const Matrix1D<double> &origin,
378  const Matrix1D<double> &X, const Matrix1D<double> &Y,
379  const Matrix1D<double> &Z, double R2)
380 {
381  SimpleGrid grid;
382  double R = sqrt(R2);
383 
384  grid.set_X(X);
385  grid.set_Y(Y);
386  grid.set_Z(Z);
388  grid.origin = origin;
389  grid.R2 = R2;
390  grid.lowest.initZeros(3);
391  grid.highest.initZeros(3);
392  grid.prepare_grid();
393 
394  // Find grid limits
395  int iR = CEIL(R);
396  Matrix1D<double> univ_position(3);
397  Matrix1D<double> grid_position(3);
398  for (int k = -iR; k <= iR; k++)
399  for (int i = -iR; i <= iR; i++)
400  for (int j = -iR; j <= iR; j++)
401  {
402  VECTOR_R3(univ_position, j, i, k);
403  if (univ_position.module() > R) continue;
404  grid.universe2grid(univ_position, grid_position);
405  XX(grid.lowest) = XMIPP_MIN(XX(grid.lowest), FLOOR(XX(grid_position)));
406  YY(grid.lowest) = XMIPP_MIN(YY(grid.lowest), FLOOR(YY(grid_position)));
407  ZZ(grid.lowest) = XMIPP_MIN(ZZ(grid.lowest), FLOOR(ZZ(grid_position)));
408  XX(grid.highest) = XMIPP_MAX(XX(grid.highest), CEIL(XX(grid_position)));
409  YY(grid.highest) = XMIPP_MAX(YY(grid.highest), CEIL(YY(grid_position)));
410  ZZ(grid.highest) = XMIPP_MAX(ZZ(grid.highest), CEIL(ZZ(grid_position)));
411  }
412 
413 #ifdef DEBUG
414  std::cout << "Sphere radius = " << R << std::endl
415  << "relative size = " << relative_size << std::endl
416  << "X module = " << X.module() << std::endl
417  << "Y module = " << Y.module() << std::endl
418  << "Z module = " << Z.module() << std::endl
419  << grid
420  ;
421 #endif
422  return grid;
423 }
424 #undef DEBUG
425 
426 /* Create CC grid ---------------------------------------------------------- */
428 {
429  Grid result;
430  SimpleGrid aux_grid;
431 
433  origin.initZeros();
434  Matrix1D<double> x(3);
435  Matrix1D<double> y(3);
436  Matrix1D<double> z(3);
437  VECTOR_R3(x, 1, 0, 0);
438  VECTOR_R3(y, 0, 1, 0);
439  VECTOR_R3(z, 0, 0, 1);
440  aux_grid = Create_grid_within_sphere(relative_size, origin, x, y, z, R * R);
441  result.add_grid(aux_grid);
442  return result;
443 }
444 
445 /* Create BCC grid --------------------------------------------------------- */
447 {
448  Grid result;
449  SimpleGrid aux_grid;
450 
452  origin.initZeros();
453  Matrix1D<double> x(3);
454  Matrix1D<double> y(3);
455  Matrix1D<double> z(3);
456  VECTOR_R3(x, 0.5, 0.5, -0.5);
457  VECTOR_R3(y, 0.5, -0.5, 0.5);
458  VECTOR_R3(z, -0.5, 0.5, 0.5);
459  aux_grid = Create_grid_within_sphere(relative_size, origin, x, y, z, R * R);
460  result.add_grid(aux_grid);
461  return result;
462 }
463 
464 /* Create FCC grid --------------------------------------------------------- */
466 {
467  Grid result;
468  SimpleGrid aux_grid;
469 
471  origin.initZeros();
472  Matrix1D<double> x(3);
473  Matrix1D<double> y(3);
474  Matrix1D<double> z(3);
475  VECTOR_R3(x, 0.5, 0.5, 0);
476  VECTOR_R3(y, 0.5, 0, 0.5);
477  VECTOR_R3(z, 0, 0.5, 0.5);
478  aux_grid = Create_grid_within_sphere(relative_size, origin, x, y, z, R * R);
479  result.add_grid(aux_grid);
480  return result;
481 }
Just to locate unclassified errors.
Definition: xmipp_error.h:192
void set_Y(const Matrix1D< double > &v)
Definition: grids.h:198
void selfROUND()
Definition: matrix1d.cpp:522
void universe2grid(const Matrix1D< double > &uv, Matrix1D< double > &gv) const
Definition: grids.h:349
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
Matrix1D< double > highest
Definition: grids.h:161
SimpleGrid Create_grid_within_sphere(double relative_size, const Matrix1D< double > &origin, const Matrix1D< double > &X, const Matrix1D< double > &Y, const Matrix1D< double > &Z, double R2)
Definition: grids.cpp:376
double module() const
Definition: matrix1d.h:983
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
SimpleGrid Create_CC_grid(double relative_size, const Matrix1D< double > &corner1, const Matrix1D< double > &corner2, const Matrix1D< double > &origin)
Definition: grids.cpp:196
void grid2universe(const Matrix1D< double > &gv, Matrix1D< double > &uv) const
Definition: grids.h:318
void sqrt(Image< double > &op)
static double * y
Matrix1D< double > vectorR3(double x, double y, double z)
Definition: matrix1d.cpp:892
friend std::ostream & operator<<(std::ostream &o, const SimpleGrid &grid)
Definition: grids.cpp:47
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
void set_X(const Matrix1D< double > &v)
Definition: grids.h:191
Definition: grids.h:479
bool is_interesting(const Matrix1D< double > &uv) const
Definition: grids.h:361
Matrix1D< double > lowest
Definition: grids.h:158
Matrix2D< double > basis
Definition: grids.h:148
doublereal * x
#define i
void setCol()
Definition: matrix1d.h:554
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
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
double R2
Definition: grids.h:170
glob_log first
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
Matrix2D< double > inv_basis
Definition: grids.h:153
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define XX(v)
Definition: matrix1d.h:85
#define CEIL(x)
Definition: xmipp_macros.h:225
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
void assign(const SimpleGrid &SG)
Definition: grids.cpp:63
#define ABS(x)
Definition: xmipp_macros.h:142
double z
#define ROUND(x)
Definition: xmipp_macros.h:210
void set_Z(const Matrix1D< double > &v)
Definition: grids.h:205
void initZeros()
Definition: matrix1d.h:592
double relative_size
Measuring unit in the grid coordinate system.
Definition: grids.h:163
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define YY(v)
Definition: matrix1d.h:93
Grid Create_FCC_grid(double relative_size, const Matrix1D< double > &corner1, const Matrix1D< double > &corner2)
Definition: grids.cpp:306
void selfFLOOR()
Definition: matrix1d.cpp:499
Grid Create_BCC_grid(double relative_size, const Matrix1D< double > &corner1, const Matrix1D< double > &corner2)
Definition: grids.cpp:251
SimpleGrid()
Definition: grids.cpp:35
Matrix1D< double > origin
Origin of the grid in the Universal coordinate system.
Definition: grids.h:165
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
int get_number_of_samples() const
Definition: grids.cpp:69
void add_grid(const SimpleGrid &SG)
Definition: grids.h:491
void prepare_grid()
Definition: grids.cpp:103
int * n
void voxel_corners(Matrix1D< double > &Gcorner1, Matrix1D< double > &Gcorner2, const Matrix2D< double > *V=nullptr) const
Definition: grids.cpp:120
#define ZZ(v)
Definition: matrix1d.h:101
void initIdentity()
Definition: matrix2d.h:673
void selfCEIL()
Definition: matrix1d.cpp:476
void getSize(int &Zdim, int &Ydim, int &Xdim) const
Definition: grids.h:245
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403