ProSHADE  0.7.6.1 (AUG 2021)
Protein Shape Detection
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup Class Reference

This class contains peak groups detected in the rotation function mapped spheres. More...

#include <ProSHADE_spheres.hpp>

Public Member Functions

 ProSHADE_rotFun_spherePeakGroup (proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_unsign angDim)
 Constructor for getting empty ProSHADE_rotFun_spherePeakGroup class. More...
 
 ~ProSHADE_rotFun_spherePeakGroup (void)
 Destructor for the ProSHADE_rotFun_spherePeakGroup class. More...
 
bool checkIfPeakBelongs (proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_double cosTol, proshade_signed verbose)
 This function takes a new prospective peak and tests if it belongs to this peak group or not. More...
 
void findCyclicPointGroupsGivenFold (std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals, std::vector< proshade_double * > *detectedCs, bool bicubicInterp, proshade_unsign fold, proshade_signed verbose)
 Function detecting cyclic point groups with a particular fold in a peak group. More...
 
proshade_double getLatFromIndices (void)
 Accessor function for the private variable latFromInds. More...
 
proshade_double getLatToIndices (void)
 Accessor function for the private variable latToInds. More...
 
proshade_double getLonFromIndices (void)
 Accessor function for the private variable lonFromInds. More...
 
proshade_double getLonToIndices (void)
 Accessor function for the private variable lonToInds. More...
 
std::vector< proshade_unsign > getSpherePositions (void)
 Accessor function for the private variable spherePositions. More...
 

Public Attributes

proshade_double latSampling
 
proshade_double lonSampling
 
proshade_unsign dimension
 
proshade_double latFrom
 
proshade_double latTo
 
proshade_double lonFrom
 
proshade_double lonTo
 
proshade_double latFromInds
 
proshade_double latToInds
 
proshade_double lonFromInds
 
proshade_double lonToInds
 
std::vector< proshade_unsign > spherePositions
 
proshade_double * latMinLonMinXYZ
 
proshade_double * latMaxLonMinXYZ
 
proshade_double * latMinLonMaxXYZ
 
proshade_double * latMaxLonMaxXYZ
 

Protected Member Functions

void computeCornerPositions (void)
 This function computes the group corner vectors, saving results into internal variables.
 
proshade_signed angularDistanceWithBorders (proshade_signed origLat, proshade_signed testedLat)
 This function takes two lattitude or longitude positions and finds the smallest distance between them considering the border periodicity. More...
 
void getAllAngleDifferences (std::vector< proshade_double > *angDiffs, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals)
 This function takes all angles present in this peak group and finds the set of unique angle differeces. More...
 
void getAllPossibleFolds (std::vector< proshade_double > *angDiffs, std::vector< proshade_unsign > *foldsToTry)
 This function angle differences and creates a list of folds that may be present in the group. More...
 
void getSpheresFormingFold (proshade_unsign foldToTry, std::vector< proshade_unsign > *spheresFormingFold, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals, proshade_double sphereAngleTolerance)
 This function simply finds the indices of the spheres which form the requested form. More...
 
void getBestIndexForFold (proshade_double *bestPosVal, proshade_double *bestLatInd, proshade_double *bestLonInd, std::vector< proshade_unsign > *spheresFormingFold, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals)
 Function which does simple search through all peak groups indices and saves the index with the highest peak height sum over all spheres. More...
 

Detailed Description

This class contains peak groups detected in the rotation function mapped spheres.

This class codes the object that contains all the information about a single group of peaks found in the set of ProSHADE_rotFun_sphere objects with mapped rotation function values.

Definition at line 128 of file ProSHADE_spheres.hpp.

Constructor & Destructor Documentation

◆ ProSHADE_rotFun_spherePeakGroup()

ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::ProSHADE_rotFun_spherePeakGroup ( proshade_double  lat,
proshade_double  lon,
proshade_unsign  sphPos,
proshade_unsign  angDim 
)

Constructor for getting empty ProSHADE_rotFun_spherePeakGroup class.

This function simply creates an object of the ProSHADE_rotFun_spherePeakGroup class and fills in the initial data.

