Xmipp  v3.23.11-Nereus
common_lines.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 
26 #include <fstream>
27 #include "common_lines.h"
28 #include "data/mask.h"
30 #include "data/fourier_filter.h"
31 #include "reconstruction/radon.h"
33 
34 /* Read parameters --------------------------------------------------------- */
36  fn_sel = getParam("-i");
37  fn_out = getParam("-o");
38  outputStyle = getParam("--ostyle");
39  lpf = getDoubleParam("--lpf");
40  hpf = getDoubleParam("--hpf");
41  stepAng = getDoubleParam("--stepAng");
42  mem = getDoubleParam("--mem");
43  Nthr = getIntParam("--thr");
44  scaleDistance = checkParam("--scaleDistance");
45  outlierFraction = getDoubleParam("--outlierFraction");
46  Nmpi = 1;
47 }
48 
49 /* Usage ------------------------------------------------------------------- */
52  "For every pair of images in the metadata, find the common line");
53  addParamsLine(" -i <file_in> : input selfile");
54  addParamsLine(" [-o <file_out=\"commonlines.txt\">] : Output filename");
55  addParamsLine(" [--ostyle <style=matrix>] : Output style");
56  addParamsLine(" where <style>");
57  addParamsLine(" matrix: Text file with the indexes of the corresponding common lines");
58  addParamsLine(" line_entries: Text file with a line for each matrix entry");
59  addParamsLine(" [--lpf <f=0.01>] : low pass frequency (0<lpf<0.5)");
60  addParamsLine(" [--hpf <f=0.35>] : high pass frequency (lpf<hpf<0.5)");
61  addParamsLine(" : Set both frequencies to -1 for no filter");
62  addParamsLine(" [--stepAng <s=1>] : angular step");
63  addParamsLine(" [--mem <m=1>] : float number with the memory available in Gb");
64  addParamsLine(" [--thr <thr=1>] : number of threads for each process");
65  addParamsLine(" [--scaleDistance] : scale the output distance to 16-bit integers");
66  addParamsLine(" [--outlierFraction <f=0.25>] : Fraction of expected outliers in the detection of common lines");
67 }
68 
69 /* Side info --------------------------------------------------------------- */
71 {
72  SF.read(fn_sel);
73  Nimg = SF.size();
74 
75  // Compute the number of images in each block
76  size_t Ydim, Zdim, Ndim;
77  getImageSize(SF, Xdim, Ydim, Zdim, Ndim);
78  Nblock = FLOOR(sqrt(mem*pow(2.0,30.0)/(2*Ydim*(360/stepAng)*sizeof(double))));
79  Nblock = XMIPP_MIN(Nblock,CEIL(((float)Nimg)/Nmpi));
80 
81  // Ask for memory for the common line matrix
83  for (int i = 0; i < Nimg * Nimg; i++)
84  CLmatrix.push_back(dummy);
85 }
86 
87 /* Show -------------------------------------------------------------------- */
89  std::cout << "File in: " << fn_sel << std::endl << "File out: "
90  << fn_out << std::endl << "Lowpass: " << lpf << std::endl
91  << "Highpass: " << hpf << std::endl << "StepAng: "
92  << stepAng << std::endl << "Memory(Gb): " << mem << std::endl
93  << "Block size: " << Nblock << std::endl << "N.Threads: "
94  << Nthr << std::endl;
95 }
96 
97 /* Get and prepare block --------------------------------------------------- */
102  std::vector<MultidimArray<std::complex<double> > > *blockRTFs;
103  std::vector<MultidimArray<double> > *blockRTs;
104 };
105 
106 void * threadPrepareImages(void * args)
107 {
108  auto * master = (ThreadPrepareImages *) args;
109  ProgCommonLine * parent = master->parent;
110  MetaDataVec SFi = *(master->SFi);
111  size_t Ydim, Xdim, Zdim, Ndim;
112  getImageSize(SFi, Xdim, Ydim, Zdim, Ndim);
113 
114  MultidimArray<int> mask;
115  mask.resize(Ydim, Xdim);
116  mask.setXmippOrigin();
117  BinaryCircularMask(mask, Xdim / 2, OUTSIDE_MASK);
118  auto NInsideMask = (int)(XSIZE(mask) * YSIZE(mask) - mask.sum());
119 
120  FourierFilter Filter;
121  Filter.w1 = -1;
122  if (parent->lpf > 0 && parent->hpf > 0)
123  {
124  Filter.FilterBand = BANDPASS;
125  Filter.w1 = parent->lpf;
126  Filter.w2 = parent->hpf;
127  }
128  else if (parent->lpf > 0)
129  {
130  Filter.FilterBand = LOWPASS;
131  Filter.w1 = parent->lpf;
132  }
133  else if (parent->hpf > 0)
134  {
135  Filter.FilterBand = HIGHPASS;
136  Filter.w1 = parent->hpf;
137  }
138  Filter.raised_w = Filter.w1 / 3;
139 
140  int ii = 0;
141  bool first = true;
142  Image<double> I;
143  FileName fnImg;
144  MultidimArray<double> RT, linei(Xdim);
145  FourierTransformer transformer;
146  transformer.setReal(linei);
147  MultidimArray<std::complex<double> >&mlineiFourier=transformer.fFourier;
149  for (size_t objId : SFi.ids())
150  {
151  if ((ii + 1) % parent->Nthr == master->myThreadID) {
152  I.readApplyGeo(SFi, objId);
153  I().setXmippOrigin();
154  MultidimArray<double> &mI = I();
155 
156  // Bandpass filter images
157  if (Filter.w1 > 0)
158  {
159  if (first)
160  {
161  Filter.generateMask(mI);
162  first = false;
163  }
164  Filter.applyMaskSpace(mI);
165  }
166 
167  // Cut the image outside the largest circle
168  // And compute the DC value inside the mask
169  double meanInside = 0;
171  if (A2D_ELEM(mask,i,j))A2D_ELEM(mI,i,j)=0;
172  else
173  meanInside+=A2D_ELEM(mI,i,j);
174  meanInside /= NInsideMask;
175 
176  // Subtract the mean inside the circle
178  if (!A2D_ELEM(mask,i,j))
179  A2D_ELEM(mI,i,j)-=meanInside;
180 
181  // Compute the Radon transform
182  Radon_Transform(I(), parent->stepAng, RT);
183 
184  // Normalize each line in the Radon Transform so that the
185  // multiplication of any two lines is actually their correlation index
186  RTFourier.resize(YSIZE(RT), XSIZE(mlineiFourier));
187  for (size_t i = 0; i < YSIZE(RT); i++) {
188  memcpy(&(DIRECT_A1D_ELEM(linei,0)),&DIRECT_A2D_ELEM(RT,i,0),XSIZE(linei)*sizeof(double));
189  linei.statisticsAdjust(0.,1.);
190  transformer.FourierTransform();
191  transformer.fReal->initZeros();
192  transformer.inverseFourierTransform();
193  memcpy(&DIRECT_A2D_ELEM(RTFourier,i,0),&(DIRECT_A1D_ELEM(mlineiFourier,0)),XSIZE(mlineiFourier)*sizeof(std::complex<double>));
194 
195  memcpy(&DIRECT_A2D_ELEM(RT,i,0),&(DIRECT_A1D_ELEM(linei,0)),XSIZE(linei)*sizeof(double));
196  }
197 
198  (*(master->blockRTFs))[ii] = RTFourier;
199  (*(master->blockRTs))[ii] = RT;
200  }
201  ii++;
202  }
203  return nullptr;
204 }
205 
207  std::vector<MultidimArray<std::complex<double> > > &blockRTFs,
208  std::vector<MultidimArray<double> > &blockRTs) {
209  // Get the selfile
210  MetaDataVec SFi;
211  SFi.selectPart(SF, i * Nblock, Nblock);
212 
213  // Ask for space for all the block images
214  int jmax = SFi.size();
217  for (int j = 0; j < jmax; j++)
218  {
219  blockRTFs.push_back(dummyF);
220  blockRTs.push_back(dummy);
221  }
222 
223  // Read and preprocess the images
224  auto * th_ids = new pthread_t[Nthr];
225  auto * th_args = new ThreadPrepareImages[Nthr];
226  for (int nt = 0; nt < Nthr; nt++) {
227  // Passing parameters to each thread
228  th_args[nt].parent = this;
229  th_args[nt].myThreadID = nt;
230  th_args[nt].SFi = &SFi;
231  th_args[nt].blockRTFs = &blockRTFs;
232  th_args[nt].blockRTs = &blockRTs;
233  pthread_create((th_ids + nt), nullptr, threadPrepareImages,
234  (void *) (th_args + nt));
235  }
236 
237  // Waiting for threads to finish
238  for (int nt = 0; nt < Nthr; nt++)
239  pthread_join(*(th_ids + nt), nullptr);
240 
241  // Threads structures are not needed any more
242  delete []th_ids;
243  delete []th_args;
244 }
245 
246 /* Process block ----------------------------------------------------------- */
248  std::vector<MultidimArray<std::complex<double> > > &RTFsi,
249  std::vector<MultidimArray<double> > &RTsi,
250  int idxi,
251  std::vector<MultidimArray<std::complex<double> > >&RTFsj,
252  std::vector<MultidimArray<double> > &RTsj,
253  int idxj,
254  ProgCommonLine *parent, CommonLine &result, FourierTransformer &transformer) {
255  MultidimArray<std::complex<double> > &RTFi = RTFsi[idxi];
256  MultidimArray<std::complex<double> > &RTFj = RTFsj[idxj];
257  MultidimArray<double> &RTi = RTsi[idxi];
258  MultidimArray<double> &RTj = RTsj[idxj];
259 
260  result.distanceij = 1e60;
261  result.angj = -1;
262  MultidimArray<std::complex<double> > lineFi, lineFj;
263  MultidimArray<double> linei, linej;
264  MultidimArray<double> correlationFunction;
265  int jmax;
266  for (size_t ii = 0; ii < YSIZE(RTFi) / 2 + 1; ii++) {
267  lineFi.aliasRow(RTFi,ii);
268  linei.aliasRow(RTi,ii);
269 
270  for (size_t jj=0; jj<YSIZE(RTFj); jj++)
271  {
272  lineFj.aliasRow(RTFj,jj);
273  linej.aliasRow(RTj,jj);
274 
275  // Compute distance between the two lines
276  fast_correlation_vector(lineFi, lineFj, correlationFunction, transformer);
277  correlationFunction.maxIndex(jmax);
278  double distance=1-A1D_ELEM(correlationFunction,jmax);
279 
280  // Check if this is the best match
281  if (distance<result.distanceij)
282  {
283  result.distanceij=distance;
284  result.angi=ii;
285  result.angj=jj;
286  result.jmax=jmax;
287  }
288  }
289  }
290  result.angi *= parent->stepAng;
291  result.angj *= parent->stepAng;
292 }
293 
297  int i;
298  int j;
299  std::vector<MultidimArray<std::complex<double> > > *RTFsi;
300  std::vector<MultidimArray<std::complex<double> > > *RTFsj;
301  std::vector<MultidimArray<double> > *RTsi;
302  std::vector<MultidimArray<double> > *RTsj;
303 }
304 ;
305 
306 void * threadCompareImages(void * args)
307 {
308  auto * master = (ThreadCompareImages *) args;
309  ProgCommonLine * parent = master->parent;
310 
311  int blockIsize = master->RTFsi->size();
312  int blockJsize = master->RTFsj->size();
313  FourierTransformer transformer;
314  MultidimArray<double> linei;
315  linei.resize(parent->Xdim);
316  transformer.setReal(linei);
317  for (int i = 0; i < blockIsize; i++) {
318  long int ii = parent->Nblock * master->i + i;
319  for (int j = 0; j < blockJsize; j++) {
320  // Check if this two images have to be compared
321  long int jj = parent->Nblock * master->j + j;
322  if (ii >= jj)
323  continue;
324  if ((ii * blockJsize + jj + 1) % parent->Nthr != master->myThreadID)
325  continue;
326 
327  // Effectively compare the two images
328  long int idx_ij = ii * parent->Nimg + jj;
330  *(master->RTFsi), *(master->RTsi), i,
331  *(master->RTFsj), *(master->RTsj), j,
332  parent, parent->CLmatrix[idx_ij], transformer);
333 
334  // Compute the symmetric element
335  long int idx_ji = jj * parent->Nimg + ii;
336  parent->CLmatrix[idx_ji].distanceij = parent->CLmatrix[idx_ij].distanceij;
337  parent->CLmatrix[idx_ji].angi = parent->CLmatrix[idx_ij].angj;
338  parent->CLmatrix[idx_ji].angj = parent->CLmatrix[idx_ij].angi;
339  parent->CLmatrix[idx_ji].jmax = -parent->CLmatrix[idx_ij].jmax;
340  }
341  }
342  return nullptr;
343 }
344 
346 {
347  if (i > j)
348  return;
349 
350  // Preprocess each one of the selfiles
351  std::vector<MultidimArray<std::complex<double> > > RTFsi, RTFsj;
352  std::vector<MultidimArray<double> > RTsi, RTsj;
353  getAndPrepareBlock(i, RTFsi, RTsi);
354  if (i != j)
355  getAndPrepareBlock(j, RTFsj, RTsj);
356 
357  // Compare all versus all
358  // Read and preprocess the images
359  auto * th_ids = new pthread_t[Nthr];
360  auto * th_args = new ThreadCompareImages[Nthr];
361  for (int nt = 0; nt < Nthr; nt++) {
362  // Passing parameters to each thread
363  th_args[nt].parent = this;
364  th_args[nt].myThreadID = nt;
365  th_args[nt].i = i;
366  th_args[nt].j = j;
367  th_args[nt].RTFsi = &RTFsi;
368  th_args[nt].RTsi = &RTsi;
369  if (i != j)
370  {
371  th_args[nt].RTFsj = &RTFsj;
372  th_args[nt].RTsj = &RTsj;
373  }
374  else
375  {
376  th_args[nt].RTFsj = &RTFsi;
377  th_args[nt].RTsj = &RTsi;
378  }
379  pthread_create((th_ids + nt), nullptr, threadCompareImages,
380  (void *) (th_args + nt));
381  }
382 
383  // Waiting for threads to finish
384  for (int nt = 0; nt < Nthr; nt++)
385  pthread_join(*(th_ids + nt), nullptr);
386 
387  // Threads structures are not needed any more
388  delete[] th_ids;
389  delete[] th_args;
390 }
391 
392 /* Qualify common lines ---------------------------------------------------- */
394 {
395  std::vector<double> distance;
396  size_t imax=CLmatrix.size();
397  distance.reserve(imax);
398  double dmax=imax;
399  for (size_t i=0; i<imax; ++i)
400  distance.push_back(CLmatrix[i].distanceij);
401 
402  std::sort(distance.begin(),distance.end());
403 
404  std::vector<double>::iterator dbegin=distance.begin();
405  std::vector<double>::iterator low;
406  for (size_t i=0; i<imax; ++i)
407  {
408  low=std::lower_bound(dbegin, distance.end(), CLmatrix[i].distanceij);
409  CLmatrix[i].percentile=1.0-(double)(low-dbegin)/dmax;
410  }
411 }
412 
413 /* Write results ----------------------------------------------------------- */
415 {
416  // Look for the minimum and maximum of the common line matrix
417  double minVal = 2, maxVal = -2;
418  if (scaleDistance)
419  {
420  for (int i = 0; i < Nimg; i++)
421  for (int j = 0; j < Nimg; j++)
422  {
423  double val = CLmatrix[i * Nimg + j].distanceij;
424  if (val > 0)
425  {
426  minVal = XMIPP_MIN(minVal,val);
427  maxVal = XMIPP_MAX(maxVal,val);
428  }
429  }
430  }
431 
432  // Write the common line matrix
433  if (outputStyle == "matrix") {
434  Matrix2D<int> CL(Nimg,Nimg);
435  CL.initConstant(-1);
436  for (int j = 1; j < Nimg; j++)
437  for (int i = 0; i < j; i++) {
438  int ii = i * Nimg + j;
439  MAT_ELEM(CL,i,j)= (int)round(CLmatrix[ii].angi/stepAng);
440  MAT_ELEM(CL,j,i)= (int)round(CLmatrix[ii].angj/stepAng);
441  }
442  CL.write(fn_out);
443  } else {
444  std::ofstream fh_out;
445  fh_out.open(fn_out.c_str());
446  if (!fh_out)
448  for (int j = 1; j < Nimg; j++)
449  for (int i = 0; i < j; i++) {
450  int ii = i * Nimg + j;
451  if (CLmatrix[ii].distanceij > 0) {
452  fh_out << j << " " << i << " ";
453  if (scaleDistance)
454  fh_out << round(65535*(CLmatrix[ii].distanceij-minVal)/
455  (maxVal-minVal)) << " ";
456  else
457  fh_out << CLmatrix[ii].distanceij << " ";
458  fh_out << round(CLmatrix[ii].angi/stepAng) << " "
459  << round(CLmatrix[ii].angj/stepAng) << " "
460  << CLmatrix[ii].jmax << " "
461  << CLmatrix[ii].percentile << std::endl;
462  }
463  }
464  fh_out.close();
465  }
466 
467  // Write the aligned images
468  int idx=0;
469  for (size_t objId : SF.ids())
470  {
471  SF.setValue(MDL_SHIFT_X,-shift(idx++)/2, objId); // *** FIXME: COSS Why /2?
472  SF.setValue(MDL_SHIFT_Y,-shift(idx++)/2, objId);
473  }
474  SF.write(fn_out.insertBeforeExtension("_aligned_images"));
475 }
476 
477 /* Main program ------------------------------------------------------------ */
479 {
481  int nmax=Nimg*(Nimg-1)/2;
482  solver.A.resize(nmax,Nimg*2);
483  solver.w.resize(nmax);
484  solver.b.resize(nmax);
485  int n=0;
486  for (int j = 1; j < Nimg; j++)
487  for (int i = 0; i < j; i++, n++) {
488  int ii = i * Nimg + j;
489  if (CLmatrix[ii].distanceij > 0) {
490  const CommonLine& cl=CLmatrix[ii];
491  double sini, cosi, sinj, cosj;
492  //sincos(DEG2RAD(cl.angi),&sini,&cosi);
493  sini = sin(DEG2RAD(cl.angi));
494  cosi = cos(DEG2RAD(cl.angi));
495  //sincos(DEG2RAD(cl.angj),&sinj,&cosj);
496  sinj = sin(DEG2RAD(cl.angj));
497  cosj = cos(DEG2RAD(cl.angj));
498  int idxi=2*i;
499  int idxj=2*j;
500  MAT_ELEM(solver.A,n,idxi)=cosi;
501  MAT_ELEM(solver.A,n,idxi+1)=sini;
502  MAT_ELEM(solver.A,n,idxj)=-cosj;
503  MAT_ELEM(solver.A,n,idxj+1)=-sinj;
504  VEC_ELEM(solver.b,n)=cl.jmax;
505  VEC_ELEM(solver.w,n)=cl.percentile;
506  }
507  }
508 
509  const double maxShiftError=1;
510  ransacWeightedLeastSquares(solver,shift,maxShiftError,10000,outlierFraction,Nthr);
511 }
512 
513 /* Main program ------------------------------------------------------------ */
515 {
516  produceSideInfo();
517 
518  // Process all blocks
519  int maxBlock = CEIL(((float)Nimg)/Nblock);
520  if (rank == 0)
521  init_progress_bar(maxBlock * maxBlock);
522  for (int i = 0; i < maxBlock; i++)
523  for (int j = 0; j < maxBlock; j++)
524  {
525  int numBlock = i * maxBlock + j;
526  if ((numBlock + 1) % Nmpi == rank)
527  processBlock(i, j);
528  if (rank == 0)
529  progress_bar(i * maxBlock + j);
530  }
531  if (rank == 0)
532  {
533  progress_bar(maxBlock * maxBlock);
535  solveForShifts();
536  writeResults();
537  }
538 }
539 
540 
541 /***************** Porting code from Yoel Shkolnisky **********************************
542  *
543  */
544 
545 void
546 randomQuaternions(int k, DMatrix &quaternions)
547 {
548  // function q=qrand(K)
549  // %
550  // % q=qrand(K)
551  // %
552  // % Generate K random uniformly distributed quaternions.
553  // % Each quaternions is a four-elements column vector. Returns a matrix of
554  // % size 4xK.
555  // %
556  // % The 3-sphere S^3 in R^4 is a double cover of the rotation group SO(3),
557  // % SO(3) = RP^3.
558  // % We identify unit norm quaternions a^2+b^2+c^2+d^2=1 with group elements.
559  // % The antipodal points (-a,-b,-c,-d) and (a,b,c,d) are identified as the
560  // % same group elements, so we take a>=0.
561  // %
562  quaternions.initGaussian(4, k);
563  //quaternions.resize(4, k);
564  //quaternions.initRandom(0., 1.);
565  saveMatrix("random_numbers.txt", quaternions);
566 
567  DVector q(4);
568 
569  for (int j = 0; j < k; ++j)
570  {
571  //Get the j-column that is the quaternion
572  quaternions.getCol(j, q);
573  q.selfNormalize();
574  if (XX(q) < 0)
575  q *= -1;
576  quaternions.setCol(j, q);
577  }
578  saveMatrix("random_quaternions.txt", quaternions);
579 }
580 
581 void saveMatrix(const char *fn, DMatrix &matrix)
582 {
583  std::fstream fs;
584  fs.open(fn, std::fstream::trunc | std::fstream::out);
585  fs.precision(16);
586 
587  for (size_t j = 0; j < MAT_YSIZE(matrix); ++j)
588  {
589  for (size_t i = 0; i < MAT_XSIZE(matrix); ++i)
590  {
591  fs << std::scientific << dMij(matrix, j, i) << "\t";
592  //std::cerr << dAij(matrix, j, i) << " ";
593  }
594  fs << std::endl;
595  //std::cerr << std::endl;
596  }
597  fs.close();
598  //std::cerr << "DEBUG_JM: leaving saveMatrix" <<std::endl;
599 }
600 
601 void quaternionToMatrix(const DVector &q, DMatrix &rotMatrix)
602 {
603  // function rot_matrix = q_to_rot(q)
604  // %
605  // % Convert a quaternion into a rotation matrix.
606  // %
607 #define q0 dMi(q, 0)
608 #define q1 dMi(q, 1)
609 #define q2 dMi(q, 2)
610 #define q3 dMi(q, 3)
611 
612  rotMatrix.resize(3, 3);
613 
614  rotMatrix(0, 0) = POW2(q0) + POW2(q1) - POW2(q2) - POW2(q3);
615  rotMatrix(0, 1) = 2 * q1 * q2 - 2 * q0 * q3;
616  rotMatrix(0, 2) = 2 * q0 * q2 + 2 * q1 * q3;
617 
618  rotMatrix(1, 0) = 2 * q1 * q2 + 2 * q0 * q3;
619  rotMatrix(1, 1) = POW2(q0) - POW2(q1) + POW2(q2) - POW2(q3);
620  rotMatrix(1, 2) = -2 * q0 * q1 + 2 * q2 * q3;
621 
622  rotMatrix(2, 0) = -2 * q0 * q2 + 2 * q1 * q3;
623  rotMatrix(2, 1) = 2 * q0 * q1 + 2 * q2 * q3;
624  rotMatrix(2, 2) = POW2(q0) - POW2(q1) - POW2(q2) + POW2(q3);
625 
626  //saveMatrix("rot_matrix.txt", rotMatrix);
627 }
628 
629 
630 
631 #define AXIS(var) DVector var(3); var.initZeros()
632 
633 
634 // function [idx1,idx2,Z3]=commonline_q(q,k1,k2,n_theta)
635 // %
636 // % Given a Kx4 array of quaternions, find the common lines between
637 // % projections k1 and k2. Each projection has n_theta Fourier rays.
638 // %
639 // % idx1 is the index of the common line in projection k1. idx2 is the index
640 // % of the common line in projection k2. Z3 is the direction vector of the
641 // % common line.
642 // %
643 // % Yoel Shkolnisky, October 2008.
644 
645 void quaternionCommonLines(const DMatrix &quaternions, CommonLineInfo &clInfo)
646 // clInfo serve as input param: k1, k2 and nRays
647 // and as output: idx1, idx2 and vector
648 {
649  DVector qa1(4);
650  DVector qa2(4); //quaternions k1 and k2
651  DMatrix R1, R2; //rotation matrixes
652 
653  for (int i = 0; i < 4; ++i)
654  {
655  qa1(i) = quaternions(i, clInfo.getImage(0));
656  qa2(i) = quaternions(i, clInfo.getImage(1));
657  }
658  quaternionToMatrix(qa1, R1);
659  quaternionToMatrix(qa2, R2);
660  //Should be the inversve, but transpose is fine here
661  // R1.selfInverse();
662  // R2.selfInverse();
663  R1 = R1.transpose();
664  R2 = R2.transpose();
665 
666  // % Rotated coordinate system is the columns of the rotation matrix.
667  // % We use explicit multiplication to show which column corresponds to x,
668  // % which to y, and which to z. See commonline_euler for the difference.
669  // X1=R1*([1 0 0].');
670  // Y1=R1*([0 1 0].');
671  // Z1=R1*([0 0 1].');
672  //
673  // X2=R2*([1 0 0].');
674  // Y2=R2*([0 1 0].');
675  // Z2=R2*([0 0 1].');
676  //
677  // Z3=[Z1(2)*Z2(3)-Z1(3)*Z2(2);...
678  // Z1(3)*Z2(1)-Z1(1)*Z2(3);...
679  // Z1(1)*Z2(2)-Z1(2)*Z2(1)];
680  DVector X1, Y1, Z1, X2, Y2, Z2;
681  DVector &Z3 = clInfo.vector;
682  R1.getCol(0, X1);
683  R1.getCol(1, Y1);
684  R1.getCol(2, Z1);
685 
686  R2.getCol(0, X2);
687  R2.getCol(1, Y2);
688  R2.getCol(2, Z2);
689 
690  XX(Z3) = YY(Z1) * ZZ(Z2) - ZZ(Z1) * YY(Z2);
691  YY(Z3) = ZZ(Z1) * XX(Z2) - XX(Z1) * ZZ(Z2);
692  ZZ(Z3) = XX(Z1) * YY(Z2) - YY(Z1) * XX(Z2);
693 
694  double normZ3 = Z3.module();
695 
696  if (normZ3 < 1.0e-8)
697  REPORT_ERROR(ERR_NUMERICAL, "GCAR:normTooSmall','Images have same orientation");
698 
699  Z3 /= normZ3;
700  DVector Z3_t(Z3);
701  Z3_t.selfTranspose();
702 
703  // % Compute coordinates of the common-line in each local coordinate system.
704  // XY1=[X1 Y1];
705  // XY2=[X2 Y2];
706  // c1=(Z3.')*XY1;
707  // c2=(Z3.')*XY2;
708  DMatrix XY1(3, 2), XY2(3, 2);
709  XY1.setCol(0, X1);
710  XY1.setCol(1, Y1);
711  XY2.setCol(0, X2);
712  XY2.setCol(1, Y2);
713  DVector c1 = Z3_t * XY1;
714  DVector c2 = Z3_t * XY2;
715  // % Verify that the common-line is indeed common to both planes. The
716  // % following warning should never happen! Just to make sure nothing went
717  // % terribly wrong.
718  // ev1=XY1*c1(:)-Z3;
719  // ev2=XY2*c2(:)-Z3;
720  c1.selfTranspose();
721  c2.selfTranspose();
722  DVector ev1 = XY1 * c1 - Z3;
723  DVector ev2 = XY2 * c2 - Z3;
724 
725  double normEv1 = ev1.module() / normZ3;
726  double normEv2 = ev2.module() / normZ3;
727 
728  if (normEv1 > 1.0e-12 || normEv2 > 1.0e-12)
730  formatString("GCAR:largeErrors: Common line is not common. Error1 = %f, Error2 = %f", normEv1, normEv2));
731  // % Compute angle of the common line at each projection's coordinate system
732  // theta1=atan2(c1(2),c1(1));
733  // theta2=atan2(c2(2),c2(1));
734  //
735  // PI=4*atan(1.0);
736  // theta1=theta1+PI; % Shift from [-pi,pi] to [0,2*pi].
737  // theta2=theta2+PI;
738  //std::cerr << "DEBUG_JM: c1: " << c1 <<std::endl;
739  //std::cerr << "DEBUG_JM: c2: " << c2 << std::endl;
740  double theta1 = atan2(YY(c1), XX(c1)) + PI;
741  double theta2 = atan2(YY(c2), XX(c2)) + PI;
742  //
743  clInfo.setIndex(0, theta1);
744  clInfo.setIndex(1, theta2);
745 }//function quaternionCommonLines
746 
747 
748 // function [clmatrix,clcorr]=clmatrix_cheat_q(q,n_theta)
749 // %
750 // % Build common lines matrix using the true quaternions corresponding to the
751 // % projections orientations. Each projection has n_theta rays.
752 // % clcorr is set to 1.0e-8.
753 // %
754 // % Yoel Shkolnisky, October 2008.
755 //
756 // N=size(q,2);
757 //
758 // clmatrix=zeros(N); % common lines matrix
759 // clcorr=zeros(N); % correlation coefficient for ach common line
760 //
761 // for k1=1:N-1
762 // for k2=k1+1:N
763 // [idx1,idx2]=commonline_q(q,k1,k2,n_theta);
764 // clmatrix(k1,k2)=idx1+1;
765 // clmatrix(k2,k1)=idx2+1;
766 // clcorr(k1,k2)=1.0e-8;
767 // end
768 // end
769 void commonlineMatrixCheat(const DMatrix &quaternions, size_t nRays,
770  DMatrix &clMatrix, DMatrix &clCorr)
771 {
772  int n = quaternions.Xdim();
773 
774  clMatrix.initConstant(n, n, 0);
775  clCorr.initZeros(n, n);
776 
777  CommonLineInfo clInfo(nRays);
778 
779  for (int i = 0; i < n - 1; ++i)
780  for (int j = i + 1; j < n; ++j)
781  {
782  clInfo.setImages(i, j);
783  quaternionCommonLines(quaternions, clInfo);
784  dMij(clMatrix, i, j) = clInfo.getIndex(0);
785  dMij(clMatrix, j, i) = clInfo.getIndex(1);
786  dMij(clCorr, i, j) = 1.0e-8;
787  }
788 
789 }//function commonlineMatrixCheat
790 
791 
792 
793 void anglesRotationMatrix(size_t nRays, int clI, int clJ,
794  const DVector &Q1, const DVector &Q2,
795  DMatrix &R)
796 {
797 
798  double alpha1 = TWOPI * clI / nRays;
799  double alpha2 = TWOPI * clJ / nRays;
800  DVector N1(3);
801  vectorProduct(Q1, Q2, N1);
802  N1.selfNormalize();
803 
804  DMatrix U(3, 3);
805 
806  //sincos(alpha1, &dMij(U, 1, 0), &dMij(U, 0, 0));
807  dMij(U, 1, 0) = sin(alpha1);
808  dMij(U, 0, 0) = cos(alpha1);
809  //sincos(alpha2, &dMij(U, 1, 1), &dMij(U, 0, 1));
810  dMij(U, 1, 1) = sin(alpha2);
811  dMij(U, 0, 1) = cos(alpha2);
812  dMij(U, 2, 2) = 1.;
813 
814  if (U.det3x3() < 0)
815  dMij(U, 2, 2) = -1.; //% Make sure we have a right-handed system)
816 
817  DMatrix Q(3, 3);
818  Q.setCol(0, Q1);
819  Q.setCol(1, Q2);
820  Q.setCol(2, N1);
821 
822  U.selfInverse();
823  DMatrix T = Q * U;
824  T.svd(U, N1, Q);
825  R = U * Q.transpose();
826 }//function
827 
828 constexpr long double EPS = 1.0e-13; // % Should be 1.0e-13 after fixing XXX below.
829 constexpr int MAX_COND = 1000; // % Largest allowed condition number for the system of equations
830 #define cl(i, j) dMij(clMatrix, k##i, k##j)
831 
835 int tripletRotationMatrix(const DMatrix &clMatrix, size_t nRays,
836  int k1, int k2, int k3, DMatrix &R)
837 {
838  DMatrix G(3, 3), Q;
839  // % Find Q12, Q13, Q23
840  double factor = TWOPI / nRays;
841  double a = cos(factor * (cl(3,2)-cl(3,1)));
842  double b = cos(factor * (cl(2,3)-cl(2,1)));
843  double c = cos(factor * (cl(1,3)-cl(1,2)));
844 
845  if (1 + 2 * a * b * c - (POW2(a) + POW2(b) + POW2(c))<1.0e-5)
846  return SMALL_TRIANGLE;
847 
848  G.initIdentity();
849  // Compute G matrix according to (4.2)
850  dMij(G, 0, 1) = a;
851  dMij(G, 0, 2) = b;
852  dMij(G, 1, 0) = a;
853  dMij(G, 1, 2) = c;
854  dMij(G, 2, 0) = b;
855  dMij(G, 2, 1) = c;
856 
857  cholesky(G, Q);
858 
859  //Our cholesky gives us the lower triangular matrix
860  //so we need to transpose to have the same as in Yoel code
861  //that's why we take now rows instead of columns
862  DVector Q12, Q13, Q23;
863  Q.getRow(0, Q23);
864  Q.getRow(1, Q13);
865  Q.getRow(2, Q12);
866  Q12.setCol();
867  Q13.setCol();
868  Q23.setCol();
869 
870  DMatrix R1, R2;
871  anglesRotationMatrix( nRays, (int)cl(1, 2), (int)cl(1, 3), Q12, Q13, R1);
872  anglesRotationMatrix( nRays, (int)cl(2, 1), (int)cl(2, 3), Q12, Q23, R2);
873  // Compute rotation matrix according to (4.6)
874  R = R1.transpose() * R2;
875 
876  return 0;
877 }//function tripleRotationMatrix
878 
882 void putRotationMatrix(const DMatrix &R, int k1, int k2, DMatrix &syncMatrix)
883 {
884 #define SET_POINT(x, y) dMij(syncMatrix, x+2*k1, y+2*k2) = dMij(R, x, y)
885  SET_POINT(0, 0);
886  SET_POINT(0, 1);
887  SET_POINT(1, 0);
888  SET_POINT(1, 1);
889 }
890 
891 //%
892 //% Construct the CryoEM synchronization matrix, given a common lines matrix
893 //% clmatrix, that was constructed using angular resolution of L radial lines
894 //% per image.
895 //%
896 //% refq (optional) are the quaternions used to computed the common lines
897 //% matrix.
898 //%
899 //% Yoel Shkolnisky, August 2010.
900 void computeSyncMatrix(const DMatrix &clMatrix, size_t nRays, DMatrix &sMatrix)
901 {
902  int K = clMatrix.Xdim();
903  DMatrix J, R, S(3,3);
904  J.initIdentity(3);
905  dMij(J, 2, 2) = -1;
906  int kk;
907  int result = 0;
908 
909  sMatrix.initIdentity(2*K);
910 
911  for (int k1 = 0; k1 < K - 1; ++k1)
912  {
913  for (int k2 = k1 + 1; k2 < K; ++k2)
914  {
915  kk = 0; //% Each triplet (k1,k2,k3) defines some rotation matrix from
916  // % image k1 to image k2. kk counts the number of such
917  // % rotations, that is, the number of thrid images k3 that give
918  // % rise to a rotation from image k1 to image k2. Not all
919  // % images k3 give rise to such a rotation, since, for example
920  // % the resuling triangle can be too small.
921 
922  //For now average all rotation matrixes, maybe later on
923  // we will need to store all of them for a better estimation
924  // than just average
925  S.initZeros();
926 
927  for (int k3 = 0; k3 < K; ++k3)
928  if (k3 != k1 && k3 != k2)
929  {
930  result = tripletRotationMatrix(clMatrix, nRays, k1, k2, k3, R);
931  if (result >= 0)
932  {
933  S += R;
934  ++kk;
935  }
936  std::cerr << "DEBUG_JM: triplet: " << formatString("%d %d, %d", k1, k2, k3) << std::endl;
937  std::cerr << "DEBUG_JM: R: " << R << std::endl;
938  }
939  if (kk > 0)
940  S /= kk;
941  putRotationMatrix(S, k1, k2, sMatrix);
942  putRotationMatrix(S.transpose(), k2, k1, sMatrix);
943  }
944  }
945 }//function computeSyncMatrix
946 
947 void rotationsFromSyncMatrix(const DMatrix &sMatrix)
948 {
949  int K = sMatrix.Xdim() / 2;
950  int Kx3 = 3 * K;
951 
952  DMatrix U, V, V1(3, K), V2(3, K);
953  DVector W;
954  IVector indexes;
955  sMatrix.svd(U, W, V);
956  indexes.resizeNoCopy(W);
957  indexes.enumerate();
958 
959  //std::cerr << "DEBUG_JM: W: " << W << std::endl;
960 
961 #define SORTED_INDEX(i) dMi(indexes, i)
962 #define SORTED_ELEM(M, i) dMi(M, SORTED_INDEX(i))
963 
964  //Order by insertion sort
965  int iAux;
967  for (int j = i; j > 0 && SORTED_ELEM(W, j) > SORTED_ELEM(W, j-1); --j)
968  VEC_SWAP(indexes, j, j-1, iAux);
969 
970 // std::cerr << "DEBUG_JM: VEC_XSIZE(indexes): " << VEC_XSIZE(indexes) << std::endl;
971 // std::cerr << "DEBUG_JM: 10 bigger eigenvalues:" <<std::endl;
972 // std::cerr << "DEBUG_JM: indexes: " << indexes << std::endl;
973 // for (int i = 0; i < VEC_XSIZE(indexes); ++i)
974 // std::cerr << SORTED_ELEM(W, i) << std::endl;
975 
976  for (int i = 0; i < K; ++i)
977  {
978  iAux = 2 * i;
979  for (int j = 0; j < 3; ++j)
980  {
981  dMij(V1, j, i) = dMij(V, iAux, SORTED_INDEX(j));
982  dMij(V2, j, i) = dMij(V, iAux+1, SORTED_INDEX(j));
983  }
984  }
985 
986  std::cerr << "DEBUG_JM: V1: " << V1 << std::endl;
987  std::cerr << "DEBUG_JM: V2: " << V2 << std::endl;
988 
989  //% 3*K equations in 9 variables (3 x 3 matrix entries).
990  DMatrix equations(Kx3, 9);
991  int index;
992 
993  for (int k = 0; k < K; ++k)
994  for (int i = 0; i < 3; ++i)
995  for (int j = 0; j < 3; ++j)
996  {
997  index = 3 * i + j;
998  iAux = 3 * k;
999  dMij(equations, iAux, index) = dMij(V1, i, k) * dMij(V1, j, k);
1000  dMij(equations, iAux+1, index) = dMij(V2, i, k) * dMij(V2, j, k);
1001  dMij(equations, iAux+2, index) = dMij(V1, i, k) * dMij(V2, j, k);
1002  }
1003 // std::cerr << "DEBUG_JM: equations: " << equations << std::endl;
1004  PseudoInverseHelper pih;
1005 
1006  DMatrix &trunc_equations = pih.A;
1007  trunc_equations.resizeNoCopy(Kx3, 6);
1008  //Use vector W to select columns from equations
1009  int cols[6] = {0, 1, 2, 4, 5, 8};
1010  for (int i = 0; i < 6; ++i)
1011  {
1012  equations.getCol(cols[i], W);
1013  trunc_equations.setCol(i, W);
1014  }
1015 
1016  DVector &b = pih.b;
1017  b.initConstant(Kx3, 1.);
1018  for (int i = 2; i < Kx3; i+=3)
1019  dMi(b, i) = 0.;
1020 
1021  //% Find the least squares approximation
1022  DVector ATA_vec;
1023  DMatrix ATA(3, 3);
1024 
1025  //C
1026  solveLinearSystem(pih, ATA_vec);
1027 
1028 // std::cerr << "DEBUG_JM: trunc_equations: " << trunc_equations << std::endl;
1029 // saveMatrix("truncated.txt", trunc_equations);
1030 // std::cerr << "DEBUG_JM: b: " << b << std::endl;
1031 // std::cerr << "DEBUG_JM: ATA_vec: " << ATA_vec << std::endl;
1032 
1033  dMij(ATA, 0, 0) = dMi(ATA_vec, 0);
1034  dMij(ATA, 0, 1) = dMi(ATA_vec, 1);
1035  dMij(ATA, 0, 2) = dMi(ATA_vec, 2);
1036  dMij(ATA, 1, 0) = dMi(ATA_vec, 1);
1037  dMij(ATA, 1, 1) = dMi(ATA_vec, 3);
1038  dMij(ATA, 1, 2) = dMi(ATA_vec, 4);
1039  dMij(ATA, 2, 0) = dMi(ATA_vec, 2);
1040  dMij(ATA, 2, 1) = dMi(ATA_vec, 4);
1041  dMij(ATA, 2, 2) = dMi(ATA_vec, 5);
1042 
1043  std::cerr << "DEBUG_JM: ATA: " << ATA << std::endl;
1044 
1045  DMatrix A, R1, R2;
1046  cholesky(ATA, A);
1047  A = A.transpose();
1048 
1049  std::cerr << "DEBUG_JM: A: " << A << std::endl;
1050 
1051  R1 = A * V1;
1052  R2 = A * V2;
1053  //DMatrix R3(R1);
1054  DVector v1, v2, v3(3);
1055  std::vector<DMatrix> rotations(K);
1056 
1057  MetaDataVec MD("images.xmd");
1058  auto idIt(MD.ids().begin());
1059  for (int i = 0; i < K; ++i)
1060  {
1061  DMatrix &R = rotations[i];
1062  R.resizeNoCopy(3, 3);
1063  R1.getCol(i, v1);
1064  R2.getCol(i, v2);
1065  vectorProduct(v1, v2, v3);
1066  //R3.setCol(i, v3);
1067  R.setCol(0, v1);
1068  R.setCol(1, v2);
1069  R.setCol(2, v3);
1070  //% Enforce R to be a rotation (in case the error is large)
1071  R.svd(U, W, V);
1072  R = U * V.transpose();
1073 
1074  double rot, tilt, psi;
1075  //
1076  Euler_matrix2angles(R.transpose(), rot, tilt, psi);
1077  MD.setValue(MDL_ANGLE_ROT,rot,*idIt);
1078  MD.setValue(MDL_ANGLE_TILT,tilt,*idIt);
1079  MD.setValue(MDL_ANGLE_PSI,psi,*idIt);
1080  ++idIt;
1081 
1082  std::cerr << "DEBUG_JM: R" << i << " : " << R << std::endl;
1083  }
1084  MD.write("imagesReconstruction.xmd");
1085 }//function rotationsFromSyncMatrix
1086 
std::vector< MultidimArray< double > > * blockRTs
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
void init_progress_bar(long total)
size_t Xdim() const
Definition: matrix2d.h:575
double lpf
Low pass filter.
Definition: common_lines.h:74
#define SORTED_INDEX(i)
int * nmax
Rotation angle of an image (double,degrees)
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
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
double module() const
Definition: matrix1d.h:983
double getDoubleParam(const char *param, int arg=0)
void inverseFourierTransform()
Definition: xmipp_fftw.cpp:329
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
String outputStyle
Output style.
Definition: common_lines.h:68
#define VEC_SWAP(v, i, j, aux)
Definition: matrix1d.h:248
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void setIndex(int i, double theta)
Definition: common_lines.h:184
void quaternionCommonLines(const DMatrix &quaternions, CommonLineInfo &clInfo)
void processBlock(int i, int j)
#define SET_POINT(x, y)
doublereal * c
std::vector< MultidimArray< double > > * RTsi
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
void initConstant(T val)
Definition: matrix2d.h:602
void setImages(int k1, int k2)
Definition: common_lines.h:178
constexpr signed int SMALL_TRIANGLE
Definition: common_lines.h:204
#define q0
MultidimArray< std::complex< double > > fFourier
Definition: xmipp_fftw.h:70
void sqrt(Image< double > &op)
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
Tilting angle of an image (double,degrees)
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
#define BANDPASS
constexpr int MAX_COND
CommonLine Parameters.
Definition: common_lines.h:60
Shift for the image in the X axis (double)
FileName insertBeforeExtension(const String &str) const
#define DIRECT_A2D_ELEM(v, i, j)
#define A1D_ELEM(v, i)
void getAndPrepareBlock(int i, std::vector< MultidimArray< std::complex< double > > > &blockRTFs, std::vector< MultidimArray< double > > &blockRTs)
void getImageSize(const MetaData &md, size_t &Xdim, size_t &Ydim, size_t &Zdim, size_t &Ndim, MDLabel image_label)
void commonlineMatrixCheat(const DMatrix &quaternions, size_t nRays, DMatrix &clMatrix, DMatrix &clCorr)
void maxIndex(int &jmax) const
int getImage(int i)
Definition: common_lines.h:168
void anglesRotationMatrix(size_t nRays, int clI, int clJ, const DVector &Q1, const DVector &Q2, DMatrix &R)
#define TWOPI
Definition: xmipp_macros.h:111
Special label to be used when gathering MDs in MpiMetadataPrograms.
void selectPart(const MetaData &mdIn, size_t startPosition, size_t numberOfObjects, const MDLabel sortLabel=MDL_OBJID) override
void write(const FileName &outFile, WriteModeMetaData mode=MD_OVERWRITE) const
void enumerate()
Definition: matrix1d.cpp:98
void selfNormalize()
Definition: matrix1d.cpp:723
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
Matrix1D< T > vectorProduct(const Matrix1D< T > &v1, const Matrix1D< T > &v2)
Definition: matrix1d.h:1165
double hpf
High pass filter.
Definition: common_lines.h:76
MetaDataVec SF
Definition: common_lines.h:128
virtual IdIteratorProxy< false > ids()
double angj
Angle of the best common line in image j.
Definition: common_lines.h:48
#define q1
void selfTranspose()
Definition: matrix1d.h:944
std::vector< MultidimArray< std::complex< double > > > * RTFsj
void randomQuaternions(int k, DMatrix &quaternions)
Commonline.
Definition: common_lines.h:42
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
size_t size() const override
#define i
void * threadCompareImages(void *args)
void setCol()
Definition: matrix1d.h:554
double angi
Angle of the best common line in image i.
Definition: common_lines.h:46
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
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
double mem
Memory limit.
Definition: common_lines.h:81
MultidimArray< double > * fReal
Definition: xmipp_fftw.h:64
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
void putRotationMatrix(const DMatrix &R, int k1, int k2, DMatrix &syncMatrix)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
void Radon_Transform(const MultidimArray< double > &vol, double rot, double tilt, MultidimArray< double > &RT)
Definition: radon.cpp:30
#define cl(i, j)
glob_log first
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
#define DIRECT_A1D_ELEM(v, i)
std::vector< CommonLine > CLmatrix
Definition: common_lines.h:137
doublereal * b
double v1
Matrix1D< double > b
#define FLOOR(x)
Definition: xmipp_macros.h:240
int Nthr
Number of threads.
Definition: common_lines.h:83
const char * getParam(const char *param, int arg=0)
void cholesky(const Matrix2D< double > &M, Matrix2D< double > &L)
Definition: matrix2d.cpp:160
#define XX(v)
Definition: matrix1d.h:85
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
int tripletRotationMatrix(const DMatrix &clMatrix, size_t nRays, int k1, int k2, int k3, DMatrix &R)
viol index
void computeSyncMatrix(const DMatrix &clMatrix, size_t nRays, DMatrix &sMatrix)
bool setValue(const MDObject &mdValueIn, size_t id)
#define CEIL(x)
Definition: xmipp_macros.h:225
int Nmpi
Number of processors.
Definition: common_lines.h:85
void quaternionToMatrix(const DVector &q, DMatrix &rotMatrix)
Matrix2D< double > A
#define dMij(m, i, j)
Definition: matrix2d.h:139
void commonLineTwoImages(std::vector< MultidimArray< std::complex< double > > > &RTFsi, std::vector< MultidimArray< double > > &RTsi, int idxi, std::vector< MultidimArray< std::complex< double > > > &RTFsj, std::vector< MultidimArray< double > > &RTsj, int idxj, ProgCommonLine *parent, CommonLine &result, FourierTransformer &transformer)
void * threadPrepareImages(void *args)
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
#define XSIZE(v)
void progress_bar(long rlen)
#define HIGHPASS
double stepAng
Angular sampling.
Definition: common_lines.h:78
void produceSideInfo()
Error related to numerical calculation.
Definition: xmipp_error.h:179
void fast_correlation_vector(const MultidimArray< std::complex< double > > &FFT1, const MultidimArray< std::complex< double > > &FFT2, MultidimArray< double > &R, FourierTransformer &transformer)
Definition: xmipp_fftw.cpp:926
#define SORTED_ELEM(M, i)
ProgCommonLine * parent
double dummy
ProgCommonLine * parent
void solveLinearSystem(PseudoInverseHelper &h, Matrix1D< double > &result)
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
double outlierFraction
Outlier fraction.
Definition: common_lines.h:72
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
T det3x3() const
determinat of 3x3 matrix
Definition: matrix2d.h:1061
#define q2
double distanceij
Distance between both common lines.
Definition: common_lines.h:50
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
Matrix1D< double > shift
Definition: common_lines.h:140
#define dMi(v, i)
Definition: matrix1d.h:246
#define dmax(a, b)
#define j
std::vector< MultidimArray< double > > * RTsj
#define YY(v)
Definition: matrix1d.h:93
void getCol(size_t j, Matrix1D< T > &v) const
Definition: matrix2d.cpp:890
int trunc(double x)
Definition: ap.cpp:7248
void svd(Matrix2D< double > &U, Matrix1D< double > &W, Matrix2D< double > &V) const
Definition: matrix2d.h:1124
TYPE distance(struct Point_T *p, struct Point_T *q)
Definition: point.cpp:28
int rank
MPI Rank.
Definition: common_lines.h:87
void ransacWeightedLeastSquares(WeightedLeastSquaresHelper &h, Matrix1D< double > &result, double tol, int Niter, double outlierFraction, int Nthreads)
FileName fn_sel
input file
Definition: common_lines.h:64
int round(double x)
Definition: ap.cpp:7245
constexpr long double EPS
Definition: ctf.h:38
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
std::vector< MultidimArray< std::complex< double > > > * blockRTFs
void saveMatrix(const char *fn, DMatrix &matrix)
double psi(const double x)
FileName fn_out
output file
Definition: common_lines.h:66
int getIndex(int i)
Definition: common_lines.h:173
void write(const FileName &fn) const
Definition: matrix2d.cpp:113
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
void qualifyCommonLines()
String formatString(const char *format,...)
void initZeros()
Definition: matrix2d.h:626
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
bool checkParam(const char *param)
void aliasRow(const MultidimArray< T > &m, size_t select_row)
constexpr int OUTSIDE_MASK
Definition: mask.h:48
constexpr int K
std::vector< MultidimArray< std::complex< double > > > * RTFsi
Shift for the image in the Y axis (double)
void addUsageLine(const char *line, bool verbatim=false)
void initZeros(const MultidimArray< T1 > &op)
void initGaussian(int Ydim, int Xdim, double op1=0., double op2=1.)
Definition: matrix2d.cpp:1118
void rotationsFromSyncMatrix(const DMatrix &sMatrix)
double percentile
Percentile (good common lines have very high percentiles)
Definition: common_lines.h:56
#define PI
Definition: tools.h:43
int getIntParam(const char *param, int arg=0)
void generateMask(MultidimArray< double > &v)
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
void initConstant(T val)
Definition: matrix1d.cpp:83
int * n
#define POW2(x)
Definition: common_lines.h:143
#define ZZ(v)
Definition: matrix1d.h:101
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
#define q3
doublereal * a
double sum() const
void selfInverse()
Definition: matrix2d.h:1146
#define LOWPASS
void addParamsLine(const String &line)
void statisticsAdjust(U avgF, U stddevF)
void initIdentity()
Definition: matrix2d.h:673
void applyMaskSpace(MultidimArray< double > &v)
bool scaleDistance
Scale output measure.
Definition: common_lines.h:70