39 double ang_incr, rot_ang;
45 std::vector<std::string> fileContent;
50 if ((fpoii = fopen(fn_sym.c_str(),
"r")) == NULL)
59 +
" or do not recognize symmetry group" + fn_sym);
63 while (fgets(line, 79, fpoii) != NULL)
65 if (line[0] ==
';' || line[0] ==
'#' || line[0] ==
'\0')
67 fileContent.push_back(line);
79 int no_axis, no_mirror_planes, no_inversion_points;
80 no_axis = no_mirror_planes = no_inversion_points = 0;
82 for (
size_t n=0;
n<fileContent.size();
n++)
84 strcpy(line,fileContent[
n].c_str());
89 std::cout <<
"Wrong line in symmetry file, the line is skipped\n";
92 if (strcmp(auxstr,
"rot_axis") == 0)
99 else if (strcmp(auxstr,
"mirror_plane") == 0)
104 else if (strcmp(auxstr,
"inversion") == 0)
107 no_inversion_points = 1;
109 else if (strcmp(auxstr,
"P4212") == 0)
111 else if (strcmp(auxstr,
"P2_122") == 0)
113 else if (strcmp(auxstr,
"P22_12") == 0)
127 for (
size_t n=0;
n<fileContent.size();
n++)
129 strcpy(line,fileContent[
n].c_str());
132 if (strcmp(auxstr,
"rot_axis") == 0)
142 ang_incr = 360. / fold;
144 for (j = 1, rot_ang = ang_incr; j < fold; j++, rot_ang += ang_incr)
153 else if (strcmp(auxstr,
"inversion") == 0)
166 else if (strcmp(auxstr,
"mirror_plane") == 0)
186 else if (strcmp(auxstr,
"P4212") == 0)
195 R(0, 0) = R(1, 1) = -1;
202 R(0, 1) = R(1, 0) = 1;
207 R(2, 2) = R(0, 1) = R(1, 0) = -1;
216 R(1, 0) = R(2, 2) = 1;
222 R(0, 1) = R(2, 2) = 1;
227 R(0, 0) = R(2, 2) = -1;
233 R(1, 1) = R(2, 2) = -1;
240 else if (strcmp(auxstr,
"P2_122") == 0)
273 else if (strcmp(auxstr,
"P22_12") == 0)
312 if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
315 else if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
318 else if (no_axis == 0 && no_mirror_planes == 0 && no_inversion_points == 0 &&
322 else if (no_axis == 1 && no_mirror_planes == 0 && no_inversion_points == 0 &&
340 else if (no_axis == 0 && no_inversion_points == 0 && no_mirror_planes == 0)
357 for (k = 4 * i, kp=0; k < 4*i + 4; k++, kp++)
358 for (l = 0; l < 4; l++)
368 for (k = 4 * i, kp=0; k < 4*i + 3; k++, kp++)
369 for (l = 0; l < 3; l++)
382 for (k = 4 * i; k < 4*i + 4; k++)
383 for (l = 0; l < 4; l++)
385 __L(k, l) = L(k - 4 * i, l);
386 __R(k, l) = R(k - 4 * i, l);
401 if (shift.
size() != 3)
410 if (shift.
size() != 3)
444 if (
dMij(tried,i, j) == 0 && !(i >= true_symNo && j >= true_symNo))
471 Matrix2D<double> L1(4, 4), R1(4, 4),
L2(4, 4), R2(4, 4), newL(4, 4), newR(4, 4),identity(4,4);
476 int new_chain_length;
493 if (newL.equal(identity, accuracy) &&
494 newR.equal(identity, accuracy))
500 for (
int l = 0; l <
symsNo(); l++)
503 if (newL.equal(
L1, accuracy) && newR.equal(R1, accuracy))
521 std::cerr <<
"newR " << kjhg++ <<
"\n" << newR <<std::endl;
530 std::cerr <<
"__R" <<
__R <<std::endl;
542 double ang_a2b_deg)
const 553 std::cerr <<
"\nWARNING: P42 but mag_a != mag_b\n" 554 <<
" or ang_a2b !=90" << std::endl;
560 std::cerr <<
"\nWARNING: P2_122 but mag_a != mag_b\n" 561 <<
" or ang_a2b !=90" << std::endl;
567 std::cerr <<
"\nWARNING: P22_12 but mag_a != mag_b\n" 568 <<
" or ang_a2b !=90" << std::endl;
574 std::cerr <<
"\nWARNING: P42_12 but mag_a != mag_b\n" 575 <<
" or ang_a2b !=90" << std::endl;
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";
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;
603 char G1,G2,G3=
'\0',G4;
611 int mySize=fn_sym_tmp.size();
616 if(mySize>4 || mySize<1)
623 G1=toupper((fn_sym_tmp.c_str())[0]);
624 G2=toupper((fn_sym_tmp.c_str())[1]);
627 G3=toupper((fn_sym_tmp.c_str())[2]);
629 G4=toupper((fn_sym.c_str())[3]);
634 if (mySize==2 && G1==
'C' && isdigit(G2))
640 if (mySize==3 && G1==
'C' && isdigit(G2) && isdigit(G3))
645 pgOrder=atoi(auxChar);
649 else if (mySize==2 && G1==
'C' && G2==
'I')
656 else if (mySize==2 && G1==
'C' && G2==
'S')
663 else if (mySize==3 && G1==
'C' && isdigit(G2) && G3==
'H')
669 else if (mySize==4 && G1==
'C' && isdigit(G2) && isdigit(G3) && G4==
'H')
674 pgOrder=atoi(auxChar);
678 else if (mySize==3 && G1==
'C' && isdigit(G2) && G3==
'V')
684 else if (mySize==4 && G1==
'C' && isdigit(G2) && isdigit(G3) && G4==
'V')
689 pgOrder=atoi(auxChar);
693 else if (mySize==2 && G1==
'S' && isdigit(G2) )
699 else if (mySize==3 && G1==
'S' && isdigit(G2) && isdigit(G3) )
704 pgOrder=atoi(auxChar);
708 else if (mySize==2 && G1==
'D' && isdigit(G2) )
714 if (mySize==3 && G1==
'D' && isdigit(G2) && isdigit(G3))
719 pgOrder=atoi(auxChar);
723 else if (mySize==3 && G1==
'D' && isdigit(G2) && G3==
'V')
729 else if (mySize==4 && G1==
'D' && isdigit(G2) && isdigit(G3) && G4==
'V')
734 pgOrder=atoi(auxChar);
738 else if (mySize==3 && G1==
'D' && isdigit(G2) && G3==
'H')
744 else if (mySize==4 && G1==
'D' && isdigit(G2) && isdigit(G3) && G4==
'H')
749 pgOrder=atoi(auxChar);
753 else if (mySize==1 && G1==
'T')
760 else if (mySize==2 && G1==
'T' && G2==
'D')
767 else if (mySize==2 && G1==
'T' && G2==
'H')
774 else if (mySize==1 && G1==
'O')
781 else if (mySize==2 && G1==
'O'&& G2==
'H')
788 else if (mySize==1 && G1==
'I')
795 else if (mySize==2 && G1==
'I'&& G2==
'1')
802 else if (mySize==2 && G1==
'I'&& G2==
'2')
809 else if (mySize==2 && G1==
'I'&& G2==
'3')
816 else if (mySize==2 && G1==
'I'&& G2==
'4')
823 else if (mySize==2 && G1==
'I'&& G2==
'5')
830 else if (mySize==2 && G1==
'I'&& G2==
'H')
837 else if (mySize==3 && G1==
'I'&& G2==
'1'&& G3==
'H')
844 else if (mySize==3 && G1==
'I'&& G2==
'2'&& G3==
'H')
851 else if (mySize==3 && G1==
'I'&& G2==
'3'&& G3==
'H')
858 else if (mySize==3 && G1==
'I'&& G2==
'4'&& G3==
'H')
865 else if (mySize==3 && G1==
'I'&& G2==
'5'&& G3==
'H')
873 std::cerr <<
"pgGroup" << pgGroup <<
" pgOrder " << pgOrder << std::endl;
880 std::vector<std::string> &fileContent)
882 std::ostringstream line1;
883 std::ostringstream line2;
884 std::ostringstream line3;
885 std::ostringstream line4;
886 if (pgGroup ==
pg_CN)
888 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
890 else if (pgGroup ==
pg_CI)
892 line1 <<
"inversion ";
894 else if (pgGroup ==
pg_CS)
896 line1 <<
"mirror_plane 0 0 1";
898 else if (pgGroup ==
pg_CNV)
900 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
901 line2 <<
"mirror_plane 0 1 0";
903 else if (pgGroup ==
pg_CNH)
905 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
906 line2 <<
"mirror_plane 0 0 1";
908 else if (pgGroup ==
pg_SN)
910 int order = pgOrder / 2;
911 if(2*order != pgOrder)
913 std::cerr <<
"ERROR: order for SN group must be even" << std::endl;
916 line1 <<
"rot_axis " << order <<
" 0 0 1";
917 line2 <<
"inversion ";
919 else if (pgGroup ==
pg_DN)
921 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
922 line2 <<
"rot_axis " <<
"2" <<
" 1 0 0";
924 else if (pgGroup ==
pg_DNV)
926 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
927 line2 <<
"rot_axis " <<
"2" <<
" 1 0 0";
928 line3 <<
"mirror_plane 1 0 0";
930 else if (pgGroup ==
pg_DNH)
932 line1 <<
"rot_axis " << pgOrder <<
" 0 0 1";
933 line2 <<
"rot_axis " <<
"2" <<
" 1 0 0";
934 line3 <<
"mirror_plane 0 0 1";
936 else if (pgGroup ==
pg_T)
938 line1 <<
"rot_axis " <<
"3" <<
" 0. 0. 1.";
939 line2 <<
"rot_axis " <<
"2" <<
" 0. 0.816496 0.577350";
941 else if (pgGroup ==
pg_TD)
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";
947 else if (pgGroup ==
pg_TH)
949 line1 <<
"rot_axis " <<
"3" <<
" 0. 0. 1.";
950 line2 <<
"rot_axis " <<
"2" <<
" 0. -0.816496 -0.577350";
951 line3 <<
"inversion";
953 else if (pgGroup ==
pg_O)
955 line1 <<
"rot_axis " <<
"3" <<
" .5773502 .5773502 .5773502";
956 line2 <<
"rot_axis " <<
"4" <<
" 0 0 1";
958 else if (pgGroup ==
pg_OH)
960 line1 <<
"rot_axis " <<
"3" <<
" .5773502 .5773502 .5773502";
961 line2 <<
"rot_axis " <<
"4" <<
" 0 0 1";
962 line3 <<
"mirror_plane 0 1 1";
964 else if (pgGroup ==
pg_I || pgGroup ==
pg_I2)
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";
970 else if (pgGroup ==
pg_I1)
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";
976 else if (pgGroup ==
pg_I3)
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";
982 else if (pgGroup ==
pg_I4)
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";
988 else if (pgGroup ==
pg_I5)
990 std::cerr <<
"ERROR: Symmetry pg_I5 not implemented" << std::endl;
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";
1000 else if (pgGroup ==
pg_I1H)
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";
1007 else if (pgGroup ==
pg_I3H)
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";
1014 else if (pgGroup ==
pg_I4H)
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";
1021 else if (pgGroup ==
pg_I5H)
1023 std::cerr <<
"ERROR: Symmetry pg_I5H not implemented" << std::endl;
1028 std::cerr <<
"ERROR: Symmetry " << symmetry <<
"is not known" << std::endl;
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());
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;
1050 if (pgGroup ==
pg_CN)
1052 return 4.*
PI/pgOrder;
1054 else if (pgGroup ==
pg_CI)
1058 else if (pgGroup ==
pg_CS)
1062 else if (pgGroup ==
pg_CNV)
1064 return 4.*
PI/pgOrder/2;
1066 else if (pgGroup ==
pg_CNH)
1068 return 4.*
PI/pgOrder/2;
1070 else if (pgGroup ==
pg_SN)
1072 return 4.*
PI/pgOrder;
1074 else if (pgGroup ==
pg_DN)
1076 return 4.*
PI/pgOrder/2;
1078 else if (pgGroup ==
pg_DNV)
1080 return 4.*
PI/pgOrder/4;
1082 else if (pgGroup ==
pg_DNH)
1084 return 4.*
PI/pgOrder/4;
1086 else if (pgGroup ==
pg_T)
1090 else if (pgGroup ==
pg_TD)
1094 else if (pgGroup ==
pg_TH)
1098 else if (pgGroup ==
pg_O)
1102 else if (pgGroup ==
pg_OH)
1106 else if (pgGroup ==
pg_I || pgGroup ==
pg_I2)
1110 else if (pgGroup ==
pg_I1)
1114 else if (pgGroup ==
pg_I3)
1118 else if (pgGroup ==
pg_I4)
1122 else if (pgGroup ==
pg_I5)
1130 else if (pgGroup ==
pg_I1H)
1134 else if (pgGroup ==
pg_I3H)
1138 else if (pgGroup ==
pg_I4H)
1142 else if (pgGroup ==
pg_I5H)
1148 std::cerr <<
"ERROR: Symmetry group, order=" << pgGroup
1158 bool projdir_mode,
bool check_mirrors,
1159 bool object_rotation)
1161 double rot1, tilt1, psi1;
1162 double rot2, tilt2, psi2;
1164 for (
const auto& row : md)
1177 projdir_mode, check_mirrors,
1189 double &rot2,
double &tilt2,
double &psi2,
1190 bool projdir_mode,
bool check_mirrors,
1191 bool object_rotation,
bool write_mirrors )
1198 double best_ang_dist = 3600;
1199 double best_rot2=0, best_tilt2=0, best_psi2=0;
1201 for (
int i = 0;
i < imax;
i++)
1203 double rot2p, tilt2p, psi2p;
1213 if (object_rotation)
1222 if (ang_dist < best_ang_dist)
1225 best_tilt2 = tilt2p;
1227 best_ang_dist = ang_dist;
1232 double rot2pm, tilt2pm, psi2pm;
1233 Euler_mirrorY(rot2p, tilt2p, psi2p, rot2pm, tilt2pm, psi2pm);
1235 rot2pm, tilt2pm, psi2pm,projdir_mode, E2);
1237 if (ang_dist_mirror < best_ang_dist)
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;
1250 return best_ang_dist;
1254 double &rot2,
double &tilt2,
double &psi2
1259 static bool doRandomize=
true;
1265 srand ( time(NULL) );
1268 int symOrder =
symsNo()+1;
1270 i = rand() % symOrder;
1281 rot2=rot1; tilt2=tilt1;psi2=psi1;
double nonRedundantProjectionSphere(int pgGroup, int pgOrder)
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
#define REPORT_ERROR(nerr, ErrormMsg)
Problem with matrix size.
void Euler_angles2matrix(T alpha, T beta, T gamma, Matrix2D< T > &A, bool homogeneous)
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
void Euler_mirrorY(double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
bool isSymmetryGroup(FileName fn_sym, int &pgGroup, int &pgOrder)
FileName removeDirectories(int keep=0) const
void inv(Matrix2D< T > &result) const
Matrix2D< T > transpose() const
void getShift(int i, Matrix1D< double > &shift) const
Matrix1D< int > __chain_length
void Euler_apply_transf(const Matrix2D< double > &L, const Matrix2D< double > &R, double rot, double tilt, double psi, double &newrot, double &newtilt, double &newpsi)
Matrix2D< double > __shift
void computeSubgroup(double accuracy=SYM_ACCURACY)
void fillSymmetryClass(const FileName &symmetry, int pgGroup, int pgOrder, std::vector< std::string > &fileContent)
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)
int crystallographicSpaceGroup(double mag_a, double mag_b, double ang_a2b_deg) const
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)
bool found_not_tried(const Matrix2D< int > &tried, int &i, int &j, int true_symNo)
void addMatrices(const Matrix2D< double > &L, const Matrix2D< double > &R, int chain_length)
float textToFloat(const char *str)
void addShift(const Matrix1D< double > &shift)
#define XMIPP_EQUAL_ACCURACY
void resize(size_t Xdim, bool copy=true)
void breakSymmetry(double rot1, double tilt1, double psi1, double &rot2, double &tilt2, double &psi2)
void setShift(int i, const Matrix1D< double > &shift)
void Euler_matrix2angles(const Matrix2D< double > &A, double &alpha, double &beta, double &gamma, bool homogeneous)
#define VECTOR_R3(v, x, y, z)
int textToInteger(const char *str)
char * firstToken(const char *str)
T Euler_distanceBetweenAngleSets_fast(const Matrix2D< T > &E1, T rot2, T tilt2, T psi2, bool only_projdir, Matrix2D< T > &E2)
String nextToken(const String &str, size_t &i)
void resize(size_t Ydim, size_t Xdim, bool noCopy=false)