ProSHADE  0.7.6.2 (DEC 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, proshade_signed messageShift)
 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, proshade_signed messageShift)
 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 1054 of file ProSHADE_spheres.cpp.

1055 {
1056  //================================================ Compute the run-specific values
1057  this->dimension = angDim;
1058  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1059  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1060 
1061  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1062  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1063  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1064  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1065  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1066  this->latFromInds = lat;
1067  this->latToInds = lat;
1068  this->lonFromInds = lon;
1069  this->lonToInds = lon;
1070  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1071 
1072  //================================================ Allocate memory for similarity positions
1073  this->latMinLonMinXYZ = new proshade_double[3];
1074  this->latMaxLonMinXYZ = new proshade_double[3];
1075  this->latMinLonMaxXYZ = new proshade_double[3];
1076  this->latMaxLonMaxXYZ = new proshade_double[3];
1077  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1078  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1079  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1080  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1081 
1082  //================================================ Compute corner vectors
1083  this->computeCornerPositions ( );
1084 
1085  //================================================ Done
1086 
1087 }

◆ ~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 1093 of file ProSHADE_spheres.cpp.

1094 {
1095  //================================================ Release the XYZ arrays
1096  delete[] this->latMinLonMinXYZ;
1097  delete[] this->latMaxLonMinXYZ;
1098  delete[] this->latMinLonMaxXYZ;
1099  delete[] this->latMaxLonMaxXYZ;
1100 }

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 1134 of file ProSHADE_spheres.cpp.

1135 {
1136  //================================================ Initialise variables
1137  proshade_signed smallerAngul = newAngul - static_cast< proshade_signed > ( this->dimension );
1138  proshade_signed largerAngul = newAngul + static_cast< proshade_signed > ( this->dimension );
1139 
1140  //================================================ Find the smallest distance
1141  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1142 
1143  //================================================ Done
1144  return ( ret );
1145 
1146 }

◆ checkIfPeakBelongs()

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

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.
[in]messageShiftAre we in a subprocess, so that the log should be shifted for this function call? If so, by how much?
[out]resBoolean value signifying if the peak was added.

Definition at line 1163 of file ProSHADE_spheres.cpp.

1164 {
1165  //================================================ Initialise local variables
1166  bool peakAdded = false;
1167  std::stringstream hlpSS;
1168  std::stringstream hlpSS2;
1169 
1170  //================================================ Compute peaks XYZ and its cosine distance to group corners
1171  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1172  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1173  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1174  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1175 
1176  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]; }
1177  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]; }
1178  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]; }
1179  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]; }
1180 
1181  //================================================ If peak within corners, add it
1182  if ( peakAdded )
1183  {
1184  //============================================ Report progress
1185  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1186  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str(), messageShift );
1187 
1188  //============================================ Initialise local variables
1189  proshade_signed largerCorner, smallerCorner;
1190  bool latCornersDone = false;
1191  bool lonCornersDone = false;
1192 
1193  //============================================ Check if lattitude boundaries need to be modified
1194  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1195  {
1196  //======================================== Lattitude is outside of group boundaries
1197  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1198  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1199 
1200  if ( smallerCorner < largerCorner )
1201  {
1202  this->latFromInds = lat;
1203  latCornersDone = true;
1204  }
1205  if ( smallerCorner > largerCorner )
1206  {
1207  this->latToInds = lat;
1208  latCornersDone = true;
1209  }
1210  if ( smallerCorner == largerCorner )
1211  {
1212  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1213  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1214  }
1215  }
1216 
1217  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1218  {
1219  //======================================== Lattitude is outside of group boundaries
1220  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1221  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1222 
1223  if ( smallerCorner < largerCorner )
1224  {
1225  this->latFromInds = lat;
1226  latCornersDone = true;
1227  }
1228  if ( smallerCorner > largerCorner )
1229  {
1230  this->latToInds = lat;
1231  latCornersDone = true;
1232  }
1233  if ( smallerCorner == largerCorner )
1234  {
1235  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1236  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1237  }
1238  }
1239 
1240 
1241  //============================================ Check if longitude boundaries need to be modified
1242  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1243  {
1244  //======================================== Lattitude is outside of group boundaries
1245  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1246  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1247 
1248  if ( smallerCorner < largerCorner )
1249  {
1250  this->lonFromInds = lon;
1251  lonCornersDone = true;
1252  }
1253  if ( smallerCorner > largerCorner )
1254  {
1255  this->lonToInds = lon;
1256  lonCornersDone = true;
1257  }
1258  if ( smallerCorner == largerCorner )
1259  {
1260  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1261  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1262  }
1263  }
1264 
1265  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1266  {
1267  //======================================== Lattitude is outside of group boundaries
1268  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1269  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1270 
1271  if ( smallerCorner < largerCorner )
1272  {
1273  this->lonFromInds = lon;
1274  lonCornersDone = true;
1275  }
1276  if ( smallerCorner > largerCorner )
1277  {
1278  this->lonToInds = lon;
1279  lonCornersDone = true;
1280  }
1281  if ( smallerCorner == largerCorner )
1282  {
1283  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1284  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1285  }
1286  }
1287 
1288  //============================================ Modify corner positions
1289  if ( latCornersDone )
1290  {
1291  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1292  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1293  }
1294 
1295  if ( lonCornersDone )
1296  {
1297  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1298  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1299  }
1300 
1301  //============================================ Compute corner vectors
1302  this->computeCornerPositions ( );
1303  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1304  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str(), messageShift );
1305 
1306  //============================================ If new sphere, add it to the list
1307  bool isSphereNew = true;
1308  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1309  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1310  }
1311 
1312  //================================================ Done
1313  return ( peakAdded );
1314 
1315 }

