ProSHADE  0.7.6.0 (JUL 2021)
Protein Shape Detection
ProSHADE_spheres.cpp
Go to the documentation of this file.
1 
23 //============================================ ProSHADE
24 #include "ProSHADE_spheres.hpp"
25 
46 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 )
47 {
48  //================================================ Save inputs
49  this->shellOrder = shOrder;
50  this->sphereWidth = static_cast< proshade_single > ( ( spherePos->at(0) + spherePos->at(1) ) / 2.0f );
51  this->sphereRadius = static_cast< proshade_double > ( spherePos->at(shOrder) );
52 
53  //================================================ Determine shell ranges in angstroms
54  proshade_double maxDist = 0.0;
55  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) ) ); }
56  else { maxDist = static_cast<proshade_double> ( ( spherePos->at(shOrder) + spherePos->at(shOrder+1) ) / 2.0f ); }
57 
58  //================================================ Set the max range
59  this->maxSphereRange = static_cast<proshade_single> ( 2.0 * maxDist );
60 
61  //================================================ Set map sampling rates
62  this->xDimSampling = xSize / static_cast<proshade_single> (xDimMax);
63  this->yDimSampling = ySize / static_cast<proshade_single> (yDimMax);
64  this->zDimSampling = zSize / static_cast<proshade_single> (zDimMax);
65 
66  //================================================ Get maximum circumference
67  proshade_unsign maxCircumference = this->getMaxCircumference ( xDimMax, yDimMax, zDimMax, this->maxSphereRange );
68 
69  //================================================ Get spherical harmonics calculation values
70  if ( progressiveMapping )
71  {
72  this->localBandwidth = std::min ( autoDetermineBandwidth ( maxCircumference ), band );
73  this->localAngRes = this->localBandwidth * 2;
74  }
75  else
76  {
77  this->localBandwidth = band;
78  this->localAngRes = this->localBandwidth * 2;
79  }
80 
81  //================================================ Save the maximum shell band for later
82  if ( *maxShellBand < this->localBandwidth ) { *maxShellBand = this->localBandwidth; }
83 
84  //================================================ Allocate memory for sphere mapping
85  this->mappedData = new proshade_double[this->localAngRes * this->localAngRes];
86  ProSHADE_internal_misc::checkMemoryAllocation ( this->mappedData, __FILE__, __LINE__, __func__ );
87 
88  //================================================ Set rotated mapped data
89  this->mappedDataRot = nullptr;
90 
91  //================================================ Map the data to the sphere
92  this->mapData ( map, xDimMax, yDimMax, zDimMax );
93 
94 }
95 
103 {
104  delete[] this->mappedData;
105 
106  if ( this->mappedDataRot != nullptr )
107  {
108  delete[] this->mappedDataRot;
109  }
110 }
111 
121 proshade_unsign ProSHADE_internal_spheres::ProSHADE_sphere::getMaxCircumference ( proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_single maxRange )
122 {
123  //================================================ Find from and to limits on indices
124  proshade_signed xFromInd = static_cast<proshade_signed> ( xDimMax / 2 ) -
125  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
126  proshade_signed yFromInd = static_cast<proshade_signed> ( yDimMax / 2 ) -
127  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
128  proshade_signed zFromInd = static_cast<proshade_signed> ( zDimMax / 2 ) -
129  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
130 
131  proshade_signed xToInd = static_cast<proshade_signed> ( xDimMax / 2 ) +
132  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
133  proshade_signed yToInd = static_cast<proshade_signed> ( yDimMax / 2 ) +
134  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
135  proshade_signed zToInd = static_cast<proshade_signed> ( zDimMax / 2 ) +
136  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
137 
138  //================================================ Check for bounds
139  if ( xFromInd < 0 ) { xFromInd = 0; }
140  if ( yFromInd < 0 ) { yFromInd = 0; }
141  if ( zFromInd < 0 ) { zFromInd = 0; }
142  if ( xToInd > static_cast<proshade_signed> ( xDimMax ) ) { xToInd = static_cast<proshade_signed> ( xDimMax ); }
143  if ( yToInd > static_cast<proshade_signed> ( yDimMax ) ) { yToInd = static_cast<proshade_signed> ( yDimMax ); }
144  if ( zToInd > static_cast<proshade_signed> ( zDimMax ) ) { zToInd = static_cast<proshade_signed> ( zDimMax ); }
145 
146  //================================================ Get dim sizes
147  proshade_unsign xDimSZ = static_cast< proshade_unsign > ( xToInd - xFromInd );
148  proshade_unsign yDimSZ = static_cast< proshade_unsign > ( yToInd - yFromInd );
149  proshade_unsign zDimSZ = static_cast< proshade_unsign > ( zToInd - zFromInd );
150 
151  //================================================ check for too sparse sampling
152  if ( ( xDimSZ == 0 ) && ( yDimSZ == 0 ) && ( zDimSZ == 0 ) ) { xDimSZ = 1; yDimSZ = 1; zDimSZ = 1; }
153 
154  //================================================ Find max and mid dims
155  std::vector<proshade_unsign> dimSizes;
156  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, xDimSZ );
157  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, yDimSZ );
158  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, zDimSZ );
159  std::sort ( dimSizes.begin(), dimSizes.end() );
160  proshade_unsign maxDim = dimSizes.at(2);
161  proshade_unsign midDim = dimSizes.at(1);
162 
163  //================================================ Return max circumference
164  return ( maxDim + midDim );
165 }
166 
178 void ProSHADE_internal_spheres::ProSHADE_sphere::mapData ( proshade_double* map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax )
179 {
180  //================================================ Initialise local variavles
181  proshade_double x, y, z, xRelative, yRelative, zRelative;
182  proshade_signed xBottom, yBottom, zBottom, xTop, yTop, zTop;
183  std::vector<proshade_double> lonCO ( this->localAngRes + 1 );
184  std::vector<proshade_double> latCO ( this->localAngRes + 1 );
185  std::vector<proshade_double> c000 = std::vector<proshade_double> ( 4 );
186  std::vector<proshade_double> c001 = std::vector<proshade_double> ( 4 );
187  std::vector<proshade_double> c010 = std::vector<proshade_double> ( 4 );
188  std::vector<proshade_double> c011 = std::vector<proshade_double> ( 4 );
189  std::vector<proshade_double> c100 = std::vector<proshade_double> ( 4 );
190  std::vector<proshade_double> c101 = std::vector<proshade_double> ( 4 );
191  std::vector<proshade_double> c110 = std::vector<proshade_double> ( 4 );
192  std::vector<proshade_double> c111 = std::vector<proshade_double> ( 4 );
193  std::vector<proshade_double> c00 = std::vector<proshade_double> ( 4 );
194  std::vector<proshade_double> c01 = std::vector<proshade_double> ( 4 );
195  std::vector<proshade_double> c10 = std::vector<proshade_double> ( 4 );
196  std::vector<proshade_double> c11 = std::vector<proshade_double> ( 4 );
197  std::vector<proshade_double> c0 = std::vector<proshade_double> ( 4 );
198  std::vector<proshade_double> c1 = std::vector<proshade_double> ( 4 );
199 
200  //================================================ Find pixelisation cutOffs
201  this->getLongitudeCutoffs ( &lonCO );
202  this->getLattitudeCutoffs ( &latCO );
203 
204  //================================================ Interpolate the map onto this shell
205  for ( unsigned int thIt = 0; thIt < this->localAngRes; thIt++ )
206  {
207  for ( unsigned int phIt = 0; phIt < this->localAngRes; phIt++ )
208  {
209  //======================================== Get grid point x, y and z
210  this->getInterpolationXYZ ( &x, &y, &z, thIt, &lonCO, phIt, &latCO );
211 
212  //======================================== Find 8 closest point around the grid point in indices
213  this->getXYZTopBottoms ( xDimMax, yDimMax, zDimMax, x, y, z, &xBottom, &yBottom, &zBottom, &xTop, &yTop, &zTop );
214 
215  //======================================== Get the 8 closest points interpolation vectors (or set to 0 if out-of-bounds)
216  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zBottom, &c000 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
217  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zTop , &c001 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
218  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zBottom, &c010 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
219  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zTop , &c011 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
220  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zBottom, &c100 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
221  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zTop , &c101 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
222  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zBottom, &c110 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
223  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zTop , &c111 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
224 
225  //======================================== Interpolate along X axis
226  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 );
227  this->interpolateAlongFirst ( c000, c001, c010, c011, c100, c101, c110, c111, &c00, &c01, &c10, &c11, xRelative );
228 
229  //======================================== Interpolate along Y axis
230  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 );
231  this->interpolateAlongSecond ( c00, c01, c10, c11, &c0, &c1, yRelative );
232 
233  //======================================== Save the resulting value
234  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 );
235  this->mappedData[phIt * this->localAngRes + thIt] = ( c0.at(3) * ( 1.0 - zRelative ) ) + ( c1.at(3) * zRelative );
236  }
237  }
238 
239  //================================================ Done
240  return ;
241 
242 }
243 
260 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 )
261 {
262  //================================================ Initialise local variables
263  proshade_signed posIter = zPos + static_cast<proshade_signed> ( zDimMax ) * ( yPos + static_cast<proshade_signed> ( yDimMax ) * xPos );
264 
265  //================================================ Check of out-of-bounds shells
266  if ( ( xPos < 0 ) || ( xPos >= static_cast<proshade_signed> ( xDimMax ) ) ) { return ( false ); }
267  if ( ( yPos < 0 ) || ( yPos >= static_cast<proshade_signed> ( yDimMax ) ) ) { return ( false ); }
268  if ( ( zPos < 0 ) || ( zPos >= static_cast<proshade_signed> ( zDimMax ) ) ) { return ( false ); }
269 
270  //================================================ Get the interpolation values
271  interpVec->at(0) = static_cast<proshade_double> ( xPos ) * static_cast<proshade_double> ( this->xDimSampling );
272  interpVec->at(1) = static_cast<proshade_double> ( yPos ) * static_cast<proshade_double> ( this->yDimSampling );
273  interpVec->at(2) = static_cast<proshade_double> ( zPos ) * static_cast<proshade_double> ( this->zDimSampling );
274  interpVec->at(3) = map[posIter];
275 
276  //================================================ Done
277  return ( true );
278 
279 }
280 
287 void ProSHADE_internal_spheres::ProSHADE_sphere::getLongitudeCutoffs ( std::vector<proshade_double>* lonCO )
288 {
289  //================================================ Get the cut-offs
290  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
291  {
292  lonCO->at(iter) = static_cast<proshade_double> ( iter ) *
293  ( ( static_cast<proshade_double> ( M_PI ) * 2.0 ) / static_cast<proshade_double> ( this->localAngRes ) ) -
294  ( static_cast<proshade_double> ( M_PI ) );
295  }
296 
297  //================================================ Done
298  return ;
299 
300 }
301 
308 void ProSHADE_internal_spheres::ProSHADE_sphere::getLattitudeCutoffs ( std::vector<proshade_double>* latCO )
309 {
310  //================================================ Get the cut-offs
311  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
312  {
313  latCO->at(iter) = ( static_cast<proshade_double> ( iter ) *
314  ( static_cast<proshade_double> ( M_PI ) / static_cast<proshade_double> ( this->localAngRes ) ) -
315  ( static_cast<proshade_double> ( M_PI ) / 2.0 ) );
316  }
317 
318  //================================================ Done
319  return ;
320 
321 }
322 
336 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 )
337 {
338  //================================================ Compute and save XYZ interpolation positions
339  *x = this->sphereRadius * std::cos ( ( lonCO->at( static_cast<proshade_unsign> ( thetaIt ) ) + lonCO->at( static_cast<proshade_unsign> ( thetaIt+1 ) ) ) / 2.0 ) *
340  std::cos ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
341  *y = this->sphereRadius * std::sin ( ( lonCO->at( static_cast<proshade_unsign> ( thetaIt ) ) + lonCO->at( static_cast<proshade_unsign> ( thetaIt+1 ) ) ) / 2.0 ) *
342  std::cos ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
343  *z = this->sphereRadius * std::sin ( ( latCO->at( static_cast<proshade_unsign> ( phiIt ) ) + latCO->at( static_cast<proshade_unsign> ( phiIt+1 ) ) ) / 2.0 );
344 
345  //================================================ Done
346  return ;
347 
348 }
349 
367 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 )
368 {
369  //================================================ Get the values
370  *xBottom = static_cast< proshade_signed > ( std::floor ( ( x / static_cast< proshade_double > ( this->xDimSampling ) ) ) + ( static_cast< proshade_double > ( xDimMax ) / 2.0 ) );
371  *yBottom = static_cast< proshade_signed > ( std::floor ( ( y / static_cast< proshade_double > ( this->yDimSampling ) ) ) + ( static_cast< proshade_double > ( yDimMax ) / 2.0 ) );
372  *zBottom = static_cast< proshade_signed > ( std::floor ( ( z / static_cast< proshade_double > ( this->zDimSampling ) ) ) + ( static_cast< proshade_double > ( zDimMax ) / 2.0 ) );
373 
374  *xTop = *xBottom + 1;
375  *yTop = *yBottom + 1;
376  *zTop = *zBottom + 1;
377 
378  //================================================ Done
379  return ;
380 
381 }
382 
391 {
392  //================================================ Return the value
393  return ( this->localBandwidth );
394 }
395 
404 {
405  //================================================ Return the value
406  return ( this->localAngRes );
407 }
408 
417 {
418  //================================================ Return the value
419  return ( this->mappedData );
420 }
421 
442 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 )
443 {
444  //================================================ Interpolate for the less less point
445  c00->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c000.at(0);
446  c00->at(1) = c000.at(1);
447  c00->at(2) = c000.at(2);
448  c00->at(3) = ( c000.at(3) * ( 1.0 - xd ) ) + ( c100.at(3) * xd );
449 
450  //================================================ Interpolate for the less more point
451  c01->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c001.at(0);
452  c01->at(1) = c001.at(1);
453  c01->at(2) = c001.at(2);
454  c01->at(3) = ( c001.at(3) * ( 1.0 - xd ) ) + ( c101.at(3) * xd );
455 
456  //================================================ Interpolate for the more less point
457  c10->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c010.at(0);
458  c10->at(1) = c010.at(1);
459  c10->at(2) = c010.at(2);
460  c10->at(3) = ( c010.at(3) * ( 1.0 - xd ) ) + ( c110.at(3) * xd );
461 
462  //================================================ Interpolate for the more more point
463  c11->at(0) = ( static_cast< proshade_double > ( this->xDimSampling ) * xd ) + c011.at(0);
464  c11->at(1) = c011.at(1);
465  c11->at(2) = c011.at(2);
466  c11->at(3) = ( c011.at(3) * ( 1.0 - xd ) ) + ( c111.at(3) * xd );
467 
468  //================================================ Done
469  return ;
470 
471 }
472 
488 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 )
489 {
490  //================================================ Interpolate for the less point
491  c0->at(0) = c00.at(0);
492  c0->at(1) = ( static_cast< proshade_double > ( this->yDimSampling ) * yd ) + c00.at(1);
493  c0->at(2) = c00.at(2);
494  c0->at(3) = ( c00.at(3) * ( 1.0 - yd ) ) + ( c10.at(3) * yd );
495 
496  //================================================ Interpolate for the more point
497  c1->at(0) = c01.at(0);
498  c1->at(1) = ( static_cast< proshade_double > ( this->yDimSampling ) * yd ) + c01.at(1);
499  c1->at(2) = c01.at(2);
500  c1->at(3) = ( c01.at(3) * ( 1.0 - yd ) ) + ( c11.at(3) * yd );
501 
502  //================================================ Done
503  return ;
504 
505 }
506 
515 proshade_unsign ProSHADE_internal_spheres::autoDetermineBandwidth ( proshade_unsign circumference )
516 {
517  //================================================ Determine and return
518  if ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) % 2 == 0 )
519  {
520  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) );
521  }
522  else
523  {
524  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) + 1 );
525  }
526 }
527 
537 proshade_single ProSHADE_internal_spheres::autoDetermineSphereDistances ( proshade_single maxMapRange, proshade_single resolution )
538 {
539  //================================================ Get starting point
540  proshade_single ret = resolution / 2.0f;
541 
542  //================================================ Make sure at least 10 shells will exist
543  while ( std::floor ( maxMapRange / ret ) < 10 )
544  {
545  ret /= 2.0f;
546  }
547 
548  //================================================ Done
549  return ( ret );
550 }
551 
561 proshade_unsign ProSHADE_internal_spheres::autoDetermineIntegrationOrder ( proshade_single maxMapRange, proshade_single sphereDist )
562 {
563  //================================================ Initialise local variables
564  proshade_double sphereDistanceAsFractionOfTotal = static_cast<proshade_double> ( sphereDist / ( maxMapRange / 2.0f ) );
565  proshade_unsign ret = 0;
566 
567  //================================================ Compare to precomputed values
568  for ( proshade_unsign iter = 2; iter < static_cast<proshade_unsign> ( 10000 ); iter++ )
569  {
570  if ( ProSHADE_internal_precomputedVals::glIntMaxDists[iter] >= sphereDistanceAsFractionOfTotal )
571  {
572  ret = iter;
573  }
574  }
575 
576  //================================================ Return largest passing value
577  return ( ret );
578 
579 }
580 
588 {
589  //================================================ Done
590  return ( this->sphereRadius );
591 
592 }
593 
597 {
598  //================================================ Allocate memory for sphere mapping
599  this->mappedDataRot = nullptr;
600  this->mappedDataRot = new proshade_double[this->localAngRes * this->localAngRes];
601  ProSHADE_internal_misc::checkMemoryAllocation ( this->mappedDataRot, __FILE__, __LINE__, __func__ );
602 
603  //================================================ Done
604  return ;
605 
606 }
607 
613 void ProSHADE_internal_spheres::ProSHADE_sphere::setRotatedMappedData ( proshade_unsign pos, proshade_double value )
614 {
615  //================================================ Set the value to the position
616  this->mappedDataRot[pos] = value;
617 
618  //================================================ Done
619  return ;
620 
621 }
622 
628 {
629  //================================================ Done
630  return ( this->mappedDataRot[pos] );
631 
632 }
633 
645 ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::ProSHADE_rotFun_sphere ( proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_double repAng, proshade_unsign sphNo )
646 {
647  //================================================ Set internal values
648  this->radius = rad;
649  this->angularDim = dim;
650  this->radiusMin = this->radius - ( radRange / 2.0 );
651  this->radiusMax = this->radius + ( radRange / 2.0 );
652  this->representedAngle = repAng;
653  this->sphereNumber = sphNo;
654 
655  //================================================ Allocate the axis field
656  this->axesValues = new proshade_double[dim*dim];
657  ProSHADE_internal_misc::checkMemoryAllocation ( this->axesValues, __FILE__, __LINE__, __func__ );
658 
659  //================================================ Fill axis field with zeroes
660  for ( proshade_unsign iter = 0; iter < ( dim * dim ); iter++ ) { this->axesValues[iter] = 0.0; }
661 
662 }
663 
669 {
670  //================================================ Release the allocated memory
671  if ( this->axesValues != nullptr )
672  {
673  delete[] this->axesValues;
674  }
675 }
676 
682 {
683  //================================================ Done
684  return ( this->radius );
685 }
686 
692 {
693  //================================================ Done
694  return ( this->radiusMax );
695 
696 }
697 
703 {
704  //================================================ Done
705  return ( this->angularDim );
706 
707 }
708 
714 {
715  //================================================ Done
716  return ( this->radiusMin );
717 
718 }
719 
725 {
726  //================================================ Done
727  return ( this->representedAngle );
728 
729 }
730 
736 {
737  //================================================ Done
738  return ( this->sphereNumber );
739 
740 }
741 
746 std::vector<std::pair<proshade_unsign,proshade_unsign>> ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getPeaks ( void )
747 {
748  //================================================ Done
749  return ( this->peaks );
750 
751 }
752 
763 {
764  //================================================ Initialise variables
765  proshade_double lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->angularDim );
766  proshade_double latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->angularDim );
767 
768  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;
769  proshade_signed xBottom, xTop, yBottom, yTop, zBottom, zTop, mapIndex;
770 
771  //================================================ For each sphere grid position
772  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
773  {
774  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
775  {
776  //======================================== Convert to XYZ position on unit sphere. The radius here is not important, as it does not change the direction of the vector.
777  lon = static_cast<proshade_double> ( lonIt ) * lonSampling;
778  lat = static_cast<proshade_double> ( latIt ) * latSampling;
779  cX = 1.0 * std::sin ( lon ) * std::cos ( lat );
780  cY = 1.0 * std::sin ( lon ) * std::sin ( lat );
781  cZ = 1.0 * std::cos ( lon );
782 
783  //======================================== Convert to ZXZ Euler angles
784  ProSHADE_internal_maths::getEulerZXZFromAngleAxis ( cX, cY, cZ, this->representedAngle, &eulerAlpha, &eulerBeta, &eulerGamma );
785 
786  //======================================== Convert to SOFT map position (decimal, not indices)
787  ProSHADE_internal_maths::getSOFTPositionFromEulerZXZ ( this->angularDim / 2, eulerAlpha, eulerBeta, eulerGamma, &mapX, &mapY, &mapZ );
788 
789  //======================================== Find lower and higher points and deal with boundaries
790  xBottom = static_cast< proshade_signed > ( std::floor ( mapX ) ); if ( xBottom < 0 ) { xBottom += this->angularDim; } if ( xBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { xBottom -= static_cast<proshade_signed> ( this->angularDim ); }
791  yBottom = static_cast< proshade_signed > ( std::floor ( mapY ) ); if ( yBottom < 0 ) { yBottom += this->angularDim; } if ( yBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { yBottom -= static_cast<proshade_signed> ( this->angularDim ); }
792  zBottom = static_cast< proshade_signed > ( std::floor ( mapZ ) ); if ( zBottom < 0 ) { zBottom += this->angularDim; } if ( zBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { zBottom -= static_cast<proshade_signed> ( this->angularDim ); }
793  xTop = static_cast< proshade_signed > ( std::ceil ( mapX ) ); if ( xTop < 0 ) { xTop += this->angularDim; } if ( xTop >= static_cast<proshade_signed> ( this->angularDim ) ) { xTop -= static_cast<proshade_signed> ( this->angularDim ); }
794  yTop = static_cast< proshade_signed > ( std::ceil ( mapY ) ); if ( yTop < 0 ) { yTop += this->angularDim; } if ( yTop >= static_cast<proshade_signed> ( this->angularDim ) ) { yTop -= static_cast<proshade_signed> ( this->angularDim ); }
795  zTop = static_cast< proshade_signed > ( std::ceil ( mapZ ) ); if ( zTop < 0 ) { zTop += this->angularDim; } if ( zTop >= static_cast<proshade_signed> ( this->angularDim ) ) { zTop -= static_cast<proshade_signed> ( this->angularDim ); }
796 
797  //======================================== Start X interpolation - bottom, bottom, bottom
798  mapIndex = zBottom + static_cast< proshade_signed > ( this->angularDim ) * ( yBottom + static_cast< proshade_signed > ( this->angularDim ) * xBottom );
799  c000 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
800 
801  //======================================== X interpolation - bottom, bottom, top
802  mapIndex = zTop + static_cast< proshade_signed > ( this->angularDim ) * ( yBottom + static_cast< proshade_signed > ( this->angularDim ) * xBottom );
803  c001 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
804 
805  //======================================== X interpolation - bottom, top, bottom
806  mapIndex = zBottom + static_cast< proshade_signed > ( this->angularDim ) * ( yTop + static_cast< proshade_signed > ( this->angularDim ) * xBottom );
807  c010 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
808 
809  //======================================== X interpolation - bottom, top, top
810  mapIndex = zTop + static_cast< proshade_signed > ( this->angularDim ) * ( yTop + static_cast< proshade_signed > ( this->angularDim ) * xBottom );
811  c011 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
812 
813  //======================================== X interpolation - top, bottom, bottom
814  mapIndex = zBottom + static_cast< proshade_signed > ( this->angularDim ) * ( yBottom + static_cast< proshade_signed > ( this->angularDim ) * xTop );
815  c100 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
816 
817  //======================================== X interpolation - top, bottom, top
818  mapIndex = zTop + static_cast< proshade_signed > ( this->angularDim ) * ( yBottom + static_cast< proshade_signed > ( this->angularDim ) * xTop );
819  c101 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
820 
821  //======================================== X interpolation - top, top, bottom
822  mapIndex = zBottom + static_cast< proshade_signed > ( this->angularDim ) * ( yTop + static_cast< proshade_signed > ( this->angularDim ) * xTop );
823  c110 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
824 
825  //======================================== X interpolation - top, top, top
826  mapIndex = zTop + static_cast< proshade_signed > ( this->angularDim ) * ( yTop + static_cast< proshade_signed > ( this->angularDim ) * xTop );
827  c111 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
828 
829  //======================================== Solve for X
830  xRelative = mapX - std::floor( mapX );
831  c00 = ( c000 * ( 1.0 - xRelative ) ) + ( c100 * xRelative );
832  c01 = ( c001 * ( 1.0 - xRelative ) ) + ( c101 * xRelative );
833  c10 = ( c010 * ( 1.0 - xRelative ) ) + ( c110 * xRelative );
834  c11 = ( c011 * ( 1.0 - xRelative ) ) + ( c111 * xRelative );
835 
836  //======================================== Solve for Y
837  yRelative = mapY - std::floor( mapY );
838  c0 = ( c00 * ( 1.0 - yRelative ) ) + ( c10 * yRelative );
839  c1 = ( c01 * ( 1.0 - yRelative ) ) + ( c11 * yRelative );
840 
841  //======================================== Solve for Z
842  zRelative = mapZ - std::floor( mapZ );
843 
844  //======================================== Save result
845  mapIndex = lonIt + ( latIt * static_cast< proshade_signed > ( this->angularDim ) );
846  this->axesValues[mapIndex] = ( c0 * ( 1.0 - zRelative ) ) + ( c1 * zRelative );
847  }
848  }
849 
850  //================================================ Done
851  return ;
852 
853 }
854 
861 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonPosition ( proshade_unsign lattitude, proshade_unsign longitude )
862 {
863  //================================================ Done
864  return ( this->axesValues[longitude + ( lattitude * static_cast<proshade_unsign> ( this->angularDim ) )] );
865 }
866 
875 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonLinearInterpolationPos ( proshade_double lattitude, proshade_double longitude )
876 {
877  //================================================ Initialise variables
878  proshade_double c00, c01, c10, c11, c0, c1, latRelative, lonRelative;
879  proshade_signed latTop, latBottom, lonTop, lonBottom, gridIndex;
880 
881  //================================================ Find lower and higher indices and deal with boundaries
882  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; }
883  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; }
884  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; }
885  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; }
886 
887  //================================================ Interpolate
888  gridIndex = lonBottom + ( latBottom * static_cast< proshade_signed > ( this->angularDim ) );
889  c00 = this->axesValues[gridIndex];
890 
891  gridIndex = lonBottom + ( latTop * static_cast< proshade_signed > ( this->angularDim ) );
892  c01 = this->axesValues[gridIndex];
893 
894  gridIndex = lonTop + ( latBottom * static_cast< proshade_signed > ( this->angularDim ) );
895  c10 = this->axesValues[gridIndex];
896 
897  gridIndex = lonTop + ( latTop * static_cast< proshade_signed > ( this->angularDim ) );
898  c11 = this->axesValues[gridIndex];
899 
900  //================================================ Solve for longitude
901  lonRelative = longitude - std::floor( longitude );
902  c0 = ( c00 * ( 1.0 - lonRelative ) ) + ( c10 * lonRelative );
903  c1 = ( c01 * ( 1.0 - lonRelative ) ) + ( c11 * lonRelative );
904 
905  //================================================ Solve for lattitude
906  latRelative = lattitude - std::floor ( lattitude );
907  proshade_double res = ( c0 * ( 1.0 - latRelative ) ) + ( c1 * latRelative );
908 
909  //================================================ Done
910  return ( res );
911 
912 }
913 
921 void ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::findAllPeaks ( proshade_signed noSmNeighbours, std::vector< proshade_double >* allHeights )
922 {
923  //================================================ Initialise local variables
924  proshade_double currentHeight;
925  proshade_signed nbLat, nbLon;
926  bool isPeak;
927 
928  //================================================ Find all peaks
929  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
930  {
931  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
932  {
933  //======================================== Initialise peak search
934  currentHeight = this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( latIt ), static_cast< proshade_unsign > ( lonIt ) );
935  isPeak = true;
936 
937  //======================================== Find all neighbours in the same sphere
938  for ( proshade_signed latRound = -noSmNeighbours; latRound <= noSmNeighbours; latRound++ )
939  {
940  for ( proshade_signed lonRound = -noSmNeighbours; lonRound <= noSmNeighbours; lonRound++ )
941  {
942  //================================ Ignore same point
943  if ( latRound == 0 && lonRound == 0 ) { continue; }
944 
945  //================================ Get neighbour height
946  nbLat = latIt + latRound;
947  nbLon = lonIt + lonRound;
948  if ( nbLat < 0 ) { nbLat += this->angularDim; } if ( nbLat >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLat -= this->angularDim; }
949  if ( nbLon < 0 ) { nbLon += this->angularDim; } if ( nbLon >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLon -= this->angularDim; }
950 
951  //================================ If this value is larger than the tested one, no peak
952  if ( this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( nbLat ), static_cast< proshade_unsign > ( nbLon ) ) > currentHeight ) { isPeak = false; break; }
953  }
954 
955  if ( !isPeak ) { break; }
956  }
957 
958  if ( isPeak )
959  {
960  //==================================== Save!
961  this->peaks.emplace_back ( std::pair<proshade_unsign,proshade_unsign> ( latIt, lonIt ) );
962  }
963  else
964  {
965  ProSHADE_internal_misc::addToDoubleVector ( allHeights, currentHeight );
966  }
967  }
968  }
969 
970  //================================================ Done
971  return ;
972 
973 }
974 
984 {
985  //================================================ Initialise variables
986  proshade_double curHeight;
987  std::vector< proshade_unsign > dels ( 0, static_cast< proshade_unsign > ( this->peaks.size() ) );
988 
989  //================================================ For each peak in this sphere
990  for ( proshade_unsign peakIt = 0; peakIt < static_cast<proshade_unsign> ( this->peaks.size() ); peakIt++ )
991  {
992  //============================================ Find the peak height
993  curHeight = this->getSphereLatLonPosition ( this->peaks.at(peakIt).first, this->peaks.at(peakIt).second );
994 
995  //============================================ Should this peak be deleted?
996  if ( curHeight < peakThres )
997  {
999  }
1000  }
1001 
1002  //================================================ Descending sort to avoid changing the order
1003  std::sort ( dels.begin(), dels.end(), std::greater <proshade_unsign>() );
1004 
1005  //================================================ Delete the low peaks
1006  for ( proshade_unsign delIt = 0; delIt < static_cast< proshade_unsign > ( dels.size() ); delIt++ )
1007  {
1008  this->peaks.erase ( this->peaks.begin() + static_cast< long int > ( dels.at(delIt) ) );
1009  }
1010 
1011  //================================================ Done
1012  return ;
1013 
1014 }
1015 
1026 ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::ProSHADE_rotFun_spherePeakGroup ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_unsign angDim )
1027 {
1028  //================================================ Compute the run-specific values
1029  this->dimension = angDim;
1030  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1031  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1032 
1033  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1034  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1035  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1036  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1037  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1038  this->latFromInds = lat;
1039  this->latToInds = lat;
1040  this->lonFromInds = lon;
1041  this->lonToInds = lon;
1042  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1043 
1044  //================================================ Allocate memory for similarity positions
1045  this->latMinLonMinXYZ = new proshade_double[3];
1046  this->latMaxLonMinXYZ = new proshade_double[3];
1047  this->latMinLonMaxXYZ = new proshade_double[3];
1048  this->latMaxLonMaxXYZ = new proshade_double[3];
1049  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1050  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1051  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1052  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1053 
1054  //================================================ Compute corner vectors
1055  this->computeCornerPositions ( );
1056 
1057  //================================================ Done
1058 
1059 }
1060 
1066 {
1067  //================================================ Release the XYZ arrays
1068  delete[] this->latMinLonMinXYZ;
1069  delete[] this->latMaxLonMinXYZ;
1070  delete[] this->latMinLonMaxXYZ;
1071  delete[] this->latMaxLonMaxXYZ;
1072 }
1073 
1077 {
1078  //================================================ Compute corner vectors
1079  this->latMinLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latFrom );
1080  this->latMinLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latFrom );
1081  this->latMinLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1082 
1083  this->latMaxLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latTo );
1084  this->latMaxLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latTo );
1085  this->latMaxLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1086 
1087  this->latMinLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latFrom );
1088  this->latMinLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latFrom );
1089  this->latMinLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1090 
1091  this->latMaxLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latTo );
1092  this->latMaxLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latTo );
1093  this->latMaxLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1094 
1095  //================================================ Done
1096  return ;
1097 
1098 }
1099 
1106 proshade_signed ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders ( proshade_signed newAngul, proshade_signed currentAngul )
1107 {
1108  //================================================ Initialise variables
1109  proshade_signed smallerAngul = newAngul - static_cast< proshade_signed > ( this->dimension );
1110  proshade_signed largerAngul = newAngul + static_cast< proshade_signed > ( this->dimension );
1111 
1112  //================================================ Find the smallest distance
1113  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1114 
1115  //================================================ Done
1116  return ( ret );
1117 
1118 }
1119 
1134 bool ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::checkIfPeakBelongs ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_double cosTol, proshade_signed verbose )
1135 {
1136  //================================================ Initialise local variables
1137  bool peakAdded = false;
1138  std::stringstream hlpSS;
1139  std::stringstream hlpSS2;
1140 
1141  //================================================ Compute peaks XYZ and its cosine distance to group corners
1142  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1143  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1144  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1145  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1146 
1147  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMinXYZ[0], this->latMinLonMinXYZ[1], this->latMinLonMinXYZ[2], cosTol ) ) { peakAdded = true; hlpSS2 << this->latMinLonMinXYZ[0] << " ; " << this->latMinLonMinXYZ[1] << " ; " << this->latMinLonMinXYZ[2]; }
1148  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMinXYZ[0], this->latMaxLonMinXYZ[1], this->latMaxLonMinXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMinXYZ[0] << " ; " << this->latMaxLonMinXYZ[1] << " ; " << this->latMaxLonMinXYZ[2]; }
1149  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMaxXYZ[0], this->latMinLonMaxXYZ[1], this->latMinLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMinLonMaxXYZ[0] << " ; " << this->latMinLonMaxXYZ[1] << " ; " << this->latMinLonMaxXYZ[2]; }
1150  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMaxXYZ[0], this->latMaxLonMaxXYZ[1], this->latMaxLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMaxXYZ[0] << " ; " << this->latMaxLonMaxXYZ[1] << " ; " << this->latMaxLonMaxXYZ[2]; }
1151 
1152  //================================================ If peak within corners, add it
1153  if ( peakAdded )
1154  {
1155  //============================================ Report progress
1156  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1157  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str() );
1158 
1159  //============================================ Initialise local variables
1160  proshade_signed largerCorner, smallerCorner;
1161  bool latCornersDone = false;
1162  bool lonCornersDone = false;
1163 
1164  //============================================ Check if lattitude boundaries need to be modified
1165  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1166  {
1167  //======================================== Lattitude is outside of group boundaries
1168  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1169  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1170 
1171  if ( smallerCorner < largerCorner )
1172  {
1173  this->latFromInds = lat;
1174  latCornersDone = true;
1175  }
1176  if ( smallerCorner > largerCorner )
1177  {
1178  this->latToInds = lat;
1179  latCornersDone = true;
1180  }
1181  if ( smallerCorner == largerCorner )
1182  {
1183  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1184  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1185  }
1186  }
1187 
1188  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1189  {
1190  //======================================== Lattitude is outside of group boundaries
1191  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1192  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1193 
1194  if ( smallerCorner < largerCorner )
1195  {
1196  this->latFromInds = lat;
1197  latCornersDone = true;
1198  }
1199  if ( smallerCorner > largerCorner )
1200  {
1201  this->latToInds = lat;
1202  latCornersDone = true;
1203  }
1204  if ( smallerCorner == largerCorner )
1205  {
1206  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1207  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1208  }
1209  }
1210 
1211 
1212  //============================================ Check if longitude boundaries need to be modified
1213  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1214  {
1215  //======================================== Lattitude is outside of group boundaries
1216  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1217  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1218 
1219  if ( smallerCorner < largerCorner )
1220  {
1221  this->lonFromInds = lon;
1222  lonCornersDone = true;
1223  }
1224  if ( smallerCorner > largerCorner )
1225  {
1226  this->lonToInds = lon;
1227  lonCornersDone = true;
1228  }
1229  if ( smallerCorner == largerCorner )
1230  {
1231  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1232  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1233  }
1234  }
1235 
1236  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1237  {
1238  //======================================== Lattitude is outside of group boundaries
1239  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1240  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1241 
1242  if ( smallerCorner < largerCorner )
1243  {
1244  this->lonFromInds = lon;
1245  lonCornersDone = true;
1246  }
1247  if ( smallerCorner > largerCorner )
1248  {
1249  this->lonToInds = lon;
1250  lonCornersDone = true;
1251  }
1252  if ( smallerCorner == largerCorner )
1253  {
1254  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1255  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1256  }
1257  }
1258 
1259  //============================================ Modify corner positions
1260  if ( latCornersDone )
1261  {
1262  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1263  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1264  }
1265 
1266  if ( lonCornersDone )
1267  {
1268  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1269  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1270  }
1271 
1272  //============================================ Compute corner vectors
1273  this->computeCornerPositions ( );
1274  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1275  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str() );
1276 
1277  //============================================ If new sphere, add it to the list
1278  bool isSphereNew = true;
1279  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1280  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1281  }
1282 
1283  //================================================ Done
1284  return ( peakAdded );
1285 
1286 }
1287 
1293 {
1294  //================================================ Done
1295  return ( this->latFromInds );
1296 
1297 }
1298 
1304 {
1305  //================================================ Done
1306  return ( this->latToInds );
1307 
1308 }
1309 
1315 {
1316  //================================================ Done
1317  return ( this->lonFromInds );
1318 
1319 }
1320 
1326 {
1327  //================================================ Done
1328  return ( this->lonToInds );
1329 
1330 }
1331 
1337 {
1338  //================================================ Done
1339  return ( this->spherePositions );
1340 
1341 }
1342 
1362 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 )
1363 {
1364  //================================================ Check that this peak group has all the angles
1365  if ( ( fold - 1 ) != spherePositions.size() ) { return ; }
1366 
1367  //================================================ Initialise variables
1368  proshade_double bestPosVal, bestLatInd, bestLonInd;
1369  std::vector< proshade_unsign > spheresFormingFold;
1370 
1371  //================================================ Set all supplied spheres to be required to form the fold
1372  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1373  {
1374  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1375  }
1376 
1377  //================================================ Find the index with the highest peak height sum
1378  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1379 
1380  //================================================ Optimise by bicubic interpolation if required
1381  if ( bicubicInterp )
1382  {
1383  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1384  }
1385 
1386  //================================================ Create ProSHADE symmetry axis array and save it
1387  proshade_double* detectedSymmetry = new proshade_double[7];
1388  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1389 
1390  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1391  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1392  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1393  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1394  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1395  detectedSymmetry[5] = ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 );
1396  detectedSymmetry[6] = -1.0;
1397 
1398  //================================================ Make sure max is positive
1399  const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) );
1400  const FloatingPoint< proshade_double > rhs1 ( std::abs ( detectedSymmetry[1] ) );
1401  const FloatingPoint< proshade_double > rhs2 ( std::abs ( detectedSymmetry[2] ) );
1402  const FloatingPoint< proshade_double > rhs3 ( std::abs ( detectedSymmetry[3] ) );
1403  if ( ( lhs1.AlmostEquals ( rhs1 ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1404  ( lhs1.AlmostEquals ( rhs2 ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1405  ( lhs1.AlmostEquals ( rhs3 ) && ( detectedSymmetry[3] < 0.0 ) ) )
1406  {
1407  detectedSymmetry[1] *= -1.0;
1408  detectedSymmetry[2] *= -1.0;
1409  detectedSymmetry[3] *= -1.0;
1410  detectedSymmetry[4] *= -1.0;
1411  }
1412 
1413  //================================================ Check for decimal underflows. They are not an issue as rounding to zero is fine, but having negative sign to zero will switch the signs and cause problems.
1414  const FloatingPoint< proshade_double > llhs1 ( detectedSymmetry[1] ), llhs2 ( detectedSymmetry[2] ), llhs3 ( detectedSymmetry[3] ), rrhs1 ( 0.0 );
1415  if ( llhs1.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[1] = 0.0; }
1416  if ( llhs2.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[2] = 0.0; }
1417  if ( llhs3.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[3] = 0.0; }
1418 
1419  //================================================ Save detected point group
1420  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1421 
1422  //================================================ Report progress
1423  std::stringstream hlpSS;
1424  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1425  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str() );
1426 
1427  //================================================ Done
1428  return ;
1429 
1430 }
1431 
1437 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences ( std::vector< proshade_double >* angDiffs, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals )
1438 {
1439  //================================================ Initialise local variables
1440  std::vector< proshade_double > angs;
1441 
1442  //================================================ Find all present angles
1443  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1444  {
1445  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1446  }
1447 
1448  //================================================ Find all angle differences
1449  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1450  {
1451  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1452  {
1453  //======================================== Use unique combinations only
1454  if ( ang1It >= ang2It ) { continue; }
1455 
1456  //======================================== Add angle difference rounded to 5 decimal places
1457  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1458  }
1459  }
1460 
1461  //================================================ Sort and remove duplicates
1462  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1463  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1464 
1465  //================================================ Done
1466  return ;
1467 
1468 }
1469 
1479 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds ( std::vector< proshade_double >* angDiffs, std::vector< proshade_unsign >* foldsToTry )
1480 {
1481  //================================================ Initialise local variables
1482  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1483  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1484 
1485  //================================================ For each angle difference in the group
1486  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1487  {
1488  //============================================ Find the basis and remainder of the 2pi/dist equation
1489  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1490 
1491  //============================================ If the remainder would be smaller for larger basis, so change the basis
1492  if ( divRem > 0.5 )
1493  {
1494  divRem -= 1.0;
1495  divBasis += 1.0;
1496  }
1497 
1498  //============================================ Remove fold 1, that is not really what we are after here ...
1499  const FloatingPoint< proshade_double > lhs1 ( divBasis ), rhs1 ( 1.0 );
1500  if ( lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1501 
1502  //============================================ Is there enough angles in the group for such a fold?
1503  if ( static_cast< proshade_double > ( this->spherePositions.size() ) < ( divBasis - 1.0 ) ) { continue; }
1504 
1505  //============================================ Determine errors on peaks and on folds
1506  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1507  angTolerance = std::abs( symmErr / peakErr );
1508  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1509 
1510  //============================================ Is remainder small enough?
1511  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1512  {
1513  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1514  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1515  {
1516  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1517  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis - 1 ) );
1518  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis + 1 ) );
1519  }
1520 
1521  //======================================== This fold seems reasonable, save it
1522  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis ) );
1523  }
1524  }
1525 
1526  //================================================ Sort and remove duplicates
1527  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1528  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1529 
1530  //================================================ Done
1531  return ;
1532 
1533 }
1534 
1542 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 )
1543 {
1544  //================================================ Initialise local variables
1545  proshade_double soughtAngle, minSphereVal;
1546  proshade_unsign minSpherePos = 0;
1547 
1548  //================================================ Generate expected angles and check if close-by sphere exists
1549  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1550  {
1551  //============================================ Set variables for the iteration
1552  minSphereVal = 999.9;
1553  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1554 
1555  //============================================ Find the closest sphere passing conditions
1556  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1557  {
1558  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1559  {
1560  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1561  {
1562  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1563  minSpherePos = angsIt;
1564  }
1565  }
1566  }
1567 
1568  //============================================ If no passing sphere, test next fold
1569  const FloatingPoint< proshade_double > lhs1 ( minSphereVal ), rhs1 ( 999.9 );
1570  if ( lhs1.AlmostEquals ( rhs1 ) ) { break; }
1571 
1572  //============================================ Save best position
1573  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1574  }
1575 
1576  //================================================ Done
1577  return ;
1578 
1579 }
1580 
1581 
1590 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 )
1591 {
1592  //================================================ Initialise variables
1593  proshade_double curPosVal;
1594  *bestPosVal = -1.0;
1595  if ( this->latFromInds > this->latToInds ) { this->latToInds += static_cast< proshade_double > ( this->dimension ); }
1596  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += static_cast< proshade_double > ( this->dimension ); }
1597 
1598  //================================================ Compute the best average peak height axis for peak indices
1599  for ( proshade_unsign latIt = static_cast< proshade_unsign > ( this->latFromInds ); latIt <= static_cast< proshade_unsign > ( this->latToInds ); latIt++ )
1600  {
1601  //============================================ Deal with boundaries
1602  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= static_cast< proshade_double > ( this->dimension ); }
1603 
1604  for ( proshade_unsign lonIt = static_cast< proshade_unsign > ( this->lonFromInds ); lonIt <= static_cast< proshade_unsign > ( this->lonToInds ); lonIt++ )
1605  {
1606  //======================================== Deal with boundaries
1607  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= static_cast< proshade_double > ( this->dimension ); }
1608 
1609  //======================================== Initialise variables
1610  curPosVal = 1.0;
1611 
1612  //======================================== Find this indices value
1613  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1614  {
1615  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1616  }
1617 
1618  //======================================== If best, save it
1619  if ( curPosVal > *bestPosVal )
1620  {
1621  *bestPosVal = curPosVal;
1622  *bestLatInd = static_cast< proshade_double > ( latIt );
1623  *bestLonInd = static_cast< proshade_double > ( lonIt );
1624  }
1625  }
1626  }
1627 
1628  //================================================ Done
1629  return ;
1630 
1631 }
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:336
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:390
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMinRadius
proshade_double getMinRadius(void)
Accessor function for the private variable minimal radius.
Definition: ProSHADE_spheres.cpp:713
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereNumber
proshade_unsign getSphereNumber(void)
Accessor function for the private variable sphere number.
Definition: ProSHADE_spheres.cpp:735
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:442
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatToIndices
proshade_double getLatToIndices(void)
Accessor function for the private variable latToInds.
Definition: ProSHADE_spheres.cpp:1303
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:668
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders
proshade_signed angularDistanceWithBorders(proshade_signed origLat, proshade_signed testedLat)
This function takes two lattitude or longitude positions and finds the smallest distance between them...
Definition: ProSHADE_spheres.cpp:1106
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::computeCornerPositions
void computeCornerPositions(void)
This function computes the group corner vectors, saving results into internal variables.
Definition: ProSHADE_spheres.cpp:1076
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatFromIndices
proshade_double getLatFromIndices(void)
Accessor function for the private variable latFromInds.
Definition: ProSHADE_spheres.cpp:1292
ProSHADE_internal_maths::getSOFTPositionFromEulerZXZ
void getSOFTPositionFromEulerZXZ(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 (ZXZ convention).
Definition: ProSHADE_maths.cpp:988
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRepresentedAngle
proshade_double getRepresentedAngle(void)
Accessor function for the private variable represented angle.
Definition: ProSHADE_spheres.cpp:724
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:1542
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:260
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:627
ProSHADE_internal_maths::getEulerZXZFromAngleAxis
void getEulerZXZFromAngleAxis(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 ZXZ angles representation.
Definition: ProSHADE_maths.cpp:1602
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:2400
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpherePositions
std::vector< proshade_unsign > getSpherePositions(void)
Accessor function for the private variable spherePositions.
Definition: ProSHADE_spheres.cpp:1336
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:2370
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMaxRadius
proshade_double getMaxRadius(void)
Accessor function for the private variable maximum radius.
Definition: ProSHADE_spheres.cpp:691
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:1479
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:537
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:1437
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:921
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:367
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::removeSmallPeaks
void removeSmallPeaks(proshade_double peakThres)
Function for removing peaks with too small height.
Definition: ProSHADE_spheres.cpp:983
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:1026
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::checkIfPeakBelongs
bool checkIfPeakBelongs(proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_double cosTol, proshade_signed verbose)
This function takes a new prospective peak and tests if it belongs to this peak group or not.
Definition: ProSHADE_spheres.cpp:1134
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)
Constructor for getting empty ProSHADE_sphere class.
Definition: ProSHADE_spheres.cpp:46
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:121
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:416
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonToIndices
proshade_double getLonToIndices(void)
Accessor function for the private variable lonToInds.
Definition: ProSHADE_spheres.cpp:1325
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::ProSHADE_rotFun_sphere
ProSHADE_rotFun_sphere(proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_double repAng, proshade_unsign sphNo)
Constructor for getting empty ProSHADE_rotFun_sphere class.
Definition: ProSHADE_spheres.cpp:645
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:861
ProSHADE_internal_spheres::ProSHADE_sphere::~ProSHADE_sphere
~ProSHADE_sphere(void)
Destructor for the ProSHADE_sphere class.
Definition: ProSHADE_spheres.cpp:102
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:561
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonFromIndices
proshade_double getLonFromIndices(void)
Accessor function for the private variable lonFromInds.
Definition: ProSHADE_spheres.cpp:1314
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:67
ProSHADE_internal_spheres::autoDetermineBandwidth
proshade_unsign autoDetermineBandwidth(proshade_unsign circumference)
This function determines the bandwidth for the spherical harmonics computation.
Definition: ProSHADE_spheres.cpp:515
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getBestIndexForFold
void getBestIndexForFold(proshade_double *bestPosVal, proshade_double *bestLatInd, proshade_double *bestLonInd, std::vector< proshade_unsign > *spheresFormingFold, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals)
Function which does simple search through all peak groups indices and saves the index with the highes...
Definition: ProSHADE_spheres.cpp:1590
ProSHADE_internal_misc::addToUnsignVector
void addToUnsignVector(std::vector< proshade_unsign > *vecToAddTo, proshade_unsign elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:99
ProSHADE_internal_spheres::ProSHADE_sphere::getLocalAngRes
proshade_unsign getLocalAngRes(void)
This function returns the local angular resolution.
Definition: ProSHADE_spheres.cpp:403
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:287
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRadius
proshade_double getRadius(void)
Accessor function for the private variable radius.
Definition: ProSHADE_spheres.cpp:681
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)
Function detecting cyclic point groups with a particular fold in a peak group.
Definition: ProSHADE_spheres.cpp:1362
ProSHADE_internal_spheres::ProSHADE_sphere::allocateRotatedMap
void allocateRotatedMap(void)
This function allocates the rotated map memory.
Definition: ProSHADE_spheres.cpp:596
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:875
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:178
ProSHADE_internal_messages::printProgressMessage
void printProgressMessage(proshade_signed verbose, proshade_signed messageLevel, std::string message)
General stdout message printing.
Definition: ProSHADE_messages.cpp:70
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:488
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getAngularDim
proshade_unsign getAngularDim(void)
Accessor function for the private variable angular dim.
Definition: ProSHADE_spheres.cpp:702
ProSHADE_internal_spheres::ProSHADE_sphere::getShellRadius
proshade_double getShellRadius(void)
This function returns the radius of the shell in question.
Definition: ProSHADE_spheres.cpp:587
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:762
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:746
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:613
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:308
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::~ProSHADE_rotFun_spherePeakGroup
~ProSHADE_rotFun_spherePeakGroup(void)
Destructor for the ProSHADE_rotFun_spherePeakGroup class.
Definition: ProSHADE_spheres.cpp:1065