26 proshade_double
determinePeakThreshold ( std::vector < proshade_double > inArr, proshade_double noIQRsFromMedian, proshade_double startMinVal );
28 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestIcosDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
29 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestOctaDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
30 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestTetraDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr );
73 proshade_double
determinePeakThreshold ( std::vector < proshade_double > inArr, proshade_double noIQRsFromMedian, proshade_double startMinVal )
76 proshade_double ret = 0.0;
77 proshade_double rmsd = 0.0;
78 size_t vecSize = inArr.size();
79 proshade_unsign noVals = 0;
80 proshade_double mean = 0.0;
83 if ( vecSize == 0 ) {
return ( ret ); }
84 if ( vecSize <= 4 ) { ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) /
static_cast< proshade_double
> ( vecSize );
return ( ret ); }
90 mean = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) /
static_cast< proshade_double
> ( vecSize );
93 for (
size_t i = 0; i < vecSize; i++ )
95 rmsd += std::pow ( ret - inArr.at(i), 2.0 );
97 rmsd = std::sqrt ( rmsd );
100 ret = std::min ( mean + ( noIQRsFromMedian * rmsd ), startMinVal );
101 for (
size_t iter = 0; iter < inArr.size(); iter++ ) {
if ( inArr.at(iter) > ret ) { noVals += 1; } }
102 while ( noVals > 1000)
106 for (
size_t iter = 0; iter < inArr.size(); iter++ ) {
if ( inArr.at(iter) > ret ) { noVals += 1; } }
108 if ( noVals == 0 ) { ret -= 0.01; }
112 if ( ret > *( std::max_element ( inArr.begin(), inArr.end() ) ) )
114 ret = *( std::max_element ( inArr.begin(), inArr.end() ) );
117 if ( ret > 0.85 ) { ret = 0.85; }
141 proshade_double shellSpacing = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( this->getMaxBand ( ) ) * 2.0;
142 std::vector< proshade_double > allPeakHeights;
145 for ( proshade_unsign spIt = 1; spIt < ( this->getMaxBand ( ) * 2 ); spIt++ )
149 this->getMaxBand ( ) * 2,
150 this->getEMatDim ( ) * 2,
151 static_cast<proshade_double
> ( spIt ) * shellSpacing,
156 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereMappedRotFun.size() ); shIt++ )
159 std::stringstream hlpSS;
160 hlpSS <<
"Interpolating sphere " << shIt <<
" ( radius: " << this->sphereMappedRotFun.at(shIt)->getRadius() <<
" ).";
164 this->sphereMappedRotFun.at(shIt)->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
172 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
174 this->sphereMappedRotFun.at(shIt)->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
178 std::stringstream hlpSS;
179 hlpSS <<
"Detected " << allPeakHeights.size() <<
" peaks with any height.";
186 std::stringstream hlpSS2;
187 hlpSS2 <<
"From these peaks, decided the threshold will be " << peakThres <<
" peak height.";
191 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
193 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( peakThres );
218 proshade_double dotProduct = 0.0;
222 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
225 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
226 if ( lhs.AlmostEquals ( rhs ) )
230 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
231 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
234 *matchedPos =
static_cast< proshade_signed
> ( symIt );
237 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
240 ret->at(symIt)[1] = sym[1];
241 ret->at(symIt)[2] = sym[2];
242 ret->at(symIt)[3] = sym[3];
243 ret->at(symIt)[5] = sym[5];
269 proshade_double dotProduct = 0.0;
273 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
276 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
277 if ( lhs.AlmostEquals ( rhs ) )
281 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
282 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
285 *matchedPos =
static_cast< proshade_signed
> ( symIt );
288 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
291 ret->at(symIt)[1] = sym[1];
292 ret->at(symIt)[2] = sym[2];
293 ret->at(symIt)[3] = sym[3];
294 ret->at(symIt)[5] = sym[5];
295 ret->at(symIt)[6] = fscVal;
320 proshade_double dotProduct;
326 if ( CSymList->size() < 2 ) { return ; }
329 for ( proshade_unsign ax1 = 0; ax1 < static_cast<proshade_unsign> ( CSymList->size() ); ax1++ )
332 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(ax1)[5] ), rhs1 ( -999.9 );
333 if ( ( CSymList->at(ax1)[5] < settings->
minSymPeak ) && !( lhs1.AlmostEquals ( rhs1 ) ) ) {
continue; }
335 for ( proshade_unsign ax2 = 1; ax2 < static_cast<proshade_unsign> ( CSymList->size() ); ax2++ )
338 if ( ax1 >= ax2 ) {
continue; }
341 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(ax2)[5] ), rhs2 ( -999.9 );
342 if ( ( CSymList->at(ax2)[5] < settings->
minSymPeak ) && !( lhs2.AlmostEquals ( rhs2 ) ) ) {
continue; }
346 &CSymList->at(ax1)[3], &CSymList->at(ax2)[1],
347 &CSymList->at(ax2)[2], &CSymList->at(ax2)[3] );
353 if ( CSymList->at(ax1)[0] >= CSymList->at(ax2)[0] )
355 std::vector< proshade_double* > hlpVec;
357 proshade_double* hlpSym =
new proshade_double[7];
359 for (
size_t iter = 0; iter < 7; iter++ ) { hlpSym[iter] = CSymList->at(ax1)[iter]; }
362 proshade_double* hlpSym2 =
new proshade_double[7];
364 for (
size_t iter = 0; iter < 7; iter++ ) { hlpSym2[iter] = CSymList->at(ax2)[iter]; }
371 std::vector< proshade_double* > hlpVec;
373 proshade_double* hlpSym =
new proshade_double[7];
375 for (
size_t iter = 0; iter < 7; iter++ ) { hlpSym[iter] = CSymList->at(ax2)[iter]; }
378 proshade_double* hlpSym2 =
new proshade_double[7];
380 for (
size_t iter = 0; iter < 7; iter++ ) { hlpSym2[iter] = CSymList->at(ax1)[iter]; }
390 std::stringstream hlpSS;
391 hlpSS <<
"Detected " << this->dihedralSymmetries.size() <<
" D symmetries.";
413 std::vector< proshade_unsign > C3List;
414 proshade_double dotProduct;
417 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
419 const FloatingPoint< proshade_double > lhs ( CSymList->at(cSym)[0] ), rhs ( 3.0 );
424 for ( proshade_unsign c31 = 0; c31 < static_cast<proshade_unsign> ( C3List.size() ); c31++ )
426 for ( proshade_unsign c32 = 1; c32 < static_cast<proshade_unsign> ( C3List.size() ); c32++ )
429 if ( c31 >= c32 ) {
continue; }
432 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] );
435 if ( ( ( 1.0 / 3.0 ) > ( dotProduct - axErr ) ) && ( ( 1.0 / 3.0 ) < ( dotProduct + axErr ) ) )
464 std::vector< proshade_unsign > C3PossibilitiesHlp;
465 std::vector< std::vector< proshade_unsign > > C3Possibilities;
472 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
475 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
481 groupMatched =
false;
482 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
495 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
496 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; } } }
498 if ( C3Possibilities.at(maxGrp).size() == 4 )
501 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)) ); }
534 bool allAnglesMet =
true;
535 proshade_double dotProduct;
540 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
544 if ( ( ( 1.0 > ( dotProduct - axErr ) ) && ( 1.0 < ( dotProduct + axErr ) ) ) || ( ( -1.0 > ( dotProduct - axErr ) ) && ( -1.0 < ( dotProduct + axErr ) ) ) )
546 if ( sym[5] > CSymList->at(grp->at(mIt))[5] )
552 allAnglesMet =
false;
553 return ( allAnglesMet );
560 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
564 if ( ( angle > ( std::abs ( dotProduct ) - axErr ) ) &&
565 ( angle < ( std::abs ( dotProduct ) + axErr ) ) )
572 allAnglesMet =
false;
578 return ( allAnglesMet );
601 std::vector< proshade_double* > hlpVec;
602 bool atLeastOne =
false;
605 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
607 if (
static_cast<proshade_unsign
> ( possibilities->at(gIt).size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
611 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
614 if ( possibilities->at(gIt).size() < 2 ) {
continue; }
623 if ( hlpVec.size() > 0 )
629 for ( proshade_unsign axIt = 0; axIt < static_cast<proshade_unsign> ( hlpVec.size() ); axIt++ )
644 if ( possibilities->at(gIt).size() == requiredNoAxes ) { atLeastOne =
true; }
648 return ( atLeastOne );
661 return ( a[0] < b[0] );
682 proshade_double ret = 0.0;
683 proshade_double curSum = 0.0;
684 proshade_double maxVal = 0.0;
685 proshade_double angStep = std::acos ( 1.0 - axErr ) / 2;
686 std::vector< proshade_double* > angVec;
695 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( std::floor ( ( 2.0 * M_PI / angStep ) /
static_cast< proshade_double
> ( fold ) ) ); iter++ )
701 for ( proshade_unsign angCmb = 0; angCmb < static_cast<proshade_unsign> ( fold ); angCmb++ )
707 for ( proshade_unsign angIt = 0; angIt < static_cast<proshade_unsign> ( angVec.size() ); angIt++ )
709 if ( angVec.at(angIt)[0] < ( (
static_cast< proshade_double
> ( iter ) * angStep ) +
710 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
continue; }
711 if ( angVec.at(angIt)[0] > ( ( (
static_cast< proshade_double
> ( iter ) + 1.0 ) * angStep ) +
712 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
break; }
714 if ( angVec.at(angIt)[1] > maxVal ) { maxVal = angVec.at(angIt)[1]; }
718 curSum /=
static_cast<proshade_double
> ( fold );
719 if ( ret < curSum ) { ret = curSum; }
723 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( angVec.size() ); iter++ ) {
delete[] angVec.at(iter); }
746 proshade_double euA, euB, euG, xPk, yPk, zPk, anglPk;
747 proshade_double* rotMat =
new proshade_double [9];
749 proshade_unsign arrIndex;
750 std::vector< proshade_double* > angVec;
753 for ( proshade_unsign xIt = 0; xIt < ( dataObj->
getMaxBand ( ) * 2 ); xIt++ )
755 for ( proshade_unsign yIt = 0; yIt < ( dataObj->
getMaxBand ( ) * 2 ); yIt++ )
757 for ( proshade_unsign zIt = 0; zIt < ( dataObj->
getMaxBand ( ) * 2 ); zIt++ )
760 arrIndex = zIt + ( dataObj->
getMaxBand ( ) * 2 ) * ( yIt + ( dataObj->
getMaxBand ( ) * 2 ) * xIt );
764 static_cast< proshade_signed
> ( yIt ),
static_cast< proshade_signed
> ( zIt ),
770 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( xPk ), std::max( std::abs ( yPk ), std::abs ( zPk ) ) ) );
771 const FloatingPoint< proshade_double > rhs1 ( std::abs ( xPk ));
772 const FloatingPoint< proshade_double > rhs2 ( std::abs ( yPk ) );
773 const FloatingPoint< proshade_double > rhs3 ( std::abs ( zPk ) );
774 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( xPk < 0.0 ) ) ||
775 ( lhs1.AlmostEquals ( rhs2 ) && ( yPk < 0.0 ) ) ||
776 ( lhs1.AlmostEquals ( rhs3 ) && ( zPk < 0.0 ) ) )
788 proshade_double* hlpArr =
new proshade_double [2];
790 hlpArr[0] = anglPk + M_PI;
824 proshade_double* hlpSym =
new proshade_double [6];
828 hlpSym[0] =
static_cast<proshade_double
> ( fold );
832 hlpSym[4] = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( fold );
836 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( axVec->size() ); symIt++ )
839 const FloatingPoint< proshade_double > lhs1 ( axVec->at(symIt)[0] ), rhs1 ( hlpSym[0] );
840 if ( lhs1.AlmostEquals ( rhs1 ) )
851 if ( axVec->at(symIt)[5] < hlpSym[5] )
854 delete[] axVec->at(symIt);
855 axVec->at(symIt) = hlpSym;
893 if ( grp->size() < 2 ) {
return; }
896 proshade_double axHeight = 0.0;
897 proshade_double* symHlp =
new proshade_double[7];
901 for ( proshade_unsign fAx = 0; fAx < static_cast<proshade_unsign> ( grp->size() ); fAx++ )
903 for ( proshade_unsign sAx = 1; sAx < static_cast<proshade_unsign> ( grp->size() ); sAx++ )
906 if ( fAx >= sAx ) {
continue; }
910 CSymList->at(grp->at(fAx))[2],
911 CSymList->at(grp->at(fAx))[3],
912 CSymList->at(grp->at(sAx))[1],
913 CSymList->at(grp->at(sAx))[2],
914 CSymList->at(grp->at(sAx))[3], angle, angle );
917 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
918 const FloatingPoint< proshade_double > rhs1 ( std::abs ( solVec.at(0) ) );
919 const FloatingPoint< proshade_double > rhs2 ( std::abs ( solVec.at(1) ) );
920 const FloatingPoint< proshade_double > rhs3 ( std::abs ( solVec.at(2) ) );
921 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( solVec.at(0) < 0.0 ) ) ||
922 ( lhs1.AlmostEquals ( rhs2 ) && ( solVec.at(1) < 0.0 ) ) ||
923 ( lhs1.AlmostEquals ( rhs3 ) && ( solVec.at(2) < 0.0 ) ) )
925 solVec.at(0) *= -1.0;
926 solVec.at(1) *= -1.0;
927 solVec.at(2) *= -1.0;
931 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
943 CSymList->at(grp->at(fAx))[2],
944 CSymList->at(grp->at(fAx))[3],
945 CSymList->at(grp->at(sAx))[1],
946 CSymList->at(grp->at(sAx))[2],
947 CSymList->at(grp->at(sAx))[3], -angle, -angle );
950 const FloatingPoint< proshade_double > lhs2 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
951 const FloatingPoint< proshade_double > rhs4 ( std::abs ( solVec.at(0) ) );
952 const FloatingPoint< proshade_double > rhs5 ( std::abs ( solVec.at(1) ) );
953 const FloatingPoint< proshade_double > rhs6 ( std::abs ( solVec.at(2) ) );
954 if ( ( lhs2.AlmostEquals ( rhs4 ) && ( solVec.at(0) < 0.0 ) ) ||
955 ( lhs2.AlmostEquals ( rhs5 ) && ( solVec.at(1) < 0.0 ) ) ||
956 ( lhs2.AlmostEquals ( rhs6 ) && ( solVec.at(2) < 0.0 ) ) )
958 solVec.at(0) *= -1.0;
959 solVec.at(1) *= -1.0;
960 solVec.at(2) *= -1.0;
964 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
1001 std::vector< proshade_unsign > C3s, prospectiveC2s, C2PossibilitiesHlp;
1002 std::vector< std::vector< proshade_unsign > > C2Possibilities;
1003 proshade_double dotProd;
1011 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
1014 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1017 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
1018 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
1022 &CSymList->at(cIt)[1], &CSymList->at(cIt)[2], &CSymList->at(cIt)[3] );
1029 C2Possibilities.clear(); C2PossibilitiesHlp.clear();
1030 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC2s.size() ); cIt++ )
1033 groupMatched =
false;
1034 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C2Possibilities.size() ); gIt++ )
1044 while ( C2Possibilities.size() != 0 )
1050 if ( C2Possibilities.at(0).size() == 3 )
1061 else { C2Possibilities.erase ( C2Possibilities.begin() ); }
1083 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 )
1087 proshade_double dotProduct;
1090 for ( proshade_unsign g1It = 0; g1It < static_cast<proshade_unsign> ( grp1->size() ); g1It++ )
1092 for ( proshade_unsign g2It = 0; g2It < static_cast<proshade_unsign> ( grp2->size() ); g2It++ )
1096 &GrList1->at(grp1->at(g1It))[2],
1097 &GrList1->at(grp1->at(g1It))[3],
1098 &GrList2->at(grp2->at(g2It))[1],
1099 &GrList2->at(grp2->at(g2It))[2],
1100 &GrList2->at(grp2->at(g2It))[3] );
1103 if ( ( angle > ( dotProduct - axErr ) ) && ( angle < ( dotProduct + axErr ) ) )
1130 std::vector< proshade_unsign > C4List;
1131 proshade_double dotProduct;
1134 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1136 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 4.0 );
1141 for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
1143 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1146 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1147 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
1151 &CSymList->at(C4List.at(c4))[2],
1152 &CSymList->at(C4List.at(c4))[3],
1153 &CSymList->at(cSym)[1],
1154 &CSymList->at(cSym)[2],
1155 &CSymList->at(cSym)[3] );
1158 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( dotProduct - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( dotProduct + axErr ) ) )
1188 std::vector< proshade_unsign > C4PossibilitiesHlp;
1189 std::vector< std::vector< proshade_unsign > > C4Possibilities;
1196 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1199 if ( CSymList->at(cIt)[0] != 4.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
1202 groupMatched =
false;
1203 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C4Possibilities.size() ); gIt++ )
1216 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
1217 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; } } }
1219 if ( C4Possibilities.at(maxGrp).size() == 3 )
1222 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)) ); }
1255 std::vector< proshade_unsign > C4s, prospectiveC3s, C3PossibilitiesHlp;
1256 std::vector< std::vector< proshade_unsign > > C3Possibilities;
1257 proshade_double dotProd;
1265 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
1268 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1271 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
1281 C3Possibilities.clear(); C3PossibilitiesHlp.clear();
1282 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC3s.size() ); cIt++ )
1285 groupMatched =
false;
1286 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
1296 while ( C3Possibilities.size() != 0 )
1302 if ( C3Possibilities.at(0).size() == 4 )
1313 else { C3Possibilities.erase ( C3Possibilities.begin() ); }
1338 std::vector< proshade_unsign > prospectiveC2s, retGrp;
1339 proshade_double dotProd;
1340 proshade_unsign noPerpendicular, noSqrtTwo;
1346 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1349 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
1350 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && ! ( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
1353 noPerpendicular = 0; noSqrtTwo = 0;
1354 for ( proshade_unsign rIt = 0; rIt < 3; rIt++ )
1359 &CSymList->at(cIt)[1],
1360 &CSymList->at(cIt)[2],
1361 &CSymList->at(cIt)[3] );
1363 if ( ( std::abs ( dotProd ) > ( ( 1.0 / sqrt(2.0) ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / sqrt(2.0) ) + axErr ) ) ) { noSqrtTwo += 1;
continue; }
1364 if ( ( std::abs ( dotProd ) > ( 0.0 - axErr ) ) && ( std::abs ( dotProd ) < ( 0.0 + axErr ) ) ) { noPerpendicular += 1;
continue; }
1368 if ( ( noSqrtTwo == 2 ) && ( noPerpendicular == 1 ) )
1376 if ( !
ProSHADE_internal_symmetry::findMissingAxesDual ( &prospectiveC2s, CSymList, ret, &retGrp, 6, axErr, 1, 0.0, 2, 1/sqrt(2.0), 2, dataObj ) )
1382 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
1416 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 )
1419 bool atLeastOne =
false;
1420 std::vector< proshade_double* > prosp;
1421 std::vector< proshade_double > sol;
1424 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
1427 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
1430 CSymList->at(possibilities->at(prIt))[1],
1431 CSymList->at(possibilities->at(prIt))[2],
1432 CSymList->at(possibilities->at(prIt))[3],
1433 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
1437 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
1439 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
1442 if ( rgIt1 == rgIt2 ) {
continue; }
1446 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], angle1, angle2 );
1449 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
1450 if ( prosp.size() == requiredNoAxes ) {
break; }
1454 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], -angle1, -angle2 );
1457 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
1458 if ( prosp.size() == requiredNoAxes ) {
break; }
1461 if ( prosp.size() == requiredNoAxes ) {
break; }
1465 if (
static_cast<proshade_unsign
> ( prosp.size() ) == requiredNoAxes )
1468 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
1480 return ( atLeastOne );
1485 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
1487 delete[] prosp.at(iter);
1492 return ( atLeastOne );
1511 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 )
1514 proshade_double* symHlp =
new proshade_double[7];
1516 proshade_signed ret = -1;
1519 symHlp[0] =
static_cast<proshade_double
> ( fold );
1523 symHlp[4] = 2.0 * M_PI / symHlp[0];
1524 symHlp[5] = axHeight;
1525 symHlp[6] = averageFSC;
1531 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
1560 proshade_double* symHlp =
new proshade_double[7];
1562 proshade_signed ret = -1;
1565 symHlp[0] =
static_cast<proshade_double
> ( fold );
1569 symHlp[4] = 2.0 * M_PI / symHlp[0];
1570 symHlp[5] = axHeight;
1571 symHlp[6] = -std::numeric_limits < proshade_double >::infinity();
1577 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
1610 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 )
1613 proshade_unsign noG1 = 0;
1614 proshade_unsign noG2 = 0;
1615 proshade_double dotProd = 0.0;
1616 proshade_double axHeight = 0.0;
1619 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
1622 &ret->at(retGroup->at(rIt))[2],
1623 &ret->at(retGroup->at(rIt))[3],
1626 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
1627 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
1631 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) )
1637 if ( axHeight > 0.1 )
1639 proshade_unsign prevProsp =
static_cast<proshade_unsign
> ( prosp->size() );
1642 if (
static_cast<proshade_unsign
> ( prosp->size() ) > prevProsp ) {
return (
true ); }
1643 else {
return (
false ); }
1659 std::vector< proshade_double* >
ProSHADE_internal_data::ProSHADE_data::decidePolyFromList (
ProSHADE_settings* settings, std::vector < std::vector< proshade_double* > >* polyList,
size_t fullGroupSize, std::vector< proshade_double* >* CSyms, proshade_double tolerance, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
1662 std::vector< proshade_double* > ret;
1663 proshade_double fscVal = 0.0;
1664 proshade_double fscValAvg = 0.0;
1665 proshade_double fscMax = 0.0;
1666 size_t fscMaxInd = 0;
1667 proshade_signed matchedPos = -1;
1670 for (
size_t gIt = 0; gIt < polyList->size(); gIt++ )
1673 if ( polyList->at(gIt).size() != fullGroupSize ) {
continue; }
1680 for (
size_t aIt = 0; aIt < polyList->at(gIt).size(); aIt++ )
1683 matchedPos =
ProSHADE_internal_symmetry::addAxisUnlessSame (
static_cast< proshade_unsign
> ( polyList->at(gIt).at(aIt)[0] ), polyList->at(gIt).at(aIt)[1], polyList->at(gIt).at(aIt)[2], polyList->at(gIt).at(aIt)[3], polyList->at(gIt).at(aIt)[5], polyList->at(gIt).at(aIt)[6], CSyms, tolerance );
1686 fscVal = this->
computeFSC ( settings, CSyms,
static_cast< size_t > ( matchedPos ), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
1687 polyList->at(gIt).at(aIt)[6] = fscVal;
1688 fscValAvg += fscVal;
1698 fscValAvg /=
static_cast< proshade_double
> ( fullGroupSize );
1701 if ( fscValAvg > fscMax )
1712 for (
size_t retIt = 0; retIt < polyList->at(fscMaxInd).size(); retIt++ )
1715 matchedPos =
ProSHADE_internal_symmetry::addAxisUnlessSame (
static_cast< proshade_unsign
> ( polyList->at(fscMaxInd).at(retIt)[0] ), polyList->at(fscMaxInd).at(retIt)[1], polyList->at(fscMaxInd).at(retIt)[2], polyList->at(fscMaxInd).at(retIt)[3], polyList->at(fscMaxInd).at(retIt)[5], polyList->at(fscMaxInd).at(retIt)[6], CSyms, tolerance );
1749 void ProSHADE_internal_data::ProSHADE_data::getPredictedIcosahedralSymmetriesList (
ProSHADE_settings* settings, std::vector< proshade_double* >* CSymList, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
1752 std::vector< std::vector< proshade_double* > > hlpVec;
1764 for (
size_t pIt = 0; pIt < hlpVec.size(); pIt++ )
1772 this->icosahedralSymmetries =
ProSHADE_data::decidePolyFromList ( settings, &hlpVec, 31, CSymList, settings->
axisErrTolerance, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
1775 for (
size_t gIt = 0; gIt < hlpVec.size(); gIt++ ) {
for (
size_t aIt = 0; aIt < hlpVec.at(gIt).size(); aIt++ ) {
if ( hlpVec.at(gIt).at(aIt) !=
nullptr ) {
delete[] hlpVec.at(gIt).at(aIt); } } }
1807 void ProSHADE_internal_data::ProSHADE_data::getPredictedOctahedralSymmetriesList (
ProSHADE_settings* settings, std::vector< proshade_double* >* CSymList, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
1810 std::vector< std::vector< proshade_double* > > hlpVec;
1822 for (
size_t pIt = 0; pIt < hlpVec.size(); pIt++ )
1830 this->octahedralSymmetries =
ProSHADE_data::decidePolyFromList ( settings, &hlpVec, 13, CSymList, settings->
axisErrTolerance, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
1833 for (
size_t gIt = 0; gIt < hlpVec.size(); gIt++ ) {
for (
size_t aIt = 0; aIt < hlpVec.at(gIt).size(); aIt++ ) {
if ( hlpVec.at(gIt).at(aIt) !=
nullptr ) {
delete[] hlpVec.at(gIt).at(aIt); } } }
1857 std::vector< proshade_unsign > C5List;
1858 proshade_double dotProduct;
1861 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1863 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 5.0 );
1868 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
1870 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1873 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1874 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
1878 &CSymList->at(C5List.at(c5))[2],
1879 &CSymList->at(C5List.at(c5))[3],
1880 &CSymList->at(cSym)[1],
1881 &CSymList->at(cSym)[2],
1882 &CSymList->at(cSym)[3] );
1885 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr ) {
return (
true ); }
1915 std::vector< proshade_unsign > C5PossibilitiesHlp;
1916 std::vector< std::vector< proshade_unsign > > C5Possibilities;
1923 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1926 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cIt)[0] ), rhs1 ( 5.0 );
1927 if ( !lhs1.AlmostEquals ( rhs1 ) || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
1930 groupMatched =
false;
1931 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C5Possibilities.size() ); gIt++ )
1944 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
1945 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; } } }
1947 if ( C5Possibilities.at(maxGrp).size() == 6 )
1950 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)) ); }
1971 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestIcosDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
1974 std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
1975 std::vector< proshade_unsign > C5List;
1976 proshade_double dotProduct;
1979 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 ); } }
1982 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
1984 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1987 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
1988 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
1989 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
1993 &CSymList->at(C5List.at(c5))[2],
1994 &CSymList->at(C5List.at(c5))[3],
1995 &CSymList->at(cSym)[1],
1996 &CSymList->at(cSym)[2],
1997 &CSymList->at(cSym)[3] );
2000 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
2002 std::pair< proshade_unsign, proshade_unsign > hlp;
2003 hlp.first = C5List.at(c5);
2005 ret.emplace_back ( hlp );
2037 std::vector < std::pair< proshade_unsign, proshade_unsign > > initAxes =
findBestIcosDihedralPair ( CSymList, minPeakHeight, axErr );
2040 for (
size_t pIt = 0; pIt < initAxes.size(); pIt++ )
2049 CSymList->at(initAxes.at(pIt).first)[1],
2050 CSymList->at(initAxes.at(pIt).first)[2],
2051 CSymList->at(initAxes.at(pIt).first)[3] );
2060 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
2061 proshade_double* rotMatHlp =
new proshade_double[9];
2063 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
2075 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.at(pIt).second)[1], 2.0 ) +
2076 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.at(pIt).second)[2], 2.0 ) +
2077 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.at(pIt).second)[3], 2.0 ) );
2080 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
2083 delete[] rotRotModelC3;
2090 proshade_double* rotMat2 =
new proshade_double[9];
2098 std::vector< proshade_double* > hlpAxes;
2099 for ( proshade_unsign iter = 0; iter < icoAx->
getNoAxes ( ); iter++ )
2108 proshade_double* axis =
new proshade_double[7];
2111 axis[0] = icoAx->
getValue ( iter, 0 );
2112 axis[1] = rotAxis[0];
2113 axis[2] = rotAxis[1];
2114 axis[3] = rotAxis[2];
2115 axis[4] = ( 2.0 * M_PI ) / axis[0];
2117 axis[6] = -std::numeric_limits < proshade_double >::infinity();
2128 ret->emplace_back ( hlpAxes );
2134 delete[] rotModelC3;
2150 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestOctaDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
2153 std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
2154 std::vector< proshade_unsign > C4List;
2155 proshade_double dotProduct;
2158 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 ); } }
2161 for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
2163 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2166 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
2167 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
2168 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
2172 &CSymList->at(C4List.at(c4))[2],
2173 &CSymList->at(C4List.at(c4))[3],
2174 &CSymList->at(cSym)[1],
2175 &CSymList->at(cSym)[2],
2176 &CSymList->at(cSym)[3] );
2179 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
2181 std::pair< proshade_unsign, proshade_unsign > hlp;
2182 hlp.first = C4List.at(c4);
2184 ret.emplace_back ( hlp );
2217 std::vector < std::pair< proshade_unsign, proshade_unsign > > initAxes =
findBestOctaDihedralPair ( CSymList, minPeakHeight, axErr );
2220 for (
size_t pIt = 0; pIt < initAxes.size(); pIt++ )
2229 CSymList->at(initAxes.at(pIt).first)[1],
2230 CSymList->at(initAxes.at(pIt).first)[2],
2231 CSymList->at(initAxes.at(pIt).first)[3] );
2240 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
2241 proshade_double* rotMatHlp =
new proshade_double[9];
2243 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
2255 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.at(pIt).second)[1], 2.0 ) +
2256 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.at(pIt).second)[2], 2.0 ) +
2257 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.at(pIt).second)[3], 2.0 ) );
2260 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
2263 delete[] rotRotModelC3;
2270 proshade_double* rotMat2 =
new proshade_double[9];
2278 std::vector< proshade_double* > hlpAxes;
2279 for ( proshade_unsign iter = 0; iter < octAx->
getNoAxes ( ); iter++ )
2288 proshade_double* axis =
new proshade_double[7];
2291 axis[0] = octAx->
getValue ( iter, 0 );
2292 axis[1] = rotAxis[0];
2293 axis[2] = rotAxis[1];
2294 axis[3] = rotAxis[2];
2295 axis[4] = ( 2.0 * M_PI ) / axis[0];
2297 axis[6] = -std::numeric_limits < proshade_double >::infinity();
2308 ret->emplace_back ( hlpAxes );
2314 delete[] rotModelC3;
2340 std::vector< proshade_unsign > prospectiveC3s, retGrp;
2341 proshade_double dotProd;
2342 proshade_unsign noClose, noAway;
2348 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2351 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
2354 noClose = 0; noAway = 0;
2355 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
2360 &CSymList->at(cIt)[1],
2361 &CSymList->at(cIt)[2],
2362 &CSymList->at(cIt)[3] );
2364 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; }
2365 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; }
2369 if ( ( noClose == 3 ) && ( noAway == 3 ) )
2377 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 ) )
2383 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC3s.size() ); iter++ )
2413 std::vector< proshade_unsign > prospectiveC2s, retGrp;
2414 proshade_double dotProd;
2415 proshade_unsign noClose, noMidway, noAway;
2421 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2424 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2425 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
2428 noClose = 0; noMidway = 0; noAway = 0;
2429 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
2434 &CSymList->at(cIt)[1],
2435 &CSymList->at(cIt)[2],
2436 &CSymList->at(cIt)[3] );
2438 if ( ( std::abs ( dotProd ) > ( ( sqrt ( 3.0 ) / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( sqrt ( 3.0 ) / 2.0 ) + axErr ) ) ) { noAway += 1;
continue; }
2439 if ( ( std::abs ( dotProd ) > ( ( 1.0 / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / 2.0 ) + axErr ) ) ) { noMidway += 1;
continue; }
2440 if ( ( std::abs ( dotProd ) > ( ( 0.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 0.0 ) + axErr ) ) ) { noClose += 1;
continue; }
2444 if ( ( noClose == 2 ) && ( noMidway == 2 ) && ( noAway == 2 ) )
2452 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 ) )
2458 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
2493 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 )
2496 bool atLeastOne =
false;
2497 std::vector< proshade_double* > prosp;
2498 std::vector< proshade_double > sol;
2501 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
2504 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
2507 CSymList->at(possibilities->at(prIt))[1],
2508 CSymList->at(possibilities->at(prIt))[2],
2509 CSymList->at(possibilities->at(prIt))[3],
2510 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
2514 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
2516 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
2519 if ( rgIt1 == rgIt2 ) {
continue; }
2521 for ( proshade_unsign rgIt3 = 0; rgIt3 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt3++ )
2524 if ( ( rgIt1 == rgIt3 ) || ( rgIt2 == rgIt3 ) ) {
continue; }
2528 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
2529 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], angle1, angle2, angle3 );
2532 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 );
2533 if ( prosp.size() == requiredNoAxes ) {
break; }
2537 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
2538 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], -angle1, -angle2, -angle3 );
2541 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 );
2542 if ( prosp.size() == requiredNoAxes ) {
break; }
2545 if ( prosp.size() == requiredNoAxes ) {
break; }
2548 if ( prosp.size() == requiredNoAxes ) {
break; }
2552 if ( prosp.size() == requiredNoAxes )
2555 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
2566 return ( atLeastOne );
2571 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
2573 delete[] prosp.at(axIt);
2578 return ( atLeastOne );
2604 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 )
2607 proshade_unsign noG1 = 0;
2608 proshade_unsign noG2 = 0;
2609 proshade_unsign noG3 = 0;
2610 proshade_double dotProd = 0.0;
2611 proshade_double axHeight = 0.0;
2614 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
2617 &ret->at(retGroup->at(rIt))[2],
2618 &ret->at(retGroup->at(rIt))[3],
2621 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
2622 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
2623 if ( ( std::abs ( dotProd ) > ( angle3 - axErr ) ) && ( std::abs ( dotProd ) < ( angle3 + axErr ) ) ) { noG3 += 1;
continue; }
2627 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) && ( noG3 == noMatchesG3 ) )
2633 if ( axHeight > 0.1 )
2660 std::vector< proshade_double* > ret, tmpHolder;
2661 std::vector< proshade_unsign > testedFolds;
2662 proshade_double symThres;
2663 proshade_unsign foldToTest, rotationNumber;
2664 bool foldDone, anyNewSyms =
true;
2667 fftw_complex* fCoeffsCut;
2668 proshade_double **bindata, *fscByBin;
2669 proshade_signed *cutIndices, *binCounts, noBins, cutXDim, cutYDim, cutZDim;
2670 this->prepareFSCFourierMemory ( cutIndices, fCoeffsCut, &noBins, bindata, binCounts, fscByBin, settings->
requestedResolution, &cutXDim, &cutYDim, &cutZDim );
2673 for ( proshade_unsign prIt = 0; prIt < static_cast< proshade_unsign > ( primes.size() ); prIt++ )
2676 std::stringstream hlpSS;
2677 hlpSS <<
"Searching for prime fold symmetry C" << primes.at(prIt) <<
".";
2685 std::vector< proshade_signed > divisAll;
2687 for ( proshade_unsign pfIt = primes.at(prIt) + 4; pfIt >= ( std::max ( primes.at(prIt) - 4, settings->
supportedSymmetryFold ) ); pfIt-- )
2689 if ( pfIt == primes.at(prIt) ) {
continue; }
2690 if ( pfIt < 2 ) {
continue; }
2696 std::vector< proshade_double > prevRots;
2697 for (
size_t fIt = 0; fIt < divisAll.size(); fIt++ ) {
for (
size_t rIt = 1; rIt < static_cast< size_t > ( divisAll.at(fIt) - 1 ); rIt++ ) {
ProSHADE_internal_misc::addToDoubleVector ( &prevRots, ( ( 2.0 * M_PI ) /
static_cast< proshade_double
> ( divisAll.at(fIt) ) ) *
static_cast< proshade_double
> ( rIt ) ); } }
2700 proshade_unsign bestPos = 1;
2701 proshade_double bestDist = 0.0;
2702 proshade_double curPos = 0.0;
2703 proshade_double bestDistHlp;
2706 for ( proshade_unsign fIt = 2; fIt <= static_cast< proshade_unsign >( ( primes.at(prIt) + 1 ) / 2 ); fIt++ )
2709 curPos = ( ( 2.0 * M_PI ) /
static_cast< proshade_double
> ( primes.at(prIt) ) ) *
static_cast< proshade_double
> ( fIt );
2710 bestDistHlp = std::numeric_limits < proshade_double >::infinity();
2713 for ( proshade_unsign dIt = 0; dIt < static_cast< proshade_unsign > ( prevRots.size() ); dIt++ ) {
if ( std::abs ( prevRots.at(dIt) - curPos ) < bestDistHlp ) { bestDistHlp = std::abs ( prevRots.at(dIt) - curPos ); } }
2716 if ( bestDistHlp > bestDist ) { bestDist = bestDistHlp; bestPos = fIt; }
2719 rotationNumber = bestPos;
2720 if ( rotationNumber >= ( primes.at(prIt) - 1 ) ) { rotationNumber = 1; }
2724 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, primes.at(prIt), &symThres );
2727 for (
size_t axIt = 0; axIt < prSyms.size(); axIt++ )
2730 if ( prSyms.at(axIt)[5] >= std::max ( symThres, settings->
minSymPeak ) )
2736 this->
computeFSC ( settings, prSyms.at(axIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim, rotationNumber );
2741 prSyms.at(axIt)[6] = -std::numeric_limits < proshade_double >::infinity();
2742 this->
computeFSC ( settings, prSyms.at(axIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim, 0 );
2751 delete[] prSyms.at(axIt);
2756 if ( ret.size() < 1 ) {
return ( ret ); }
2760 proshade_double dotProduct = 0.0;
2763 while ( anyNewSyms )
2769 for ( proshade_unsign axIt1 = 0; axIt1 < static_cast< proshade_unsign > ( ret.size() ); axIt1++ )
2772 if ( bestFSCPeakStart > ret.at(axIt1)[6] ) {
continue; }
2774 for ( proshade_unsign axIt2 = 0; axIt2 < static_cast< proshade_unsign > ( ret.size() ); axIt2++ )
2777 if ( bestFSCPeakStart > ret.at(axIt2)[6] ) {
continue; }
2789 &ret.at(axIt2)[3] );
2790 if ( std::abs ( dotProduct ) < ( 1.0 - settings->
axisErrTolerance ) ) {
continue; }
2793 foldToTest =
static_cast< proshade_unsign
> ( ret.at(axIt1)[0] * ret.at(axIt2)[0] );
2800 std::vector< proshade_signed > divisAll;
2803 for (
size_t iter = 0; iter < ret.size(); iter++ ) {
if ( ret.at(iter)[6] > ( bestFSCPeakStart * 0.9 ) ) {
ProSHADE_internal_misc::addToSignedVector ( &divisAll,
static_cast< proshade_signed
> ( ret.at(iter)[0] ) ); } }
2806 std::vector< proshade_double > prevRots;
2807 for (
size_t fIt = 0; fIt < divisAll.size(); fIt++ ) {
for (
size_t rIt = 1; rIt < static_cast< size_t > ( divisAll.at(fIt) - 1 ); rIt++ ) {
ProSHADE_internal_misc::addToDoubleVector ( &prevRots, ( ( 2.0 * M_PI ) /
static_cast< proshade_double
> ( divisAll.at(fIt) ) ) *
static_cast< proshade_double
> ( rIt ) ); } }
2810 proshade_unsign bestPos = 1;
2811 proshade_double bestDist = 0.0;
2812 proshade_double curPos = 0.0;
2813 proshade_double bestDistHlp;
2816 for ( proshade_unsign fIt = 2; fIt <= static_cast< proshade_unsign >( foldToTest / 2 ); fIt++ )
2819 curPos = ( ( 2.0 * M_PI ) /
static_cast< proshade_double
> ( foldToTest ) ) *
static_cast< proshade_double
> ( fIt );
2820 bestDistHlp = std::numeric_limits < proshade_double >::infinity();
2823 for ( proshade_unsign dIt = 0; dIt < static_cast< proshade_unsign > ( prevRots.size() ); dIt++ ) {
if ( std::abs ( prevRots.at(dIt) - curPos ) < bestDistHlp ) { bestDistHlp = std::abs ( prevRots.at(dIt) - curPos ); } }
2826 if ( bestDistHlp > bestDist ) { bestDist = bestDistHlp; bestPos = fIt; }
2829 rotationNumber = bestPos;
2830 if ( rotationNumber >= ( foldToTest - 1 ) ) { rotationNumber = 1; }
2835 for ( proshade_unsign fIt = 0; fIt < static_cast< proshade_unsign > ( testedFolds.size() ); fIt++ ) {
if ( testedFolds.at(fIt) == foldToTest ) { foldDone =
true;
break; } }
2836 if ( foldDone ) {
continue; }
2840 std::stringstream hlpSS2;
2841 hlpSS2 <<
"Searching for fold combination of detected folds " << ret.at(axIt1)[0] <<
" and " << ret.at(axIt2)[0] <<
", i.e. C" << foldToTest <<
".";
2845 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, foldToTest, &symThres );
2848 for (
size_t newAxIt = 0; newAxIt < prSyms.size(); newAxIt++ )
2851 if ( prSyms.at(newAxIt)[5] >= symThres )
2858 this->
computeFSC ( settings, prSyms.at(newAxIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim, rotationNumber );
2861 if ( ( foldToTest >= settings->
supportedSymmetryFold ) || ( prSyms.at(newAxIt)[6] >= bestFSCPeakStart ) )
2863 prSyms.at(newAxIt)[6] = -std::numeric_limits < proshade_double >::infinity();
2864 this->
computeFSC ( settings, prSyms.at(newAxIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim, 0 );
2873 delete[] prSyms.at(newAxIt);
2877 if ( tmpHolder.size() != 0 )
2880 for ( proshade_unsign tmpIt = 0; tmpIt < static_cast< proshade_unsign > ( tmpHolder.size() ); tmpIt++ )
2883 delete[] tmpHolder.at(tmpIt);
2890 tmpHolder.clear ( );
2896 for (
size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) {
delete[] bindata[binIt]; }
2900 delete[] cutIndices;
2901 fftw_free ( fCoeffsCut );
2919 return ( a[5] > b[5] );
2942 proshade_double soughtAngle;
2943 std::vector< proshade_double > allPeakHeights;
2944 std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup* > peakGroups;
2945 std::vector< proshade_double* > ret;
2949 if ( ( M_PI /
static_cast < proshade_double
> ( this->maxShellBand ) ) >= ( M_PI /
static_cast< proshade_double
> ( fold ) ) )
2952 std::stringstream hlpSS;
2953 hlpSS <<
"!!! ProSHADE WARNING !!! Will not search for fold " << fold <<
" as the map sampling does not support its reliable detection. Increase resolution/bandwidth if you suspect this fold could be present in the structure.";
2959 this->sphereMappedRotFun.clear();
2962 for ( proshade_double angIt = 1.0; angIt < static_cast < proshade_double > ( fold ); angIt += 1.0 )
2965 soughtAngle = angIt * ( 2.0 * M_PI /
static_cast<proshade_double
> ( fold ) );
2969 M_PI /
static_cast < proshade_double
> ( this->maxShellBand ),
2970 this->getMaxBand ( ) * 2,
2971 this->getEMatDim ( ) * 2,
2973 static_cast < proshade_unsign
> ( angIt - 1.0 ) ) );
2976 this->sphereMappedRotFun.at(
static_cast < size_t > ( angIt - 1.0 ))->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
2979 this->sphereMappedRotFun.at(
static_cast < size_t > ( angIt - 1.0 ))->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
2983 std::stringstream hlpSS;
2984 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.";
2991 std::stringstream hlpSS2;
2992 hlpSS2 <<
"Determined peak threshold " << *peakThres <<
".";
2996 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
2998 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( *peakThres );
3002 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); sphIt++ )
3005 for ( proshade_unsign pkIt = 0; pkIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().size() ); pkIt++ )
3009 for ( proshade_unsign pkGrpIt = 0; pkGrpIt < static_cast<proshade_unsign> ( peakGroups.size() ); pkGrpIt++ )
3011 if ( peakGroups.at(pkGrpIt)->checkIfPeakBelongs (
static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).first ),
3012 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
3017 if ( !newPeak ) {
continue; }
3021 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
3023 this->sphereMappedRotFun.at(sphIt)->getAngularDim() ) );
3028 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( peakGroups.size() ); grIt++ )
3031 std::stringstream hlpSS3;
3032 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 ";
3033 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( peakGroups.at(grIt)->getSpherePositions().size() ); sphIt++ ) { hlpSS3 << peakGroups.at(grIt)->getSpherePositions().at(sphIt) <<
" ; "; }
3040 delete peakGroups.at(grIt);
3066 std::vector < proshade_unsign > folds;
3067 std::vector < proshade_double > angs, applicableAngs;
3068 bool alreadyFound =
false;
3069 size_t corAngIt = 0;
3070 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;
3071 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3072 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3075 for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( ret->size() ); iter++ )
3077 alreadyFound =
false;
3078 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; } }
3084 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) ) ) ); } }
3085 std::sort ( angs.begin(), angs.end() );
3088 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) ); } }
3091 dataObj->sphereMappedRotFun.clear();
3092 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3095 if ( ( angIt == 0 ) && ( angs.size() > 1 ) ) { radRange = ( angs.at(1) - angs.at(0) ) / 2; }
3096 else {
if ( ( angIt == ( angs.size() - 1 ) ) && ( angs.size() > 1 ) ) { radRange = ( angs.at(angIt) - angs.at(angIt-1) ) / 2; }
3097 else {
if ( angs.size() > 2 ) { radRange = std::min ( ( angs.at(angIt) - angs.at(angIt-1) ) / 2, ( angs.at(angIt+1) - angs.at(angIt) ) / 2 ); }
3098 else { radRange = 0.5; } } }
3106 static_cast<proshade_unsign
> ( angIt ) ) );
3109 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
3113 searchRangeInDeg = 360.0 / (
static_cast< proshade_double
> ( dataObj->
getMaxBand() ) * 2.0 );
3114 proshade_double* rotMat, *newAxis;
3115 while ( searchRangeInDeg > 0.09 )
3118 for ( proshade_double xChan = -searchRangeInDeg; xChan < ( 1.5 * searchRangeInDeg ); xChan += searchRangeInDeg )
3120 for ( proshade_double yChan = -searchRangeInDeg; yChan < ( 1.5 * searchRangeInDeg ); yChan += searchRangeInDeg )
3122 for ( proshade_double zChan = -searchRangeInDeg; zChan < ( 1.5 * searchRangeInDeg ); zChan += searchRangeInDeg )
3131 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3137 lat = ( std::atan2( newAxis[1], newAxis[0] ) / latSamlUnit );
3138 lon = ( std::acos ( newAxis[2] ) / lonSamlUnit );
3140 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3141 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3144 applicableAngs.clear ( );
3149 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3152 alreadyFound =
false;
3153 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; } }
3155 if ( !alreadyFound ) {
continue; }
3158 axSum += dataObj->sphereMappedRotFun.at(corAngIt)->getSphereLatLonLinearInterpolationPos ( lat, lon );
3162 axSum /= ret->at(axIt)[0];
3170 curSum /=
static_cast< proshade_double
> ( ret->size() );
3173 if ( curSum > maxSum )
3190 searchRangeInDeg /= 2.0;
3191 finXRotChan += bestXRot;
3192 finYRotChan += bestYRot;
3193 finZRotChan += bestZRot;
3201 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3207 ret->at(axIt)[1] = newAxis[0];
3208 ret->at(axIt)[2] = newAxis[1];
3209 ret->at(axIt)[3] = newAxis[2];
3216 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
3219 lat = std::atan2( ret->at(axIt)[2], ret->at(axIt)[1] ) / latSamlUnit;
3220 lon = std::acos ( ret->at(axIt)[3] ) / lonSamlUnit;
3222 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3223 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3226 applicableAngs.clear ( );
3230 ret->at(axIt)[5] = 0.0;
3231 for (
size_t angIt = 0; angIt < angs.size(); angIt++ )
3234 alreadyFound =
false;
3235 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; } }
3237 if ( !alreadyFound ) {
continue; }
3240 ret->at(axIt)[5] += dataObj->sphereMappedRotFun.at(corAngIt)->getSphereLatLonLinearInterpolationPos ( lat, lon );
3244 ret->at(axIt)[5] /= ( ret->at(axIt)[0] - 1.0 );
3245 maxSum += ret->at(axIt)[5];
3272 if ( ret->size() != 2 )
3274 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." );
3278 proshade_double *crossProd, *perpVec, normFactor;
3279 size_t higherRFIndex = 0;
3285 if ( ret->at(1).at(5) > ret->at(0).at(5) ) { higherRFIndex = 1; }
3289 normFactor = std::sqrt ( pow ( perpVec[0], 2.0 ) + pow ( perpVec[1], 2.0 ) + pow ( perpVec[2], 2.0 ) );
3290 perpVec[0] /= normFactor; perpVec[1] /= normFactor; perpVec[2] /= normFactor;
3293 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( perpVec[0] ), std::max( std::abs ( perpVec[1] ), std::abs ( perpVec[2] ) ) ) );
3294 const FloatingPoint< proshade_double > rhs1 ( std::abs ( perpVec[0] ));
3295 const FloatingPoint< proshade_double > rhs2 ( std::abs ( perpVec[1] ) );
3296 const FloatingPoint< proshade_double > rhs3 ( std::abs ( perpVec[2] ) );
3297 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( perpVec[0] < 0.0 ) ) ||
3298 ( lhs1.AlmostEquals ( rhs2 ) && ( perpVec[1] < 0.0 ) ) ||
3299 ( lhs1.AlmostEquals ( rhs3 ) && ( perpVec[2] < 0.0 ) ) )
3307 if ( higherRFIndex == 0 ) { higherRFIndex = 1; }
3308 else { higherRFIndex = 0; }
3311 ret->at(higherRFIndex).at(1) = perpVec[0]; ret->at(higherRFIndex).at(2) = perpVec[1]; ret->at(higherRFIndex).at(3) = perpVec[2];
3318 std::vector< proshade_double* > convVec;
3319 for (
size_t axIt = 0; axIt < 2; axIt++ )
3322 proshade_double* axVals =
new proshade_double[7];
3326 for (
size_t elIt = 0; elIt < 7; elIt++ )
3328 axVals[elIt] = ret->at(axIt).at(elIt);
3332 convVec.push_back ( axVals );
3339 for (
size_t axIt = 0; axIt < 2; axIt++ )
3342 for (
size_t elIt = 0; elIt < 7; elIt++ )
3344 ret->at(axIt).at(elIt) = convVec.at(axIt)[elIt];
3348 delete[] convVec.at(axIt);
3369 std::vector < std::vector< proshade_double > > ortPair;
3370 std::vector< proshade_double > hlpVec;
3373 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] );
3374 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] );
3375 hlpVec.push_back ( allCs->at(selection.at(0))[6] );
3376 ortPair.push_back ( hlpVec ); hlpVec.clear ( );
3377 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] );
3378 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] );
3379 hlpVec.push_back ( allCs->at(selection.at(1))[6] );
3380 ortPair.push_back ( hlpVec );
3386 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);
3387 allCs->at(selection.at(0))[5] = ortPair.at(0).at(5); allCs->at(selection.at(0))[6] = ortPair.at(0).at(6);
3389 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);
3390 allCs->at(selection.at(1))[5] = ortPair.at(1).at(5); allCs->at(selection.at(1))[6] = ortPair.at(1).at(6);
3412 proshade_double height = 0.0;
3413 proshade_double lat, lon;
3414 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3415 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
3418 dataObj->sphereMappedRotFun.clear ( );
3421 for ( proshade_double angIt = 1.0; angIt < fold; angIt += 1.0 )
3428 angIt * ( 2.0 * M_PI / fold ),
3429 static_cast<proshade_unsign
> ( angIt - 1.0 ) ) );
3432 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt - 1.0 ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
3436 lat = std::atan2( axis[1], axis[0] ) / latSamlUnit;
3437 lon = std::acos ( axis[2] ) / lonSamlUnit;
3439 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3440 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
3442 lat = std::round ( lat );
3443 lon = std::round ( lon );
3449 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( dataObj->sphereMappedRotFun.size() ); sphIt++ )
3464 std::vector < proshade_double* > detectedAxis;
3468 if ( detectedAxis.size() > 0 ) { height = detectedAxis.at(0)[5]; }
3469 else { height = 0.0; }
3472 for ( proshade_unsign i = 0; i < static_cast < proshade_unsign > ( detectedAxis.size() ); i++ ) {
delete detectedAxis.at(i); }
3487 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestTetraDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
3490 std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
3491 std::vector< proshade_unsign > C3List;
3492 proshade_double dotProduct;
3495 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 ); } }
3498 for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
3500 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3503 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 2.0 );
3504 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
3505 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
3509 &CSymList->at(C3List.at(c3))[2],
3510 &CSymList->at(C3List.at(c3))[3],
3511 &CSymList->at(cSym)[1],
3512 &CSymList->at(cSym)[2],
3513 &CSymList->at(cSym)[3] );
3516 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3518 std::pair< proshade_unsign, proshade_unsign > hlp;
3519 hlp.first = C3List.at(c3);
3521 ret.emplace_back ( hlp );
3553 void ProSHADE_internal_data::ProSHADE_data::getPredictedTetrahedralSymmetriesList (
ProSHADE_settings* settings, std::vector< proshade_double* >* CSymList, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
3556 std::vector< std::vector< proshade_double* > > hlpVec;
3568 for (
size_t pIt = 0; pIt < hlpVec.size(); pIt++ )
3576 this->tetrahedralSymmetries =
ProSHADE_data::decidePolyFromList ( settings, &hlpVec, 7, CSymList, settings->
axisErrTolerance, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
3579 for (
size_t gIt = 0; gIt < hlpVec.size(); gIt++ ) {
for (
size_t aIt = 0; aIt < hlpVec.at(gIt).size(); aIt++ ) {
if ( hlpVec.at(gIt).at(aIt) !=
nullptr ) {
delete[] hlpVec.at(gIt).at(aIt); } } }
3612 std::vector< std::pair< proshade_unsign, proshade_unsign > > initAxes =
findBestTetraDihedralPair ( CSymList, minPeakHeight, axErr );
3615 for (
size_t pIt = 0; pIt < initAxes.size(); pIt++ )
3624 CSymList->at(initAxes.at(pIt).first)[1],
3625 CSymList->at(initAxes.at(pIt).first)[2],
3626 CSymList->at(initAxes.at(pIt).first)[3] );
3635 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
3636 proshade_double* rotMatHlp =
new proshade_double[9];
3638 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
3650 curAngDist = std::sqrt ( std::pow ( rotRotModelC2[0] - CSymList->at(initAxes.at(pIt).second)[1], 2.0 ) +
3651 std::pow ( rotRotModelC2[1] - CSymList->at(initAxes.at(pIt).second)[2], 2.0 ) +
3652 std::pow ( rotRotModelC2[2] - CSymList->at(initAxes.at(pIt).second)[3], 2.0 ) );
3655 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
3658 delete[] rotRotModelC2;
3665 proshade_double* rotMat2 =
new proshade_double[9];
3673 std::vector< proshade_double* > hlpAxes;
3674 for ( proshade_unsign iter = 0; iter < tetAx->
getNoAxes( ); iter++ )
3683 proshade_double* axis =
new proshade_double[7];
3686 axis[0] = tetAx->
getValue ( iter, 0 );
3687 axis[1] = rotAxis[0];
3688 axis[2] = rotAxis[1];
3689 axis[3] = rotAxis[2];
3690 axis[4] = ( 2.0 * M_PI ) / axis[0];
3692 axis[6] = -std::numeric_limits < proshade_double >::infinity();
3703 ret->emplace_back ( hlpAxes );
3709 delete[] rotModelC2;
3741 std::vector< proshade_unsign > ret;
3746 if ( bestHistPeakStart > 0.9 ) { bestHistPeakStart = 0.9; }
3749 proshade_double maxOrtSum = 0.0, curOrtSum = 0.0;
3750 proshade_signed maxOrtAx1 = 0, maxOrtAx2 = 0;
3751 for (
size_t relAx = 0; relAx < allDs->size(); relAx++ )
3754 if ( allDs->at(relAx).at(0)[5] < bestHistPeakStart ) {
continue; }
3755 if ( allDs->at(relAx).at(1)[5] < bestHistPeakStart ) {
continue; }
3756 if ( allDs->at(relAx).at(0)[6] < bestFSCPeakStart ) {
continue; }
3757 if ( allDs->at(relAx).at(1)[6] < bestFSCPeakStart ) {
continue; }
3760 curOrtSum = allDs->at(relAx).at(0)[6] + allDs->at(relAx).at(1)[6];
3761 if ( curOrtSum > maxOrtSum )
3763 maxOrtSum = curOrtSum;
3765 allDs->at(relAx).at(0)[1],
3766 allDs->at(relAx).at(0)[2],
3767 allDs->at(relAx).at(0)[3],
3768 allDs->at(relAx).at(0)[5], allCs, tolerance );
3770 allDs->at(relAx).at(1)[1],
3771 allDs->at(relAx).at(1)[2],
3772 allDs->at(relAx).at(1)[3],
3773 allDs->at(relAx).at(1)[5], allCs, tolerance );
3778 if ( maxOrtAx2 != 0 )
3787 curOrtSum = 0.0; maxOrtSum = 0.0; maxOrtAx1 = -1;
3788 for (
size_t relAx = 0; relAx < allCs->size(); relAx++ )
3791 if ( allCs->at(relAx)[5] < bestHistPeakStart ) {
continue; }
3794 if ( allCs->at(relAx)[6] < bestFSCPeakStart ) {
continue; }
3797 curOrtSum = allCs->at(relAx)[6];
3800 if ( curOrtSum > maxOrtSum )
3802 maxOrtSum = curOrtSum;
3803 maxOrtAx1 =
static_cast< proshade_signed
> ( relAx );
3808 if ( maxOrtAx1 >= 0 )
3841 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 )
3844 origMap =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3845 origCoeffs =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3846 rotMapComplex =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3847 rotCoeffs =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3848 trFunc =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3849 trFuncCoeffs =
reinterpret_cast< fftw_complex*
> ( fftw_malloc (
sizeof ( fftw_complex ) * xDim * yDim * zDim ) );
3860 *planForwardFourier = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), origMap, origCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3861 *planForwardFourierRot = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), rotMapComplex, rotCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3862 *planReverseFourierComb = fftw_plan_dft_3d (
static_cast< int > ( xDim ),
static_cast< int > ( yDim ),
static_cast< int > ( zDim ), trFuncCoeffs, trFunc, FFTW_BACKWARD, FFTW_ESTIMATE );
3884 fftw_destroy_plan ( planReverseFourierComb );
3885 fftw_destroy_plan ( planForwardFourier );
3886 fftw_destroy_plan ( planForwardFourierRot );
3889 planReverseFourierComb =
nullptr;
3890 planForwardFourier =
nullptr;
3891 planForwardFourierRot =
nullptr;
3894 fftw_free ( origMap );
3895 fftw_free ( origCoeffs );
3896 fftw_free ( rotMapComplex );
3897 fftw_free ( rotCoeffs );
3898 fftw_free ( trFunc );
3899 fftw_free ( trFuncCoeffs );
3922 proshade_double axX, axY, axZ, axAng, mapPeak, trsX, trsY, trsZ;
3923 std::vector< proshade_double > trsVec;
3926 proshade_double *rotMap;
3931 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; }
3932 fftw_execute ( planForwardFourierRot );
3938 fftw_execute ( planReverseFourierComb );
3945 trsX *=
static_cast< proshade_double
> ( symStr->
getXDimSize() ) /
static_cast< proshade_double
> ( symStr->
getXDim() );
3946 trsY *=
static_cast< proshade_double
> ( symStr->
getYDimSize() ) /
static_cast< proshade_double
> ( symStr->
getYDim() );
3947 trsZ *=
static_cast< proshade_double
> ( symStr->
getZDimSize() ) /
static_cast< proshade_double
> ( symStr->
getZDim() );
3950 if ( trsX > (
static_cast< proshade_double
> ( symStr->
getXDimSize() ) / 2.0 ) ) { trsX = trsX -
static_cast< proshade_double
> ( symStr->
getXDimSize() ); }
3951 if ( trsY > (
static_cast< proshade_double
> ( symStr->
getYDimSize() ) / 2.0 ) ) { trsY = trsY -
static_cast< proshade_double
> ( symStr->
getYDimSize() ); }
3952 if ( trsZ > (
static_cast< proshade_double
> ( symStr->
getZDimSize() ) / 2.0 ) ) { trsZ = trsZ -
static_cast< proshade_double
> ( symStr->
getZDimSize() ); }
3988 std::vector< proshade_double > pointOnLine ( 3, 0.0 );
3989 std::vector< proshade_double > identityMat ( 9, 0.0 ); identityMat.at(0) = 1.0; identityMat.at(4) = 1.0; identityMat.at(8) = 1.0;
3992 for (
size_t gEl = 0; gEl < symElems.size(); gEl++ )
4000 origCoeffs, rotMapComplex,
4001 rotCoeffs, planForwardFourierRot,
4002 trFuncCoeffs, trFunc,
4003 planReverseFourierComb );
4006 pointOnLine.at(0) += trsCenHlp.at(0);
4007 pointOnLine.at(1) += trsCenHlp.at(1);
4008 pointOnLine.at(2) += trsCenHlp.at(2);
4012 pointOnLine.at(0) /=
static_cast< proshade_double
> ( symElems.size() );
4013 pointOnLine.at(1) /=
static_cast< proshade_double
> ( symElems.size() );
4014 pointOnLine.at(2) /=
static_cast< proshade_double
> ( symElems.size() );
4017 return ( pointOnLine );