26 proshade_double
determinePeakThreshold ( std::vector < proshade_double > inArr, proshade_double noIQRsFromMedian );
28 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestIcosDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
29 std::pair< proshade_unsign, proshade_unsign >
findBestOctaDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
30 std::pair< proshade_unsign, proshade_unsign >
findBestTetraDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
74 proshade_double ret = 0.0;
75 proshade_double rmsd = 0.0;
76 size_t vecSize = inArr.size();
79 if ( vecSize == 0 ) {
return ( ret ); }
80 if ( vecSize <= 4 ) { ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) /
static_cast< proshade_double
> ( vecSize );
return ( ret ); }
86 ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) /
static_cast< proshade_double
> ( vecSize );
89 for (
size_t i = 0; i < vecSize; i++ )
91 rmsd += std::pow ( ret - inArr.at(i), 2.0 );
93 rmsd = std::sqrt ( rmsd );
96 ret = ret + ( noIQRsFromMedian * rmsd );
100 if ( ret > *( std::max_element ( inArr.begin(), inArr.end() ) ) )
102 ret = *( std::max_element ( inArr.begin(), inArr.end() ) );
127 proshade_double shellSpacing = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( this->maxShellBand ) * 2.0;
128 std::vector< proshade_double > allPeakHeights;
131 for ( proshade_unsign spIt = 1; spIt < ( this->maxShellBand * 2 ); spIt++ )
135 this->maxShellBand * 2,
136 static_cast<proshade_double
> ( spIt ) * shellSpacing,
141 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereMappedRotFun.size() ); shIt++ )
144 std::stringstream hlpSS;
145 hlpSS <<
"Interpolating sphere " << shIt <<
" ( radius: " << this->sphereMappedRotFun.at(shIt)->getRadius() <<
" ).";
149 this->sphereMappedRotFun.at(shIt)->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
157 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
159 this->sphereMappedRotFun.at(shIt)->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
163 std::stringstream hlpSS;
164 hlpSS <<
"Detected " << allPeakHeights.size() <<
" peaks with any height.";
171 std::stringstream hlpSS2;
172 hlpSS2 <<
"From these peaks, decided the threshold will be " << peakThres <<
" peak height.";
176 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
178 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( peakThres );
203 proshade_double dotProduct = 0.0;
207 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
210 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
211 if ( lhs.AlmostEquals ( rhs ) )
215 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
216 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
219 *matchedPos =
static_cast< proshade_signed
> ( symIt );
222 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
225 ret->at(symIt)[1] = sym[1];
226 ret->at(symIt)[2] = sym[2];
227 ret->at(symIt)[3] = sym[3];
228 ret->at(symIt)[5] = sym[5];
254 proshade_double dotProduct = 0.0;
258 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
261 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
262 if ( lhs.AlmostEquals ( rhs ) )
266 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
267 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
270 *matchedPos =
static_cast< proshade_signed
> ( symIt );
273 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
276 ret->at(symIt)[1] = sym[1];
277 ret->at(symIt)[2] = sym[2];
278 ret->at(symIt)[3] = sym[3];
279 ret->at(symIt)[5] = sym[5];
280 ret->at(symIt)[6] = fscVal;
305 std::vector< proshade_double* > ret;
306 proshade_double dotProduct;
312 if ( CSymList->size() < 2 ) {
return ( ret ); }
315 for ( proshade_unsign ax1 = 0; ax1 < static_cast<proshade_unsign> ( CSymList->size() ); ax1++ )
318 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(ax1)[5] ), rhs1 ( -999.9 );
319 if ( ( CSymList->at(ax1)[5] < settings->
minSymPeak ) && !( lhs1.AlmostEquals ( rhs1 ) ) ) {
continue; }
321 for ( proshade_unsign ax2 = 1; ax2 < static_cast<proshade_unsign> ( CSymList->size() ); ax2++ )
324 if ( ax1 >= ax2 ) {
continue; }
327 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(ax2)[5] ), rhs2 ( -999.9 );
328 if ( ( CSymList->at(ax2)[5] < settings->
minSymPeak ) && !( lhs2.AlmostEquals ( rhs2 ) ) ) {
continue; }
332 &CSymList->at(ax1)[3], &CSymList->at(ax2)[1],
333 &CSymList->at(ax2)[2], &CSymList->at(ax2)[3] );
339 if ( CSymList->at(ax1)[0] >= CSymList->at(ax2)[0] )
343 std::vector< proshade_unsign > DSymInd;
353 std::vector< proshade_unsign > DSymInd;
363 std::stringstream hlpSS;
364 hlpSS <<
"Detected " << ret.size() <<
" D symmetries.";
386 proshade_double* hlpP =
new proshade_double [14];
390 hlpP[0] = CSymList->at(axisOne)[0];
391 hlpP[1] = CSymList->at(axisOne)[1];
392 hlpP[2] = CSymList->at(axisOne)[2];
393 hlpP[3] = CSymList->at(axisOne)[3];
394 hlpP[4] = CSymList->at(axisOne)[4];
395 hlpP[5] = CSymList->at(axisOne)[5];
396 hlpP[6] = CSymList->at(axisOne)[6];
397 hlpP[7] = CSymList->at(axisTwo)[0];
398 hlpP[8] = CSymList->at(axisTwo)[1];
399 hlpP[9] = CSymList->at(axisTwo)[2];
400 hlpP[10] = CSymList->at(axisTwo)[3];
401 hlpP[11] = CSymList->at(axisTwo)[4];
402 hlpP[12] = CSymList->at(axisTwo)[5];
403 hlpP[13] = CSymList->at(axisTwo)[6];
425 std::vector< proshade_double* > ret;
441 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
443 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
449 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
450 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
451 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
452 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
453 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
454 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
455 if ( ( lhs1.AlmostEquals ( rhs1 ) ) &&
456 ( lhs2.AlmostEquals ( rhs2 ) ) &&
457 ( lhs3.AlmostEquals ( rhs3 ) ) &&
458 ( lhs4.AlmostEquals ( rhs4 ) ) &&
459 ( lhs5.AlmostEquals ( rhs5 ) ) &&
460 ( lhs6.AlmostEquals ( rhs6 ) ) )
491 std::vector< proshade_unsign > C3List;
492 proshade_double dotProduct;
495 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
497 const FloatingPoint< proshade_double > lhs ( CSymList->at(cSym)[0] ), rhs ( 3.0 );
502 for ( proshade_unsign c31 = 0; c31 < static_cast<proshade_unsign> ( C3List.size() ); c31++ )
504 for ( proshade_unsign c32 = 1; c32 < static_cast<proshade_unsign> ( C3List.size() ); c32++ )
507 if ( c31 >= c32 ) {
continue; }
510 dotProduct =
ProSHADE_internal_maths::computeDotProduct ( &CSymList->at(C3List.at(c31))[1], &CSymList->at(C3List.at(c31))[2], &CSymList->at(C3List.at(c31))[3], &CSymList->at(C3List.at(c32))[1], &CSymList->at(C3List.at(c32))[2], &CSymList->at(C3List.at(c32))[3] );
513 if ( ( ( 1.0 / 3.0 ) > ( dotProduct - axErr ) ) && ( ( 1.0 / 3.0 ) < ( dotProduct + axErr ) ) )
542 std::vector< proshade_unsign > C3PossibilitiesHlp;
543 std::vector< std::vector< proshade_unsign > > C3Possibilities;
550 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
553 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
559 groupMatched =
false;
560 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
573 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
574 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( C3Possibilities.size() ); iter++ ) {
if ( C3Possibilities.at(iter).size() == 4 ) {
if ( ( ( CSymList->at(C3Possibilities.at(iter).at(0))[5] + CSymList->at(C3Possibilities.at(iter).at(1))[5] + CSymList->at(C3Possibilities.at(iter).at(2))[5] + CSymList->at(C3Possibilities.at(iter).at(3))[5] ) / 4.0 ) > maxHeight ) { maxHeight = ( ( CSymList->at(C3Possibilities.at(iter).at(0))[5] + CSymList->at(C3Possibilities.at(iter).at(1))[5] + CSymList->at(C3Possibilities.at(iter).at(2))[5] + CSymList->at(C3Possibilities.at(iter).at(3))[5] ) / 4.0 ); maxGrp = iter; } } }
576 if ( C3Possibilities.at(maxGrp).size() == 4 )
579 for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( C3Possibilities.at(maxGrp).size() ); it++ ) {
ProSHADE_internal_misc::addToDblPtrVector ( ret, CSymList->at(C3Possibilities.at(maxGrp).at(it)) ); }
612 bool allAnglesMet =
true;
613 proshade_double dotProduct;
618 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
622 if ( ( ( 1.0 > ( dotProduct - axErr ) ) && ( 1.0 < ( dotProduct + axErr ) ) ) || ( ( -1.0 > ( dotProduct - axErr ) ) && ( -1.0 < ( dotProduct + axErr ) ) ) )
624 if ( sym[5] > CSymList->at(grp->at(mIt))[5] )
630 allAnglesMet =
false;
631 return ( allAnglesMet );
638 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
642 if ( ( angle > ( std::abs ( dotProduct ) - axErr ) ) &&
643 ( angle < ( std::abs ( dotProduct ) + axErr ) ) )
650 allAnglesMet =
false;
656 return ( allAnglesMet );
679 std::vector< proshade_double* > hlpVec;
680 bool atLeastOne =
false;
683 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
685 if (
static_cast<proshade_unsign
> ( possibilities->at(gIt).size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
689 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
692 if ( possibilities->at(gIt).size() < 2 ) {
continue; }
701 if ( hlpVec.size() > 0 )
707 for ( proshade_unsign axIt = 0; axIt < static_cast<proshade_unsign> ( hlpVec.size() ); axIt++ )
722 if ( possibilities->at(gIt).size() == requiredNoAxes ) { atLeastOne =
true; }
726 return ( atLeastOne );
739 return ( a[0] < b[0] );
760 proshade_double ret = 0.0;
761 proshade_double curSum = 0.0;
762 proshade_double maxVal = 0.0;
763 proshade_double angStep = std::acos ( 1.0 - axErr ) / 2;
764 std::vector< proshade_double* > angVec;
773 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( std::floor ( ( 2.0 * M_PI / angStep ) /
static_cast< proshade_double
> ( fold ) ) ); iter++ )
779 for ( proshade_unsign angCmb = 0; angCmb < static_cast<proshade_unsign> ( fold ); angCmb++ )
785 for ( proshade_unsign angIt = 0; angIt < static_cast<proshade_unsign> ( angVec.size() ); angIt++ )
787 if ( angVec.at(angIt)[0] < ( (
static_cast< proshade_double
> ( iter ) * angStep ) +
788 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
continue; }
789 if ( angVec.at(angIt)[0] > ( ( (
static_cast< proshade_double
> ( iter ) + 1.0 ) * angStep ) +
790 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
break; }
792 if ( angVec.at(angIt)[1] > maxVal ) { maxVal = angVec.at(angIt)[1]; }
796 curSum /=
static_cast<proshade_double
> ( fold );
797 if ( ret < curSum ) { ret = curSum; }
801 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( angVec.size() ); iter++ ) {
delete[] angVec.at(iter); }
824 proshade_double euA, euB, euG, xPk, yPk, zPk, anglPk;
825 proshade_double* rotMat =
new proshade_double [9];
827 proshade_unsign arrIndex;
828 std::vector< proshade_double* > angVec;
831 for ( proshade_unsign xIt = 0; xIt < ( dataObj->
getMaxBand() * 2 ); xIt++ )
833 for ( proshade_unsign yIt = 0; yIt < ( dataObj->
getMaxBand() * 2 ); yIt++ )
835 for ( proshade_unsign zIt = 0; zIt < ( dataObj->
getMaxBand() * 2 ); zIt++ )
842 static_cast< proshade_signed
> ( yIt ),
static_cast< proshade_signed
> ( zIt ),
848 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( xPk ), std::max( std::abs ( yPk ), std::abs ( zPk ) ) ) );
849 const FloatingPoint< proshade_double > rhs1 ( std::abs ( xPk ));
850 const FloatingPoint< proshade_double > rhs2 ( std::abs ( yPk ) );
851 const FloatingPoint< proshade_double > rhs3 ( std::abs ( zPk ) );
852 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( xPk < 0.0 ) ) ||
853 ( lhs1.AlmostEquals ( rhs2 ) && ( yPk < 0.0 ) ) ||
854 ( lhs1.AlmostEquals ( rhs3 ) && ( zPk < 0.0 ) ) )
866 proshade_double* hlpArr =
new proshade_double [2];
868 hlpArr[0] = anglPk + M_PI;
902 proshade_double* hlpSym =
new proshade_double [6];
906 hlpSym[0] =
static_cast<proshade_double
> ( fold );
910 hlpSym[4] = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( fold );
914 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( axVec->size() ); symIt++ )
917 const FloatingPoint< proshade_double > lhs1 ( axVec->at(symIt)[0] ), rhs1 ( hlpSym[0] );
918 if ( lhs1.AlmostEquals ( rhs1 ) )
929 if ( axVec->at(symIt)[5] < hlpSym[5] )
932 delete[] axVec->at(symIt);
933 axVec->at(symIt) = hlpSym;
971 if ( grp->size() < 2 ) {
return; }
974 proshade_double axHeight = 0.0;
975 proshade_double* symHlp =
new proshade_double[7];
979 for ( proshade_unsign fAx = 0; fAx < static_cast<proshade_unsign> ( grp->size() ); fAx++ )
981 for ( proshade_unsign sAx = 1; sAx < static_cast<proshade_unsign> ( grp->size() ); sAx++ )
984 if ( fAx >= sAx ) {
continue; }
988 CSymList->at(grp->at(fAx))[2],
989 CSymList->at(grp->at(fAx))[3],
990 CSymList->at(grp->at(sAx))[1],
991 CSymList->at(grp->at(sAx))[2],
992 CSymList->at(grp->at(sAx))[3], angle, angle );
995 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
996 const FloatingPoint< proshade_double > rhs1 ( std::abs ( solVec.at(0) ) );
997 const FloatingPoint< proshade_double > rhs2 ( std::abs ( solVec.at(1) ) );
998 const FloatingPoint< proshade_double > rhs3 ( std::abs ( solVec.at(2) ) );
999 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( solVec.at(0) < 0.0 ) ) ||
1000 ( lhs1.AlmostEquals ( rhs2 ) && ( solVec.at(1) < 0.0 ) ) ||
1001 ( lhs1.AlmostEquals ( rhs3 ) && ( solVec.at(2) < 0.0 ) ) )
1003 solVec.at(0) *= -1.0;
1004 solVec.at(1) *= -1.0;
1005 solVec.at(2) *= -1.0;
1009 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
1021 CSymList->at(grp->at(fAx))[2],
1022 CSymList->at(grp->at(fAx))[3],
1023 CSymList->at(grp->at(sAx))[1],
1024 CSymList->at(grp->at(sAx))[2],
1025 CSymList->at(grp->at(sAx))[3], -angle, -angle );
1028 const FloatingPoint< proshade_double > lhs2 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
1029 const FloatingPoint< proshade_double > rhs4 ( std::abs ( solVec.at(0) ) );
1030 const FloatingPoint< proshade_double > rhs5 ( std::abs ( solVec.at(1) ) );
1031 const FloatingPoint< proshade_double > rhs6 ( std::abs ( solVec.at(2) ) );
1032 if ( ( lhs2.AlmostEquals ( rhs4 ) && ( solVec.at(0) < 0.0 ) ) ||
1033 ( lhs2.AlmostEquals ( rhs5 ) && ( solVec.at(1) < 0.0 ) ) ||
1034 ( lhs2.AlmostEquals ( rhs6 ) && ( solVec.at(2) < 0.0 ) ) )
1036 solVec.at(0) *= -1.0;
1037 solVec.at(1) *= -1.0;
1038 solVec.at(2) *= -1.0;
1042 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
1079 std::vector< proshade_unsign > C3s, prospectiveC2s, C2PossibilitiesHlp;
1080 std::vector< std::vector< proshade_unsign > > C2Possibilities;
1081 proshade_double dotProd;
1089 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
1092 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1095 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
1096 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
1100 &CSymList->at(cIt)[1], &CSymList->at(cIt)[2], &CSymList->at(cIt)[3] );
1107 C2Possibilities.clear(); C2PossibilitiesHlp.clear();
1108 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC2s.size() ); cIt++ )
1111 groupMatched =
false;
1112 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C2Possibilities.size() ); gIt++ )
1122 while ( C2Possibilities.size() != 0 )
1128 if ( C2Possibilities.at(0).size() == 3 )
1139 else { C2Possibilities.erase ( C2Possibilities.begin() ); }
1161 bool ProSHADE_internal_symmetry::testGroupAgainstGroup ( std::vector< proshade_double* >* GrList1, std::vector< proshade_unsign >* grp1, std::vector< proshade_double* >* GrList2, std::vector< proshade_unsign >* grp2, proshade_double angle, proshade_double axErr )
1165 proshade_double dotProduct;
1168 for ( proshade_unsign g1It = 0; g1It < static_cast<proshade_unsign> ( grp1->size() ); g1It++ )
1170 for ( proshade_unsign g2It = 0; g2It < static_cast<proshade_unsign> ( grp2->size() ); g2It++ )
1174 &GrList1->at(grp1->at(g1It))[2],
1175 &GrList1->at(grp1->at(g1It))[3],
1176 &GrList2->at(grp2->at(g2It))[1],
1177 &GrList2->at(grp2->at(g2It))[2],
1178 &GrList2->at(grp2->at(g2It))[3] );
1181 if ( ( angle > ( dotProduct - axErr ) ) && ( angle < ( dotProduct + axErr ) ) )
1207 std::vector< proshade_double* > ret;
1226 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
1228 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
1234 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
1235 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
1236 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
1237 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
1238 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
1239 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
1240 if ( lhs1.AlmostEquals ( rhs1 ) &&
1241 lhs2.AlmostEquals ( rhs2 ) &&
1242 lhs3.AlmostEquals ( rhs3 ) &&
1243 lhs4.AlmostEquals ( rhs4 ) &&
1244 lhs5.AlmostEquals ( rhs5 ) &&
1245 lhs6.AlmostEquals ( rhs6 ) )
1276 std::vector< proshade_unsign > C4List;
1277 proshade_double dotProduct;
1280 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1282 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 4.0 );
1287 for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
1289 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1292 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1293 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
1297 &CSymList->at(C4List.at(c4))[2],
1298 &CSymList->at(C4List.at(c4))[3],
1299 &CSymList->at(cSym)[1],
1300 &CSymList->at(cSym)[2],
1301 &CSymList->at(cSym)[3] );
1304 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( dotProduct - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( dotProduct + axErr ) ) )
1334 std::vector< proshade_unsign > C4PossibilitiesHlp;
1335 std::vector< std::vector< proshade_unsign > > C4Possibilities;
1342 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1345 if ( CSymList->at(cIt)[0] != 4.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
1348 groupMatched =
false;
1349 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C4Possibilities.size() ); gIt++ )
1362 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
1363 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( C4Possibilities.size() ); iter++ ) {
if ( C4Possibilities.at(iter).size() == 3 ) {
if ( ( ( CSymList->at(C4Possibilities.at(iter).at(0))[5] + CSymList->at(C4Possibilities.at(iter).at(1))[5] + CSymList->at(C4Possibilities.at(iter).at(2))[5] ) / 3.0 ) > maxHeight ) { maxHeight = ( ( CSymList->at(C4Possibilities.at(iter).at(0))[5] + CSymList->at(C4Possibilities.at(iter).at(1))[5] + CSymList->at(C4Possibilities.at(iter).at(2))[5] ) / 3.0 ); maxGrp = iter; } } }
1365 if ( C4Possibilities.at(maxGrp).size() == 3 )
1368 for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( C4Possibilities.at(maxGrp).size() ); it++ ) {
ProSHADE_internal_misc::addToDblPtrVector ( ret, CSymList->at(C4Possibilities.at(maxGrp).at(it)) ); }
1401 std::vector< proshade_unsign > C4s, prospectiveC3s, C3PossibilitiesHlp;
1402 std::vector< std::vector< proshade_unsign > > C3Possibilities;
1403 proshade_double dotProd;
1411 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
1414 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1417 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
1427 C3Possibilities.clear(); C3PossibilitiesHlp.clear();
1428 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC3s.size() ); cIt++ )
1431 groupMatched =
false;
1432 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
1442 while ( C3Possibilities.size() != 0 )
1448 if ( C3Possibilities.at(0).size() == 4 )
1459 else { C3Possibilities.erase ( C3Possibilities.begin() ); }
1484 std::vector< proshade_unsign > prospectiveC2s, retGrp;
1485 proshade_double dotProd;
1486 proshade_unsign noPerpendicular, noSqrtTwo;
1492 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1495 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
1496 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && ! ( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
1499 noPerpendicular = 0; noSqrtTwo = 0;
1500 for ( proshade_unsign rIt = 0; rIt < 3; rIt++ )
1505 &CSymList->at(cIt)[1],
1506 &CSymList->at(cIt)[2],
1507 &CSymList->at(cIt)[3] );
1509 if ( ( std::abs ( dotProd ) > ( ( 1.0 / sqrt(2.0) ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / sqrt(2.0) ) + axErr ) ) ) { noSqrtTwo += 1;
continue; }
1510 if ( ( std::abs ( dotProd ) > ( 0.0 - axErr ) ) && ( std::abs ( dotProd ) < ( 0.0 + axErr ) ) ) { noPerpendicular += 1;
continue; }
1514 if ( ( noSqrtTwo == 2 ) && ( noPerpendicular == 1 ) )
1522 if ( !
ProSHADE_internal_symmetry::findMissingAxesDual ( &prospectiveC2s, CSymList, ret, &retGrp, 6, axErr, 1, 0.0, 2, 1/sqrt(2.0), 2, dataObj ) )
1528 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
1562 bool ProSHADE_internal_symmetry::findMissingAxesDual ( std::vector< proshade_unsign >* possibilities, std::vector< proshade_double* >* CSymList, std::vector< proshade_double* >* ret, std::vector< proshade_unsign >* retGroup, proshade_unsign requiredNoAxes, proshade_double axErr, proshade_unsign noMatchesG1, proshade_double angle1, proshade_unsign noMatchesG2, proshade_double angle2, proshade_unsign fold,
ProSHADE_internal_data::ProSHADE_data* dataObj )
1565 bool atLeastOne =
false;
1566 std::vector< proshade_double* > prosp;
1567 std::vector< proshade_double > sol;
1570 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
1573 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
1576 CSymList->at(possibilities->at(prIt))[1],
1577 CSymList->at(possibilities->at(prIt))[2],
1578 CSymList->at(possibilities->at(prIt))[3],
1579 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
1583 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
1585 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
1588 if ( rgIt1 == rgIt2 ) {
continue; }
1592 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], angle1, angle2 );
1595 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
1596 if ( prosp.size() == requiredNoAxes ) {
break; }
1600 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], -angle1, -angle2 );
1603 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
1604 if ( prosp.size() == requiredNoAxes ) {
break; }
1607 if ( prosp.size() == requiredNoAxes ) {
break; }
1611 if (
static_cast<proshade_unsign
> ( prosp.size() ) == requiredNoAxes )
1614 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
1626 return ( atLeastOne );
1631 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
1633 delete[] prosp.at(iter);
1638 return ( atLeastOne );
1657 proshade_signed
ProSHADE_internal_symmetry::addAxisUnlessSame ( proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axHeight, proshade_double averageFSC, std::vector< proshade_double* >* prosp, proshade_double axErr )
1660 proshade_double* symHlp =
new proshade_double[7];
1662 proshade_signed ret = -1;
1665 symHlp[0] =
static_cast<proshade_double
> ( fold );
1669 symHlp[4] = 2.0 * M_PI / symHlp[0];
1670 symHlp[5] = axHeight;
1671 symHlp[6] = averageFSC;
1677 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
1706 proshade_double* symHlp =
new proshade_double[7];
1708 proshade_signed ret = -1;
1711 symHlp[0] =
static_cast<proshade_double
> ( fold );
1715 symHlp[4] = 2.0 * M_PI / symHlp[0];
1716 symHlp[5] = axHeight;
1717 symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
1723 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
1756 bool ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( std::vector< proshade_unsign >* retGroup, std::vector< proshade_double* >* ret, proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, std::vector< proshade_double* >* prosp, proshade_double axErr, proshade_unsign noMatchesG1, proshade_double angle1, proshade_unsign noMatchesG2, proshade_double angle2,
ProSHADE_internal_data::ProSHADE_data* dataObj )
1759 proshade_unsign noG1 = 0;
1760 proshade_unsign noG2 = 0;
1761 proshade_double dotProd = 0.0;
1762 proshade_double axHeight = 0.0;
1765 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
1768 &ret->at(retGroup->at(rIt))[2],
1769 &ret->at(retGroup->at(rIt))[3],
1772 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
1773 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
1777 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) )
1783 if ( axHeight > 0.1 )
1785 proshade_unsign prevProsp =
static_cast<proshade_unsign
> ( prosp->size() );
1788 if (
static_cast<proshade_unsign
> ( prosp->size() ) > prevProsp ) {
return (
true ); }
1789 else {
return (
false ); }
1811 std::vector< proshade_double* > ret;
1834 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
1836 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
1838 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
1839 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
1840 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
1841 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
1842 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
1843 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
1844 if ( lhs1.AlmostEquals ( rhs1 ) &&
1845 lhs2.AlmostEquals ( rhs2 ) &&
1846 lhs3.AlmostEquals ( rhs3 ) &&
1847 lhs4.AlmostEquals ( rhs4 ) &&
1848 lhs5.AlmostEquals ( rhs5 ) &&
1849 lhs6.AlmostEquals ( rhs6 ) )
1883 std::vector< std::vector< proshade_double* > > ret;
1895 for (
size_t pIt = 0; pIt < ret.size(); pIt++ )
1930 std::vector< proshade_double* > ret;
1945 for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ret.size() ); retIt++ )
1974 std::vector< proshade_unsign > C5List;
1975 proshade_double dotProduct;
1978 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1980 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 5.0 );
1985 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
1987 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1990 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1991 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
1995 &CSymList->at(C5List.at(c5))[2],
1996 &CSymList->at(C5List.at(c5))[3],
1997 &CSymList->at(cSym)[1],
1998 &CSymList->at(cSym)[2],
1999 &CSymList->at(cSym)[3] );
2002 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
2035 std::vector< proshade_unsign > C5PossibilitiesHlp;
2036 std::vector< std::vector< proshade_unsign > > C5Possibilities;
2043 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2046 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cIt)[0] ), rhs1 ( 5.0 );
2047 if ( !lhs1.AlmostEquals ( rhs1 ) || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
2050 groupMatched =
false;
2051 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C5Possibilities.size() ); gIt++ )
2064 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
2065 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( C5Possibilities.size() ); iter++ ) {
if ( C5Possibilities.at(iter).size() == 6 ) {
if ( ( ( CSymList->at(C5Possibilities.at(iter).at(0))[5] + CSymList->at(C5Possibilities.at(iter).at(1))[5] + CSymList->at(C5Possibilities.at(iter).at(2))[5] + CSymList->at(C5Possibilities.at(iter).at(3))[5] + CSymList->at(C5Possibilities.at(iter).at(4))[5] + CSymList->at(C5Possibilities.at(iter).at(5))[5] ) / 6.0 ) > maxHeight ) { maxHeight = ( ( CSymList->at(C5Possibilities.at(iter).at(0))[5] + CSymList->at(C5Possibilities.at(iter).at(1))[5] + CSymList->at(C5Possibilities.at(iter).at(2))[5] + CSymList->at(C5Possibilities.at(iter).at(3))[5] + CSymList->at(C5Possibilities.at(iter).at(4))[5] + CSymList->at(C5Possibilities.at(iter).at(5))[5] ) / 6.0 ); maxGrp = iter; } } }
2067 if ( C5Possibilities.at(maxGrp).size() == 6 )
2070 for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( C5Possibilities.at(maxGrp).size() ); it++ ) {
ProSHADE_internal_misc::addToDblPtrVector ( ret, CSymList->at(C5Possibilities.at(maxGrp).at(it)) ); }
2091 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestIcosDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
2094 std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
2095 std::vector< proshade_unsign > C5List;
2096 proshade_double dotProduct;
2099 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) {
const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 5.0 );
if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) {
ProSHADE_internal_misc::addToUnsignVector ( &C5List, cSym ); } }
2102 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
2104 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2107 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
2108 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
2109 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
2113 &CSymList->at(C5List.at(c5))[2],
2114 &CSymList->at(C5List.at(c5))[3],
2115 &CSymList->at(cSym)[1],
2116 &CSymList->at(cSym)[2],
2117 &CSymList->at(cSym)[3] );
2120 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
2122 std::pair< proshade_unsign, proshade_unsign > hlp;
2123 hlp.first = C5List.at(c5);
2125 ret.emplace_back ( hlp );
2157 std::vector < std::pair< proshade_unsign, proshade_unsign > > initAxes =
findBestIcosDihedralPair ( CSymList, minPeakHeight, axErr );
2160 for (
size_t pIt = 0; pIt < initAxes.size(); pIt++ )
2169 CSymList->at(initAxes.at(pIt).first)[1],
2170 CSymList->at(initAxes.at(pIt).first)[2],
2171 CSymList->at(initAxes.at(pIt).first)[3] );
2180 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
2181 proshade_double* rotMatHlp =
new proshade_double[9];
2183 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
2195 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.at(pIt).second)[1], 2.0 ) +
2196 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.at(pIt).second)[2], 2.0 ) +
2197 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.at(pIt).second)[3], 2.0 ) );
2200 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
2203 delete[] rotRotModelC3;
2210 proshade_double* rotMat2 =
new proshade_double[9];
2218 std::vector< proshade_double* > hlpAxes;
2219 for ( proshade_unsign iter = 0; iter < icoAx->
getNoAxes ( ); iter++ )
2228 proshade_double* axis =
new proshade_double[7];
2231 axis[0] = icoAx->
getValue ( iter, 0 );
2232 axis[1] = rotAxis[0];
2233 axis[2] = rotAxis[1];
2234 axis[3] = rotAxis[2];
2235 axis[4] = ( 2.0 * M_PI ) / axis[0];
2237 axis[6] = -std::numeric_limits < proshade_double >::infinity();
2248 ret->emplace_back ( hlpAxes );
2254 delete[] rotModelC3;
2270 std::pair< proshade_unsign, proshade_unsign >
findBestOctaDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
2273 std::pair< proshade_unsign, proshade_unsign > ret;
2274 std::vector< proshade_unsign > C4List;
2275 proshade_double bestHeightSum = 0.0;
2276 proshade_double dotProduct;
2279 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) {
const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 4.0 );
if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) {
ProSHADE_internal_misc::addToUnsignVector ( &C4List, cSym ); } }
2282 for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
2284 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2287 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
2288 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
2289 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
2293 &CSymList->at(C4List.at(c4))[2],
2294 &CSymList->at(C4List.at(c4))[3],
2295 &CSymList->at(cSym)[1],
2296 &CSymList->at(cSym)[2],
2297 &CSymList->at(cSym)[3] );
2300 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
2302 if ( bestHeightSum < ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] ) )
2304 bestHeightSum = ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] );
2305 ret.first = C4List.at(c4);
2343 std::pair< proshade_unsign, proshade_unsign > initAxes =
findBestOctaDihedralPair ( CSymList, minPeakHeight, axErr );
2349 CSymList->at(initAxes.first)[1],
2350 CSymList->at(initAxes.first)[2],
2351 CSymList->at(initAxes.first)[3] );
2360 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
2361 proshade_double* rotMatHlp =
new proshade_double[9];
2363 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
2375 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.second)[1], 2.0 ) +
2376 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.second)[2], 2.0 ) +
2377 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.second)[3], 2.0 ) );
2380 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
2383 delete[] rotRotModelC3;
2390 proshade_double* rotMat2 =
new proshade_double[9];
2398 for ( proshade_unsign iter = 0; iter < octAx->
getNoAxes ( ); iter++ )
2407 proshade_double* axis =
new proshade_double[7];
2410 axis[0] = octAx->
getValue ( iter, 0 );
2411 axis[1] = rotAxis[0];
2412 axis[2] = rotAxis[1];
2413 axis[3] = rotAxis[2];
2414 axis[4] = ( 2.0 * M_PI ) / axis[0];
2416 axis[6] = -std::numeric_limits < proshade_double >::infinity();
2429 delete[] rotModelC3;
2454 std::vector< proshade_unsign > prospectiveC3s, retGrp;
2455 proshade_double dotProd;
2456 proshade_unsign noClose, noAway;
2462 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2465 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
2468 noClose = 0; noAway = 0;
2469 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
2474 &CSymList->at(cIt)[1],
2475 &CSymList->at(cIt)[2],
2476 &CSymList->at(cIt)[3] );
2478 if ( ( std::abs ( dotProd ) > ( ( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) + axErr ) ) ) { noClose += 1;
continue; }
2479 if ( ( std::abs ( dotProd ) > ( 1.0 - ( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - axErr ) ) && ( std::abs ( dotProd ) < ( 1.0 - ( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) + axErr ) ) ) { noAway += 1;
continue; }
2483 if ( ( noClose == 3 ) && ( noAway == 3 ) )
2491 if ( !
ProSHADE_internal_symmetry::findMissingAxesDual ( &prospectiveC3s, CSymList, ret, &retGrp, 10, axErr, 3, std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ), 3, 1.0 - ( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ), 3, dataObj ) )
2497 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC3s.size() ); iter++ )
2527 std::vector< proshade_unsign > prospectiveC2s, retGrp;
2528 proshade_double dotProd;
2529 proshade_unsign noClose, noMidway, noAway;
2535 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2538 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2539 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
2542 noClose = 0; noMidway = 0; noAway = 0;
2543 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
2548 &CSymList->at(cIt)[1],
2549 &CSymList->at(cIt)[2],
2550 &CSymList->at(cIt)[3] );
2552 if ( ( std::abs ( dotProd ) > ( ( sqrt ( 3.0 ) / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( sqrt ( 3.0 ) / 2.0 ) + axErr ) ) ) { noAway += 1;
continue; }
2553 if ( ( std::abs ( dotProd ) > ( ( 1.0 / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / 2.0 ) + axErr ) ) ) { noMidway += 1;
continue; }
2554 if ( ( std::abs ( dotProd ) > ( ( 0.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 0.0 ) + axErr ) ) ) { noClose += 1;
continue; }
2558 if ( ( noClose == 2 ) && ( noMidway == 2 ) && ( noAway == 2 ) )
2566 if ( !
ProSHADE_internal_symmetry::findMissingAxesTriple ( &prospectiveC2s, CSymList, ret, &retGrp, 15, axErr, 2, 0.0, 2, 1.0/2.0, 2, sqrt ( 3.0 ) / 2.0, 2, dataObj ) )
2572 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
2607 bool ProSHADE_internal_symmetry::findMissingAxesTriple ( std::vector< proshade_unsign >* possibilities, std::vector< proshade_double* >* CSymList, std::vector< proshade_double* >* ret, std::vector< proshade_unsign >* retGroup, proshade_unsign requiredNoAxes, proshade_double axErr, proshade_unsign noMatchesG1, proshade_double angle1, proshade_unsign noMatchesG2, proshade_double angle2, proshade_unsign noMatchesG3, proshade_double angle3, proshade_unsign fold,
ProSHADE_internal_data::ProSHADE_data* dataObj )
2610 bool atLeastOne =
false;
2611 std::vector< proshade_double* > prosp;
2612 std::vector< proshade_double > sol;
2615 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
2618 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
2621 CSymList->at(possibilities->at(prIt))[1],
2622 CSymList->at(possibilities->at(prIt))[2],
2623 CSymList->at(possibilities->at(prIt))[3],
2624 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
2628 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
2630 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
2633 if ( rgIt1 == rgIt2 ) {
continue; }
2635 for ( proshade_unsign rgIt3 = 0; rgIt3 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt3++ )
2638 if ( ( rgIt1 == rgIt3 ) || ( rgIt2 == rgIt3 ) ) {
continue; }
2642 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
2643 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], angle1, angle2, angle3 );
2646 ProSHADE_internal_symmetry::checkFittingAxisTripleAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, noMatchesG3, angle3, dataObj );
2647 if ( prosp.size() == requiredNoAxes ) {
break; }
2651 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
2652 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], -angle1, -angle2, -angle3 );
2655 ProSHADE_internal_symmetry::checkFittingAxisTripleAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, noMatchesG3, angle3, dataObj );
2656 if ( prosp.size() == requiredNoAxes ) {
break; }
2659 if ( prosp.size() == requiredNoAxes ) {
break; }
2662 if ( prosp.size() == requiredNoAxes ) {
break; }
2666 if ( prosp.size() == requiredNoAxes )
2669 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
2680 return ( atLeastOne );
2685 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
2687 delete[] prosp.at(axIt);
2692 return ( atLeastOne );
2718 void ProSHADE_internal_symmetry::checkFittingAxisTripleAndSave ( std::vector< proshade_unsign >* retGroup, std::vector< proshade_double* >* ret, proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, std::vector< proshade_double* >* prosp, proshade_double axErr, proshade_unsign noMatchesG1, proshade_double angle1, proshade_unsign noMatchesG2, proshade_double angle2, proshade_unsign noMatchesG3, proshade_double angle3,
ProSHADE_internal_data::ProSHADE_data* dataObj )
2721 proshade_unsign noG1 = 0;
2722 proshade_unsign noG2 = 0;
2723 proshade_unsign noG3 = 0;
2724 proshade_double dotProd = 0.0;
2725 proshade_double axHeight = 0.0;
2728 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
2731 &ret->at(retGroup->at(rIt))[2],
2732 &ret->at(retGroup->at(rIt))[3],
2735 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
2736 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
2737 if ( ( std::abs ( dotProd ) > ( angle3 - axErr ) ) && ( std::abs ( dotProd ) < ( angle3 + axErr ) ) ) { noG3 += 1;
continue; }
2741 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) && ( noG3 == noMatchesG3 ) )
2747 if ( axHeight > 0.1 )
2774 std::vector< proshade_double* > ret, tmpHolder;
2775 std::vector< proshade_unsign > testedFolds;
2776 proshade_double symThres;
2777 proshade_unsign foldToTest;
2778 bool foldDone, anyNewSyms =
true;
2781 for ( proshade_unsign prIt = 0; prIt < static_cast< proshade_unsign > ( primes.size() ); prIt++ )
2784 std::stringstream hlpSS;
2785 hlpSS <<
"Searching for prime fold symmetry C" << primes.at(prIt) <<
".";
2789 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, primes.at(prIt), &symThres );
2792 for (
size_t axIt = 0; axIt < prSyms.size(); axIt++ )
2795 if ( prSyms.at(axIt)[5] >= symThres )
2805 delete[] prSyms.at(axIt);
2810 if ( ret.size() < 1 ) {
return ( ret ); }
2813 while ( anyNewSyms )
2819 for ( proshade_unsign axIt1 = 0; axIt1 < static_cast< proshade_unsign > ( ret.size() ); axIt1++ )
2821 for ( proshade_unsign axIt2 = 0; axIt2 < static_cast< proshade_unsign > ( ret.size() ); axIt2++ )
2824 foldToTest =
static_cast< proshade_unsign
> ( ret.at(axIt1)[0] * ret.at(axIt2)[0] );
2829 for ( proshade_unsign fIt = 0; fIt < static_cast< proshade_unsign > ( testedFolds.size() ); fIt++ ) {
if ( testedFolds.at(fIt) == foldToTest ) { foldDone =
true;
break; } }
2830 if ( foldDone ) {
continue; }
2834 std::stringstream hlpSS2;
2835 hlpSS2 <<
"Searching for fold combination of detected folds " << ret.at(axIt1)[0] <<
" and " << ret.at(axIt2)[0] <<
", i.e. C" << foldToTest <<
".";
2839 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, foldToTest, &symThres );
2842 for (
size_t newAxIt = 0; newAxIt < prSyms.size(); newAxIt++ )
2844 if ( prSyms.at(newAxIt)[5] >= symThres )
2854 delete[] prSyms.at(newAxIt);
2860 if ( tmpHolder.size() > 0 )
2862 for ( proshade_unsign tmpIt = 0; tmpIt < static_cast< proshade_unsign > ( tmpHolder.size() ); tmpIt++ )
2865 delete[] tmpHolder.at(tmpIt);
2869 tmpHolder.clear ( );
2889 return ( a[5] > b[5] );
2912 proshade_double soughtAngle;
2913 std::vector< proshade_double > allPeakHeights;
2914 std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup* > peakGroups;
2915 std::vector< proshade_double* > ret;
2919 this->sphereMappedRotFun.clear();
2922 for ( proshade_double angIt = 1.0; angIt < static_cast < proshade_double > ( fold ); angIt += 1.0 )
2925 soughtAngle = angIt * ( 2.0 * M_PI /
static_cast<proshade_double
> ( fold ) );
2929 M_PI /
static_cast < proshade_double
> ( this->maxShellBand ),
2930 this->maxShellBand * 2,
2932 static_cast < proshade_unsign
> ( angIt - 1.0 ) ) );
2935 this->sphereMappedRotFun.at(
static_cast < size_t > ( angIt - 1.0 ))->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
2938 this->sphereMappedRotFun.at(
static_cast < size_t > ( angIt - 1.0 ))->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
2942 std::stringstream hlpSS;
2943 hlpSS <<
"Found a total of " << std::pow (
static_cast< proshade_double
> ( this->maxShellBand ) * 2.0 * (
static_cast< proshade_double
> ( fold ) - 1.0 ), 2.0 ) -
static_cast< proshade_double
> ( allPeakHeights.size() ) <<
" non-peaks for thresholding.";
2950 std::stringstream hlpSS2;
2951 hlpSS2 <<
"Determined peak threshold " << *peakThres <<
".";
2955 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
2957 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( *peakThres );
2961 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); sphIt++ )
2964 for ( proshade_unsign pkIt = 0; pkIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().size() ); pkIt++ )
2968 for ( proshade_unsign pkGrpIt = 0; pkGrpIt < static_cast<proshade_unsign> ( peakGroups.size() ); pkGrpIt++ )
2970 if ( peakGroups.at(pkGrpIt)->checkIfPeakBelongs (
static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).first ),
2971 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
2976 if ( !newPeak ) {
continue; }
2980 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
2982 this->sphereMappedRotFun.at(sphIt)->getAngularDim() ) );
2987 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( peakGroups.size() ); grIt++ )
2990 std::stringstream hlpSS3;
2991 hlpSS3 <<
"Now considering group with LAT " << peakGroups.at(grIt)->getLatFromIndices() <<
" - " << peakGroups.at(grIt)->getLatToIndices() <<
" and LON " << peakGroups.at(grIt)->getLonFromIndices() <<
" - " << peakGroups.at(grIt)->getLonToIndices() <<
" spanning spheres ";
2992 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( peakGroups.at(grIt)->getSpherePositions().size() ); sphIt++ ) { hlpSS3 << peakGroups.at(grIt)->getSpherePositions().at(sphIt) <<
" ; "; }
2999 delete peakGroups.at(grIt);
3025 std::vector < proshade_unsign > folds;
3026 std::vector < proshade_double > angs, applicableAngs;
3027 bool alreadyFound =
false;
3028 size_t corAngIt = 0;
3029 proshade_double lat = 0.0, lon = 0.0, radRange = 0.0, searchRangeInDeg = 0.0, axSum = 0.0, curSum = 0.0, maxSum = 0.0, bestXRot = 0.0, bestYRot = 0.0, bestZRot = 0.0, finXRotChan = 0.0, finYRotChan = 0.0, finZRotChan = 0.0;
3030 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3031 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3034 for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( ret->size() ); iter++ )
3036 alreadyFound =
false;
3037 for ( proshade_unsign it = 0; it < static_cast < proshade_unsign > ( folds.size() ); it++ ) {
const FloatingPoint< proshade_double > lhs1 (
static_cast< proshade_double
> ( folds.at(it) ) ), rhs1 ( ret->at(iter)[0] );
if ( lhs1.AlmostEquals ( rhs1 ) ) { alreadyFound =
true;
break; } }
3043 for ( proshade_unsign foldIt = 0; foldIt < static_cast < proshade_unsign > ( folds.size() ); foldIt++ ) {
for ( proshade_double angIt = 1.0; angIt < static_cast<proshade_double> ( folds.at(foldIt) ); angIt += 1.0 ) {
ProSHADE_internal_misc::addToDoubleVector ( &angs, angIt * ( 2.0 * M_PI /
static_cast<proshade_double
> ( folds.at(foldIt) ) ) ); } }
3044 std::sort ( angs.begin(), angs.end() );
3047 for (
int angIt =
static_cast< int > ( angs.size() - 2 ); angIt >= 0; angIt-- ) {
const FloatingPoint< proshade_double > lhs1 ( angs.at(
static_cast< size_t > ( angIt ) ) ), rhs1 ( angs.at(
static_cast< size_t > ( angIt + 1 ) ) );
if ( lhs1.AlmostEquals ( rhs1 ) ) { angs.erase ( angs.begin() + (angIt+1) ); } }
3050 dataObj->sphereMappedRotFun.clear();
3051 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3054 if ( ( angIt == 0 ) && ( angs.size() > 1 ) ) { radRange = ( angs.at(1) - angs.at(0) ) / 2; }
3055 else {
if ( ( angIt == ( angs.size() - 1 ) ) && ( angs.size() > 1 ) ) { radRange = ( angs.at(angIt) - angs.at(angIt-1) ) / 2; }
3056 else {
if ( angs.size() > 2 ) { radRange = std::min ( ( angs.at(angIt) - angs.at(angIt-1) ) / 2, ( angs.at(angIt+1) - angs.at(angIt) ) / 2 ); }
3057 else { radRange = 0.5; } } }
3064 static_cast<proshade_unsign
> ( angIt ) ) );
3067 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
3071 searchRangeInDeg = 360.0 / ( dataObj->
getMaxBand() * 2.0 );
3072 proshade_double* rotMat, *newAxis;
3073 while ( searchRangeInDeg > 0.09 )
3076 for ( proshade_double xChan = -searchRangeInDeg; xChan < ( 1.5 * searchRangeInDeg ); xChan += searchRangeInDeg )
3078 for ( proshade_double yChan = -searchRangeInDeg; yChan < ( 1.5 * searchRangeInDeg ); yChan += searchRangeInDeg )
3080 for ( proshade_double zChan = -searchRangeInDeg; zChan < ( 1.5 * searchRangeInDeg ); zChan += searchRangeInDeg )
3089 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3095 lat = ( std::atan2( newAxis[1], newAxis[0] ) / latSamlUnit );
3096 lon = ( std::acos ( newAxis[2] ) / lonSamlUnit );
3098 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3099 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3102 applicableAngs.clear ( );
3107 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3110 alreadyFound =
false;
3111 for (
size_t aIt = 0; aIt < applicableAngs.size(); aIt++ ) {
if ( alreadyFound ) {
break; }
const FloatingPoint< proshade_double > lhs1 ( angs.at(angIt) ), rhs1 ( applicableAngs.at(aIt) );
if ( lhs1.AlmostEquals ( rhs1 ) ) { alreadyFound =
true; corAngIt = angIt; } }
3113 if ( !alreadyFound ) {
continue; }
3116 axSum += dataObj->sphereMappedRotFun.at(corAngIt)->getSphereLatLonLinearInterpolationPos ( lat, lon );
3120 axSum /= ret->at(axIt)[0];
3128 curSum /=
static_cast< proshade_double
> ( ret->size() );
3131 if ( curSum > maxSum )
3148 searchRangeInDeg /= 2.0;
3149 finXRotChan += bestXRot;
3150 finYRotChan += bestYRot;
3151 finZRotChan += bestZRot;
3159 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3165 ret->at(axIt)[1] = newAxis[0];
3166 ret->at(axIt)[2] = newAxis[1];
3167 ret->at(axIt)[3] = newAxis[2];
3174 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3177 lat = std::atan2( ret->at(axIt)[2], ret->at(axIt)[1] ) / latSamlUnit;
3178 lon = std::acos ( ret->at(axIt)[3] ) / lonSamlUnit;
3180 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3181 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3184 applicableAngs.clear ( );
3188 ret->at(axIt)[5] = 0.0;
3189 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3192 alreadyFound =
false;
3193 for (
size_t aIt = 0; aIt < applicableAngs.size(); aIt++ ) {
if ( alreadyFound ) {
break; }
const FloatingPoint< proshade_double > lhs1 ( angs.at(angIt) ), rhs1 ( applicableAngs.at(aIt) );
if ( lhs1.AlmostEquals ( rhs1 ) ) { alreadyFound =
true; corAngIt = angIt; } }
3195 if ( !alreadyFound ) {
continue; }
3198 ret->at(axIt)[5] += dataObj->sphereMappedRotFun.at(corAngIt)->getSphereLatLonLinearInterpolationPos ( lat, lon );
3202 ret->at(axIt)[5] /= ( ret->at(axIt)[0] - 1.0 );
3203 maxSum += ret->at(axIt)[5];
3230 if ( ret->size() != 2 )
3232 throw ProSHADE_exception (
"Attempted to optimise less than two axes for dihedral\n : group.",
"ES00070", __FILE__, __LINE__, __func__,
"The function for optimisation of dihedral angle of D\n : group was called on group with less than two axes. This\n : seems like a programming bug and should not happen - \n : contact author if you ever see this." );
3236 proshade_double *crossProd, *perpVec, normFactor;
3237 size_t higherRFIndex = 0;
3243 if ( ret->at(1).at(5) > ret->at(0).at(5) ) { higherRFIndex = 1; }
3247 normFactor = std::sqrt ( pow ( perpVec[0], 2.0 ) + pow ( perpVec[1], 2.0 ) + pow ( perpVec[2], 2.0 ) );
3248 perpVec[0] /= normFactor; perpVec[1] /= normFactor; perpVec[2] /= normFactor;
3251 if ( higherRFIndex == 0 ) { higherRFIndex = 1; }
3252 else { higherRFIndex = 0; }
3255 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( perpVec[0] ), std::max( std::abs ( perpVec[1] ), std::abs ( perpVec[2] ) ) ) );
3256 const FloatingPoint< proshade_double > rhs1 ( std::abs ( perpVec[0] ));
3257 const FloatingPoint< proshade_double > rhs2 ( std::abs ( perpVec[1] ) );
3258 const FloatingPoint< proshade_double > rhs3 ( std::abs ( perpVec[2] ) );
3259 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( perpVec[0] < 0.0 ) ) ||
3260 ( lhs1.AlmostEquals ( rhs2 ) && ( perpVec[1] < 0.0 ) ) ||
3261 ( lhs1.AlmostEquals ( rhs3 ) && ( perpVec[2] < 0.0 ) ) )
3269 ret->at(higherRFIndex).at(1) = perpVec[0]; ret->at(higherRFIndex).at(2) = perpVec[1]; ret->at(higherRFIndex).at(3) = perpVec[2];
3276 std::vector< proshade_double* > convVec;
3277 for (
size_t axIt = 0; axIt < 2; axIt++ )
3280 proshade_double* axVals =
new proshade_double[7];
3284 for (
size_t elIt = 0; elIt < 7; elIt++ )
3286 axVals[elIt] = ret->at(axIt).at(elIt);
3290 convVec.push_back ( axVals );
3297 for (
size_t axIt = 0; axIt < 2; axIt++ )
3300 for (
size_t elIt = 0; elIt < 7; elIt++ )
3302 ret->at(axIt).at(elIt) = convVec.at(axIt)[elIt];
3306 delete[] convVec.at(axIt);
3327 std::vector < std::vector< proshade_double > > ortPair;
3328 std::vector< proshade_double > hlpVec;
3331 hlpVec.push_back ( allCs->at(selection.at(0))[0] ); hlpVec.push_back ( allCs->at(selection.at(0))[1] ); hlpVec.push_back ( allCs->at(selection.at(0))[2] );
3332 hlpVec.push_back ( allCs->at(selection.at(0))[3] ); hlpVec.push_back ( allCs->at(selection.at(0))[4] ); hlpVec.push_back ( allCs->at(selection.at(0))[5] );
3333 hlpVec.push_back ( allCs->at(selection.at(0))[6] );
3334 ortPair.push_back ( hlpVec ); hlpVec.clear ( );
3335 hlpVec.push_back ( allCs->at(selection.at(1))[0] ); hlpVec.push_back ( allCs->at(selection.at(1))[1] ); hlpVec.push_back ( allCs->at(selection.at(1))[2] );
3336 hlpVec.push_back ( allCs->at(selection.at(1))[3] ); hlpVec.push_back ( allCs->at(selection.at(1))[4] ); hlpVec.push_back ( allCs->at(selection.at(1))[5] );
3337 hlpVec.push_back ( allCs->at(selection.at(1))[6] );
3338 ortPair.push_back ( hlpVec );
3344 allCs->at(selection.at(0))[1] = ortPair.at(0).at(1); allCs->at(selection.at(0))[2] = ortPair.at(0).at(2); allCs->at(selection.at(0))[3] = ortPair.at(0).at(3);
3345 allCs->at(selection.at(0))[5] = ortPair.at(0).at(5); allCs->at(selection.at(0))[6] = ortPair.at(0).at(6);
3347 allCs->at(selection.at(1))[1] = ortPair.at(1).at(1); allCs->at(selection.at(1))[2] = ortPair.at(1).at(2); allCs->at(selection.at(1))[3] = ortPair.at(1).at(3);
3348 allCs->at(selection.at(1))[5] = ortPair.at(1).at(5); allCs->at(selection.at(1))[6] = ortPair.at(1).at(6);
3370 proshade_double height = 0.0;
3371 proshade_double lat, lon;
3372 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3373 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3376 dataObj->sphereMappedRotFun.clear ( );
3379 for ( proshade_double angIt = 1.0; angIt < fold; angIt += 1.0 )
3385 angIt * ( 2.0 * M_PI / fold ),
3386 static_cast<proshade_unsign
> ( angIt - 1.0 ) ) );
3389 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt - 1.0 ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
3393 lat = std::atan2( axis[1], axis[0] ) / latSamlUnit;
3394 lon = std::acos ( axis[2] ) / lonSamlUnit;
3396 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3397 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3399 lat = std::round ( lat );
3400 lon = std::round ( lon );
3406 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( dataObj->sphereMappedRotFun.size() ); sphIt++ )
3421 std::vector < proshade_double* > detectedAxis;
3425 if ( detectedAxis.size() > 0 ) { height = detectedAxis.at(0)[5]; }
3426 else { height = 0.0; }
3429 for ( proshade_unsign i = 0; i < static_cast < proshade_unsign > ( detectedAxis.size() ); i++ ) {
delete detectedAxis.at(i); }
3444 std::pair< proshade_unsign, proshade_unsign >
findBestTetraDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
3447 std::pair< proshade_unsign, proshade_unsign > ret;
3448 std::vector< proshade_unsign > C3List;
3449 proshade_double bestHeightSum = 0.0;
3450 proshade_double dotProduct;
3453 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ ) {
const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
if ( lhs1.AlmostEquals ( rhs1 ) && CSymList->at(cSym)[5] >= minPeakHeight ) {
ProSHADE_internal_misc::addToUnsignVector ( &C3List, cSym ); } }
3456 for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
3458 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3461 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 2.0 );
3462 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
3463 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
3467 &CSymList->at(C3List.at(c3))[2],
3468 &CSymList->at(C3List.at(c3))[3],
3469 &CSymList->at(cSym)[1],
3470 &CSymList->at(cSym)[2],
3471 &CSymList->at(cSym)[3] );
3474 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3476 if ( bestHeightSum < ( CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5] ) )
3478 bestHeightSum = CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5];
3479 ret.first = C3List.at(c3);
3508 std::vector< proshade_double* > ret;
3523 for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ret.size() ); retIt++ )
3570 CSymList->at(initAxes.first)[1],
3571 CSymList->at(initAxes.first)[2],
3572 CSymList->at(initAxes.first)[3] );
3581 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
3582 proshade_double* rotMatHlp =
new proshade_double[9];
3584 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
3596 curAngDist = std::sqrt ( std::pow ( rotRotModelC2[0] - CSymList->at(initAxes.second)[1], 2.0 ) +
3597 std::pow ( rotRotModelC2[1] - CSymList->at(initAxes.second)[2], 2.0 ) +
3598 std::pow ( rotRotModelC2[2] - CSymList->at(initAxes.second)[3], 2.0 ) );
3601 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
3604 delete[] rotRotModelC2;
3611 proshade_double* rotMat2 =
new proshade_double[9];
3619 for ( proshade_unsign iter = 0; iter < tetAx->
getNoAxes( ); iter++ )
3628 proshade_double* axis =
new proshade_double[7];
3631 axis[0] = tetAx->
getValue ( iter, 0 );
3632 axis[1] = rotAxis[0];
3633 axis[2] = rotAxis[1];
3634 axis[3] = rotAxis[2];
3635 axis[4] = ( 2.0 * M_PI ) / axis[0];
3637 axis[6] = -std::numeric_limits < proshade_double >::infinity();
3650 delete[] rotModelC2;
3680 std::vector< proshade_unsign > ret;
3685 if ( bestHistPeakStart > 0.9 ) { bestHistPeakStart = 0.9; }
3688 proshade_double dotProduct, maxOrtSum = 0.0, curOrtSum = 0.0;
3689 proshade_unsign maxOrtAx1 = 0, maxOrtAx2 = 0;
3690 for (
size_t relAx1 = 0; relAx1 < allCs->size(); relAx1++ )
3693 if ( allCs->at(relAx1)[5] < bestHistPeakStart ) {
continue; }
3694 if ( allCs->at(relAx1)[6] < bestFSCPeakStart ) {
continue; }
3696 for (
size_t relAx2 = 1; relAx2 < allCs->size(); relAx2++ )
3699 if ( relAx1 >= relAx2 ) {
continue; }
3702 if ( allCs->at(relAx2)[5] < bestHistPeakStart ) {
continue; }
3703 if ( allCs->at(relAx2)[6] < bestFSCPeakStart ) {
continue; }
3707 &allCs->at(relAx1)[3], &allCs->at(relAx2)[1],
3708 &allCs->at(relAx2)[2], &allCs->at(relAx2)[3] );
3711 if ( std::abs( dotProduct ) < tolerance )
3714 curOrtSum = allCs->at(relAx1)[5] + allCs->at(relAx1)[6] + allCs->at(relAx2)[5] + allCs->at(relAx2)[6];
3717 if ( curOrtSum > maxOrtSum )
3719 maxOrtSum = curOrtSum;
3720 maxOrtAx1 =
static_cast< proshade_unsign
> ( relAx1 );
3721 maxOrtAx2 =
static_cast< proshade_unsign
> ( relAx2 );
3728 if ( maxOrtAx2 != 0 )
3737 curOrtSum = 0.0; maxOrtSum = 0.0;
3738 for (
size_t relAx1 = 0; relAx1 < allCs->size(); relAx1++ )
3741 if ( allCs->at(relAx1)[5] < bestHistPeakStart ) {
continue; }
3744 if ( allCs->at(relAx1)[6] < 0.3 ) {
continue; }
3747 curOrtSum = allCs->at(relAx1)[5] + allCs->at(relAx1)[6];
3750 if ( curOrtSum > maxOrtSum )
3752 maxOrtSum = curOrtSum;
3753 maxOrtAx1 =
static_cast< proshade_unsign
> ( relAx1 );
3758 if ( maxOrtSum > 0.1 )
3791 void ProSHADE_internal_symmetry::allocateCentreOfMapFourierTransforms ( proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, fftw_complex *&origMap, fftw_complex *&origCoeffs, fftw_complex *&rotMapComplex, fftw_complex *&rotCoeffs, fftw_complex *&trFunc, fftw_complex *&trFuncCoeffs, fftw_plan *planForwardFourier, fftw_plan *planForwardFourierRot, fftw_plan *planReverseFourierComb )
3794 origMap =
new fftw_complex [xDim * yDim * zDim];
3795 origCoeffs =
new fftw_complex [xDim * yDim * zDim];
3796 rotMapComplex =
new fftw_complex [xDim * yDim * zDim];
3797 rotCoeffs =
new fftw_complex [xDim * yDim * zDim];
3798 trFunc =
new fftw_complex [xDim * yDim * zDim];
3799 trFuncCoeffs =
new fftw_complex [xDim * yDim * zDim];
3810 *planForwardFourier = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), origMap, origCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3811 *planForwardFourierRot = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), rotMapComplex, rotCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3812 *planReverseFourierComb = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), trFuncCoeffs, trFunc, FFTW_BACKWARD, FFTW_ESTIMATE );
3834 fftw_destroy_plan ( planReverseFourierComb );
3835 fftw_destroy_plan ( planForwardFourier );
3836 fftw_destroy_plan ( planForwardFourierRot );
3839 planReverseFourierComb =
nullptr;
3840 planForwardFourier =
nullptr;
3841 planForwardFourierRot =
nullptr;
3845 delete[] origCoeffs;
3846 delete[] rotMapComplex;
3849 delete[] trFuncCoeffs;
3872 proshade_double axX, axY, axZ, axAng, mapPeak, trsX, trsY, trsZ;
3873 std::vector< proshade_double > trsVec;
3876 proshade_double *rotMap;
3881 for (
size_t it = 0; it < static_cast< size_t > ( symStr->
getXDim() * symStr->
getYDim() * symStr->
getZDim() ); it++ ) { rotMapComplex[it][0] = rotMap[it]; rotMapComplex[it][1] = 0.0; }
3882 fftw_execute ( planForwardFourierRot );
3888 fftw_execute ( planReverseFourierComb );
3895 trsX *=
static_cast< proshade_double
> ( symStr->
getXDimSize() / symStr->
getXDim() );
3896 trsY *=
static_cast< proshade_double
> ( symStr->
getYDimSize() / symStr->
getYDim() );
3897 trsZ *=
static_cast< proshade_double
> ( symStr->
getZDimSize() / symStr->
getZDim() );
3900 if ( trsX > (
static_cast< proshade_double
> ( symStr->
getXDimSize() ) / 2.0 ) ) { trsX = trsX -
static_cast< proshade_double
> ( symStr->
getXDimSize() ); }
3901 if ( trsY > (
static_cast< proshade_double
> ( symStr->
getYDimSize() ) / 2.0 ) ) { trsY = trsY -
static_cast< proshade_double
> ( symStr->
getYDimSize() ); }
3902 if ( trsZ > (
static_cast< proshade_double
> ( symStr->
getZDimSize() ) / 2.0 ) ) { trsZ = trsZ -
static_cast< proshade_double
> ( symStr->
getZDimSize() ); }
3938 std::vector< proshade_double > pointOnLine ( 3, 0.0 );
3939 std::vector< proshade_double > identityMat ( 9, 0.0 ); identityMat.at(0) = 1.0; identityMat.at(4) = 1.0; identityMat.at(8) = 1.0;
3942 for (
size_t gEl = 0; gEl < symElems.size(); gEl++ )
3950 origCoeffs, rotMapComplex,
3951 rotCoeffs, planForwardFourierRot,
3952 trFuncCoeffs, trFunc,
3953 planReverseFourierComb );
3956 pointOnLine.at(0) += trsCenHlp.at(0);
3957 pointOnLine.at(1) += trsCenHlp.at(1);
3958 pointOnLine.at(2) += trsCenHlp.at(2);
3962 pointOnLine.at(0) /=
static_cast< proshade_double
> ( symElems.size() );
3963 pointOnLine.at(1) /=
static_cast< proshade_double
> ( symElems.size() );
3964 pointOnLine.at(2) /=
static_cast< proshade_double
> ( symElems.size() );
3967 return ( pointOnLine );