ProSHADE  0.7.6.6 (JUL 2022)
Protein Shape Detection
ProSHADE_spheres.cpp
Go to the documentation of this file.
1 
23 //============================================ ProSHADE
24 #include "ProSHADE_spheres.hpp"
25 
47 ProSHADE_internal_spheres::ProSHADE_sphere::ProSHADE_sphere ( proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_single xSize, proshade_single ySize, proshade_single zSize, proshade_unsign shOrder, std::vector<proshade_single>* spherePos, bool progressiveMapping, proshade_unsign band, proshade_double* map, proshade_unsign* maxShellBand, proshade_unsign* maxCompBand )
48 {
49  //================================================ Save inputs
50  this->shellOrder = shOrder;
51  this->sphereWidth = static_cast< proshade_single > ( ( spherePos->at(0) + spherePos->at(1) ) / 2.0f );
52  this->sphereRadius = static_cast< proshade_double > ( spherePos->at(shOrder) );
53 
54  //================================================ Determine shell ranges in angstroms
55  proshade_double maxDist = 0.0;
56  if ( shOrder == static_cast<proshade_unsign> ( spherePos->size() - 1 ) ) { maxDist = static_cast<proshade_double> ( spherePos->at(spherePos->size()-1) + ( spherePos->at(1) - spherePos->at(0) ) ); }
57  else { maxDist = static_cast<proshade_double> ( ( spherePos->at(shOrder) + spherePos->at(shOrder+1) ) / 2.0f ); }
58 
59  //================================================ Set the max range
60  this->maxSphereRange = static_cast<proshade_single> ( 2.0 * maxDist );
61 
62  //================================================ Set map sampling rates
63  this->xDimSampling = xSize / static_cast<proshade_single> (xDimMax);
64  this->yDimSampling = ySize / static_cast<proshade_single> (yDimMax);
65  this->zDimSampling = zSize / static_cast<proshade_single> (zDimMax);
66 
67  //================================================ Get maximum circumference
68  proshade_unsign maxCircumference = this->getMaxCircumference ( xDimMax, yDimMax, zDimMax, this->maxSphereRange );
69 
70  //================================================ Get spherical harmonics calculation values
71  if ( progressiveMapping )
72  {
73  this->localBandwidth = std::min ( autoDetermineBandwidth ( maxCircumference ), band );
74  this->localAngRes = this->localBandwidth * 2;
75  }
76  else
77  {
78  this->localBandwidth = band;
79  this->localAngRes = this->localBandwidth * 2;
80  }
81 
82  //================================================ Save the maximum shell band for later
83  if ( *maxShellBand < this->localBandwidth ) { *maxShellBand = this->localBandwidth; *maxCompBand = this->localBandwidth; }
84 
85  //================================================ Allocate memory for sphere mapping
86  this->mappedData = new proshade_double[this->localAngRes * this->localAngRes];
87  ProSHADE_internal_misc::checkMemoryAllocation ( this->mappedData, __FILE__, __LINE__, __func__ );
88 
89  //================================================ Set rotated mapped data
90  this->mappedDataRot = nullptr;
91 
92  //================================================ Map the data to the sphere
93  this->mapData ( map, xDimMax, yDimMax, zDimMax );
94 
95 }
96 
104 {
105  delete[] this->mappedData;
106 
107  if ( this->mappedDataRot != nullptr )
108  {
109  delete[] this->mappedDataRot;
110  }
111 }
112 
122 proshade_unsign ProSHADE_internal_spheres::ProSHADE_sphere::getMaxCircumference ( proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_single maxRange )
123 {
124  //================================================ Find from and to limits on indices
125  proshade_signed xFromInd = static_cast<proshade_signed> ( xDimMax / 2 ) -
126  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
127  proshade_signed yFromInd = static_cast<proshade_signed> ( yDimMax / 2 ) -
128  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
129  proshade_signed zFromInd = static_cast<proshade_signed> ( zDimMax / 2 ) -
130  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
131 
132  proshade_signed xToInd = static_cast<proshade_signed> ( xDimMax / 2 ) +
133  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
134  proshade_signed yToInd = static_cast<proshade_signed> ( yDimMax / 2 ) +
135  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
136  proshade_signed zToInd = static_cast<proshade_signed> ( zDimMax / 2 ) +
137  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
138 
139  //================================================ Check for bounds
140  if ( xFromInd < 0 ) { xFromInd = 0; }
141  if ( yFromInd < 0 ) { yFromInd = 0; }
142  if ( zFromInd < 0 ) { zFromInd = 0; }
143  if ( xToInd > static_cast<proshade_signed> ( xDimMax ) ) { xToInd = static_cast<proshade_signed> ( xDimMax ); }
144  if ( yToInd > static_cast<proshade_signed> ( yDimMax ) ) { yToInd = static_cast<proshade_signed> ( yDimMax ); }
145  if ( zToInd > static_cast<proshade_signed> ( zDimMax ) ) { zToInd = static_cast<proshade_signed> ( zDimMax ); }
146 
147  //================================================ Get dim sizes
148  proshade_unsign xDimSZ = static_cast< proshade_unsign > ( xToInd - xFromInd );
149  proshade_unsign yDimSZ = static_cast< proshade_unsign > ( yToInd - yFromInd );
150  proshade_unsign zDimSZ = static_cast< proshade_unsign > ( zToInd - zFromInd );
151 
152  //================================================ check for too sparse sampling
153  if ( ( xDimSZ == 0 ) && ( yDimSZ == 0 ) && ( zDimSZ == 0 ) ) { xDimSZ = 1; yDimSZ = 1; zDimSZ = 1; }
154 
155  //================================================ Find max and mid dims
156  std::vector<proshade_unsign> dimSizes;
157  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, xDimSZ );
158  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, yDimSZ );
159  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, zDimSZ );
160  std::sort ( dimSizes.begin(), dimSizes.end() );
161  proshade_unsign maxDim = dimSizes.at(2);
162  proshade_unsign midDim = dimSizes.at(1);
163 
164  //================================================ Return max circumference
165  return ( maxDim + midDim );
166 }
167 
179 void ProSHADE_internal_spheres::ProSHADE_sphere::mapData ( proshade_double* map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax )
180 {
181  //================================================ Initialise local variavles
182  proshade_double x, y, z, xRelative, yRelative, zRelative;
183  proshade_signed xBottom, yBottom, zBottom, xTop, yTop, zTop;
184  std::vector<proshade_double> lonCO ( this->localAngRes + 1 );
185  std::vector<proshade_double> latCO ( this->localAngRes + 1 );
186  std::vector<proshade_double> c000 = std::vector<proshade_double> ( 4 );
187  std::vector<proshade_double> c001 = std::vector<proshade_double> ( 4 );
188  std::vector<proshade_double> c010 = std::vector<proshade_double> ( 4 );
189  std::vector<proshade_double> c011 = std::vector<proshade_double> ( 4 );
190  std::vector<proshade_double> c100 = std::vector<proshade_double> ( 4 );
191  std::vector<proshade_double> c101 = std::vector<proshade_double> ( 4 );
192  std::vector<proshade_double> c110 = std::vector<proshade_double> ( 4 );
193  std::vector<proshade_double> c111 = std::vector<proshade_double> ( 4 );
194  std::vector<proshade_double> c00 = std::vector<proshade_double> ( 4 );
195  std::vector<proshade_double> c01 = std::vector<proshade_double> ( 4 );
196  std::vector<proshade_double> c10 = std::vector<proshade_double> ( 4 );
197  std::vector<proshade_double> c11 = std::vector<proshade_double> ( 4 );
198  std::vector<proshade_double> c0 = std::vector<proshade_double> ( 4 );
199  std::vector<proshade_double> c1 = std::vector<proshade_double> ( 4 );
200 
201  //================================================ Find pixelisation cutOffs
202  this->getLongitudeCutoffs ( &lonCO );
203  this->getLattitudeCutoffs ( &latCO );
204 
205  //================================================ Interpolate the map onto this shell
206  for ( unsigned int thIt = 0; thIt < this->localAngRes; thIt++ )
207  {
208  for ( unsigned int phIt = 0; phIt < this->localAngRes; phIt++ )
209  {
210  //======================================== Get grid point x, y and z
211  this->getInterpolationXYZ ( &x, &y, &z, thIt, &lonCO, phIt, &latCO );
212 
213  //======================================== Find 8 closest point around the grid point in indices
214  this->getXYZTopBottoms ( xDimMax, yDimMax, zDimMax, x, y, z, &xBottom, &yBottom, &zBottom, &xTop, &yTop, &zTop );
215 
216  //======================================== Get the 8 closest points interpolation vectors (or set to 0 if out-of-bounds)
217  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zBottom, &c000 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
218  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zTop , &c001 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
219  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zBottom, &c010 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
220  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zTop , &c011 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
221  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zBottom, &c100 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
222  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zTop , &c101 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
223  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zBottom, &c110 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
224  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zTop , &c111 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
225 
226  //======================================== Interpolate along X axis
227  xRelative = ( x - ( static_cast< proshade_double > ( xBottom - static_cast<proshade_signed> ( ( ( xDimMax ) / 2 ) ) ) * static_cast< proshade_double > ( this->xDimSampling ) ) ) / static_cast< proshade_double > ( this->xDimSampling );
228  this->interpolateAlongFirst ( c000, c001, c010, c011, c100, c101, c110, c111, &c00, &c01, &c10, &c11, xRelative );
229 
230  //======================================== Interpolate along Y axis
231  yRelative = ( y - ( static_cast< proshade_double > ( yBottom - static_cast<proshade_signed> ( ( ( yDimMax ) / 2 ) ) ) * static_cast< proshade_double > ( this->yDimSampling ) ) ) / static_cast< proshade_double > ( this->yDimSampling );
232  this->interpolateAlongSecond ( c00, c01, c10, c11, &c0, &c1, yRelative );
233 
234  //======================================== Save the resulting value
235  zRelative = ( z - ( static_cast< proshade_double > ( zBottom - static_cast<proshade_signed> ( ( ( zDimMax ) / 2 ) ) ) * static_cast< proshade_double > ( this->zDimSampling ) ) ) / static_cast< proshade_double > ( this->zDimSampling );
236  this->mappedData[phIt * this->localAngRes + thIt] = ( c0.at(3) * ( 1.0 - zRelative ) ) + ( c1.at(3) * zRelative );
237  }
238  }
239 
240  //================================================ Done
241  return ;
242 
243 }
244 
261 bool ProSHADE_internal_spheres::ProSHADE_sphere::getMapPoint ( proshade_double* map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_signed xPos, proshade_signed yPos, proshade_signed zPos, std::vector<proshade_double>* interpVec )
262 {
263  //================================================ Initialise local variables
264  proshade_signed posIter = zPos + static_cast<proshade_signed> ( zDimMax ) * ( yPos + static_cast<proshade_signed> ( yDimMax ) * xPos );
265 
266  //================================================ Check of out-of-bounds shells
267  if ( ( xPos < 0 ) || ( xPos >= static_cast<proshade_signed> ( xDimMax ) ) ) { return ( false ); }
268  if ( ( yPos < 0 ) || ( yPos >= static_cast<proshade_signed> ( yDimMax ) ) ) { return ( false ); }
269  if ( ( zPos < 0 ) || ( zPos >= static_cast<proshade_signed> ( zDimMax ) ) ) { return ( false ); }
270 
271  //================================================ Get the interpolation values
272  interpVec->at(0) = static_cast<proshade_double> ( xPos ) * static_cast<proshade_double> ( this->xDimSampling );
273  interpVec->at(1) = static_cast<proshade_double> ( yPos ) * static_cast<proshade_double> ( this->yDimSampling );
274  interpVec->at(2) = static_cast<proshade_double> ( zPos ) * static_cast<proshade_double> ( this->zDimSampling );
275  interpVec->at(3) = map[posIter];
276 
277  //================================================ Done
278  return ( true );
279 
280 }
281 
288 void ProSHADE_internal_spheres::ProSHADE_sphere::getLongitudeCutoffs ( std::vector<proshade_double>* lonCO )
289 {
290  //================================================ Get the cut-offs
291  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
292  {
293  lonCO->at(iter) = static_cast<proshade_double> ( iter ) *
294  ( ( static_cast<proshade_double> ( M_PI ) * 2.0 ) / static_cast<proshade_double> ( this->localAngRes ) ) -
295  ( static_cast<proshade_double> ( M_PI ) );
296  }
297 
298  //================================================ Done
299  return ;
300 
301 }
302 
309 void ProSHADE_internal_spheres::ProSHADE_sphere::getLattitudeCutoffs ( std::vector<proshade_double>* latCO )
310 {
311  //================================================ Get the cut-offs
312  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
313  {
314  latCO->at(iter) = ( static_cast<proshade_double> ( iter ) *
315  ( static_cast<proshade_double> ( M_PI ) / static_cast<proshade_double> ( this->localAngRes ) ) -
316  ( static_cast<proshade_double> ( M_PI ) / 2.0 ) );
317  }
318 
319  //================================================ Done
320  return ;
321 
322 }
323 
337 void ProSHADE_internal_spheres::ProSHADE_sphere::getInterpolationXYZ ( proshade_double* x, proshade_double* y, proshade_double* z, proshade_double thetaIt, std::vector<proshade_double>* lonCO, proshade_unsign phiIt, std::vector<proshade_double>* latCO )
338 {
339  //================================================ Compute and save XYZ interpolation positions
340  *x = this->sphereRadius * std::cos ( ( lonCO->at( static_cast<proshade_unsign> ( thetaIt ) ) + lonCO->at( static_cast<proshade_unsign> ( thetaIt+1 ) ) ) / 2.0 ) *
341  std::cos ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
342  *y = this->sphereRadius * std::sin ( ( lonCO->at( static_cast<proshade_unsign> ( thetaIt ) ) + lonCO->at( static_cast<proshade_unsign> ( thetaIt+1 ) ) ) / 2.0 ) *
343  std::cos ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
344  *z = this->sphereRadius * std::sin ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
345 
346  //================================================ Done
347  return ;
348 
349 }
350 
368 void ProSHADE_internal_spheres::ProSHADE_sphere::getXYZTopBottoms ( proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_double x, proshade_double y, proshade_double z, proshade_signed* xBottom, proshade_signed* yBottom, proshade_signed* zBottom, proshade_signed* xTop, proshade_signed* yTop, proshade_signed* zTop )
369 {
370  //================================================ Get the values
371  *xBottom = static_cast< proshade_signed > ( std::floor ( ( x / static_cast< proshade_double > ( this->xDimSampling ) ) ) + ( static_cast< proshade_double > ( xDimMax ) / 2.0 ) );
372  *yBottom = static_cast< proshade_signed > ( std::floor ( ( y / static_cast< proshade_double > ( this->yDimSampling ) ) ) + ( static_cast< proshade_double > ( yDimMax ) / 2.0 ) );
373  *zBottom = static_cast< proshade_signed > ( std::floor ( ( z / static_cast< proshade_double > ( this->zDimSampling ) ) ) + ( static_cast< proshade_double > ( zDimMax ) / 2.0 ) );
374 
375  *xTop = *xBottom + 1;
376  *yTop = *yBottom + 1;
377  *zTop = *zBottom + 1;
378 
379  //================================================ Done
380  return ;
381 
382 }
383 
392 {
393  //================================================ Return the value
394  return ( this->localBandwidth );
395 }
396 
405 {
406  //================================================ Return the value
407  return ( this->localAngRes );
408 }
409 
418 {
419  //================================================ Return the value
420  return ( this->mappedData );
421 }
422 
443 void ProSHADE_internal_spheres::ProSHADE_sphere::interpolateAlongFirst ( std::vector<proshade_double> c000, std::vector<proshade_double> c001, std::vector<proshade_double> c010, std::vector<proshade_double> c011, std::vector<proshade_double> c100, std::vector<proshade_double> c101, std::vector<proshade_double> c110, std::vector<proshade_double> c111, std::vector<proshade_double>* c00, std::vector<proshade_double>* c01, std::vector<proshade_double>* c10, std::vector<proshade_double>* c11, proshade_double xd )
444 {
445  //================================================ Interpolate for the less less point
446  c00->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c000.at(0);
447  c00->at(1) = c000.at(1);
448  c00->at(2) = c000.at(2);
449  c00->at(3) = ( c000.at(3) * ( 1.0 - xd ) ) + ( c100.at(3) * xd );
450 
451  //================================================ Interpolate for the less more point
452  c01->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c001.at(0);
453  c01->at(1) = c001.at(1);
454  c01->at(2) = c001.at(2);
455  c01->at(3) = ( c001.at(3) * ( 1.0 - xd ) ) + ( c101.at(3) * xd );
456 
457  //================================================ Interpolate for the more less point
458  c10->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c010.at(0);
459  c10->at(1) = c010.at(1);
460  c10->at(2) = c010.at(2);
461  c10->at(3) = ( c010.at(3) * ( 1.0 - xd ) ) + ( c110.at(3) * xd );
462 
463  //================================================ Interpolate for the more more point
464  c11->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c011.at(0);
465  c11->at(1) = c011.at(1);
466  c11->at(2) = c011.at(2);
467  c11->at(3) = ( c011.at(3) * ( 1.0 - xd ) ) + ( c111.at(3) * xd );
468 
469  //================================================ Done
470  return ;
471 
472 }
473 
489 void ProSHADE_internal_spheres::ProSHADE_sphere::interpolateAlongSecond ( std::vector<proshade_double> c00, std::vector<proshade_double> c01, std::vector<proshade_double> c10, std::vector<proshade_double> c11, std::vector<proshade_double>* c0, std::vector<proshade_double>* c1, proshade_double yd )
490 {
491  //================================================ Interpolate for the less point
492  c0->at(0) = c00.at(0);
493  c0->at(1) = ( static_cast< proshade_double > ( this->yDimSampling ) * yd ) + c00.at(1);
494  c0->at(2) = c00.at(2);
495  c0->at(3) = ( c00.at(3) * ( 1.0 - yd ) ) + ( c10.at(3) * yd );
496 
497  //================================================ Interpolate for the more point
498  c1->at(0) = c01.at(0);
499  c1->at(1) = ( static_cast< proshade_double > ( this->yDimSampling ) * yd ) + c01.at(1);
500  c1->at(2) = c01.at(2);
501  c1->at(3) = ( c01.at(3) * ( 1.0 - yd ) ) + ( c11.at(3) * yd );
502 
503  //================================================ Done
504  return ;
505 
506 }
507 
516 proshade_unsign ProSHADE_internal_spheres::autoDetermineBandwidth ( proshade_unsign circumference )
517 {
518  //================================================ Determine and return
519  if ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) % 2 == 0 )
520  {
521  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) );
522  }
523  else
524  {
525  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) + 1 );
526  }
527 }
528 
538 proshade_single ProSHADE_internal_spheres::autoDetermineSphereDistances ( proshade_single maxMapRange, proshade_single resolution )
539 {
540  //================================================ Get starting point
541  proshade_single ret = resolution / 2.0f;
542 
543  //================================================ Make sure at least 10 shells will exist
544  while ( std::floor ( maxMapRange / ret ) < 10 )
545  {
546  ret /= 2.0f;
547  }
548 
549  //================================================ Done
550  return ( ret );
551 }
552 
562 proshade_unsign ProSHADE_internal_spheres::autoDetermineIntegrationOrder ( proshade_single maxMapRange, proshade_single sphereDist )
563 {
564  //================================================ Initialise local variables
565  proshade_double sphereDistanceAsFractionOfTotal = static_cast<proshade_double> ( sphereDist / ( maxMapRange / 2.0f ) );
566  proshade_unsign ret = 0;
567 
568  //================================================ Compare to precomputed values
569  for ( proshade_unsign iter = 2; iter < static_cast<proshade_unsign> ( 10000 ); iter++ )
570  {
571  if ( ProSHADE_internal_precomputedVals::glIntMaxDists[iter] >= sphereDistanceAsFractionOfTotal )
572  {
573  ret = iter;
574  }
575  }
576 
577  //================================================ Require a minimum value
578  if ( ret < 5 ) { ret = 5; }
579 
580  //================================================ Return largest passing value
581  return ( ret );
582 
583 }
584 
592 {
593  //================================================ Done
594  return ( this->sphereRadius );
595 
596 }
597 
601 {
602  //================================================ Allocate memory for sphere mapping
603  this->mappedDataRot = nullptr;
604  this->mappedDataRot = new proshade_double[this->localAngRes * this->localAngRes];
605  ProSHADE_internal_misc::checkMemoryAllocation ( this->mappedDataRot, __FILE__, __LINE__, __func__ );
606 
607  //================================================ Done
608  return ;
609 
610 }
611 
617 void ProSHADE_internal_spheres::ProSHADE_sphere::setRotatedMappedData ( proshade_unsign pos, proshade_double value )
618 {
619  //================================================ Set the value to the position
620  this->mappedDataRot[pos] = value;
621 
622  //================================================ Done
623  return ;
624 
625 }
626 
632 {
633  //================================================ Done
634  return ( this->mappedDataRot[pos] );
635 
636 }
637 
650 ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::ProSHADE_rotFun_sphere ( proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_unsign rfDim, proshade_double repAng, proshade_unsign sphNo )
651 {
652  //================================================ Set internal values
653  this->radius = rad;
654  this->angularDim = dim;
655  this->rotFunDim = rfDim;
656  this->radiusMin = this->radius - ( radRange / 2.0 );
657  this->radiusMax = this->radius + ( radRange / 2.0 );
658  this->representedAngle = repAng;
659  this->sphereNumber = sphNo;
660 
661  //================================================ Allocate the axis field
662  this->axesValues = new proshade_double[dim*dim];
663  ProSHADE_internal_misc::checkMemoryAllocation ( this->axesValues, __FILE__, __LINE__, __func__ );
664 
665  //================================================ Fill axis field with zeroes
666  for ( proshade_unsign iter = 0; iter < ( dim * dim ); iter++ ) { this->axesValues[iter] = 0.0; }
667 
668 }
669 
675 {
676  //================================================ Release the allocated memory
677  if ( this->axesValues != nullptr )
678  {
679  delete[] this->axesValues;
680  }
681 }
682 
688 {
689  //================================================ Done
690  return ( this->radius );
691 }
692 
698 {
699  //================================================ Done
700  return ( this->radiusMax );
701 
702 }
703 
709 {
710  //================================================ Done
711  return ( this->rotFunDim );
712 
713 }
714 
720 {
721  //================================================ Done
722  return ( this->angularDim );
723 
724 }
725 
731 {
732  //================================================ Done
733  return ( this->radiusMin );
734 
735 }
736 
742 {
743  //================================================ Done
744  return ( this->representedAngle );
745 
746 }
747 
753 {
754  //================================================ Done
755  return ( this->sphereNumber );
756 
757 }
758 
763 std::vector<std::pair<proshade_unsign,proshade_unsign>> ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getPeaks ( void )
764 {
765  //================================================ Done
766  return ( this->peaks );
767 
768 }
769 
780 {
781  //================================================ Initialise variables
782  proshade_double lonSampling = ( M_PI ) / static_cast< proshade_double > ( this->angularDim );
783  proshade_double latSampling = ( M_PI * 2.0 ) / static_cast< proshade_double > ( this->angularDim );
784 
785  proshade_double lat, lon, cX, cY, cZ, c000, c001, c010, c011, c100, c101, c110, c111, c00, c01, c10, c11, c0, c1, xRelative, yRelative, zRelative, eulerAlpha, eulerBeta, eulerGamma, mapX, mapY, mapZ;
786  proshade_signed xBottom, xTop, yBottom, yTop, zBottom, zTop, mapIndex;
787 
788  //================================================ For each sphere grid position
789  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
790  {
791  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
792  {
793  //======================================== Convert to XYZ position on unit sphere. The radius here is not important, as it does not change the direction of the vector.
794  lon = static_cast<proshade_double> ( lonIt ) * lonSampling;
795  lat = static_cast<proshade_double> ( latIt ) * latSampling;
796  cX = 1.0 * std::sin ( lon ) * std::cos ( lat );
797  cY = 1.0 * std::sin ( lon ) * std::sin ( lat );
798  cZ = 1.0 * std::cos ( lon );
799 
800  //======================================== Convert to ZYZ Euler angles
801  ProSHADE_internal_maths::getEulerZYZFromAngleAxis ( cX, cY, cZ, this->representedAngle, &eulerAlpha, &eulerBeta, &eulerGamma );
802 
803  //======================================== Convert to SOFT map position (decimal, not indices)
804  ProSHADE_internal_maths::getSOFTPositionFromEulerZYZ ( this->rotFunDim / 2, eulerAlpha, eulerBeta, eulerGamma, &mapX, &mapY, &mapZ );
805 
806  //======================================== Find lower and higher points and deal with boundaries
807  xBottom = static_cast< proshade_signed > ( std::floor ( mapX ) ); if ( xBottom < 0 ) { xBottom = 0; } if ( xBottom >= static_cast< proshade_signed > ( this->rotFunDim ) ) { xBottom = static_cast<proshade_signed> ( this->rotFunDim - 2 ); }
808  yBottom = static_cast< proshade_signed > ( std::floor ( mapY ) ); if ( yBottom < 0 ) { yBottom = 0; } if ( yBottom >= static_cast< proshade_signed > ( this->rotFunDim ) ) { yBottom = static_cast<proshade_signed> ( this->rotFunDim - 2 ); }
809  zBottom = static_cast< proshade_signed > ( std::floor ( mapZ ) ); if ( zBottom < 0 ) { zBottom = 0; } if ( zBottom >= static_cast< proshade_signed > ( this->rotFunDim ) ) { zBottom = static_cast<proshade_signed> ( this->rotFunDim - 2 ); }
810  xTop = static_cast< proshade_signed > ( std::ceil ( mapX ) ); if ( xTop < 1 ) { xTop = 1; } if ( xTop >= static_cast< proshade_signed > ( this->rotFunDim ) ) { xTop = static_cast<proshade_signed> ( this->rotFunDim - 1 ); }
811  yTop = static_cast< proshade_signed > ( std::ceil ( mapY ) ); if ( yTop < 1 ) { yTop = 1; } if ( yTop >= static_cast< proshade_signed > ( this->rotFunDim ) ) { yTop = static_cast<proshade_signed> ( this->rotFunDim - 1 ); }
812  zTop = static_cast< proshade_signed > ( std::ceil ( mapZ ) ); if ( zTop < 1 ) { zTop = 1; } if ( zTop >= static_cast< proshade_signed > ( this->rotFunDim ) ) { zTop = static_cast<proshade_signed> ( this->rotFunDim - 1 ); }
813 
814  //======================================== Start X interpolation - bottom, bottom, bottom
815  mapIndex = zBottom + static_cast< proshade_signed > ( this->rotFunDim ) * ( yBottom + static_cast< proshade_signed > ( this->rotFunDim ) * xBottom );
816  c000 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
817 
818  //======================================== X interpolation - bottom, bottom, top
819  mapIndex = zTop + static_cast< proshade_signed > ( this->rotFunDim ) * ( yBottom + static_cast< proshade_signed > ( this->rotFunDim ) * xBottom );
820  c001 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
821 
822  //======================================== X interpolation - bottom, top, bottom
823  mapIndex = zBottom + static_cast< proshade_signed > ( this->rotFunDim ) * ( yTop + static_cast< proshade_signed > ( this->rotFunDim ) * xBottom );
824  c010 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
825 
826  //======================================== X interpolation - bottom, top, top
827  mapIndex = zTop + static_cast< proshade_signed > ( this->rotFunDim ) * ( yTop + static_cast< proshade_signed > ( this->rotFunDim ) * xBottom );
828  c011 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
829 
830  //======================================== X interpolation - top, bottom, bottom
831  mapIndex = zBottom + static_cast< proshade_signed > ( this->rotFunDim ) * ( yBottom + static_cast< proshade_signed > ( this->rotFunDim ) * xTop );
832  c100 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
833 
834  //======================================== X interpolation - top, bottom, top
835  mapIndex = zTop + static_cast< proshade_signed > ( this->rotFunDim ) * ( yBottom + static_cast< proshade_signed > ( this->rotFunDim ) * xTop );
836  c101 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
837 
838  //======================================== X interpolation - top, top, bottom
839  mapIndex = zBottom + static_cast< proshade_signed > ( this->rotFunDim ) * ( yTop + static_cast< proshade_signed > ( this->rotFunDim ) * xTop );
840  c110 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
841 
842  //======================================== X interpolation - top, top, top
843  mapIndex = zTop + static_cast< proshade_signed > ( this->rotFunDim ) * ( yTop + static_cast< proshade_signed > ( this->rotFunDim ) * xTop );
844  c111 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
845 
846  //======================================== Solve for X
847  xRelative = mapX - std::floor( mapX );
848  c00 = ( c000 * ( 1.0 - xRelative ) ) + ( c100 * xRelative );
849  c01 = ( c001 * ( 1.0 - xRelative ) ) + ( c101 * xRelative );
850  c10 = ( c010 * ( 1.0 - xRelative ) ) + ( c110 * xRelative );
851  c11 = ( c011 * ( 1.0 - xRelative ) ) + ( c111 * xRelative );
852 
853  //======================================== Solve for Y
854  yRelative = mapY - std::floor( mapY );
855  c0 = ( c00 * ( 1.0 - yRelative ) ) + ( c10 * yRelative );
856  c1 = ( c01 * ( 1.0 - yRelative ) ) + ( c11 * yRelative );
857 
858  //======================================== Solve for Z
859  zRelative = mapZ - std::floor( mapZ );
860 
861  //======================================== Save result
862  mapIndex = lonIt + ( latIt * static_cast< proshade_signed > ( this->angularDim ) );
863  this->axesValues[mapIndex] = ( c0 * ( 1.0 - zRelative ) ) + ( c1 * zRelative );
864  }
865  }
866  //================================================ Done
867  return ;
868 
869 }
870 
877 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonPosition ( proshade_unsign lattitude, proshade_unsign longitude )
878 {
879  //================================================ Done
880  return ( this->axesValues[longitude + ( lattitude * static_cast<proshade_unsign> ( this->angularDim ) )] );
881 }
882 
891 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonLinearInterpolationPos ( proshade_double lattitude, proshade_double longitude )
892 {
893  //================================================ Initialise variables
894  proshade_double c00, c01, c10, c11, c0, c1, latRelative, lonRelative;
895  proshade_signed latTop, latBottom, lonTop, lonBottom, gridIndex;
896 
897  //================================================ Find lower and higher indices and deal with boundaries
898  latBottom = static_cast< proshade_signed > ( std::floor ( lattitude ) ); if ( latBottom < 0 ) { latBottom += this->angularDim; } if ( latBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { latBottom -= this->angularDim; }
899  lonBottom = static_cast< proshade_signed > ( std::floor ( longitude ) ); if ( lonBottom < 0 ) { lonBottom += this->angularDim; } if ( lonBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { lonBottom -= this->angularDim; }
900  latTop = static_cast< proshade_signed > ( std::ceil ( lattitude ) ); if ( latTop < 0 ) { latTop += this->angularDim; } if ( latTop >= static_cast<proshade_signed> ( this->angularDim ) ) { latTop -= this->angularDim; }
901  lonTop = static_cast< proshade_signed > ( std::ceil ( longitude ) ); if ( lonTop < 0 ) { lonTop += this->angularDim; } if ( lonTop >= static_cast<proshade_signed> ( this->angularDim ) ) { lonTop -= this->angularDim; }
902 
903  //================================================ Interpolate
904  gridIndex = lonBottom + ( latBottom * static_cast< proshade_signed > ( this->angularDim ) );
905  c00 = this->axesValues[gridIndex];
906 
907  gridIndex = lonBottom + ( latTop * static_cast< proshade_signed > ( this->angularDim ) );
908  c01 = this->axesValues[gridIndex];
909 
910  gridIndex = lonTop + ( latBottom * static_cast< proshade_signed > ( this->angularDim ) );
911  c10 = this->axesValues[gridIndex];
912 
913  gridIndex = lonTop + ( latTop * static_cast< proshade_signed > ( this->angularDim ) );
914  c11 = this->axesValues[gridIndex];
915 
916  //================================================ Solve for longitude
917  lonRelative = longitude - std::floor( longitude );
918  c0 = ( c00 * ( 1.0 - lonRelative ) ) + ( c10 * lonRelative );
919  c1 = ( c01 * ( 1.0 - lonRelative ) ) + ( c11 * lonRelative );
920 
921  //================================================ Solve for lattitude
922  latRelative = lattitude - std::floor ( lattitude );
923  proshade_double res = ( c0 * ( 1.0 - latRelative ) ) + ( c1 * latRelative );
924 
925  //================================================ Done
926  return ( res );
927 
928 }
929 
936 std::vector< std::vector< proshade_double > > ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getCopyOfValues ( )
937 {
938  //================================================ Initialise variables
939  std::vector< std::vector< proshade_double > > ret ( this->angularDim );
940  std::vector< proshade_double > retHlp ( this->angularDim, 0.0 );
941 
942  //================================================ Fill in the values
943  for ( size_t lonIt = 0; lonIt < this->angularDim; lonIt++ )
944  {
945  for ( size_t latIt = 0; latIt < this->angularDim; latIt++ )
946  {
947  retHlp.at(latIt) = this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( latIt ), static_cast< proshade_unsign > ( lonIt ) );
948  }
949 
950  ret.at(lonIt) = retHlp;
951  }
952 
953  //================================================ Done
954  return ( ret );
955 
956 }
957 
965 void ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::findAllPeaks ( proshade_signed noSmNeighbours, std::vector< proshade_double >* allHeights )
966 {
967  //================================================ Initialise local variables
968  proshade_double currentHeight;
969  proshade_signed nbLat, nbLon;
970  bool isPeak;
971 
972  //================================================ Find all peaks
973  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
974  {
975  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
976  {
977  //======================================== Initialise peak search
978  currentHeight = this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( latIt ), static_cast< proshade_unsign > ( lonIt ) );
979  isPeak = true;
980 
981  //======================================== Find all neighbours in the same sphere
982  for ( proshade_signed latRound = -noSmNeighbours; latRound <= noSmNeighbours; latRound++ )
983  {
984  for ( proshade_signed lonRound = -noSmNeighbours; lonRound <= noSmNeighbours; lonRound++ )
985  {
986  //================================ Ignore same point
987  if ( latRound == 0 && lonRound == 0 ) { continue; }
988 
989  //================================ Get neighbour height
990  nbLat = latIt + latRound;
991  nbLon = lonIt + lonRound;
992  if ( nbLat < 0 ) { nbLat += this->angularDim; } if ( nbLat >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLat -= this->angularDim; }
993  if ( nbLon < 0 ) { continue; } if ( nbLon >= static_cast<proshade_signed> ( this->angularDim ) ) { continue; }
994 
995  //================================ If this value is larger than the tested one, no peak
996  if ( this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( nbLat ), static_cast< proshade_unsign > ( nbLon ) ) > currentHeight ) { isPeak = false; break; }
997  }
998 
999  if ( !isPeak ) { break; }
1000  }
1001 
1002  if ( isPeak )
1003  {
1004  //==================================== Save!
1005  this->peaks.emplace_back ( std::pair<proshade_unsign,proshade_unsign> ( latIt, lonIt ) );
1006  }
1007  else
1008  {
1009  ProSHADE_internal_misc::addToDoubleVector ( allHeights, currentHeight );
1010  }
1011  }
1012  }
1013 
1014  //================================================ Done
1015  return ;
1016 
1017 }
1018 
1028 {
1029  //================================================ Initialise variables
1030  proshade_double curHeight;
1031  std::vector< proshade_unsign > dels ( 0, static_cast< proshade_unsign > ( this->peaks.size() ) );
1032 
1033  //================================================ For each peak in this sphere
1034  for ( proshade_unsign peakIt = 0; peakIt < static_cast<proshade_unsign> ( this->peaks.size() ); peakIt++ )
1035  {
1036  //============================================ Find the peak height
1037  curHeight = this->getSphereLatLonPosition ( this->peaks.at(peakIt).first, this->peaks.at(peakIt).second );
1038 
1039  //============================================ Should this peak be deleted?
1040  if ( curHeight < peakThres )
1041  {
1043  }
1044  }
1045 
1046  //================================================ Descending sort to avoid changing the order
1047  std::sort ( dels.begin(), dels.end(), std::greater <proshade_unsign>() );
1048 
1049  //================================================ Delete the low peaks
1050  for ( proshade_unsign delIt = 0; delIt < static_cast< proshade_unsign > ( dels.size() ); delIt++ )
1051  {
1052  this->peaks.erase ( this->peaks.begin() + static_cast< long int > ( dels.at(delIt) ) );
1053  }
1054 
1055  //================================================ Done
1056  return ;
1057 
1058 }
1059 
1070 ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::ProSHADE_rotFun_spherePeakGroup ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_unsign angDim )
1071 {
1072  //================================================ Compute the run-specific values
1073  this->dimension = angDim;
1074  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1075  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1076 
1077  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1078  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1079  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1080  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1081  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1082  this->latFromInds = lat;
1083  this->latToInds = lat;
1084  this->lonFromInds = lon;
1085  this->lonToInds = lon;
1086  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1087 
1088  //================================================ Allocate memory for similarity positions
1089  this->latMinLonMinXYZ = new proshade_double[3];
1090  this->latMaxLonMinXYZ = new proshade_double[3];
1091  this->latMinLonMaxXYZ = new proshade_double[3];
1092  this->latMaxLonMaxXYZ = new proshade_double[3];
1093  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1094  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1095  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1096  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1097 
1098  //================================================ Compute corner vectors
1099  this->computeCornerPositions ( );
1100 
1101  //================================================ Done
1102 
1103 }
1104 
1110 {
1111  //================================================ Release the XYZ arrays
1112  delete[] this->latMinLonMinXYZ;
1113  delete[] this->latMaxLonMinXYZ;
1114  delete[] this->latMinLonMaxXYZ;
1115  delete[] this->latMaxLonMaxXYZ;
1116 }
1117 
1121 {
1122  //================================================ Compute corner vectors
1123  this->latMinLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latFrom );
1124  this->latMinLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latFrom );
1125  this->latMinLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1126 
1127  this->latMaxLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latTo );
1128  this->latMaxLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latTo );
1129  this->latMaxLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1130 
1131  this->latMinLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latFrom );
1132  this->latMinLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latFrom );
1133  this->latMinLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1134 
1135  this->latMaxLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latTo );
1136  this->latMaxLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latTo );
1137  this->latMaxLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1138 
1139  //================================================ Done
1140  return ;
1141 
1142 }
1143 
1150 proshade_signed ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders ( proshade_signed newAngul, proshade_signed currentAngul )
1151 {
1152  //================================================ Initialise variables
1153  proshade_signed smallerAngul = newAngul - static_cast< proshade_signed > ( this->dimension );
1154  proshade_signed largerAngul = newAngul + static_cast< proshade_signed > ( this->dimension );
1155 
1156  //================================================ Find the smallest distance
1157  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1158 
1159  //================================================ Done
1160  return ( ret );
1161 
1162 }
1163 
1180 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, proshade_double allowedAngle )
1181 {
1182  //================================================ Initialise local variables
1183  bool peakAdded = false;
1184  std::stringstream hlpSS;
1185  std::stringstream hlpSS2;
1186 
1187  //================================================ Compute peaks XYZ and its cosine distance to group corners
1188  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1189  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1190  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1191  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1192 
1193  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]; }
1194  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]; }
1195  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]; }
1196  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]; }
1197 
1198  //================================================ If group grows over allowedAngle radians, do not add to it
1199  if ( peakAdded )
1200  {
1201  proshade_double lenPos = std::sqrt ( std::pow ( xPos, 2.0 ) + std::pow ( yPos, 2.0 ) + std::pow( zPos, 2.0 ) );
1202  proshade_double minMinPos = std::sqrt ( std::pow ( this->latMinLonMinXYZ[0], 2.0 ) + std::pow ( this->latMinLonMinXYZ[1], 2.0 ) + std::pow( this->latMinLonMinXYZ[2], 2.0 ) );
1203  proshade_double minMaxPos = std::sqrt ( std::pow ( this->latMinLonMaxXYZ[0], 2.0 ) + std::pow ( this->latMinLonMaxXYZ[1], 2.0 ) + std::pow( this->latMinLonMaxXYZ[2], 2.0 ) );
1204  proshade_double maxMinPos = std::sqrt ( std::pow ( this->latMaxLonMinXYZ[0], 2.0 ) + std::pow ( this->latMaxLonMinXYZ[1], 2.0 ) + std::pow( this->latMaxLonMinXYZ[2], 2.0 ) );
1205  proshade_double maxMaxPos = std::sqrt ( std::pow ( this->latMaxLonMaxXYZ[0], 2.0 ) + std::pow ( this->latMaxLonMaxXYZ[1], 2.0 ) + std::pow( this->latMaxLonMaxXYZ[2], 2.0 ) );
1206 
1207  if ( ( std::acos ( ( xPos * this->latMinLonMinXYZ[0] + yPos * this->latMinLonMinXYZ[1] + zPos * this->latMinLonMinXYZ[2] ) / ( lenPos * minMinPos ) ) > allowedAngle ) ||
1208  ( std::acos ( ( xPos * this->latMinLonMaxXYZ[0] + yPos * this->latMinLonMaxXYZ[1] + zPos * this->latMinLonMaxXYZ[2] ) / ( lenPos * minMaxPos ) ) > allowedAngle ) ||
1209  ( std::acos ( ( xPos * this->latMaxLonMinXYZ[0] + yPos * this->latMaxLonMinXYZ[1] + zPos * this->latMaxLonMinXYZ[2] ) / ( lenPos * maxMinPos ) ) > allowedAngle ) ||
1210  ( std::acos ( ( xPos * this->latMaxLonMaxXYZ[0] + yPos * this->latMaxLonMaxXYZ[1] + zPos * this->latMaxLonMaxXYZ[2] ) / ( lenPos * maxMaxPos ) ) > allowedAngle ) )
1211  {
1212  peakAdded = false;
1213  }
1214  }
1215 
1216  //================================================ If peak within corners, add it
1217  if ( peakAdded )
1218  {
1219  //============================================ Report progress
1220  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1221  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str(), messageShift );
1222 
1223  //============================================ Initialise local variables
1224  proshade_signed largerCorner, smallerCorner;
1225  bool latCornersDone = false;
1226  bool lonCornersDone = false;
1227 
1228  //============================================ Check if lattitude boundaries need to be modified
1229  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1230  {
1231  //======================================== Lattitude is outside of group boundaries
1232  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1233  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1234 
1235  if ( smallerCorner < largerCorner )
1236  {
1237  this->latFromInds = lat;
1238  latCornersDone = true;
1239  }
1240  if ( smallerCorner > largerCorner )
1241  {
1242  this->latToInds = lat;
1243  latCornersDone = true;
1244  }
1245  if ( smallerCorner == largerCorner )
1246  {
1247  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1248  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1249  }
1250  }
1251 
1252  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1253  {
1254  //======================================== Lattitude is outside of group boundaries
1255  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1256  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1257 
1258  if ( smallerCorner < largerCorner )
1259  {
1260  this->latFromInds = lat;
1261  latCornersDone = true;
1262  }
1263  if ( smallerCorner > largerCorner )
1264  {
1265  this->latToInds = lat;
1266  latCornersDone = true;
1267  }
1268  if ( smallerCorner == largerCorner )
1269  {
1270  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1271  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1272  }
1273  }
1274 
1275 
1276  //============================================ Check if longitude boundaries need to be modified
1277  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1278  {
1279  //======================================== Lattitude is outside of group boundaries
1280  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1281  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1282 
1283  if ( smallerCorner < largerCorner )
1284  {
1285  this->lonFromInds = lon;
1286  lonCornersDone = true;
1287  }
1288  if ( smallerCorner > largerCorner )
1289  {
1290  this->lonToInds = lon;
1291  lonCornersDone = true;
1292  }
1293  if ( smallerCorner == largerCorner )
1294  {
1295  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1296  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1297  }
1298  }
1299 
1300  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1301  {
1302  //======================================== Lattitude is outside of group boundaries
1303  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1304  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1305 
1306  if ( smallerCorner < largerCorner )
1307  {
1308  this->lonFromInds = lon;
1309  lonCornersDone = true;
1310  }
1311  if ( smallerCorner > largerCorner )
1312  {
1313  this->lonToInds = lon;
1314  lonCornersDone = true;
1315  }
1316  if ( smallerCorner == largerCorner )
1317  {
1318  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1319  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1320  }
1321  }
1322 
1323  //============================================ Modify corner positions
1324  if ( latCornersDone )
1325  {
1326  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1327  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1328  }
1329 
1330  if ( lonCornersDone )
1331  {
1332  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1333  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1334  }
1335 
1336  //============================================ Compute corner vectors
1337  this->computeCornerPositions ( );
1338  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1339  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str(), messageShift );
1340 
1341  //============================================ If new sphere, add it to the list
1342  bool isSphereNew = true;
1343  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1344  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1345  }
1346 
1347  //================================================ Done
1348  return ( peakAdded );
1349 
1350 }
1351 
1357 {
1358  //================================================ Done
1359  return ( this->latFromInds );
1360 
1361 }
1362 
1368 {
1369  //================================================ Done
1370  return ( this->latToInds );
1371 
1372 }
1373 
1379 {
1380  //================================================ Done
1381  return ( this->lonFromInds );
1382 
1383 }
1384 
1390 {
1391  //================================================ Done
1392  return ( this->lonToInds );
1393 
1394 }
1395 
1401 {
1402  //================================================ Done
1403  return ( this->spherePositions );
1404 
1405 }
1406 
1427 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 )
1428 {
1429  //================================================ Initialise variables
1430  proshade_double bestPosVal, bestLatInd, bestLonInd;
1431  std::vector< proshade_unsign > spheresFormingFold;
1432 
1433  //================================================ Set all supplied spheres to be required to form the fold
1434  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1435  {
1436  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1437  }
1438 
1439  //================================================ Find the index with the highest peak height sum
1440  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1441 
1442  //================================================ Optimise by bicubic interpolation if required
1443  if ( bicubicInterp )
1444  {
1445  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1446  }
1447 
1448  //================================================ Create ProSHADE symmetry axis array and save it
1449  proshade_double* detectedSymmetry = new proshade_double[7];
1450  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1451 
1452  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1453  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1454  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1455  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1456  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1457  detectedSymmetry[5] = std::min ( ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 ), 1.0 );
1458  detectedSymmetry[6] = -std::numeric_limits < proshade_double >::infinity();
1459 
1460  //================================================ Make sure max is positive
1461  const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) );
1462  const FloatingPoint< proshade_double > rhs1 ( std::abs ( detectedSymmetry[1] ) );
1463  const FloatingPoint< proshade_double > rhs2 ( std::abs ( detectedSymmetry[2] ) );
1464  const FloatingPoint< proshade_double > rhs3 ( std::abs ( detectedSymmetry[3] ) );
1465  if ( ( lhs1.AlmostEquals ( rhs1 ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1466  ( lhs1.AlmostEquals ( rhs2 ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1467  ( lhs1.AlmostEquals ( rhs3 ) && ( detectedSymmetry[3] < 0.0 ) ) )
1468  {
1469  detectedSymmetry[1] *= -1.0;
1470  detectedSymmetry[2] *= -1.0;
1471  detectedSymmetry[3] *= -1.0;
1472  detectedSymmetry[4] *= -1.0;
1473  }
1474 
1475  //================================================ 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.
1476  const FloatingPoint< proshade_double > llhs1 ( detectedSymmetry[1] ), llhs2 ( detectedSymmetry[2] ), llhs3 ( detectedSymmetry[3] ), rrhs1 ( 0.0 );
1477  if ( llhs1.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[1] = 0.0; }
1478  if ( llhs2.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[2] = 0.0; }
1479  if ( llhs3.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[3] = 0.0; }
1480 
1481  //================================================ Save detected point group
1482  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1483 
1484  //================================================ Report progress
1485  std::stringstream hlpSS;
1486  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1487  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str(), messageShift );
1488 
1489  //================================================ Done
1490  return ;
1491 
1492 }
1493 
1499 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences ( std::vector< proshade_double >* angDiffs, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals )
1500 {
1501  //================================================ Initialise local variables
1502  std::vector< proshade_double > angs;
1503 
1504  //================================================ Find all present angles
1505  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1506  {
1507  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1508  }
1509 
1510  //================================================ Find all angle differences
1511  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1512  {
1513  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1514  {
1515  //======================================== Use unique combinations only
1516  if ( ang1It >= ang2It ) { continue; }
1517 
1518  //======================================== Add angle difference rounded to 5 decimal places
1519  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1520  }
1521  }
1522 
1523  //================================================ Sort and remove duplicates
1524  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1525  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1526 
1527  //================================================ Done
1528  return ;
1529 
1530 }
1531 
1541 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds ( std::vector< proshade_double >* angDiffs, std::vector< proshade_unsign >* foldsToTry )
1542 {
1543  //================================================ Initialise local variables
1544  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1545  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1546 
1547  //================================================ For each angle difference in the group
1548  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1549  {
1550  //============================================ Find the basis and remainder of the 2pi/dist equation
1551  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1552 
1553  //============================================ If the remainder would be smaller for larger basis, so change the basis
1554  if ( divRem > 0.5 )
1555  {
1556  divRem -= 1.0;
1557  divBasis += 1.0;
1558  }
1559 
1560  //============================================ Remove fold 1, that is not really what we are after here ...
1561  const FloatingPoint< proshade_double > lhs1 ( divBasis ), rhs1 ( 1.0 );
1562  if ( lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1563 
1564  //============================================ Is there enough angles in the group for such a fold?
1565  if ( static_cast< proshade_double > ( this->spherePositions.size() ) < ( divBasis - 1.0 ) ) { continue; }
1566 
1567  //============================================ Determine errors on peaks and on folds
1568  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1569  angTolerance = std::abs( symmErr / peakErr );
1570  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1571 
1572  //============================================ Is remainder small enough?
1573  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1574  {
1575  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1576  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1577  {
1578  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1579  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis - 1 ) );
1580  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis + 1 ) );
1581  }
1582 
1583  //======================================== This fold seems reasonable, save it
1584  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis ) );
1585  }
1586  }
1587 
1588  //================================================ Sort and remove duplicates
1589  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1590  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1591 
1592  //================================================ Done
1593  return ;
1594 
1595 }
1596 
1604 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 )
1605 {
1606  //================================================ Initialise local variables
1607  proshade_double soughtAngle, minSphereVal;
1608  proshade_unsign minSpherePos = 0;
1609 
1610  //================================================ Generate expected angles and check if close-by sphere exists
1611  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1612  {
1613  //============================================ Set variables for the iteration
1614  minSphereVal = 999.9;
1615  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1616 
1617  //============================================ Find the closest sphere passing conditions
1618  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1619  {
1620  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1621  {
1622  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1623  {
1624  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1625  minSpherePos = angsIt;
1626  }
1627  }
1628  }
1629 
1630  //============================================ If no passing sphere, test next fold
1631  const FloatingPoint< proshade_double > lhs1 ( minSphereVal ), rhs1 ( 999.9 );
1632  if ( lhs1.AlmostEquals ( rhs1 ) ) { break; }
1633 
1634  //============================================ Save best position
1635  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1636  }
1637 
1638  //================================================ Done
1639  return ;
1640 
1641 }
1642 
1643 
1652 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 )
1653 {
1654  //================================================ Initialise variables
1655  proshade_double curPosVal;
1656  *bestPosVal = -1.0;
1657  if ( this->latFromInds > this->latToInds ) { this->latToInds += static_cast< proshade_double > ( this->dimension ); }
1658  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += static_cast< proshade_double > ( this->dimension ); }
1659 
1660  //================================================ Compute the best average peak height axis for peak indices
1661  for ( proshade_unsign latIt = static_cast< proshade_unsign > ( this->latFromInds ); latIt <= static_cast< proshade_unsign > ( this->latToInds ); latIt++ )
1662  {
1663  //============================================ Deal with boundaries
1664  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= static_cast< proshade_double > ( this->dimension ); }
1665 
1666  for ( proshade_unsign lonIt = static_cast< proshade_unsign > ( this->lonFromInds ); lonIt <= static_cast< proshade_unsign > ( this->lonToInds ); lonIt++ )
1667  {
1668  //======================================== Deal with boundaries
1669  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= static_cast< proshade_double > ( this->dimension ); }
1670 
1671  //======================================== Initialise variables
1672  curPosVal = 1.0;
1673 
1674  //======================================== Find this indices value
1675  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1676  {
1677  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1678  }
1679 
1680  //======================================== If best, save it
1681  if ( curPosVal > *bestPosVal )
1682  {
1683  *bestPosVal = curPosVal;
1684  *bestLatInd = static_cast< proshade_double > ( latIt );
1685  *bestLonInd = static_cast< proshade_double > ( lonIt );
1686  }
1687  }
1688  }
1689 
1690  //================================================ Done
1691  return ;
1692 
1693 }
ProSHADE_internal_spheres::ProSHADE_sphere::getInterpolationXYZ
void getInterpolationXYZ(proshade_double *x, proshade_double *y, proshade_double *z, proshade_double thetaIt, std::vector< proshade_double > *lonCO, proshade_unsign phiIt, std::vector< proshade_double > *latCO)
This function finds the x, y and z positions of supplied shell point.
Definition: ProSHADE_spheres.cpp:337
ProSHADE_internal_maths::getSOFTPositionFromEulerZYZ
void getSOFTPositionFromEulerZYZ(proshade_signed band, proshade_double eulerAlpha, proshade_double eulerBeta, proshade_double eulerGamma, proshade_double *x, proshade_double *y, proshade_double *z)
Function to find the index position in the inverse SOFT map from given Euler angles (ZYZ convention).
Definition: ProSHADE_maths.cpp:991
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_sphere::getLocalBandwidth
proshade_unsign getLocalBandwidth(void)
This function returns the local bandwidth.
Definition: ProSHADE_spheres.cpp:391
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMinRadius
proshade_double getMinRadius(void)
Accessor function for the private variable minimal radius.
Definition: ProSHADE_spheres.cpp:730
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereNumber
proshade_unsign getSphereNumber(void)
Accessor function for the private variable sphere number.
Definition: ProSHADE_spheres.cpp:752
ProSHADE_internal_spheres::ProSHADE_sphere::interpolateAlongFirst
void interpolateAlongFirst(std::vector< proshade_double > c000, std::vector< proshade_double > c001, std::vector< proshade_double > c010, std::vector< proshade_double > c011, std::vector< proshade_double > c100, std::vector< proshade_double > c101, std::vector< proshade_double > c110, std::vector< proshade_double > c111, std::vector< proshade_double > *c00, std::vector< proshade_double > *c01, std::vector< proshade_double > *c10, std::vector< proshade_double > *c11, proshade_double xd)
This function interpolates along the first (X) dimension.
Definition: ProSHADE_spheres.cpp:443
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatToIndices
proshade_double getLatToIndices(void)
Accessor function for the private variable latToInds.
Definition: ProSHADE_spheres.cpp:1367
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::~ProSHADE_rotFun_sphere
~ProSHADE_rotFun_sphere(void)
Destructor for releasing memory from the ProSHADE_rotFun_sphere class.
Definition: ProSHADE_spheres.cpp:674
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:1150
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:1120
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatFromIndices
proshade_double getLatFromIndices(void)
Accessor function for the private variable latFromInds.
Definition: ProSHADE_spheres.cpp:1356
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getCopyOfValues
std::vector< std::vector< proshade_double > > getCopyOfValues(void)
Function for obtaining a copy of all sphere values.
Definition: ProSHADE_spheres.cpp:936
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRepresentedAngle
proshade_double getRepresentedAngle(void)
Accessor function for the private variable represented angle.
Definition: ProSHADE_spheres.cpp:741
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpheresFormingFold
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.
Definition: ProSHADE_spheres.cpp:1604
ProSHADE_internal_spheres::ProSHADE_sphere::getMapPoint
bool getMapPoint(proshade_double *map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_signed xPos, proshade_signed yPos, proshade_signed zPos, std::vector< proshade_double > *interpVec)
This function fills in the interpolation vector for a single map point.
Definition: ProSHADE_spheres.cpp:261
ProSHADE_internal_spheres::ProSHADE_sphere::getRotatedMappedData
proshade_double getRotatedMappedData(proshade_unsign pos)
This function gets the rotated mapped data value for a particular position.
Definition: ProSHADE_spheres.cpp:631
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:2744
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpherePositions
std::vector< proshade_unsign > getSpherePositions(void)
Accessor function for the private variable spherePositions.
Definition: ProSHADE_spheres.cpp:1400
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:2714
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMaxRadius
proshade_double getMaxRadius(void)
Accessor function for the private variable maximum radius.
Definition: ProSHADE_spheres.cpp:697
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds
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.
Definition: ProSHADE_spheres.cpp:1541
ProSHADE_internal_spheres::autoDetermineSphereDistances
proshade_single autoDetermineSphereDistances(proshade_single maxMapRange, proshade_single resolution)
This function determines the sphere distances for sphere mapping.
Definition: ProSHADE_spheres.cpp:538
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::ProSHADE_rotFun_sphere
ProSHADE_rotFun_sphere(proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_unsign rfDim, proshade_double repAng, proshade_unsign sphNo)
Constructor for getting empty ProSHADE_rotFun_sphere class.
Definition: ProSHADE_spheres.cpp:650
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences
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 differece...
Definition: ProSHADE_spheres.cpp:1499
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::findAllPeaks
void findAllPeaks(proshade_signed noSmNeighbours, std::vector< proshade_double > *allHeights)
Function for finding all peaks in the sampling grid.
Definition: ProSHADE_spheres.cpp:965
ProSHADE_internal_spheres::ProSHADE_sphere::getXYZTopBottoms
void getXYZTopBottoms(proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_double x, proshade_double y, proshade_double z, proshade_signed *xBottom, proshade_signed *yBottom, proshade_signed *zBottom, proshade_signed *xTop, proshade_signed *yTop, proshade_signed *zTop)
This function fills in the interpolation vector for a single map point.
Definition: ProSHADE_spheres.cpp:368
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::removeSmallPeaks
void removeSmallPeaks(proshade_double peakThres)
Function for removing peaks with too small height.
Definition: ProSHADE_spheres.cpp:1027
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::checkIfPeakBelongs
bool checkIfPeakBelongs(proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_double cosTol, proshade_signed verbose, proshade_signed messageShift, proshade_double allowedAngle)
This function takes a new prospective peak and tests if it belongs to this peak group or not.
Definition: ProSHADE_spheres.cpp:1180
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::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.
Definition: ProSHADE_spheres.cpp:1070
ProSHADE_internal_maths::getEulerZYZFromAngleAxis
void getEulerZYZFromAngleAxis(proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axAng, proshade_double *eA, proshade_double *eB, proshade_double *eG)
This function converts angle-axis representation to the Euler ZYZ angles representation.
Definition: ProSHADE_maths.cpp:1612
ProSHADE_internal_spheres::ProSHADE_sphere::getMaxCircumference
proshade_unsign getMaxCircumference(proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_single maxRange)
This function determines the maximum circumference of a shell.
Definition: ProSHADE_spheres.cpp:122
ProSHADE_spheres.hpp
This header file contains the declarations for the ProSHADE_sphere class.
ProSHADE_internal_spheres::ProSHADE_sphere::getMappedData
proshade_double * getMappedData(void)
This function returns the mapped data array.
Definition: ProSHADE_spheres.cpp:417
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonToIndices
proshade_double getLonToIndices(void)
Accessor function for the private variable lonToInds.
Definition: ProSHADE_spheres.cpp:1389
ProSHADE_internal_spheres::ProSHADE_sphere::ProSHADE_sphere
ProSHADE_sphere(proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_single xSize, proshade_single ySize, proshade_single zSize, proshade_unsign shOrder, std::vector< proshade_single > *spherePos, bool progressiveMapping, proshade_unsign band, proshade_double *map, proshade_unsign *maxShellBand, proshade_unsign *maxCompBand)
Constructor for getting empty ProSHADE_sphere class.
Definition: ProSHADE_spheres.cpp:47
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonPosition
proshade_double getSphereLatLonPosition(proshade_unsign lattitude, proshade_unsign longitude)
Accessor function for specific lattitude and longitude point of the sphere sampling grid.
Definition: ProSHADE_spheres.cpp:877
ProSHADE_internal_spheres::ProSHADE_sphere::~ProSHADE_sphere
~ProSHADE_sphere(void)
Destructor for the ProSHADE_sphere class.
Definition: ProSHADE_spheres.cpp:103
ProSHADE_internal_spheres::autoDetermineIntegrationOrder
proshade_unsign autoDetermineIntegrationOrder(proshade_single maxMapRange, proshade_single sphereDist)
This function determines the integration order for the between spheres integration.
Definition: ProSHADE_spheres.cpp:562
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonFromIndices
proshade_double getLonFromIndices(void)
Accessor function for the private variable lonFromInds.
Definition: ProSHADE_spheres.cpp:1378
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:73
ProSHADE_internal_spheres::autoDetermineBandwidth
proshade_unsign autoDetermineBandwidth(proshade_unsign circumference)
This function determines the bandwidth for the spherical harmonics computation.
Definition: ProSHADE_spheres.cpp:516
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:1652
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_spheres::ProSHADE_sphere::getLocalAngRes
proshade_unsign getLocalAngRes(void)
This function returns the local angular resolution.
Definition: ProSHADE_spheres.cpp:404
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::findCyclicPointGroupsGivenFold
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.
Definition: ProSHADE_spheres.cpp:1427
ProSHADE_internal_spheres::ProSHADE_sphere::getLongitudeCutoffs
void getLongitudeCutoffs(std::vector< proshade_double > *lonCO)
This function fills in the vector of longitudal bin boarder values.
Definition: ProSHADE_spheres.cpp:288
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRadius
proshade_double getRadius(void)
Accessor function for the private variable radius.
Definition: ProSHADE_spheres.cpp:687
ProSHADE_internal_spheres::ProSHADE_sphere::allocateRotatedMap
void allocateRotatedMap(void)
This function allocates the rotated map memory.
Definition: ProSHADE_spheres.cpp:600
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonLinearInterpolationPos
proshade_double getSphereLatLonLinearInterpolationPos(proshade_double lattitude, proshade_double longitude)
Function for obtaining sphere values outside of the grid points.
Definition: ProSHADE_spheres.cpp:891
ProSHADE_internal_spheres::ProSHADE_sphere::mapData
void mapData(proshade_double *map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax)
This function maps the internal map to the specific sphere.
Definition: ProSHADE_spheres.cpp:179
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
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRotFunDim
proshade_unsign getRotFunDim(void)
Accessor function for the private variable rotastion function dim.
Definition: ProSHADE_spheres.cpp:708
ProSHADE_internal_spheres::ProSHADE_sphere::interpolateAlongSecond
void interpolateAlongSecond(std::vector< proshade_double > c00, std::vector< proshade_double > c01, std::vector< proshade_double > c10, std::vector< proshade_double > c11, std::vector< proshade_double > *c0, std::vector< proshade_double > *c1, proshade_double yd)
This function interpolates along the second (Y) dimension.
Definition: ProSHADE_spheres.cpp:489
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getAngularDim
proshade_unsign getAngularDim(void)
Accessor function for the private variable angular dim.
Definition: ProSHADE_spheres.cpp:719
ProSHADE_internal_spheres::ProSHADE_sphere::getShellRadius
proshade_double getShellRadius(void)
This function returns the radius of the shell in question.
Definition: ProSHADE_spheres.cpp:591
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::interpolateSphereValues
void interpolateSphereValues(proshade_complex *rotFun)
Function for interpolating the sphere grid values from angle-axis converted rotation function.
Definition: ProSHADE_spheres.cpp:779
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getPeaks
std::vector< std::pair< proshade_unsign, proshade_unsign > > getPeaks(void)
Accessor function for the private variable containing all detected peaks.
Definition: ProSHADE_spheres.cpp:763
ProSHADE_internal_spheres::ProSHADE_sphere::setRotatedMappedData
void setRotatedMappedData(proshade_unsign pos, proshade_double value)
This function sets the rotated mapped data value to the given position.
Definition: ProSHADE_spheres.cpp:617
ProSHADE_internal_spheres::ProSHADE_sphere::getLattitudeCutoffs
void getLattitudeCutoffs(std::vector< proshade_double > *latCO)
This function fills in the vector of lattitudal bin boarder values.
Definition: ProSHADE_spheres.cpp:309
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::~ProSHADE_rotFun_spherePeakGroup
~ProSHADE_rotFun_spherePeakGroup(void)
Destructor for the ProSHADE_rotFun_spherePeakGroup class.
Definition: ProSHADE_spheres.cpp:1109