ProSHADE  0.7.6.2 (DEC 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 
920 std::vector< std::vector< proshade_double > > ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getCopyOfValues ( )
921 {
922  //================================================ Initialise variables
923  std::vector< std::vector< proshade_double > > ret ( this->angularDim );
924  std::vector< proshade_double > retHlp ( this->angularDim, 0.0 );
925 
926  //================================================ Fill in the values
927  for ( size_t lonIt = 0; lonIt < this->angularDim; lonIt++ )
928  {
929  for ( size_t latIt = 0; latIt < this->angularDim; latIt++ )
930  {
931  retHlp.at(latIt) = this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( latIt ), static_cast< proshade_unsign > ( lonIt ) );
932  }
933 
934  ret.at(lonIt) = retHlp;
935  }
936 
937  //================================================ Done
938  return ( ret );
939 
940 }
941 
949 void ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::findAllPeaks ( proshade_signed noSmNeighbours, std::vector< proshade_double >* allHeights )
950 {
951  //================================================ Initialise local variables
952  proshade_double currentHeight;
953  proshade_signed nbLat, nbLon;
954  bool isPeak;
955 
956  //================================================ Find all peaks
957  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
958  {
959  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
960  {
961  //======================================== Initialise peak search
962  currentHeight = this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( latIt ), static_cast< proshade_unsign > ( lonIt ) );
963  isPeak = true;
964 
965  //======================================== Find all neighbours in the same sphere
966  for ( proshade_signed latRound = -noSmNeighbours; latRound <= noSmNeighbours; latRound++ )
967  {
968  for ( proshade_signed lonRound = -noSmNeighbours; lonRound <= noSmNeighbours; lonRound++ )
969  {
970  //================================ Ignore same point
971  if ( latRound == 0 && lonRound == 0 ) { continue; }
972 
973  //================================ Get neighbour height
974  nbLat = latIt + latRound;
975  nbLon = lonIt + lonRound;
976  if ( nbLat < 0 ) { nbLat += this->angularDim; } if ( nbLat >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLat -= this->angularDim; }
977  if ( nbLon < 0 ) { nbLon += this->angularDim; } if ( nbLon >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLon -= this->angularDim; }
978 
979  //================================ If this value is larger than the tested one, no peak
980  if ( this->getSphereLatLonPosition ( static_cast< proshade_unsign > ( nbLat ), static_cast< proshade_unsign > ( nbLon ) ) > currentHeight ) { isPeak = false; break; }
981  }
982 
983  if ( !isPeak ) { break; }
984  }
985 
986  if ( isPeak )
987  {
988  //==================================== Save!
989  this->peaks.emplace_back ( std::pair<proshade_unsign,proshade_unsign> ( latIt, lonIt ) );
990  }
991  else
992  {
993  ProSHADE_internal_misc::addToDoubleVector ( allHeights, currentHeight );
994  }
995  }
996  }
997 
998  //================================================ Done
999  return ;
1000 
1001 }
1002 
1012 {
1013  //================================================ Initialise variables
1014  proshade_double curHeight;
1015  std::vector< proshade_unsign > dels ( 0, static_cast< proshade_unsign > ( this->peaks.size() ) );
1016 
1017  //================================================ For each peak in this sphere
1018  for ( proshade_unsign peakIt = 0; peakIt < static_cast<proshade_unsign> ( this->peaks.size() ); peakIt++ )
1019  {
1020  //============================================ Find the peak height
1021  curHeight = this->getSphereLatLonPosition ( this->peaks.at(peakIt).first, this->peaks.at(peakIt).second );
1022 
1023  //============================================ Should this peak be deleted?
1024  if ( curHeight < peakThres )
1025  {
1027  }
1028  }
1029 
1030  //================================================ Descending sort to avoid changing the order
1031  std::sort ( dels.begin(), dels.end(), std::greater <proshade_unsign>() );
1032 
1033  //================================================ Delete the low peaks
1034  for ( proshade_unsign delIt = 0; delIt < static_cast< proshade_unsign > ( dels.size() ); delIt++ )
1035  {
1036  this->peaks.erase ( this->peaks.begin() + static_cast< long int > ( dels.at(delIt) ) );
1037  }
1038 
1039  //================================================ Done
1040  return ;
1041 
1042 }
1043 
1054 ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::ProSHADE_rotFun_spherePeakGroup ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_unsign angDim )
1055 {
1056  //================================================ Compute the run-specific values
1057  this->dimension = angDim;
1058  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1059  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1060 
1061  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1062  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1063  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1064  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1065  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1066  this->latFromInds = lat;
1067  this->latToInds = lat;
1068  this->lonFromInds = lon;
1069  this->lonToInds = lon;
1070  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1071 
1072  //================================================ Allocate memory for similarity positions
1073  this->latMinLonMinXYZ = new proshade_double[3];
1074  this->latMaxLonMinXYZ = new proshade_double[3];
1075  this->latMinLonMaxXYZ = new proshade_double[3];
1076  this->latMaxLonMaxXYZ = new proshade_double[3];
1077  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1078  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1079  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1080  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1081 
1082  //================================================ Compute corner vectors
1083  this->computeCornerPositions ( );
1084 
1085  //================================================ Done
1086 
1087 }
1088 
1094 {
1095  //================================================ Release the XYZ arrays
1096  delete[] this->latMinLonMinXYZ;
1097  delete[] this->latMaxLonMinXYZ;
1098  delete[] this->latMinLonMaxXYZ;
1099  delete[] this->latMaxLonMaxXYZ;
1100 }
1101 
1105 {
1106  //================================================ Compute corner vectors
1107  this->latMinLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latFrom );
1108  this->latMinLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latFrom );
1109  this->latMinLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1110 
1111  this->latMaxLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latTo );
1112  this->latMaxLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latTo );
1113  this->latMaxLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1114 
1115  this->latMinLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latFrom );
1116  this->latMinLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latFrom );
1117  this->latMinLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1118 
1119  this->latMaxLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latTo );
1120  this->latMaxLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latTo );
1121  this->latMaxLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1122 
1123  //================================================ Done
1124  return ;
1125 
1126 }
1127 
1134 proshade_signed ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders ( proshade_signed newAngul, proshade_signed currentAngul )
1135 {
1136  //================================================ Initialise variables
1137  proshade_signed smallerAngul = newAngul - static_cast< proshade_signed > ( this->dimension );
1138  proshade_signed largerAngul = newAngul + static_cast< proshade_signed > ( this->dimension );
1139 
1140  //================================================ Find the smallest distance
1141  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1142 
1143  //================================================ Done
1144  return ( ret );
1145 
1146 }
1147 
1163 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 )
1164 {
1165  //================================================ Initialise local variables
1166  bool peakAdded = false;
1167  std::stringstream hlpSS;
1168  std::stringstream hlpSS2;
1169 
1170  //================================================ Compute peaks XYZ and its cosine distance to group corners
1171  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1172  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1173  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1174  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1175 
1176  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMinXYZ[0], this->latMinLonMinXYZ[1], this->latMinLonMinXYZ[2], cosTol ) ) { peakAdded = true; hlpSS2 << this->latMinLonMinXYZ[0] << " ; " << this->latMinLonMinXYZ[1] << " ; " << this->latMinLonMinXYZ[2]; }
1177  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMinXYZ[0], this->latMaxLonMinXYZ[1], this->latMaxLonMinXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMinXYZ[0] << " ; " << this->latMaxLonMinXYZ[1] << " ; " << this->latMaxLonMinXYZ[2]; }
1178  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMinLonMaxXYZ[0], this->latMinLonMaxXYZ[1], this->latMinLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMinLonMaxXYZ[0] << " ; " << this->latMinLonMaxXYZ[1] << " ; " << this->latMinLonMaxXYZ[2]; }
1179  if ( ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection ( xPos, yPos, zPos, this->latMaxLonMaxXYZ[0], this->latMaxLonMaxXYZ[1], this->latMaxLonMaxXYZ[2], cosTol ) && !peakAdded ) { peakAdded = true; hlpSS2 << this->latMaxLonMaxXYZ[0] << " ; " << this->latMaxLonMaxXYZ[1] << " ; " << this->latMaxLonMaxXYZ[2]; }
1180 
1181  //================================================ If peak within corners, add it
1182  if ( peakAdded )
1183  {
1184  //============================================ Report progress
1185  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1186  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str(), messageShift );
1187 
1188  //============================================ Initialise local variables
1189  proshade_signed largerCorner, smallerCorner;
1190  bool latCornersDone = false;
1191  bool lonCornersDone = false;
1192 
1193  //============================================ Check if lattitude boundaries need to be modified
1194  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1195  {
1196  //======================================== Lattitude is outside of group boundaries
1197  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1198  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1199 
1200  if ( smallerCorner < largerCorner )
1201  {
1202  this->latFromInds = lat;
1203  latCornersDone = true;
1204  }
1205  if ( smallerCorner > largerCorner )
1206  {
1207  this->latToInds = lat;
1208  latCornersDone = true;
1209  }
1210  if ( smallerCorner == largerCorner )
1211  {
1212  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1213  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1214  }
1215  }
1216 
1217  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1218  {
1219  //======================================== Lattitude is outside of group boundaries
1220  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latFromInds ) );
1221  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lat ), static_cast< proshade_signed > ( this->latToInds ) );
1222 
1223  if ( smallerCorner < largerCorner )
1224  {
1225  this->latFromInds = lat;
1226  latCornersDone = true;
1227  }
1228  if ( smallerCorner > largerCorner )
1229  {
1230  this->latToInds = lat;
1231  latCornersDone = true;
1232  }
1233  if ( smallerCorner == largerCorner )
1234  {
1235  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1236  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1237  }
1238  }
1239 
1240 
1241  //============================================ Check if longitude boundaries need to be modified
1242  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1243  {
1244  //======================================== Lattitude is outside of group boundaries
1245  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1246  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1247 
1248  if ( smallerCorner < largerCorner )
1249  {
1250  this->lonFromInds = lon;
1251  lonCornersDone = true;
1252  }
1253  if ( smallerCorner > largerCorner )
1254  {
1255  this->lonToInds = lon;
1256  lonCornersDone = true;
1257  }
1258  if ( smallerCorner == largerCorner )
1259  {
1260  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1261  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1262  }
1263  }
1264 
1265  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1266  {
1267  //======================================== Lattitude is outside of group boundaries
1268  smallerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonFromInds ) );
1269  largerCorner = angularDistanceWithBorders ( static_cast< proshade_signed > ( lon ), static_cast< proshade_signed > ( this->lonToInds ) );
1270 
1271  if ( smallerCorner < largerCorner )
1272  {
1273  this->lonFromInds = lon;
1274  lonCornersDone = true;
1275  }
1276  if ( smallerCorner > largerCorner )
1277  {
1278  this->lonToInds = lon;
1279  lonCornersDone = true;
1280  }
1281  if ( smallerCorner == largerCorner )
1282  {
1283  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1284  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1285  }
1286  }
1287 
1288  //============================================ Modify corner positions
1289  if ( latCornersDone )
1290  {
1291  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1292  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1293  }
1294 
1295  if ( lonCornersDone )
1296  {
1297  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1298  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1299  }
1300 
1301  //============================================ Compute corner vectors
1302  this->computeCornerPositions ( );
1303  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1304  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str(), messageShift );
1305 
1306  //============================================ If new sphere, add it to the list
1307  bool isSphereNew = true;
1308  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1309  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1310  }
1311 
1312  //================================================ Done
1313  return ( peakAdded );
1314 
1315 }
1316 
1322 {
1323  //================================================ Done
1324  return ( this->latFromInds );
1325 
1326 }
1327 
1333 {
1334  //================================================ Done
1335  return ( this->latToInds );
1336 
1337 }
1338 
1344 {
1345  //================================================ Done
1346  return ( this->lonFromInds );
1347 
1348 }
1349 
1355 {
1356  //================================================ Done
1357  return ( this->lonToInds );
1358 
1359 }
1360 
1366 {
1367  //================================================ Done
1368  return ( this->spherePositions );
1369 
1370 }
1371 
1392 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 )
1393 {
1394  //================================================ Check that this peak group has all the angles
1395  if ( ( fold - 1 ) != spherePositions.size() ) { return ; }
1396 
1397  //================================================ Initialise variables
1398  proshade_double bestPosVal, bestLatInd, bestLonInd;
1399  std::vector< proshade_unsign > spheresFormingFold;
1400 
1401  //================================================ Set all supplied spheres to be required to form the fold
1402  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1403  {
1404  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1405  }
1406 
1407  //================================================ Find the index with the highest peak height sum
1408  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1409 
1410  //================================================ Optimise by bicubic interpolation if required
1411  if ( bicubicInterp )
1412  {
1413  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1414  }
1415 
1416  //================================================ Create ProSHADE symmetry axis array and save it
1417  proshade_double* detectedSymmetry = new proshade_double[7];
1418  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1419 
1420  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1421  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1422  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1423  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1424  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1425  detectedSymmetry[5] = ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 );
1426  detectedSymmetry[6] = -std::numeric_limits < proshade_double >::infinity();
1427 
1428  //================================================ Make sure max is positive
1429  const FloatingPoint< proshade_double > lhs1 ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) );
1430  const FloatingPoint< proshade_double > rhs1 ( std::abs ( detectedSymmetry[1] ) );
1431  const FloatingPoint< proshade_double > rhs2 ( std::abs ( detectedSymmetry[2] ) );
1432  const FloatingPoint< proshade_double > rhs3 ( std::abs ( detectedSymmetry[3] ) );
1433  if ( ( lhs1.AlmostEquals ( rhs1 ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1434  ( lhs1.AlmostEquals ( rhs2 ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1435  ( lhs1.AlmostEquals ( rhs3 ) && ( detectedSymmetry[3] < 0.0 ) ) )
1436  {
1437  detectedSymmetry[1] *= -1.0;
1438  detectedSymmetry[2] *= -1.0;
1439  detectedSymmetry[3] *= -1.0;
1440  detectedSymmetry[4] *= -1.0;
1441  }
1442 
1443  //================================================ Check for decimal underflows. They are not an issue as rounding to zero is fine, but having negative sign to zero will switch the signs and cause problems.
1444  const FloatingPoint< proshade_double > llhs1 ( detectedSymmetry[1] ), llhs2 ( detectedSymmetry[2] ), llhs3 ( detectedSymmetry[3] ), rrhs1 ( 0.0 );
1445  if ( llhs1.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[1] = 0.0; }
1446  if ( llhs2.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[2] = 0.0; }
1447  if ( llhs3.AlmostEquals ( rrhs1 ) ) { detectedSymmetry[3] = 0.0; }
1448 
1449  //================================================ Save detected point group
1450  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1451 
1452  //================================================ Report progress
1453  std::stringstream hlpSS;
1454  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1455  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str(), messageShift );
1456 
1457  //================================================ Done
1458  return ;
1459 
1460 }
1461 
1467 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences ( std::vector< proshade_double >* angDiffs, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals )
1468 {
1469  //================================================ Initialise local variables
1470  std::vector< proshade_double > angs;
1471 
1472  //================================================ Find all present angles
1473  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1474  {
1475  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1476  }
1477 
1478  //================================================ Find all angle differences
1479  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1480  {
1481  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1482  {
1483  //======================================== Use unique combinations only
1484  if ( ang1It >= ang2It ) { continue; }
1485 
1486  //======================================== Add angle difference rounded to 5 decimal places
1487  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1488  }
1489  }
1490 
1491  //================================================ Sort and remove duplicates
1492  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1493  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1494 
1495  //================================================ Done
1496  return ;
1497 
1498 }
1499 
1509 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds ( std::vector< proshade_double >* angDiffs, std::vector< proshade_unsign >* foldsToTry )
1510 {
1511  //================================================ Initialise local variables
1512  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1513  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1514 
1515  //================================================ For each angle difference in the group
1516  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1517  {
1518  //============================================ Find the basis and remainder of the 2pi/dist equation
1519  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1520 
1521  //============================================ If the remainder would be smaller for larger basis, so change the basis
1522  if ( divRem > 0.5 )
1523  {
1524  divRem -= 1.0;
1525  divBasis += 1.0;
1526  }
1527 
1528  //============================================ Remove fold 1, that is not really what we are after here ...
1529  const FloatingPoint< proshade_double > lhs1 ( divBasis ), rhs1 ( 1.0 );
1530  if ( lhs1.AlmostEquals ( rhs1 ) ) { continue; }
1531 
1532  //============================================ Is there enough angles in the group for such a fold?
1533  if ( static_cast< proshade_double > ( this->spherePositions.size() ) < ( divBasis - 1.0 ) ) { continue; }
1534 
1535  //============================================ Determine errors on peaks and on folds
1536  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1537  angTolerance = std::abs( symmErr / peakErr );
1538  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1539 
1540  //============================================ Is remainder small enough?
1541  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1542  {
1543  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1544  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1545  {
1546  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1547  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis - 1 ) );
1548  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis + 1 ) );
1549  }
1550 
1551  //======================================== This fold seems reasonable, save it
1552  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, static_cast< proshade_unsign > ( divBasis ) );
1553  }
1554  }
1555 
1556  //================================================ Sort and remove duplicates
1557  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1558  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1559 
1560  //================================================ Done
1561  return ;
1562 
1563 }
1564 
1572 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 )
1573 {
1574  //================================================ Initialise local variables
1575  proshade_double soughtAngle, minSphereVal;
1576  proshade_unsign minSpherePos = 0;
1577 
1578  //================================================ Generate expected angles and check if close-by sphere exists
1579  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1580  {
1581  //============================================ Set variables for the iteration
1582  minSphereVal = 999.9;
1583  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1584 
1585  //============================================ Find the closest sphere passing conditions
1586  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1587  {
1588  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1589  {
1590  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1591  {
1592  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1593  minSpherePos = angsIt;
1594  }
1595  }
1596  }
1597 
1598  //============================================ If no passing sphere, test next fold
1599  const FloatingPoint< proshade_double > lhs1 ( minSphereVal ), rhs1 ( 999.9 );
1600  if ( lhs1.AlmostEquals ( rhs1 ) ) { break; }
1601 
1602  //============================================ Save best position
1603  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1604  }
1605 
1606  //================================================ Done
1607  return ;
1608 
1609 }
1610 
1611 
1620 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 )
1621 {
1622  //================================================ Initialise variables
1623  proshade_double curPosVal;
1624  *bestPosVal = -1.0;
1625  if ( this->latFromInds > this->latToInds ) { this->latToInds += static_cast< proshade_double > ( this->dimension ); }
1626  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += static_cast< proshade_double > ( this->dimension ); }
1627 
1628  //================================================ Compute the best average peak height axis for peak indices
1629  for ( proshade_unsign latIt = static_cast< proshade_unsign > ( this->latFromInds ); latIt <= static_cast< proshade_unsign > ( this->latToInds ); latIt++ )
1630  {
1631  //============================================ Deal with boundaries
1632  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= static_cast< proshade_double > ( this->dimension ); }
1633 
1634  for ( proshade_unsign lonIt = static_cast< proshade_unsign > ( this->lonFromInds ); lonIt <= static_cast< proshade_unsign > ( this->lonToInds ); lonIt++ )
1635  {
1636  //======================================== Deal with boundaries
1637  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= static_cast< proshade_double > ( this->dimension ); }
1638 
1639  //======================================== Initialise variables
1640  curPosVal = 1.0;
1641 
1642  //======================================== Find this indices value
1643  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1644  {
1645  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1646  }
1647 
1648  //======================================== If best, save it
1649  if ( curPosVal > *bestPosVal )
1650  {
1651  *bestPosVal = curPosVal;
1652  *bestLatInd = static_cast< proshade_double > ( latIt );
1653  *bestLonInd = static_cast< proshade_double > ( lonIt );
1654  }
1655  }
1656  }
1657 
1658  //================================================ Done
1659  return ;
1660 
1661 }
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:1332
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:1134
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::computeCornerPositions
void computeCornerPositions(void)
This function computes the group corner vectors, saving results into internal variables.
Definition: ProSHADE_spheres.cpp:1104
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatFromIndices
proshade_double getLatFromIndices(void)
Accessor function for the private variable latFromInds.
Definition: ProSHADE_spheres.cpp:1321
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::getCopyOfValues
std::vector< std::vector< proshade_double > > getCopyOfValues(void)
Function for obtaining a copy of all sphere values.
Definition: ProSHADE_spheres.cpp:920
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:1572
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:1613
ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation
void optimiseAxisBiCubicInterpolation(proshade_double *bestLattitude, proshade_double *bestLongitude, proshade_double *bestSum, std::vector< proshade_unsign > *sphereList, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > *sphereMappedRotFun, proshade_double step=0.05)
This function provides axis optimisation given starting lattitude and longitude indices.
Definition: ProSHADE_maths.cpp:2653
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpherePositions
std::vector< proshade_unsign > getSpherePositions(void)
Accessor function for the private variable spherePositions.
Definition: ProSHADE_spheres.cpp:1365
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)
This function takes a new prospective peak and tests if it belongs to this peak group or not.
Definition: ProSHADE_spheres.cpp:1163
ProSHADE_internal_misc::addToDoubleVector
void addToDoubleVector(std::vector< proshade_double > *vecToAddTo, proshade_double elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:77
ProSHADE_internal_maths::vectorOrientationSimilaritySameDirection
bool vectorOrientationSimilaritySameDirection(proshade_double a1, proshade_double a2, proshade_double a3, proshade_double b1, proshade_double b2, proshade_double b3, proshade_double tolerance=0.1)
This function compares two vectors using cosine distance and decides if they are similar using tolera...
Definition: ProSHADE_maths.cpp:2623
ProSHADE_internal_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:1509
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:1467
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:949
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:1011
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:1054
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:1354
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:1343
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:68
ProSHADE_internal_spheres::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:1620
ProSHADE_internal_misc::addToUnsignVector
void addToUnsignVector(std::vector< proshade_unsign > *vecToAddTo, proshade_unsign elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:99
ProSHADE_internal_spheres::ProSHADE_sphere::getLocalAngRes
proshade_unsign getLocalAngRes(void)
This function returns the local angular resolution.
Definition: ProSHADE_spheres.cpp:403
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:1392
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_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, proshade_signed messageShift=0)
General stdout message printing.
Definition: ProSHADE_messages.cpp:71
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:1093