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_unsign vecSize =
static_cast< proshade_unsign
> ( inArr.size() );
76 proshade_double* meadianAndIQR =
new proshade_double[2];
79 if ( vecSize == 0 ) {
delete[] meadianAndIQR;
return ( ret ); }
80 if ( vecSize <= 4 ) { ret = std::accumulate ( inArr.begin(), inArr.end(), 0.0 ) /
static_cast< proshade_double
> ( vecSize ); }
92 ret = meadianAndIQR[0] + ( meadianAndIQR[1] * noIQRsFromMedian );
96 if ( ret > *( std::max_element ( inArr.begin(), inArr.end() ) ) )
98 ret = *( std::max_element ( inArr.begin(), inArr.end() ) );
102 delete[] meadianAndIQR;
126 proshade_double shellSpacing = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( this->maxShellBand ) * 2.0;
127 std::vector< proshade_double > allPeakHeights;
130 for ( proshade_unsign spIt = 1; spIt < ( this->maxShellBand * 2 ); spIt++ )
134 this->maxShellBand * 2,
135 static_cast<proshade_double
> ( spIt ) * shellSpacing,
140 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereMappedRotFun.size() ); shIt++ )
143 std::stringstream hlpSS;
144 hlpSS <<
"Interpolating sphere " << shIt <<
" ( radius: " << this->sphereMappedRotFun.at(shIt)->getRadius() <<
" ).";
148 this->sphereMappedRotFun.at(shIt)->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
156 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
158 this->sphereMappedRotFun.at(shIt)->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
162 std::stringstream hlpSS;
163 hlpSS <<
"Detected " << allPeakHeights.size() <<
" peaks with any height.";
170 std::stringstream hlpSS2;
171 hlpSS2 <<
"From these peaks, decided the threshold will be " << peakThres <<
" peak height.";
175 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
177 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( peakThres );
201 std::vector< proshade_double* > ret;
218 std::vector< std::vector< proshade_unsign > > detectedCSymmetries;
219 for ( proshade_signed iter =
static_cast< proshade_signed
> ( peakGroupsBoundaries.size() - 1 ); iter >= 0; iter-- )
222 std::vector< proshade_double* > symPeaks;
223 for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( peaksAA.size() ); it++ )
233 settings->axisErrToleranceDefault,
244 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( peaksAA.size() ); iter++ ) {
delete[] allPeaks.at(iter);
delete[] peaksAA.at(iter); }
266 std::vector< proshade_double* > ret;
267 proshade_double* hlpP =
nullptr;
268 proshade_double* rotMat =
new proshade_double [9];
272 for ( proshade_unsign peakIter = 0; peakIter < static_cast<proshade_unsign> ( allPeaks.size() ); peakIter++ )
278 hlpP =
new proshade_double [5];
283 hlpP[4] = allPeaks.at(peakIter)[3];
293 std::stringstream hlpSSP;
294 hlpSSP <<
"Found " << ret.size() <<
" possible peaks.";
298 if ( ret.size() < 1 )
300 ProSHADE_internal_messages::printWarningMessage ( verbose,
"!!! ProSHADE WARNING !!! Failed to detect any symmetries. There are no reasonable peaks in the self-rotation map. If you believe there should be some symmetry, you can try decreasing the resolution or changing the peak IQR threshold.",
"WS00029" );
320 std::vector< proshade_double > boundaries;
322 proshade_double peakContribution = 0.0;
325 std::vector< proshade_double > pdf;
326 for ( proshade_double iter = 0.0; iter <= 1.0; iter += 0.01 )
329 peakContribution = 0.0;
332 for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( allPeaks.size() ); it++ )
342 proshade_double prev = pdf.at(0);
343 for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( pdf.size() - 1 ); iter ++ )
346 if ( ( prev > pdf.at(iter) ) && ( pdf.at(iter+1) > pdf.at(iter) ) )
356 return ( boundaries );
378 std::vector< std::vector< proshade_unsign > > ret;
379 std::vector< proshade_double > triedAlready;
380 std::vector< proshade_unsign > angsToTry, testedAlready;
381 proshade_double angDist, angDivisionRemainder, angDivisionBasis, nextSymmetryError, nextPeakError = ( M_PI * 2.0 ) / (
static_cast<proshade_double
> ( band ) * 2.0 );
384 if ( peaks->size() < 1 ) {
return ( ret ); }
390 for ( proshade_unsign grpIt = 0; grpIt < static_cast<proshade_unsign> ( sameAxesGroups.size() ); grpIt++ )
396 triedAlready.clear ( );
397 testedAlready.clear ( );
429 std::vector< std::vector< proshade_unsign > > ret;
430 bool sameAxisFound =
false;
431 proshade_double angTolerance = std::acos ( 1.0 - errTolerance );
437 for ( proshade_unsign peakIter = 0; peakIter < static_cast<proshade_unsign> ( peaks.size() ); peakIter++ )
440 sameAxisFound =
false;
443 if ( ( peaks.at(peakIter)[3] - angTolerance <= 0.0 ) && ( peaks.at(peakIter)[3] + angTolerance > 0.0 ) ) {
continue; }
447 if ( ( ( peaks.at(peakIter)[0] - 0.1 <= 0.0 ) && ( peaks.at(peakIter)[0] + 0.1 > 0.0 ) ) &&
448 ( ( peaks.at(peakIter)[1] - 0.1 <= 0.0 ) && ( peaks.at(peakIter)[1] + 0.1 > 0.0 ) ) &&
449 ( ( peaks.at(peakIter)[2] - 0.1 <= 0.0 ) && ( peaks.at(peakIter)[2] + 0.1 > 0.0 ) ) ) {
continue; }
452 for ( proshade_unsign sameAxisGrp = 0; sameAxisGrp < static_cast<proshade_unsign> ( ret.size() ); sameAxisGrp++ )
455 for ( proshade_unsign sameAxis = 0; sameAxis < static_cast<proshade_unsign> ( ret.at(sameAxisGrp).size() ); sameAxis++ )
459 peaks.at(ret.at(sameAxisGrp).at(sameAxis))[1],
460 peaks.at(ret.at(sameAxisGrp).at(sameAxis))[2],
461 peaks.at(peakIter)[0],
462 peaks.at(peakIter)[1],
463 peaks.at(peakIter)[2],
466 sameAxisFound =
true;
474 if ( sameAxisFound ) {
continue; }
477 std::vector<proshade_unsign> hlpVec;
501 for ( proshade_unsign i = 0; i < static_cast<proshade_unsign> ( peaks.size() ); i++ )
503 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( peaks.at(i)[0] ), std::max( std::abs ( peaks.at(i)[1] ), std::abs ( peaks.at(i)[2] ) ) ) );
504 const FloatingPoint< proshade_double > rhs1 ( std::abs ( peaks.at(i)[0] ) );
505 const FloatingPoint< proshade_double > rhs2 ( std::abs ( peaks.at(i)[1] ) );
506 const FloatingPoint< proshade_double > rhs3 ( std::abs ( peaks.at(i)[2] ) );
507 if ( ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( peaks.at(i)[0] < 0.0 ) ) ||
508 ( ( lhs1.AlmostEquals ( rhs2 ) ) && ( peaks.at(i)[1] < 0.0 ) ) ||
509 ( ( lhs1.AlmostEquals ( rhs3 ) ) && ( peaks.at(i)[2] < 0.0 ) ) )
511 peaks.at(i)[0] *= -1.0;
512 peaks.at(i)[1] *= -1.0;
513 peaks.at(i)[2] *= -1.0;
514 peaks.at(i)[3] *= -1.0;
532 std::stringstream hlpSS;
533 hlpSS <<
"Symmetry axis group " << groupNo;
538 for ( proshade_unsign axIt = 0; axIt < static_cast<proshade_unsign> ( grp.size() ); axIt++ )
540 std::stringstream SS;
541 SS <<
" " << axIt <<
"\t " <<
static_cast<int>( peaks.at(grp.at(axIt))[0] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(axIt))[1] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(axIt))[2] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(axIt))[3] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(axIt))[4] * 100.0 ) / 100.0;
567 proshade_unsign g1 = 0, g2 = 0;
571 for ( proshade_unsign gr1It = 0; gr1It < static_cast<proshade_unsign> ( grp.size() ); gr1It++ )
573 for ( proshade_unsign gr2It = 1; gr2It < static_cast<proshade_unsign> ( grp.size() ); gr2It++ )
576 if ( gr1It >= gr2It ) {
continue; }
580 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( tried->size() ); iter += 3 )
583 const FloatingPoint< proshade_double > lhs1 (
static_cast< proshade_double
> ( gr2It ) ), rhs1 ( tried->at( iter + 1 ) );
584 const FloatingPoint< proshade_double > lhs2 (
static_cast< proshade_double
> ( gr1It ) ), rhs2 ( tried->at( iter ) );
585 if ( ( lhs1.AlmostEquals ( rhs1 ) ) && ( lhs2.AlmostEquals ( rhs2 ) ) ) { skip =
true; }
589 ( ( std::abs( std::abs ( peaks.at(grp.at(gr1It))[3] ) - std::abs ( peaks.at(grp.at(gr2It))[3] ) ) - 0.01 ) < tried->at( iter + 2 ) ) &&
590 ( ( std::abs( std::abs ( peaks.at(grp.at(gr1It))[3] ) - std::abs ( peaks.at(grp.at(gr2It))[3] ) ) + 0.01 ) > tried->at( iter + 2 ) ) )
595 if ( skip ) {
continue; }
598 if ( std::abs( std::abs ( peaks.at(grp.at(gr1It))[3] ) - std::abs ( peaks.at(grp.at(gr2It))[3] ) ) < (*dist) )
601 if ( std::abs( std::abs ( peaks.at(grp.at(gr1It))[3] ) - std::abs ( peaks.at(grp.at(gr2It))[3] ) ) > 0.01 )
605 *dist = std::abs( std::abs ( peaks.at(grp.at(gr1It))[3] ) - std::abs ( peaks.at(grp.at(gr2It))[3] ) );
612 const FloatingPoint< proshade_double > lhs1 ( *dist ), rhs1 ( 999.9 );
613 if ( !lhs1.AlmostEquals ( rhs1 ) )
638 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( grpsVec.size() ); iter++ )
640 proshade_double* hlpP =
new proshade_double [5];
642 hlpP[0] = peaks.at(grpsVec.at(iter).at(0))[0];
643 hlpP[1] = peaks.at(grpsVec.at(iter).at(0))[1];
644 hlpP[2] = peaks.at(grpsVec.at(iter).at(0))[2];
646 hlpP[4] = peaks.at(grpsVec.at(iter).at(0))[4];
678 *divRem = std::modf (
static_cast<proshade_double
> ( ( 2.0 * M_PI ) / std::abs ( dist ) ), divBasis );
688 *symmErr = ( M_PI * 2.0 / *divBasis ) - ( M_PI * 2.0 / ( *divBasis + 1.0 ) );
689 proshade_double angTolerance = ( peakErr / *symmErr );
692 if ( ( *divRem < ( 0.0 + angTolerance ) ) && ( *divRem > ( 0.0 - angTolerance ) ) )
696 for ( proshade_signed iter = -angTolRound; iter <= angTolRound; iter++ )
703 if ( angsToTry->size() == 0 ) { ret =
false; }
722 proshade_double groupAngle = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( fold );
725 for ( proshade_signed iter =
static_cast<proshade_signed
> ( -(
static_cast<proshade_double
> ( fold ) / 2.0 + 1.0) ); iter <= static_cast<proshade_signed> (
static_cast<proshade_double
> ( fold )/2.0 + 1.0 ); iter++ )
748 proshade_unsign
ProSHADE_internal_symmetry::checkExpectedAgainstFound ( std::vector< proshade_unsign > grp, std::vector< proshade_double* > peaks, std::vector< proshade_double >* expAngs, std::vector< proshade_unsign >* matchedAngs, std::vector< proshade_unsign >* missingAngs, proshade_double angTol )
751 proshade_unsign ret = 0;
752 proshade_unsign retHlp = 0;
753 proshade_double groupAngle = expAngs->at(1) - expAngs->at(0);
754 bool matchedThisPeak =
false;
755 bool noDoubleMatches =
false;
756 std::vector < proshade_unsign > matchedAlready;
759 for ( proshade_unsign expAngIt = 0; expAngIt < static_cast<proshade_unsign> ( expAngs->size() ); expAngIt++ )
762 matchedThisPeak =
false;
763 for ( proshade_unsign peakIt = 0; peakIt < static_cast<proshade_unsign> ( grp.size() ); peakIt++ )
765 if ( ( expAngs->at(expAngIt) < ( peaks.at(grp.at(peakIt))[3] + angTol ) ) &&
766 ( expAngs->at(expAngIt) > ( peaks.at(grp.at(peakIt))[3] - angTol ) ) )
768 noDoubleMatches =
false;
769 for ( proshade_unsign ndm = 0; ndm < static_cast<proshade_unsign> ( matchedAlready.size() ); ndm++ )
771 if ( matchedAlready.at(ndm) == grp.at(peakIt) ) { noDoubleMatches =
true;
break; }
774 if ( !noDoubleMatches )
778 matchedThisPeak =
true;
785 if ( !matchedThisPeak )
792 if ( matchedAngs->size () > 1 )
794 for ( proshade_unsign iter = 1; iter < static_cast<unsigned int> ( matchedAngs->size () ); iter++ )
796 if ( ( ( peaks.at(matchedAngs->at(iter-1))[3] + groupAngle ) < ( peaks.at(matchedAngs->at(iter))[3] + angTol ) ) &&
797 ( ( peaks.at(matchedAngs->at(iter-1))[3] + groupAngle ) > ( peaks.at(matchedAngs->at(iter))[3] - angTol ) ) )
805 if ( retHlp > ret ) { ret = retHlp; }
833 proshade_double ret = 0.0;
834 proshade_unsign arrIndex = 0;
835 proshade_double* rotMat =
new proshade_double [9];
837 proshade_double pointHeight, euA, euB, euG, xPk, yPk, zPk, anglPk;
838 proshade_double angTol = std::acos ( 1.0 - axTol );
841 for ( proshade_unsign xIt = 0; xIt < ( dataObj->
getMaxBand() * 2 ); xIt++ )
843 for ( proshade_unsign yIt = 0; yIt < ( dataObj->
getMaxBand() * 2 ); yIt++ )
845 for ( proshade_unsign zIt = 0; zIt < ( dataObj->
getMaxBand() * 2 ); zIt++ )
850 if ( pointHeight < heightThres ) {
continue; }
854 static_cast<proshade_signed
> ( yIt ),
static_cast<proshade_signed
> ( zIt ),
860 if ( ( ( std::abs( anglPk ) - angTol ) < std::abs ( angle ) ) && ( ( std::abs( anglPk ) + angTol ) > std::abs ( angle ) ) )
863 const FloatingPoint< proshade_double > lhs1 ( std::max( std::abs( xPk ), std::max( std::abs( yPk ), std::abs( zPk ) ) ) );
864 const FloatingPoint< proshade_double > rhs1 ( std::abs( xPk ) );
865 const FloatingPoint< proshade_double > rhs2 ( std::abs( yPk ) );
866 const FloatingPoint< proshade_double > rhs3 ( std::abs( zPk ) );
867 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( xPk < 0.0 ) ) ||
868 ( lhs1.AlmostEquals ( rhs2 ) && ( yPk < 0.0 ) ) ||
869 ( lhs1.AlmostEquals ( rhs3 ) && ( zPk < 0.0 ) ) )
880 if ( ret < pointHeight ) { ret = pointHeight; }
905 std::vector< proshade_unsign > hlpVec;
909 for ( proshade_unsign pIt = 0; pIt < static_cast<proshade_unsign> ( matchedPeaks->size() ); pIt++ )
916 std::stringstream hlpS;
917 hlpS <<
"Found symmetry C" << fold;
948 std::stringstream hlpSSP;
949 hlpSSP <<
"Searching for missing peaks for symmetry C" << fold;
953 proshade_double heightThreshold = 0.0;
954 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( grp->size() ); grIt++ ) { heightThreshold += peaks->at(grp->at(grIt))[4]; }
955 heightThreshold /=
static_cast<proshade_double
> ( grp->size() );
956 heightThreshold *= 0.5;
959 for ( proshade_unsign misPkIt = 0; misPkIt < static_cast<proshade_unsign> ( missingPeaks->size() ); misPkIt++ )
962 if ( expectedAngles->at(missingPeaks->at(misPkIt)) > M_PI ) {
continue; }
963 if ( expectedAngles->at(missingPeaks->at(misPkIt)) < -M_PI ) {
continue; }
966 proshade_double misHeight =
ProSHADE_internal_symmetry::checkForMissingPeak ( dataObj, peaks->at(grp->at(0))[0], peaks->at(grp->at(0))[1], peaks->at(grp->at(0))[2], expectedAngles->at(missingPeaks->at(misPkIt)), heightThreshold, axErrTolerance );
967 if ( misHeight != 0.0 )
970 proshade_double* hlpP =
new proshade_double [5];
972 hlpP[0] = peaks->at(grp->at(0))[0];
973 hlpP[1] = peaks->at(grp->at(0))[1];
974 hlpP[2] = peaks->at(grp->at(0))[2];
975 hlpP[3] = expectedAngles->at(missingPeaks->at(misPkIt));
1010 bool skipFold =
false;
1011 std::vector< proshade_unsign > matchedPeaks, missingPeaks;
1012 std::vector< proshade_double > expectedAngles;
1013 proshade_double angTolerance = std::acos ( 1.0 - axErrTolerance );
1016 for ( proshade_unsign fIt = 0; fIt < static_cast<proshade_unsign> ( angsToTry->size() ); fIt++ )
1020 for ( proshade_unsign ftIt = 0; ftIt < static_cast<proshade_unsign> ( testedAlready->size() ); ftIt++ ) {
if ( testedAlready->at(ftIt) == angsToTry->at(fIt) ) { skipFold =
true; } }
1021 if ( skipFold ) {
continue; }
1025 if ( axErrToleranceDefault )
1027 angTolerance = std::max ( std::min ( angTolerance, ( ( (M_PI * 2.0) /
static_cast<double> ( angsToTry->at(fIt) ) ) -
1028 ( (M_PI * 2.0) /
static_cast<double> ( angsToTry->at(fIt) + 1 ) ) ) * 2.0 ), 0.02 );
1029 axErrTolerance = std::max ( 1.0 - std::cos ( angTolerance ), 0.0008 );
1033 expectedAngles.clear ( );
1037 matchedPeaks.clear ( );
1038 missingPeaks.clear ( );
1040 &matchedPeaks, &missingPeaks, angTolerance );
1043 if ( consecMatches >= angsToTry->at(fIt) )
1049 if ( (
static_cast<proshade_double
> ( matchedPeaks.size() ) /
static_cast<proshade_double
> ( angsToTry->at(fIt) ) ) >= ( 1.0 - missPeakThres ) )
1053 &expectedAngles, &matchedPeaks, axErrTolerance, verbose ) )
1080 std::stringstream ss;
1081 ss <<
"Detected C" << grp.at(0) <<
" symmetry with following peaks:";
1086 for ( proshade_unsign pkIt = 1; pkIt < static_cast<proshade_unsign> ( grp.size() ); pkIt++ )
1088 std::stringstream SS;
1089 SS <<
" " <<
static_cast<int>( peaks.at(grp.at(pkIt))[0] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(pkIt))[1] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(pkIt))[2] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(pkIt))[3] * 100.0 ) / 100.0 <<
"\t" <<
static_cast<int>( peaks.at(grp.at(pkIt))[4] * 100.0 ) / 100.0;
1106 std::stringstream ss;
1107 ss <<
"Detected " << noSyms <<
" Cyclic symmetries.";
1113 ProSHADE_internal_messages::printWarningMessage ( verbose,
"!!! ProSHADE WARNING !!! Failed to detect any symmetries. If you believe there should be one, you can try decreasing the resolution or checking that the map is centred on the centry of symmetry (or use map centering option in ProSHADE).",
"WS00030" );
1136 proshade_double sumX, sumY, sumZ, sumH;
1137 proshade_signed matchedPos = -1;
1140 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( detected.size() ); symIt++ )
1143 proshade_double* hlpP =
new proshade_double [6];
1147 hlpP[0] =
static_cast<proshade_double
> ( detected.at(symIt).at(0) );
1148 hlpP[4] =
static_cast<proshade_double
> ( ( 2.0 * M_PI ) / hlpP[0] );
1151 sumX = 0.0; sumY = 0.0; sumZ = 0.0; sumH = 0.0;
1152 for ( proshade_unsign pkIt = 1; pkIt < static_cast<proshade_unsign> ( detected.at(symIt).size() ); pkIt++ )
1154 sumX += peaks.at(detected.at(symIt).at(pkIt))[0];
1155 sumY += peaks.at(detected.at(symIt).at(pkIt))[1];
1156 sumZ += peaks.at(detected.at(symIt).at(pkIt))[2];
1157 sumH += peaks.at(detected.at(symIt).at(pkIt))[4];
1159 sumX /=
static_cast<proshade_double
> ( detected.at(symIt).size() - 1 );
1160 sumY /=
static_cast<proshade_double
> ( detected.at(symIt).size() - 1 );
1161 sumZ /=
static_cast<proshade_double
> ( detected.at(symIt).size() - 1 );
1162 sumH /=
static_cast<proshade_double
> ( detected.at(symIt).size() - 1 );
1200 proshade_double dotProduct = 0.0;
1204 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
1207 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
1208 if ( lhs.AlmostEquals ( rhs ) )
1212 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
1213 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
1216 *matchedPos =
static_cast< proshade_signed
> ( symIt );
1219 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
1222 ret->at(symIt)[1] = sym[1];
1223 ret->at(symIt)[2] = sym[2];
1224 ret->at(symIt)[3] = sym[3];
1225 ret->at(symIt)[5] = sym[5];
1251 proshade_double dotProduct = 0.0;
1255 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( ret->size() ); symIt++ )
1258 const FloatingPoint< proshade_double > lhs ( ret->at(symIt)[0] ), rhs ( sym[0] );
1259 if ( lhs.AlmostEquals ( rhs ) )
1263 &ret->at(symIt)[3], &sym[1], &sym[2], &sym[3] );
1264 if ( ( ( 1.0 > ( dotProduct - simThres ) ) && ( 1.0 < ( dotProduct + simThres ) ) ) || ( ( -1.0 > ( dotProduct - simThres ) ) && ( -1.0 < ( dotProduct + simThres ) ) ) )
1267 *matchedPos =
static_cast< proshade_signed
> ( symIt );
1270 if ( ret->at(symIt)[5] >= sym[5] ) {
return (
true ); }
1273 ret->at(symIt)[1] = sym[1];
1274 ret->at(symIt)[2] = sym[2];
1275 ret->at(symIt)[3] = sym[3];
1276 ret->at(symIt)[5] = sym[5];
1277 ret->at(symIt)[6] = fscVal;
1302 std::vector< proshade_double* > ret;
1303 proshade_double dotProduct;
1309 if ( CSymList->size() < 2 ) {
return ( ret ); }
1312 for ( proshade_unsign ax1 = 0; ax1 < static_cast<proshade_unsign> ( CSymList->size() ); ax1++ )
1315 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(ax1)[5] ), rhs1 ( -999.9 );
1316 if ( ( CSymList->at(ax1)[5] < settings->
minSymPeak ) && !( lhs1.AlmostEquals ( rhs1 ) ) ) {
continue; }
1318 for ( proshade_unsign ax2 = 1; ax2 < static_cast<proshade_unsign> ( CSymList->size() ); ax2++ )
1321 if ( ax1 >= ax2 ) {
continue; }
1324 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(ax2)[5] ), rhs2 ( -999.9 );
1325 if ( ( CSymList->at(ax2)[5] < settings->
minSymPeak ) && !( lhs2.AlmostEquals ( rhs2 ) ) ) {
continue; }
1329 &CSymList->at(ax1)[3], &CSymList->at(ax2)[1],
1330 &CSymList->at(ax2)[2], &CSymList->at(ax2)[3] );
1336 if ( CSymList->at(ax1)[0] >= CSymList->at(ax2)[0] )
1340 std::vector< proshade_unsign > DSymInd;
1350 std::vector< proshade_unsign > DSymInd;
1360 std::stringstream hlpSS;
1361 hlpSS <<
"Detected " << ret.size() <<
" D symmetries.";
1383 proshade_double* hlpP =
new proshade_double [14];
1387 hlpP[0] = CSymList->at(axisOne)[0];
1388 hlpP[1] = CSymList->at(axisOne)[1];
1389 hlpP[2] = CSymList->at(axisOne)[2];
1390 hlpP[3] = CSymList->at(axisOne)[3];
1391 hlpP[4] = CSymList->at(axisOne)[4];
1392 hlpP[5] = CSymList->at(axisOne)[5];
1393 hlpP[6] = CSymList->at(axisOne)[6];
1394 hlpP[7] = CSymList->at(axisTwo)[0];
1395 hlpP[8] = CSymList->at(axisTwo)[1];
1396 hlpP[9] = CSymList->at(axisTwo)[2];
1397 hlpP[10] = CSymList->at(axisTwo)[3];
1398 hlpP[11] = CSymList->at(axisTwo)[4];
1399 hlpP[12] = CSymList->at(axisTwo)[5];
1400 hlpP[13] = CSymList->at(axisTwo)[6];
1422 std::vector< proshade_double* > ret;
1438 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
1440 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
1446 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
1447 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
1448 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
1449 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
1450 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
1451 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
1452 if ( ( lhs1.AlmostEquals ( rhs1 ) ) &&
1453 ( lhs2.AlmostEquals ( rhs2 ) ) &&
1454 ( lhs3.AlmostEquals ( rhs3 ) ) &&
1455 ( lhs4.AlmostEquals ( rhs4 ) ) &&
1456 ( lhs5.AlmostEquals ( rhs5 ) ) &&
1457 ( lhs6.AlmostEquals ( rhs6 ) ) )
1488 std::vector< proshade_unsign > C3List;
1489 proshade_double dotProduct;
1492 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
1494 const FloatingPoint< proshade_double > lhs ( CSymList->at(cSym)[0] ), rhs ( 3.0 );
1499 for ( proshade_unsign c31 = 0; c31 < static_cast<proshade_unsign> ( C3List.size() ); c31++ )
1501 for ( proshade_unsign c32 = 1; c32 < static_cast<proshade_unsign> ( C3List.size() ); c32++ )
1504 if ( c31 >= c32 ) {
continue; }
1507 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] );
1510 if ( ( ( 1.0 / 3.0 ) > ( dotProduct - axErr ) ) && ( ( 1.0 / 3.0 ) < ( dotProduct + axErr ) ) )
1538 std::vector< proshade_unsign > C3PossibilitiesHlp;
1539 std::vector< std::vector< proshade_unsign > > C3Possibilities;
1546 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
1549 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
1555 groupMatched =
false;
1556 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
1569 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
1570 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; } } }
1572 if ( C3Possibilities.at(maxGrp).size() == 4 )
1575 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)) ); }
1608 bool allAnglesMet =
true;
1609 proshade_double dotProduct;
1614 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
1618 if ( ( ( 1.0 > ( dotProduct - axErr ) ) && ( 1.0 < ( dotProduct + axErr ) ) ) || ( ( -1.0 > ( dotProduct - axErr ) ) && ( -1.0 < ( dotProduct + axErr ) ) ) )
1620 if ( sym[5] > CSymList->at(grp->at(mIt))[5] )
1626 allAnglesMet =
false;
1627 return ( allAnglesMet );
1634 for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( grp->size() ); mIt++ )
1638 if ( ( angle > ( std::abs ( dotProduct ) - axErr ) ) &&
1639 ( angle < ( std::abs ( dotProduct ) + axErr ) ) )
1646 allAnglesMet =
false;
1652 return ( allAnglesMet );
1675 std::vector< proshade_double* > hlpVec;
1676 bool atLeastOne =
false;
1679 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
1681 if (
static_cast<proshade_unsign
> ( possibilities->at(gIt).size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
1685 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( possibilities->size() ); gIt++ )
1688 if ( possibilities->at(gIt).size() < 2 ) {
continue; }
1697 if ( hlpVec.size() > 0 )
1703 for ( proshade_unsign axIt = 0; axIt < static_cast<proshade_unsign> ( hlpVec.size() ); axIt++ )
1718 if ( possibilities->at(gIt).size() == requiredNoAxes ) { atLeastOne =
true; }
1722 return ( atLeastOne );
1735 return ( a[0] < b[0] );
1756 proshade_double ret = 0.0;
1757 proshade_double curSum = 0.0;
1758 proshade_double maxVal = 0.0;
1759 proshade_double angStep = std::acos ( 1.0 - axErr ) / 2;
1760 std::vector< proshade_double* > angVec;
1769 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( std::floor ( ( 2.0 * M_PI / angStep ) /
static_cast< proshade_double
> ( fold ) ) ); iter++ )
1775 for ( proshade_unsign angCmb = 0; angCmb < static_cast<proshade_unsign> ( fold ); angCmb++ )
1781 for ( proshade_unsign angIt = 0; angIt < static_cast<proshade_unsign> ( angVec.size() ); angIt++ )
1783 if ( angVec.at(angIt)[0] < ( (
static_cast< proshade_double
> ( iter ) * angStep ) +
1784 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
continue; }
1785 if ( angVec.at(angIt)[0] > ( ( (
static_cast< proshade_double
> ( iter ) + 1.0 ) * angStep ) +
1786 ( ( 2.0 * M_PI /
static_cast< proshade_double
> ( fold ) ) *
static_cast< proshade_double
> ( angCmb ) ) ) ) {
break; }
1788 if ( angVec.at(angIt)[1] > maxVal ) { maxVal = angVec.at(angIt)[1]; }
1792 curSum /=
static_cast<proshade_double
> ( fold );
1793 if ( ret < curSum ) { ret = curSum; }
1797 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( angVec.size() ); iter++ ) {
delete[] angVec.at(iter); }
1820 proshade_double euA, euB, euG, xPk, yPk, zPk, anglPk;
1821 proshade_double* rotMat =
new proshade_double [9];
1823 proshade_unsign arrIndex;
1824 std::vector< proshade_double* > angVec;
1827 for ( proshade_unsign xIt = 0; xIt < ( dataObj->
getMaxBand() * 2 ); xIt++ )
1829 for ( proshade_unsign yIt = 0; yIt < ( dataObj->
getMaxBand() * 2 ); yIt++ )
1831 for ( proshade_unsign zIt = 0; zIt < ( dataObj->
getMaxBand() * 2 ); zIt++ )
1834 arrIndex = zIt + ( dataObj->
getMaxBand() * 2 ) * ( yIt + ( dataObj->
getMaxBand() * 2 ) * xIt );
1838 static_cast< proshade_signed
> ( yIt ),
static_cast< proshade_signed
> ( zIt ),
1844 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( xPk ), std::max( std::abs ( yPk ), std::abs ( zPk ) ) ) );
1845 const FloatingPoint< proshade_double > rhs1 ( std::abs ( xPk ));
1846 const FloatingPoint< proshade_double > rhs2 ( std::abs ( yPk ) );
1847 const FloatingPoint< proshade_double > rhs3 ( std::abs ( zPk ) );
1848 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( xPk < 0.0 ) ) ||
1849 ( lhs1.AlmostEquals ( rhs2 ) && ( yPk < 0.0 ) ) ||
1850 ( lhs1.AlmostEquals ( rhs3 ) && ( zPk < 0.0 ) ) )
1862 proshade_double* hlpArr =
new proshade_double [2];
1864 hlpArr[0] = anglPk + M_PI;
1898 proshade_double* hlpSym =
new proshade_double [6];
1902 hlpSym[0] =
static_cast<proshade_double
> ( fold );
1906 hlpSym[4] = ( 2.0 * M_PI ) /
static_cast<proshade_double
> ( fold );
1910 for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( axVec->size() ); symIt++ )
1913 const FloatingPoint< proshade_double > lhs1 ( axVec->at(symIt)[0] ), rhs1 ( hlpSym[0] );
1914 if ( lhs1.AlmostEquals ( rhs1 ) )
1917 axVec->at(symIt)[2],
1918 axVec->at(symIt)[3],
1925 if ( axVec->at(symIt)[5] < hlpSym[5] )
1928 delete[] axVec->at(symIt);
1929 axVec->at(symIt) = hlpSym;
1967 if ( grp->size() < 2 ) {
return; }
1970 proshade_double axHeight = 0.0;
1971 proshade_double* symHlp =
new proshade_double[7];
1975 for ( proshade_unsign fAx = 0; fAx < static_cast<proshade_unsign> ( grp->size() ); fAx++ )
1977 for ( proshade_unsign sAx = 1; sAx < static_cast<proshade_unsign> ( grp->size() ); sAx++ )
1980 if ( fAx >= sAx ) {
continue; }
1984 CSymList->at(grp->at(fAx))[2],
1985 CSymList->at(grp->at(fAx))[3],
1986 CSymList->at(grp->at(sAx))[1],
1987 CSymList->at(grp->at(sAx))[2],
1988 CSymList->at(grp->at(sAx))[3], angle, angle );
1991 const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
1992 const FloatingPoint< proshade_double > rhs1 ( std::abs ( solVec.at(0) ) );
1993 const FloatingPoint< proshade_double > rhs2 ( std::abs ( solVec.at(1) ) );
1994 const FloatingPoint< proshade_double > rhs3 ( std::abs ( solVec.at(2) ) );
1995 if ( ( lhs1.AlmostEquals ( rhs1 ) && ( solVec.at(0) < 0.0 ) ) ||
1996 ( lhs1.AlmostEquals ( rhs2 ) && ( solVec.at(1) < 0.0 ) ) ||
1997 ( lhs1.AlmostEquals ( rhs3 ) && ( solVec.at(2) < 0.0 ) ) )
1999 solVec.at(0) *= -1.0;
2000 solVec.at(1) *= -1.0;
2001 solVec.at(2) *= -1.0;
2005 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -1.0;
2017 CSymList->at(grp->at(fAx))[2],
2018 CSymList->at(grp->at(fAx))[3],
2019 CSymList->at(grp->at(sAx))[1],
2020 CSymList->at(grp->at(sAx))[2],
2021 CSymList->at(grp->at(sAx))[3], -angle, -angle );
2024 const FloatingPoint< proshade_double > lhs2 ( std::max ( std::abs ( solVec.at(0) ), std::max( std::abs ( solVec.at(1) ), std::abs ( solVec.at(2) ) ) ) );
2025 const FloatingPoint< proshade_double > rhs4 ( std::abs ( solVec.at(0) ) );
2026 const FloatingPoint< proshade_double > rhs5 ( std::abs ( solVec.at(1) ) );
2027 const FloatingPoint< proshade_double > rhs6 ( std::abs ( solVec.at(2) ) );
2028 if ( ( lhs2.AlmostEquals ( rhs4 ) && ( solVec.at(0) < 0.0 ) ) ||
2029 ( lhs2.AlmostEquals ( rhs5 ) && ( solVec.at(1) < 0.0 ) ) ||
2030 ( lhs2.AlmostEquals ( rhs6 ) && ( solVec.at(2) < 0.0 ) ) )
2032 solVec.at(0) *= -1.0;
2033 solVec.at(1) *= -1.0;
2034 solVec.at(2) *= -1.0;
2038 symHlp[1] = solVec.at(0); symHlp[2] = solVec.at(1); symHlp[3] = solVec.at(2); symHlp[6] = -1.0;
2074 std::vector< proshade_unsign > C3s, prospectiveC2s, C2PossibilitiesHlp;
2075 std::vector< std::vector< proshade_unsign > > C2Possibilities;
2076 proshade_double dotProd;
2084 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
2087 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2090 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2091 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
2095 &CSymList->at(cIt)[1], &CSymList->at(cIt)[2], &CSymList->at(cIt)[3] );
2102 C2Possibilities.clear(); C2PossibilitiesHlp.clear();
2103 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC2s.size() ); cIt++ )
2106 groupMatched =
false;
2107 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C2Possibilities.size() ); gIt++ )
2117 while ( C2Possibilities.size() != 0 )
2123 if ( C2Possibilities.at(0).size() == 3 )
2134 else { C2Possibilities.erase ( C2Possibilities.begin() ); }
2156 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 )
2160 proshade_double dotProduct;
2163 for ( proshade_unsign g1It = 0; g1It < static_cast<proshade_unsign> ( grp1->size() ); g1It++ )
2165 for ( proshade_unsign g2It = 0; g2It < static_cast<proshade_unsign> ( grp2->size() ); g2It++ )
2169 &GrList1->at(grp1->at(g1It))[2],
2170 &GrList1->at(grp1->at(g1It))[3],
2171 &GrList2->at(grp2->at(g2It))[1],
2172 &GrList2->at(grp2->at(g2It))[2],
2173 &GrList2->at(grp2->at(g2It))[3] );
2176 if ( ( angle > ( dotProduct - axErr ) ) && ( angle < ( dotProduct + axErr ) ) )
2202 std::vector< proshade_double* > ret;
2221 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
2223 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
2229 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
2230 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
2231 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
2232 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
2233 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
2234 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
2235 if ( lhs1.AlmostEquals ( rhs1 ) &&
2236 lhs2.AlmostEquals ( rhs2 ) &&
2237 lhs3.AlmostEquals ( rhs3 ) &&
2238 lhs4.AlmostEquals ( rhs4 ) &&
2239 lhs5.AlmostEquals ( rhs5 ) &&
2240 lhs6.AlmostEquals ( rhs6 ) )
2271 std::vector< proshade_unsign > C4List;
2272 proshade_double dotProduct;
2275 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2277 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 4.0 );
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; }
2292 &CSymList->at(C4List.at(c4))[2],
2293 &CSymList->at(C4List.at(c4))[3],
2294 &CSymList->at(cSym)[1],
2295 &CSymList->at(cSym)[2],
2296 &CSymList->at(cSym)[3] );
2299 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( dotProduct - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( dotProduct + axErr ) ) )
2327 std::vector< proshade_unsign > C4PossibilitiesHlp;
2328 std::vector< std::vector< proshade_unsign > > C4Possibilities;
2335 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2338 if ( CSymList->at(cIt)[0] != 4.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
2341 groupMatched =
false;
2342 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C4Possibilities.size() ); gIt++ )
2355 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
2356 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; } } }
2358 if ( C4Possibilities.at(maxGrp).size() == 3 )
2361 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)) ); }
2393 std::vector< proshade_unsign > C4s, prospectiveC3s, C3PossibilitiesHlp;
2394 std::vector< std::vector< proshade_unsign > > C3Possibilities;
2395 proshade_double dotProd;
2403 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( ret->size() ); rIt++ )
2406 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2409 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
2419 C3Possibilities.clear(); C3PossibilitiesHlp.clear();
2420 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( prospectiveC3s.size() ); cIt++ )
2423 groupMatched =
false;
2424 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C3Possibilities.size() ); gIt++ )
2434 while ( C3Possibilities.size() != 0 )
2440 if ( C3Possibilities.at(0).size() == 4 )
2451 else { C3Possibilities.erase ( C3Possibilities.begin() ); }
2475 std::vector< proshade_unsign > prospectiveC2s, retGrp;
2476 proshade_double dotProd;
2477 proshade_unsign noPerpendicular, noSqrtTwo;
2483 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
2486 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
2487 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && ! ( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
2490 noPerpendicular = 0; noSqrtTwo = 0;
2491 for ( proshade_unsign rIt = 0; rIt < 3; rIt++ )
2496 &CSymList->at(cIt)[1],
2497 &CSymList->at(cIt)[2],
2498 &CSymList->at(cIt)[3] );
2500 if ( ( std::abs ( dotProd ) > ( ( 1.0 / sqrt(2.0) ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / sqrt(2.0) ) + axErr ) ) ) { noSqrtTwo += 1;
continue; }
2501 if ( ( std::abs ( dotProd ) > ( 0.0 - axErr ) ) && ( std::abs ( dotProd ) < ( 0.0 + axErr ) ) ) { noPerpendicular += 1;
continue; }
2505 if ( ( noSqrtTwo == 2 ) && ( noPerpendicular == 1 ) )
2513 if ( !
ProSHADE_internal_symmetry::findMissingAxesDual ( &prospectiveC2s, CSymList, ret, &retGrp, 6, axErr, 1, 0.0, 2, 1/sqrt(2.0), 2, dataObj ) )
2519 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
2553 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 )
2556 bool atLeastOne =
false;
2557 std::vector< proshade_double* > prosp;
2558 std::vector< proshade_double > sol;
2561 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
2564 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
2567 CSymList->at(possibilities->at(prIt))[1],
2568 CSymList->at(possibilities->at(prIt))[2],
2569 CSymList->at(possibilities->at(prIt))[3],
2570 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
2574 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
2576 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
2579 if ( rgIt1 == rgIt2 ) {
continue; }
2583 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], angle1, angle2 );
2586 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
2587 if ( prosp.size() == requiredNoAxes ) {
break; }
2591 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3], -angle1, -angle2 );
2594 ProSHADE_internal_symmetry::checkFittingAxisDualAndSave ( retGroup, ret, fold, sol.at(0), sol.at(1), sol.at(2), &prosp, axErr, noMatchesG1, angle1, noMatchesG2, angle2, dataObj );
2595 if ( prosp.size() == requiredNoAxes ) {
break; }
2598 if ( prosp.size() == requiredNoAxes ) {
break; }
2602 if (
static_cast<proshade_unsign
> ( prosp.size() ) == requiredNoAxes )
2605 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
2617 return ( atLeastOne );
2622 for ( proshade_unsign iter =
static_cast<proshade_unsign
> ( possibilities->size() ); iter <
static_cast<proshade_unsign
> ( prosp.size() ); iter++ )
2624 delete[] prosp.at(iter);
2629 return ( atLeastOne );
2648 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 )
2651 proshade_double* symHlp =
new proshade_double[7];
2653 proshade_signed ret = -1;
2656 symHlp[0] =
static_cast<proshade_double
> ( fold );
2660 symHlp[4] = 2.0 * M_PI / symHlp[0];
2661 symHlp[5] = axHeight;
2662 symHlp[6] = averageFSC;
2668 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
2697 proshade_double* symHlp =
new proshade_double[7];
2699 proshade_signed ret = -1;
2702 symHlp[0] =
static_cast<proshade_double
> ( fold );
2706 symHlp[4] = 2.0 * M_PI / symHlp[0];
2707 symHlp[5] = axHeight;
2714 return (
static_cast< proshade_signed
> ( prosp->size() - 1 ) );
2747 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 )
2750 proshade_unsign noG1 = 0;
2751 proshade_unsign noG2 = 0;
2752 proshade_double dotProd = 0.0;
2753 proshade_double axHeight = 0.0;
2756 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
2759 &ret->at(retGroup->at(rIt))[2],
2760 &ret->at(retGroup->at(rIt))[3],
2763 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
2764 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
2768 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) )
2774 if ( axHeight > 0.1 )
2776 proshade_unsign prevProsp =
static_cast<proshade_unsign
> ( prosp->size() );
2779 if (
static_cast<proshade_unsign
> ( prosp->size() ) > prevProsp ) {
return (
true ); }
2780 else {
return (
false ); }
2802 std::vector< proshade_double* > ret;
2825 for ( proshade_unsign csIt = 0; csIt < static_cast<proshade_unsign> ( CSymList->size() ); csIt++ )
2827 for ( proshade_unsign retIt = 0; retIt < static_cast<proshade_unsign> ( ret.size() ); retIt++ )
2829 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(csIt)[0] ), rhs1 ( ret.at(retIt)[0] );
2830 const FloatingPoint< proshade_double > lhs2 ( CSymList->at(csIt)[1] ), rhs2 ( ret.at(retIt)[1] );
2831 const FloatingPoint< proshade_double > lhs3 ( CSymList->at(csIt)[2] ), rhs3 ( ret.at(retIt)[2] );
2832 const FloatingPoint< proshade_double > lhs4 ( CSymList->at(csIt)[3] ), rhs4 ( ret.at(retIt)[3] );
2833 const FloatingPoint< proshade_double > lhs5 ( CSymList->at(csIt)[4] ), rhs5 ( ret.at(retIt)[4] );
2834 const FloatingPoint< proshade_double > lhs6 ( CSymList->at(csIt)[5] ), rhs6 ( ret.at(retIt)[5] );
2835 if ( lhs1.AlmostEquals ( rhs1 ) &&
2836 lhs2.AlmostEquals ( rhs2 ) &&
2837 lhs3.AlmostEquals ( rhs3 ) &&
2838 lhs4.AlmostEquals ( rhs4 ) &&
2839 lhs5.AlmostEquals ( rhs5 ) &&
2840 lhs6.AlmostEquals ( rhs6 ) )
2874 std::vector< std::vector< proshade_double* > > ret;
2886 for (
size_t pIt = 0; pIt < ret.size(); pIt++ )
2919 std::vector< proshade_double* > ret;
2934 for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ret.size() ); retIt++ )
2963 std::vector< proshade_unsign > C5List;
2964 proshade_double dotProduct;
2967 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2969 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 5.0 );
2974 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
2976 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
2979 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
2980 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
2984 &CSymList->at(C5List.at(c5))[2],
2985 &CSymList->at(C5List.at(c5))[3],
2986 &CSymList->at(cSym)[1],
2987 &CSymList->at(cSym)[2],
2988 &CSymList->at(cSym)[3] );
2991 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
3023 std::vector< proshade_unsign > C5PossibilitiesHlp;
3024 std::vector< std::vector< proshade_unsign > > C5Possibilities;
3031 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
3034 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cIt)[0] ), rhs1 ( 5.0 );
3035 if ( !lhs1.AlmostEquals ( rhs1 ) || CSymList->at(cIt)[5] < minPeakHeight ) {
continue; }
3038 groupMatched =
false;
3039 for ( proshade_unsign gIt = 0; gIt < static_cast<proshade_unsign> ( C5Possibilities.size() ); gIt++ )
3052 proshade_double maxHeight = 0.0; proshade_unsign maxGrp = 0;
3053 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; } } }
3055 if ( C5Possibilities.at(maxGrp).size() == 6 )
3058 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)) ); }
3079 std::vector < std::pair< proshade_unsign, proshade_unsign > >
findBestIcosDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
3082 std::vector < std::pair< proshade_unsign, proshade_unsign > > ret;
3083 std::vector< proshade_unsign > C5List;
3084 proshade_double dotProduct;
3087 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 ); } }
3090 for ( proshade_unsign c5 = 0; c5 < static_cast<proshade_unsign> ( C5List.size() ); c5++ )
3092 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3095 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
3096 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
3097 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
3101 &CSymList->at(C5List.at(c5))[2],
3102 &CSymList->at(C5List.at(c5))[3],
3103 &CSymList->at(cSym)[1],
3104 &CSymList->at(cSym)[2],
3105 &CSymList->at(cSym)[3] );
3108 if ( std::abs ( std::abs( std::sqrt ( ( 1.0 + 2.0 / std::sqrt ( 5.0 ) ) / 3.0 ) ) - std::abs( dotProduct ) ) < axErr )
3110 std::pair< proshade_unsign, proshade_unsign > hlp;
3111 hlp.first = C5List.at(c5);
3113 ret.emplace_back ( hlp );
3145 std::vector < std::pair< proshade_unsign, proshade_unsign > > initAxes =
findBestIcosDihedralPair ( CSymList, minPeakHeight, axErr );
3148 for (
size_t pIt = 0; pIt < initAxes.size(); pIt++ )
3157 CSymList->at(initAxes.at(pIt).first)[1],
3158 CSymList->at(initAxes.at(pIt).first)[2],
3159 CSymList->at(initAxes.at(pIt).first)[3] );
3168 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
3169 proshade_double* rotMatHlp =
new proshade_double[9];
3171 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
3183 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.at(pIt).second)[1], 2.0 ) +
3184 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.at(pIt).second)[2], 2.0 ) +
3185 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.at(pIt).second)[3], 2.0 ) );
3188 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
3191 delete[] rotRotModelC3;
3198 proshade_double* rotMat2 =
new proshade_double[9];
3206 std::vector< proshade_double* > hlpAxes;
3207 for ( proshade_unsign iter = 0; iter < icoAx->
getNoAxes ( ); iter++ )
3216 proshade_double* axis =
new proshade_double[7];
3219 axis[0] = icoAx->
getValue ( iter, 0 );
3220 axis[1] = rotAxis[0];
3221 axis[2] = rotAxis[1];
3222 axis[3] = rotAxis[2];
3223 axis[4] = ( 2.0 * M_PI ) / axis[0];
3236 ret->emplace_back ( hlpAxes );
3242 delete[] rotModelC3;
3258 std::pair< proshade_unsign, proshade_unsign >
findBestOctaDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
3261 std::pair< proshade_unsign, proshade_unsign > ret;
3262 std::vector< proshade_unsign > C4List;
3263 proshade_double bestHeightSum = 0.0;
3264 proshade_double dotProduct;
3267 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 ); } }
3270 for ( proshade_unsign c4 = 0; c4 < static_cast<proshade_unsign> ( C4List.size() ); c4++ )
3272 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
3275 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 3.0 );
3276 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
3277 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
3281 &CSymList->at(C4List.at(c4))[2],
3282 &CSymList->at(C4List.at(c4))[3],
3283 &CSymList->at(cSym)[1],
3284 &CSymList->at(cSym)[2],
3285 &CSymList->at(cSym)[3] );
3288 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
3290 if ( bestHeightSum < ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] ) )
3292 bestHeightSum = ( CSymList->at(C4List.at(c4))[5] + CSymList->at(cSym)[5] );
3293 ret.first = C4List.at(c4);
3331 std::pair< proshade_unsign, proshade_unsign > initAxes =
findBestOctaDihedralPair ( CSymList, minPeakHeight, axErr );
3337 CSymList->at(initAxes.first)[1],
3338 CSymList->at(initAxes.first)[2],
3339 CSymList->at(initAxes.first)[3] );
3348 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
3349 proshade_double* rotMatHlp =
new proshade_double[9];
3351 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
3363 curAngDist = std::sqrt ( std::pow ( rotRotModelC3[0] - CSymList->at(initAxes.second)[1], 2.0 ) +
3364 std::pow ( rotRotModelC3[1] - CSymList->at(initAxes.second)[2], 2.0 ) +
3365 std::pow ( rotRotModelC3[2] - CSymList->at(initAxes.second)[3], 2.0 ) );
3368 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
3371 delete[] rotRotModelC3;
3378 proshade_double* rotMat2 =
new proshade_double[9];
3386 for ( proshade_unsign iter = 0; iter < octAx->
getNoAxes ( ); iter++ )
3395 proshade_double* axis =
new proshade_double[7];
3398 axis[0] = octAx->
getValue ( iter, 0 );
3399 axis[1] = rotAxis[0];
3400 axis[2] = rotAxis[1];
3401 axis[3] = rotAxis[2];
3402 axis[4] = ( 2.0 * M_PI ) / axis[0];
3417 delete[] rotModelC3;
3441 std::vector< proshade_unsign > prospectiveC3s, retGrp;
3442 proshade_double dotProd;
3443 proshade_unsign noClose, noAway;
3449 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
3452 if ( CSymList->at(cIt)[0] != 3.0 || CSymList->at(cIt)[0] < minPeakHeight ) {
continue; }
3455 noClose = 0; noAway = 0;
3456 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
3461 &CSymList->at(cIt)[1],
3462 &CSymList->at(cIt)[2],
3463 &CSymList->at(cIt)[3] );
3465 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; }
3466 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; }
3470 if ( ( noClose == 3 ) && ( noAway == 3 ) )
3478 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 ) )
3484 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC3s.size() ); iter++ )
3513 std::vector< proshade_unsign > prospectiveC2s, retGrp;
3514 proshade_double dotProd;
3515 proshade_unsign noClose, noMidway, noAway;
3521 for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSymList->size() ); cIt++ )
3524 const FloatingPoint< proshade_double > lhs999 ( CSymList->at(cIt)[5] ), rhs999 (
static_cast< proshade_double
> ( -999.9 ) );
3525 if ( CSymList->at(cIt)[0] != 2.0 || ( ( CSymList->at(cIt)[5] < minPeakHeight ) && !( lhs999.AlmostEquals( rhs999 ) ) ) ) {
continue; }
3528 noClose = 0; noMidway = 0; noAway = 0;
3529 for ( proshade_unsign rIt = 0; rIt < 6; rIt++ )
3534 &CSymList->at(cIt)[1],
3535 &CSymList->at(cIt)[2],
3536 &CSymList->at(cIt)[3] );
3538 if ( ( std::abs ( dotProd ) > ( ( sqrt ( 3.0 ) / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( sqrt ( 3.0 ) / 2.0 ) + axErr ) ) ) { noAway += 1;
continue; }
3539 if ( ( std::abs ( dotProd ) > ( ( 1.0 / 2.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 1.0 / 2.0 ) + axErr ) ) ) { noMidway += 1;
continue; }
3540 if ( ( std::abs ( dotProd ) > ( ( 0.0 ) - axErr ) ) && ( std::abs ( dotProd ) < ( ( 0.0 ) + axErr ) ) ) { noClose += 1;
continue; }
3544 if ( ( noClose == 2 ) && ( noMidway == 2 ) && ( noAway == 2 ) )
3552 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 ) )
3558 for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( prospectiveC2s.size() ); iter++ )
3593 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 )
3596 bool atLeastOne =
false;
3597 std::vector< proshade_double* > prosp;
3598 std::vector< proshade_double > sol;
3601 if (
static_cast<proshade_unsign
> ( possibilities->size() ) == requiredNoAxes ) { atLeastOne =
true;
return ( atLeastOne ); }
3604 for ( proshade_unsign prIt = 0; prIt < static_cast<proshade_unsign> ( possibilities->size() ); prIt++ )
3607 CSymList->at(possibilities->at(prIt))[1],
3608 CSymList->at(possibilities->at(prIt))[2],
3609 CSymList->at(possibilities->at(prIt))[3],
3610 CSymList->at(possibilities->at(prIt))[5], &prosp, axErr );
3614 for ( proshade_unsign rgIt1 = 0; rgIt1 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt1++ )
3616 for ( proshade_unsign rgIt2 = 0; rgIt2 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt2++ )
3619 if ( rgIt1 == rgIt2 ) {
continue; }
3621 for ( proshade_unsign rgIt3 = 0; rgIt3 < static_cast<proshade_unsign> ( retGroup->size() ); rgIt3++ )
3624 if ( ( rgIt1 == rgIt3 ) || ( rgIt2 == rgIt3 ) ) {
continue; }
3628 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
3629 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], angle1, angle2, angle3 );
3632 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 );
3633 if ( prosp.size() == requiredNoAxes ) {
break; }
3637 ret->at(rgIt2)[1], ret->at(rgIt2)[2], ret->at(rgIt2)[3],
3638 ret->at(rgIt3)[1], ret->at(rgIt3)[2], ret->at(rgIt3)[3], -angle1, -angle2, -angle3 );
3641 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 );
3642 if ( prosp.size() == requiredNoAxes ) {
break; }
3645 if ( prosp.size() == requiredNoAxes ) {
break; }
3648 if ( prosp.size() == requiredNoAxes ) {
break; }
3652 if ( prosp.size() == requiredNoAxes )
3655 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
3666 return ( atLeastOne );
3671 for ( proshade_unsign axIt =
static_cast<proshade_unsign
> ( possibilities->size() ); axIt <
static_cast<proshade_unsign
> ( prosp.size() ); axIt++ )
3673 delete[] prosp.at(axIt);
3678 return ( atLeastOne );
3704 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 )
3707 proshade_unsign noG1 = 0;
3708 proshade_unsign noG2 = 0;
3709 proshade_unsign noG3 = 0;
3710 proshade_double dotProd = 0.0;
3711 proshade_double axHeight = 0.0;
3714 for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( retGroup->size() ); rIt++ )
3717 &ret->at(retGroup->at(rIt))[2],
3718 &ret->at(retGroup->at(rIt))[3],
3721 if ( ( std::abs ( dotProd ) > ( angle1 - axErr ) ) && ( std::abs ( dotProd ) < ( angle1 + axErr ) ) ) { noG1 += 1;
continue; }
3722 if ( ( std::abs ( dotProd ) > ( angle2 - axErr ) ) && ( std::abs ( dotProd ) < ( angle2 + axErr ) ) ) { noG2 += 1;
continue; }
3723 if ( ( std::abs ( dotProd ) > ( angle3 - axErr ) ) && ( std::abs ( dotProd ) < ( angle3 + axErr ) ) ) { noG3 += 1;
continue; }
3727 if ( ( noG1 == noMatchesG1 ) && ( noG2 == noMatchesG2 ) && ( noG3 == noMatchesG3 ) )
3733 if ( axHeight > 0.1 )
3760 std::vector< proshade_double* > ret, tmpHolder;
3761 std::vector< proshade_unsign > testedFolds;
3762 proshade_double symThres;
3763 proshade_unsign foldToTest;
3764 bool foldDone, anyNewSyms =
true;
3767 for ( proshade_unsign prIt = 0; prIt < static_cast< proshade_unsign > ( primes.size() ); prIt++ )
3770 std::stringstream hlpSS;
3771 hlpSS <<
"Searching for prime fold symmetry C" << primes.at(prIt) <<
".";
3775 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, primes.at(prIt), &symThres );
3778 for (
size_t axIt = 0; axIt < prSyms.size(); axIt++ )
3781 if ( prSyms.at(axIt)[5] >= symThres )
3791 delete[] prSyms.at(axIt);
3796 if ( ret.size() < 1 ) {
return ( ret ); }
3799 while ( anyNewSyms )
3805 for ( proshade_unsign axIt1 = 0; axIt1 < static_cast< proshade_unsign > ( ret.size() ); axIt1++ )
3807 for ( proshade_unsign axIt2 = 0; axIt2 < static_cast< proshade_unsign > ( ret.size() ); axIt2++ )
3810 foldToTest =
static_cast< proshade_unsign
> ( ret.at(axIt1)[0] * ret.at(axIt2)[0] );
3815 for ( proshade_unsign fIt = 0; fIt < static_cast< proshade_unsign > ( testedFolds.size() ); fIt++ ) {
if ( testedFolds.at(fIt) == foldToTest ) { foldDone =
true;
break; } }
3816 if ( foldDone ) {
continue; }
3820 std::stringstream hlpSS2;
3821 hlpSS2 <<
"Searching for fold combination of detected folds " << ret.at(axIt1)[0] <<
" and " << ret.at(axIt2)[0] <<
", i.e. C" << foldToTest <<
".";
3825 std::vector< proshade_double* > prSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, foldToTest, &symThres );
3828 for (
size_t newAxIt = 0; newAxIt < prSyms.size(); newAxIt++ )
3830 if ( prSyms.at(newAxIt)[5] >= symThres )
3840 delete[] prSyms.at(newAxIt);
3846 if ( tmpHolder.size() > 0 )
3848 for ( proshade_unsign tmpIt = 0; tmpIt < static_cast< proshade_unsign > ( tmpHolder.size() ); tmpIt++ )
3851 delete[] tmpHolder.at(tmpIt);
3855 tmpHolder.clear ( );
3875 return ( a[5] > b[5] );
3898 proshade_double soughtAngle;
3899 std::vector< proshade_double > allPeakHeights;
3900 std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup* > peakGroups;
3901 std::vector< proshade_double* > ret;
3905 this->sphereMappedRotFun.clear();
3908 for ( proshade_double angIt = 1.0; angIt < static_cast<proshade_double> ( fold ); angIt += 1.0 )
3911 soughtAngle = angIt * ( 2.0 * M_PI /
static_cast<proshade_double
> ( fold ) );
3915 M_PI /
static_cast< proshade_double
> ( this->maxShellBand ),
3916 this->maxShellBand * 2,
3918 static_cast<proshade_unsign
> ( angIt - 1.0 ) ) );
3921 this->sphereMappedRotFun.at(
static_cast<proshade_unsign
> ( angIt - 1.0 ))->interpolateSphereValues ( this->getInvSO3Coeffs ( ) );
3924 this->sphereMappedRotFun.at(
static_cast<proshade_unsign
> ( angIt - 1.0 ))->findAllPeaks (
static_cast< proshade_signed
> ( settings->
peakNeighbours ), &allPeakHeights );
3928 std::stringstream hlpSS;
3929 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.";
3936 std::stringstream hlpSS2;
3937 hlpSS2 <<
"Determined peak threshold " << *peakThres <<
".";
3941 for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); shIt++ )
3943 this->sphereMappedRotFun.at(shIt)->removeSmallPeaks ( *peakThres );
3947 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); sphIt++ )
3950 for ( proshade_unsign pkIt = 0; pkIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().size() ); pkIt++ )
3954 for ( proshade_unsign pkGrpIt = 0; pkGrpIt < static_cast<proshade_unsign> ( peakGroups.size() ); pkGrpIt++ )
3956 if ( peakGroups.at(pkGrpIt)->checkIfPeakBelongs (
static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).first ),
3957 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
3962 if ( !newPeak ) {
continue; }
3966 static_cast< proshade_double
> ( this->sphereMappedRotFun.at(sphIt)->getPeaks().at(pkIt).second ),
3968 this->sphereMappedRotFun.at(sphIt)->getAngularDim() ) );
3973 for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( peakGroups.size() ); grIt++ )
3976 std::stringstream hlpSS3;
3977 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 ";
3978 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( peakGroups.at(grIt)->getSpherePositions().size() ); sphIt++ ) { hlpSS3 << peakGroups.at(grIt)->getSpherePositions().at(sphIt) <<
" ; "; }
3985 delete peakGroups.at(grIt);
4011 std::vector < proshade_unsign > folds;
4013 proshade_double lat, lon;
4014 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
4015 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
4018 for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( ret->size() ); iter++ )
4020 alreadyFound =
false;
4021 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; } }
4027 for ( proshade_unsign foldIt = 0; foldIt < static_cast < proshade_unsign > ( folds.size() ); foldIt++ )
4030 dataObj->sphereMappedRotFun.clear();
4033 for ( proshade_double angIt = 1.0; angIt < static_cast<proshade_double> ( folds.at(foldIt) ); angIt += 1.0 )
4037 M_PI /
static_cast < proshade_double
> ( folds.at(foldIt) ),
4039 angIt * ( 2.0 * M_PI /
static_cast<proshade_double
> ( folds.at(foldIt) ) ),
4040 static_cast<proshade_unsign
> ( angIt - 1.0 ) ) );
4043 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt - 1.0 ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
4047 for ( proshade_unsign axIt = 0; axIt < static_cast< proshade_unsign > ( ret->size() ); axIt++ )
4050 const FloatingPoint< proshade_double > lhs1 ( ret->at(axIt)[0] ), rhs1 (
static_cast< proshade_double
> ( folds.at(foldIt) ) );
4051 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
4054 lat = std::atan2( ret->at(axIt)[2], ret->at(axIt)[1] ) / latSamlUnit;
4055 lon = std::acos ( ret->at(axIt)[3] ) / lonSamlUnit;
4057 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
4058 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
4060 lat = std::round ( lat );
4061 lon = std::round ( lon );
4067 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( dataObj->sphereMappedRotFun.size() ); sphIt++ )
4082 std::vector < proshade_double* > detectedAxis;
4086 if ( detectedAxis.size() > 0 ) { ret->at(axIt)[5] = detectedAxis.at(0)[5]; }
4087 else { ret->at(axIt)[5] = 0.0; }
4090 for ( proshade_unsign i = 0; i < static_cast < proshade_unsign > ( detectedAxis.size() ); i++ ) {
delete detectedAxis.at(i); }
4118 proshade_double height = 0.0;
4119 proshade_double lat, lon;
4120 proshade_double latSamlUnit = ( 2.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
4121 proshade_double lonSamlUnit = ( 1.0 * M_PI ) / (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 );
4124 dataObj->sphereMappedRotFun.clear ( );
4127 for ( proshade_double angIt = 1.0; angIt < fold; angIt += 1.0 )
4133 angIt * ( 2.0 * M_PI / fold ),
4134 static_cast<proshade_unsign
> ( angIt - 1.0 ) ) );
4137 dataObj->sphereMappedRotFun.at(
static_cast < proshade_unsign
> ( angIt - 1.0 ))->interpolateSphereValues ( dataObj->
getInvSO3Coeffs ( ) );
4141 lat = std::atan2( axis[1], axis[0] ) / latSamlUnit;
4142 lon = std::acos ( axis[2] ) / lonSamlUnit;
4144 if ( lat < 0.0 ) { lat += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
4145 if ( lon < 0.0 ) { lon += (
static_cast< proshade_double
> ( dataObj->
maxShellBand ) * 2.0 ); }
4147 lat = std::round ( lat );
4148 lon = std::round ( lon );
4154 for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( dataObj->sphereMappedRotFun.size() ); sphIt++ )
4169 std::vector < proshade_double* > detectedAxis;
4173 if ( detectedAxis.size() > 0 ) { height = detectedAxis.at(0)[5]; }
4174 else { height = 0.0; }
4177 for ( proshade_unsign i = 0; i < static_cast < proshade_unsign > ( detectedAxis.size() ); i++ ) {
delete detectedAxis.at(i); }
4192 std::pair< proshade_unsign, proshade_unsign >
findBestTetraDihedralPair ( std::vector< proshade_double* >* CSymList, proshade_double minPeakHeight, proshade_double axErr )
4195 std::pair< proshade_unsign, proshade_unsign > ret;
4196 std::vector< proshade_unsign > C3List;
4197 proshade_double bestHeightSum = 0.0;
4198 proshade_double dotProduct;
4201 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 ); } }
4204 for ( proshade_unsign c3 = 0; c3 < static_cast<proshade_unsign> ( C3List.size() ); c3++ )
4206 for ( proshade_unsign cSym = 0; cSym < static_cast<proshade_unsign> ( CSymList->size() ); cSym++ )
4209 const FloatingPoint< proshade_double > lhs1 ( CSymList->at(cSym)[0] ), rhs1 ( 2.0 );
4210 if ( !lhs1.AlmostEquals ( rhs1 ) ) {
continue; }
4211 if ( CSymList->at(cSym)[5] < minPeakHeight ) {
continue; }
4215 &CSymList->at(C3List.at(c3))[2],
4216 &CSymList->at(C3List.at(c3))[3],
4217 &CSymList->at(cSym)[1],
4218 &CSymList->at(cSym)[2],
4219 &CSymList->at(cSym)[3] );
4222 if ( ( ( 1.0 / sqrt ( 3.0 ) ) > ( std::abs( dotProduct ) - axErr ) ) && ( ( 1.0 / sqrt ( 3.0 ) ) < ( std::abs( dotProduct ) + axErr ) ) )
4224 if ( bestHeightSum < ( CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5] ) )
4226 bestHeightSum = CSymList->at(C3List.at(c3))[5] + CSymList->at(cSym)[5];
4227 ret.first = C3List.at(c3);
4256 std::vector< proshade_double* > ret;
4271 for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ret.size() ); retIt++ )
4318 CSymList->at(initAxes.first)[1],
4319 CSymList->at(initAxes.first)[2],
4320 CSymList->at(initAxes.first)[3] );
4329 proshade_double bestAng = 0.0, curAngDist, bestAngDist = 999.9;
4330 proshade_double* rotMatHlp =
new proshade_double[9];
4332 for ( proshade_double ang = 0.0; ang < ( M_PI * 2.0 ); ang += 0.002 )
4344 curAngDist = std::sqrt ( std::pow ( rotRotModelC2[0] - CSymList->at(initAxes.second)[1], 2.0 ) +
4345 std::pow ( rotRotModelC2[1] - CSymList->at(initAxes.second)[2], 2.0 ) +
4346 std::pow ( rotRotModelC2[2] - CSymList->at(initAxes.second)[3], 2.0 ) );
4349 if ( curAngDist < bestAngDist ) { bestAngDist = curAngDist; bestAng = ang; }
4352 delete[] rotRotModelC2;
4359 proshade_double* rotMat2 =
new proshade_double[9];
4367 for ( proshade_unsign iter = 0; iter < tetAx->
getNoAxes( ); iter++ )
4376 proshade_double* axis =
new proshade_double[7];
4379 axis[0] = tetAx->
getValue ( iter, 0 );
4380 axis[1] = rotAxis[0];
4381 axis[2] = rotAxis[1];
4382 axis[3] = rotAxis[2];
4383 axis[4] = ( 2.0 * M_PI ) / axis[0];
4398 delete[] rotModelC2;