Parameters
[in]latThe lattitude value of the first peak of the group.
[in]lonThe longitude value of the first peak of the group.
[in]sphPosThe sphere number of the peak.
[in]angDimThe dimensionality of the sphere grid that we are processing.
[out]XData object with all values set and ready to add new data or search for point groups in the supplied peaks.

Definition at line 1026 of file ProSHADE_spheres.cpp.

1027 {
1028  //================================================ Compute the run-specific values
1029  this->dimension = angDim;
1030  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1031  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1032 
1033  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1034  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1035  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1036  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1037  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1038  this->latFromInds = lat;
1039  this->latToInds = lat;
1040  this->lonFromInds = lon;
1041  this->lonToInds = lon;
1042  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1043 
1044  //================================================ Allocate memory for similarity positions
1045  this->latMinLonMinXYZ = new proshade_double[3];
1046  this->latMaxLonMinXYZ = new proshade_double[3];
1047  this->latMinLonMaxXYZ = new proshade_double[3];
1048  this->latMaxLonMaxXYZ = new proshade_double[3];
1049  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1050  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1051  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1052  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1053 
1054  //================================================ Compute corner vectors
1055  this->computeCornerPositions ( );
1056 
1057  //================================================ Done
1058 
1059 }

◆ ~ProSHADE_rotFun_spherePeakGroup()

ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::~ProSHADE_rotFun_spherePeakGroup ( void  )

Destructor for the ProSHADE_rotFun_spherePeakGroup class.

This function releases all memory allocated by the ProSHADE_rotFun_spherePeakGroup object.

Definition at line 1065 of file ProSHADE_spheres.cpp.

1066 {
1067  //================================================ Release the XYZ arrays
1068  delete[] this->latMinLonMinXYZ;
1069  delete[] this->latMaxLonMinXYZ;
1070  delete[] this->latMinLonMaxXYZ;
1071  delete[] this->latMaxLonMaxXYZ;
1072 }

Member Function Documentation

◆ angularDistanceWithBorders()

proshade_signed ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders ( proshade_signed  newAngul,
proshade_signed  currentAngul 
)
protected

This function takes two lattitude or longitude positions and finds the smallest distance between them considering the border periodicity.

Parameters
[in]newAngulThe first lattitude or longitude value.
[in]currentAngulThe second lattitude or longitude value.
[out]retThe smallest distance between the first and the second lattitude or longitude values.

Definition at line 1106 of file ProSHADE_spheres.cpp.

1107 {
1108  //================================================ Initialise variables
1109  proshade_signed smallerAngul = newAngul - static_cast< proshade_signed > ( this->dimension );
1110  proshade_signed largerAngul = newAngul + static_cast< proshade_signed > ( this->dimension );
1111 
1112  //================================================ Find the smallest distance
1113  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1114 
1115  //================================================ Done
1116  return ( ret );
1117 
1118 }

◆ checkIfPeakBelongs()

bool ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::checkIfPeakBelongs ( proshade_double  lat,
proshade_double  lon,
proshade_unsign  sphPos,
proshade_double  cosTol,
proshade_signed  verbose 
)

This function takes a new prospective peak and tests if it belongs to this peak group or not.

This function takes a new peak position in terms of lattitude and longitude and proceeds to convert these to XYZ position. It then checks this XYZ position against this group's "corners" (i.e. the group's lattitude and longitude minimum and maximum borders). If the tested position belongs to the group (i.e. it has small cosine distance to one of the corners), then it is added and the group corners are updated. Otherwise, false is returned and nothing changes in the group.

Parameters
[in]latThe lattitude value of the first peak of the group.
[in]lonThe longitude value of the first peak of the group.
[in]sphPosThe sphere number of the peak.
[in]cosTolThe tolerance for cosine distance similarity to consider the two vectors similar.
[in]verboseHow verbose should the run be? Use -1 if you do not want any standard output output.
[out]resBoolean value signifying if the peak was added.

Definition at line 1134 of file ProSHADE_spheres.cpp.

