Xmipp  v3.23.11-Nereus
Macros | Functions
recons_misc.cpp File Reference
#include <fstream>
#include "recons_misc.h"
#include "basic_art.h"
#include "core/metadata_vec.h"
#include "core/symmetries.h"
#include "data/mask.h"
#include "data/projection.h"
#include "data/wavelet.h"
#include "symmetrize.h"
Include dependency graph for recons_misc.cpp:

Go to the source code of this file.

Macros

#define MODE8
 
#define NFEATURES   8
 
#define GET_RESULTS(fh, fn, avg, cov, N, idx)
 
#define POCS_N_measure   8
 
#define POCS_N_use   2
 

Functions

void buildReconsInfo (MetaDataVec &selfile, const FileName &fn_ctf, const SymList &SL, ReconsInfo *&IMG_Inf, bool do_not_use_symproj)
 
void sortPerpendicular (int numIMG, ReconsInfo *IMG_Inf, MultidimArray< int > &ordered_list, int N)
 
void noSort (int numIMG, MultidimArray< int > &ordered_list)
 
void sortRandomly (int numIMG, MultidimArray< int > &ordered_list)
 
void updateResidualVector (BasicARTParameters &prm, GridVolume &vol_basis, double &kappa, double &pow_residual_vol, double &pow_residual_imgs)
 

Macro Definition Documentation

◆ GET_RESULTS

#define GET_RESULTS (   fh,
  fn,
  avg,
  cov,
  N,
  idx 
)
Value:
fh.open(fn);\
if (!fh) \
REPORT_ERROR(ERR_IO_NOTOPEN,(std::string)"VariabilityClass::finishAnalysis: " \
"Cannot open "+fn+" for input"); \
n_previous=-1; \
while (!fh.eof()) { \
int n; fh >> n; \
if (n!=n_previous) { \
n_previous=n; N++; \
idx(n)=1; \
avg+=v[n]; \
aux.fromVector(v[n]); \
cov+=aux*aux.transpose(); \
}\
} \
avg/=N; \
cov/=N; \
aux.fromVector(avg); \
cov-=aux*aux.transpose();
File cannot be open.
Definition: xmipp_error.h:137
int * n

◆ MODE8

#define MODE8

Definition at line 412 of file recons_misc.cpp.

◆ NFEATURES

#define NFEATURES   8

◆ POCS_N_measure

#define POCS_N_measure   8

Definition at line 696 of file recons_misc.cpp.

◆ POCS_N_use

#define POCS_N_use   2

Definition at line 697 of file recons_misc.cpp.

Function Documentation

◆ buildReconsInfo()

void buildReconsInfo ( MetaDataVec selfile,
const FileName fn_ctf,
const SymList SL,
ReconsInfo *&  IMG_Inf,
bool  do_not_use_symproj 
)

Build from a Selection File and a Symmetry List. The result is stored in the Recons_info array which should point to NULL when it is not initialized.

Definition at line 37 of file recons_misc.cpp.

