Xmipp  v3.23.11-Nereus
symmetries.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 <stdio.h>
27 
28 #include "symmetries.h"
29 #include "geometry.h"
30 
31 // Read Symmetry file ======================================================
32 // crystal symmetry matices from http://cci.lbl.gov/asu_gallery/
33 int SymList::readSymmetryFile(FileName fn_sym, double accuracy)
34 {
35  int i, j;
36  FILE *fpoii;
37  char line[80];
38  char *auxstr;
39  double ang_incr, rot_ang;
40  int fold;
41  Matrix2D<double> L(4, 4), R(4, 4);
42  Matrix1D<double> axis(3), shift(3);
43  int pgGroup = sym_undefined;
44  int pgOrder;
45  std::vector<std::string> fileContent;
46 
47  //check if reserved word
48 
49  // Open file ---------------------------------------------------------
50  if ((fpoii = fopen(fn_sym.c_str(), "r")) == NULL)
51  {
52  //check if reserved word and return group and order
53  if (isSymmetryGroup(fn_sym, pgGroup, pgOrder))
54  {
55  fillSymmetryClass(fn_sym, pgGroup, pgOrder,fileContent);
56  }
57  else
58  REPORT_ERROR(ERR_IO_NOTOPEN, (std::string)"SymList::read_sym_file:Can't open file: "
59  + " or do not recognize symmetry group" + fn_sym);
60  }
61  else
62  {
63  while (fgets(line, 79, fpoii) != NULL)
64  {
65  if (line[0] == ';' || line[0] == '#' || line[0] == '\0')
66  continue;
67  fileContent.push_back(line);
68  }
69  fclose(fpoii);
70  }
71 
72  //reset space_group
73  space_group = 0;
74  // Count the number of symmetries ------------------------------------
75  true_symNo = 0;
76  // count number of axis and mirror planes. It will help to identify
77  // the crystallographic symmetry
78 
79  int no_axis, no_mirror_planes, no_inversion_points;
80  no_axis = no_mirror_planes = no_inversion_points = 0;
81 
82  for (size_t n=0; n<fileContent.size(); n++)
83  {
84  strcpy(line,fileContent[n].c_str());
85  auxstr = firstToken(line);
86  if (auxstr == NULL)
87  {
88  std::cout << line;
89  std::cout << "Wrong line in symmetry file, the line is skipped\n";
90  continue;
91  }
92  if (strcmp(auxstr, "rot_axis") == 0)
93  {
94  auxstr = nextToken();
95  fold = textToInteger(auxstr);
96  true_symNo += (fold - 1);
97  no_axis++;
98  }
99  else if (strcmp(auxstr, "mirror_plane") == 0)
100  {
101  true_symNo++;
102  no_mirror_planes++;
103  }
104  else if (strcmp(auxstr, "inversion") == 0)
105  {
106  true_symNo += 1;
107  no_inversion_points = 1;
108  }
109  else if (strcmp(auxstr, "P4212") == 0)
110  true_symNo += 7;
111  else if (strcmp(auxstr, "P2_122") == 0)
112  true_symNo += 3;
113  else if (strcmp(auxstr, "P22_12") == 0)
114  true_symNo += 3;
115  }
116  // Ask for memory
117  __L.resize(4*true_symNo, 4);
118  __R.resize(4*true_symNo, 4);
122 
123  // Read symmetry parameters
124  i = 0;
125  shift.initZeros();
126 
127  for (size_t n=0; n<fileContent.size(); n++)
128  {
129  strcpy(line,fileContent[n].c_str());
130  auxstr = firstToken(line);
131  // Rotational axis ---------------------------------------------------
132  if (strcmp(auxstr, "rot_axis") == 0)
133  {
134  auxstr = nextToken();
135  fold = textToInteger(auxstr);
136  auxstr = nextToken();
137  XX(axis) = textToFloat(auxstr);
138  auxstr = nextToken();
139  YY(axis) = textToFloat(auxstr);
140  auxstr = nextToken();
141  ZZ(axis) = textToFloat(auxstr);
142  ang_incr = 360. / fold;
143  L.initIdentity();
144  for (j = 1, rot_ang = ang_incr; j < fold; j++, rot_ang += ang_incr)
145  {
146  rotation3DMatrix(rot_ang, axis, R);
147  setShift(i, shift);
148  setMatrices(i++, L, R.transpose());
149  }
150  __sym_elements++;
151  // inversion ------------------------------------------------------
152  }
153  else if (strcmp(auxstr, "inversion") == 0)
154  {
155  L.initIdentity();
156  L(2, 2) = -1;
157  R.initIdentity();
158  R(0, 0) = -1.;
159  R(1, 1) = -1.;
160  R(2, 2) = -1.;
161  setShift(i, shift);
162  setMatrices(i++, L, R);
163  __sym_elements++;
164  // mirror plane -------------------------------------------------------------
165  }
166  else if (strcmp(auxstr, "mirror_plane") == 0)
167  {
168  auxstr = nextToken();
169  XX(axis) = textToFloat(auxstr);
170  auxstr = nextToken();
171  YY(axis) = textToFloat(auxstr);
172  auxstr = nextToken();
173  ZZ(axis) = textToFloat(auxstr);
174  L.initIdentity();
175  L(2, 2) = -1;
177  alignWithZ(axis,A);
178  A = A.transpose();
179  R = A * L * A.inv();
180  setShift(i, shift);
181  L.initIdentity();
182  setMatrices(i++, L, R);
183  __sym_elements++;
184  // P4212 -------------------------------------------------------------
185  }
186  else if (strcmp(auxstr, "P4212") == 0)
187  {
188  space_group = sym_P42_12;
189  accuracy = -1; // Do not compute subgroup
190  L.initIdentity();
191 
192  // With 0 shift
193  R.initZeros();
194  R(3, 3) = 1;
195  R(0, 0) = R(1, 1) = -1;
196  R(2, 2) = 1;
197  setShift(i, shift);
198  setMatrices(i++, L, R);
199  R.initZeros();
200  R(3, 3) = 1;
201  R(2, 2) = -1;
202  R(0, 1) = R(1, 0) = 1;
203  setShift(i, shift);
204  setMatrices(i++, L, R);
205  R.initZeros();
206  R(3, 3) = 1;
207  R(2, 2) = R(0, 1) = R(1, 0) = -1;
208  setShift(i, shift);
209  setMatrices(i++, L, R);
210 
211  // With 1/2 shift
212  VECTOR_R3(shift, 0.5, 0.5, 0);
213  R.initZeros();
214  R(3, 3) = 1;
215  R(0, 1) = -1;
216  R(1, 0) = R(2, 2) = 1;
217  setShift(i, shift);
218  setMatrices(i++, L, R);
219  R.initZeros();
220  R(3, 3) = 1;
221  R(1, 0) = -1;
222  R(0, 1) = R(2, 2) = 1;
223  setShift(i, shift);
224  setMatrices(i++, L, R);
225  R.initZeros();
226  R(3, 3) = 1;
227  R(0, 0) = R(2, 2) = -1;
228  R(1, 1) = 1;
229  setShift(i, shift);
230  setMatrices(i++, L, R);
231  R.initZeros();
232  R(3, 3) = 1;
233  R(1, 1) = R(2, 2) = -1;
234  R(0, 0) = 1;
235  setShift(i, shift);
236  setMatrices(i++, L, R);
237 
238  __sym_elements++;
239  }
240  else if (strcmp(auxstr, "P2_122") == 0)
241  {
242  space_group = sym_P2_122;
243  accuracy = -1; // Do not compute subgroup
244  L.initIdentity();
245 
246  // With 0 shift
247  R.initZeros();
248  R(3, 3) = 1;
249  R(0, 0) = -1;
250  R(1, 1) = -1;
251  R(2, 2) = 1;
252  setShift(i, shift);
253  setMatrices(i++, L, R);
254 
255  // With 1/2 shift
256  VECTOR_R3(shift, 0.5, 0.0, 0.0);
257  R.initZeros();
258  R(3, 3) = 1;
259  R(0, 0) = -1;
260  R(1, 1) = 1;
261  R(2, 2) = -1;
262  setShift(i, shift);
263  setMatrices(i++, L, R);
264  R.initZeros();
265  R(3, 3) = 1;
266  R(0, 0) = 1;
267  R(1, 1) = -1;
268  R(2, 2) = -1;
269  setShift(i, shift);
270  setMatrices(i++, L, R);
271  __sym_elements++;
272  }
273  else if (strcmp(auxstr, "P22_12") == 0)
274  {
275  space_group = sym_P22_12;
276  accuracy = -1; // Do not compute subgroup
277  L.initIdentity();
278 
279  // With 0 shift
280  R.initZeros();
281  R(3, 3) = 1;
282  R(0, 0) = -1;
283  R(1, 1) = -1;
284  R(2, 2) = 1;
285  setShift(i, shift);
286  setMatrices(i++, L, R);
287 
288  // With 1/2 shift
289  VECTOR_R3(shift, 0.0, 0.5, 0.0);
290  R.initZeros();
291  R(3, 3) = 1;
292  R(0, 0) = 1;
293  R(1, 1) = -1;
294  R(2, 2) = -1;
295  setShift(i, shift);
296  setMatrices(i++, L, R);
297  R.initZeros();
298  R(3, 3) = 1;
299  R(0, 0) = -1;
300  R(1, 1) = 1;
301  R(2, 2) = -1;
302  setShift(i, shift);
303  setMatrices(i++, L, R);
304  __sym_elements++;
305  }
306  }
307 
308  if (accuracy > 0)
309  computeSubgroup(accuracy);
310 
311  //possible crystallographic symmetry
312  if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
313  true_symNo == 7 && space_group == sym_P42_12)
314  space_group = sym_P42_12;
315  else if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
316  true_symNo == 3 && space_group == sym_P2_122)
317  space_group = sym_P2_122;
318  else if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
319  true_symNo == 3 && space_group == sym_P22_12)
320  space_group = sym_P22_12;
321  // P4 and P6
322  else if (no_axis == 1 && no_mirror_planes == 0 && no_inversion_points == 0 &&
323  fabs(R(2, 2) - 1.) < XMIPP_EQUAL_ACCURACY &&
324  fabs(R(0, 0) - R(1, 1)) < XMIPP_EQUAL_ACCURACY &&
325  fabs(R(0, 1) + R(1, 0)) < XMIPP_EQUAL_ACCURACY)
326  {
327  switch (true_symNo)
328  {
329  case(5):
330  space_group = sym_P6;
331  break;
332  case(3):
333  space_group = sym_P4;
334  break;
335  default:
336  space_group = sym_undefined;
337  break;
338  }//switch end
339  }//end else if (no_axis==1 && no_mirror_planes== 0
340  else if (no_axis == 0 && no_inversion_points == 0 && no_mirror_planes == 0)
341  space_group = sym_P1;
342  else
343  space_group = sym_undefined;
344  return pgGroup;
345 }
346 
347 // Get matrix ==============================================================
349  bool homogeneous)
350 const
351 {
352  int k, kp, l;
353  if (homogeneous)
354  {
355  L.initZeros(4, 4);
356  R.initZeros(4, 4);
357  for (k = 4 * i, kp=0; k < 4*i + 4; k++, kp++)
358  for (l = 0; l < 4; l++)
359  {
360  dMij(L,kp, l) = dMij(__L,k, l);
361  dMij(R,kp, l) = dMij(__R,k, l);
362  }
363  }
364  else
365  {
366  L.initZeros(3, 3);
367  R.initZeros(3, 3);
368  for (k = 4 * i, kp=0; k < 4*i + 3; k++, kp++)
369  for (l = 0; l < 3; l++)
370  {
371  dMij(L,kp, l) = dMij(__L,k, l);
372  dMij(R,kp, l) = dMij(__R,k, l);
373  }
374  }
375 }
376 
377 // Set matrix ==============================================================
379  const Matrix2D<double> &R)
380 {
381  int k, l;
382  for (k = 4 * i; k < 4*i + 4; k++)
383  for (l = 0; l < 4; l++)
384  {
385  __L(k, l) = L(k - 4 * i, l);
386  __R(k, l) = R(k - 4 * i, l);
387  }
388 }
389 
390 // Get/Set shift ===========================================================
391 void SymList::getShift(int i, Matrix1D<double> &shift) const
392 {
393  shift.resize(3);
394  XX(shift) = __shift(i, 0);
395  YY(shift) = __shift(i, 1);
396  ZZ(shift) = __shift(i, 2);
397 }
398 
399 void SymList::setShift(int i, const Matrix1D<double> &shift)
400 {
401  if (shift.size() != 3)
402  REPORT_ERROR(ERR_MATRIX_SIZE, "SymList::add_shift: Shift vector is not 3x1");
403  __shift(i, 0) = XX(shift);
404  __shift(i, 1) = YY(shift);
405  __shift(i, 2) = ZZ(shift);
406 }
407 
409 {
410  if (shift.size() != 3)
411  REPORT_ERROR(ERR_MATRIX_SIZE, "SymList::add_shift: Shift vector is not 3x1");
412  int i = MAT_YSIZE(__shift);
413  __shift.resize(i + 1, 3);
414  setShift(i, shift);
415 }
416 
417 // Add matrix ==============================================================
419  int chain_length)
420 {
421  if (MAT_XSIZE(L) != 4 || MAT_YSIZE(L) != 4 || MAT_XSIZE(R) != 4 || MAT_YSIZE(R) != 4)
422  REPORT_ERROR(ERR_MATRIX_SIZE, "SymList::add_matrix: Transformation matrix is not 4x4");
423  if (trueSymsNo() == symsNo())
424  {
425  __L.resize(MAT_YSIZE(__L) + 4, 4);
426  __R.resize(MAT_YSIZE(__R) + 4, 4);
428  }
429 
430  setMatrices(true_symNo, L, R);
431  __chain_length(__chain_length.size() - 1) = chain_length;
432  true_symNo++;
433 }
434 
435 // Compute subgroup ========================================================
436 bool found_not_tried(const Matrix2D<int> &tried, int &i, int &j,
437  int true_symNo)
438 {
439  i = j = 0;
440  size_t n = 0;
441  while (n != MAT_YSIZE(tried))
442  {
443  // if (tried(i, j) == 0 && !(i >= true_symNo && j >= true_symNo))
444  if (dMij(tried,i, j) == 0 && !(i >= true_symNo && j >= true_symNo))
445  return true;
446  if (i != (int)n)
447  {
448  // Move downwards
449  i++;
450  }
451  else
452  {
453  // Move leftwards
454  j--;
455  if (j == -1)
456  {
457  n++;
458  j = n;
459  i = 0;
460  }
461  }
462  }
463  return false;
464 }
465 
466 //#define DEBUG
467 void SymList::computeSubgroup(double accuracy)
468 {
469  Matrix2D<double> I(4, 4);
470  I.initIdentity();
471  Matrix2D<double> L1(4, 4), R1(4, 4), L2(4, 4), R2(4, 4), newL(4, 4), newR(4, 4),identity(4,4);
473  Matrix1D<double> shift(3);
474  shift.initZeros();
475  int i, j;
476  int new_chain_length;
477  identity.initIdentity();
478  while (found_not_tried(tried, i, j, true_symNo))
479  {
480  tried(i, j) = 1;
481 
482  // Form new symmetry matrices
483  // if (__chain_length(i)+__chain_length(j)>__sym_elements+2) continue;
484 
485  getMatrices(i, L1, R1);
486  getMatrices(j, L2, R2);
487  newL = L1 * L2;
488  newR = R1 * R2;
489  new_chain_length = __chain_length(i) + __chain_length(j);
490 
491  //if (newL.isIdentity() && newR.isIdentity()) continue;
492  //rounding error make newR different from identity
493  if (newL.equal(identity, accuracy) &&
494  newR.equal(identity, accuracy))
495  continue;
496 
497  // Try to find it in current ones
498  bool found;
499  found = false;
500  for (int l = 0; l < symsNo(); l++)
501  {
502  getMatrices(l, L1, R1);
503  if (newL.equal(L1, accuracy) && newR.equal(R1, accuracy))
504  {
505  found = true;
506  break;
507  }
508  }
509 
510  if (!found)
511  {
512  //#define DEBUG
513 #ifdef DEBUG
514  static int kjhg=0;
515  /* std::cout << "Matrix size " << tried.Xdim() << " "
516  << "trying " << i << " " << j << " "
517  << "chain length=" << new_chain_length << std::endl;
518  std::cout << "Result R Sh\n" << newR << shift;
519  */
520  //std::cerr << "shift" << __shift <<std::endl;
521  std::cerr << "newR " << kjhg++ << "\n" << newR <<std::endl;
522 #endif
523 
524  addMatrices(newL, newR, new_chain_length);
525  addShift(shift);
526  tried.resize(MAT_YSIZE(tried) + 1, MAT_XSIZE(tried) + 1);
527  }
528  }
529 #ifdef DEBUG
530  std::cerr << "__R" << __R <<std::endl;
531 #endif
532 #undef DEBUG
533 }
541 int SymList::crystallographicSpaceGroup(double mag_a, double mag_b,
542  double ang_a2b_deg) const
543 {
544 
545  switch (space_group)
546  {
547  case sym_undefined:
548  case sym_P1:
549  return(space_group);
550  case sym_P4:
551  if (fabs((mag_a - mag_b)) > XMIPP_EQUAL_ACCURACY ||
552  fabs(ang_a2b_deg - 90) > XMIPP_EQUAL_ACCURACY)
553  std::cerr << "\nWARNING: P42 but mag_a != mag_b\n"
554  << " or ang_a2b !=90" << std::endl;
555  return(space_group);
556  break;
557  case sym_P2_122:
558  if (fabs((mag_a - mag_b)) > XMIPP_EQUAL_ACCURACY ||
559  fabs(ang_a2b_deg - 90) > XMIPP_EQUAL_ACCURACY)
560  std::cerr << "\nWARNING: P2_122 but mag_a != mag_b\n"
561  << " or ang_a2b !=90" << std::endl;
562  return(space_group);
563  break;
564  case sym_P22_12:
565  if (fabs((mag_a - mag_b)) > XMIPP_EQUAL_ACCURACY ||
566  fabs(ang_a2b_deg - 90) > XMIPP_EQUAL_ACCURACY)
567  std::cerr << "\nWARNING: P22_12 but mag_a != mag_b\n"
568  << " or ang_a2b !=90" << std::endl;
569  return(space_group);
570  break;
571  case sym_P42_12:
572  if (fabs((mag_a - mag_b)) > XMIPP_EQUAL_ACCURACY ||
573  fabs(ang_a2b_deg - 90) > XMIPP_EQUAL_ACCURACY)
574  std::cerr << "\nWARNING: P42_12 but mag_a != mag_b\n"
575  << " or ang_a2b !=90" << std::endl;
576  return(space_group);
577  break;
578  case sym_P6:
579  if (fabs((mag_a - mag_b)) > XMIPP_EQUAL_ACCURACY ||
580  fabs(ang_a2b_deg - 120.) > XMIPP_EQUAL_ACCURACY)
581  {
582  std::cerr << "\nWARNING: marked as P6 but mag_a != mag_b\n"
583  << "or ang_a2b !=120" << std::endl;
584  std::cerr << "\nWARNING: P1 is assumed\n";
585  return(sym_P1);
586  }
587  else
588  return(space_group);
589  break;
590  default:
591  std::cerr << "\n Congratulations: you have found a bug in the\n"
592  << "routine crystallographic_space_group or\n"
593  << "You have called to this rotuine BEFORE reading\n"
594  << "the symmetry info" << std::endl;
595  exit(0);
596  break;
597  }//switch(space_group) end
598 
599 }//crystallographicSpaceGroup end
600 
601 bool SymList::isSymmetryGroup(FileName fn_sym, int &pgGroup, int &pgOrder)
602 {
603  char G1,G2,G3='\0',G4;
604  char auxChar[3];
605  //each case check length, check first letter, second, is number
606  //Non a point group
607 
608  //remove path
609  FileName fn_sym_tmp;
610  fn_sym_tmp=fn_sym.removeDirectories();
611  int mySize=fn_sym_tmp.size();
612  bool return_true;
613  return_true=false;
614  auxChar[2]='\0';
615  //size maybe 4 because n maybe a 2 digit number
616  if(mySize>4 || mySize<1)
617  {
618  pgGroup=-1;
619  pgOrder=-1;
620  return false;
621  }
622  //get the group character by character
623  G1=toupper((fn_sym_tmp.c_str())[0]);
624  G2=toupper((fn_sym_tmp.c_str())[1]);
625  if (mySize > 2)
626  {
627  G3=toupper((fn_sym_tmp.c_str())[2]);
628  if(mySize > 3)
629  G4=toupper((fn_sym.c_str())[3]);
630  }
631  else
632  G4='\0';
633  //CN
634  if (mySize==2 && G1=='C' && isdigit(G2))
635  {
636  pgGroup=pg_CN;
637  pgOrder=int(G2)-48;
638  return_true=true;
639  }
640  if (mySize==3 && G1=='C' && isdigit(G2) && isdigit(G3))
641  {
642  pgGroup=pg_CN;
643  auxChar[0]=G2;
644  auxChar[1]=G3;
645  pgOrder=atoi(auxChar);
646  return_true=true;
647  }
648  //CI
649  else if (mySize==2 && G1=='C' && G2=='I')
650  {
651  pgGroup=pg_CI;
652  pgOrder=-1;
653  return_true=true;
654  }
655  //CS
656  else if (mySize==2 && G1=='C' && G2=='S')
657  {
658  pgGroup=pg_CS;
659  pgOrder=-1;
660  return_true=true;
661  }
662  //CNH
663  else if (mySize==3 && G1=='C' && isdigit(G2) && G3=='H')
664  {
665  pgGroup=pg_CNH;
666  pgOrder=int(G2)-48;
667  return_true=true;
668  }
669  else if (mySize==4 && G1=='C' && isdigit(G2) && isdigit(G3) && G4=='H')
670  {
671  pgGroup=pg_CNH;
672  auxChar[0]=G2;
673  auxChar[1]=G3;
674  pgOrder=atoi(auxChar);
675  return_true=true;
676  }
677  //CNV
678  else if (mySize==3 && G1=='C' && isdigit(G2) && G3=='V')
679  {
680  pgGroup=pg_CNV;
681  pgOrder=int(G2)-48;
682  return_true=true;
683  }
684  else if (mySize==4 && G1=='C' && isdigit(G2) && isdigit(G3) && G4=='V')
685  {
686  pgGroup=pg_CNV;
687  auxChar[0]=G2;
688  auxChar[1]=G3;
689  pgOrder=atoi(auxChar);
690  return_true=true;
691  }
692  //SN
693  else if (mySize==2 && G1=='S' && isdigit(G2) )
694  {
695  pgGroup=pg_SN;
696  pgOrder=int(G2)-48;
697  return_true=true;
698  }
699  else if (mySize==3 && G1=='S' && isdigit(G2) && isdigit(G3) )
700  {
701  pgGroup=pg_SN;
702  auxChar[0]=G2;
703  auxChar[1]=G3;
704  pgOrder=atoi(auxChar);
705  return_true=true;
706  }
707  //DN
708  else if (mySize==2 && G1=='D' && isdigit(G2) )
709  {
710  pgGroup=pg_DN;
711  pgOrder=int(G2)-48;
712  return_true=true;
713  }
714  if (mySize==3 && G1=='D' && isdigit(G2) && isdigit(G3))
715  {
716  pgGroup=pg_DN;
717  auxChar[0]=G2;
718  auxChar[1]=G3;
719  pgOrder=atoi(auxChar);
720  return_true=true;
721  }
722  //DNV
723  else if (mySize==3 && G1=='D' && isdigit(G2) && G3=='V')
724  {
725  pgGroup=pg_DNV;
726  pgOrder=int(G2)-48;
727  return_true=true;
728  }
729  else if (mySize==4 && G1=='D' && isdigit(G2) && isdigit(G3) && G4=='V')
730  {
731  pgGroup=pg_DNV;
732  auxChar[0]=G2;
733  auxChar[1]=G3;
734  pgOrder=atoi(auxChar);
735  return_true=true;
736  }
737  //DNH
738  else if (mySize==3 && G1=='D' && isdigit(G2) && G3=='H')
739  {
740  pgGroup=pg_DNH;
741  pgOrder=int(G2)-48;
742  return_true=true;
743  }
744  else if (mySize==4 && G1=='D' && isdigit(G2) && isdigit(G3) && G4=='H')
745  {
746  pgGroup=pg_DNH;
747  auxChar[0]=G2;
748  auxChar[1]=G3;
749  pgOrder=atoi(auxChar);
750  return_true=true;
751  }
752  //T
753  else if (mySize==1 && G1=='T')
754  {
755  pgGroup=pg_T;
756  pgOrder=-1;
757  return_true=true;
758  }
759  //TD
760  else if (mySize==2 && G1=='T' && G2=='D')
761  {
762  pgGroup=pg_TD;
763  pgOrder=-1;
764  return_true=true;
765  }
766  //TH
767  else if (mySize==2 && G1=='T' && G2=='H')
768  {
769  pgGroup=pg_TH;
770  pgOrder=-1;
771  return_true=true;
772  }
773  //O
774  else if (mySize==1 && G1=='O')
775  {
776  pgGroup=pg_O;
777  pgOrder=-1;
778  return_true=true;
779  }
780  //OH
781  else if (mySize==2 && G1=='O'&& G2=='H')
782  {
783  pgGroup=pg_OH;
784  pgOrder=-1;
785  return_true=true;
786  }
787  //I
788  else if (mySize==1 && G1=='I')
789  {
790  pgGroup=pg_I;
791  pgOrder=-1;
792  return_true=true;
793  }
794  //I1
795  else if (mySize==2 && G1=='I'&& G2=='1')
796  {
797  pgGroup=pg_I1;
798  pgOrder=-1;
799  return_true=true;
800  }
801  //I2
802  else if (mySize==2 && G1=='I'&& G2=='2')
803  {
804  pgGroup=pg_I2;
805  pgOrder=-1;
806  return_true=true;
807  }
808  //I3
809  else if (mySize==2 && G1=='I'&& G2=='3')
810  {
811  pgGroup=pg_I3;
812  pgOrder=-1;
813  return_true=true;
814  }
815  //I4
816  else if (mySize==2 && G1=='I'&& G2=='4')
817  {
818  pgGroup=pg_I4;
819  pgOrder=-1;
820  return_true=true;
821  }
822  //I5
823  else if (mySize==2 && G1=='I'&& G2=='5')
824  {
825  pgGroup=pg_I5;
826  pgOrder=-1;
827  return_true=true;
828  }
829  //IH
830  else if (mySize==2 && G1=='I'&& G2=='H')
831  {
832  pgGroup=pg_IH;
833  pgOrder=-1;
834  return_true=true;
835  }
836  //I1H
837  else if (mySize==3 && G1=='I'&& G2=='1'&& G3=='H')
838  {
839  pgGroup=pg_I1H;
840  pgOrder=-1;
841  return_true=true;
842  }
843  //I2H
844  else if (mySize==3 && G1=='I'&& G2=='2'&& G3=='H')
845  {
846  pgGroup=pg_I2H;
847  pgOrder=-1;
848  return_true=true;
849  }
850  //I3H
851  else if (mySize==3 && G1=='I'&& G2=='3'&& G3=='H')
852  {
853  pgGroup=pg_I3H;
854  pgOrder=-1;
855  return_true=true;
856  }
857  //I4H
858  else if (mySize==3 && G1=='I'&& G2=='4'&& G3=='H')
859  {
860  pgGroup=pg_I4H;
861  pgOrder=-1;
862  return_true=true;
863  }
864  //I5H
865  else if (mySize==3 && G1=='I'&& G2=='5'&& G3=='H')
866  {
867  pgGroup=pg_I5H;
868  pgOrder=-1;
869  return_true=true;
870  }
871  //#define DEBUG7
872 #ifdef DEBUG7
873  std::cerr << "pgGroup" << pgGroup << " pgOrder " << pgOrder << std::endl;
874 #endif
875 #undef DEBUG7
876 
877  return return_true;
878 }
879 void SymList::fillSymmetryClass(const FileName &symmetry, int pgGroup, int pgOrder,
880  std::vector<std::string> &fileContent)
881 {
882  std::ostringstream line1;
883  std::ostringstream line2;
884  std::ostringstream line3;
885  std::ostringstream line4;
886  if (pgGroup == pg_CN)
887  {
888  line1 << "rot_axis " << pgOrder << " 0 0 1";
889  }
890  else if (pgGroup == pg_CI)
891  {
892  line1 << "inversion ";
893  }
894  else if (pgGroup == pg_CS)
895  {
896  line1 << "mirror_plane 0 0 1";
897  }
898  else if (pgGroup == pg_CNV)
899  {
900  line1 << "rot_axis " << pgOrder << " 0 0 1";
901  line2 << "mirror_plane 0 1 0";
902  }
903  else if (pgGroup == pg_CNH)
904  {
905  line1 << "rot_axis " << pgOrder << " 0 0 1";
906  line2 << "mirror_plane 0 0 1";
907  }
908  else if (pgGroup == pg_SN)
909  {
910  int order = pgOrder / 2;
911  if(2*order != pgOrder)
912  {
913  std::cerr << "ERROR: order for SN group must be even" << std::endl;
914  exit(0);
915  }
916  line1 << "rot_axis " << order << " 0 0 1";
917  line2 << "inversion ";
918  }
919  else if (pgGroup == pg_DN)
920  {
921  line1 << "rot_axis " << pgOrder << " 0 0 1";
922  line2 << "rot_axis " << "2" << " 1 0 0";
923  }
924  else if (pgGroup == pg_DNV)
925  {
926  line1 << "rot_axis " << pgOrder << " 0 0 1";
927  line2 << "rot_axis " << "2" << " 1 0 0";
928  line3 << "mirror_plane 1 0 0";
929  }
930  else if (pgGroup == pg_DNH)
931  {
932  line1 << "rot_axis " << pgOrder << " 0 0 1";
933  line2 << "rot_axis " << "2" << " 1 0 0";
934  line3 << "mirror_plane 0 0 1";
935  }
936  else if (pgGroup == pg_T)
937  {
938  line1 << "rot_axis " << "3" << " 0. 0. 1.";
939  line2 << "rot_axis " << "2" << " 0. 0.816496 0.577350";
940  }
941  else if (pgGroup == pg_TD)
942  {
943  line1 << "rot_axis " << "3" << " 0. 0. 1.";
944  line2 << "rot_axis " << "2" << " 0. 0.816496 0.577350";
945  line3 << "mirror_plane 1.4142136 2.4494897 0.0000000";
946  }
947  else if (pgGroup == pg_TH)
948  {
949  line1 << "rot_axis " << "3" << " 0. 0. 1.";
950  line2 << "rot_axis " << "2" << " 0. -0.816496 -0.577350";
951  line3 << "inversion";
952  }
953  else if (pgGroup == pg_O)
954  {
955  line1 << "rot_axis " << "3" << " .5773502 .5773502 .5773502";
956  line2 << "rot_axis " << "4" << " 0 0 1";
957  }
958  else if (pgGroup == pg_OH)
959  {
960  line1 << "rot_axis " << "3" << " .5773502 .5773502 .5773502";
961  line2 << "rot_axis " << "4" << " 0 0 1";
962  line3 << "mirror_plane 0 1 1";
963  }
964  else if (pgGroup == pg_I || pgGroup == pg_I2)
965  {
966  line1 << "rot_axis 2 0 0 1";
967  line2 << "rot_axis 5 0.525731114 0 0.850650807";
968  line3 << "rot_axis 3 0 0.356822076 0.934172364";
969  }
970  else if (pgGroup == pg_I1)
971  {
972  line1 << "rot_axis 2 1 0 0";
973  line2 << "rot_axis 5 0.85065080702670 0 -0.5257311142635";
974  line3 << "rot_axis 3 0.9341723640 0.3568220765 0";
975  }
976  else if (pgGroup == pg_I3)
977  {
978  line1 << "rot_axis 2 -0.5257311143 0 0.8506508070";
979  line3 << "rot_axis 5 0. 0. 1.";
980  line2 << "rot_axis 3 -0.4911234778630044, 0.3568220764705179, 0.7946544753759428";
981  }
982  else if (pgGroup == pg_I4)
983  {
984  line1 << "rot_axis 2 0.5257311143 0 0.8506508070";
985  line3 << "rot_axis 5 0.8944271932547096 0 0.4472135909903704";
986  line2 << "rot_axis 3 0.4911234778630044 0.3568220764705179 0.7946544753759428";
987  }
988  else if (pgGroup == pg_I5)
989  {
990  std::cerr << "ERROR: Symmetry pg_I5 not implemented" << std::endl;
991  exit(0);
992  }
993  else if (pgGroup == pg_IH || pgGroup == pg_I2H)
994  {
995  line1 << "rot_axis 2 0 0 1";
996  line2 << "rot_axis 5 0.525731114 0 0.850650807";
997  line3 << "rot_axis 3 0 0.356822076 0.934172364";
998  line4 << "mirror_plane 1 0 0";
999  }
1000  else if (pgGroup == pg_I1H)
1001  {
1002  line1 << "rot_axis 2 1 0 0";
1003  line2 << "rot_axis 5 0.85065080702670 0 -0.5257311142635";
1004  line3 << "rot_axis 3 0.9341723640 0.3568220765 0";
1005  line4 << "mirror_plane 0 0 -1";
1006  }
1007  else if (pgGroup == pg_I3H)
1008  {
1009  line1 << "rot_axis 2 -0.5257311143 0 0.8506508070";
1010  line3 << "rot_axis 5 0. 0. 1.";
1011  line2 << "rot_axis 3 -0.4911234778630044, 0.3568220764705179, 0.7946544753759428";
1012  line4 << "mirror_plane 0.850650807 0 0.525731114";
1013  }
1014  else if (pgGroup == pg_I4H)
1015  {
1016  line1 << "rot_axis 2 0.5257311143 0 0.8506508070";
1017  line3 << "rot_axis 5 0.8944271932547096 0 0.4472135909903704";
1018  line2 << "rot_axis 3 0.4911234778630044 0.3568220764705179 0.7946544753759428";
1019  line4 << "mirror_plane 0.850650807 0 -0.525731114";
1020  }
1021  else if (pgGroup == pg_I5H)
1022  {
1023  std::cerr << "ERROR: Symmetry pg_I5H not implemented" << std::endl;
1024  exit(0);
1025  }
1026  else
1027  {
1028  std::cerr << "ERROR: Symmetry " << symmetry << "is not known" << std::endl;
1029  exit(0);
1030  }
1031  if (line1.str().size()>0)
1032  fileContent.push_back(line1.str());
1033  if (line2.str().size()>0)
1034  fileContent.push_back(line2.str());
1035  if (line3.str().size()>0)
1036  fileContent.push_back(line3.str());
1037  if (line4.str().size()>0)
1038  fileContent.push_back(line4.str());
1039  //#define DEBUG5
1040 #ifdef DEBUG5
1041 
1042  for (int n=0; n<fileContent.size(); n++)
1043  std::cerr << fileContent[n] << std::endl;
1044  std::cerr << "fileContent.size()" << fileContent.size() << std::endl;
1045 #endif
1046  #undef DEBUG5
1047 }
1048 double SymList::nonRedundantProjectionSphere(int pgGroup, int pgOrder)
1049 {
1050  if (pgGroup == pg_CN)
1051  {
1052  return 4.*PI/pgOrder;
1053  }
1054  else if (pgGroup == pg_CI)
1055  {
1056  return 4.*PI/2.;
1057  }
1058  else if (pgGroup == pg_CS)
1059  {
1060  return 4.*PI/2.;
1061  }
1062  else if (pgGroup == pg_CNV)
1063  {
1064  return 4.*PI/pgOrder/2;
1065  }
1066  else if (pgGroup == pg_CNH)
1067  {
1068  return 4.*PI/pgOrder/2;
1069  }
1070  else if (pgGroup == pg_SN)
1071  {
1072  return 4.*PI/pgOrder;
1073  }
1074  else if (pgGroup == pg_DN)
1075  {
1076  return 4.*PI/pgOrder/2;
1077  }
1078  else if (pgGroup == pg_DNV)
1079  {
1080  return 4.*PI/pgOrder/4;
1081  }
1082  else if (pgGroup == pg_DNH)
1083  {
1084  return 4.*PI/pgOrder/4;
1085  }
1086  else if (pgGroup == pg_T)
1087  {
1088  return 4.*PI/12;
1089  }
1090  else if (pgGroup == pg_TD)
1091  {
1092  return 4.*PI/24;
1093  }
1094  else if (pgGroup == pg_TH)
1095  {
1096  return 4.*PI/24;
1097  }
1098  else if (pgGroup == pg_O)
1099  {
1100  return 4.*PI/24;
1101  }
1102  else if (pgGroup == pg_OH)
1103  {
1104  return 4.*PI/48;
1105  }
1106  else if (pgGroup == pg_I || pgGroup == pg_I2)
1107  {
1108  return 4.*PI/60;
1109  }
1110  else if (pgGroup == pg_I1)
1111  {
1112  return 4.*PI/60;
1113  }
1114  else if (pgGroup == pg_I3)
1115  {
1116  return 4.*PI/60;
1117  }
1118  else if (pgGroup == pg_I4)
1119  {
1120  return 4.*PI/60;
1121  }
1122  else if (pgGroup == pg_I5)
1123  {
1124  return 4.*PI/60;
1125  }
1126  else if (pgGroup == pg_IH || pgGroup == pg_I2H)
1127  {
1128  return 4.*PI/120;
1129  }
1130  else if (pgGroup == pg_I1H)
1131  {
1132  return 4.*PI/120;
1133  }
1134  else if (pgGroup == pg_I3H)
1135  {
1136  return 4.*PI/120;
1137  }
1138  else if (pgGroup == pg_I4H)
1139  {
1140  return 4.*PI/120;
1141  }
1142  else if (pgGroup == pg_I5H)
1143  {
1144  return 4.*PI/120;
1145  }
1146  else
1147  {
1148  std::cerr << "ERROR: Symmetry group, order=" << pgGroup
1149  << " "
1150  << pgOrder
1151  << "is not known"
1152  << std::endl;
1153  exit(0);
1154  }
1155 }
1156 
1158  bool projdir_mode, bool check_mirrors,
1159  bool object_rotation)
1160 {
1161  double rot1, tilt1, psi1;
1162  double rot2, tilt2, psi2;
1163  double angDistance;
1164  for (const auto& row : md)
1165  {
1166  row.getValue(MDL_ANGLE_ROT, rot1);
1167  row.getValue(MDL_ANGLE_ROT2, rot2);
1168 
1169  row.getValue(MDL_ANGLE_TILT, tilt1);
1170  row.getValue(MDL_ANGLE_TILT2, tilt2);
1171 
1172  row.getValue(MDL_ANGLE_PSI, psi1);
1173  row.getValue(MDL_ANGLE_PSI2, psi2);
1174 
1175  angDistance=computeDistance( rot1, tilt1, psi1,
1176  rot2, tilt2, psi2,
1177  projdir_mode, check_mirrors,
1178  object_rotation);
1179 
1180  md.setValue(MDL_ANGLE_ROT_DIFF,rot1 - rot2, row.id());
1181  md.setValue(MDL_ANGLE_TILT_DIFF,tilt1 - tilt2, row.id());
1182  md.setValue(MDL_ANGLE_PSI_DIFF,psi1 - psi2, row.id());
1183  md.setValue(MDL_ANGLE_DIFF,angDistance, row.id());
1184  }
1185 
1186 }
1187 
1188 double SymList::computeDistance(double rot1, double tilt1, double psi1,
1189  double &rot2, double &tilt2, double &psi2,
1190  bool projdir_mode, bool check_mirrors,
1191  bool object_rotation, bool write_mirrors )
1192 {
1193  Matrix2D<double> E1, E2;
1194  Euler_angles2matrix(rot1, tilt1, psi1, E1, false);
1195 
1196  int imax = symsNo() + 1;
1197  Matrix2D<double> L(3, 3), R(3, 3); // A matrix from the list
1198  double best_ang_dist = 3600;
1199  double best_rot2=0, best_tilt2=0, best_psi2=0;
1200 
1201  for (int i = 0; i < imax; i++)
1202  {
1203  double rot2p, tilt2p, psi2p;
1204  if (i == 0)
1205  {
1206  rot2p = rot2;
1207  tilt2p = tilt2;
1208  psi2p = psi2;
1209  }
1210  else
1211  {
1212  getMatrices(i - 1, L, R, false);
1213  if (object_rotation)
1214  Euler_apply_transf(R, L, rot2, tilt2, psi2, rot2p, tilt2p, psi2p);
1215  else
1216  Euler_apply_transf(L, R, rot2, tilt2, psi2, rot2p, tilt2p, psi2p);
1217  }
1218 
1219  double ang_dist = Euler_distanceBetweenAngleSets_fast(E1,rot2p, tilt2p, psi2p,
1220  projdir_mode, E2);
1221 
1222  if (ang_dist < best_ang_dist)
1223  {
1224  best_rot2 = rot2p;
1225  best_tilt2 = tilt2p;
1226  best_psi2 = psi2p;
1227  best_ang_dist = ang_dist;
1228  }
1229 
1230  if (check_mirrors)
1231  {
1232  double rot2pm, tilt2pm, psi2pm;
1233  Euler_mirrorY(rot2p, tilt2p, psi2p, rot2pm, tilt2pm, psi2pm);
1234  double ang_dist_mirror = Euler_distanceBetweenAngleSets_fast(E1,
1235  rot2pm, tilt2pm, psi2pm,projdir_mode, E2);
1236 
1237  if (ang_dist_mirror < best_ang_dist)
1238  {
1239  best_rot2 = write_mirrors ? rot2pm : rot2p;
1240  best_tilt2 = write_mirrors ? tilt2pm : tilt2p;
1241  best_psi2 = write_mirrors ? psi2pm : psi2p;
1242  best_ang_dist = ang_dist_mirror;
1243  }
1244 
1245  }
1246  }
1247  rot2 = best_rot2;
1248  tilt2 = best_tilt2;
1249  psi2 = best_psi2;
1250  return best_ang_dist;
1251 }
1252 
1253 void SymList::breakSymmetry(double rot1, double tilt1, double psi1,
1254  double &rot2, double &tilt2, double &psi2
1255  )
1256 {
1257  Matrix2D<double> E1;
1258  Euler_angles2matrix(rot1, tilt1, psi1, E1, true);
1259  static bool doRandomize=true;
1260  Matrix2D<double> L(3, 3), R(3, 3); // A matrix from the list
1261 
1262  int i;
1263  if (doRandomize)
1264  {
1265  srand ( time(NULL) );
1266  doRandomize=false;
1267  }
1268  int symOrder = symsNo()+1;
1269  //std::cerr << "DEBUG_ROB: symOrder: " << symOrder << std::endl;
1270  i = rand() % symOrder;//59+1
1271  //std::cerr << "DEBUG_ROB: i: " << i << std::endl;
1272  if (i < symOrder-1)
1273  {
1274  getMatrices(i, L, R);
1275  //std::cerr << R << std::endl;
1276  Euler_matrix2angles(E1 * R, rot2, tilt2, psi2);
1277  }
1278  else
1279  {
1280  //std::cerr << "else" <<std::endl;
1281  rot2=rot1; tilt2=tilt1;psi2=psi1;
1282  }
1283 // if (rot2==0)
1284 //: std::cerr << "rot2 is zero " << i << R << L << std::endl;
1285 }
double nonRedundantProjectionSphere(int pgGroup, int pgOrder)
#define pg_I2H
Definition: symmetries.h:98
#define pg_TD
Definition: symmetries.h:84
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
Rotation angle of an image (double,degrees)
#define pg_DN
Definition: symmetries.h:80
Tilting angle of an image (double,degrees)
#define pg_T
Definition: symmetries.h:83
#define sym_P22_12
Definition: symmetries.h:60
#define pg_DNH
Definition: symmetries.h:82
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
#define pg_O
Definition: symmetries.h:86
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
size_t size() const
Definition: matrix1d.h:508
Problem with matrix size.
Definition: xmipp_error.h:152
difference between rot angles (double,degrees)
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
Definition: geometry.cpp:624
#define pg_I3H
Definition: symmetries.h:99
Tilting angle of an image (double,degrees)
#define pg_I3
Definition: symmetries.h:93
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
#define sym_P4
Definition: symmetries.h:63
void Euler_mirrorY(double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Definition: geometry.cpp:1011
bool isSymmetryGroup(FileName fn_sym, int &pgGroup, int &pgOrder)
Definition: symmetries.cpp:601
#define pg_I1H
Definition: symmetries.h:97
#define sym_P6
Definition: symmetries.h:68
#define pg_I4H
Definition: symmetries.h:100
FileName removeDirectories(int keep=0) const
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
Special label to be used when gathering MDs in MpiMetadataPrograms.
#define pg_CNV
Definition: symmetries.h:77
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
int symsNo() const
Definition: symmetries.h:268
#define pg_OH
Definition: symmetries.h:87
void getShift(int i, Matrix1D< double > &shift) const
Definition: symmetries.cpp:391
Matrix1D< int > __chain_length
Definition: symmetries.h:148
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
int __sym_elements
Definition: symmetries.h:156
Matrix2D< double > __shift
Definition: symmetries.h:147
void computeSubgroup(double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:467
#define i
void fillSymmetryClass(const FileName &symmetry, int pgGroup, int pgOrder, std::vector< std::string > &fileContent)
Definition: symmetries.cpp:879
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void setMatrices(int i, const Matrix2D< double > &L, const Matrix2D< double > &R)
Definition: symmetries.cpp:378
void rotation3DMatrix(double ang, char axis, Matrix2D< double > &result, bool homogeneous)
#define pg_CS
Definition: symmetries.h:75
#define sym_P2_122
Definition: symmetries.h:59
Rotation angle of an image (double,degrees)
#define pg_I5H
Definition: symmetries.h:101
int crystallographicSpaceGroup(double mag_a, double mag_b, double ang_a2b_deg) const
Definition: symmetries.cpp:541
double computeDistance(double rot1, double tilt1, double psi1, double &rot2, double &tilt2, double &psi2, bool projdir_mode, bool check_mirrors, bool object_rotation=false, bool write_mirrors=true)
#define pg_I4
Definition: symmetries.h:94
char axis
Matrix2D< double > __R
Definition: symmetries.h:146
#define XX(v)
Definition: matrix1d.h:85
difference between psi angles (double,degrees)
bool found_not_tried(const Matrix2D< int > &tried, int &i, int &j, int true_symNo)
Definition: symmetries.cpp:436
void addMatrices(const Matrix2D< double > &L, const Matrix2D< double > &R, int chain_length)
Definition: symmetries.cpp:418
float textToFloat(const char *str)
#define dMij(m, i, j)
Definition: matrix2d.h:139
void addShift(const Matrix1D< double > &shift)
Definition: symmetries.cpp:408
#define pg_I1
Definition: symmetries.h:91
#define pg_DNV
Definition: symmetries.h:81
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
void resize(size_t Xdim, bool copy=true)
Definition: matrix1d.h:410
Matrix2D< double > __L
Definition: symmetries.h:146
int true_symNo
Definition: symmetries.h:153
void breakSymmetry(double rot1, double tilt1, double psi1, double &rot2, double &tilt2, double &psi2)
void initZeros()
Definition: matrix1d.h:592
#define sym_P42_12
Definition: symmetries.h:65
Psi angle of an image (double,degrees)
#define pg_CNH
Definition: symmetries.h:78
#define j
difference between two angles (double,degrees)
#define YY(v)
Definition: matrix1d.h:93
#define pg_TH
Definition: symmetries.h:85
File cannot be open.
Definition: xmipp_error.h:137
#define pg_CN
Definition: symmetries.h:76
void setShift(int i, const Matrix1D< double > &shift)
Definition: symmetries.cpp:399
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
#define sym_P1
Definition: symmetries.h:54
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
Definition: geometry.cpp:839
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
#define pg_I2
Definition: symmetries.h:92
void initZeros()
Definition: matrix2d.h:626
int textToInteger(const char *str)
char * firstToken(const char *str)
#define pg_SN
Definition: symmetries.h:79
#define pg_CI
Definition: symmetries.h:74
#define pg_IH
Definition: symmetries.h:89
difference between tilt angles (double,degrees)
T Euler_distanceBetweenAngleSets_fast(const Matrix2D< T > &E1, T rot2, T tilt2, T psi2, bool only_projdir, Matrix2D< T > &E2)
Definition: geometry.cpp:693
void alignWithZ(const Matrix1D< double > &axis, Matrix2D< double > &result, bool homogeneous)
#define PI
Definition: tools.h:43
String nextToken(const String &str, size_t &i)
int trueSymsNo() const
Definition: symmetries.h:283
void initConstant(T val)
Definition: matrix1d.cpp:83
int * n
#define sym_undefined
Definition: symmetries.h:53
#define ZZ(v)
Definition: matrix1d.h:101
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)
Definition: matrix2d.cpp:1022
void initIdentity()
Definition: matrix2d.h:673
#define pg_I
Definition: symmetries.h:88
#define pg_I5
Definition: symmetries.h:95