1135 {
1136  //================================================ Initialise local variables
1137  bool peakAdded = false;
1138  std::stringstream hlpSS;
1139  std::stringstream hlpSS2;
1140 
1141  //================================================ Compute peaks XYZ and its cosine distance to group corners
1142  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1143  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1144  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1145  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1146 
1147  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMinXYZ[0], this->latMinLonMinXYZ[1], this->latMinLonMinXYZ[2], cosTol ) ) { peakAdded = true; hlpSS2 << this->latMinLonMinXYZ[0] << " ; " << this->latMinLonMinXYZ[1] << " ; " << this->latMinLonMinXYZ[2]; }
1148  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMinXYZ[0], this->latMaxLonMinXYZ[1], this->latMaxLonMinXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMinXYZ[0] << " ; " << this->latMaxLonMinXYZ[1] << " ; " << this->latMaxLonMinXYZ[2]; }
1149  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMaxXYZ[0], this->latMinLonMaxXYZ[1], this->latMinLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMinLonMaxXYZ[0] << " ; " << this->latMinLonMaxXYZ[1] << " ; " << this->latMinLonMaxXYZ[2]; }
1150  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMaxXYZ[0], this->latMaxLonMaxXYZ[1], this->latMaxLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMaxXYZ[0] << " ; " << this->latMaxLonMaxXYZ[1] << " ; " << this->latMaxLonMaxXYZ[2]; }
1151 
1152  //================================================ If peak within corners, add it
1153  if ( peakAdded )
1154  {
1155  //============================================ Report progress
1156  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1157  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str() );
1158 
1159  //============================================ Initialise local variables
1160  proshade_signed largerCorner, smallerCorner;
1161  bool latCornersDone = false;
1162  bool lonCornersDone = false;
1163 
1164  //============================================ Check if lattitude boundaries need to be modified
1165  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1166  {
1167  //======================================== Lattitude is outside of group boundaries
1168  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1169  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1170 
1171  if ( smallerCorner < largerCorner )
1172  {
1173  this->latFromInds = lat;
1174  latCornersDone = true;
1175  }
1176  if ( smallerCorner > largerCorner )
1177  {
1178  this->latToInds = lat;
1179  latCornersDone = true;
1180  }
1181  if ( smallerCorner == largerCorner )
1182  {
1183  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1184  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1185  }
1186  }
1187 
1188  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1189  {
1190  //======================================== Lattitude is outside of group boundaries
1191  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1192  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1193 
1194  if ( smallerCorner < largerCorner )
1195  {
1196  this->latFromInds = lat;
1197  latCornersDone = true;
1198  }
1199  if ( smallerCorner > largerCorner )
1200  {
1201  this->latToInds = lat;
1202  latCornersDone = true;
1203  }
1204  if ( smallerCorner == largerCorner )
1205  {
1206  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1207  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1208  }
1209  }
1210 
1211 
1212  //============================================ Check if longitude boundaries need to be modified
1213  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1214  {
1215  //======================================== Lattitude is outside of group boundaries
1216  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1217  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1218 
1219  if ( smallerCorner < largerCorner )
1220  {
1221  this->lonFromInds = lon;
1222  lonCornersDone = true;
1223  }
1224  if ( smallerCorner > largerCorner )
1225  {
1226  this->lonToInds = lon;
1227  lonCornersDone = true;
1228  }
1229  if ( smallerCorner == largerCorner )
1230  {
1231  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1232  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1233  }
1234  }
1235 
1236  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1237  {
1238  //======================================== Lattitude is outside of group boundaries
1239  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1240  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1241 
1242  if ( smallerCorner < largerCorner )
1243  {
1244  this->lonFromInds = lon;
1245  lonCornersDone = true;
1246  }
1247  if ( smallerCorner > largerCorner )
1248  {
1249  this->lonToInds = lon;
1250  lonCornersDone = true;
1251  }
1252  if ( smallerCorner == largerCorner )
1253  {
1254  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1255  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1256  }
1257  }
1258 
1259  //============================================ Modify corner positions
1260  if ( latCornersDone )
1261  {
1262  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1263  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1264  }
1265 
1266  if ( lonCornersDone )
1267  {
1268  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1269  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1270  }
1271 
1272  //============================================ Compute corner vectors
1273  this->computeCornerPositions ( );
1274  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1275  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str() );
1276 
1277  //============================================ If new sphere, add it to the list
1278  bool isSphereNew = true;
1279  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1280  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1281  }
1282 
1283  //================================================ Done
1284  return ( peakAdded );
1285 
1286 }