40 {
41  Matrix2D<double> L(4, 4), R(4, 4); // A matrix from the list
42  FileName fn_proj;
43  FileName fn_ctf1;
44  Projection read_proj;
45  bool is_there_ctf = false;
46  bool is_ctf_unique = false;
47 
48  int trueIMG = selfile.size();
49  selfile.firstRowId();
50  int numIMG;
51  if (!do_not_use_symproj)
52  numIMG = trueIMG * (SL.symsNo() + 1);
53  else
54  numIMG = trueIMG;
55 
56  // The next two ifs check whether there is a CTF file, and
57  // whether it is unique
58  if (fn_ctf != "")
59  {
60  is_there_ctf = true;
61  is_ctf_unique = true;
62  }
63  else if (selfile.containsLabel(MDL_CTF_MODEL))
64  {
65  is_there_ctf = true;
66  is_ctf_unique = false;
67  }
68 
69  if (IMG_Inf != nullptr)
70  delete [] IMG_Inf;
71  if ((IMG_Inf = new ReconsInfo[numIMG]) == nullptr)
72  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Build_Recons_Info: No memory for the sorting");
73 
74  int i = 0; // It will account for the number of valid projections processed
75  std::cout << "Reading angle information ...\n";
76  init_progress_bar(trueIMG);
77  for (size_t objId : selfile.ids())
78  {
79  ReconsInfo &imgInfo = IMG_Inf[i];
80  selfile.getValue(MDL_IMAGE,fn_proj,objId);
81  if (is_there_ctf && !is_ctf_unique)
82  selfile.getValue(MDL_CTF_MODEL,fn_ctf1,objId);
83  if (fn_proj != "")
84  {
85  // read_proj.read(fn_proj, false, HEADER);
86  // Filling structure
87  imgInfo.fn_proj = fn_proj;
88  imgInfo.row = selfile.getRowVec(objId);
89  imgInfo.row.detach();
90  if (is_ctf_unique)
91  imgInfo.fn_ctf = fn_ctf;
92  else if (is_there_ctf)
93  imgInfo.fn_ctf = fn_ctf1;
94  imgInfo.sym = -1;
95  imgInfo.seed = ROUND(65535 * rnd_unif());
96 
97  imgInfo.rot = imgInfo.tilt = imgInfo.psi = 0;
98 
99  selfile.getValue(MDL_ANGLE_ROT, imgInfo.rot,objId);
100  selfile.getValue(MDL_ANGLE_TILT, imgInfo.tilt,objId);
101  selfile.getValue(MDL_ANGLE_PSI, imgInfo.psi,objId);
102  // read_proj.getEulerAngles(imgInfo.rot, imgInfo.tilt, imgInfo.psi);
103  EULER_CLIPPING(imgInfo.rot, imgInfo.tilt, imgInfo.psi);
104 
105  // Any symmetry?
106  if (SL.symsNo() > 0 && !do_not_use_symproj)
107  {
108  for (int j = 0; j < SL.symsNo(); j++)
109  {
110  int sym_index = SYMINDEX(SL, j, i, trueIMG);
111  IMG_Inf[sym_index].fn_proj = imgInfo.fn_proj;
112  IMG_Inf[sym_index].seed = imgInfo.seed;
113  if (is_ctf_unique)
114  IMG_Inf[sym_index].fn_ctf = fn_ctf;
115  else if (is_there_ctf)
116  IMG_Inf[sym_index].fn_ctf = imgInfo.fn_ctf;
117  IMG_Inf[sym_index].sym = j;
118  SL.getMatrices(j, L, R);
119  L.resize(3, 3); // Erase last row and column
120  R.resize(3, 3); // as only the relative orientation
121  // is useful and not the translation
122  double drot, dtilt, dpsi;
123  Euler_apply_transf(L, R,
124  imgInfo.rot, imgInfo.tilt, imgInfo.psi,
125  drot, dtilt, dpsi);
126  IMG_Inf[sym_index].rot = (float)drot;
127  IMG_Inf[sym_index].tilt = (float)dtilt;
128  IMG_Inf[sym_index].psi = (float)dpsi;
129  }
130  }
131  }
132 
133  ++i; // I have processed one more image
134  if (i % 25 == 0)
135  progress_bar(i);
136  }
137  progress_bar(trueIMG);
138 }
void init_progress_bar(long total)
MDRowVec row
Header information of projection.
Definition: basic_art.h:63
Rotation angle of an image (double,degrees)
double psi
Psi angle.
Definition: basic_art.h:71
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Tilting angle of an image (double,degrees)
There is not enough memory for allocation.
Definition: xmipp_error.h:166
Special label to be used when gathering MDs in MpiMetadataPrograms.
Name for the CTF Model (std::string)
int symsNo() const
Definition: symmetries.h:268
virtual IdIteratorProxy< false > ids()
void Euler_apply_transf(const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1038
size_t size() const override
#define i
double rnd_unif()
#define EULER_CLIPPING(rot, tilt, psi)
Definition: geometry.h:471
double tilt
Tilting angle.
Definition: basic_art.h:69
size_t firstRowId() const override
int seed
Definition: basic_art.h:81
void progress_bar(long rlen)
FileName fn_ctf
CTF filename.
Definition: basic_art.h:65
#define ROUND(x)
Definition: xmipp_macros.h:210
FileName fn_proj
Projection filename.
Definition: basic_art.h:61
#define j
bool getValue(MDObject &mdValueOut, size_t id) const override
double rot
Rotational angle.
Definition: basic_art.h:67
MDRowVec getRowVec(size_t id)
void detach() override
bool containsLabel(const MDLabel label) const override
#define SYMINDEX(SL, sym_no, i, numIMG)
Definition: symmetries.h:110
Name of an image (std::string)

◆ noSort()

void noSort ( int  numIMG,
MultidimArray< int > &  ordered_list 
)

No projection sorting at all. This function directly returns the same order as in the selection file

Definition at line 222 of file recons_misc.cpp.

223 {
224  ordered_list.initLinear(0, numIMG - 1);
225 }
void initLinear(T minF, T maxF, int n=1, const String &mode="incr")

◆ sortPerpendicular()

void sortPerpendicular ( int  numIMG,
ReconsInfo IMG_Inf,
MultidimArray< int > &  ordered_list,
int  N = 2 
)

Sort projections orthogonally. This function sorts a number of images given by numIMG, whose information about their Euler angles are in IMG_inf, into an ordered list which gives the indexes. First an image is chosen randomly from the whole set. Then all images are compared to the first one, and the most perpendicular one is chosen. The remaining set of images are compared to this two images and the most perpendicular one to the former two is chosen, and so on until no image is left in the set.

If the result in ordered list is 4, 70, 54, 203, 1, 0, ... it means that the first image is the number 4, then goes the 70, then the 54, ...

If N!=-1 then the product is done only with the last N images. A very useful value is N=2

Definition at line 145 of file recons_misc.cpp.

147 {
148  int i, j;
149  MultidimArray<short> chosen(numIMG); // 1 if that image has been already
150  // chosen
151  double min_prod;
152  int min_prod_proj=0;
153  Matrix2D<double> v(numIMG, 3);
154  Matrix2D<double> euler;
155  MultidimArray<double> product(numIMG);
156 
157  // Initialization
158  ordered_list.resize(numIMG);
159  for (i = 0; i < numIMG; i++)
160  {
162  // Initially no image is chosen
163  A1D_ELEM(chosen, i) = 0;
164 
165  // Compute the Euler matrix for each image and keep only
166  // the third row of each one
167  Euler_angles2matrix(IMG_Inf[i].rot, IMG_Inf[i].tilt, 0., euler);
168  euler.getRow(2, z);
169  v.setRow(i, z);
170  }
171 
172  // Pick first projection as the first one to be presented
173  i = 0;
174  A1D_ELEM(chosen, i) = 1;
175  A1D_ELEM(ordered_list, 0) = i;
176 
177  // Choose the rest of projections
178  std::cout << "Sorting projections ...\n";
179  init_progress_bar(numIMG - 1);
180  Matrix1D<double> rowj, rowi_1, rowi_N_1;
181  for (i = 1; i < numIMG; i++)
182  {
183  // Compute the product of not already chosen vectors with the just
184  // chosen one, and select that which has minimum product
185  min_prod = MAXFLOAT;
186  v.getRow(A1D_ELEM(ordered_list, i - 1),rowi_1);
187  if (N != -1 && i > N)
188  v.getRow(A1D_ELEM(ordered_list, i - N - 1),rowi_N_1);
189  for (j = 0; j < numIMG; j++)
190  {
191  if (!A1D_ELEM(chosen, j))
192  {
193  v.getRow(j,rowj);
194  A1D_ELEM(product, j) += ABS(dotProduct(rowi_1,rowj));
195  if (N != -1 && i > N)
196  A1D_ELEM(product, j) -= ABS(dotProduct(rowi_N_1,rowj));
197  if (A1D_ELEM(product, j) < min_prod)
198  {
199  min_prod = A1D_ELEM(product, j);
200  min_prod_proj = j;
201  }
202  }
203  }
204 
205  // Store the chosen vector and mark it as chosen
206  A1D_ELEM(ordered_list, i) = min_prod_proj;
207  A1D_ELEM(chosen, min_prod_proj) = 1;
208 
209  // The progress bar is updated only every 10 images
210  if (i % 10 == 0)
211  progress_bar(i);
212  }
213 
214  // A final call to progress bar to finish a possible small piece
215  progress_bar(numIMG - 1);
216  std::cout << std::endl;
217 }
void init_progress_bar(long total)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
#define A1D_ELEM(v, i)
#define i
void progress_bar(long rlen)
#define ABS(x)
Definition: xmipp_macros.h:142
double z
#define MAXFLOAT
Definition: data_types.h:47
#define j
T dotProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1140
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871

◆ sortRandomly()

void sortRandomly ( int  numIMG,
MultidimArray< int > &  ordered_list 
)

Randomize the projections. This function sorts randomly a number of images given by numIMG.

Definition at line 230 of file recons_misc.cpp.

231 {
232  MultidimArray<int> chosen;
233 
234  // Initialisation
235  ordered_list.resize(numIMG);
236  chosen.initZeros(numIMG);
237 
238  std::cout << "Randomizing projections ...\n";
239  init_progress_bar(numIMG - 1);
240  int ptr = 0;
242  for (int i = numIMG; i > 0; i--)
243  {
244  // Jump a random number starting at the pointed projection
245  int rnd_indx = (int) rnd_unif(0, i) + 1;
246  while (rnd_indx > 0)
247  {
248  // Jump one not chosen image
249  ptr = (ptr + 1) % numIMG;
250  // Check it is not chosen, if it is, go on skipping
251  while (chosen(ptr))
252  {
253  ptr = (ptr + 1) % numIMG;
254  }
255  rnd_indx--;
256  }
257 
258  // Annotate this image
259  A1D_ELEM(ordered_list, i - 1) = ptr;
260  A1D_ELEM(chosen, ptr) = 1;
261 
262  // The progress bar is updated only every 10 images
263  if (i % 10 == 0)
264  progress_bar(i);
265  }
266 
267  // A final call to progress bar to finish a possible small piece
268  progress_bar(numIMG - 1);
269  std::cout << std::endl;
270 }
void init_progress_bar(long total)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define A1D_ELEM(v, i)
#define i
double rnd_unif()
void progress_bar(long rlen)
void initZeros(const MultidimArray< T1 > &op)
unsigned int randomize_random_generator()

◆ updateResidualVector()

void updateResidualVector ( BasicARTParameters prm,
GridVolume vol_basis,
double &  kappa,
double &  pow_residual_vol,
double &  pow_residual_imgs 
)

Update residual vector for WLS ART

Definition at line 275 of file recons_misc.cpp.

277 {
278  GridVolume residual_vol;
279  Projection read_proj, dummy_proj, new_proj;
280  FileName fn_resi, fn_tmp;
281  double sqrtweight, dim2;
282  Matrix2D<double> *A = nullptr;
283  std::vector<MultidimArray<double> > newres_imgs;
284  MultidimArray<int> mask;
285 
286  residual_vol.resize(vol_basis);
287  residual_vol.initZeros();
288 
289  // Calculate volume from all backprojected residual images
290  std::cout << "Backprojection of residual images " << std::endl;
291  if (!(prm.tell&TELL_SHOW_ERROR))
293 
294  for (int iact_proj = 0; iact_proj < prm.numIMG ; iact_proj++)
295  {
296  // backprojection of the weighted residual image
297  sqrtweight = sqrt(prm.residual_imgs[iact_proj].weight() / prm.sum_weight);
298  read_proj = prm.residual_imgs[iact_proj];
299  read_proj() *= sqrtweight;
300  dummy_proj().resize(read_proj());
301 
302  dummy_proj.setAngles(prm.IMG_Inf[iact_proj].rot,
303  prm.IMG_Inf[iact_proj].tilt,
304  prm.IMG_Inf[iact_proj].psi);
305 
306  project_GridVolume(residual_vol, prm.basis, dummy_proj,
307  read_proj, YSIZE(read_proj()), XSIZE(read_proj()),
308  prm.IMG_Inf[iact_proj].rot,
309  prm.IMG_Inf[iact_proj].tilt,
310  prm.IMG_Inf[iact_proj].psi, BACKWARD, prm.eq_mode,
311  prm.GVNeq, nullptr, nullptr, prm.ray_length, prm.threads);
312 
313  if (!(prm.tell&TELL_SHOW_ERROR))
314  if (iact_proj % XMIPP_MAX(1, prm.numIMG / 60) == 0)
315  progress_bar(iact_proj);
316  }
317  if (!(prm.tell&TELL_SHOW_ERROR))
318  progress_bar(prm.numIMG);
319 
320  // Convert to voxels: solely for output of power of residual volume
321  Image<double> residual_vox;
322  int Xoutput_volume_size = (prm.Xoutput_volume_size == 0) ?
323  prm.projXdim : prm.Xoutput_volume_size;
324  int Youtput_volume_size = (prm.Youtput_volume_size == 0) ?
325  prm.projYdim : prm.Youtput_volume_size;
326  int Zoutput_volume_size = (prm.Zoutput_volume_size == 0) ?
327  prm.projXdim : prm.Zoutput_volume_size;
328  prm.basis.changeToVoxels(residual_vol, &(residual_vox()),
329  Zoutput_volume_size, Youtput_volume_size, Xoutput_volume_size);
330  pow_residual_vol = residual_vox().sum2() / MULTIDIM_SIZE(residual_vox());
331  residual_vox.clear();
332 
333  std::cout << "Projection of residual volume; kappa = " << kappa << std::endl;
334  if (!(prm.tell&TELL_SHOW_ERROR))
336 
337  // Now that we have the residual volume: project in all directions
338  pow_residual_imgs = 0.;
339  new_proj().resize(read_proj());
340  mask.resize(read_proj());
341  BinaryCircularMask(mask, YSIZE(read_proj()) / 2, INNER_MASK);
342 
343  dim2 = (double)YSIZE(read_proj()) * XSIZE(read_proj());
344  for (int iact_proj = 0; iact_proj < prm.numIMG ; iact_proj++)
345  {
346  project_GridVolume(residual_vol, prm.basis, new_proj,
347  dummy_proj, YSIZE(read_proj()), XSIZE(read_proj()),
348  prm.IMG_Inf[iact_proj].rot,
349  prm.IMG_Inf[iact_proj].tilt,
350  prm.IMG_Inf[iact_proj].psi, FORWARD, prm.eq_mode,
351  prm.GVNeq, A, nullptr, prm.ray_length, prm.threads);
352 
353  sqrtweight = sqrt(prm.residual_imgs[iact_proj].weight() / prm.sum_weight);
354 
355  // Next lines like normalization in [EHL] (2.18)?
357  {
358  dAij(dummy_proj(), i, j) = XMIPP_MAX(1., dAij(dummy_proj(), i, j)); // to avoid division by zero
359  dAij(new_proj(), i, j) /= dAij(dummy_proj(), i, j);
360  }
361  new_proj() *= sqrtweight * kappa;
362 
363  /*
364  fn_tmp="residual_"+integerToString(iact_proj);
365  dummy_proj()=1000*prm.residual_imgs[iact_proj]();
366  dummy_proj.write(fn_tmp+".old");
367  */
368 
369  prm.residual_imgs[iact_proj]() -= new_proj();
370  pow_residual_imgs += prm.residual_imgs[iact_proj]().sum2();
371 
372  // Mask out edges of the images
373  apply_binary_mask(mask, prm.residual_imgs[iact_proj](), prm.residual_imgs[iact_proj](), 0.);
374 
375  /*
376  dummy_proj()=1000*new_proj();
377  dummy_proj.write(fn_tmp+".change");
378  dummy_proj()=1000*prm.residual_imgs[iact_proj]();
379  dummy_proj.write(fn_tmp+".new");
380  */
381 
382  if (!(prm.tell&TELL_SHOW_ERROR))
383  if (iact_proj % XMIPP_MAX(1, prm.numIMG / 60) == 0)
384  progress_bar(iact_proj);
385  }
386 
387  pow_residual_imgs /= dim2;
388  newres_imgs.clear();
389 
390  if (!(prm.tell&TELL_SHOW_ERROR))
391  progress_bar(prm.numIMG);
392 
393 }
void init_progress_bar(long total)
int numIMG
Total number of images to process (taking symmetries into account)
Definition: basic_art.h:348
#define YSIZE(v)
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
size_t projXdim
Projection X dimension.
Definition: basic_art.h:333
double psi
Psi angle.
Definition: basic_art.h:71
#define TELL_SHOW_ERROR
Definition: basic_art.h:272
Basis basis
Basis function. By default, blobs.
Definition: basic_art.h:97
void resize(const Matrix1D< double > &corner1, const Matrix1D< double > &corner2)
Definition: grids.h:873
void apply_binary_mask(const MultidimArray< int > &mask, const MultidimArray< T > &m_in, MultidimArray< T > &m_out, T subs_val=(T) 0)
Definition: mask.h:857
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
#define MULTIDIM_SIZE(v)
#define dAij(M, i, j)
void sqrt(Image< double > &op)
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
#define BACKWARD
Definition: blobs.cpp:1092
size_t projYdim
Projection Y dimension.
Definition: basic_art.h:336
void changeToVoxels(GridVolume &vol_basis, MultidimArray< double > *vol_voxels, int Zdim, int Ydim, int Xdim, int threads=1) const
Definition: basis.cpp:261
#define i
double tilt
Tilting angle.
Definition: basic_art.h:69
GridVolumeT< int > * GVNeq
Definition: basic_art.h:381
void project_GridVolume(GridVolumeT< T > &vol, const Basis &basis, Projection &proj, Projection &norm_proj, int Ydim, int Xdim, double rot, double tilt, double psi, int FORW, int eq_mode, GridVolumeT< int > *GVNeq, Matrix2D< double > *M, const MultidimArray< int > *mask, double ray_length, int threads)
ReconsInfo * IMG_Inf
Array with all the sorting information for each projection.
Definition: basic_art.h:342
void initZeros()
Definition: grids.h:936
#define XSIZE(v)
void progress_bar(long rlen)
#define j
#define FORWARD
Definition: blobs.cpp:1091
double rot
Rotational angle.
Definition: basic_art.h:67
void setAngles(double _rot, double _tilt, double _psi)
int threads
Number of threads to use. Can not be different than 1 when using MPI.
Definition: basic_art.h:267
void clear()
Definition: xmipp_image.h:144
std::vector< Projection > residual_imgs
Definition: basic_art.h:135
constexpr int INNER_MASK
Definition: mask.h:47