ProSHADE  0.7.5.3 (FEB 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 = ( spherePos->at(0) + spherePos->at(1) ) / 2.0;
51  this->sphereRadius = 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.0 ); }
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, xSize, ySize, zSize );
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 = NULL;
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 != NULL )
107  {
108  delete[] this->mappedDataRot;
109  }
110 }
111 
124 proshade_unsign ProSHADE_internal_spheres::ProSHADE_sphere::getMaxCircumference ( proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_double maxRange, proshade_single xSize, proshade_single ySize, proshade_single zSize )
125 {
126  //================================================ Find from and to limits on indices
127  proshade_signed xFromInd = static_cast<proshade_signed> ( xDimMax / 2 ) -
128  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
129  proshade_signed yFromInd = static_cast<proshade_signed> ( yDimMax / 2 ) -
130  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
131  proshade_signed zFromInd = static_cast<proshade_signed> ( zDimMax / 2 ) -
132  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
133 
134  proshade_signed xToInd = static_cast<proshade_signed> ( xDimMax / 2 ) +
135  static_cast<proshade_signed> ( (maxRange/2) / this->xDimSampling );
136  proshade_signed yToInd = static_cast<proshade_signed> ( yDimMax / 2 ) +
137  static_cast<proshade_signed> ( (maxRange/2) / this->yDimSampling );
138  proshade_signed zToInd = static_cast<proshade_signed> ( zDimMax / 2 ) +
139  static_cast<proshade_signed> ( (maxRange/2) / this->zDimSampling );
140 
141  //================================================ Check for bounds
142  if ( xFromInd < 0 ) { xFromInd = 0; }
143  if ( yFromInd < 0 ) { yFromInd = 0; }
144  if ( zFromInd < 0 ) { zFromInd = 0; }
145  if ( xToInd > static_cast<proshade_signed> ( xDimMax ) ) { xToInd = xDimMax; }
146  if ( yToInd > static_cast<proshade_signed> ( yDimMax ) ) { yToInd = yDimMax; }
147  if ( zToInd > static_cast<proshade_signed> ( zDimMax ) ) { zToInd = zDimMax; }
148 
149  //================================================ Get dim sizes
150  proshade_unsign xDimSZ = xToInd - xFromInd;
151  proshade_unsign yDimSZ = yToInd - yFromInd;
152  proshade_unsign zDimSZ = zToInd - zFromInd;
153 
154  //================================================ check for too sparse sampling
155  if ( ( xDimSZ == 0 ) && ( yDimSZ == 0 ) && ( zDimSZ == 0 ) ) { xDimSZ = 1; yDimSZ = 1; zDimSZ = 1; }
156 
157  //================================================ Find max and mid dims
158  std::vector<proshade_unsign> dimSizes;
159  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, xDimSZ );
160  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, yDimSZ );
161  ProSHADE_internal_misc::addToUnsignVector ( &dimSizes, zDimSZ );
162  std::sort ( dimSizes.begin(), dimSizes.end() );
163  proshade_unsign maxDim = dimSizes.at(2);
164  proshade_unsign midDim = dimSizes.at(1);
165 
166  //================================================ Return max circumference
167  return ( maxDim + midDim );
168 }
169 
181 void ProSHADE_internal_spheres::ProSHADE_sphere::mapData ( proshade_double* map, proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax )
182 {
183  //================================================ Initialise local variavles
184  proshade_double x, y, z, xRelative, yRelative, zRelative;
185  proshade_signed xBottom, yBottom, zBottom, xTop, yTop, zTop;
186  std::vector<proshade_double> lonCO ( this->localAngRes + 1 );
187  std::vector<proshade_double> latCO ( this->localAngRes + 1 );
188  std::vector<proshade_double> c000 = std::vector<proshade_double> ( 4 );
189  std::vector<proshade_double> c001 = std::vector<proshade_double> ( 4 );
190  std::vector<proshade_double> c010 = std::vector<proshade_double> ( 4 );
191  std::vector<proshade_double> c011 = std::vector<proshade_double> ( 4 );
192  std::vector<proshade_double> c100 = std::vector<proshade_double> ( 4 );
193  std::vector<proshade_double> c101 = std::vector<proshade_double> ( 4 );
194  std::vector<proshade_double> c110 = std::vector<proshade_double> ( 4 );
195  std::vector<proshade_double> c111 = std::vector<proshade_double> ( 4 );
196  std::vector<proshade_double> c00 = std::vector<proshade_double> ( 4 );
197  std::vector<proshade_double> c01 = std::vector<proshade_double> ( 4 );
198  std::vector<proshade_double> c10 = std::vector<proshade_double> ( 4 );
199  std::vector<proshade_double> c11 = std::vector<proshade_double> ( 4 );
200  std::vector<proshade_double> c0 = std::vector<proshade_double> ( 4 );
201  std::vector<proshade_double> c1 = std::vector<proshade_double> ( 4 );
202 
203  //================================================ Find pixelisation cutOffs
204  this->getLongitudeCutoffs ( &lonCO );
205  this->getLattitudeCutoffs ( &latCO );
206 
207  //================================================ Interpolate the map onto this shell
208  for ( unsigned int thIt = 0; thIt < this->localAngRes; thIt++ )
209  {
210  for ( unsigned int phIt = 0; phIt < this->localAngRes; phIt++ )
211  {
212  //======================================== Get grid point x, y and z
213  this->getInterpolationXYZ ( &x, &y, &z, thIt, &lonCO, phIt, &latCO );
214 
215  //======================================== Find 8 closest point around the grid point in indices
216  this->getXYZTopBottoms ( xDimMax, yDimMax, zDimMax, x, y, z, &xBottom, &yBottom, &zBottom, &xTop, &yTop, &zTop );
217 
218  //======================================== Get the 8 closest points interpolation vectors (or set to 0 if out-of-bounds)
219  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zBottom, &c000 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
220  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yBottom, zTop , &c001 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
221  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zBottom, &c010 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
222  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xBottom, yTop , zTop , &c011 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
223  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zBottom, &c100 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
224  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yBottom, zTop , &c101 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
225  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zBottom, &c110 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
226  if ( !getMapPoint ( map, xDimMax, yDimMax, zDimMax, xTop , yTop , zTop , &c111 ) ) { this->mappedData[phIt * this->localAngRes + thIt] = 0.0; continue; }
227 
228  //======================================== Interpolate along X axis
229  xRelative = ( x - ( ( xBottom - static_cast<proshade_signed> ( ( ( xDimMax ) / 2 ) ) ) * this->xDimSampling ) ) / this->xDimSampling;
230  this->interpolateAlongFirst ( c000, c001, c010, c011, c100, c101, c110, c111, &c00, &c01, &c10, &c11, xRelative );
231 
232  //======================================== Interpolate along Y axis
233  yRelative = ( y - ( ( yBottom - static_cast<proshade_signed> ( ( ( yDimMax ) / 2 ) ) ) * this->yDimSampling ) ) / this->yDimSampling;
234  this->interpolateAlongSecond ( c00, c01, c10, c11, &c0, &c1, yRelative );
235 
236  //======================================== Save the resulting value
237  zRelative = ( z - ( ( zBottom - static_cast<proshade_signed> ( ( ( zDimMax ) / 2 ) ) ) * this->zDimSampling ) ) / this->zDimSampling;
238  this->mappedData[phIt * this->localAngRes + thIt] = ( c0.at(3) * ( 1.0 - zRelative ) ) + ( c1.at(3) * zRelative );
239  }
240  }
241 
242  //================================================ Done
243  return ;
244 
245 }
246 
263 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 )
264 {
265  //================================================ Initialise local variables
266  proshade_signed posIter = zPos + zDimMax * ( yPos + yDimMax * xPos );
267 
268  //================================================ Check of out-of-bounds shells
269  if ( ( xPos < 0 ) || ( xPos >= static_cast<proshade_signed> ( xDimMax ) ) ) { return ( false ); }
270  if ( ( yPos < 0 ) || ( yPos >= static_cast<proshade_signed> ( yDimMax ) ) ) { return ( false ); }
271  if ( ( zPos < 0 ) || ( zPos >= static_cast<proshade_signed> ( zDimMax ) ) ) { return ( false ); }
272 
273  //================================================ Get the interpolation values
274  interpVec->at(0) = static_cast<proshade_double> ( xPos * this->xDimSampling );
275  interpVec->at(1) = static_cast<proshade_double> ( yPos * this->yDimSampling );
276  interpVec->at(2) = static_cast<proshade_double> ( zPos * this->zDimSampling );
277  interpVec->at(3) = map[posIter];
278 
279  //================================================ Done
280  return ( true );
281 
282 }
283 
290 void ProSHADE_internal_spheres::ProSHADE_sphere::getLongitudeCutoffs ( std::vector<proshade_double>* lonCO )
291 {
292  //================================================ Get the cut-offs
293  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
294  {
295  lonCO->at(iter) = static_cast<proshade_double> ( iter ) *
296  ( ( static_cast<proshade_double> ( M_PI ) * 2.0 ) / static_cast<proshade_double> ( this->localAngRes ) ) -
297  ( static_cast<proshade_double> ( M_PI ) );
298  }
299 
300  //================================================ Done
301  return ;
302 
303 }
304 
311 void ProSHADE_internal_spheres::ProSHADE_sphere::getLattitudeCutoffs ( std::vector<proshade_double>* latCO )
312 {
313  //================================================ Get the cut-offs
314  for ( proshade_unsign iter = 0; iter <= this->localAngRes; iter++ )
315  {
316  latCO->at(iter) = ( static_cast<proshade_double> ( iter ) *
317  ( static_cast<proshade_double> ( M_PI ) / static_cast<proshade_double> ( this->localAngRes ) ) -
318  ( static_cast<proshade_double> ( M_PI ) / 2.0 ) );
319  }
320 
321  //================================================ Done
322  return ;
323 
324 }
325 
339 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 )
340 {
341  //================================================ Compute and save XYZ interpolation positions
342  *x = this->sphereRadius * cos( ( lonCO->at(thetaIt) + lonCO->at(thetaIt+1) ) / 2.0 ) *
343  cos( ( latCO->at(phiIt) + latCO->at(phiIt+1) ) / 2.0 );
344  *y = this->sphereRadius * sin( ( lonCO->at(thetaIt) + lonCO->at(thetaIt+1) ) / 2.0 ) *
345  cos( ( latCO->at(phiIt) + latCO->at(phiIt+1) ) / 2.0 );
346  *z = this->sphereRadius * sin( ( latCO->at(phiIt) + latCO->at(phiIt+1) ) / 2.0 );
347 
348  //================================================ Done
349  return ;
350 
351 }
352 
370 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 )
371 {
372  //================================================ Get the values
373  *xBottom = std::floor ( (x / this->xDimSampling) ) + (xDimMax/2);
374  *yBottom = std::floor ( (y / this->yDimSampling) ) + (yDimMax/2);
375  *zBottom = std::floor ( (z / this->zDimSampling) ) + (zDimMax/2);
376 
377  *xTop = *xBottom + 1;
378  *yTop = *yBottom + 1;
379  *zTop = *zBottom + 1;
380 
381  //================================================ Done
382  return ;
383 
384 }
385 
394 {
395  //================================================ Return the value
396  return ( this->localBandwidth );
397 }
398 
407 {
408  //================================================ Return the value
409  return ( this->localAngRes );
410 }
411 
420 {
421  //================================================ Return the value
422  return ( this->mappedData );
423 }
424 
445 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 )
446 {
447  //================================================ Interpolate for the less less point
448  c00->at(0) = ( this->xDimSampling * xd ) + c000.at(0);
449  c00->at(1) = c000.at(1);
450  c00->at(2) = c000.at(2);
451  c00->at(3) = ( c000.at(3) * ( 1.0 - xd ) ) + ( c100.at(3) * xd );
452 
453  //================================================ Interpolate for the less more point
454  c01->at(0) = ( this->xDimSampling * xd ) + c001.at(0);
455  c01->at(1) = c001.at(1);
456  c01->at(2) = c001.at(2);
457  c01->at(3) = ( c001.at(3) * ( 1.0 - xd ) ) + ( c101.at(3) * xd );
458 
459  //================================================ Interpolate for the more less point
460  c10->at(0) = ( this->xDimSampling * xd ) + c010.at(0);
461  c10->at(1) = c010.at(1);
462  c10->at(2) = c010.at(2);
463  c10->at(3) = ( c010.at(3) * ( 1.0 - xd ) ) + ( c110.at(3) * xd );
464 
465  //================================================ Interpolate for the more more point
466  c11->at(0) = ( this->xDimSampling * xd ) + c011.at(0);
467  c11->at(1) = c011.at(1);
468  c11->at(2) = c011.at(2);
469  c11->at(3) = ( c011.at(3) * ( 1.0 - xd ) ) + ( c111.at(3) * xd );
470 
471  //================================================ Done
472  return ;
473 
474 }
475 
491 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 )
492 {
493  //================================================ Interpolate for the less point
494  c0->at(0) = c00.at(0);
495  c0->at(1) = ( this->yDimSampling * yd ) + c00.at(1);
496  c0->at(2) = c00.at(2);
497  c0->at(3) = ( c00.at(3) * ( 1.0 - yd ) ) + ( c10.at(3) * yd );
498 
499  //================================================ Interpolate for the more point
500  c1->at(0) = c01.at(0);
501  c1->at(1) = ( this->yDimSampling * yd ) + c01.at(1);
502  c1->at(2) = c01.at(2);
503  c1->at(3) = ( c01.at(3) * ( 1.0 - yd ) ) + ( c11.at(3) * yd );
504 
505  //================================================ Done
506  return ;
507 
508 }
509 
518 proshade_unsign ProSHADE_internal_spheres::autoDetermineBandwidth ( proshade_unsign circumference )
519 {
520  //================================================ Determine and return
521  if ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) % 2 == 0 )
522  {
523  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) );
524  }
525  else
526  {
527  return ( static_cast<proshade_unsign> ( std::ceil ( circumference / 2 ) ) + 1 );
528  }
529 }
530 
540 proshade_single ProSHADE_internal_spheres::autoDetermineSphereDistances ( proshade_single maxMapRange, proshade_single resolution )
541 {
542  //================================================ Get starting point
543  proshade_single ret = static_cast<proshade_single> ( resolution / 2.0 );
544 
545  //================================================ Make sure at least 10 shells will exist
546  while ( std::floor ( maxMapRange / ret ) < 10 )
547  {
548  ret /= 2.0;
549  }
550 
551  //================================================ Done
552  return ( ret );
553 }
554 
564 proshade_unsign ProSHADE_internal_spheres::autoDetermineIntegrationOrder ( proshade_single maxMapRange, proshade_single sphereDist )
565 {
566  //================================================ Initialise local variables
567  proshade_double sphereDistanceAsFractionOfTotal = static_cast<proshade_double> ( sphereDist ) / ( maxMapRange / 2.0 );
568  proshade_unsign ret = 0;
569 
570  //================================================ Compare to precomputed values
571  for ( proshade_unsign iter = 2; iter < static_cast<proshade_unsign> ( 10000 ); iter++ )
572  {
573  if ( ProSHADE_internal_precomputedVals::glIntMaxDists[iter] >= sphereDistanceAsFractionOfTotal )
574  {
575  ret = iter;
576  }
577  }
578 
579  //================================================ Return largest passing value
580  return ( ret );
581 
582 }
583 
591 {
592  //================================================ Done
593  return ( this->sphereRadius );
594 
595 }
596 
600 {
601  //================================================ Allocate memory for sphere mapping
602  this->mappedDataRot = NULL;
603  this->mappedDataRot = new proshade_double[this->localAngRes * this->localAngRes];
604  ProSHADE_internal_misc::checkMemoryAllocation ( this->mappedDataRot, __FILE__, __LINE__, __func__ );
605 
606  //================================================ Done
607  return ;
608 
609 }
610 
616 void ProSHADE_internal_spheres::ProSHADE_sphere::setRotatedMappedData ( proshade_unsign pos, proshade_double value )
617 {
618  //================================================ Set the value to the position
619  this->mappedDataRot[pos] = value;
620 
621  //================================================ Done
622  return ;
623 
624 }
625 
631 {
632  //================================================ Done
633  return ( this->mappedDataRot[pos] );
634 
635 }
636 
648 ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::ProSHADE_rotFun_sphere ( proshade_double rad, proshade_double radRange, proshade_unsign dim, proshade_double repAng, proshade_unsign sphNo )
649 {
650  //================================================ Set internal values
651  this->radius = rad;
652  this->angularDim = dim;
653  this->radiusMin = this->radius - ( radRange / 2.0 );
654  this->radiusMax = this->radius + ( radRange / 2.0 );
655  this->representedAngle = repAng;
656  this->sphereNumber = sphNo;
657 
658  //================================================ Allocate the axis field
659  this->axesValues = new proshade_double[dim*dim];
660  ProSHADE_internal_misc::checkMemoryAllocation ( this->axesValues, __FILE__, __LINE__, __func__ );
661 
662  //================================================ Fill axis field with zeroes
663  for ( proshade_unsign iter = 0; iter < ( dim * dim ); iter++ ) { this->axesValues[iter] = 0.0; }
664 
665 }
666 
672 {
673  //================================================ Release the allocated memory
674  if ( this->axesValues != nullptr )
675  {
676  delete[] this->axesValues;
677  }
678 }
679 
685 {
686  //================================================ Done
687  return ( this->radius );
688 }
689 
695 {
696  //================================================ Done
697  return ( this->radiusMax );
698 
699 }
700 
706 {
707  //================================================ Done
708  return ( this->angularDim );
709 
710 }
711 
717 {
718  //================================================ Done
719  return ( this->radiusMin );
720 
721 }
722 
728 {
729  //================================================ Done
730  return ( this->representedAngle );
731 
732 }
733 
739 {
740  //================================================ Done
741  return ( this->sphereNumber );
742 
743 }
744 
749 std::vector<std::pair<proshade_unsign,proshade_unsign>> ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getPeaks ( void )
750 {
751  //================================================ Done
752  return ( this->peaks );
753 
754 }
755 
766 {
767  //================================================ Initialise variables
768  proshade_double lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->angularDim );
769  proshade_double latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->angularDim );
770 
771  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;
772  proshade_signed xBottom, xTop, yBottom, yTop, zBottom, zTop, mapIndex;
773 
774  //================================================ For each sphere grid position
775  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
776  {
777  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
778  {
779  //======================================== Convert to XYZ position on unit sphere. The radius here is not important, as it does not change the direction of the vector.
780  lon = static_cast<proshade_double> ( lonIt ) * lonSampling;
781  lat = static_cast<proshade_double> ( latIt ) * latSampling;
782  cX = 1.0 * std::sin ( lon ) * std::cos ( lat );
783  cY = 1.0 * std::sin ( lon ) * std::sin ( lat );
784  cZ = 1.0 * std::cos ( lon );
785 
786  //======================================== Convert to ZXZ Euler angles
787  ProSHADE_internal_maths::getEulerZXZFromAngleAxis ( cX, cY, cZ, this->representedAngle, &eulerAlpha, &eulerBeta, &eulerGamma, this->angularDim );
788 
789  //======================================== Convert to SOFT map position (decimal, not indices)
790  ProSHADE_internal_maths::getSOFTPositionFromEulerZXZ ( this->angularDim / 2, eulerAlpha, eulerBeta, eulerGamma, &mapX, &mapY, &mapZ );
791 
792  //======================================== Find lower and higher points and deal with boundaries
793  xBottom = std::floor ( mapX ); if ( xBottom < 0.0 ) { xBottom += this->angularDim; } if ( xBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { xBottom -= static_cast<proshade_signed> ( this->angularDim ); }
794  yBottom = std::floor ( mapY ); if ( yBottom < 0.0 ) { yBottom += this->angularDim; } if ( yBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { yBottom -= static_cast<proshade_signed> ( this->angularDim ); }
795  zBottom = std::floor ( mapZ ); if ( zBottom < 0.0 ) { zBottom += this->angularDim; } if ( zBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { zBottom -= static_cast<proshade_signed> ( this->angularDim ); }
796  xTop = std::ceil ( mapX ); if ( xTop < 0.0 ) { xTop += this->angularDim; } if ( xTop >= static_cast<proshade_signed> ( this->angularDim ) ) { xTop -= static_cast<proshade_signed> ( this->angularDim ); }
797  yTop = std::ceil ( mapY ); if ( yTop < 0.0 ) { yTop += this->angularDim; } if ( yTop >= static_cast<proshade_signed> ( this->angularDim ) ) { yTop -= static_cast<proshade_signed> ( this->angularDim ); }
798  zTop = std::ceil ( mapZ ); if ( zTop < 0.0 ) { zTop += this->angularDim; } if ( zTop >= static_cast<proshade_signed> ( this->angularDim ) ) { zTop -= static_cast<proshade_signed> ( this->angularDim ); }
799 
800  //======================================== Start X interpolation - bottom, bottom, bottom
801  mapIndex = zBottom + this->angularDim * ( yBottom + this->angularDim * xBottom );
802  c000 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
803 
804  //======================================== X interpolation - bottom, bottom, top
805  mapIndex = zTop + this->angularDim * ( yBottom + this->angularDim * xBottom );
806  c001 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
807 
808  //======================================== X interpolation - bottom, top, bottom
809  mapIndex = zBottom + this->angularDim * ( yTop + this->angularDim * xBottom );
810  c010 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
811 
812  //======================================== X interpolation - bottom, top, top
813  mapIndex = zTop + this->angularDim * ( yTop + this->angularDim * xBottom );
814  c011 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
815 
816  //======================================== X interpolation - top, bottom, bottom
817  mapIndex = zBottom + this->angularDim * ( yBottom + this->angularDim * xTop );
818  c100 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
819 
820  //======================================== X interpolation - top, bottom, top
821  mapIndex = zTop + this->angularDim * ( yBottom + this->angularDim * xTop );
822  c101 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
823 
824  //======================================== X interpolation - top, top, bottom
825  mapIndex = zBottom + this->angularDim * ( yTop + this->angularDim * xTop );
826  c110 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
827 
828  //======================================== X interpolation - top, top, top
829  mapIndex = zTop + this->angularDim * ( yTop + this->angularDim * xTop );
830  c111 = pow( rotFun[mapIndex][0], 2.0 ) + pow( rotFun[mapIndex][1], 2.0 );
831 
832  //======================================== Solve for X
833  xRelative = mapX - std::floor( mapX );
834  c00 = ( c000 * ( 1.0 - xRelative ) ) + ( c100 * xRelative );
835  c01 = ( c001 * ( 1.0 - xRelative ) ) + ( c101 * xRelative );
836  c10 = ( c010 * ( 1.0 - xRelative ) ) + ( c110 * xRelative );
837  c11 = ( c011 * ( 1.0 - xRelative ) ) + ( c111 * xRelative );
838 
839  //======================================== Solve for Y
840  yRelative = mapY - std::floor( mapY );
841  c0 = ( c00 * ( 1.0 - yRelative ) ) + ( c10 * yRelative );
842  c1 = ( c01 * ( 1.0 - yRelative ) ) + ( c11 * yRelative );
843 
844  //======================================== Solve for Z
845  zRelative = mapZ - std::floor( mapZ );
846 
847  //======================================== Save result
848  mapIndex = lonIt + ( latIt * static_cast<proshade_unsign> ( this->angularDim ) );
849  this->axesValues[mapIndex] = ( c0 * ( 1.0 - zRelative ) ) + ( c1 * zRelative );
850  }
851  }
852 
853  //================================================ Done
854  return ;
855 
856 }
857 
864 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonPosition ( proshade_unsign lattitude, proshade_unsign longitude )
865 {
866  //================================================ Done
867  return ( this->axesValues[longitude + ( lattitude * static_cast<proshade_unsign> ( this->angularDim ) )] );
868 }
869 
878 proshade_double ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereLatLonLinearInterpolationPos ( proshade_double lattitude, proshade_double longitude )
879 {
880  //================================================ Initialise variables
881  proshade_double c00, c01, c10, c11, c0, c1, latRelative, lonRelative;
882  proshade_signed latTop, latBottom, lonTop, lonBottom, gridIndex;
883 
884  //================================================ Find lower and higher indices and deal with boundaries
885  latBottom = std::floor ( lattitude ); if ( latBottom < 0.0 ) { latBottom += this->angularDim; } if ( latBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { latBottom -= this->angularDim; }
886  lonBottom = std::floor ( longitude ); if ( lonBottom < 0.0 ) { lonBottom += this->angularDim; } if ( lonBottom >= static_cast<proshade_signed> ( this->angularDim ) ) { lonBottom -= this->angularDim; }
887  latTop = std::ceil ( lattitude ); if ( latTop < 0.0 ) { latTop += this->angularDim; } if ( latTop >= static_cast<proshade_signed> ( this->angularDim ) ) { latTop -= this->angularDim; }
888  lonTop = std::ceil ( longitude ); if ( lonTop < 0.0 ) { lonTop += this->angularDim; } if ( lonTop >= static_cast<proshade_signed> ( this->angularDim ) ) { lonTop -= this->angularDim; }
889 
890  //================================================ Interpolate
891  gridIndex = lonBottom + ( latBottom * static_cast<proshade_unsign> ( this->angularDim ) );
892  c00 = this->axesValues[gridIndex];
893 
894  gridIndex = lonBottom + ( latTop * static_cast<proshade_unsign> ( this->angularDim ) );
895  c01 = this->axesValues[gridIndex];
896 
897  gridIndex = lonTop + ( latBottom * static_cast<proshade_unsign> ( this->angularDim ) );
898  c10 = this->axesValues[gridIndex];
899 
900  gridIndex = lonTop + ( latTop * static_cast<proshade_unsign> ( this->angularDim ) );
901  c11 = this->axesValues[gridIndex];
902 
903  //================================================ Solve for longitude
904  lonRelative = longitude - std::floor( longitude );
905  c0 = ( c00 * ( 1.0 - lonRelative ) ) + ( c10 * lonRelative );
906  c1 = ( c01 * ( 1.0 - lonRelative ) ) + ( c11 * lonRelative );
907 
908  //================================================ Solve for lattitude
909  latRelative = lattitude - std::floor ( lattitude );
910  proshade_double res = ( c0 * ( 1.0 - latRelative ) ) + ( c1 * latRelative );
911 
912  //================================================ Done
913  return ( res );
914 
915 }
916 
924 void ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::findAllPeaks ( proshade_signed noSmNeighbours, std::vector< proshade_double >* allHeights )
925 {
926  //================================================ Initialise local variables
927  proshade_double currentHeight;
928  proshade_signed nbLat, nbLon;
929  bool isPeak;
930 
931  //================================================ Find all peaks
932  for ( proshade_signed latIt = 0; latIt < static_cast<proshade_signed> ( this->angularDim ); latIt++ )
933  {
934  for ( proshade_signed lonIt = 0; lonIt < static_cast<proshade_signed> ( this->angularDim ); lonIt++ )
935  {
936  //======================================== Initialise peak search
937  currentHeight = this->getSphereLatLonPosition ( latIt, lonIt );
938  isPeak = true;
939 
940  //======================================== Find all neighbours in the same sphere
941  for ( proshade_signed latRound = -noSmNeighbours; latRound <= noSmNeighbours; latRound++ )
942  {
943  for ( proshade_signed lonRound = -noSmNeighbours; lonRound <= noSmNeighbours; lonRound++ )
944  {
945  //================================ Ignore same point
946  if ( latRound == 0 && lonRound == 0 ) { continue; }
947 
948  //================================ Get neighbour height
949  nbLat = latIt + latRound;
950  nbLon = lonIt + lonRound;
951  if ( nbLat < 0 ) { nbLat += this->angularDim; } if ( nbLat >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLat -= this->angularDim; }
952  if ( nbLon < 0 ) { nbLon += this->angularDim; } if ( nbLon >= static_cast<proshade_signed> ( this->angularDim ) ) { nbLon -= this->angularDim; }
953 
954  //================================ If this value is larger than the tested one, no peak
955  if ( this->getSphereLatLonPosition ( nbLat, nbLon ) > currentHeight ) { isPeak = false; break; }
956  }
957 
958  if ( !isPeak ) { break; }
959  }
960 
961  if ( isPeak )
962  {
963  //==================================== Save!
964  this->peaks.emplace_back ( std::pair<proshade_unsign,proshade_unsign> ( latIt, lonIt ) );
965  }
966  else
967  {
968  ProSHADE_internal_misc::addToDoubleVector ( allHeights, currentHeight );
969  }
970  }
971  }
972 
973  //================================================ Done
974  return ;
975 
976 }
977 
987 {
988  //================================================ Initialise variables
989  proshade_double curHeight;
990  std::vector< proshade_unsign > dels ( 0, this->peaks.size() );
991 
992  //================================================ For each peak in this sphere
993  for ( proshade_unsign peakIt = 0; peakIt < static_cast<proshade_unsign> ( this->peaks.size() ); peakIt++ )
994  {
995  //============================================ Find the peak height
996  curHeight = this->getSphereLatLonPosition ( this->peaks.at(peakIt).first, this->peaks.at(peakIt).second );
997 
998  //============================================ Should this peak be deleted?
999  if ( curHeight < peakThres )
1000  {
1002  }
1003  }
1004 
1005  //================================================ Descending sort to avoid changing the order
1006  std::sort ( dels.begin(), dels.end(), std::greater <proshade_unsign>() );
1007 
1008  //================================================ Delete the low peaks
1009  for ( proshade_unsign delIt = 0; delIt < static_cast< proshade_unsign > ( dels.size() ); delIt++ )
1010  {
1011  this->peaks.erase ( this->peaks.begin() + dels.at(delIt) );
1012  }
1013 
1014  //================================================ Done
1015  return ;
1016 
1017 }
1018 
1029 ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::ProSHADE_rotFun_spherePeakGroup ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_unsign angDim )
1030 {
1031  //================================================ Compute the run-specific values
1032  this->dimension = angDim;
1033  this->lonSampling = ( M_PI ) / static_cast<proshade_double> ( this->dimension );
1034  this->latSampling = ( M_PI * 2.0 ) / static_cast<proshade_double> ( this->dimension );
1035 
1036  //================================================ The constructor is called when firstt peak of the group is found. Save the values of this initial peak.
1037  this->latFrom = static_cast<proshade_double> ( lat ) * this->latSampling;
1038  this->latTo = static_cast<proshade_double> ( lat ) * this->latSampling;
1039  this->lonFrom = static_cast<proshade_double> ( lon ) * this->lonSampling;
1040  this->lonTo = static_cast<proshade_double> ( lon ) * this->lonSampling;
1041  this->latFromInds = lat;
1042  this->latToInds = lat;
1043  this->lonFromInds = lon;
1044  this->lonToInds = lon;
1045  ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos );
1046 
1047  //================================================ Allocate memory for similarity positions
1048  this->latMinLonMinXYZ = new proshade_double[3];
1049  this->latMaxLonMinXYZ = new proshade_double[3];
1050  this->latMinLonMaxXYZ = new proshade_double[3];
1051  this->latMaxLonMaxXYZ = new proshade_double[3];
1052  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMinXYZ, __FILE__, __LINE__, __func__ );
1053  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMinXYZ, __FILE__, __LINE__, __func__ );
1054  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMinLonMaxXYZ, __FILE__, __LINE__, __func__ );
1055  ProSHADE_internal_misc::checkMemoryAllocation ( this->latMaxLonMaxXYZ, __FILE__, __LINE__, __func__ );
1056 
1057  //================================================ Compute corner vectors
1058  this->computeCornerPositions ( );
1059 
1060  //================================================ Done
1061 
1062 }
1063 
1069 {
1070  //================================================ Release the XYZ arrays
1071  delete[] this->latMinLonMinXYZ;
1072  delete[] this->latMaxLonMinXYZ;
1073  delete[] this->latMinLonMaxXYZ;
1074  delete[] this->latMaxLonMaxXYZ;
1075 }
1076 
1080 {
1081  //================================================ Compute corner vectors
1082  this->latMinLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latFrom );
1083  this->latMinLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latFrom );
1084  this->latMinLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1085 
1086  this->latMaxLonMinXYZ[0] = 1.0 * std::sin ( this->lonFrom ) * std::cos ( this->latTo );
1087  this->latMaxLonMinXYZ[1] = 1.0 * std::sin ( this->lonFrom ) * std::sin ( this->latTo );
1088  this->latMaxLonMinXYZ[2] = 1.0 * std::cos ( this->lonFrom );
1089 
1090  this->latMinLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latFrom );
1091  this->latMinLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latFrom );
1092  this->latMinLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1093 
1094  this->latMaxLonMaxXYZ[0] = 1.0 * std::sin ( this->lonTo ) * std::cos ( this->latTo );
1095  this->latMaxLonMaxXYZ[1] = 1.0 * std::sin ( this->lonTo ) * std::sin ( this->latTo );
1096  this->latMaxLonMaxXYZ[2] = 1.0 * std::cos ( this->lonTo );
1097 
1098  //================================================ Done
1099  return ;
1100 
1101 }
1102 
1109 proshade_signed ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::angularDistanceWithBorders ( proshade_signed newAngul, proshade_signed currentAngul )
1110 {
1111  //================================================ Initialise variables
1112  proshade_signed smallerAngul = newAngul - this->dimension;
1113  proshade_signed largerAngul = newAngul + this->dimension;
1114 
1115  //================================================ Find the smallest distance
1116  proshade_signed ret = std::min ( std::abs ( currentAngul - newAngul ), std::min ( std::abs ( currentAngul - smallerAngul ), std::abs ( currentAngul - largerAngul ) ) );
1117 
1118  //================================================ Done
1119  return ( ret );
1120 
1121 }
1122 
1137 bool ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::checkIfPeakBelongs ( proshade_double lat, proshade_double lon, proshade_unsign sphPos, proshade_double cosTol, proshade_signed verbose )
1138 {
1139  //================================================ Initialise local variables
1140  bool peakAdded = false;
1141  std::stringstream hlpSS;
1142  std::stringstream hlpSS2;
1143 
1144  //================================================ Compute peaks XYZ and its cosine distance to group corners
1145  proshade_double xPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::cos ( lat * this->latSampling );
1146  proshade_double yPos = 1.0 * std::sin ( lon * this->lonSampling ) * std::sin ( lat * this->latSampling );
1147  proshade_double zPos = 1.0 * std::cos ( lon * this->lonSampling );
1148  hlpSS2 << "Peak " << xPos << " ; " << yPos << " ; " << zPos << " is close enough to group with corner ";
1149 
1150  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]; }
1151  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]; }
1152  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]; }
1153  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]; }
1154 
1155  //================================================ If peak within corners, add it
1156  if ( peakAdded )
1157  {
1158  //============================================ Report progress
1159  hlpSS << "Peak group dimensions changed from LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " to ";
1160  ProSHADE_internal_messages::printProgressMessage ( verbose, 6, hlpSS2.str() );
1161 
1162  //============================================ Initialise local variables
1163  proshade_unsign largerCorner, smallerCorner;
1164  bool latCornersDone = false;
1165  bool lonCornersDone = false;
1166 
1167  //============================================ Check if lattitude boundaries need to be modified
1168  if ( ( this->latFromInds <= this->latToInds ) && !( ( lat >= this->latFromInds ) && ( lat <= this->latToInds ) ) )
1169  {
1170  //======================================== Lattitude is outside of group boundaries
1171  smallerCorner = angularDistanceWithBorders ( lat, this->latFromInds );
1172  largerCorner = angularDistanceWithBorders ( lat, this->latToInds );
1173 
1174  if ( smallerCorner < largerCorner )
1175  {
1176  this->latFromInds = lat;
1177  latCornersDone = true;
1178  }
1179  if ( smallerCorner > largerCorner )
1180  {
1181  this->latToInds = lat;
1182  latCornersDone = true;
1183  }
1184  if ( smallerCorner == largerCorner )
1185  {
1186  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1187  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1188  }
1189  }
1190 
1191  if ( ( this->latFromInds > this->latToInds ) && !( ( lat >= this->latFromInds ) || ( lat <= this->latToInds ) ) )
1192  {
1193  //======================================== Lattitude is outside of group boundaries
1194  smallerCorner = angularDistanceWithBorders ( lat, this->latFromInds );
1195  largerCorner = angularDistanceWithBorders ( lat, this->latToInds );
1196 
1197  if ( smallerCorner < largerCorner )
1198  {
1199  this->latFromInds = lat;
1200  latCornersDone = true;
1201  }
1202  if ( smallerCorner > largerCorner )
1203  {
1204  this->latToInds = lat;
1205  latCornersDone = true;
1206  }
1207  if ( smallerCorner == largerCorner )
1208  {
1209  if ( lat < this->latFromInds ) { this->latFromInds = lat; latCornersDone = true; }
1210  else if ( lat > this->latToInds ) { this->latToInds = lat; latCornersDone = true; }
1211  }
1212  }
1213 
1214 
1215  //============================================ Check if longitude boundaries need to be modified
1216  if ( ( this->lonFromInds <= this->lonToInds ) && !( ( lon >= this->lonFromInds ) && ( lon <= this->lonToInds ) ) )
1217  {
1218  //======================================== Lattitude is outside of group boundaries
1219  smallerCorner = angularDistanceWithBorders ( lon, this->lonFromInds );
1220  largerCorner = angularDistanceWithBorders ( lon, this->lonToInds );
1221 
1222  if ( smallerCorner < largerCorner )
1223  {
1224  this->lonFromInds = lon;
1225  lonCornersDone = true;
1226  }
1227  if ( smallerCorner > largerCorner )
1228  {
1229  this->lonToInds = lon;
1230  lonCornersDone = true;
1231  }
1232  if ( smallerCorner == largerCorner )
1233  {
1234  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1235  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1236  }
1237  }
1238 
1239  if ( ( this->lonFromInds > this->lonToInds ) && !( ( lon >= this->lonFromInds ) || ( lon <= this->lonToInds ) ) )
1240  {
1241  //======================================== Lattitude is outside of group boundaries
1242  smallerCorner = angularDistanceWithBorders ( lon, this->lonFromInds );
1243  largerCorner = angularDistanceWithBorders ( lon, this->lonToInds );
1244 
1245  if ( smallerCorner < largerCorner )
1246  {
1247  this->lonFromInds = lon;
1248  lonCornersDone = true;
1249  }
1250  if ( smallerCorner > largerCorner )
1251  {
1252  this->lonToInds = lon;
1253  lonCornersDone = true;
1254  }
1255  if ( smallerCorner == largerCorner )
1256  {
1257  if ( lon < this->lonFromInds ) { this->lonFromInds = lon; lonCornersDone = true; }
1258  else if ( lon > this->lonToInds ) { this->lonToInds = lon; lonCornersDone = true; }
1259  }
1260  }
1261 
1262  //============================================ Modify corner positions
1263  if ( latCornersDone )
1264  {
1265  this->latFrom = static_cast<proshade_double> ( this->latFromInds ) * this->latSampling;
1266  this->latTo = static_cast<proshade_double> ( this->latToInds ) * this->latSampling;
1267  }
1268 
1269  if ( lonCornersDone )
1270  {
1271  this->lonFrom = static_cast<proshade_double> ( this->lonFromInds ) * this->lonSampling;
1272  this->lonTo = static_cast<proshade_double> ( this->lonToInds ) * this->lonSampling;
1273  }
1274 
1275  //============================================ Compute corner vectors
1276  this->computeCornerPositions ( );
1277  hlpSS << "LAT " << this->latFromInds << " - " << this->latToInds << " and LON " << this->lonFromInds << " - " << this->lonToInds << " ( peak position LAT " << lat << " LON " << lon << " )";
1278  ProSHADE_internal_messages::printProgressMessage ( verbose, 7, hlpSS.str() );
1279 
1280  //============================================ If new sphere, add it to the list
1281  bool isSphereNew = true;
1282  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePositions.size() ); iter++ ) { if ( this->spherePositions.at(iter) == sphPos ) { isSphereNew = false; } }
1283  if ( isSphereNew ) { ProSHADE_internal_misc::addToUnsignVector ( &this->spherePositions, sphPos ); }
1284  }
1285 
1286  //================================================ Done
1287  return ( peakAdded );
1288 
1289 }
1290 
1296 {
1297  //================================================ Done
1298  return ( this->latFromInds );
1299 
1300 }
1301 
1307 {
1308  //================================================ Done
1309  return ( this->latToInds );
1310 
1311 }
1312 
1318 {
1319  //================================================ Done
1320  return ( this->lonFromInds );
1321 
1322 }
1323 
1329 {
1330  //================================================ Done
1331  return ( this->lonToInds );
1332 
1333 }
1334 
1340 {
1341  //================================================ Done
1342  return ( this->spherePositions );
1343 
1344 }
1345 
1366 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::findCyclicPointGroupsGivenFold ( std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals, proshade_double axisTolerance, std::vector < proshade_double* >* detectedCs, bool bicubicInterp, proshade_unsign fold, proshade_unsign verbose )
1367 {
1368  //================================================ Check that this peak group has all the angles
1369  if ( ( fold - 1 ) != spherePositions.size() ) { return ; }
1370 
1371  //================================================ Initialise variables
1372  proshade_double bestPosVal, bestLatInd, bestLonInd;
1373  std::vector< proshade_unsign > spheresFormingFold;
1374 
1375  //================================================ Set all supplied spheres to be required to form the fold
1376  for ( proshade_unsign shIt = 0; shIt < static_cast<proshade_unsign> ( sphereVals.size() ); shIt++ )
1377  {
1378  ProSHADE_internal_misc::addToUnsignVector ( &spheresFormingFold, shIt );
1379  }
1380 
1381  //================================================ Find the index with the highest peak height sum
1382  this->getBestIndexForFold ( &bestPosVal, &bestLatInd, &bestLonInd, &spheresFormingFold, sphereVals );
1383 
1384  //================================================ Optimise by bicubic interpolation if required
1385  if ( bicubicInterp )
1386  {
1387  ProSHADE_internal_maths::optimiseAxisBiCubicInterpolation ( &bestLatInd, &bestLonInd, &bestPosVal, &spheresFormingFold, &sphereVals );
1388  }
1389 
1390  //================================================ Create ProSHADE symmetry axis array and save it
1391  proshade_double* detectedSymmetry = new proshade_double[6];
1392  ProSHADE_internal_misc::checkMemoryAllocation ( detectedSymmetry, __FILE__, __LINE__, __func__ );
1393 
1394  detectedSymmetry[0] = static_cast<proshade_double> ( fold );
1395  detectedSymmetry[1] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::cos ( bestLatInd * this->latSampling );
1396  detectedSymmetry[2] = 1.0 * std::sin ( bestLonInd * this->lonSampling ) * std::sin ( bestLatInd * this->latSampling );
1397  detectedSymmetry[3] = 1.0 * std::cos ( bestLonInd * this->lonSampling );
1398  detectedSymmetry[4] = ( 2.0 * M_PI ) / detectedSymmetry[0];
1399  detectedSymmetry[5] = ( bestPosVal - 1.0 ) / ( detectedSymmetry[0] - 1 );
1400 
1401  //================================================ Make sure max is positive
1402  if ( ( ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) == std::abs ( detectedSymmetry[1] ) ) && ( detectedSymmetry[1] < 0.0 ) ) ||
1403  ( ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) == std::abs ( detectedSymmetry[2] ) ) && ( detectedSymmetry[2] < 0.0 ) ) ||
1404  ( ( std::max ( std::abs ( detectedSymmetry[1] ), std::max ( std::abs ( detectedSymmetry[2] ), std::abs ( detectedSymmetry[3] ) ) ) == std::abs ( detectedSymmetry[3] ) ) && ( detectedSymmetry[3] < 0.0 ) ) )
1405  {
1406  detectedSymmetry[1] *= -1.0;
1407  detectedSymmetry[2] *= -1.0;
1408  detectedSymmetry[3] *= -1.0;
1409  detectedSymmetry[4] *= -1.0;
1410  }
1411 
1412  //================================================ Save detected point group
1413  ProSHADE_internal_misc::addToDblPtrVector ( detectedCs, detectedSymmetry );
1414 
1415  //================================================ Report progress
1416  std::stringstream hlpSS;
1417  hlpSS << "Detected group with fold " << detectedSymmetry[0] << " along axis " << detectedSymmetry[1] << " ; " << detectedSymmetry[2] << " ; " << detectedSymmetry[3] << " and with peak height " << detectedSymmetry[5];
1418  ProSHADE_internal_messages::printProgressMessage ( verbose, 4, hlpSS.str() );
1419 
1420  //================================================ Done
1421  return ;
1422 
1423 }
1424 
1430 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllAngleDifferences ( std::vector< proshade_double >* angDiffs, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals )
1431 {
1432  //================================================ Initialise local variables
1433  std::vector< proshade_double > angs;
1434 
1435  //================================================ Find all present angles
1436  for ( proshade_unsign shPos = 0; shPos < static_cast<proshade_unsign> ( this->spherePositions.size() ); shPos++ )
1437  {
1438  ProSHADE_internal_misc::addToDoubleVector ( &angs, sphereVals.at(this->spherePositions.at(shPos))->getRadius() );
1439  }
1440 
1441  //================================================ Find all angle differences
1442  for ( proshade_unsign ang1It = 0; ang1It < static_cast<proshade_unsign> ( angs.size() ); ang1It++ )
1443  {
1444  for ( proshade_unsign ang2It = 1; ang2It < static_cast<proshade_unsign> ( angs.size() ); ang2It++ )
1445  {
1446  //======================================== Use unique combinations only
1447  if ( ang1It >= ang2It ) { continue; }
1448 
1449  //======================================== Add angle difference rounded to 5 decimal places
1450  ProSHADE_internal_misc::addToDoubleVector ( angDiffs, std::floor ( std::abs ( angs.at(ang1It) - angs.at(ang2It) ) * 100000.0 ) / 100000.0 );
1451  }
1452  }
1453 
1454  //================================================ Sort and remove duplicates
1455  std::sort ( (*angDiffs).begin(), (*angDiffs).end() );
1456  (*angDiffs).erase ( std::unique ( (*angDiffs).begin(), (*angDiffs).end() ), (*angDiffs).end() );
1457 
1458  //================================================ Done
1459  return ;
1460 
1461 }
1462 
1473 void ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds ( std::vector< proshade_double >* angDiffs, std::vector< proshade_unsign >* foldsToTry, std::vector<ProSHADE_internal_spheres::ProSHADE_rotFun_sphere*> sphereVals )
1474 {
1475  //================================================ Initialise local variables
1476  proshade_double divRem, divBasis, symmErr, angTolerance, angToleranceNext;
1477  proshade_double peakErr = ( M_PI * 2.0 ) / ( static_cast<proshade_double> ( this->dimension ) );
1478 
1479  //================================================ For each angle difference in the group
1480  for ( proshade_unsign diffIt = 0; diffIt < static_cast<proshade_unsign> ( angDiffs->size() ); diffIt++ )
1481  {
1482  //============================================ Find the basis and remainder of the 2pi/dist equation
1483  divRem = std::modf ( static_cast<proshade_double> ( ( 2.0 * M_PI ) / std::abs ( angDiffs->at(diffIt) ) ), &divBasis );
1484 
1485  //============================================ If the remainder would be smaller for larger basis, so change the basis
1486  if ( divRem > 0.5 )
1487  {
1488  divRem -= 1.0;
1489  divBasis += 1.0;
1490  }
1491 
1492  //============================================ Remove fold 1, that is not really what we are after here ...
1493  if ( divBasis == 1 ) { continue; }
1494 
1495  //============================================ Is there enough angles in the group for such a fold?
1496  if ( static_cast<proshade_unsign> ( this->spherePositions.size() ) < ( divBasis - 1 ) ) { continue; }
1497 
1498  //============================================ Determine errors on peaks and on folds
1499  symmErr = divRem * ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) );
1500  angTolerance = std::abs( symmErr / peakErr );
1501  angToleranceNext = ( ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis ) ) - ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( divBasis + 1 ) ) ) / peakErr;
1502 
1503  //============================================ Is remainder small enough?
1504  if ( angTolerance < std::max ( 3.0, ( 0.1 / peakErr ) ) )
1505  {
1506  //======================================== Is the next symmetry close enough? If so, test previous and next folds as well.
1507  if ( angToleranceNext < std::max ( 1.5, ( 0.1 / peakErr ) ) )
1508  {
1509  //==================================== The next fold would pass as well. Use one previous and one following fold as well to cover for errors
1510  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, divBasis - 1 );
1511  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, divBasis + 1 );
1512  }
1513 
1514  //======================================== This fold seems reasonable, save it
1515  ProSHADE_internal_misc::addToUnsignVector ( foldsToTry, divBasis );
1516  }
1517  }
1518 
1519  //================================================ Sort and remove duplicates
1520  std::sort ( (*foldsToTry).begin(), (*foldsToTry).end(), std::greater <proshade_unsign>() );
1521  foldsToTry->erase ( std::unique ( (*foldsToTry).begin(), (*foldsToTry).end() ), (*foldsToTry).end() );
1522 
1523  //================================================ Done
1524  return ;
1525 
1526 }
1527 
1535 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 )
1536 {
1537  //================================================ Initialise local variables
1538  proshade_double soughtAngle, minSphereVal;
1539  proshade_unsign minSpherePos;
1540 
1541  //================================================ Generate expected angles and check if close-by sphere exists
1542  for ( proshade_double fIt = 1.0; fIt < static_cast<proshade_double> ( foldToTry ); fIt += 1.0 )
1543  {
1544  //============================================ Set variables for the iteration
1545  minSphereVal = 999.9;
1546  soughtAngle = fIt * ( 2.0 * M_PI / static_cast<proshade_double> ( foldToTry ) );
1547 
1548  //============================================ Find the closest sphere passing conditions
1549  for ( proshade_unsign angsIt = 0; angsIt < static_cast<proshade_unsign> ( this->spherePositions.size() ); angsIt++ )
1550  {
1551  if ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) < sphereAngleTolerance )
1552  {
1553  if ( minSphereVal > 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) ) )
1554  {
1555  minSphereVal = 1.0 - std::cos ( std::abs ( sphereVals.at(this->spherePositions.at(angsIt))->getRepresentedAngle() - soughtAngle ) );
1556  minSpherePos = angsIt;
1557  }
1558  }
1559  }
1560 
1561  //============================================ If no passing sphere, test next fold
1562  if ( minSphereVal == 999.9 ) { break; }
1563 
1564  //============================================ Save best position
1565  ProSHADE_internal_misc::addToUnsignVector ( spheresFormingFold, this->spherePositions.at(minSpherePos) );
1566  }
1567 
1568  //================================================ Done
1569  return ;
1570 
1571 }
1572 
1573 
1582 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 )
1583 {
1584  //================================================ Initialise variables
1585  proshade_double curPosVal;
1586  *bestPosVal = -1.0;
1587  if ( this->latFromInds > this->latToInds ) { this->latToInds += this->dimension; }
1588  if ( this->lonFromInds > this->lonToInds ) { this->lonToInds += this->dimension; }
1589 
1590  //================================================ Compute the best average peak height axis for peak indices
1591  for ( proshade_unsign latIt = this->latFromInds; latIt <= this->latToInds; latIt++ )
1592  {
1593  //============================================ Deal with boundaries
1594  if ( latIt >= this->dimension ) { latIt -= this->dimension; this->latToInds -= this->dimension; }
1595 
1596  for ( proshade_unsign lonIt = this->lonFromInds; lonIt <= this->lonToInds; lonIt++ )
1597  {
1598  //======================================== Deal with boundaries
1599  if ( lonIt >= this->dimension ) { lonIt -= this->dimension; this->lonToInds -= this->dimension; }
1600 
1601  //======================================== Initialise variables
1602  curPosVal = 1.0;
1603 
1604  //======================================== Find this indices value
1605  for ( proshade_unsign sphIt = 0; sphIt < static_cast<proshade_unsign> ( spheresFormingFold->size() ); sphIt++ )
1606  {
1607  curPosVal += sphereVals.at(spheresFormingFold->at(sphIt))->getSphereLatLonPosition ( latIt, lonIt );
1608  }
1609 
1610  //======================================== If best, save it
1611  if ( curPosVal > *bestPosVal )
1612  {
1613  *bestPosVal = curPosVal;
1614  *bestLatInd = latIt;
1615  *bestLonInd = lonIt;
1616  }
1617  }
1618  }
1619 
1620  //================================================ Done
1621  return ;
1622 
1623 }
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:339
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:393
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMinRadius
proshade_double getMinRadius(void)
Accessor function for the private variable minimal radius.
Definition: ProSHADE_spheres.cpp:716
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getSphereNumber
proshade_unsign getSphereNumber(void)
Accessor function for the private variable sphere number.
Definition: ProSHADE_spheres.cpp:738
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:445
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatToIndices
proshade_double getLatToIndices(void)
Accessor function for the private variable latToInds.
Definition: ProSHADE_spheres.cpp:1306
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:671
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:1109
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:1079
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLatFromIndices
proshade_double getLatFromIndices(void)
Accessor function for the private variable latFromInds.
Definition: ProSHADE_spheres.cpp:1295
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:986
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, proshade_unsign angDim)
This function converts angle-axis representation to the Euler ZXZ angles representation.
Definition: ProSHADE_maths.cpp:1437
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRepresentedAngle
proshade_double getRepresentedAngle(void)
Accessor function for the private variable represented angle.
Definition: ProSHADE_spheres.cpp:727
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:1535
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:263
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:630
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:2296
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getAllPossibleFolds
void getAllPossibleFolds(std::vector< proshade_double > *angDiffs, std::vector< proshade_unsign > *foldsToTry, std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals)
This function angle differences and creates a list of folds that may be present in the group.
Definition: ProSHADE_spheres.cpp:1473
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getSpherePositions
std::vector< proshade_unsign > getSpherePositions(void)
Accessor function for the private variable spherePositions.
Definition: ProSHADE_spheres.cpp:1339
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:2266
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getMaxRadius
proshade_double getMaxRadius(void)
Accessor function for the private variable maximum radius.
Definition: ProSHADE_spheres.cpp:694
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:540
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:1430
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:924
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:370
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::removeSmallPeaks
void removeSmallPeaks(proshade_double peakThres)
Function for removing peaks with too small height.
Definition: ProSHADE_spheres.cpp:986
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::findCyclicPointGroupsGivenFold
void findCyclicPointGroupsGivenFold(std::vector< ProSHADE_internal_spheres::ProSHADE_rotFun_sphere * > sphereVals, proshade_double axisTolerance, std::vector< proshade_double * > *detectedCs, bool bicubicInterp, proshade_unsign fold, proshade_unsign verbose)
Function detecting cyclic point groups with a particular fold in a peak group.
Definition: ProSHADE_spheres.cpp:1366
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:1029
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:1137
ProSHADE_internal_spheres::ProSHADE_sphere::getMaxCircumference
proshade_unsign getMaxCircumference(proshade_unsign xDimMax, proshade_unsign yDimMax, proshade_unsign zDimMax, proshade_double maxRange, proshade_single xSize, proshade_single ySize, proshade_single zSize)
This function determines the maximum circumference of a shell.
Definition: ProSHADE_spheres.cpp:124
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_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:419
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonToIndices
proshade_double getLonToIndices(void)
Accessor function for the private variable lonToInds.
Definition: ProSHADE_spheres.cpp:1328
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:648
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:864
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:564
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::getLonFromIndices
proshade_double getLonFromIndices(void)
Accessor function for the private variable lonFromInds.
Definition: ProSHADE_spheres.cpp:1317
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:65
ProSHADE_internal_spheres::autoDetermineBandwidth
proshade_unsign autoDetermineBandwidth(proshade_unsign circumference)
This function determines the bandwidth for the spherical harmonics computation.
Definition: ProSHADE_spheres.cpp:518
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:1582
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:406
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:290
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getRadius
proshade_double getRadius(void)
Accessor function for the private variable radius.
Definition: ProSHADE_spheres.cpp:684
ProSHADE_internal_spheres::ProSHADE_sphere::allocateRotatedMap
void allocateRotatedMap(void)
This function allocates the rotated map memory.
Definition: ProSHADE_spheres.cpp:599
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:878
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:181
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:491
ProSHADE_internal_spheres::ProSHADE_rotFun_sphere::getAngularDim
proshade_unsign getAngularDim(void)
Accessor function for the private variable angular dim.
Definition: ProSHADE_spheres.cpp:705
ProSHADE_internal_spheres::ProSHADE_sphere::getShellRadius
proshade_double getShellRadius(void)
This function returns the radius of the shell in question.
Definition: ProSHADE_spheres.cpp:590
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:765
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:749
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:616
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:311
ProSHADE_internal_spheres::ProSHADE_rotFun_spherePeakGroup::~ProSHADE_rotFun_spherePeakGroup
~ProSHADE_rotFun_spherePeakGroup(void)
Destructor for the ProSHADE_rotFun_spherePeakGroup class.
Definition: ProSHADE_spheres.cpp:1068