◆ findCyclicPointGroupsGivenFold()

void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::findCyclicPointGroupsGivenFold ( std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * >  sphereVals,
std::vector< proshade_double * > *  detectedCs,
bool  bicubicInterp,
proshade_unsign  fold,
proshade_signed  verbose 
)

Function detecting cyclic point groups with a particular fold in a peak group.

This function is a simplification of the findCyclicPointGroups function for the cases where the required fold is known. It simply assumes that all the supplied mapped spheres are to be used to find the fold, i.e. that fold-1 is equal to the length of sphereVals. With this assumption, the function can go directly for finding the peak index with highest peak height sum.

At this point, this function can also optionally do bi-cubic interpolation around this index with highest peak sum to try to improve the symmetry axis by searching between the lattitude and longitude indices. Finally, this function will create the ProSHADE formatted array of symmetry group information and save it into the supplied vector, terminating thereafter.

Warning
This function assumes that the supplied sphereVals argument contains only the spheres relating to the required fold and no other spheres - this assumption does not hold if the convertRotationFunction() function was called - consider yourself warned.
Parameters
[in]sphereValsA vector of spheres with mapped rotation function values.
[in]detectedCsA vector of double pointers pointer to which any detected axis will be added in the ProSHADE format - [0] = fold, [1] = x-axis, [2] = y-axis, [3] = z-axis, [4] = angle, [5] = average peak height.
[in]bicubicInterpShould the bicubic interpolation between the peak indices be done?
[in]foldThe fold for which we are searching for cyclic point groups.
[in]verboseThe verbosity of the run.

Definition at line 1362 of file ProSHADE_spheres.cpp.