◆ 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,
proshade_signed  messageShift 
)

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.
[in]messageShiftAre we in a subprocess, so that the log should be shifted for this function call? If so, by how much?

Definition at line 1392 of file ProSHADE_spheres.cpp.

1393 {
1394  //================================================ Check that this peak group has all the angles
1395  if ( ( fold - 1 ) != spherePositions.size() ) { return ; }
1396 
1397  //================================================ Initialise variables
1398  proshade_double bestPosVal, bestLatInd, bestLonInd;
1399  std::vector< proshade_unsign > spheresFormingFold;
1400 
1401  //================================================ Set all supplied spheres to be required to form the fold
1402  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1403  {
1404  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1405  }
1406 
1407  //================================================ Find the index with the highest peak height sum
1408  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1409 
1410  //================================================ Optimise by bicubic interpolation if required
1411  if ( bicubicInterp )
1412  {
1413  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1414  }
1415 
1416  //================================================ Create ProSHADE symmetry axis array and save it
1417  proshade_double* detectedSymmetry = new proshade_double[7];
1418  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1419 
1420  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1421  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1422  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1423  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1424  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1425  detectedSymmetry[5] = ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 );
1426  detectedSymmetry[6] = -std::numeric_limits < proshade_double >::infinity();
1427 
1428  //================================================ Make sure max is positive
1429  const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) );
1430  const FloatingPoint< proshade_double > rhs1 ( std::abs ( detectedSymmetry[1] ) );
1431  const FloatingPoint< proshade_double > rhs2 ( std::abs ( detectedSymmetry[2] ) );
1432  const FloatingPoint< proshade_double > rhs3 ( std::abs ( detectedSymmetry[3] ) );
1433  if ( ( lhs1.AlmostEquals ( rhs1 ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1434  ( lhs1.AlmostEquals ( rhs2 ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1435  ( lhs1.AlmostEquals ( rhs3 ) && ( detectedSymmetry[3] < 0.0 ) ) )
1436  {
1437  detectedSymmetry[1] *= -1.0;
1438  detectedSymmetry[2] *= -1.0;
1439  detectedSymmetry[3] *= -1.0;
1440  detectedSymmetry[4] *= -1.0;
1441  }
1442 
1443  //================================================ 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.
1444  const FloatingPoint< proshade_double > llhs1 ( detectedSymmetry[1] ), llhs2 ( detectedSymmetry[2] ), llhs3 ( detectedSymmetry[3] ), rrhs1 ( 0.0 );
1445  if ( llhs1.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[1] = 0.0; }
1446  if ( llhs2.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[2] = 0.0; }
1447  if ( llhs3.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[3] = 0.0; }
1448 
1449  //================================================ Save detected point group
1450  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1451 
1452  //================================================ Report progress
1453  std::stringstream hlpSS;
1454  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1455  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str(), messageShift );
1456 
1457  //================================================ Done
1458  return ;
1459 
1460 }

◆ 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 1467 of file ProSHADE_spheres.cpp.

1468 {
1469  //================================================ Initialise local variables
1470  std::vector< proshade_double > angs;
1471 
1472  //================================================ Find all present angles
1473  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1474  {
1475  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1476  }
1477 
1478  //================================================ Find all angle differences
1479  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1480  {
1481  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1482  {
1483  //======================================== Use unique combinations only
1484  if ( ang1It >= ang2It ) { continue; }
1485 
1486  //======================================== Add angle difference rounded to 5 decimal places
1487  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1488  }
1489  }
1490 
1491  //================================================ Sort and remove duplicates
1492  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1493  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1494 
1495  //================================================ Done
1496  return ;
1497 
1498 }

◆ 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 1509 of file ProSHADE_spheres.cpp.

1510 {
1511  //================================================ Initialise local variables
1512  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1513  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1514 
1515  //================================================ For each angle difference in the group
1516  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1517  {
1518  //============================================ Find the basis and remainder of the 2pi/dist equation
1519  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1520 
1521  //============================================ If the remainder would be smaller for larger basis, so change the basis
1522  if ( divRem > 0.5 )
1523  {
1524  divRem -= 1.0;
1525  divBasis += 1.0;
1526  }
1527 
1528  //============================================ Remove fold 1, that is not really what we are after here ...
1529  const FloatingPoint< proshade_double > lhs1 ( divBasis ), rhs1 ( 1.0 );
1530  if ( lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1531 
1532  //============================================ Is there enough angles in the group for such a fold?
1533  if ( static_cast< proshade_double > ( this->spherePositions.size() ) < ( divBasis - 1.0 ) ) { continue; }
1534 
1535  //============================================ Determine errors on peaks and on folds
1536  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1537  angTolerance = std::abs( symmErr / peakErr );
1538  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1539 
1540  //============================================ Is remainder small enough?
1541  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1542  {
1543  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1544  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1545  {
1546  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1547  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis - 1 ) );
1548  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis + 1 ) );
1549  }
1550 
1551  //======================================== This fold seems reasonable, save it
1552  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis ) );
1553  }
1554  }
1555 
1556  //================================================ Sort and remove duplicates
1557  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1558  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1559 
1560  //================================================ Done
1561  return ;
1562 
1563 }

