Xmipp  v3.23.11-Nereus
grids.h
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 /* ------------------------------------------------------------------------- */
26 /* GRIDS */
27 /* ------------------------------------------------------------------------- */
28 
29 #ifndef _CORE_GRIDS_HH
30 #define _CORE_GRIDS_HH
31 
32 #include <vector>
33 
34 #include <core/xmipp_image.h>
35 #include <core/geometry.h>
36 #include <core/args.h>
37 #include "core/matrix2d.h"
38 
39 /* Forward declarations ---------------------------------------------------- */
40 template <class T>
42 template <class T>
44 template <class T>
46 template <class T>
47 std::ostream& operator << (std::ostream &o, const GridVolumeT<T> &GV);
48 class Basis;
49 
68 /*****************************************************************************/
69 /* Simple Grids */
70 /*****************************************************************************/
145 {
146  /* Structure --------------------------------------------------------------- */
147 public:
148  Matrix2D<double> basis; // These are the 3 unitary vectors
149  // which define the grid. First
150  // column is vector X, second
151  // column is vector Y, and the third
152  // is Z
153  Matrix2D<double> inv_basis; // Inverse matrix of the basis
154  // It is used to save computation
155  // time
170  double R2;
171 
172  /* Prototypes --------------------------------------------------------------- */
173 public:
179  SimpleGrid();
180 
184  friend std::ostream& operator <<(std::ostream& o, const SimpleGrid &grid);
185 
187  void assign(const SimpleGrid &SG);
188 
191  void set_X(const Matrix1D<double> &v)
192  {
193  basis.setCol(0, v);
194  }
195 
198  void set_Y(const Matrix1D<double> &v)
199  {
200  basis.setCol(1, v);
201  }
202 
205  void set_Z(const Matrix1D<double> &v)
206  {
207  basis.setCol(2, v);
208  }
209 
212  void get_X(Matrix1D<double> &v) const
213  {
214  basis.getCol(0, v);
215  }
216 
219  void get_Y(Matrix1D<double> &v) const
220  {
221  basis.getCol(1, v);
222  }
223 
226  void get_Z(Matrix1D<double> &v) const
227  {
228  basis.getCol(2, v);
229  }
230 
245  void getSize(int &Zdim, int &Ydim, int &Xdim) const
246  {
247  Zdim = (int)(ZZ(highest) - ZZ(lowest)) + 1;
248  Ydim = (int)(YY(highest) - YY(lowest)) + 1;
249  Xdim = (int)(XX(highest) - XX(lowest)) + 1;
250  }
251 
256  int get_number_of_samples() const;
257 
259  void set_interest_radius(double _R)
260  {
261  if (_R == -1)
262  R2 = -1;
263  else
264  R2 = _R * _R;
265  }
266 
268  double get_interest_radius() const
269  {
270  if (R2 == -1)
271  return R2;
272  else
273  return sqrt(R2);
274  }
275 
277  void set_relative_size(double size)
278  {
279  relative_size = size;
280  }
281 
283  double get_relative_size() const
284  {
285  return relative_size;
286  }
287 
301  void prepare_grid();
302 
319  {
321  uv.resize(3);
322  M3x3_BY_V3x1(uv, basis, gv);
323  V3_BY_CT(uv, uv, relative_size);
324  V3_PLUS_V3(uv, uv, origin);
325  }
326 
350  {
352  gv.resize(3);
353  V3_MINUS_V3(gv, uv, origin);
354  V3_BY_CT(gv, gv, 1 / relative_size);
355  M3x3_BY_V3x1(gv, inv_basis, gv);
356  }
357 
361  bool is_interesting(const Matrix1D<double> &uv) const
362  {
363  if (R2 == -1)
364  return true;
365  else
366  return XX(uv)*XX(uv) + YY(uv)*YY(uv) + ZZ(uv)*ZZ(uv) < R2;
367  }
368 
382  double rot, double tilt, double psi, Matrix1D<double> &result) const
383  {
384  grid2universe(gr, result);
385  Uproject_to_plane(result, rot, tilt, psi, result);
386  }
387 
400  const Matrix2D<double> &euler, Matrix1D<double> &result) const
401  {
402  grid2universe(gr, result);
403  Uproject_to_plane(result, euler, result);
404  }
405 
433  double rot, double tilt, double psi, Matrix1D<double> &result) const
434  {
435  grid2universe(gr, result);
436  V3_MINUS_V3(result, result, origin);
437  Uproject_to_plane(result, rot, tilt, psi, result);
438  }
439 
447  const Matrix2D<double> &euler, Matrix1D<double> &result) const
448  {
449  grid2universe(gr, result);
450  V3_MINUS_V3(result, result, origin);
451  Uproject_to_plane(result, euler, result);
452  }
453 };
454 
455 /*****************************************************************************/
456 /* Complex Grids */
457 /*****************************************************************************/
479 class Grid
480 {
481  /* Structure --------------------------------------------------------------- */
482  std::vector<SimpleGrid> LG; // List of grids
483 public:
484  /* Protoypes --------------------------------------------------------------- */
491  void add_grid(const SimpleGrid &SG)
492  {
493  LG.push_back(SG);
494  }
495 
504  const SimpleGrid & operator()(size_t n) const
505  {
506  if (n>LG.size())
507  REPORT_ERROR(ERR_VALUE_INCORRECT, "The Grid hasn't got so many Simple Grids");
508  return LG[n];
509  }
510 
520  {
521  if (n>LG.size())
522  REPORT_ERROR(ERR_VALUE_INCORRECT, "The Grid hasn't got so many Simple Grids");
523  return LG[n];
524  }
525 
527  void get_SimpleGrid(int n, SimpleGrid& G) const
528  {
529  G = (*this)(n);
530  }
531 
536  size_t GridsNo() const
537  {
538  return LG.size();
539  }
540 
544  friend std::ostream& operator << (std::ostream& o, const Grid &grid)
545  {
546  o << "Complex Grid -------------------------------------\n";
547  for (size_t i = 0; i < grid.GridsNo(); i++)
548  o << grid(i);
549  return o;
550  }
551 
553  void assign(const Grid &G)
554  {
555  *this = G;
556  }
557 
559  void clear()
560  {
561  LG.clear();
562  }
563 
567  void voxel_corners(Matrix1D<double> &Gcorner1, Matrix1D<double> &Gcorner2,
568  const Matrix2D<double> *V = nullptr) const;
569 };
570 
571 /*****************************************************************************/
572 /* Some useful Grids */
573 /*****************************************************************************/
584 #define CC 0
586 #define FCC 1
588 #define BCC 2
590 
617  const Matrix1D<double> &corner1,
618  const Matrix1D<double> &corner2,
619  const Matrix1D<double> &origin);
620 
635  const Matrix1D<double> &corner1,
636  const Matrix1D<double> &corner2);
637 
654  int Zdim, int Ydim, int Xdim);
655 
677  const Matrix1D<double> &corner1, const Matrix1D<double> &corner2);
678 
712  const Matrix1D<double> &corner1, const Matrix1D<double> &corner2);
713 
724  const Matrix1D<double> &origin,
725  const Matrix1D<double> &X, const Matrix1D<double> &Y,
726  const Matrix1D<double> &Z, double R2);
727 
736 Grid Create_CC_grid(double relative_size, double R);
737 
746 Grid Create_BCC_grid(double relative_size, double R);
747 
756 Grid Create_FCC_grid(double relative_size, double R);
758 
759 /*****************************************************************************/
760 /* Grid Volumes */
761 /*****************************************************************************/
771 template <class T>
772 class GridVolumeT
773 {
774  // Structure ---------------------------------------------------------------
775  std::vector<Image<T> * > LV; // List of volumes
776  Grid G; // Grid associated to this volume
777 
778 public:
779  // Protoypes ---------------------------------------------------------------
783  {
784  LV.clear();
785  (Grid) G;
786  }
787 
790  {
791  *this = _RV;
792  }
793 
798  GridVolumeT(const Grid &_grid)
799  {
800  adapt_to_grid(_grid);
801  }
802 
804  GridVolumeT& operator = (const GridVolumeT& RV)
805  {
806  if (this != &RV)
807  {
808  clear();
809  G = RV.G;
810  for (size_t i = 0; i < RV.VolumesNo(); i++)
811  {
812  auto *V = new Image<T>;
813  *V = RV(i);
814  LV.push_back(V);
815  }
816  }
817  return *this;
818  }
819 
821  void assign(const GridVolumeT& RV)
822  {
823  *this = RV;
824  }
825 
828  {
829  clear();
830  }
831 
838  void adapt_to_grid(const Grid &_grid)
839  {
840  // Clear old list of volumes
841  for (size_t i = 0; i < VolumesNo(); i++)
842  if (LV[i]!=nullptr)
843  delete LV[i];
844  LV.clear();
845 
846  // Keep the incoming Grid at the same time the old grid is forgotten
847  G = _grid;
848 
849  // Generate a volume for each subgrid
850  int Zdim;
851  int Ydim;
852  int Xdim;
853  Image<T> * Vol_aux;
854  for (size_t i = 0; i < G.GridsNo(); i++)
855  {
856  SimpleGrid & grid = G(i);
857  grid.getSize(Zdim, Ydim, Xdim);
858  Vol_aux = new Image<T>;
859  (*Vol_aux)().resize(Zdim, Ydim, Xdim); // Using this function
860  // after empty creation the volume
861  // is zero-valued.
862  STARTINGX((*Vol_aux)()) = (int) XX(grid.lowest); // This values are already
863  STARTINGY((*Vol_aux)()) = (int) YY(grid.lowest); // integer although they
864  STARTINGZ((*Vol_aux)()) = (int) ZZ(grid.lowest); // are stored as float
865  LV.push_back(Vol_aux);
866  }
867  }
868 
873  void resize(const Matrix1D<double> &corner1,
874  const Matrix1D<double> &corner2)
875  {
876  Image<T> * Vol_aux;
877  std::vector<Image<T> * > LV_aux;
878 
879  for (size_t n = 0; n < G.GridsNo(); n++)
880  {
881  SimpleGrid &grid = G(n);
882 
883  // Resize grid
884  grid.universe2grid(corner1, grid.lowest);
885  grid.lowest.selfFLOOR();
886  grid.universe2grid(corner2, grid.highest);
887  grid.highest.selfCEIL();
888 
889  // Resize auxiliary volume
890  int Zdim;
891  int Ydim;
892  int Xdim;
893  grid.getSize(Zdim, Ydim, Xdim);
894  Vol_aux = new Image<T>;
895  (*Vol_aux)().resize(Zdim, Ydim, Xdim);
896  STARTINGX((*Vol_aux)()) = (int) XX(grid.lowest); // This values are already
897  STARTINGY((*Vol_aux)()) = (int) YY(grid.lowest); // integer although they
898  STARTINGZ((*Vol_aux)()) = (int) ZZ(grid.lowest); // are stored as float
899 
900  // Copy values in common
901  Image<T> * origin = LV[n];
904  {
905  VOLVOXEL(*Vol_aux, k, i, j) = VOLVOXEL(*origin, k, i, j);
906  }
907 
908  // Extract old volume and push new one
909  delete LV[n];
910  LV_aux.push_back(Vol_aux);
911  }
912  LV = LV_aux;
913  }
914 
918  template <class T1>
919  void resize(const GridVolumeT<T1> &GV)
920  {
921  clear();
922  for (size_t n = 0; n < GV.VolumesNo(); n++)
923  {
924  SimpleGrid grid;
925  grid = GV.grid(n);
926  G.add_grid(grid);
927 
928  Image<T> *Vol_aux;
929  Vol_aux = new Image<T>;
930  (*Vol_aux)().resize(GV(n)());
931  LV.push_back(Vol_aux);
932  }
933  }
934 
936  void initZeros()
937  {
938  for (size_t i = 0; i < VolumesNo(); i++)
939  (*this)(i)().initZeros();
940  }
941 
943  void clear()
944  {
945  for (size_t i = 0; i < VolumesNo(); i++)
946  delete LV[i];
947  LV.clear();
948  G.clear();
949  }
950 
954  {
955  if (n>LV.size())
956  REPORT_ERROR(ERR_VALUE_INCORRECT, "The Grid Volume hasn't got so many Simple Volumes");
957  return *(LV[n]);
958  }
959 
961  void get_volume(size_t n, Image<T> &V)
962  {
963  V = (*this)(n);
964  }
965 
968  const Image<T> & operator()(size_t n) const
969  {
970  if (n>LV.size())
971  REPORT_ERROR(ERR_VALUE_INCORRECT, "The Grid Volume hasn't got so many Simple Volumes");
972  return *(LV[n]);
973  }
974 
978  const SimpleGrid & grid(size_t n) const
979  {
980  return G(n);
981  }
982 
984  void get_SimpleGrid(size_t n, SimpleGrid &G)
985  {
986  G = grid(n);
987  }
988 
991  const Grid & grid() const
992  {
993  return G;
994  }
995 
997  void get_Grid(Grid &G)
998  {
999  G = grid();
1000  }
1001 
1003  size_t VolumesNo() const
1004  {
1005  return LV.size();
1006  }
1007 
1008 #define GRIDVOLUME_BY_SCALAR(op) \
1009  GridVolumeT<T> result; \
1010  result.G = G; \
1011  result.LV.reserve(VolumesNo()); \
1012  for (size_t i=0; i<VolumesNo(); i++) \
1013  array_by_scalar((*this)(i)(),f,result(i)(),op); \
1014  return result;
1015 
1020  {
1021  GRIDVOLUME_BY_SCALAR('+');
1022  }
1023 
1028  {
1029  GRIDVOLUME_BY_SCALAR('-');
1030  }
1031 
1036  {
1037  GRIDVOLUME_BY_SCALAR('*');
1038  }
1039 
1044  {
1045  GRIDVOLUME_BY_SCALAR('/');
1046  }
1047 
1052  {
1053  return GV + f;
1054  }
1055 
1060  {
1061  return GV*f;
1062  }
1063 
1064 #define GRIDVOL_BY_GRIDVOL(op) \
1065  GridVolumeT<T> result; \
1066  Image<T> * Vol_aux; \
1067  \
1068  if (VolumesNo()!=GV.VolumesNo()) \
1069  REPORT_ERROR(ERR_GRID_SIZE,(std::string)"GridVolume::"+op+": Different number of subvolumes");\
1070  \
1071  result.G = G;\
1072  result.LV.reserve(VolumesNo());\
1073  \
1074  for (size_t i=0; i<VolumesNo(); i++) { \
1075  try { \
1076  Vol_aux = new Image<T>; \
1077  arrayByArray((*this)(i)(),GV(i)(),(*Vol_aux)(),op); \
1078  result.LV.push_back(Vol_aux); \
1079  } catch (XmippError XE) {\
1080  std::cout << XE.what(); \
1081  REPORT_ERROR(ERR_GRID_SIZE,(std::string)"GridVolume::"+op+": Different shape of volume " +\
1082  integerToString(i)); \
1083  } \
1084  } \
1085  \
1086  return result;
1087 
1094  {
1095  GRIDVOL_BY_GRIDVOL('+');
1096  }
1097 
1104  {
1105  GRIDVOL_BY_GRIDVOL('-');
1106  }
1107 
1114  {
1115  GRIDVOL_BY_GRIDVOL('*');
1116  }
1117 
1124  {
1125  GRIDVOL_BY_GRIDVOL('/');
1126  }
1127 
1128 #define GRIDVOL_BY_GRIDVOLASSIG(op) \
1129  if (VolumesNo()!=GV.VolumesNo()) \
1130  REPORT_ERROR(ERR_GRID_SIZE,(std::string)"GridVolume::"+op+"=: Different number of subvolumes");\
1131  \
1132  for (size_t i=0; i<VolumesNo(); i++) { \
1133  try { \
1134  arrayByArray((*this)(i)(),GV(i)(),(*this)(i)(),op); \
1135  } catch (XmippError XE) {\
1136  std::cout << XE.what(); \
1137  REPORT_ERROR(ERR_GRID_SIZE,(std::string)"GridVolume::"+op+"=: Different shape of volume " +\
1138  integerToString(i)); \
1139  } \
1140  }
1141 
1144  {
1146  }
1147 
1150  {
1152  }
1153 
1156  {
1158  }
1159 
1162  {
1164  }
1165 
1196  void write(const FileName &fn) const
1197  {
1198  Image<T> V;
1199  float temp_float;
1200  size_t floatsize;
1201  const std::type_info &typeinfoT = typeid(T); // We need to know what kind
1202  // of variable is T
1203  const std::type_info &typeinfoD = typeid(double);
1204  const std::type_info &typeinfoI = typeid(int);
1205 
1206  floatsize = (size_t) sizeof(float);
1207 
1208  if (VolumesNo() == 0)
1209  return;
1210 
1211  // Create the writing volume ............................................
1212  size_t Zdim = 0;
1213  size_t Ydim = 0;
1214  size_t Xdim = 0;
1215  for (size_t v = 0; v < VolumesNo(); v++)
1216  {
1217  const Image<T> & this_vol = (*this)(v);
1218  Zdim += ZSIZE(this_vol());
1219  Ydim = XMIPP_MAX(Ydim, YSIZE(this_vol()));
1220  Xdim = XMIPP_MAX(Xdim, XSIZE(this_vol()));
1221  }
1222 
1223  // Check if there is enough space for the control slice
1224  if (Xdim*Ydim < 25)
1225  Ydim = (int) CEIL(25.0f / Xdim);
1226 
1227  // A slice is added for control information for each subvolume
1228  VOLMATRIX(V).initZeros(Zdim + VolumesNo(), Ydim, Xdim);
1229 
1230  // Write Grid volume ....................................................
1231 #define PACK_DOUBLE(v) \
1232 {jj=pos%Xdim; ii=pos/Xdim; pos++; VOLVOXEL(V,sli,ii,jj)=(T)(v);}
1233 #define PACK_INT(v) \
1234  {jj=pos%Xdim; ii=pos/Xdim; pos++; \
1235  temp_float = (float) (v); \
1236  memcpy( &(VOLVOXEL(V,sli,ii,jj)) , &temp_float, floatsize); \
1237  }
1238 
1239  int sli = 0;
1240  for (size_t v = 0; v < VolumesNo(); v++)
1241  {
1242  int pos; // Position inside the control slice
1243  int ii; // Position inside the control slice
1244  int jj; // Position inside the control slice
1245  size_t k; // Auxiliar counters
1246  size_t i; // Auxiliar counters
1247  size_t j; // Auxiliar counters
1248 
1249  // Choose grid and volume
1250  const SimpleGrid & this_grid = grid(v);
1251  const Image<T> & this_vol = (*this)(v);
1252 
1253  // Store Grid data ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1254  pos = 0;
1255 
1256  if (typeinfoT == typeinfoD)
1257  {
1258  for (i = 0; i < 3; i++)
1259  for (j = 0; j < 3; j++)
1260  PACK_DOUBLE((this_grid.basis)(i, j));
1261  for (i = 0; i < 3; i++)
1262  PACK_DOUBLE((this_grid.lowest)(i));
1263  for (i = 0; i < 3; i++)
1264  PACK_DOUBLE((this_grid.highest)(i));
1265  PACK_DOUBLE(this_grid.relative_size);
1266  for (i = 0; i < 3; i++)
1267  PACK_DOUBLE((this_grid.origin)(i));
1268  PACK_DOUBLE(this_grid.R2);
1269 
1270  // Store volume control ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1271  PACK_DOUBLE(ZSIZE(this_vol()));
1272  PACK_DOUBLE(YSIZE(this_vol()));
1273  PACK_DOUBLE(XSIZE(this_vol()));
1274  PACK_DOUBLE(STARTINGZ(this_vol()));
1275  PACK_DOUBLE(STARTINGY(this_vol()));
1276  PACK_DOUBLE(STARTINGX(this_vol()));
1277  }
1278  else if (typeinfoT == typeinfoI)
1279  {
1280  // We use a trick to save the grid information in the volume
1281  // If the following if is true the trick can not be used
1282  if (sizeof(float) != sizeof(int))
1284  "GridVolume is integer and (sizeof(float)!= sizeof(int)");
1285 
1286  for (i = 0; i < 3; i++)
1287  for (j = 0; j < 3; j++)
1288  PACK_INT((this_grid.basis)(i, j));
1289  for (i = 0; i < 3; i++)
1290  PACK_INT((this_grid.lowest)(i));
1291  for (i = 0; i < 3; i++)
1292  PACK_INT((this_grid.highest)(i));
1293  PACK_INT(this_grid.relative_size);
1294  for (i = 0; i < 3; i++)
1295  PACK_INT((this_grid.origin)(i));
1296  PACK_INT(this_grid.R2);
1297 
1298  // Store volume control ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1299  PACK_INT(ZSIZE(this_vol()));
1300  PACK_INT(YSIZE(this_vol()));
1301  PACK_INT(XSIZE(this_vol()));
1302  PACK_INT(STARTINGZ(this_vol()));
1303  PACK_INT(STARTINGY(this_vol()));
1304  PACK_INT(STARTINGX(this_vol()));
1305  }
1306  else
1307  REPORT_ERROR(ERR_TYPE_INCORRECT, "GridVolume must be double or int\n");
1308 
1309  sli++;
1310 
1311  // Write the whole volume ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1312  for (k = 0; k < ZSIZE(VOLMATRIX(this_vol)); k++)
1313  {
1314  for (i = 0; i < YSIZE(VOLMATRIX(this_vol)); i++)
1315  for (j = 0; j < XSIZE(VOLMATRIX(this_vol)); j++)
1316  DIRECT_VOLVOXEL(V, sli, i, j) = DIRECT_VOLVOXEL(this_vol, k, i, j);
1317  sli++;
1318  }
1319  }
1320 #undef PACK_DOUBLE
1321 #undef PACK_INT
1322 
1323  // Effectively write the volume .........................................
1324  V.write(fn);
1325  }
1326 
1330  void read(const FileName &fn, const std::string &basisName)
1331  {
1332  Image<T> V;
1333  Image<T> * sV;
1334  SimpleGrid sG;
1335  size_t sli = 0;
1336 
1337  float temp_float;
1338  size_t floatsize;
1339  const std::type_info &typeinfoT = typeid(T); // We need to know what kind
1340  // of variable is T
1341  const std::type_info &typeinfoD = typeid(double);
1342  const std::type_info &typeinfoI = typeid(int);
1343 
1344  floatsize = (size_t) sizeof(float);
1345  // We use a trick to save the grid information in the volume
1346  // If the following if is true the trick can not be used
1347  if ((typeid(T) == typeid(int)) && (sizeof(float) != sizeof(int)))
1348  REPORT_ERROR(ERR_TYPE_INCORRECT,"Error: GridVolume is integer and (sizeof(float)!= sizeof(int)");
1349 
1350  // Allocate memory ......................................................
1351  sG.basis.resize(3, 3);
1352  sG.lowest.resize(3);
1353  sG.highest.resize(3);
1354  sG.origin.resize(3);
1355 
1356  // Read Reconstructing volume from file .................................
1357  V.read(fn);
1358  if (basisName=="voxels")
1359  {
1360  V().setXmippOrigin();
1361  sV=new Image<double>;
1362  *sV=V;
1363  LV.push_back(sV);
1364  G=Create_CC_grid(1.0,ZSIZE(V()),YSIZE(V()),XSIZE(V()));
1365  }
1366  else
1367  {
1368 #define UNPACK_DOUBLE(v,cast) \
1369  {jj=pos%VOLMATRIX(V).xdim; ii=pos/VOLMATRIX(V).xdim; pos++; \
1370  (v)=(cast)VOLVOXEL(V,sli,ii,jj);}
1371 #define UNPACK_INT(v,cast) \
1372  {jj=pos%VOLMATRIX(V).xdim; ii=pos/VOLMATRIX(V).xdim; pos++; \
1373  memcpy( &temp_float, &(VOLVOXEL(V,sli,ii,jj)),floatsize);\
1374  (v)=(cast)temp_float;}
1375 
1376  while (sli < ZSIZE(V()))
1377  {
1378  int pos; // Position inside the control slice
1379  int ii; // Position inside the control slice
1380  int jj; // Position inside the control slice
1381  size_t k; // Auxiliary counters
1382  size_t i; // Auxiliary counters
1383  size_t j; // Auxiliary counters
1384  size_t Zdim;
1385  size_t Ydim;
1386  size_t Xdim;
1387  int Zinit;
1388  int Yinit;
1389  int Xinit;
1390 
1391  // Read Grid data ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1392  pos = 0;
1393  if (typeinfoT == typeinfoD)
1394  {
1395  for (i = 0; i < 3; i++)
1396  for (j = 0; j < 3; j++)
1397  UNPACK_DOUBLE((sG.basis)(i, j), double);
1398  for (i = 0; i < 3; i++)
1399  UNPACK_DOUBLE((sG.lowest)(i), int);
1400  for (i = 0; i < 3; i++)
1401  UNPACK_DOUBLE((sG.highest)(i), int);
1402  UNPACK_DOUBLE(sG.relative_size, double);
1403  for (i = 0; i < 3; i++)
1404  UNPACK_DOUBLE((sG.origin)(i), double);
1405  UNPACK_DOUBLE(sG.R2, double);
1406  }
1407  else if (typeinfoT == typeinfoI)
1408  {
1409  // We use a trick to save the grid information in the volume
1410  // If the following if is true the trick can not be used
1411  if (sizeof(float) != sizeof(int))
1413  "GridVolume is integer and (sizeof(float)!= sizeof(int)");
1414 
1415  for (i = 0; i < 3; i++)
1416  for (j = 0; j < 3; j++)
1417  UNPACK_INT((sG.basis)(i, j), double);
1418  for (i = 0; i < 3; i++)
1419  UNPACK_INT((sG.lowest)(i), int);
1420  for (i = 0; i < 3; i++)
1421  UNPACK_INT((sG.highest)(i), int);
1422  UNPACK_INT(sG.relative_size, double);
1423  for (i = 0; i < 3; i++)
1424  UNPACK_INT((sG.origin)(i), double);
1425  UNPACK_INT(sG.R2, double);
1426  }
1427  sG.inv_basis = sG.basis.inv();
1428 
1429  // Store Grid in the list of the grid volume
1430  G.add_grid(sG);
1431 
1432  // Read Volume Control Information ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1433  if (typeinfoT == typeinfoD)
1434  {
1435  UNPACK_DOUBLE(Zdim, int);
1436  UNPACK_DOUBLE(Ydim, int);
1437  UNPACK_DOUBLE(Xdim, int);
1438  UNPACK_DOUBLE(Zinit, int);
1439  UNPACK_DOUBLE(Yinit, int);
1440  UNPACK_DOUBLE(Xinit, int);
1441  }
1442  else if (typeinfoT == typeinfoI)
1443  {
1444  UNPACK_INT(Zdim, int);
1445  UNPACK_INT(Ydim, int);
1446  UNPACK_INT(Xdim, int);
1447  UNPACK_INT(Zinit, int);
1448  UNPACK_INT(Yinit, int);
1449  UNPACK_INT(Xinit, int);
1450  }
1451 
1452  // Set volume size and origin
1453  sV = new Image<T>;
1454  VOLMATRIX(*sV).initZeros(Zdim, Ydim, Xdim);
1455  STARTINGZ(VOLMATRIX(*sV)) = Zinit;
1456  STARTINGY(VOLMATRIX(*sV)) = Yinit;
1457  STARTINGX(VOLMATRIX(*sV)) = Xinit;
1458 #ifdef DEBUG
1459 
1460  std::cout << "The read grid is \n" << sG;
1461  std::cout << "Volume dimensions: " << Zdim << " x " << Ydim << " x "
1462  << Xdim << std::endl;
1463  std::cout << "Volume init: " << Zinit << " x " << Yinit << " x "
1464  << Xinit << std::endl;
1465 #endif
1466 
1467  sli++;
1468 
1469  // Read volume ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1470  for (k = 0; k < ZSIZE(VOLMATRIX(*sV)); k++)
1471  {
1472  for (i = 0; i < YSIZE(VOLMATRIX(*sV)); i++)
1473  for (j = 0; j < XSIZE(VOLMATRIX(*sV)); j++)
1474  {
1475 #ifdef DEBUG
1476  std::cout << "Reading from file position (" << sli << "," << i
1477  << "," << j << ") to subvolume position ("
1478  << k << "," << i << "," << j << ")\n";
1479 #endif
1480 
1481  DIRECT_VOLVOXEL(*sV, k, i, j) = DIRECT_VOLVOXEL(V, sli, i, j);
1482  }
1483  sli++;
1484  }
1485 
1486  // Store volume in the list
1487  LV.push_back(sV);
1488  }
1489 #undef UNPACK_DOUBLE
1490 #undef UNPACK_INT
1491  }
1492  }
1493 #undef DEBUG
1494 };
1495 
1497 
1498 // Show a grid volume ------------------------------------------------------
1500 template <class T>
1501 std::ostream& operator << (std::ostream &o, const GridVolumeT<T> &GV)
1502 {
1503  o << "Grid Volume -----------\n";
1504  o << GV.G;
1505  o << "Number of volumes= " << GV.VolumesNo() << std::endl;
1506  for (int i = 0; i < GV.VolumesNo(); i++)
1507  {
1508  o << "Volume " << i << "------------" << std::endl;
1509  o << GV(i)();
1510  }
1511  return o;
1512 }
1514 #endif
const Grid & grid() const
Definition: grids.h:991
void set_Y(const Matrix1D< double > &v)
Definition: grids.h:198
void get_volume(size_t n, Image< T > &V)
Definition: grids.h:961
void clear()
Definition: grids.h:943
#define YSIZE(v)
void universe2grid(const Matrix1D< double > &uv, Matrix1D< double > &gv) const
Definition: grids.h:349
#define VOLVOXEL(V, k, i, j)
#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
GridVolumeT(const Grid &_grid)
Definition: grids.h:798
SimpleGrid & operator()(size_t n)
Definition: grids.h:519
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void resize(const Matrix1D< double > &corner1, const Matrix1D< double > &corner2)
Definition: grids.h:873
SimpleGrid Create_CC_grid(double relative_size, const Matrix1D< double > &corner1, const Matrix1D< double > &corner2, const Matrix1D< double > &origin)
Definition: grids.cpp:196
void set_relative_size(double size)
Set relative_size.
Definition: grids.h:277
#define VOLMATRIX(V)
void get_SimpleGrid(size_t n, SimpleGrid &G)
Definition: grids.h:984
void grid2universe(const Matrix1D< double > &gv, Matrix1D< double > &uv) const
Definition: grids.h:318
void sqrt(Image< double > &op)
void Gdir_project_to_plane(const Matrix1D< double > &gr, const Matrix2D< double > &euler, Matrix1D< double > &result) const
Definition: grids.h:446
size_t GridsNo() const
Definition: grids.h:536
const SimpleGrid & operator()(size_t n) const
Definition: grids.h:504
~GridVolumeT()
Definition: grids.h:827
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
#define V3_MINUS_V3(a, b, c)
Definition: matrix1d.h:202
#define PACK_INT(v)
friend std::ostream & operator<<(std::ostream &o, const SimpleGrid &grid)
Definition: grids.cpp:47
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
std::vector< T > operator+(const std::vector< T > &v, const T &a)
Definition: vector_ops.h:51
void set_interest_radius(double _R)
Set reconstruction radius.
Definition: grids.h:259
void set_X(const Matrix1D< double > &v)
Definition: grids.h:191
Definition: grids.h:479
void Gproject_to_plane(const Matrix1D< double > &gr, double rot, double tilt, double psi, Matrix1D< double > &result) const
Definition: grids.h:381
GridVolumeT< double > GridVolume
Definition: grids.h:1496
bool is_interesting(const Matrix1D< double > &uv) const
Definition: grids.h:361
Matrix1D< double > lowest
Definition: grids.h:158
GridVolumeT(const GridVolumeT &_RV)
Definition: grids.h:789
#define UNPACK_INT(v, cast)
Matrix2D< double > basis
Definition: grids.h:148
#define STARTINGX(v)
#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
double R2
Definition: grids.h:170
#define DIRECT_VOLVOXEL(I, k, i, j)
#define STARTINGY(v)
Image< T > & operator()(size_t n)
Definition: grids.h:953
void adapt_to_grid(const Grid &_grid)
Definition: grids.h:838
#define V3_BY_CT(a, b, c)
Definition: matrix1d.h:238
size_t VolumesNo() const
Definition: grids.h:1003
Matrix2D< double > inv_basis
Definition: grids.h:153
void get_Z(Matrix1D< double > &v) const
Definition: grids.h:226
const Image< T > & operator()(size_t n) const
Definition: grids.h:968
#define XX(v)
Definition: matrix1d.h:85
#define GRIDVOLUME_BY_SCALAR(op)
Definition: grids.h:1008
GridVolumeT< T > operator/(T f, const GridVolumeT< T > &GV)
double get_relative_size() const
Get relative_size.
Definition: grids.h:283
void resize(const GridVolumeT< T1 > &GV)
Definition: grids.h:919
#define CEIL(x)
Definition: xmipp_macros.h:225
void get_Grid(Grid &G)
Definition: grids.h:997
double * f
Definition: basis.h:45
void assign(const GridVolumeT &RV)
Definition: grids.h:821
void setCol(size_t j, const Matrix1D< T > &v)
Definition: matrix2d.cpp:929
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
void initZeros()
Definition: grids.h:936
void assign(const SimpleGrid &SG)
Definition: grids.cpp:63
#define XSIZE(v)
void get_SimpleGrid(int n, SimpleGrid &G) const
Definition: grids.h:527
void read(const FileName &fn, const std::string &basisName)
Definition: grids.h:1330
void clear()
Definition: grids.h:559
void assign(const Grid &G)
Definition: grids.h:553
#define ZSIZE(v)
std::vector< T > & operator-=(std::vector< T > &_v1, const std::vector< T > &_v2)
Definition: vector_ops.h:211
void set_Z(const Matrix1D< double > &v)
Definition: grids.h:205
void Gproject_to_plane(const Matrix1D< double > &gr, const Matrix2D< double > &euler, Matrix1D< double > &result) const
Definition: grids.h:399
double relative_size
Measuring unit in the grid coordinate system.
Definition: grids.h:163
#define j
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define UNPACK_DOUBLE(v, cast)
#define YY(v)
Definition: matrix1d.h:93
void getCol(size_t j, Matrix1D< T > &v) const
Definition: matrix2d.cpp:890
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
void write(const FileName &fn) const
Definition: grids.h:1196
Matrix1D< double > origin
Origin of the grid in the Universal coordinate system.
Definition: grids.h:165
#define GRIDVOL_BY_GRIDVOL(op)
Definition: grids.h:1064
const SimpleGrid & grid(size_t n) const
Definition: grids.h:978
double psi(const double x)
int get_number_of_samples() const
Definition: grids.cpp:69
void add_grid(const SimpleGrid &SG)
Definition: grids.h:491
MatrixMultiplication< M > operator*(const MatrixExpression< M > &m, double v)
Definition: point.cpp:232
std::vector< T > & operator+=(std::vector< T > &_v1, const std::vector< T > &_v2)
Definition: vector_ops.h:193
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
#define SPEED_UP_tempsInt
Definition: xmipp_macros.h:408
void Gdir_project_to_plane(const Matrix1D< double > &gr, double rot, double tilt, double psi, Matrix1D< double > &result) const
Definition: grids.h:432
std::vector< T > & operator/=(std::vector< T > &v1, const std::vector< T > &v2)
Definition: vector_ops.h:159
double get_interest_radius() const
Get reconstruction radius.
Definition: grids.h:268
Incorrect type received.
Definition: xmipp_error.h:190
#define FOR_ALL_ELEMENTS_IN_COMMON_IN_ARRAY3D(V1, V2)
GridVolumeT()
Definition: grids.h:782
#define PACK_DOUBLE(v)
Incorrect value received.
Definition: xmipp_error.h:195
void prepare_grid()
Definition: grids.cpp:103
void Uproject_to_plane(const Matrix1D< double > &point, const Matrix1D< double > &direction, double distance, Matrix1D< double > &result)
Definition: geometry.cpp:39
#define STARTINGZ(v)
int * n
std::vector< T > & operator*=(std::vector< T > &v1, const std::vector< T > &v2)
Definition: vector_ops.h:148
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
#define ZZ(v)
Definition: matrix1d.h:101
GridVolumeT< T > operator-(T f, const GridVolumeT< T > &GV)
#define GRIDVOL_BY_GRIDVOLASSIG(op)
Definition: grids.h:1128
void get_Y(Matrix1D< double > &v) const
Definition: grids.h:219
void selfCEIL()
Definition: matrix1d.cpp:476
void getSize(int &Zdim, int &Ydim, int &Xdim) const
Definition: grids.h:245
#define V3_PLUS_V3(a, b, c)
Definition: matrix1d.h:190
void get_X(Matrix1D< double > &v) const
Definition: grids.h:212
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403