1363 {
1364  //================================================ Check that this peak group has all the angles
1365  if ( ( fold - 1 ) != spherePositions.size() ) { return ; }
1366 
1367  //================================================ Initialise variables
1368  proshade_double bestPosVal, bestLatInd, bestLonInd;
1369  std::vector< proshade_unsign > spheresFormingFold;
1370 
1371  //================================================ Set all supplied spheres to be required to form the fold
1372  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1373  {
1374  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1375  }
1376 
1377  //================================================ Find the index with the highest peak height sum
1378  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1379 
1380  //================================================ Optimise by bicubic interpolation if required
1381  if ( bicubicInterp )
1382  {
1383  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1384  }
1385 
1386  //================================================ Create ProSHADE symmetry axis array and save it
1387  proshade_double* detectedSymmetry = new proshade_double[7];
1388  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1389 
1390  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1391  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1392  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1393  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1394  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1395  detectedSymmetry[5] = ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 );
1396  detectedSymmetry[6] = -1.0;
1397 
1398  //================================================ Make sure max is positive
1399  const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) );
1400  const FloatingPoint< proshade_double > rhs1 ( std::abs ( detectedSymmetry[1] ) );
1401  const FloatingPoint< proshade_double > rhs2 ( std::abs ( detectedSymmetry[2] ) );
1402  const FloatingPoint< proshade_double > rhs3 ( std::abs ( detectedSymmetry[3] ) );
1403  if ( ( lhs1.AlmostEquals ( rhs1 ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1404  ( lhs1.AlmostEquals ( rhs2 ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1405  ( lhs1.AlmostEquals ( rhs3 ) && ( detectedSymmetry[3] < 0.0 ) ) )
1406  {
1407  detectedSymmetry[1] *= -1.0;
1408  detectedSymmetry[2] *= -1.0;
1409  detectedSymmetry[3] *= -1.0;
1410  detectedSymmetry[4] *= -1.0;
1411  }
1412 
1413  //================================================ Check for decimal underflows. They are not an issue as rounding to zero is fine, but having negative sign to zero will switch the signs and cause problems.
1414  const FloatingPoint< proshade_double > llhs1 ( detectedSymmetry[1] ), llhs2 ( detectedSymmetry[2] ), llhs3 ( detectedSymmetry[3] ), rrhs1 ( 0.0 );
1415  if ( llhs1.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[1] = 0.0; }
1416  if ( llhs2.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[2] = 0.0; }
1417  if ( llhs3.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[3] = 0.0; }
1418 
1419  //================================================ Save detected point group
1420  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1421 
1422  //================================================ Report progress
1423  std::stringstream hlpSS;
1424  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1425  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str() );
1426 
1427  //================================================ Done
1428  return ;
1429 
1430 }

◆ getAllAngleDifferences()

void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences ( std::vector< proshade_double > *  angDiffs,
std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * >  sphereVals 
)
protected

This function takes all angles present in this peak group and finds the set of unique angle differeces.

Parameters
[in]angDiffsA pointer to a vector to which all angle differences will be saved into.
[in]sphereValsA vector of spheres with mapped rotation function values.

Definition at line 1437 of file ProSHADE_spheres.cpp.

1438 {
1439  //================================================ Initialise local variables
1440  std::vector< proshade_double > angs;
1441 
1442  //================================================ Find all present angles
1443  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1444  {
1445  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1446  }
1447 
1448  //================================================ Find all angle differences
1449  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1450  {
1451  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1452  {
1453  //======================================== Use unique combinations only
1454  if ( ang1It >= ang2It ) { continue; }
1455 
1456  //======================================== Add angle difference rounded to 5 decimal places
1457  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1458  }
1459  }
1460 
1461  //================================================ Sort and remove duplicates
1462  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1463  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1464 
1465  //================================================ Done
1466  return ;
1467 
1468 }

◆ getAllPossibleFolds()

void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds ( std::vector< proshade_double > *  angDiffs,
std::vector< proshade_unsign > *  foldsToTry 
)
protected

This function angle differences and creates a list of folds that may be present in the group.

The function starts by taking each detected angle difference and checking how well it divides a circle (2 Pi). The remainder of this division is then check against a tolerance threshold, which takes into account how many peaks in the rotation function space is the distance off from the theoretical exact value.

Parameters
[in]angDiffsA pointer to a vector containing all the unique angle differences for this peak group.
[in]foldsToTryA pointer to a vector to which the predicted fold to try to find are to be saved into.

Definition at line 1479 of file ProSHADE_spheres.cpp.

1480 {
1481  //================================================ Initialise local variables
1482  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1483  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1484 
1485  //================================================ For each angle difference in the group
1486  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1487  {
1488  //============================================ Find the basis and remainder of the 2pi/dist equation
1489  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1490 
1491  //============================================ If the remainder would be smaller for larger basis, so change the basis
1492  if ( divRem > 0.5 )
1493  {
1494  divRem -= 1.0;
1495  divBasis += 1.0;
1496  }
1497 
1498  //============================================ Remove fold 1, that is not really what we are after here ...
1499  const FloatingPoint< proshade_double > lhs1 ( divBasis ), rhs1 ( 1.0 );
1500  if ( lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1501 
1502  //============================================ Is there enough angles in the group for such a fold?
1503  if ( static_cast< proshade_double > ( this->spherePositions.size() ) < ( divBasis - 1.0 ) ) { continue; }
1504 
1505  //============================================ Determine errors on peaks and on folds
1506  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1507  angTolerance = std::abs( symmErr / peakErr );
1508  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1509 
1510  //============================================ Is remainder small enough?
1511  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1512  {
1513  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1514  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1515  {
1516  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1517  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis - 1 ) );
1518  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis + 1 ) );
1519  }
1520 
1521  //======================================== This fold seems reasonable, save it
1522  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis ) );
1523  }
1524  }
1525 
1526  //================================================ Sort and remove duplicates
1527  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1528  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1529 
1530  //================================================ Done
1531  return ;
1532 
1533 }

◆ getBestIndexForFold()