◆ 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 1620 of file ProSHADE_spheres.cpp.

1621 {
1622  //================================================ Initialise variables
1623  proshade_double curPosVal;
1624  *bestPosVal = -1.0;
1625  if ( this->latFromInds > this->latToInds ) { this->latToInds += static_cast< proshade_double > ( this->dimension ); }
1626  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += static_cast< proshade_double > ( this->dimension ); }
1627 
1628  //================================================ Compute the best average peak height axis for peak indices
1629  for ( proshade_unsign latIt = static_cast< proshade_unsign > ( this->latFromInds ); latIt <= static_cast< proshade_unsign > ( this->latToInds ); latIt++ )
1630  {
1631  //============================================ Deal with boundaries
1632  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= static_cast< proshade_double > ( this->dimension ); }
1633 
1634  for ( proshade_unsign lonIt = static_cast< proshade_unsign > ( this->lonFromInds ); lonIt <= static_cast< proshade_unsign > ( this->lonToInds ); lonIt++ )
1635  {
1636  //======================================== Deal with boundaries
1637  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= static_cast< proshade_double > ( this->dimension ); }
1638 
1639  //======================================== Initialise variables
1640  curPosVal = 1.0;
1641 
1642  //======================================== Find this indices value
1643  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1644  {
1645  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1646  }
1647 
1648  //======================================== If best, save it
1649  if ( curPosVal > *bestPosVal )
1650  {
1651  *bestPosVal = curPosVal;
1652  *bestLatInd = static_cast< proshade_double > ( latIt );
1653  *bestLonInd = static_cast< proshade_double > ( lonIt );
1654  }
1655  }
1656  }
1657 
1658  //================================================ Done
1659  return ;
1660 
1661 }

◆ 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 1321 of file ProSHADE_spheres.cpp.

1322 {
1323  //================================================ Done
1324  return ( this->latFromInds );
1325 
1326 }

◆ 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 1332 of file ProSHADE_spheres.cpp.

1333 {
1334  //================================================ Done
1335  return ( this->latToInds );
1336 
1337 }

◆ 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 1343 of file ProSHADE_spheres.cpp.

1344 {
1345  //================================================ Done
1346  return ( this->lonFromInds );
1347 
1348 }

◆ 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 1354 of file ProSHADE_spheres.cpp.

1355 {
1356  //================================================ Done
1357  return ( this->lonToInds );
1358 
1359 }

◆ 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 1365 of file ProSHADE_spheres.cpp.

1366 {
1367  //================================================ Done
1368  return ( this->spherePositions );
1369 
1370 }

◆ 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 1572 of file ProSHADE_spheres.cpp.

1573 {
1574  //================================================ Initialise local variables
1575  proshade_double soughtAngle, minSphereVal;
1576  proshade_unsign minSpherePos = 0;
1577 
1578  //================================================ Generate expected angles and check if close-by sphere exists
1579  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1580  {
1581  //============================================ Set variables for the iteration
1582  minSphereVal = 999.9;
1583  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1584 
1585  //============================================ Find the closest sphere passing conditions
1586  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1587  {
1588  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1589  {
1590  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1591  {
1592  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1593  minSpherePos = angsIt;
1594  }
1595  }
1596  }
1597 
1598  //============================================ If no passing sphere, test next fold
1599  const FloatingPoint< proshade_double > lhs1 ( minSphereVal ), rhs1 ( 999.9 );
1600  if ( lhs1.AlmostEquals ( rhs1 ) ) { break; }
1601 
1602  //============================================ Save best position
1603  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1604  }
1605 
1606  //================================================ Done
1607  return ;
1608 
1609 }

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:1134
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:1104
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:2653
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:2623
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:68
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:1620
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, proshade_signed messageShift=0)
General stdout message printing.
Definition: ProSHADE_messages.cpp:71