void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getBestIndexForFold ( proshade_double *  bestPosVal,
proshade_double *  bestLatInd,
proshade_double *  bestLonInd,
std::vector< proshade_unsign > *  spheresFormingFold,
std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * >  sphereVals 
)
protected

Function which does simple search through all peak groups indices and saves the index with the highest peak height sum over all spheres.

Parameters
[in]bestPosValPointer to double where the highest sum of heights will be stored.
[in]bestLatIndPointer to double where the highest values lattitude index will be held.
[in]bestLonIndPointer to double where the highest values longitude index will be held.
[in]spheresFormingFoldA vector pointer to a vector containing the indices of the spheres forming this fold.
[in]sphereValsA vector of spheres with mapped rotation function values.

Definition at line 1590 of file ProSHADE_spheres.cpp.

1591 {
1592  //================================================ Initialise variables
1593  proshade_double curPosVal;
1594  *bestPosVal = -1.0;
1595  if ( this->latFromInds > this->latToInds ) { this->latToInds += static_cast< proshade_double > ( this->dimension ); }
1596  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += static_cast< proshade_double > ( this->dimension ); }
1597 
1598  //================================================ Compute the best average peak height axis for peak indices
1599  for ( proshade_unsign latIt = static_cast< proshade_unsign > ( this->latFromInds ); latIt <= static_cast< proshade_unsign > ( this->latToInds ); latIt++ )
1600  {
1601  //============================================ Deal with boundaries
1602  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= static_cast< proshade_double > ( this->dimension ); }
1603 
1604  for ( proshade_unsign lonIt = static_cast< proshade_unsign > ( this->lonFromInds ); lonIt <= static_cast< proshade_unsign > ( this->lonToInds ); lonIt++ )
1605  {
1606  //======================================== Deal with boundaries
1607  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= static_cast< proshade_double > ( this->dimension ); }
1608 
1609  //======================================== Initialise variables
1610  curPosVal = 1.0;
1611 
1612  //======================================== Find this indices value
1613  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1614  {
1615  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1616  }
1617 
1618  //======================================== If best, save it
1619  if ( curPosVal > *bestPosVal )
1620  {
1621  *bestPosVal = curPosVal;
1622  *bestLatInd = static_cast< proshade_double > ( latIt );
1623  *bestLonInd = static_cast< proshade_double > ( lonIt );
1624  }
1625  }
1626  }
1627 
1628  //================================================ Done
1629  return ;
1630 
1631 }

◆ getLatFromIndices()

proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatFromIndices ( void  )

Accessor function for the private variable latFromInds.

Parameters
[out]latFromIndsThe lattitude index start for the group.

Definition at line 1292 of file ProSHADE_spheres.cpp.

1293 {
1294  //================================================ Done
1295  return ( this->latFromInds );
1296 
1297 }

◆ getLatToIndices()

proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatToIndices ( void  )

Accessor function for the private variable latToInds.

Parameters
[out]latToIndsThe lattitude index end for the group.

Definition at line 1303 of file ProSHADE_spheres.cpp.

1304 {
1305  //================================================ Done
1306  return ( this->latToInds );
1307 
1308 }

◆ getLonFromIndices()

proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonFromIndices ( void  )

Accessor function for the private variable lonFromInds.

Parameters
[out]lonFromIndsThe longitude index start for the group.

Definition at line 1314 of file ProSHADE_spheres.cpp.

1315 {
1316  //================================================ Done
1317  return ( this->lonFromInds );
1318 
1319 }

◆ getLonToIndices()

proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonToIndices ( void  )

Accessor function for the private variable lonToInds.

Parameters
[out]lonToIndsThe longitude index end for the group.

Definition at line 1325 of file ProSHADE_spheres.cpp.

1326 {
1327  //================================================ Done
1328  return ( this->lonToInds );
1329 
1330 }

◆ getSpherePositions()

std::vector< proshade_unsign > ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpherePositions ( void  )

Accessor function for the private variable spherePositions.

Parameters
[out]spherePositionsA vector of all angles (spheres) indices present in this group.

Definition at line 1336 of file ProSHADE_spheres.cpp.

1337 {
1338  //================================================ Done
1339  return ( this->spherePositions );
1340 
1341 }

◆ getSpheresFormingFold()

void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpheresFormingFold ( proshade_unsign  foldToTry,
std::vector< proshade_unsign > *  spheresFormingFold,
std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * >  sphereVals,
proshade_double  sphereAngleTolerance 
)
protected

This function simply finds the indices of the spheres which form the requested form.

Parameters
[in]foldToTryThe value of the fold for which all the required spheres are to be sought.
[in]spheresFormingFoldA pointer to vector to which the sphere indices of spheres forming this fold will be saved into.
[in]sphereValsA vector of spheres with mapped rotation function values.
[in]sphereAngleToleranceThe tolerance for how different the sphere angle can be for the sphere to be still considered.

Definition at line 1542 of file ProSHADE_spheres.cpp.

1543 {
1544  //================================================ Initialise local variables
1545  proshade_double soughtAngle, minSphereVal;
1546  proshade_unsign minSpherePos = 0;
1547 
1548  //================================================ Generate expected angles and check if close-by sphere exists
1549  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1550  {
1551  //============================================ Set variables for the iteration
1552  minSphereVal = 999.9;
1553  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1554 
1555  //============================================ Find the closest sphere passing conditions
1556  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1557  {
1558  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1559  {
1560  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1561  {
1562  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1563  minSpherePos = angsIt;
1564  }
1565  }
1566  }
1567 
1568  //============================================ If no passing sphere, test next fold
1569  const FloatingPoint< proshade_double > lhs1 ( minSphereVal ), rhs1 ( 999.9 );
1570  if ( lhs1.AlmostEquals ( rhs1 ) ) { break; }
1571 
1572  //============================================ Save best position
1573  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1574  }
1575 
1576  //================================================ Done
1577  return ;
1578 
1579 }

The documentation for this class was generated from the following files:
ProSHADE_internal_misc::addToDblPtrVector
void addToDblPtrVector(std::vector< proshade_double * > *vecToAddTo, proshade_double *elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:143
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders
proshade_signed angularDistanceWithBorders(proshade_signed origLat, proshade_signed testedLat)
This function takes two lattitude or longitude positions and finds the smallest distance between them...
Definition: ProSHADE_spheres.cpp:1106
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::computeCornerPositions
void computeCornerPositions(void)
This function computes the group corner vectors, saving results into internal variables.
Definition: ProSHADE_spheres.cpp:1076
ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation
void optimiseAxisBiCubicInterpolation(proshade_double *bestLattitude, proshade_double *bestLongitude, proshade_double *bestSum, std::vector< proshade_unsign > *sphereList, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > *sphereMappedRotFun, proshade_double step=0.05)
This function provides axis optimisation given starting lattitude and longitude indices.
Definition: ProSHADE_maths.cpp:2396
ProSHADE_internal_misc::addToDoubleVector
void addToDoubleVector(std::vector< proshade_double > *vecToAddTo, proshade_double elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:77
ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection
bool vectorOrientationSimilaritySameDirection(proshade_double a1, proshade_double a2, proshade_double a3, proshade_double b1, proshade_double b2, proshade_double b3, proshade_double tolerance=0.1)
This function compares two vectors using cosine distance and decides if they are similar using tolera...
Definition: ProSHADE_maths.cpp:2366
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:67
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getBestIndexForFold
void getBestIndexForFold(proshade_double *bestPosVal, proshade_double *bestLatInd, proshade_double *bestLonInd, std::vector< proshade_unsign > *spheresFormingFold, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals)
Function which does simple search through all peak groups indices and saves the index with the highes...
Definition: ProSHADE_spheres.cpp:1590
ProSHADE_internal_misc::addToUnsignVector
void addToUnsignVector(std::vector< proshade_unsign > *vecToAddTo, proshade_unsign elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:99
ProSHADE_internal_messages::printProgressMessage
void printProgressMessage(proshade_signed verbose, proshade_signed messageLevel, std::string message)
General stdout message printing.
Definition: ProSHADE_messages.cpp:70