ProSHADE  0.7.6.0 (JUL 2021)
Protein Shape Detection
ProSHADE_data.cpp
Go to the documentation of this file.
1 
24 //==================================================== ProSHADE
25 #include "ProSHADE_data.hpp"
26 
27 //==================================================== Do not use the following flags for the included files - this causes a lot of warnings that have nothing to do with ProSHADE
28 #if defined ( __GNUC__ )
29  #pragma GCC diagnostic push
30  #pragma GCC diagnostic ignored "-Wpedantic"
31  #pragma GCC diagnostic ignored "-Wshadow"
32  #pragma GCC diagnostic ignored "-Wall"
33  #pragma GCC diagnostic ignored "-Wextra"
34  #pragma GCC diagnostic ignored "-Wdouble-promotion"
35  #pragma GCC diagnostic ignored "-Wconversion"
36 #endif
37 
38 //==================================================== Do not use the following flags for the included files - this causes a lot of warnings that have nothing to do with ProSHADE
39 #if defined ( __clang__ )
40  #pragma clang diagnostic push
41  #pragma clang diagnostic ignored "-Wpedantic"
42  #pragma clang diagnostic ignored "-Wshadow"
43  #pragma clang diagnostic ignored "-Wall"
44  #pragma clang diagnostic ignored "-Wextra"
45  #pragma clang diagnostic ignored "-Wdouble-promotion"
46  #pragma clang diagnostic ignored "-Weverything"
47 #endif
48 
49 //==================================================== Remove MSVC C4996 Warnings caused by Gemmi code
50 #if defined ( _MSC_VER )
51  #pragma warning ( disable:4996 )
52 #endif
53 
54 //==================================================== Gemmi PDB output - this cannot be with the rest of includes for some stb_sprintf library related reasons ...
55 #define GEMMI_WRITE_IMPLEMENTATION
56 #include <gemmi/to_pdb.hpp>
57 
58 //==================================================== Enable MSVC C4996 Warnings for the rest of the code
59 #if defined ( _MSC_VER )
60  #pragma warning ( default:4996 )
61 #endif
62 
63 //==================================================== Now the flags can be restored and used as per the CMakeLists.txt file.
64 #if defined ( __GNUC__ )
65  #pragma GCC diagnostic pop
66 #endif
67 
68 //==================================================== Now the flags can be restored and used as per the CMakeLists.txt file.
69 #if defined ( __clang__ )
70  #pragma clang diagnostic pop
71 #endif
72 
73 //==================================================== Forward declarations
75 {
76  proshade_signed addAxisUnlessSame ( proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axHeight, proshade_double averageFSC, std::vector< proshade_double* >* prosp, proshade_double axErr );
77 }
78 
79 //==================================================== Local functions prototypes
80 void axesToGroupTypeSanityCheck ( proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType );
81 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance );
82 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance );
83 bool sortProSHADESymmetryByFSC ( proshade_double* a, proshade_double* b );
84 
94 {
95  //================================================ Initialise variables
96  // ... Variables regarding input file
97  this->fileName = "";
98  this->fileType = ProSHADE_internal_io::UNKNOWN;
99 
100  // ... Variables regarding map
101  this->internalMap = nullptr;
102 
103  // ... Variables regarding map information
104  this->xDimSize = 0.0;
105  this->yDimSize = 0.0;
106  this->zDimSize = 0.0;
107  this->aAngle = 0.0;
108  this->bAngle = 0.0;
109  this->cAngle = 0.0;
110  this->xDimIndices = 0;
111  this->yDimIndices = 0;
112  this->zDimIndices = 0;
113  this->xGridIndices = 0;
114  this->yGridIndices = 0;
115  this->zGridIndices = 0;
116  this->xAxisOrder = 1;
117  this->yAxisOrder = 2;
118  this->zAxisOrder = 3;
119  this->xAxisOrigin = 0;
120  this->yAxisOrigin = 0;
121  this->zAxisOrigin = 0;
122  this->xCom = 0.0;
123  this->yCom = 0.0;
124  this->zCom = 0.0;
125 
126  // ... Variables regarding original input values (i.e. these do not change with ProSHADE manipulations)
127  this->xDimSizeOriginal = 0.0;
128  this->yDimSizeOriginal = 0.0;
129  this->zDimSizeOriginal = 0.0;
130  this->xDimIndicesOriginal = 0;
131  this->yDimIndicesOriginal = 0;
132  this->zDimIndicesOriginal = 0;
133  this->xAxisOriginOriginal = 0;
134  this->yAxisOriginOriginal = 0;
135  this->zAxisOriginOriginal = 0;
136  this->originalMapXCom = 0.0;
137  this->originalMapYCom = 0.0;
138  this->originalMapZCom = 0.0;
139  this->mapMovFromsChangeX = 0.0;
140  this->mapMovFromsChangeY = 0.0;
141  this->mapMovFromsChangeZ = 0.0;
142  this->mapCOMProcessChangeX = 0.0;
143  this->mapCOMProcessChangeY = 0.0;
144  this->mapCOMProcessChangeZ = 0.0;
145 
146  // ... Variables regarding rotation and translation of original input files
147  this->originalPdbRotCenX = 0.0;
148  this->originalPdbRotCenY = 0.0;
149  this->originalPdbRotCenZ = 0.0;
150  this->originalPdbTransX = 0.0;
151  this->originalPdbTransY = 0.0;
152  this->originalPdbTransZ = 0.0;
153 
154  // ... Variables regarding iterator positions
155  this->xFrom = 0;
156  this->yFrom = 0;
157  this->zFrom = 0;
158  this->xTo = 0;
159  this->yTo = 0;
160  this->zTo = 0;
161 
162  // ... Variables regarding SH mapping spheres
163  this->spherePos = std::vector<proshade_single> ( );
164  this->noSpheres = 0;
165  this->spheres = nullptr;
166  this->sphericalHarmonics = nullptr;
167  this->rotSphericalHarmonics = nullptr;
168  this->maxShellBand = 0;
169 
170  // ... Variables regarding shape distance computations
171  this->rrpMatrices = nullptr;
172  this->eMatrices = nullptr;
173  this->so3Coeffs = nullptr;
174  this->so3CoeffsInverse = nullptr;
175  this->wignerMatrices = nullptr;
176  this->integrationWeight = 0.0;
177  this->maxCompBand = 0;
178  this->translationMap = nullptr;
179 
180 
181  // ... Control variables
182  this->isEmpty = true;
183 
184  //================================================ Done
185 
186 }
187 
214 ProSHADE_internal_data::ProSHADE_data::ProSHADE_data ( std::string strName, double *mapVals, int len, proshade_single xDmSz, proshade_single yDmSz, proshade_single zDmSz, proshade_unsign xDmInd, proshade_unsign yDmInd, proshade_unsign zDmInd, proshade_signed xFr, proshade_signed yFr, proshade_signed zFr, proshade_signed xT, proshade_signed yT, proshade_signed zT, proshade_unsign inputO )
215 {
216  //================================================ Initialise variables
217  // ... Variables regarding input file
218  this->fileName = strName;
219  this->fileType = ProSHADE_internal_io::MAP;
220 
221  // ... Variables regarding map
222  this->internalMap = nullptr;
223 
224  // ... Variables regarding map information
225  this->xDimSize = xDmSz;
226  this->yDimSize = yDmSz;
227  this->zDimSize = zDmSz;
228  this->aAngle = 90.0;
229  this->bAngle = 90.0;
230  this->cAngle = 90.0;
231  this->xDimIndices = xDmInd;
232  this->yDimIndices = yDmInd;
233  this->zDimIndices = zDmInd;
234  this->xGridIndices = xDmInd;
235  this->yGridIndices = yDmInd;
236  this->zGridIndices = zDmInd;
237  this->xAxisOrder = 1;
238  this->yAxisOrder = 2;
239  this->zAxisOrder = 3;
240  this->xAxisOrigin = xFr;
241  this->yAxisOrigin = yFr;
242  this->zAxisOrigin = zFr;
243  this->xCom = 0.0;
244  this->yCom = 0.0;
245  this->zCom = 0.0;
246 
247  // ... Variables regarding original input values (i.e. these do not change with ProSHADE manipulations)
248  this->xDimSizeOriginal = 0.0;
249  this->yDimSizeOriginal = 0.0;
250  this->zDimSizeOriginal = 0.0;
251  this->xDimIndicesOriginal = 0;
252  this->yDimIndicesOriginal = 0;
253  this->zDimIndicesOriginal = 0;
254  this->xAxisOriginOriginal = 0;
255  this->yAxisOriginOriginal = 0;
256  this->zAxisOriginOriginal = 0;
257  this->originalMapXCom = 0.0;
258  this->originalMapYCom = 0.0;
259  this->originalMapZCom = 0.0;
260  this->mapMovFromsChangeX = 0.0;
261  this->mapMovFromsChangeY = 0.0;
262  this->mapMovFromsChangeZ = 0.0;
263  this->mapCOMProcessChangeX = 0.0;
264  this->mapCOMProcessChangeY = 0.0;
265  this->mapCOMProcessChangeZ = 0.0;
266 
267  // ... Variables regarding rotation and translation of original input files
268  this->originalPdbRotCenX = 0.0;
269  this->originalPdbRotCenY = 0.0;
270  this->originalPdbRotCenZ = 0.0;
271  this->originalPdbTransX = 0.0;
272  this->originalPdbTransY = 0.0;
273  this->originalPdbTransZ = 0.0;
274 
275  // ... Variables regarding iterator positions
276  this->xFrom = xFr;
277  this->yFrom = yFr;
278  this->zFrom = zFr;
279  this->xTo = xT;
280  this->yTo = yT;
281  this->zTo = zT;
282 
283  // ... Variables regarding SH mapping spheres
284  this->spherePos = std::vector<proshade_single> ( );
285  this->noSpheres = 0;
286  this->spheres = nullptr;
287  this->sphericalHarmonics = nullptr;
288  this->rotSphericalHarmonics = nullptr;
289  this->maxShellBand = 0;
290 
291  // ... Variables regarding shape distance computations
292  this->rrpMatrices = nullptr;
293  this->eMatrices = nullptr;
294  this->so3Coeffs = nullptr;
295  this->so3CoeffsInverse = nullptr;
296  this->wignerMatrices = nullptr;
297  this->integrationWeight = 0.0;
298  this->maxCompBand = 0;
299  this->translationMap = nullptr;
300 
301  // ... Control variables
302  this->isEmpty = false;
303  this->inputOrder = inputO;
304 
305  //================================================ Sanity checks
306  if ( static_cast<proshade_unsign> ( len ) != ( xDmInd * yDmInd * zDmInd ) )
307  {
308  throw ProSHADE_exception ( "Structure class input map has wrong dimensions.", "EP00044", __FILE__, __LINE__, __func__, "The supplied map array size has different dimensions to\n : the required map dimensions." );
309  }
310 
311  if ( ( static_cast<proshade_signed> ( xT - xFr ) != static_cast<proshade_signed> ( xDmInd - 1 ) ) ||
312  ( static_cast<proshade_signed> ( yT - yFr ) != static_cast<proshade_signed> ( yDmInd - 1 ) ) ||
313  ( static_cast<proshade_signed> ( zT - zFr ) != static_cast<proshade_signed> ( zDmInd - 1 ) ) )
314  {
315  throw ProSHADE_exception ( "Structure class input dimensions not in line with map\n : to/from indices.", "EP00045", __FILE__, __LINE__, __func__, "The supplied map information does not add up. The\n : dimensions are not in line with the indexing start/stop\n : position distances and therefore proper map indexing\n : cannot be done. Please check the input values." );
316  }
317 
318  //================================================ Allocate the map memory
319  this->internalMap = new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
320  ProSHADE_internal_misc::checkMemoryAllocation ( this->internalMap, __FILE__, __LINE__, __func__ );
321 
322  //================================================ Copy the values into the map
323  proshade_unsign arrPos = 0;
324  for ( proshade_unsign xIt = 0; xIt < this->xDimIndices; xIt++ )
325  {
326  for ( proshade_unsign yIt = 0; yIt < this->yDimIndices; yIt++ )
327  {
328  for ( proshade_unsign zIt = 0; zIt < this->zDimIndices; zIt++ )
329  {
330  arrPos = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
331  this->internalMap[arrPos] = static_cast<proshade_double> ( mapVals[arrPos] );
332  }
333  }
334  }
335 
336  //================================================ Release memory (it was allocated by the PyBind11 lambda function and needs to be released)
337  delete[] mapVals;
338 
339  //================================================ Done
340 
341 }
342 
350 {
351  //================================================ Release the internal map
352  if ( this->internalMap != nullptr )
353  {
354  delete[] this->internalMap;
355  }
356 
357  //================================================ Release the sphere mapping
358  if ( this->spheres != nullptr )
359  {
360  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
361  {
362  if ( this->spheres[iter] != nullptr )
363  {
364  delete this->spheres[iter];
365  this->spheres[iter] = nullptr;
366  }
367  }
368  delete[] this->spheres;
369  }
370 
371  //================================================ Release the spherical harmonics
372  if ( this->sphericalHarmonics != nullptr )
373  {
374  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
375  {
376  if ( this->sphericalHarmonics[iter] != nullptr )
377  {
378  delete[] this->sphericalHarmonics[iter];
379  this->sphericalHarmonics[iter] = nullptr;
380  }
381  }
382  delete[] this->sphericalHarmonics;
383  }
384 
385  //================================================ Release the rotated spherical harmonics
386  if ( this->rotSphericalHarmonics != nullptr )
387  {
388  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
389  {
390  if ( this->rotSphericalHarmonics[iter] != nullptr )
391  {
392  delete[] this->rotSphericalHarmonics[iter];
393  this->rotSphericalHarmonics[iter] = nullptr;
394  }
395  }
396  delete[] this->rotSphericalHarmonics;
397  }
398 
399  //================================================ Release the RRP matrices (pre-computation for the energy levels descriptor)
400  if ( this->rrpMatrices != nullptr )
401  {
402  for ( proshade_unsign bwIt = 0; bwIt < this->maxShellBand; bwIt++ )
403  {
404  if ( this->rrpMatrices[bwIt] != nullptr )
405  {
406  for ( proshade_unsign shIt = 0; shIt < this->noSpheres; shIt++ )
407  {
408  if ( this->rrpMatrices[bwIt][shIt] != nullptr )
409  {
410  delete[] this->rrpMatrices[bwIt][shIt];
411  }
412  }
413 
414  delete[] this->rrpMatrices[bwIt];
415  }
416  }
417 
418  delete[] this->rrpMatrices;
419  }
420 
421  //================================================ Release the E matrices
422  if ( this->eMatrices != nullptr )
423  {
424  for ( proshade_unsign bandIter = 0; bandIter < this->maxCompBand; bandIter++ )
425  {
426  if ( this->eMatrices[bandIter] != nullptr )
427  {
428  for ( proshade_unsign band2Iter = 0; band2Iter < static_cast<proshade_unsign> ( ( bandIter * 2 ) + 1 ); band2Iter++ )
429  {
430  if ( this->eMatrices[bandIter][band2Iter] != nullptr )
431  {
432  delete[] this->eMatrices[bandIter][band2Iter];
433  }
434  }
435 
436  delete[] this->eMatrices[bandIter];
437  }
438  }
439 
440  delete[] this->eMatrices;
441  }
442 
443  //================================================ Release SOFT and inverse SOFT coefficients
444  if ( this->so3Coeffs != nullptr )
445  {
446  delete[] this->so3Coeffs;
447  }
448  if ( this->so3CoeffsInverse != nullptr )
449  {
450  delete[] this->so3CoeffsInverse;
451  }
452 
453  //================================================ Release Wigner matrices
454  if ( this->wignerMatrices != nullptr )
455  {
456  for ( proshade_unsign bandIter = 1; bandIter < this->maxCompBand; bandIter++ )
457  {
458  if ( this->wignerMatrices[bandIter] != nullptr )
459  {
460  for ( proshade_unsign order1Iter = 0; order1Iter < ( (bandIter * 2) + 1 ); order1Iter++ )
461  {
462  if ( this->wignerMatrices[bandIter][order1Iter] != nullptr )
463  {
464  delete[] this->wignerMatrices[bandIter][order1Iter];
465  }
466  }
467  delete[] this->wignerMatrices[bandIter];
468  }
469  }
470  delete[] wignerMatrices;
471  }
472 
473  //================================================ Release translation map
474  if ( this->translationMap != nullptr )
475  {
476  delete[] this->translationMap;
477  }
478 
479  //================================================ Release the angle-axis space rotation function
480  if ( this->sphereMappedRotFun.size() > 0 )
481  {
482  for ( proshade_unsign spIt = 0; spIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); spIt++ )
483  {
484  delete this->sphereMappedRotFun.at(spIt);
485  }
486  }
487 
488  //================================================ Done
489 
490 }
491 
501 void ProSHADE_internal_data::ProSHADE_data::readInStructure ( std::string fName, proshade_unsign inputO, ProSHADE_settings* settings )
502 {
503  //================================================ Report function start
504  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting to read the structure: " + fName );
505 
506  //================================================ Check if instance is empty
507  if ( !this->isEmpty )
508  {
509  throw ProSHADE_exception ( "Structure data class not empty.", "E000005", __FILE__, __LINE__, __func__, "Attempted to read in structure into a ProSHADE_data\n : object which already does have structure read in\n : i.e. " + this->fileName );
510  }
511 
512  //================================================ Save the filename
513  this->fileName = fName;
514 
515  //================================================ Check what is the input format
516  this->fileType = ProSHADE_internal_io::figureDataType ( this->fileName );
517 
518  //================================================ Save input order
519  this->inputOrder = inputO;
520 
521  //================================================ Decide how to proceed
522  switch ( this->fileType )
523  {
524  case ProSHADE_internal_io::UNKNOWN:
525  throw ProSHADE_exception ( "Unknown file type.", "E000006", __FILE__, __LINE__, __func__, "When attempting to read the file\n : " + this->fileName + "\n : the file extension was determined as unknown. This could\n : mean either that the file does not exist, or that it is\n : not one of the supported extensions." );
526 
527  case ProSHADE_internal_io::PDB:
528  this->readInPDB ( settings );
529  break;
530 
531  case ProSHADE_internal_io::MAP:
532  this->readInMAP ( settings );
533  break;
534  }
535 
536  //================================================ This structure is now full
537  this->isEmpty = false;
538 
539  //================================================ Report function completion
540  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Structure read in successfully." );
541 
542  //================================================ Done
543  return ;
544 
545 }
546 
555 {
556  //================================================ Open the file
557  gemmi::Ccp4<float> map;
558  map.read_ccp4 ( gemmi::MaybeGzipped ( this->fileName.c_str() ) );
559 
560  //================================================ Convert to XYZ and create complete map, if need be
561  map.setup ( gemmi::GridSetup::ReorderOnly, NAN );
562 
563  //================================================ Read in the rest of the map file header
565  &this->xDimIndices, &this->yDimIndices, &this->zDimIndices,
566  &this->xDimSize, &this->yDimSize, &this->zDimSize,
567  &this->aAngle, &this->bAngle, &this->cAngle,
568  &this->xFrom, &this->yFrom, &this->zFrom,
569  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin,
570  &this->xAxisOrder, &this->yAxisOrder, &this->zAxisOrder,
571  &this->xGridIndices, &this->yGridIndices, &this->zGridIndices );
572 
573  //================================================ Save the map density to ProSHADE variable
574  ProSHADE_internal_io::readInMapData ( &map, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, this->xAxisOrder, this->yAxisOrder, this->zAxisOrder );
575 
576  //================================================ If mask is supplied and the correct task is used
577  if ( ( settings->appliedMaskFileName != "" ) && ( ( settings->task == MapManip ) || ( settings->task == Symmetry ) ) )
578  {
579  //================================================ Report progress
580  std::stringstream hlpSS;
581  hlpSS << "Reading mask file " << settings->appliedMaskFileName;
582  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, hlpSS.str() );
583 
584  //============================================ Open the mask
585  gemmi::Ccp4<float> mask;
586  mask.read_ccp4 ( gemmi::MaybeGzipped ( settings->appliedMaskFileName.c_str() ) );
587 
588  //============================================ Convert to XYZ and create complete mask, if need be
589  mask.setup ( gemmi::GridSetup::ReorderOnly, 0 );
590 
591  //============================================ Read in the rest of the mask file header
592  proshade_unsign xDI, yDI, zDI, xAOR, yAOR, zAOR, xGI, yGI, zGI;
593  proshade_single xDS, yDS, zDS, aA, bA, cA;
594  proshade_signed xF, yF, zF, xAO, yAO, zAO;
596  &xDI, &yDI, &zDI,
597  &xDS, &yDS, &zDS,
598  &aA, &bA, &cA,
599  &xF, &yF, &zF,
600  &xAO, &yAO, &zAO,
601  &xAOR, &yAOR, &zAOR,
602  &xGI, &yGI, &zGI );
603 
604  //============================================ Sanity check
605  if ( ( this->xDimIndices != xDI ) || ( this->yDimIndices != yDI ) || ( this->zDimIndices != zDI ) )
606  {
607  throw ProSHADE_exception ( "The supplied map mask has different dimensions than the\n : density map.", "EM00065", __FILE__, __LINE__, __func__, "Most likely the mask is not the correct mask for this map,\n : as it has different dimensions from the density map.\n : Please review that the supplied map and mask form a pair." );
608  }
609 
610  //============================================ Save the mask values to ProSHADE variable
611  proshade_double* internalMask = nullptr;
612  ProSHADE_internal_io::readInMapData ( &mask, internalMask, xDI, yDI, zDI, xAOR, yAOR, zAOR );
613 
614  //============================================ Apply the mask to the map
615  for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { this->internalMap[iter] *= internalMask[iter]; }
616 
617  //============================================ Release the memory
618  delete[] internalMask;
619 
620  //============================================ Report progress
621  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, "Mask read in and applied successfully." );
622  }
623 
624  //================================================ Remove negative values if so required
625  if ( settings->removeNegativeDensity ) { for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { if ( this->internalMap[iter] < 0.0 ) { this->internalMap[iter] = 0.0; } } }
626 
627  //================================================ Set resolution if need be
628  if ( settings->requestedResolution < 0.0f )
629  {
630  settings->setResolution ( std::min ( static_cast<proshade_single> ( this->xDimSize ) / static_cast<proshade_single> ( this->xDimIndices ),
631  std::min ( static_cast<proshade_single> ( this->yDimSize ) / static_cast<proshade_single> ( this->yDimIndices ),
632  static_cast<proshade_single> ( this->zDimSize ) / static_cast<proshade_single> ( this->zDimIndices ) ) ) * 2.0f );
633  }
634 
635  //================================================ Set iterators from and to
636  this->figureIndexStartStop ( );
637 
638  //================================================ If specific resolution is requested, make sure the map has it
639  if ( settings->changeMapResolution || settings->changeMapResolutionTriLinear )
640  {
641  //============================================ Before re-sampling sampling rate
642  proshade_single xSampRate = this->xDimSize / static_cast< proshade_single > ( this->xTo - this->xFrom );
643  proshade_single ySampRate = this->yDimSize / static_cast< proshade_single > ( this->yTo - this->yFrom );
644  proshade_single zSampRate = this->zDimSize / static_cast< proshade_single > ( this->zTo - this->zFrom );
645 
646  //============================================ Bofore re-sampling first index position
647  proshade_single xStartPosBefore = static_cast< proshade_single > ( this->xFrom ) * xSampRate;
648  proshade_single yStartPosBefore = static_cast< proshade_single > ( this->yFrom ) * ySampRate;
649  proshade_single zStartPosBefore = static_cast< proshade_single > ( this->zFrom ) * zSampRate;
650 
651  //============================================ Find COM before map re-sampling
652  proshade_double xMapCOMPreReSampl = 0.0, yMapCOMPreReSampl = 0.0, zMapCOMPreReSampl = 0.0;
653  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPreReSampl, &yMapCOMPreReSampl, &zMapCOMPreReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
654 
655  //============================================ Re-sample map
656  this->reSampleMap ( settings );
657 
658  //============================================ After re-sampling sampling rate
659  xSampRate = this->xDimSize / static_cast< proshade_single > ( this->xTo - this->xFrom );
660  ySampRate = this->yDimSize / static_cast< proshade_single > ( this->yTo - this->yFrom );
661  zSampRate = this->zDimSize / static_cast< proshade_single > ( this->zTo - this->zFrom );
662 
663  //============================================ After re-sampling first index position
664  proshade_single xStartPosAfter = static_cast< proshade_single > ( this->xFrom ) * xSampRate;
665  proshade_single yStartPosAfter = static_cast< proshade_single > ( this->yFrom ) * ySampRate;
666  proshade_single zStartPosAfter = static_cast< proshade_single > ( this->zFrom ) * zSampRate;
667 
668  //============================================ Translate by change in corners to make the boxes as similarly placed as possible
669  proshade_single xMov = static_cast< proshade_single > ( xStartPosAfter - xStartPosBefore );
670  proshade_single yMov = static_cast< proshade_single > ( yStartPosAfter - yStartPosBefore );
671  proshade_single zMov = static_cast< proshade_single > ( zStartPosAfter - zStartPosBefore );
672  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize,
673  &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
674  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
675 
676  //============================================ Find COM after map re-sampling and corner move
677  proshade_double xMapCOMPostReSampl = 0.0, yMapCOMPostReSampl = 0.0, zMapCOMPostReSampl = 0.0;
678  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPostReSampl, &yMapCOMPostReSampl, &zMapCOMPostReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
679 
680  //============================================ Match the COMs to get as close position of the re-sampled structure to the original as possible
682  static_cast< proshade_single > ( xMapCOMPreReSampl - xMapCOMPostReSampl ),
683  static_cast< proshade_single > ( yMapCOMPreReSampl - yMapCOMPostReSampl ),
684  static_cast< proshade_single > ( zMapCOMPreReSampl - zMapCOMPostReSampl ),
685  this->xDimSize, this->yDimSize, this->zDimSize,
686  static_cast< proshade_signed > ( this->xDimIndices ),
687  static_cast< proshade_signed > ( this->yDimIndices ),
688  static_cast< proshade_signed > ( this->zDimIndices ) );
689  }
690 
691  //================================================ Save the original sizes
692  this->xDimSizeOriginal = this->xDimSize;
693  this->yDimSizeOriginal = this->yDimSize;
694  this->zDimSizeOriginal = this->zDimSize;
695 
696  //================================================ Save the original index counts
697  this->xDimIndicesOriginal = this->xDimIndices;
698  this->yDimIndicesOriginal = this->yDimIndices;
699  this->zDimIndicesOriginal = this->zDimIndices;
700 
701  //================================================ Save the original axis origins
702  this->xAxisOriginOriginal = this->xAxisOrigin;
703  this->yAxisOriginOriginal = this->yAxisOrigin;
704  this->zAxisOriginOriginal = this->zAxisOrigin;
705 
706  //================================================ Compute and save the COM
707  this->findMapCOM ( );
708  this->originalMapXCom = this->xCom;
709  this->originalMapYCom = this->yCom;
710  this->originalMapZCom = this->zCom;
711 
712  //================================================ Done
713 
714 }
715 
726 {
727  //================================================ Set resolution if need be
728  if ( settings->requestedResolution < 0.0f )
729  {
730  settings->setResolution ( 8.0 );
731  }
732 
733  //================================================ Open PDB file for reading
734  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
735 
736  //================================================ Change B-factors if need be
737  if ( settings->pdbBFactorNewVal >= 0.0 )
738  {
740  }
741 
742  //================================================ Remove waters if required
743  if ( settings->removeWaters )
744  {
746  }
747 
748  //================================================ Get PDB COM values
749  proshade_double xCOMPdb, yCOMPdb, zCOMPdb;
750  ProSHADE_internal_mapManip::findPDBCOMValues ( pdbFile, &xCOMPdb, &yCOMPdb, &zCOMPdb, settings->firstModelOnly );
751 
752  //================================================ Find the ranges
753  proshade_single xF, xT, yF, yT, zF, zT;
754  ProSHADE_internal_mapManip::determinePDBRanges ( pdbFile, &xF, &xT, &yF, &yT, &zF, &zT, settings->firstModelOnly );
755 
756  //================================================ Move ranges to have all FROM values 20
757  proshade_single xMov = static_cast< proshade_single > ( 20.0f - xF );
758  proshade_single yMov = static_cast< proshade_single > ( 20.0f - yF );
759  proshade_single zMov = static_cast< proshade_single > ( 20.0f - zF );
760  ProSHADE_internal_mapManip::movePDBForMapCalc ( &pdbFile, xMov, yMov, zMov, settings->firstModelOnly );
761 
762  //================================================ Set the angstrom sizes
763  this->xDimSize = static_cast< proshade_single > ( xT - xF + 40.0f );
764  this->yDimSize = static_cast< proshade_single > ( yT - yF + 40.0f );
765  this->zDimSize = static_cast< proshade_single > ( zT - zF + 40.0f );
766 
767  //================================================ Generate map from nicely placed atoms (cell size will be range + 40)
768  ProSHADE_internal_mapManip::generateMapFromPDB ( pdbFile, this->internalMap, settings->requestedResolution, this->xDimSize, this->yDimSize, this->zDimSize, &this->xTo, &this->yTo, &this->zTo, settings->forceP1, settings->firstModelOnly );
769 
770  //================================================ Remove negative values if so required
771  if ( settings->removeNegativeDensity ) { for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { if ( this->internalMap[iter] < 0.0 ) { this->internalMap[iter] = 0.0; } } }
772 
773  //================================================ Set the internal variables to correct values
774  this->setPDBMapValues ( );
775 
776  //================================================ Compute reverse movement based on COMs. If there is more than 1 models, simply moving back the xyzMov is not enough.
777  proshade_double xCOMMap, yCOMMap, zCOMMap;
778  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xCOMMap, &yCOMMap, &zCOMMap,
779  this->xDimSize, this->yDimSize, this->zDimSize,
780  this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
781 
782  if ( pdbFile.models.size() > 1 )
783  {
784  xMov = static_cast< proshade_single > ( xCOMMap - xCOMPdb );
785  yMov = static_cast< proshade_single > ( yCOMMap - yCOMPdb );
786  zMov = static_cast< proshade_single > ( zCOMMap - zCOMPdb );
787  }
788 
789  //================================================ Move map back to the original PDB location
790  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize,
791  &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
792  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
793  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
794  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ),
795  static_cast< proshade_signed > ( this->zDimIndices ) );
796 
797  //================================================ If specific resolution is requested, make sure the map has it
798  if ( settings->changeMapResolution || settings->changeMapResolutionTriLinear )
799  {
800  //============================================ Before re-sampling sampling rate
801  proshade_single xSampRate = this->xDimSize / static_cast< proshade_single > ( this->xTo - this->xFrom );
802  proshade_single ySampRate = this->yDimSize / static_cast< proshade_single > ( this->yTo - this->yFrom );
803  proshade_single zSampRate = this->zDimSize / static_cast< proshade_single > ( this->zTo - this->zFrom );
804 
805  //============================================ Bofore re-sampling first index position
806  proshade_single xStartPosBefore = static_cast< proshade_single > ( this->xFrom ) * xSampRate;
807  proshade_single yStartPosBefore = static_cast< proshade_single > ( this->yFrom ) * ySampRate;
808  proshade_single zStartPosBefore = static_cast< proshade_single > ( this->zFrom ) * zSampRate;
809 
810  //============================================ Find COM before map re-sampling
811  proshade_double xMapCOMPreReSampl = 0.0, yMapCOMPreReSampl = 0.0, zMapCOMPreReSampl = 0.0;
812  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPreReSampl, &yMapCOMPreReSampl, &zMapCOMPreReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
813 
814  //============================================ Re-sample map
815  this->reSampleMap ( settings );
816 
817  //============================================ After re-sampling sampling rate
818  xSampRate = this->xDimSize / static_cast< proshade_single > ( this->xTo - this->xFrom );
819  ySampRate = this->yDimSize / static_cast< proshade_single > ( this->yTo - this->yFrom );
820  zSampRate = this->zDimSize / static_cast< proshade_single > ( this->zTo - this->zFrom );
821 
822  //============================================ After re-sampling first index position
823  proshade_single xStartPosAfter = static_cast< proshade_single > ( this->xFrom ) * xSampRate;
824  proshade_single yStartPosAfter = static_cast< proshade_single > ( this->yFrom ) * ySampRate;
825  proshade_single zStartPosAfter = static_cast< proshade_single > ( this->zFrom ) * zSampRate;
826 
827  //============================================ Translate by change in corners to make the boxes as similarly placed as possible
828  proshade_single xMovHlp = static_cast< proshade_single > ( xStartPosAfter - xStartPosBefore );
829  proshade_single yMovHlp = static_cast< proshade_single > ( yStartPosAfter - yStartPosBefore );
830  proshade_single zMovHlp = static_cast< proshade_single > ( zStartPosAfter - zStartPosBefore );
831  ProSHADE_internal_mapManip::moveMapByIndices ( &xMovHlp, &yMovHlp, &zMovHlp, this->xDimSize, this->yDimSize, this->zDimSize,
832  &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
833  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
834 
835  //============================================ Find COM after map re-sampling and corner move
836  proshade_double xMapCOMPostReSampl = 0.0, yMapCOMPostReSampl = 0.0, zMapCOMPostReSampl = 0.0;
837  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xMapCOMPostReSampl, &yMapCOMPostReSampl, &zMapCOMPostReSampl, this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom, this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
838 
839  //============================================ Match the COMs to get as close position of the re-sampled structure to the original as possible
841  static_cast< proshade_single > ( xMapCOMPreReSampl - xMapCOMPostReSampl ),
842  static_cast< proshade_single > ( yMapCOMPreReSampl - yMapCOMPostReSampl ),
843  static_cast< proshade_single > ( zMapCOMPreReSampl - zMapCOMPostReSampl ),
844  this->xDimSize, this->yDimSize, this->zDimSize,
845  static_cast< proshade_signed > ( this->xDimIndices ),
846  static_cast< proshade_signed > ( this->yDimIndices ),
847  static_cast< proshade_signed > ( this->zDimIndices ) );
848  }
849 
850  //================================================ Save the original sizes
851  this->xDimSizeOriginal = this->xDimSize;
852  this->yDimSizeOriginal = this->yDimSize;
853  this->zDimSizeOriginal = this->zDimSize;
854 
855  //================================================ Save the original index counts
856  this->xDimIndicesOriginal = this->xDimIndices;
857  this->yDimIndicesOriginal = this->yDimIndices;
858  this->zDimIndicesOriginal = this->zDimIndices;
859 
860  //================================================ Save the original axis origins
861  this->xAxisOriginOriginal = this->xAxisOrigin;
862  this->yAxisOriginOriginal = this->yAxisOrigin;
863  this->zAxisOriginOriginal = this->zAxisOrigin;
864 
865  //================================================ Compute and save the COM
866  this->findMapCOM ( );
867  this->originalMapXCom = this->xCom;
868  this->originalMapYCom = this->yCom;
869  this->originalMapZCom = this->zCom;
870 
871  //================================================ Done
872  return;
873 
874 }
875 
881 {
882  //================================================ Set starts to 0
883  this->xFrom = 0;
884  this->yFrom = 0;
885  this->zFrom = 0;
886 
887  //================================================ Set angles to 90 degrees
888  this->aAngle = 90.0;
889  this->bAngle = 90.0;
890  this->cAngle = 90.0;
891 
892  //================================================ Set dimension sizes in indices
893  this->xDimIndices = static_cast< proshade_unsign > ( this->xTo );
894  this->yDimIndices = static_cast< proshade_unsign > ( this->yTo );
895  this->zDimIndices = static_cast< proshade_unsign > ( this->zTo );
896 
897  //================================================ Set the to indices properly
898  this->xTo -= 1;
899  this->yTo -= 1;
900  this->zTo -= 1;
901 
902  //================================================ Set grid indexing to cell indexing
903  this->xGridIndices = this->xDimIndices;
904  this->yGridIndices = this->yDimIndices;
905  this->zGridIndices = this->zDimIndices;
906 
907  //================================================ Set axis order
908  this->xAxisOrder = 1;
909  this->yAxisOrder = 2;
910  this->zAxisOrder = 3;
911 
912  //================================================ Set origin to the first index
913  this->xAxisOrigin = this->xFrom;
914  this->yAxisOrigin = this->yFrom;
915  this->zAxisOrigin = this->zFrom;
916 
917  //================================================ Done
918  return ;
919 
920 }
921 
927 {
928  //================================================ Set ends to origin + size - 1
929  this->xTo = this->xFrom + static_cast< proshade_signed > ( this->xDimIndices ) - 1;
930  this->yTo = this->yFrom + static_cast< proshade_signed > ( this->yDimIndices ) - 1;
931  this->zTo = this->zFrom + static_cast< proshade_signed > ( this->zDimIndices ) - 1;
932 
933  //================================================ Done
934  return ;
935 
936 }
937 
948 void ProSHADE_internal_data::ProSHADE_data::writeMap ( std::string fName, std::string title, int mode )
949 {
950  //================================================ Create and prepare new Grid gemmi object
951  gemmi::Grid<float> mapData;
952  mapData.set_unit_cell ( static_cast< double > ( this->xDimSize ), static_cast< double > ( this->yDimSize ), static_cast< double > ( this->zDimSize ), static_cast< double > ( this->aAngle ), static_cast< double > ( this->bAngle ), static_cast< double > ( this->cAngle ) );
953  mapData.set_size_without_checking ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ) );
954  mapData.axis_order = gemmi::AxisOrder::XYZ;
955  mapData.spacegroup = &gemmi::get_spacegroup_p1();
956 
957  //================================================ Create and prepare new Ccp4 gemmi object
958  gemmi::Ccp4<float> map;
959  map.grid = mapData;
960  map.update_ccp4_header ( mode );
961 
962  //================================================ Fill in the header
964  this->xDimIndices, this->yDimIndices, this->zDimIndices,
965  this->xDimSize, this->yDimSize, this->zDimSize,
966  this->aAngle, this->bAngle, this->cAngle,
967  this->xFrom, this->yFrom, this->zFrom,
968  this->xAxisOrigin, this->yAxisOrigin, this->zAxisOrigin,
969  this->xAxisOrder, this->yAxisOrder, this->zAxisOrder,
970  this->xGridIndices, this->yGridIndices, this->zGridIndices,
971  title, mode );
972 
973  //================================================ Copy internal map to grid
974  proshade_unsign arrPos = 0;
975  for ( proshade_unsign uIt = 0; uIt < this->xDimIndices; uIt++ )
976  {
977  for ( proshade_unsign vIt = 0; vIt < this->yDimIndices; vIt++ )
978  {
979  for ( proshade_unsign wIt = 0; wIt < this->zDimIndices; wIt++ )
980  {
981  arrPos = wIt + this->zDimIndices * ( vIt + this->yDimIndices * uIt );
982  map.grid.set_value ( static_cast< int > ( uIt ), static_cast< int > ( vIt ), static_cast< int > ( wIt ), static_cast<float> ( this->internalMap[arrPos] ) );
983  }
984  }
985  }
986 
987  //================================================ Update the statistics in the header
988  map.update_ccp4_header ( mode, true );
989 
990  //================================================ Write out the map
991  map.write_ccp4_map ( fName );
992 
993  //================================================ Done
994  return ;
995 
996 }
997 
1013 void ProSHADE_internal_data::ProSHADE_data::writePdb ( std::string fName, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double trsX, proshade_double trsY, proshade_double trsZ, bool firstModel )
1014 {
1015  //================================================ Check for co-ordinate origin
1016  if ( !ProSHADE_internal_io::isFilePDB ( this->fileName ) )
1017  {
1018  throw ProSHADE_exception ( "Cannot write co-ordinate file if the input file did not contain co-ordinates.", "EP00047", __FILE__, __LINE__, __func__, "You have called the WritePDB function on structure which\n : was created by reading in a map. This is not allowed as\n : ProSHADE cannot create co-ordinates from map file." );
1019  }
1020 
1021  //================================================ Open PDB file for reading
1022  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
1023 
1024  //================================================ If the map was rotated, do the same for the co-ordinates, making sure we take into account the rotation centre of the map
1025  if ( ( euA != 0.0 ) || ( euB != 0.0 ) || ( euG != 0.0 ) )
1026  {
1027  //============================================ Rotate the co-ordinates
1028  ProSHADE_internal_mapManip::rotatePDBCoordinates ( &pdbFile, euA, euB, euG, this->originalPdbRotCenX, this->originalPdbRotCenY, this->originalPdbRotCenZ, firstModel );
1029  }
1030 
1031  //================================================ Translate by required translation and the map centering (if applied)
1032  ProSHADE_internal_mapManip::translatePDBCoordinates ( &pdbFile, trsX, trsY, trsZ, firstModel );
1033 
1034  //================================================ Write the PDB file
1035  std::ofstream outCoOrdFile;
1036  outCoOrdFile.open ( fName.c_str() );
1037 
1038  if ( outCoOrdFile.is_open() )
1039  {
1040  gemmi::PdbWriteOptions opt;
1041  write_pdb ( pdbFile, outCoOrdFile, opt );
1042  }
1043  else
1044  {
1045  std::stringstream hlpMessage;
1046  hlpMessage << "Failed to open the PDB file " << fName << " for output.";
1047  throw ProSHADE_exception ( hlpMessage.str().c_str(), "EP00048", __FILE__, __LINE__, __func__, "ProSHADE has failed to open the PDB output file. This is\n : likely caused by either not having the write privileges\n : to the required output path, or by making a mistake in\n : the path." );
1048  }
1049 
1050  outCoOrdFile.close ( );
1051 
1052  //================================================ Done
1053  return ;
1054 }
1055 
1064 void ProSHADE_internal_data::ProSHADE_data::writeMask ( std::string fName, proshade_double* mask )
1065 {
1066  //================================================ Allocate the memory
1067  proshade_double* hlpMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1068  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1069 
1070  //================================================ Copy original map and over-write with the mask
1071  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1072  {
1073  hlpMap[iter] = this->internalMap[iter];
1074  this->internalMap[iter] = mask[iter];
1075  }
1076 
1077  //================================================ Write out the mask
1078  this->writeMap ( fName );
1079 
1080  //================================================ Copy the original map values back
1081  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1082  {
1083  this->internalMap[iter] = hlpMap[iter];
1084  }
1085 
1086  //================================================ Release memory
1087  delete[] hlpMap;
1088 
1089  //================================================ Done
1090  return ;
1091 }
1092 
1102 {
1103  //================================================ Report function start
1104  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion." );
1105 
1106  //================================================ Initialise variables
1107  proshade_signed arrayPos, invPos;
1108 
1109  //================================================ Create helper map
1110  proshade_double* hlpMap = new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
1111  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1112 
1113  //================================================ Save map values to the helper map
1114  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1115  {
1116  hlpMap[iter] = this->internalMap[iter];
1117  }
1118 
1119  //================================================ Invert the values
1120  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
1121  {
1122  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
1123  {
1124  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
1125  {
1126  //==================================== Var init
1127  arrayPos = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
1128  invPos = ( static_cast< proshade_signed > ( this->zDimIndices - 1 ) - zIt ) + static_cast< proshade_signed > ( this->zDimIndices ) * ( ( static_cast< proshade_signed > ( this->yDimIndices - 1 ) - yIt ) + static_cast< proshade_signed > ( this->yDimIndices ) * ( static_cast< proshade_signed > ( this->xDimIndices - 1 ) - xIt ) );
1129 
1130  //==================================== And save
1131  this->internalMap[invPos] = hlpMap[arrayPos];
1132  }
1133  }
1134  }
1135 
1136  //================================================ Release memory
1137  delete[] hlpMap;
1138 
1139  //================================================ Report function completion
1140  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map inversion completed." );
1141 
1142  //================================================ Done
1143  return ;
1144 
1145 }
1146 
1156 {
1157  //================================================ Report function start
1158  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation." );
1159 
1160  //================================================ Initialise vector of map values
1161  std::vector<proshade_double> mapVals ( this->xDimIndices * this->yDimIndices * this->zDimIndices, 0.0 );
1162 
1163  //================================================ Get all map values
1164  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1165  {
1166  mapVals.at(iter) = this->internalMap[iter];
1167  }
1168 
1169  //================================================ Get mean and sd
1170  proshade_double* meanSD = new proshade_double[2];
1171  ProSHADE_internal_maths::vectorMeanAndSD ( &mapVals, meanSD );
1172 
1173  //================================================ Normalise the values
1174  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1175  {
1176  this->internalMap[iter] = ( this->internalMap[iter] - meanSD[0] ) / meanSD[1];
1177  }
1178 
1179  //================================================ Clear the vector
1180  mapVals.clear ( );
1181 
1182  //================================================ Release memory
1183  delete[] meanSD;
1184 
1185  //================================================ Report function completion
1186  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map normalisation completed." );
1187 
1188  //================================================ Done
1189  return ;
1190 
1191 }
1192 
1193 
1203 {
1204  //================================================ Report function start
1205  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Computing mask." );
1206 
1207  //================================================ Initialise the blurred map
1208  proshade_double* blurredMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1209  ProSHADE_internal_misc::checkMemoryAllocation ( blurredMap, __FILE__, __LINE__, __func__ );
1210 
1211  //================================================ Compute blurred map
1212  ProSHADE_internal_mapManip::blurSharpenMap ( this->internalMap, blurredMap, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1213  this->xDimSize, this->yDimSize, this->zDimSize, settings->blurFactor );
1214 
1215  //================================================ Compute mask from blurred map and save it into the original map
1216  ProSHADE_internal_mapManip::getMaskFromBlurr ( blurredMap, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->maskingThresholdIQRs );
1217 
1218  //================================================ Print the mask if need be
1219  if ( settings->saveMask ) { if ( settings->maskFileName == "" ) { this->writeMask ( "proshade_mask.map", blurredMap ); } else { std::stringstream ss; ss << settings->maskFileName << "_" << this->inputOrder << ".map"; this->writeMask ( ss.str(), blurredMap ); } }
1220 
1221  //================================================ Release memory
1222  delete[] blurredMap;
1223 
1224  //================================================ Report function completion
1225  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Mask computed." );
1226 
1227  //================================================ Done
1228  return ;
1229 
1230 }
1231 
1243 {
1244  //================================================ Report function start
1245  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Finding new boundaries." );
1246 
1247  //================================================ If same bounds as first one are required, test if possible and return these instead
1248  if ( settings->useSameBounds && ( this->inputOrder != 0 ) )
1249  {
1250  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { ret[iter] = settings->forceBounds[iter]; }
1251  }
1252  //================================================ In this case, bounds need to be found de novo
1253  else
1254  {
1255  //============================================ Find the non-zero bounds
1257  static_cast< proshade_signed > ( this->xDimIndices ),
1258  static_cast< proshade_signed > ( this->yDimIndices ),
1259  static_cast< proshade_signed > ( this->zDimIndices ),
1260  ret );
1261 
1262  //============================================ Add the extra space
1263  ProSHADE_internal_mapManip::addExtraBoundSpace ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1264  this->xDimSize, this->yDimSize, this->zDimSize, ret, settings->boundsExtraSpace );
1265 
1266  //============================================ Beautify boundaries
1267  ProSHADE_internal_mapManip::beautifyBoundaries ( ret, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->boundsSimilarityThreshold );
1268 
1269  //============================================ Report function results
1270  std::stringstream ssHlp;
1271  ssHlp << "New boundaries are: " << ret[1] - ret[0] + 1 << " x " << ret[3] - ret[2] + 1 << " x " << ret[5] - ret[4] + 1;
1272  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, ssHlp.str() );
1273 
1274  //============================================ If need be, save boundaries to be used for all other structure
1275  if ( settings->useSameBounds && ( this->inputOrder == 0 ) )
1276  {
1277  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { settings->forceBounds[iter] = ret[iter]; }
1278  }
1279  }
1280 
1281  //================================================ Report function completion
1282  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New boundaries determined." );
1283 
1284  //================================================ Done
1285  return ;
1286 
1287 }
1288 
1301 {
1302  //================================================ Report function start
1303  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Creating new structure according to the new bounds." );
1304 
1305  //================================================ Fill in basic info
1306  newStr->fileName = "N/A";
1307  newStr->fileType = ProSHADE_internal_io::MAP;
1308 
1309  //================================================ Fill in new structure values
1310  newStr->xDimIndices = static_cast< proshade_unsign > ( newBounds[1] ) - static_cast< proshade_unsign > ( newBounds[0] ) + 1;
1311  newStr->yDimIndices = static_cast< proshade_unsign > ( newBounds[3] ) - static_cast< proshade_unsign > ( newBounds[2] ) + 1;
1312  newStr->zDimIndices = static_cast< proshade_unsign > ( newBounds[5] ) - static_cast< proshade_unsign > ( newBounds[4] ) + 1;
1313 
1314  newStr->aAngle = this->aAngle;
1315  newStr->bAngle = this->aAngle;
1316  newStr->cAngle = this->aAngle;
1317 
1318  newStr->xDimSize = static_cast<proshade_single> ( newStr->xDimIndices ) * ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) );
1319  newStr->yDimSize = static_cast<proshade_single> ( newStr->yDimIndices ) * ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) );
1320  newStr->zDimSize = static_cast<proshade_single> ( newStr->zDimIndices ) * ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) );
1321 
1322  newStr->xGridIndices = newStr->xDimIndices;
1323  newStr->yGridIndices = newStr->yDimIndices;
1324  newStr->zGridIndices = newStr->zDimIndices;
1325 
1326  newStr->xAxisOrder = this->xAxisOrder;
1327  newStr->yAxisOrder = this->yAxisOrder;
1328  newStr->zAxisOrder = this->zAxisOrder;
1329 
1330  newStr->xAxisOrigin = this->xAxisOrigin + newBounds[0];
1331  newStr->yAxisOrigin = this->yAxisOrigin + newBounds[2];
1332  newStr->zAxisOrigin = this->zAxisOrigin + newBounds[4];
1333 
1334  newStr->xFrom = this->xFrom + newBounds[0];
1335  newStr->yFrom = this->yFrom + newBounds[2];
1336  newStr->zFrom = this->zFrom + newBounds[4];
1337 
1338  newStr->xTo = this->xTo - ( static_cast< proshade_signed > ( this->xDimIndices - 1 ) - newBounds[1] );
1339  newStr->yTo = this->yTo - ( static_cast< proshade_signed > ( this->yDimIndices - 1 ) - newBounds[3] );
1340  newStr->zTo = this->zTo - ( static_cast< proshade_signed > ( this->zDimIndices - 1 ) - newBounds[5] );
1341 
1342  //================================================ Allocate new structure map
1343  newStr->internalMap = new proshade_double[newStr->xDimIndices * newStr->yDimIndices * newStr->zDimIndices];
1344  ProSHADE_internal_misc::checkMemoryAllocation ( newStr->internalMap, __FILE__, __LINE__, __func__ );
1345 
1346  //================================================ Copy the map
1347  ProSHADE_internal_mapManip::copyMapByBounds ( newStr->xFrom, newStr->xTo, newStr->yFrom, newStr->yTo, newStr->zFrom, newStr->zTo,
1348  this->xFrom, this->yFrom, this->zFrom, newStr->yDimIndices, newStr->zDimIndices,
1349  this->xDimIndices, this->yDimIndices, this->zDimIndices, newStr->internalMap, this->internalMap );
1350 
1351  //================================================ Report function completion
1352  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New structure created." );
1353 
1354  //================================================ Done
1355  return ;
1356 
1357 }
1358 
1367 {
1368  //================================================ Initialise the return variable
1369  proshade_single* changeVals = new proshade_single[6];
1370 
1371  //================================================ Now re-sample the map
1372  if ( settings->changeMapResolution )
1373  {
1374  ProSHADE_internal_mapManip::reSampleMapToResolutionFourier ( this->internalMap, settings->requestedResolution, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1375  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1376 
1377  if ( settings->changeMapResolutionTriLinear )
1378  {
1379  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested both Fourier-space and real-space map re-sampling. Defaulting to only Fourier space re-samplling.", "WM00049" );
1380  }
1381  }
1382  if ( settings->changeMapResolutionTriLinear && !settings->changeMapResolution )
1383  {
1384  ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear ( this->internalMap, settings->requestedResolution, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1385  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1386 
1387  }
1388 
1389  //================================================ Set the internal values to reflect the new map size
1390  this->xDimIndices += static_cast<proshade_unsign> ( changeVals[0] );
1391  this->yDimIndices += static_cast<proshade_unsign> ( changeVals[1] );
1392  this->zDimIndices += static_cast<proshade_unsign> ( changeVals[2] );
1393 
1394  this->xGridIndices = this->xDimIndices;
1395  this->yGridIndices = this->yDimIndices;
1396  this->zGridIndices = this->zDimIndices;
1397 
1398  this->xTo += static_cast<proshade_unsign> ( changeVals[0] );
1399  this->yTo += static_cast<proshade_unsign> ( changeVals[1] );
1400  this->zTo += static_cast<proshade_unsign> ( changeVals[2] );
1401 
1402  this->xDimSize = changeVals[3];
1403  this->yDimSize = changeVals[4];
1404  this->zDimSize = changeVals[5];
1405 
1406  //================================================ Figure how much the new map moved
1407  proshade_single xMov = -( ( static_cast<proshade_single> ( this->xFrom ) * ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) - changeVals[0] ) ) -
1408  ( static_cast<proshade_single> ( this->xFrom ) * ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) ) ) );
1409  proshade_single yMov = -( ( static_cast<proshade_single> ( this->yFrom ) * ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) - changeVals[1] ) ) -
1410  ( static_cast<proshade_single> ( this->yFrom ) * ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) ) ) );
1411  proshade_single zMov = -( ( static_cast<proshade_single> ( this->zFrom ) * ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) - changeVals[2] ) ) -
1412  ( static_cast<proshade_single> ( this->zFrom ) * ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) ) ) );
1413 
1414  //================================================ Move by indices (this should be sufficient)
1415  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize, &this->xFrom, &this->xTo,
1416  &this->yFrom, &this->yTo, &this->zFrom, &this->zTo, &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
1417 
1418  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
1419  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ) );
1420 
1421  //================================================ Release memory
1422  delete[] changeVals;
1423 
1424  //================================================ Done
1425  return ;
1426 
1427 }
1428 
1439 {
1440  //================================================ Report function start
1441  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Centering map onto its COM." );
1442 
1443  //================================================ Initialise local variables
1444  proshade_double xCOM = 0.0;
1445  proshade_double yCOM = 0.0;
1446  proshade_double zCOM = 0.0;
1447 
1448  //================================================ Find the COM location
1449  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xCOM, &yCOM, &zCOM,
1450  this->xDimSize, this->yDimSize, this->xDimSize, this->xFrom,
1451  this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
1452 
1453  //================================================ Find the sampling rates
1454  proshade_single xSampRate = static_cast< proshade_single > ( this->xDimSize ) / static_cast< proshade_single > ( this->xTo - this->xFrom );
1455  proshade_single ySampRate = static_cast< proshade_single > ( this->yDimSize ) / static_cast< proshade_single > ( this->yTo - this->yFrom );
1456  proshade_single zSampRate = static_cast< proshade_single > ( this->zDimSize ) / static_cast< proshade_single > ( this->zTo - this->zFrom );
1457 
1458  //================================================ Convert to position in indices starting from 0
1459  xCOM /= static_cast< proshade_double > ( xSampRate );
1460  yCOM /= static_cast< proshade_double > ( ySampRate );
1461  zCOM /= static_cast< proshade_double > ( zSampRate );
1462 
1463  xCOM -= static_cast< proshade_double > ( this->xFrom );
1464  yCOM -= static_cast< proshade_double > ( this->yFrom );
1465  zCOM -= static_cast< proshade_double > ( this->zFrom );
1466 
1467  //================================================ Find distance from COM to map centre in Angstroms
1468  proshade_double xDist = ( ( static_cast<proshade_double> ( this->xDimIndices ) / 2.0 ) - xCOM ) * static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices );
1469  proshade_double yDist = ( ( static_cast<proshade_double> ( this->yDimIndices ) / 2.0 ) - yCOM ) * static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices );
1470  proshade_double zDist = ( ( static_cast<proshade_double> ( this->zDimIndices ) / 2.0 ) - zCOM ) * static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices );
1471 
1472  //================================================ Move the map within the box
1474  static_cast< proshade_single > ( xDist ),
1475  static_cast< proshade_single > ( yDist ),
1476  static_cast< proshade_single > ( zDist ),
1477  this->xDimSize, this->yDimSize, this->zDimSize,
1478  static_cast< proshade_signed > ( this->xDimIndices ),
1479  static_cast< proshade_signed > ( this->yDimIndices ),
1480  static_cast< proshade_signed > ( this->zDimIndices ) );
1481 
1482  //================================================ Note the change due to centering
1483  this->mapCOMProcessChangeX -= xDist;
1484  this->mapCOMProcessChangeY -= yDist;
1485  this->mapCOMProcessChangeZ -= zDist;
1486 
1487  //================================================ Report function completion
1488  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map centered." );
1489 
1490  //================================================ Done
1491  return ;
1492 
1493 }
1494 
1504 {
1505  //================================================ Report function start
1506  std::stringstream hlpSS;
1507  hlpSS << "Adding extra " << settings->addExtraSpace << " angstroms.";
1508  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str() );
1509 
1510  //================================================ Figure how much indices need to change
1511  proshade_unsign xAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) ) );
1512  proshade_unsign yAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) ) );
1513  proshade_unsign zAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) ) );
1514 
1515  //================================================ Update internal data variables
1516  this->xDimSize += 2 * static_cast<proshade_single> ( xAddIndices ) * this->xDimSize / static_cast<proshade_single> ( this->xDimIndices );
1517  this->yDimSize += 2 * static_cast<proshade_single> ( yAddIndices ) * this->yDimSize / static_cast<proshade_single> ( this->yDimIndices );
1518  this->zDimSize += 2 * static_cast<proshade_single> ( zAddIndices ) * this->zDimSize / static_cast<proshade_single> ( this->zDimIndices );
1519 
1520  this->xDimIndices += 2 * xAddIndices;
1521  this->yDimIndices += 2 * yAddIndices;
1522  this->zDimIndices += 2 * zAddIndices;
1523 
1524  this->xGridIndices = this->xDimIndices;
1525  this->yGridIndices = this->yDimIndices;
1526  this->zGridIndices = this->zDimIndices;
1527 
1528  this->xAxisOrigin -= xAddIndices;
1529  this->yAxisOrigin -= yAddIndices;
1530  this->zAxisOrigin -= zAddIndices;
1531 
1532  this->xFrom -= xAddIndices;
1533  this->yFrom -= yAddIndices;
1534  this->zFrom -= zAddIndices;
1535 
1536  this->xTo += xAddIndices;
1537  this->yTo += yAddIndices;
1538  this->zTo += zAddIndices;
1539 
1540  //================================================ Allocate new map
1541  proshade_double* newMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1542  ProSHADE_internal_misc::checkMemoryAllocation ( newMap, __FILE__, __LINE__, __func__ );
1543 
1544  //================================================ Set new map to zeroes
1545  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1546  {
1547  newMap[iter] = 0.0;
1548  }
1549 
1550  //================================================ Update the map
1551  proshade_unsign newMapIndex, oldMapIndex;
1552  for ( proshade_unsign xIt = 0; xIt < (this->xDimIndices - xAddIndices); xIt++ )
1553  {
1554  //============================================ Check if point is applicable
1555  if ( xIt < xAddIndices ) { continue; }
1556 
1557  for ( proshade_unsign yIt = 0; yIt < (this->yDimIndices - yAddIndices); yIt++ )
1558  {
1559  //======================================== Check if point is applicable
1560  if ( yIt < yAddIndices ) { continue; }
1561 
1562  for ( proshade_unsign zIt = 0; zIt < (this->zDimIndices - zAddIndices); zIt++ )
1563  {
1564  //==================================== Check if point is applicable
1565  if ( zIt < zAddIndices ) { continue; }
1566 
1567  //==================================== Var init
1568  newMapIndex = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
1569  oldMapIndex = (zIt - zAddIndices) + (this->zDimIndices - ( 2 * zAddIndices ) ) * ( (yIt - yAddIndices) + (this->yDimIndices - ( 2 * yAddIndices ) ) * (xIt - xAddIndices) );
1570 
1571  newMap[newMapIndex] = this->internalMap[oldMapIndex];
1572  }
1573  }
1574  }
1575 
1576  //================================================ Copy new to old
1577  delete[] this->internalMap;
1578 
1579  this->internalMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1580  ProSHADE_internal_misc::checkMemoryAllocation ( this->internalMap, __FILE__, __LINE__, __func__ );
1581 
1582  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1583  {
1584  this->internalMap[iter] = newMap[iter];
1585  }
1586 
1587  //================================================ Release memory
1588  delete[] newMap;
1589 
1590  //================================================ Report function completion
1591  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Extra space added." );
1592 
1593  //================================================ Done
1594  return ;
1595 
1596 }
1597 
1613 {
1614  //================================================ Invert map
1615  if ( settings->invertMap ) { this->invertMirrorMap ( settings ); }
1616  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion (mirror image) not requested." ); }
1617 
1618  //================================================ Normalise map
1619  if ( settings->normaliseMap ) { this->normaliseMap ( settings ); }
1620  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation not requested." ); }
1621 
1622  //================================================ Compute mask
1623  if ( settings->maskMap ) { this->maskMap ( settings ); }
1624  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Masking not requested." ); }
1625 
1626  //================================================ Centre map
1627  if ( settings->moveToCOM ) { this->centreMapOnCOM ( settings ); }
1628  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map centering not requested." ); }
1629 
1630  //================================================ Add extra space
1631  if ( settings->addExtraSpace != 0.0f ) { this->addExtraSpace ( settings ); }
1632  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Extra space not requested." ); }
1633 
1634  //================================================ Remove phase, if required
1635  if ( !settings->usePhase ) { this->removePhaseInormation ( settings ); ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information removed from the data." ); }
1636  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information retained in the data." ); }
1637 
1638  //================================================ Set settings values which were left on AUTO by user and will not be set later
1639  settings->setVariablesLeftOnAuto ( );
1640 
1641  //================================================ Done
1642  return ;
1643 
1644 }
1645 
1656 {
1657  //================================================ Check the current settings value is set to auto
1658  if ( this->spherePos.size() != 0 )
1659  {
1660  std::stringstream hlpSS;
1661  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1662  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1663  hlpSS << " Angstroms.";
1664  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str() );
1665  return ;
1666  }
1667 
1668  //================================================ Find maximum diagonal
1669  proshade_unsign maxDim = static_cast< proshade_unsign > ( std::max ( this->xDimSize, std::max ( this->yDimSize, this->zDimSize ) ) );
1670  proshade_unsign minDim = static_cast< proshade_unsign > ( std::min ( this->xDimSize, std::min ( this->yDimSize, this->zDimSize ) ) );
1671  proshade_unsign midDim = static_cast< proshade_unsign > ( 0 );
1672  if ( ( this->xDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->xDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->xDimSize ); }
1673  else if ( ( this->yDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->yDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->yDimSize ); }
1674  else { midDim = static_cast< proshade_unsign > ( this->zDimSize ); }
1675 
1676  proshade_single maxDiag = static_cast< proshade_single > ( std::sqrt ( std::pow ( static_cast<proshade_single> ( maxDim ), 2.0 ) +
1677  std::pow ( static_cast<proshade_single> ( midDim ), 2.0 ) ) );
1678 
1679  //================================================ Set between the points
1680  for ( proshade_single iter = 0.5f; ( iter * settings->maxSphereDists ) < ( maxDiag / 2.0f ); iter += 1.0f )
1681  {
1682  ProSHADE_internal_misc::addToSingleVector ( &this->spherePos, ( iter * settings->maxSphereDists ) );
1683  }
1684 
1685  //================================================ Save the number of spheres
1686  this->noSpheres = static_cast<proshade_unsign> ( this->spherePos.size() );
1687 
1688  //================================================ Report progress
1689  std::stringstream hlpSS;
1690  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1691  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1692  hlpSS << " Angstroms.";
1693  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str() );
1694 
1695  //================================================ Done
1696  return ;
1697 
1698 }
1699 
1700 
1713 {
1714  //================================================ Report progress
1715  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting sphere mapping procedure." );
1716 
1717  //================================================ Determine spherical harmonics variables
1718  settings->determineAllSHValues ( this->xDimIndices, this->yDimIndices,
1719  this->xDimSize, this->yDimSize, this->zDimSize );
1720  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere settings determined." );
1721 
1722  //================================================ Find number of spheres supported
1723  this->getSpherePositions ( settings );
1724  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere positions obtained." );
1725 
1726  //================================================ Create sphere objects and map the density
1727  this->spheres = new ProSHADE_internal_spheres::ProSHADE_sphere* [ this->noSpheres ];
1728  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ )
1729  {
1730  std::stringstream ss;
1731  ss << "Now mapping sphere " << iter << " .";
1732  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str() );
1733 
1734  this->spheres[iter] = new ProSHADE_internal_spheres::ProSHADE_sphere ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1735  this->xDimSize, this->yDimSize, this->zDimSize, iter,
1736  &this->spherePos, settings->progressiveSphereMapping, settings->maxBandwidth,
1737  this->internalMap, &this->maxShellBand );
1738  }
1739 
1740  //================================================ Report completion
1741  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere mapping procedure completed." );
1742 
1743  //================================================ Done
1744  return ;
1745 
1746 }
1747 
1757 {
1758  //================================================ Report progress
1759  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting spherical harmonics decomposition." );
1760 
1761  //================================================ Initialise memory
1762  this->sphericalHarmonics = new proshade_complex* [this->noSpheres];
1763  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics, __FILE__, __LINE__, __func__ );
1764  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1765  {
1766  this->sphericalHarmonics[iter] = new proshade_complex [(this->spheres[iter]->getLocalBandwidth() * 2) * (this->spheres[iter]->getLocalBandwidth() * 2)];
1767  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics[iter], __FILE__, __LINE__, __func__ );
1768  }
1769 
1770  //================================================ Compute the spherical harmonics
1771  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1772  {
1773  //============================================ Report progress
1774  std::stringstream ss;
1775  ss << "Now decomposing sphere " << iter << ". " << "( Band is: " << this->spheres[iter]->getLocalBandwidth() << ").";
1776  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str() );
1777 
1778  //============================================ Compute
1779  ProSHADE_internal_sphericalHarmonics::computeSphericalHarmonics ( this->spheres[iter]->getLocalBandwidth(), this->spheres[iter]->getMappedData(), this->sphericalHarmonics[iter] );
1780  }
1781 
1782  //================================================ Report completion
1783  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Spherical harmonics decomposition complete." );
1784 
1785  //======================================== Done
1786  return ;
1787 
1788 }
1789 
1801 void ProSHADE_internal_data::ProSHADE_data::detectSymmetryInStructure ( ProSHADE_settings* settings, std::vector< proshade_double* >* axes, std::vector < std::vector< proshade_double > >* allCs )
1802 {
1803  //================================================ Prepare FSC computation memory and variables
1804  fftw_complex *mapData, *origCoeffs, *fCoeffs;
1805  fftw_plan planForwardFourier;
1806  proshade_double **bindata;
1807  proshade_signed *binIndexing, *binCounts, noBins;
1808  this->prepareFSCFourierMemory ( mapData, origCoeffs, fCoeffs, binIndexing, &noBins, bindata, binCounts, &planForwardFourier );
1809 
1810  //================================================ Initialise variables
1811  std::vector< proshade_double* > CSyms = this->getCyclicSymmetriesList ( settings );
1812 
1813  //================================================ Was any particular symmetry requested?
1814  if ( settings->requestedSymmetryType == "" )
1815  {
1816  //============================================ Run the symmetry detection functions for C, D, T, O and I symmetries
1817  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
1818  std::vector< proshade_double* > ISyms = this->getIcosahedralSymmetriesList ( settings, &CSyms );
1819  std::vector< proshade_double* > OSyms; std::vector< proshade_double* > TSyms;
1820  if ( ISyms.size() < 31 ) { OSyms = this->getOctahedralSymmetriesList ( settings, &CSyms ); if ( OSyms.size() < 13 ) { TSyms = this->getTetrahedralSymmetriesList ( settings, &CSyms ); } }
1821 
1822  //============================================ Decide on recommended symmetry
1823  this->saveRecommendedSymmetry ( settings, &CSyms, &DSyms, &TSyms, &OSyms, &ISyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
1824  }
1825 
1826  if ( settings->requestedSymmetryType == "C" )
1827  {
1828  //============================================ Run only the C symmetry detection and search for requested fold
1829  this->saveRequestedSymmetryC ( settings, &CSyms, axes );
1830  }
1831 
1832  if ( settings->requestedSymmetryType == "D" )
1833  {
1834  //============================================ Run only the D symmetry detection and search for requested fold
1835  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
1836  this->saveRequestedSymmetryD ( settings, &DSyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
1837  }
1838 
1839  if ( settings->requestedSymmetryType == "T" )
1840  {
1841  //============================================ Run only the T symmetry detection and search for requested fold
1842  std::vector< proshade_double* > TSyms = this->getTetrahedralSymmetriesList ( settings, &CSyms );
1843  settings->setRecommendedFold ( 0 );
1844  if ( TSyms.size() == 7 ) { settings->setRecommendedSymmetry ( "T" ); for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( TSyms.size() ); it++ ) { settings->setDetectedSymmetry ( TSyms.at(it) ); ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, TSyms.at(it) ); } }
1845  else { settings->setRecommendedSymmetry ( "" ); }
1846  }
1847 
1848  if ( settings->requestedSymmetryType == "O" )
1849  {
1850  //============================================ Run only the O symmetry detection and search for requested fold
1851  std::vector< proshade_double* > OSyms = this->getOctahedralSymmetriesList ( settings, &CSyms );
1852  settings->setRecommendedFold ( 0 );
1853  if ( OSyms.size() == 13 ) { settings->setRecommendedSymmetry ( "O" ); for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( OSyms.size() ); it++ ) { settings->setDetectedSymmetry ( OSyms.at(it) ); ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, OSyms.at(it) ); } }
1854  else { settings->setRecommendedSymmetry ( "" ); }
1855  }
1856 
1857  if ( settings->requestedSymmetryType == "I" )
1858  {
1859  //============================================ Run only the T symmetry detection and search for requested fold
1860  std::vector< proshade_double* > ISyms = this->getIcosahedralSymmetriesList ( settings, &CSyms );
1861  settings->setRecommendedFold ( 0 );
1862  if ( ISyms.size() == 31 ) { settings->setRecommendedSymmetry ( "I" ); for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( ISyms.size() ); it++ ) { settings->setDetectedSymmetry ( ISyms.at(it) ); ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, ISyms.at(it) ); } }
1863  else { settings->setRecommendedSymmetry ( "" ); }
1864  }
1865 
1866  if ( ( settings->requestedSymmetryType != "" ) && ( settings->requestedSymmetryType != "C" ) && ( settings->requestedSymmetryType != "D" ) && ( settings->requestedSymmetryType != "T" ) && ( settings->requestedSymmetryType != "O" ) && ( settings->requestedSymmetryType != "I" ) )
1867  {
1868  throw ProSHADE_exception ( "Requested symmetry supplied, but not recognised.", "ES00032", __FILE__, __LINE__, __func__, "There are only the following value allowed for the\n : symmetry type request: \"C\", \"D\", \"T\", \"O\" and \"I\". Any\n : other value will result in this error." );
1869  }
1870 
1871  //================================================ Save C symmetries to argument and if different from settings, to the settings as well
1872  bool isArgSameAsSettings = true;
1873  for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSyms.size() ); cIt++ )
1874  {
1875  std::vector< proshade_double > nextSym;
1876  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[0] );
1877  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[1] );
1878  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[2] );
1879  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[3] );
1880  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[4] );
1881  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms.at(cIt)[5] );
1883 
1884  if ( ( cIt == 0 ) && ( settings->allDetectedCAxes.size() == 0 ) ) { isArgSameAsSettings = false; }
1885  if ( !isArgSameAsSettings ) { ProSHADE_internal_misc::addToDoubleVectorVector ( &settings->allDetectedCAxes, nextSym ); }
1886 
1887  nextSym.clear ( );
1888  }
1889 
1890  //================================================ Release memory
1891  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( CSyms.size() ); it++ ) { delete[] CSyms.at(it); }
1892 
1893  //================================================ Release memory after FSC computation
1894  delete[] mapData;
1895  delete[] origCoeffs;
1896  delete[] fCoeffs;
1897  fftw_destroy_plan ( planForwardFourier );
1898  delete[] binIndexing;
1899  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
1900  delete[] bindata;
1901  delete[] binCounts;
1902 
1903  //================================================ Done
1904  return ;
1905 
1906 }
1907 
1914 bool sortProSHADESymmetryByFSC ( proshade_double* a, proshade_double* b)
1915 {
1916  //================================================ Done
1917  return ( a[6] > b[6] );
1918 
1919 }
1920 
1934 void ProSHADE_internal_data::ProSHADE_data::detectSymmetryFromAngleAxisSpace ( ProSHADE_settings* settings, std::vector< proshade_double* >* axes, std::vector < std::vector< proshade_double > >* allCs )
1935 {
1936  //================================================ Modify axis tolerance and matrix tolerance by sampling, if required by user
1937  if ( settings->axisErrToleranceDefault )
1938  {
1939  settings->axisErrTolerance = std::min ( std::max ( 0.01, ( 2.0 * M_PI ) / static_cast< proshade_double > ( this->maxShellBand ) ), 0.05 );
1940  }
1941 
1942  //================================================ Prepare FSC computation memory and variables
1943  fftw_complex *mapData, *origCoeffs, *fCoeffs;
1944  fftw_plan planForwardFourier;
1945  proshade_double **bindata;
1946  proshade_signed *binIndexing, *binCounts, noBins;
1947  this->prepareFSCFourierMemory ( mapData, origCoeffs, fCoeffs, binIndexing, &noBins, bindata, binCounts, &planForwardFourier );
1948 
1949  //================================================ If C was requested, we will do it immediately - this allows for a significant speed-up.
1950  if ( settings->requestedSymmetryType == "C" )
1951  {
1952  //============================================ Report progress
1953  std::stringstream hlpSS;
1954  hlpSS << "Starting detection of cyclic point group C" << settings->requestedSymmetryFold;
1955  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str() );
1956 
1957  //============================================ Do simplified search only in the applicable data
1958  proshade_double symThres = 0.0;
1959  std::vector< proshade_double* > CSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, settings->requestedSymmetryFold, &symThres );
1960 
1961  //============================================ Deal with the rotation function 0 1 0 PI issue
1962  bool possible010PIIssue = false;
1963  for ( size_t iter = 0; iter < CSyms.size(); iter++ ) { if ( ProSHADE_internal_maths::isAxisUnique ( &CSyms, 0.0, 1.0, 0.0, 2.0, 0.1 ) ) { possible010PIIssue = true; } }
1964  if ( possible010PIIssue )
1965  {
1966  proshade_double* addAxis = new proshade_double[7];
1967  addAxis[0] = 2.0; addAxis[1] = 0.0; addAxis[2] = 1.0; addAxis[3] = 0.0; addAxis[4] = M_PI; addAxis[5] = -999.9; addAxis[6] = -1.0;
1969  delete[] addAxis;
1970  }
1971 
1972  //============================================ Compute FSC for all possible axes
1973  for ( size_t cIt = 0; cIt < CSyms.size(); cIt++ ) { const FloatingPoint< proshade_double > lhs ( CSyms.at(cIt)[5] ), rhs ( -999.9 ); if ( ( CSyms.at(cIt)[5] > settings->peakThresholdMin ) || ( lhs.AlmostEquals ( rhs ) ) ) { this->computeFSC ( settings, &CSyms, cIt, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts ); } }
1974 
1975  //============================================ Sort by FSC
1976  std::sort ( CSyms.begin(), CSyms.end(), sortProSHADESymmetryByFSC );
1977 
1978  //============================================ Save the best axis as the recommended one
1979  if ( settings->detectedSymmetry.size() == 0 ) { if ( CSyms.size() > 0 ) { settings->setDetectedSymmetry ( CSyms.at(0) ); } }
1980  if ( CSyms.size() > 0 )
1981  {
1982  bool passedTests = false;
1983  for ( size_t cIt = 0; cIt < CSyms.size(); cIt++ )
1984  {
1985  if ( CSyms.at(0)[6] > settings->fscThreshold )
1986  {
1987  settings->setRecommendedSymmetry ( "C" );
1988  settings->setRecommendedFold ( settings->requestedSymmetryFold );
1989 
1991  this->saveDetectedSymmetries ( settings, &CSyms, allCs );
1992 
1993  passedTests = true;
1994  break;
1995  }
1996  }
1997 
1998  if ( !passedTests )
1999  {
2000  settings->setRecommendedSymmetry ( "" );
2001  settings->setRecommendedFold ( 0 );
2002  }
2003  }
2004  else
2005  {
2006  settings->setRecommendedSymmetry ( "" );
2007  settings->setRecommendedFold ( 0 );
2008  }
2009 
2010  //============================================ Release memory after FSC computation
2011  delete[] mapData;
2012  delete[] origCoeffs;
2013  delete[] fCoeffs;
2014  fftw_destroy_plan ( planForwardFourier );
2015  delete[] binIndexing;
2016  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2017  delete[] bindata;
2018  delete[] binCounts;
2019 
2020  //============================================ Done
2021  return ;
2022  }
2023 
2024  //================================================ Report progress
2025  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting C symmetry detection." );
2026 
2027  //================================================ Initialise variables
2028  std::vector< proshade_double* > CSyms = getCyclicSymmetriesListFromAngleAxis ( settings );
2029 
2030  //============================================ Deal with the rotation function 0 1 0 PI issue
2031  bool possible010PIIssue = false;
2032  for ( size_t iter = 0; iter < CSyms.size(); iter++ ) { if ( ProSHADE_internal_maths::isAxisUnique ( &CSyms, 0.0, 1.0, 0.0, 2.0, 0.1 ) ) { possible010PIIssue = true; } }
2033  if ( possible010PIIssue )
2034  {
2035  proshade_double* addAxis = new proshade_double[7];
2036  addAxis[0] = 2.0; addAxis[1] = 0.0; addAxis[2] = 1.0; addAxis[3] = 0.0; addAxis[4] = M_PI; addAxis[5] = -999.9; addAxis[6] = -1.0;
2038  delete[] addAxis;
2039  }
2040 
2041  for ( size_t cIt = 0; cIt < CSyms.size(); cIt++ ) { const FloatingPoint< proshade_double > lhs ( CSyms.at(cIt)[5] ), rhs ( -999.9 ); if ( lhs.AlmostEquals ( rhs ) ) { this->computeFSC ( settings, &CSyms, cIt, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts ); } }
2042 
2043  //================================================ Report progress
2044  std::stringstream ss;
2045  ss << "Detected " << CSyms.size() << " C symmetries.";
2046  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str() );
2047 
2048  //================================================ Sanity check - was the rotation function mapped properly?
2049  if ( this->sphereMappedRotFun.size() < 1 )
2050  {
2051  throw ProSHADE_exception ( "Rotation function was not converted into angle-axis space.", "ES00062", __FILE__, __LINE__, __func__, "It seems that the convertRotationFunction() function was\n : not yet called. Therefore, there are no data to detect the\n : symmetry from; please call the convertRotationFunction()\n : function before the detectSymmetryFromAngleAxisSpace()\n : function." );
2052  }
2053 
2054  //================================================ Sanity check - was any symmetry requested?
2055  if ( ( settings->requestedSymmetryType != "" ) && ( settings->requestedSymmetryType != "C" ) && ( settings->requestedSymmetryType != "D" ) && ( settings->requestedSymmetryType != "T" ) && ( settings->requestedSymmetryType != "O" ) && ( settings->requestedSymmetryType != "I" ) )
2056  {
2057  throw ProSHADE_exception ( "Requested symmetry supplied, but not recognised.", "ES00032", __FILE__, __LINE__, __func__, "There are only the following value allowed for the\n : symmetry type request: \"C\", \"D\", \"T\", \"O\" and \"I\". Any\n : other value will result in this error." );
2058  }
2059 
2060  //================================================ Are we doing general search?
2061  if ( settings->requestedSymmetryType == "" )
2062  {
2063  //============================================ Run the symmetry detection functions for C, D, T, O and I symmetries
2064  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
2065  std::vector< proshade_double* > ISyms;
2066  std::vector< proshade_double* > OSyms = this->getPredictedOctahedralSymmetriesList ( settings, &CSyms );
2067  std::vector< proshade_double* > TSyms = this->getPredictedTetrahedralSymmetriesList ( settings, &CSyms );
2068 
2069  //============================================ Find which of the I groups is the correct one
2070  proshade_double fscMax = 0.0;
2071  size_t fscMaxInd = 0;
2072  std::vector < std::vector< proshade_double* > > ISymsHlp = this->getPredictedIcosahedralSymmetriesList ( settings, &CSyms );
2073 
2074  for ( size_t icoIt = 0; icoIt < ISymsHlp.size(); icoIt++ )
2075  {
2076  //======================================== Is this a complete icosahedron?
2077  if ( ISymsHlp.at(icoIt).size() != 31 ) { continue; }
2078 
2079  //======================================== Initialise decision vars
2080  proshade_double fscVal = 0.0;
2081  proshade_double fscValAvg = 0.0;
2082 
2083  //======================================== For each axis
2084  for ( size_t aIt = 0; aIt < ISymsHlp.at(icoIt).size(); aIt++ )
2085  {
2086  //==================================== Match to CSyms
2087  proshade_signed matchedPos = ProSHADE_internal_symmetry::addAxisUnlessSame ( static_cast< proshade_unsign > ( ISymsHlp.at(icoIt).at(aIt)[0] ), ISymsHlp.at(icoIt).at(aIt)[1], ISymsHlp.at(icoIt).at(aIt)[2], ISymsHlp.at(icoIt).at(aIt)[3], ISymsHlp.at(icoIt).at(aIt)[5], ISymsHlp.at(icoIt).at(aIt)[6], &CSyms, settings->axisErrTolerance );
2088 
2089  //==================================== Compute FSC
2090  fscVal = this->computeFSC ( settings, &CSyms, static_cast< size_t > ( matchedPos ), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
2091  ISymsHlp.at(fscMaxInd).at(aIt)[6] = fscVal;
2092  fscValAvg += fscVal;
2093  }
2094 
2095  //==================================== Get FSC average over all axes
2096  fscValAvg /= 31.0;
2097 
2098  //======================================== Is this the best
2099  if ( fscValAvg > fscMax )
2100  {
2101  fscMax = fscValAvg;
2102  fscMaxInd = icoIt;
2103  }
2104  }
2105 
2106  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2107  if ( fscMax >= ( settings->fscThreshold * 0.7 ) )
2108  {
2109  //======================================== Add predicted axes to detected C axes list and also to the settings Icosahedral symmetry list
2110  for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ISymsHlp.at(fscMaxInd).size() ); retIt++ )
2111  {
2112  //==================================== Add the correct index to the settings object
2113  proshade_signed matchedPos = ProSHADE_internal_symmetry::addAxisUnlessSame ( static_cast< proshade_unsign > ( ISymsHlp.at(fscMaxInd).at(retIt)[0] ), ISymsHlp.at(fscMaxInd).at(retIt)[1], ISymsHlp.at(fscMaxInd).at(retIt)[2], ISymsHlp.at(fscMaxInd).at(retIt)[3], ISymsHlp.at(fscMaxInd).at(retIt)[5], ISymsHlp.at(fscMaxInd).at(retIt)[6], &CSyms, settings->axisErrTolerance );
2114  ProSHADE_internal_misc::addToUnsignVector ( &settings->allDetectedIAxes, static_cast < proshade_unsign > ( matchedPos ) );
2115 
2116  //==================================== Set ISyms for saving
2117  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ISyms, ISymsHlp.at(fscMaxInd).at(retIt) );
2118  }
2119  }
2120 
2121  //============================================ Decide on recommended symmetry
2122  this->saveRecommendedSymmetry ( settings, &CSyms, &DSyms, &TSyms, &OSyms, &ISyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
2123  }
2124 
2125  if ( settings->requestedSymmetryType == "D" )
2126  {
2127  //============================================ Run only the D symmetry detection and search for requested fold
2128  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
2129  this->saveRequestedSymmetryD ( settings, &DSyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
2130  }
2131 
2132  if ( settings->requestedSymmetryType == "T" )
2133  {
2134  //============================================ Run only the T symmetry detection
2135  std::vector< proshade_double* > TSyms = this->getPredictedTetrahedralSymmetriesList ( settings, &CSyms );
2136 
2137  if ( TSyms.size() == 7 )
2138  {
2139  //======================================== Initialise decision vars
2140  proshade_double fscVal = 0.0;
2141  proshade_double fscValAvg = 0.0;
2142 
2143  //======================================== Check if axes have high enough FSC and peak height
2144  for ( size_t tIt = 0; tIt < 7; tIt++ ) { if ( CSyms.at(settings->allDetectedTAxes.at(tIt))[5] > settings->peakThresholdMin ) { fscVal = this->computeFSC ( settings, &CSyms, settings->allDetectedTAxes.at(tIt), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts ); fscValAvg += fscVal; } }
2145  fscValAvg /= 7.0;
2146 
2147  //======================================== If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2148  if ( fscValAvg >= ( settings->fscThreshold * 0.8 ) )
2149  {
2150  //==================================== The decision is T
2151  settings->setRecommendedSymmetry ( "T" );
2152  settings->setRecommendedFold ( 0 );
2153  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedTAxes.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSyms.at(settings->allDetectedTAxes.at(it)) ); }
2154  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedTAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSyms.at(settings->allDetectedTAxes.at(it)) ); } }
2155  }
2156  }
2157  }
2158 
2159  if ( settings->requestedSymmetryType == "O" )
2160  {
2161  //============================================ Run only the O symmetry detection
2162  std::vector< proshade_double* > OSyms = this->getPredictedOctahedralSymmetriesList ( settings, &CSyms );
2163 
2164  if ( OSyms.size() == 13 )
2165  {
2166  //======================================== Initialise decision vars
2167  proshade_double fscVal = 0.0;
2168  proshade_double fscValAvg = 0.0;
2169 
2170  //======================================== Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2171  for ( size_t oIt = 0; oIt < 13; oIt++ ) { if ( CSyms.at(settings->allDetectedOAxes.at(oIt))[5] > settings->peakThresholdMin ) { fscVal = this->computeFSC ( settings, &CSyms, settings->allDetectedOAxes.at(oIt), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts ); fscValAvg += fscVal; } }
2172  fscValAvg /= 13.0;
2173 
2174  //======================================== If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2175  if ( fscValAvg >= ( settings->fscThreshold * 0.8 ) )
2176  {
2177  //==================================== The decision is O
2178  settings->setRecommendedSymmetry ( "O" );
2179  settings->setRecommendedFold ( 0 );
2180  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedOAxes.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSyms.at(settings->allDetectedOAxes.at(it)) ); }
2181  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedOAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSyms.at(settings->allDetectedOAxes.at(it)) ); } }
2182  }
2183  }
2184  }
2185 
2186  if ( settings->requestedSymmetryType == "I" )
2187  {
2188  //============================================ Find which of the I groups is the correct one
2189  proshade_double fscMax = 0.0;
2190  size_t fscMaxInd = 0;
2191  std::vector < std::vector< proshade_double* > > ISymsHlp = this->getPredictedIcosahedralSymmetriesList ( settings, &CSyms );
2192  std::vector< proshade_double* > ISyms;
2193 
2194  for ( size_t icoIt = 0; icoIt < ISymsHlp.size(); icoIt++ )
2195  {
2196  //======================================== Is this a complete icosahedron?
2197  if ( ISymsHlp.at(icoIt).size() != 31 ) { continue; }
2198 
2199  //======================================== Initialise decision vars
2200  proshade_double fscVal = 0.0;
2201  proshade_double fscValAvg = 0.0;
2202 
2203  //======================================== For each axis
2204  for ( size_t aIt = 0; aIt < ISymsHlp.at(icoIt).size(); aIt++ )
2205  {
2206  //==================================== Match to CSyms
2207  proshade_signed matchedPos = ProSHADE_internal_symmetry::addAxisUnlessSame ( static_cast< proshade_unsign > ( ISymsHlp.at(icoIt).at(aIt)[0] ), ISymsHlp.at(icoIt).at(aIt)[1], ISymsHlp.at(icoIt).at(aIt)[2], ISymsHlp.at(icoIt).at(aIt)[3], ISymsHlp.at(icoIt).at(aIt)[5], ISymsHlp.at(icoIt).at(aIt)[6], &CSyms, settings->axisErrTolerance );
2208 
2209  //==================================== Compute FSC
2210  fscVal = this->computeFSC ( settings, &CSyms, static_cast< size_t > ( matchedPos ), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts );
2211  ISymsHlp.at(fscMaxInd).at(aIt)[6] = fscVal;
2212  fscValAvg += fscVal;
2213  }
2214 
2215  //==================================== Get FSC average over all axes
2216  fscValAvg /= 31.0;
2217 
2218  //======================================== Is this the best
2219  if ( fscValAvg > fscMax )
2220  {
2221  fscMax = fscValAvg;
2222  fscMaxInd = icoIt;
2223  }
2224  }
2225 
2226  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2227  if ( fscMax >= ( settings->fscThreshold * 0.7 ) )
2228  {
2229  //======================================== Add predicted axes to detected C axes list and also to the settings Icosahedral symmetry list
2230  for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ISymsHlp.at(fscMaxInd).size() ); retIt++ )
2231  {
2232  //==================================== Add the correct index to the settings object
2233  proshade_signed matchedPos = ProSHADE_internal_symmetry::addAxisUnlessSame ( static_cast< proshade_unsign > ( ISymsHlp.at(fscMaxInd).at(retIt)[0] ), ISymsHlp.at(fscMaxInd).at(retIt)[1], ISymsHlp.at(fscMaxInd).at(retIt)[2], ISymsHlp.at(fscMaxInd).at(retIt)[3], ISymsHlp.at(fscMaxInd).at(retIt)[5], ISymsHlp.at(fscMaxInd).at(retIt)[6], &CSyms, settings->axisErrTolerance );
2234  ProSHADE_internal_misc::addToUnsignVector ( &settings->allDetectedIAxes, static_cast < proshade_unsign > ( matchedPos ) );
2235 
2236  //==================================== Set ISyms for saving
2237  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ISyms, ISymsHlp.at(fscMaxInd).at(retIt) );
2238  }
2239  }
2240 
2241  //============================================ Delete all memory from ISymsHlp
2242  for ( size_t gIt = 0; gIt < ISymsHlp.size(); gIt++ ) { for ( size_t aIt = 0; aIt < ISymsHlp.at(gIt).size(); aIt++ ) { delete[] ISymsHlp.at(gIt).at(aIt); } }
2243 
2244  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2245  if ( fscMax >= ( settings->fscThreshold * 0.7 ) )
2246  {
2247  //======================================== The decision is I
2248  settings->setRecommendedSymmetry ( "I" );
2249  settings->setRecommendedFold ( 0 );
2250  for ( size_t it = 0; it < ISyms.size(); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, ISyms.at(it) ); }
2251  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedIAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSyms.at(settings->allDetectedIAxes.at(it)) ); } }
2252  }
2253  }
2254 
2255  //================================================ Save C symmetries to argument and if different from settings, to the settings as well
2256  this->saveDetectedSymmetries ( settings, &CSyms, allCs );
2257 
2258  //================================================ Release memory after FSC computation
2259  delete[] mapData;
2260  delete[] origCoeffs;
2261  delete[] fCoeffs;
2262  fftw_destroy_plan ( planForwardFourier );
2263  delete[] binIndexing;
2264  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2265  delete[] bindata;
2266  delete[] binCounts;
2267 
2268  //================================================ Done
2269  return ;
2270 
2271 }
2272 
2286 void ProSHADE_internal_data::ProSHADE_data::saveDetectedSymmetries ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSyms, std::vector < std::vector< proshade_double > >* allCs )
2287 {
2288  //================================================ Initialise variables
2289  bool isArgSameAsSettings = true;
2290 
2291  //================================================ For each detected point group
2292  for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSyms->size() ); cIt++ )
2293  {
2294  //============================================ Create vector to replace the pointer
2295  std::vector< proshade_double > nextSym;
2296  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[0] );
2297  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[1] );
2298  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[2] );
2299  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[3] );
2300  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[4] );
2301  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[5] );
2302  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[6] );
2304 
2305  //============================================ Copy the vector to output variable and if different, then also to settings object
2306  if ( ( cIt == 0 ) && ( settings->allDetectedCAxes.size() == 0 ) ) { isArgSameAsSettings = false; }
2307  if ( !isArgSameAsSettings ) { ProSHADE_internal_misc::addToDoubleVectorVector ( &settings->allDetectedCAxes, nextSym ); }
2308 
2309  //============================================ Release memory
2310  nextSym.clear ( );
2311  delete[] CSyms->at(cIt);
2312  }
2313 
2314  //================================================ Done
2315  return ;
2316 
2317 }
2318 
2332 proshade_double ProSHADE_internal_data::ProSHADE_data::findTopGroupSmooth ( std::vector< proshade_double* >* CSym, size_t peakPos, proshade_double step, proshade_double sigma, proshade_signed windowSize )
2333 {
2334  //================================================ Initialise local variables
2335  proshade_double threshold = 0.0;
2336  proshade_signed totSize = static_cast< proshade_signed > ( ( 1.0 / step ) + 1 );
2337  std::vector< std::pair < proshade_double, proshade_unsign > > vals;
2338  std::vector< proshade_double > hist ( static_cast< unsigned long int > ( totSize ), 0.0 );
2339  proshade_unsign histPos = 0;
2340 
2341  //================================================ Make sure window size is odd
2342  if ( windowSize % 2 == 0 ) { windowSize += 1; }
2343 
2344  //================================================ Get vector of pairs of peak heights and indices in CSym array
2345  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( CSym->size() ); symIt++ ) { vals.emplace_back ( std::pair < proshade_double, proshade_unsign > ( CSym->at(symIt)[peakPos], symIt ) ); }
2346 
2347  //================================================ Convert all found heights to histogram from 0.0 to 1.0 by step
2348  for ( proshade_double it = 0.0; it <= 1.0; it = it + step )
2349  {
2350  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( vals.size() ); symIt++ )
2351  {
2352  //======================================== Is this height in the range?
2353  if ( ( vals.at(symIt).first > it ) && ( vals.at(symIt).first <= ( it + step ) ) ) { hist.at(histPos) += 1.0; }
2354  }
2355 
2356  //============================================ Update counter and continue
2357  histPos += 1;
2358  }
2359 
2360  //================================================ Smoothen the distribution
2361  std::vector< proshade_double > smoothened = ProSHADE_internal_maths::smoothen1D ( step, windowSize, sigma, hist );
2362 
2363  //================================================ Find peaks in smoothened data
2364  std::vector< proshade_signed > peaks = ProSHADE_internal_peakSearch::findPeaks1D ( smoothened );
2365 
2366  //================================================ Take best peaks surroundings and produce a new set of "high" axes
2367  proshade_signed bestHistPos;
2368  if ( peaks.size() > 0 ) { bestHistPos = peaks.at(peaks.size()-1) + ( ( windowSize - 1 ) / 2 ); }
2369  else { bestHistPos = 0.0; }
2370 
2371  threshold = ( static_cast< proshade_double > ( bestHistPos ) * step ) - ( static_cast< proshade_double > ( windowSize ) * step );
2372 
2373  //================================================ Done
2374  return ( threshold );
2375 
2376 }
2377 
2388 void ProSHADE_internal_data::ProSHADE_data::prepareFSCFourierMemory ( fftw_complex*& mapData, fftw_complex*& origCoeffs, fftw_complex*& fCoeffs, proshade_signed*& binIndexing, proshade_signed* noBins, proshade_double**& bindata, proshade_signed*& binCounts, fftw_plan* planForwardFourier )
2389 {
2390  //================================================ Decide number of bins and allocate which reflection belongs to which bin
2391  ProSHADE_internal_maths::binReciprocalSpaceReflections ( this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing );
2392 
2393  //================================================ Allocate memory for FSC sums
2394  bindata = new proshade_double*[*noBins];
2395  binCounts = new proshade_signed [*noBins];
2396 
2397  //================================================ Allcate memory for bin sumation
2398  for ( size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ )
2399  {
2400  bindata[binIt] = new proshade_double[12];
2401  ProSHADE_internal_misc::checkMemoryAllocation ( bindata[binIt], __FILE__, __LINE__, __func__ );
2402  }
2403 
2404  //================================================ Allocate memory for Fourier transform imputs and outputs
2405  mapData = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2406  origCoeffs = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2407  fCoeffs = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2408 
2409  //================================================ Check memory allocation
2410  ProSHADE_internal_misc::checkMemoryAllocation ( mapData, __FILE__, __LINE__, __func__ );
2411  ProSHADE_internal_misc::checkMemoryAllocation ( origCoeffs, __FILE__, __LINE__, __func__ );
2412  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffs, __FILE__, __LINE__, __func__ );
2413  ProSHADE_internal_misc::checkMemoryAllocation ( bindata, __FILE__, __LINE__, __func__ );
2414  ProSHADE_internal_misc::checkMemoryAllocation ( binCounts, __FILE__, __LINE__, __func__ );
2415 
2416  //================================================ Prepare memory for Fourier transform
2417  *planForwardFourier = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ), mapData, fCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
2418 
2419  //================================================ Compute Fourier transform of the original map
2420  for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { mapData[iter][0] = this->internalMap[iter]; mapData[iter][1] = 0.0; }
2421  fftw_execute ( *planForwardFourier );
2422  for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { origCoeffs[iter][0] = fCoeffs[iter][0]; origCoeffs[iter][1] = fCoeffs[iter][1]; }
2423 
2424  //================================================ Done
2425  return ;
2426 
2427 }
2428 
2456 proshade_double ProSHADE_internal_data::ProSHADE_data::computeFSC ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSym, size_t symIndex, fftw_complex* mapData, fftw_complex* fCoeffs, fftw_complex* origCoeffs, fftw_plan* planForwardFourier, proshade_signed noBins, proshade_signed *binIndexing, proshade_double**& bindata, proshade_signed*& binCounts )
2457 {
2458  //================================================ Sanity check
2459  if ( symIndex >= CSym->size() )
2460  {
2461  std::cerr << "The supplied symmetry axes vector does not contain element number " << symIndex << ". Returning FSC 0.0." << std::endl;
2462  return ( -2.0 );
2463  }
2464 
2465  //================================================ Ignore if already computed
2466  const FloatingPoint< proshade_double > lhs1 ( CSym->at(symIndex)[6] ), rhs1 ( -1.0 );
2467  if ( !lhs1.AlmostEquals ( rhs1 ) ) { return ( CSym->at(symIndex)[6] ); }
2468 
2469  //================================================ Report progress
2470  std::stringstream ss2;
2471  ss2 << "Computing FSC for symmetry C" << CSym->at(symIndex)[0] << " ( " << CSym->at(symIndex)[1] << " ; " << CSym->at(symIndex)[2] << " ; " << CSym->at(symIndex)[3] << " ) with peak height " << CSym->at(symIndex)[5];
2472  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str() );
2473 
2474  //================================================ Initialise local variables
2475  proshade_double *rotMap;
2476 
2477  //================================================ For each rotation along the axis
2478  proshade_double averageFSC = 0.0;
2479  for ( proshade_double rotIter = 1.0; rotIter < CSym->at(symIndex)[0]; rotIter += 1.0 )
2480  {
2481  //============================================ Get rotated map by the smallest fold angle along the symmetry axis
2482  this->rotateMapRealSpace ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) * rotIter, rotMap );
2483 
2484  //============================================ Get Fourier for the rotated map
2485  for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { mapData[iter][0] = rotMap[iter]; mapData[iter][1] = 0.0; }
2486  fftw_execute ( *planForwardFourier );
2487 
2488  //============================================ Clean FSC computation memory
2489  for ( size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { for ( size_t valIt = 0; valIt < 12; valIt++ ) { bindata[binIt][valIt] = 0.0; } }
2490  for ( size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { binCounts[binIt] = 0; }
2491 
2492  //============================================ Compute FSC
2493  averageFSC += ProSHADE_internal_maths::computeFSC ( origCoeffs, fCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing, bindata, binCounts );
2494 
2495  //============================================ Release memory
2496  delete[] rotMap;
2497  }
2498 
2499  //================================================ Convert sum to average
2500  averageFSC /= ( CSym->at(symIndex)[0] - 1.0 );
2501 
2502  //================================================ Save result to the axis
2503  CSym->at(symIndex)[6] = averageFSC;
2504 
2505  //================================================ Report progress
2506  std::stringstream ss3;
2507  ss3 << "FSC value is " << averageFSC << " .";
2508  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str() );
2509 
2510  //================================================ Done
2511  return ( averageFSC );
2512 
2513 }
2514 
2541 proshade_double ProSHADE_internal_data::ProSHADE_data::computeFSC ( ProSHADE_settings* settings, proshade_double* sym, fftw_complex* mapData, fftw_complex* fCoeffs, fftw_complex* origCoeffs, fftw_plan* planForwardFourier, proshade_signed noBins, proshade_signed *binIndexing, proshade_double**& bindata, proshade_signed*& binCounts )
2542 {
2543  //================================================ Ignore if already computed
2544  const FloatingPoint< proshade_double > lhs1 ( sym[6] ), rhs1 ( -1.0 );
2545  if ( !lhs1.AlmostEquals ( rhs1 ) ) { return ( sym[6] ); }
2546 
2547  //================================================ Report progress
2548  std::stringstream ss2;
2549  ss2 << "Computing FSC for symmetry C" << sym[0] << " ( " << sym[1] << " ; " << sym[2] << " ; " << sym[3] << " ) with peak height " << sym[5];
2550  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str() );
2551 
2552  //================================================ Initialise local variables
2553  proshade_double *rotMap;
2554 
2555  //================================================ For each rotation along the axis
2556  proshade_double averageFSC = 0.0;
2557  for ( proshade_double rotIter = 1.0; rotIter < sym[0]; rotIter += 1.0 )
2558  {
2559  //============================================ Get rotated map by the smallest fold angle along the symmetry axis
2560  this->rotateMapRealSpace ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) * rotIter, rotMap );
2561 
2562  //============================================ Get Fourier for the rotated map
2563  for ( size_t iter = 0; iter < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ ) { mapData[iter][0] = rotMap[iter]; mapData[iter][1] = 0.0; }
2564  fftw_execute ( *planForwardFourier );
2565 
2566  //============================================ Clean FSC computation memory
2567  for ( size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { for ( size_t valIt = 0; valIt < 12; valIt++ ) { bindata[binIt][valIt] = 0.0; } }
2568  for ( size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { binCounts[binIt] = 0; }
2569 
2570  //============================================ Compute FSC
2571  averageFSC += ProSHADE_internal_maths::computeFSC ( origCoeffs, fCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing, bindata, binCounts );
2572 
2573  //============================================ Release memory
2574  delete[] rotMap;
2575  }
2576 
2577  //================================================ Convert sum to average
2578  averageFSC /= ( sym[0] - 1.0 );
2579 
2580  //================================================ Save result to the axis
2581  sym[6] = averageFSC;
2582 
2583  //================================================ Report progress
2584  std::stringstream ss3;
2585  ss3 << "FSC value is " << averageFSC << " .";
2586  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str() );
2587 
2588  //================================================ Done
2589  return ( averageFSC );
2590 
2591 }
2592 
2627 void ProSHADE_internal_data::ProSHADE_data::saveRecommendedSymmetry ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSym, std::vector< proshade_double* >* DSym, std::vector< proshade_double* >* TSym, std::vector< proshade_double* >* OSym, std::vector< proshade_double* >* ISym, std::vector< proshade_double* >* axes, fftw_complex* mapData, fftw_complex* origCoeffs, fftw_complex* fCoeffs, fftw_plan* planForwardFourier, proshade_signed noBins, proshade_signed* binIndexing, proshade_double** bindata, proshade_signed* binCounts )
2628 {
2629  //================================================ Report progress
2630  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting recommended symmetry decision procedure." );
2631 
2632  //================================================ If no C symmetries, nothing to save...
2633  if ( CSym->size() == 0 )
2634  {
2635  settings->setRecommendedSymmetry ( "" );
2636  settings->setRecommendedFold ( 0 );
2637  return;
2638  }
2639 
2640  //================================================ Find the top group minimum threshold using smoothened histogram
2641  proshade_double step = 0.01;
2642  proshade_double sigma = 0.03;
2643  proshade_signed windowSize = 9;
2644  proshade_double bestHistPeakStart = this->findTopGroupSmooth ( CSym, 5, step, sigma, windowSize );
2645  if ( bestHistPeakStart > settings->peakThresholdMin ) { bestHistPeakStart = settings->peakThresholdMin; }
2646 
2647  //================================================ Report progress
2648  proshade_unsign noPassed = 0; for ( size_t cIt = 0; cIt < CSym->size(); cIt++ ) { if ( CSym->at(cIt)[5] > bestHistPeakStart ) { noPassed += 1; } }
2649  std::stringstream ss;
2650  ss << "Smoothening has resolved in " << noPassed << " C symmetries.";
2651  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str() );
2652  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Starting FSC computation to confirm the C symmetries existence." );
2653 
2654  //================================================ Decide if I is the answer
2655  bool alreadyDecided = false;
2656  if ( ISym->size() == 31 )
2657  {
2658  //============================================ Initialise decision vars
2659  proshade_double fscVal = 0.0;
2660  proshade_double fscValAvg = 0.0;
2661 
2662  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2663  for ( size_t iIt = 0; iIt < 31; iIt++ ) { if ( CSym->at(settings->allDetectedIAxes.at(iIt))[5] > bestHistPeakStart ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedIAxes.at(iIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts ); fscValAvg += fscVal; } }
2664  fscValAvg /= 31.0;
2665 
2666  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2667  if ( fscValAvg >= ( settings->fscThreshold * 0.85 ) )
2668  {
2669  //======================================== The decision is I
2670  settings->setRecommendedSymmetry ( "I" );
2671  settings->setRecommendedFold ( 0 );
2672  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedIAxes.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedIAxes.at(it)) ); }
2673  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedIAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSym->at(settings->allDetectedIAxes.at(it)) ); } }
2674 
2675  //======================================== Done
2676  alreadyDecided = true;
2677  }
2678  }
2679 
2680  //================================================ Decide if O is the answer
2681  if ( ( OSym->size() == 13 ) && !alreadyDecided )
2682  {
2683  //============================================ Initialise decision vars
2684  proshade_double fscVal = 0.0;
2685  proshade_double fscValAvg = 0.0;
2686 
2687  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2688  for ( size_t oIt = 0; oIt < 13; oIt++ ) { if ( CSym->at(settings->allDetectedOAxes.at(oIt))[5] > bestHistPeakStart ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedOAxes.at(oIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts ); fscValAvg += fscVal; } }
2689  fscValAvg /= 13.0;
2690 
2691  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2692  if ( fscValAvg >= ( settings->fscThreshold * 0.85 ) )
2693  {
2694  //======================================== The decision is O
2695  settings->setRecommendedSymmetry ( "O" );
2696  settings->setRecommendedFold ( 0 );
2697  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedOAxes.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedOAxes.at(it)) ); }
2698  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedOAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSym->at(settings->allDetectedOAxes.at(it)) ); } }
2699 
2700  //======================================== Done
2701  alreadyDecided = true;
2702  }
2703  }
2704 
2705  //================================================ Decide if T is the answer
2706  if ( ( TSym->size() == 7 ) && !alreadyDecided )
2707  {
2708  //============================================ Initialise decision vars
2709  proshade_double fscVal = 0.0;
2710  proshade_double fscValAvg = 0.0;
2711 
2712  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2713  for ( size_t tIt = 0; tIt < 7; tIt++ ) { if ( CSym->at(settings->allDetectedTAxes.at(tIt))[5] > bestHistPeakStart ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedTAxes.at(tIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts ); fscValAvg += fscVal; } }
2714  fscValAvg /= 7.0;
2715 
2716  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2717  if ( fscValAvg >= ( settings->fscThreshold * 0.85 ) )
2718  {
2719  //======================================== The decision is T
2720  settings->setRecommendedSymmetry ( "T" );
2721  settings->setRecommendedFold ( 0 );
2722  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedTAxes.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedTAxes.at(it)) ); }
2723  if ( settings->detectedSymmetry.size() == 0 ) { for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( settings->allDetectedTAxes.size() ); it++ ) { settings->setDetectedSymmetry ( CSym->at(settings->allDetectedTAxes.at(it)) ); } }
2724 
2725  //======================================== Done
2726  alreadyDecided = true;
2727  }
2728  }
2729 
2730  //================================================ Decide if D is the answer
2731  if ( ( settings->allDetectedDAxes.size() > 0 ) && ( DSym->size() > 0 ) && !alreadyDecided )
2732  {
2733  //============================================ Initialise decision vars
2734  proshade_signed bestD = -1;
2735  proshade_unsign bestFold = 0;
2736 
2737  //============================================ Find FSCs
2738  for ( size_t dIt = 0; dIt < settings->allDetectedDAxes.size(); dIt++ )
2739  {
2740  //======================================== Do not consider more than top 20, takes time and is unlikely to produce anything...
2741  if ( dIt > 20 ) { continue; }
2742 
2743  //======================================== Check the peak heights
2744  const FloatingPoint< proshade_double > lhs999a ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] ), lhs999b ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2745  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] < bestHistPeakStart ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2746  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] < bestHistPeakStart ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2747 
2748  //======================================== Find FSCs
2749  this->computeFSC ( settings, CSym, settings->allDetectedDAxes.at(dIt).at(0), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts );
2750  this->computeFSC ( settings, CSym, settings->allDetectedDAxes.at(dIt).at(1), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts );
2751  }
2752 
2753  //============================================ Find FSC top group threshold
2754  proshade_double bestHistFSCStart = this->findTopGroupSmooth ( CSym, 6, step, sigma, windowSize );
2755 
2756  //============================================ Check if both C symmetries are reliable
2757  for ( size_t dIt = 0; dIt < settings->allDetectedDAxes.size(); dIt++ )
2758  {
2759  //======================================== Check the peak heights
2760  const FloatingPoint< proshade_double > lhs999a2 ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] ), lhs999b2 ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2761  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] < bestHistPeakStart ) && !( lhs999a2.AlmostEquals( rhs999 ) ) ) { continue; }
2762  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] < bestHistPeakStart ) && !( lhs999b2.AlmostEquals( rhs999 ) ) ) { continue; }
2763 
2764  //======================================== Does this improve the best fold?
2765  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[0] > static_cast< proshade_double > ( bestFold ) ) || ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[0] > static_cast< proshade_double > ( bestFold ) ) )
2766  {
2767  //==================================== Check the FSC vals
2768  if ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[6] < settings->fscThreshold ) { continue; }
2769  if ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[6] < settings->fscThreshold ) { continue; }
2770  if ( std::max ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[6], CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[6] ) < bestHistFSCStart ) { continue; }
2771 
2772  //==================================== All good!
2773  bestFold = static_cast< proshade_unsign > ( std::max ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[0], CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[0] ) );
2774  bestD = static_cast< proshade_signed > ( dIt );
2775  }
2776  }
2777 
2778  //============================================ Anything?
2779  if ( bestD != -1 )
2780  {
2781  //======================================== The decision is D
2782  settings->setRecommendedSymmetry ( "D" );
2783  settings->setRecommendedFold ( static_cast< proshade_unsign > ( std::max ( CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(0))[0], CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(1))[0] ) ) );
2784  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(0)) );
2785  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(1)) );
2786  if ( settings->detectedSymmetry.size() == 0 )
2787  {
2788  settings->setDetectedSymmetry ( CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(0)) );
2789  settings->setDetectedSymmetry ( CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(1)) );
2790  }
2791 
2792  //======================================== Done
2793  alreadyDecided = true;
2794  }
2795  }
2796 
2797  //================================================ Decide if C is the answer
2798  if ( ( CSym->size() > 0 ) && !alreadyDecided )
2799  {
2800  //============================================ Initialise decision vars
2801  proshade_signed bestC = -1;
2802  proshade_unsign bestFold = 0;
2803 
2804  //============================================ Find FSCs for C syms
2805  for ( size_t cIt = 0; cIt < CSym->size(); cIt++ )
2806  {
2807  //======================================== Do not consider more than top 20, takes time and is unlikely to produce anything...
2808  if ( cIt > 20 ) { continue; }
2809 
2810  //======================================== Check the peak height
2811  if ( CSym->at(cIt)[5] < bestHistPeakStart ) { continue; }
2812 
2813  //======================================== Compute FSC
2814  this->computeFSC ( settings, CSym, cIt, mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts );
2815  }
2816 
2817  //============================================ Find FSC top group threshold
2818  proshade_double bestHistFSCStart = this->findTopGroupSmooth ( CSym, 6, step, sigma, windowSize );
2819 
2820  //============================================ Find reliable C syms
2821  for ( size_t cIt = 0; cIt < CSym->size(); cIt++ )
2822  {
2823  //======================================== Check if this improves the best already found fold
2824  if ( CSym->at(cIt)[0] > static_cast< proshade_double > ( bestFold ) )
2825  {
2826  //==================================== If FSC passes
2827  if ( ( CSym->at(cIt)[6] > settings->fscThreshold ) && ( CSym->at(cIt)[6] >= bestHistFSCStart ) )
2828  {
2829  bestFold = static_cast< proshade_unsign > ( CSym->at(cIt)[0] );
2830  bestC = static_cast< proshade_signed > ( cIt );
2831  }
2832  }
2833  }
2834 
2835  //============================================ Anything?
2836  if ( bestC != -1 )
2837  {
2838  //======================================== The decision is C
2839  settings->setRecommendedSymmetry ( "C" );
2840  settings->setRecommendedFold ( static_cast< proshade_unsign > ( CSym->at( static_cast< size_t > ( bestC ) )[0] ) );
2841  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at( static_cast< size_t > ( bestC ) ) );
2842  if ( settings->detectedSymmetry.size() == 0 ) { settings->setDetectedSymmetry ( CSym->at( static_cast< size_t > ( bestC ) ) ); }
2843 
2844  //======================================== Done
2845  alreadyDecided = true;
2846  }
2847  }
2848 
2849  //================================================ Done
2850  return ;
2851 
2852 }
2853 
2865 void ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryC ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSym, std::vector< proshade_double* >* axes )
2866 {
2867  //================================================ Initialise variables
2868  proshade_unsign bestIndex = 0;
2869  proshade_double highestSym = 0.0;
2870 
2871  //================================================ Search for best fold
2872  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( CSym->size() ); iter++ )
2873  {
2874  //============================================ Check if it is tbe correct fold
2875  const FloatingPoint< proshade_double > lhs1 ( CSym->at(iter)[0] ), rhs1 ( static_cast< proshade_double > ( settings->requestedSymmetryFold ) );
2876  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2877 
2878  //============================================ If correct, is it the highest found?
2879  if ( CSym->at(iter)[5] > highestSym )
2880  {
2881  highestSym = CSym->at(iter)[5];
2882  bestIndex = iter;
2883  }
2884  }
2885 
2886  //================================================ Found?
2887  if ( highestSym > 0.0 )
2888  {
2889  settings->setRecommendedSymmetry ( "C" );
2890  settings->setRecommendedFold ( static_cast< proshade_unsign > ( CSym->at(bestIndex)[0] ) );
2891  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(bestIndex) );
2892 
2893  if ( settings->detectedSymmetry.size() == 0 ) { settings->setDetectedSymmetry ( CSym->at(bestIndex) ); }
2894  }
2895  else
2896  {
2897  settings->setRecommendedSymmetry ( "" );
2898  settings->setRecommendedFold ( 0 );
2899  }
2900 
2901  //================================================ Done
2902  return ;
2903 
2904 }
2905 
2917 void ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryD ( ProSHADE_settings* settings, std::vector< proshade_double* >* DSym, std::vector< proshade_double* >* axes, fftw_complex* mapData, fftw_complex* origCoeffs, fftw_complex* fCoeffs, fftw_plan* planForwardFourier, proshade_signed noBins, proshade_signed* binIndexing, proshade_double** bindata, proshade_signed* binCounts )
2918 {
2919  //================================================ Initialise variables
2920  proshade_unsign bestIndex = 0;
2921  proshade_double highestSym = 0.0;
2922 
2923  //================================================ Search for best fold
2924  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( DSym->size() ); iter++ )
2925  {
2926  //============================================ Check if it is tbe correct fold
2927  const FloatingPoint< proshade_double > lhs1 ( std::max ( DSym->at(iter)[0], DSym->at(iter)[7] ) ), rhs1 ( static_cast< proshade_double > ( settings->requestedSymmetryFold ) );
2928  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2929 
2930  //============================================ Check if peak height is decent
2931  const FloatingPoint< proshade_double > lhs999a ( DSym->at(iter)[5] ), lhs999b ( DSym->at(iter)[12] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2932  if ( ( DSym->at(iter)[5] < settings->peakThresholdMin ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2933  if ( ( DSym->at(iter)[12] < settings->peakThresholdMin ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2934 
2935  //============================================ If correct, compute FSC
2936  this->computeFSC ( settings, &DSym->at(iter)[0], mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts );
2937  this->computeFSC ( settings, &DSym->at(iter)[7], mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts );
2938 
2939  //============================================ If best, store it
2940  if ( ( DSym->at(iter)[6] + DSym->at(iter)[13] ) > highestSym )
2941  {
2942  highestSym = ( DSym->at(iter)[6] + DSym->at(iter)[13] );
2943  bestIndex = iter;
2944  }
2945  }
2946 
2947  //================================================ Found?
2948  if ( highestSym > 0.0 )
2949  {
2950  settings->setRecommendedSymmetry ( "D" );
2951  settings->setRecommendedFold ( static_cast< proshade_unsign > ( std::max ( DSym->at(bestIndex)[0], DSym->at(bestIndex)[7] ) ) );
2952  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, &DSym->at(bestIndex)[0] );
2953  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, &DSym->at(bestIndex)[7] );
2954 
2955  if ( settings->detectedSymmetry.size() == 0 )
2956  {
2957  settings->setDetectedSymmetry ( &DSym->at(bestIndex)[0] );
2958  settings->setDetectedSymmetry ( &DSym->at(bestIndex)[7] );
2959  }
2960  }
2961  else
2962  {
2963  settings->setRecommendedSymmetry ( "" );
2964  settings->setRecommendedFold ( 0 );
2965  }
2966 
2967  //================================================ Done
2968  return ;
2969 
2970 }
2971 
2980 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::computeGroupElementsForGroup ( proshade_double xAx, proshade_double yAx, proshade_double zAx, proshade_signed fold )
2981 {
2982  //================================================ Initialise variables
2983  std::vector< proshade_double > angList;
2984  std::vector<std::vector< proshade_double > > ret;
2985 
2986  //================================================ Allocate memory
2987  proshade_double* rotMat = new proshade_double[9];
2988  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
2989 
2990 
2991  //================================================ Normalise the axis to have magnitude of 1.0
2992  proshade_double normF = std::sqrt( std::pow ( xAx, 2.0 ) + std::pow ( yAx, 2.0 ) + std::pow ( zAx, 2.0 ) );
2993  xAx /= normF;
2994  yAx /= normF;
2995  zAx /= normF;
2996 
2997  //================================================ Determine the list of angles
2998  if ( fold % 2 == 0 )
2999  {
3000  //============================================ If fold is even, add the negative angles
3001  for ( proshade_double iter = static_cast < proshade_double > ( -( ( fold / 2 ) - 1 ) ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
3002  {
3003  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
3004  }
3005  }
3006  else
3007  {
3008  //============================================ If fold is odd, do the same as for even, but start one index earlier
3009  for ( proshade_double iter = static_cast < proshade_double > ( -fold / 2 ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
3010  {
3011  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
3012  }
3013  }
3014 
3015  //================================================ For each detected angle
3016  for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( angList.size() ); iter++ )
3017  {
3018  //============================================ Compute the rotation matrix
3019  ProSHADE_internal_maths::getRotationMatrixFromAngleAxis ( rotMat, xAx, yAx, zAx, angList.at(iter) );
3020 
3021  //============================================ Convert to vector of vectors of doubles and save to ret
3022  std::vector < proshade_double > retEl;
3023  for ( proshade_unsign matIt = 0; matIt < 9; matIt++ )
3024  {
3025  ProSHADE_internal_misc::addToDoubleVector ( &retEl, rotMat[matIt] );
3026  }
3028  }
3029 
3030  //================================================ Release memory
3031  delete[] rotMat;
3032 
3033  //================================================ Done
3034  return ( ret );
3035 
3036 }
3037 
3044 void axesToGroupTypeSanityCheck ( proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType )
3045 {
3046  //================================================ Sanity check
3047  if ( obtainedAxes != requiredAxes )
3048  {
3049  std::stringstream hlpSS;
3050  hlpSS << "The supplied number of axes for group element\n : detection ( >" << obtainedAxes << "< ) does not match the group type ( >" << groupType << "< ).";
3051  throw ProSHADE_exception ( "Mismatch between supplied number of axes and\n : symmetry type.", "ES00059", __FILE__, __LINE__, __func__, hlpSS.str() );
3052  }
3053 
3054  //================================================ Done
3055  return ;
3056 
3057 }
3058 
3066 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance )
3067 {
3068  //================================================ Initialise variables
3069  bool elementFound = false;
3070 
3071  //================================================ For each existing element
3072  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( elements->size() ); elIt++ )
3073  {
3074  if ( ProSHADE_internal_maths::rotationMatrixSimilarity ( &elements->at(elIt), elem, matrixTolerance ) )
3075  {
3076  elementFound = true;
3077  break;
3078  }
3079  }
3080 
3081  //================================================ Done
3082  return ( elementFound );
3083 
3084 }
3085 
3092 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance )
3093 {
3094  //================================================ Initialise variables
3095  bool isGroup = true;
3096 
3097  //================================================ Multiply all group element pairs
3098  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( elements->size() ); gr1++ )
3099  {
3100  for ( proshade_unsign gr2 = 1; gr2 < static_cast<proshade_unsign> ( elements->size() ); gr2++ )
3101  {
3102  //======================================== Use unique pairs only
3103  if ( gr1 >= gr2 ) { continue; }
3104 
3105  //======================================== Multiply the two rotation matrices
3106  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &elements->at(gr1), &elements->at(gr2) );
3107 
3108  //======================================== Check the group already contains the produces as an element
3109  if ( !checkElementAlreadyExists ( elements, &product, matrixTolerance ) )
3110  {
3111  isGroup = false;
3112  break;
3113  }
3114  }
3115 
3116  //============================================ Stop if problem was found
3117  if ( !isGroup ) { break; }
3118  }
3119 
3120  //================================================ Done
3121  return ( isGroup );
3122 
3123 }
3124 
3133 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::joinElementsFromDifferentGroups ( std::vector<std::vector< proshade_double > >* first, std::vector<std::vector< proshade_double > >* second, proshade_double matrixTolerance, bool combine )
3134 {
3135  //================================================ Initialise variables
3136  std::vector< std::vector< proshade_double > > ret;
3137 
3138  //================================================ Add the first list to ret, checking for uniqueness
3139  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( first->size() ); elIt++ )
3140  {
3141  if ( !checkElementAlreadyExists( &ret, &first->at(elIt), matrixTolerance ) )
3142  {
3143  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, first->at(elIt) );
3144  }
3145  }
3146 
3147  //================================================ Add the second list to ret, checking for uniqueness
3148  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( second->size() ); elIt++ )
3149  {
3150  if ( !checkElementAlreadyExists( &ret, &second->at(elIt), matrixTolerance ) )
3151  {
3152  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, second->at(elIt) );
3153  }
3154  }
3155 
3156  //================================================ Multiply all combinations of first and second and check for uniqueness
3157  if ( combine )
3158  {
3159  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( first->size() ); gr1++ )
3160  {
3161  for ( proshade_unsign gr2 = 0; gr2 < static_cast<proshade_unsign> ( second->size() ); gr2++ )
3162  {
3163  //==================================== Multiply the two rotation matrices
3164  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &first->at(gr1), &second->at(gr2) );
3165 
3166  //==================================== Add
3167  if ( !checkElementAlreadyExists( &ret, &product, matrixTolerance ) )
3168  {
3170  }
3171 
3172  }
3173  }
3174  }
3175 
3176  //================================================ Done
3177  return ( ret );
3178 
3179 }
3180 
3199 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::ProSHADE_data::getAllGroupElements ( ProSHADE_settings* settings, std::vector< proshade_unsign > axesList, std::string groupType, proshade_double matrixTolerance )
3200 {
3201  //================================================ Initialise variables
3202  std::vector<std::vector< proshade_double > > ret;
3203 
3204  //================================================ Select which symmetry type are we computing for
3205  if ( groupType == "C" )
3206  {
3207  //============================================ Sanity check
3208  axesToGroupTypeSanityCheck ( 1, static_cast< proshade_unsign > ( axesList.size() ), groupType );
3209 
3210  //============================================ Generate elements
3211  ret = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(0)).at(1),
3212  settings->allDetectedCAxes.at(axesList.at(0)).at(2),
3213  settings->allDetectedCAxes.at(axesList.at(0)).at(3),
3214  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(0)).at(0) ) );
3215 
3216  //============================================ Check the element to form a group
3217  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3218  else
3219  {
3220  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3221  }
3222  }
3223  else if ( groupType == "D" )
3224  {
3225  //============================================ Sanity check
3226  axesToGroupTypeSanityCheck ( 2, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3227 
3228  //============================================ Generate elements for both axes
3229  std::vector<std::vector< proshade_double > > first = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(0)).at(1),
3230  settings->allDetectedCAxes.at(axesList.at(0)).at(2),
3231  settings->allDetectedCAxes.at(axesList.at(0)).at(3),
3232  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(0)).at(0) ) );
3233  std::vector<std::vector< proshade_double > > second = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(1)).at(1),
3234  settings->allDetectedCAxes.at(axesList.at(1)).at(2),
3235  settings->allDetectedCAxes.at(axesList.at(1)).at(3),
3236  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(1)).at(0) ) );
3237 
3238  //============================================ Join the element lists
3239  ret = joinElementsFromDifferentGroups ( &first, &second, matrixTolerance, true );
3240 
3241  //============================================ Check the element to form a group
3242  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3243  else
3244  {
3245  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3246  }
3247  }
3248  else if ( groupType == "T" )
3249  {
3250  //============================================ Sanity check
3251  axesToGroupTypeSanityCheck ( 7, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3252 
3253  //============================================ Generate elements for all four C3 axes first
3254  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3255  {
3256  //======================================== If this is a C3 axis
3257  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3258  if ( lhs1.AlmostEquals ( rhs1 ) )
3259  {
3260  //==================================== Generate the elements
3261  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3262  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3263  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3264  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3265 
3266  //==================================== Join the elements to any already found
3267  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3268  }
3269  }
3270 
3271  //============================================ Generate elements for all three C2 axes second
3272  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3273  {
3274  //======================================== If this is a C3 axis
3275  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3276  if ( lhs1.AlmostEquals ( rhs1 ) )
3277  {
3278  //==================================== Generate the elements
3279  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3280  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3281  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3282  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3283 
3284  //==================================== Join the elements to any already found
3285  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3286  }
3287  }
3288 
3289  //============================================ Check the element to form a group
3290  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3291  else
3292  {
3293  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3294  }
3295  }
3296  else if ( groupType == "O" )
3297  {
3298  //============================================ Sanity check
3299  axesToGroupTypeSanityCheck ( 13, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3300 
3301  //============================================ Generate elements for all three C4 axes first
3302  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3303  {
3304  //======================================== If this is a C3 axis
3305  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 4.0 );
3306  if ( lhs1.AlmostEquals ( rhs1 ) )
3307  {
3308  //==================================== Generate the elements
3309  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3310  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3311  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3312  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3313 
3314  //==================================== Join the elements to any already found
3315  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3316  }
3317  }
3318 
3319  //============================================ Generate elements for all four C3 axes first
3320  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3321  {
3322  //======================================== If this is a C3 axis
3323  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3324  if ( lhs1.AlmostEquals ( rhs1 ) )
3325  {
3326  //==================================== Generate the elements
3327  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3328  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3329  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3330  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3331 
3332  //==================================== Join the elements to any already found
3333  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3334  }
3335  }
3336 
3337  //============================================ Generate elements for all six C2 axes next
3338  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3339  {
3340  //======================================== If this is a C3 axis
3341  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3342  if ( lhs1.AlmostEquals ( rhs1 ) )
3343  {
3344  //==================================== Generate the elements
3345  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3346  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3347  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3348  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3349 
3350  //==================================== Join the elements to any already found
3351  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3352  }
3353  }
3354 
3355  //============================================ Check the element to form a group
3356  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3357  else
3358  {
3359  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3360  }
3361  }
3362  else if ( groupType == "I" )
3363  {
3364  //============================================ Sanity check
3365  axesToGroupTypeSanityCheck ( 31, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3366 
3367  //============================================ Generate elements for all six C5 axes first
3368  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3369  {
3370  //======================================== If this is a C5 axis
3371  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 5.0 );
3372  if ( lhs1.AlmostEquals ( rhs1 ) )
3373  {
3374  //==================================== Generate the elements
3375  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3376  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3377  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3378  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3379 
3380  //==================================== Join the elements to any already found
3381  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3382  }
3383  }
3384 
3385  //============================================ Generate elements for all ten C3 axes next
3386  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3387  {
3388  //======================================== If this is a C3 axis
3389  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3390  if ( lhs1.AlmostEquals ( rhs1 ) )
3391  {
3392  //==================================== Generate the elements
3393  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3394  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3395  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3396  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3397 
3398  //==================================== Join the elements to any already found
3399  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3400  }
3401  }
3402 
3403  //============================================ Generate elements for all fifteen C2 axes lastly
3404  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3405  {
3406  //======================================== If this is a C3 axis
3407  const FloatingPoint< proshade_double > lhs1 ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3408  if ( lhs1.AlmostEquals ( rhs1 ) )
3409  {
3410  //==================================== Generate the elements
3411  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3412  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3413  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3414  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3415 
3416  //==================================== Join the elements to any already found
3417  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3418  }
3419  }
3420 
3421  //============================================ Check the element to form a group
3422  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3423  else
3424  {
3425  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3426  }
3427  }
3428  else if ( groupType == "X" )
3429  {
3430  //============================================ User forced no checking for unspecified symmetry
3431  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3432  {
3433  //======================================== Compute group elements
3434  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(1),
3435  settings->allDetectedCAxes.at(axesList.at(grIt)).at(2),
3436  settings->allDetectedCAxes.at(axesList.at(grIt)).at(3),
3437  static_cast< proshade_signed > ( settings->allDetectedCAxes.at(axesList.at(grIt)).at(0) ) );
3438 
3439  //======================================== Join the elements to any already found
3440  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, true );
3441  }
3442 
3443  //============================================ Check the element to form a group
3444  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3445  else
3446  {
3447  throw ProSHADE_exception ( "Computed point group elements do not form a group.", "ES00060", __FILE__, __LINE__, __func__, "The supplied cyclic groups list does not form a group and\n : therefore such group's elements cannot be obtained. Please\n : check the cyclic groups list supplied to the\n : getAllGroupElements() function." );
3448  }
3449  }
3450  else
3451  {
3452  std::stringstream hlpSS;
3453  hlpSS << "Unknown symmetry type: >" << groupType << "<";
3454  throw ProSHADE_exception ( hlpSS.str().c_str(), "ES00058", __FILE__, __LINE__, __func__, "Function getAllGroupElements was called with symmetry type\n : value outside of the allowed values C, D, T, O, I\n : or empty for using all supplied axes." );
3455  }
3456 
3457 }
3458 
3466 void ProSHADE_internal_data::ProSHADE_data::deepCopyMap ( proshade_double*& saveTo, proshade_signed verbose )
3467 {
3468  //================================================ Sanity check
3469  if ( saveTo != nullptr )
3470  {
3471  ProSHADE_internal_messages::printWarningMessage ( verbose, "!!! ProSHADE WARNING !!! The deep copy pointer is not set to NULL. Cannot proceed and returning unmodified pointer.", "WB00040" );
3472  return ;
3473  }
3474 
3475  //================================================ Allocate the memory
3476  saveTo = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3477 
3478  //================================================ Check memory allocation
3479  ProSHADE_internal_misc::checkMemoryAllocation ( saveTo, __FILE__, __LINE__, __func__ );
3480 
3481  //================================================ Copy internal map to the new pointer
3482  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
3483  {
3484  saveTo[iter] = this->internalMap[iter];
3485  }
3486 
3487  //================================================ Done
3488  return ;
3489 
3490 }
3491 
3499 {
3500  //================================================ Improve this!
3501  if ( settings->recommendedSymmetryType == "" )
3502  {
3503  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, "Did not detect any symmetry!" );
3504  }
3505  else
3506  {
3507  std::stringstream ssHlp;
3508  std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3509  ssHlp << std::endl << "Detected " << settings->recommendedSymmetryType << " symmetry with fold " << settings->recommendedSymmetryFold << " about point [" << comMove.at(0) << " , " << comMove.at(1) << " , " << comMove.at(2) << "] away from centre of mass .";
3510  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str() );
3511 
3512  if ( settings->detectedSymmetry.size() > 0 )
3513  {
3514  ssHlp.clear(); ssHlp.str ( "" );
3515  ssHlp << " Fold X Y Z Angle Height Average FSC";
3516  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str() );
3517  }
3518  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ); symIt++ )
3519  {
3520  ssHlp.clear(); ssHlp.str ( "" );
3521  ssHlp << std::showpos << std::fixed << std::setprecision(0) << " " << settings->detectedSymmetry.at(symIt)[0] << std::setprecision(5) << " " << settings->detectedSymmetry.at(symIt)[1] << " " << settings->detectedSymmetry.at(symIt)[2] << " " << settings->detectedSymmetry.at(symIt)[3] << " " << settings->detectedSymmetry.at(symIt)[4] << " " << settings->detectedSymmetry.at(symIt)[5] << " " << settings->detectedSymmetry.at(symIt)[6];
3522  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str() );
3523  }
3524 
3525  std::stringstream hlpSS3;
3526  ssHlp.clear(); ssHlp.str ( "" );
3527  hlpSS3 << std::endl << "To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3528  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, hlpSS3.str() );
3529 
3530  if ( settings->allDetectedCAxes.size() > 0 )
3531  {
3532  ssHlp.clear(); ssHlp.str ( "" );
3533  ssHlp << " Fold X Y Z Angle Height Average FSC";
3534  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str() );
3535  }
3536  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( settings->allDetectedCAxes.size() ); symIt++ )
3537  {
3538  ssHlp.clear(); ssHlp.str ( "" );
3539  ssHlp << std::showpos << std::fixed << std::setprecision(0) << " " << settings->allDetectedCAxes.at(symIt)[0] << std::setprecision(5) << " " << settings->allDetectedCAxes.at(symIt)[1] << " " << settings->allDetectedCAxes.at(symIt)[2] << " " << settings->allDetectedCAxes.at(symIt)[3] << " " << settings->allDetectedCAxes.at(symIt)[4] << " " << settings->allDetectedCAxes.at(symIt)[5] << " " << settings->allDetectedCAxes.at(symIt)[6];
3540  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str() );
3541  }
3542 
3543  }
3544 
3545  //================================================ Done
3546  return ;
3547 
3548 }
3549 
3555 {
3556  //================================================ Initialise variables
3557  this->xCom = 0.0;
3558  this->yCom = 0.0;
3559  this->zCom = 0.0;
3560  proshade_double totNonZeroPoints = 0.0;
3561  proshade_signed mapIt = 0;
3562 
3563  //================================================ Compute COM from 0 ; 0 ; 0
3564  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3565  {
3566  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3567  {
3568  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3569  {
3570  //==================================== Find map index
3571  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3572 
3573  //==================================== Use only positive density
3574  if ( this->internalMap[mapIt] <= 0.0 ) { continue; }
3575 
3576  //==================================== Compute Index COM
3577  this->xCom += this->internalMap[mapIt] * static_cast<proshade_double> ( xIt + this->xFrom );
3578  this->yCom += this->internalMap[mapIt] * static_cast<proshade_double> ( yIt + this->yFrom );
3579  this->zCom += this->internalMap[mapIt] * static_cast<proshade_double> ( zIt + this->zFrom );
3580  totNonZeroPoints += this->internalMap[mapIt];
3581  }
3582  }
3583  }
3584 
3585  this->xCom /= totNonZeroPoints;
3586  this->yCom /= totNonZeroPoints;
3587  this->zCom /= totNonZeroPoints;
3588 
3589  //================================================ Convert to real world
3590  this->xCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->xFrom ) * ( this->xDimSizeOriginal / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) +
3591  ( ( static_cast< proshade_single > ( this->xCom ) - static_cast< proshade_single > ( this->xFrom ) ) *
3592  ( static_cast< proshade_single > ( this->xDimSizeOriginal ) / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) );
3593  this->yCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->yFrom ) * ( this->yDimSizeOriginal / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) +
3594  ( ( static_cast< proshade_single > ( this->yCom ) - static_cast< proshade_single > ( this->yFrom ) ) *
3595  ( static_cast< proshade_single > ( this->yDimSizeOriginal ) / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) );
3596  this->zCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->zFrom ) * ( this->zDimSizeOriginal / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) +
3597  ( ( static_cast< proshade_single > ( this->zCom ) - static_cast< proshade_single > ( this->zFrom ) ) *
3598  ( static_cast< proshade_single > ( this->zDimSizeOriginal ) / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) );
3599 
3600  //================================================ Done
3601  return ;
3602 
3603 }
3604 
3610 {
3611  //================================================ Return the value
3612  return ( this->noSpheres );
3613 }
3614 
3620 proshade_double ProSHADE_internal_data::ProSHADE_data::getMapValue ( proshade_unsign pos )
3621 {
3622  //================================================ Return the value
3623  return ( this->internalMap[pos] );
3624 }
3625 
3631 {
3632  //================================================ Return the value
3633  return ( this->maxShellBand );
3634 }
3635 
3640 proshade_double ProSHADE_internal_data::ProSHADE_data::getRRPValue ( proshade_unsign band, proshade_unsign sh1, proshade_unsign sh2 )
3641 {
3642  //================================================ Return the value
3643  return ( this->rrpMatrices[band][sh1][sh2] );
3644 }
3645 
3656 bool ProSHADE_internal_data::ProSHADE_data::shellBandExists ( proshade_unsign shell, proshade_unsign bandVal )
3657 {
3658  if ( this->spheres[shell]->getLocalBandwidth( ) >= bandVal )
3659  {
3660  return ( true );
3661  }
3662  else
3663  {
3664  return ( false );
3665  }
3666 }
3667 
3677 {
3678  //================================================ Report function start
3679  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Centering map onto its COM." );
3680 
3681  //================================================ Copy map for processing
3682  fftw_complex* mapCoeffs = new fftw_complex[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3683  fftw_complex* pattersonMap = new fftw_complex[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3684 
3685  //================================================ Check memory allocation
3686  ProSHADE_internal_misc::checkMemoryAllocation ( mapCoeffs, __FILE__, __LINE__, __func__ );
3687  ProSHADE_internal_misc::checkMemoryAllocation ( pattersonMap, __FILE__, __LINE__, __func__ );
3688 
3689  //================================================ Copy data to mask
3690  for ( proshade_unsign iter = 0; iter < (this->xDimIndices * this->yDimIndices * this->zDimIndices); iter++ )
3691  {
3692  pattersonMap[iter][0] = this->internalMap[iter];
3693  pattersonMap[iter][1] = 0.0;
3694  }
3695 
3696  //================================================ Prepare FFTW plans
3697  fftw_plan forward = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3698  pattersonMap, mapCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3699  fftw_plan inverse = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3700  mapCoeffs, pattersonMap, FFTW_BACKWARD, FFTW_ESTIMATE );
3701 
3702  //================================================ Run forward Fourier
3703  fftw_execute ( forward );
3704 
3705  //================================================ Remove the phase
3706  ProSHADE_internal_mapManip::removeMapPhase ( mapCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices );
3707 
3708  //================================================ Run inverse Fourier
3709  fftw_execute ( inverse );
3710 
3711  //================================================ Save the results
3712  proshade_signed mapIt, patIt, patX, patY, patZ;
3713  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3714  {
3715  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3716  {
3717  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3718  {
3719  //==================================== Centre patterson map
3720  patX = xIt - ( static_cast<proshade_signed> ( this->xDimIndices ) / 2 ); if ( patX < 0 ) { patX += this->xDimIndices; }
3721  patY = yIt - ( static_cast<proshade_signed> ( this->yDimIndices ) / 2 ); if ( patY < 0 ) { patY += this->yDimIndices; }
3722  patZ = zIt - ( static_cast<proshade_signed> ( this->zDimIndices ) / 2 ); if ( patZ < 0 ) { patZ += this->zDimIndices; }
3723 
3724  //==================================== Find indices
3725  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3726  patIt = patZ + static_cast< proshade_signed > ( this->zDimIndices ) * ( patY + static_cast< proshade_signed > ( this->yDimIndices ) * patX );
3727 
3728  //==================================== Copy
3729  this->internalMap[mapIt] = pattersonMap[patIt][0];
3730  }
3731  }
3732  }
3733 
3734  //================================================ Release memory
3735  delete[] pattersonMap;
3736  delete[] mapCoeffs;
3737 
3738  //================================================ Delete FFTW plans
3739  fftw_destroy_plan ( forward );
3740  fftw_destroy_plan ( inverse );
3741 
3742  //================================================ Report function completion
3743  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Phase information removed." );
3744 
3745  //================================================ Done
3746  return ;
3747 
3748 }
3749 
3754 proshade_double* ProSHADE_internal_data::ProSHADE_data::getRealSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3755 {
3756  //================================================ Done
3757  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3758  static_cast< int > ( band ),
3759  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][0] );
3760 
3761 }
3762 
3767 proshade_double* ProSHADE_internal_data::ProSHADE_data::getImagSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3768 {
3769  //================================================ Done
3770  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3771  static_cast< int > ( band ),
3772  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][1] );
3773 
3774 }
3775 
3780 proshade_double ProSHADE_internal_data::ProSHADE_data::getAnySphereRadius ( proshade_unsign shell )
3781 {
3782  //================================================ Done
3783  return ( this->spheres[shell]->getShellRadius() );
3784 
3785 }
3786 
3792 {
3793  //================================================ Done
3794  return ( this->integrationWeight );
3795 
3796 }
3797 
3803 proshade_unsign ProSHADE_internal_data::ProSHADE_data::getShellBandwidth ( proshade_unsign shell )
3804 {
3805  //================================================ Done
3806  return ( this->spheres[shell]->getLocalBandwidth ( ) );
3807 
3808 }
3809 
3815 proshade_single ProSHADE_internal_data::ProSHADE_data::getSpherePosValue ( proshade_unsign shell )
3816 {
3817  //================================================ Done
3818  return ( this->spherePos.at(shell) );
3819 
3820 }
3821 
3827 proshade_complex** ProSHADE_internal_data::ProSHADE_data::getEMatrixByBand ( proshade_unsign band )
3828 {
3829  //================================================ Done
3830  return ( this->eMatrices[band] );
3831 
3832 }
3833 
3842 void ProSHADE_internal_data::ProSHADE_data::getEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
3843 {
3844  //================================================ Set pointer
3845  *valueReal = this->eMatrices[band][order1][order2][0];
3846  *valueImag = this->eMatrices[band][order1][order2][1];
3847 
3848  //================================================ Done
3849  return ;
3850 
3851 }
3852 
3858 {
3859  //================================================ Done
3860  return ( this->so3CoeffsInverse );
3861 
3862 }
3863 
3869 {
3870  //================================================ Done
3871  return ( this->so3Coeffs );
3872 
3873 }
3874 
3880 {
3881  //================================================ Done
3882  return ( this->maxCompBand );
3883 
3884 }
3885 
3894 void ProSHADE_internal_data::ProSHADE_data::getWignerMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
3895 {
3896  //================================================ Set pointer
3897  *valueReal = this->wignerMatrices[band][order1][order2][0];
3898  *valueImag = this->wignerMatrices[band][order1][order2][1];
3899 
3900  //================================================ Done
3901  return ;
3902 
3903 }
3904 
3910 {
3911  //================================================ Return the requested value
3912  return ( this->xDimSize );
3913 }
3914 
3920 {
3921  //================================================ Return the requested value
3922  return ( this->yDimSize );
3923 }
3924 
3930 {
3931  //================================================ Return the requested value
3932  return ( this->zDimSize );
3933 }
3934 
3940 {
3941  //================================================ Return the requested value
3942  return ( this->xDimIndices );
3943 }
3944 
3950 {
3951  //================================================ Return the requested value
3952  return ( this->yDimIndices );
3953 }
3954 
3960 {
3961  //================================================ Return the requested value
3962  return ( this->zDimIndices );
3963 }
3964 
3970 {
3971  //================================================ Return the requested value
3972  return ( &this->xFrom );
3973 }
3974 
3980 {
3981  //================================================ Return the requested value
3982  return ( &this->yFrom );
3983 }
3984 
3990 {
3991  //================================================ Return the requested value
3992  return ( &this->zFrom );
3993 }
3994 
4000 {
4001  //================================================ Return the requested value
4002  return ( &this->xTo );
4003 }
4004 
4010 {
4011  //================================================ Return the requested value
4012  return ( &this->yTo );
4013 }
4014 
4020 {
4021  //================================================ Return the requested value
4022  return ( &this->zTo );
4023 }
4024 
4030 {
4031  //================================================ Return the requested value
4032  return ( &this->xAxisOrigin );
4033 }
4034 
4040 {
4041  //================================================ Return the requested value
4042  return ( &this->yAxisOrigin );
4043 }
4044 
4050 {
4051  //================================================ Return the requested value
4052  return ( &this->zAxisOrigin );
4053 }
4054 
4060 {
4061  //================================================ Return the requested value
4062  return ( this->internalMap );
4063 }
4064 
4070 {
4071  //================================================ Return the requested value
4072  return ( this->translationMap );
4073 }
4074 
4080 {
4081  //================================================ Initialise local variables
4082  std::vector< proshade_double > ret;
4083 
4084  //================================================ Save the values
4085  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeX );
4086  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeY );
4087  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeZ );
4088 
4089  //================================================ Return the requested value
4090  return ( ret );
4091 }
4092 
4098 {
4099  //================================================ Mutate
4100  this->integrationWeight = intW;
4101 
4102  //================================================ Done
4103  return ;
4104 
4105 }
4106 
4112 {
4113  //================================================ Mutate
4114  this->integrationWeight += intW;
4115 
4116  //================================================ Done
4117  return ;
4118 
4119 }
4120 
4128 void ProSHADE_internal_data::ProSHADE_data::setEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_complex val )
4129 {
4130  //================================================ Mutate
4131  this->eMatrices[band][order1][order2][0] = val[0];
4132  this->eMatrices[band][order1][order2][1] = val[1];
4133 
4134  //================================================ Done
4135  return ;
4136 
4137 }
4138 
4146 void ProSHADE_internal_data::ProSHADE_data::normaliseEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double normF )
4147 {
4148  //================================================ Mutate
4149  this->eMatrices[band][order1][order2][0] /= normF;
4150  this->eMatrices[band][order1][order2][1] /= normF;
4151 
4152  //================================================ Done
4153  return ;
4154 
4155 }
4156 
4162 void ProSHADE_internal_data::ProSHADE_data::setSO3CoeffValue ( proshade_unsign position, proshade_complex val )
4163 {
4164  //================================================ Mutate
4165  this->so3Coeffs[position][0] = val[0];
4166  this->so3Coeffs[position][1] = val[1];
4167 
4168  //================================================ Done
4169  return ;
4170 
4171 }
4172 
4180 void ProSHADE_internal_data::ProSHADE_data::setWignerMatrixValue ( proshade_complex val, proshade_unsign band, proshade_unsign order1, proshade_unsign order2 )
4181 {
4182  //================================================ Mutate
4183  this->wignerMatrices[band][order1][order2][0] = val[0];
4184  this->wignerMatrices[band][order1][order2][1] = val[1];
4185 
4186  //================================================ Done
4187  return ;
4188 
4189 }
4190 
4198 void ProSHADE_internal_data::ProSHADE_data::getRealEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMReal, int len )
4199 {
4200  //================================================ Save the data into the output array
4201  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4202  {
4203  eMatsLMReal[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][0] );
4204  }
4205 
4206  //================================================ Done
4207  return ;
4208 
4209 }
4210 
4218 void ProSHADE_internal_data::ProSHADE_data::getImagEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMImag, int len )
4219 {
4220  //================================================ Save the data into the output array
4221  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4222  {
4223  eMatsLMImag[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][1] );
4224  }
4225 
4226  //================================================ Done
4227  return ;
4228 
4229 }
4230 
4236 void ProSHADE_internal_data::ProSHADE_data::getRealSO3Coeffs ( double *so3CoefsReal, int len )
4237 {
4238  //================================================ Save the data into the output array
4239  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4240  {
4241  so3CoefsReal[iter] = static_cast<double> ( this->so3Coeffs[iter][0] );
4242  }
4243 
4244  //================================================ Done
4245  return ;
4246 
4247 }
4248 
4254 void ProSHADE_internal_data::ProSHADE_data::getImagSO3Coeffs ( double *so3CoefsImag, int len )
4255 {
4256  //================================================ Save the data into the output array
4257  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4258  {
4259  so3CoefsImag[iter] = static_cast<double> ( this->so3Coeffs[iter][1] );
4260  }
4261 
4262  //================================================ Done
4263  return ;
4264 
4265 }
4266 
4276 int ProSHADE_internal_data::ProSHADE_data::so3CoeffsArrayIndex ( proshade_signed order1, proshade_signed order2, proshade_signed band )
4277 {
4278  //================================================ Return the value
4279  return ( static_cast<int> ( so3CoefLoc ( static_cast< int > ( order1 ), static_cast< int > ( order2 ), static_cast< int > ( band ), static_cast< int > ( this->getMaxBand() ) ) ) );
4280 }
4281 
4288 {
4289  //================================================ Save the data into the output array
4290  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4291  {
4292  rotFunReal[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][0] );
4293  }
4294 
4295  //================================================ Done
4296  return ;
4297 
4298 }
4299 
4306 {
4307  //================================================ Save the data into the output array
4308  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4309  {
4310  rotFunImag[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][1] );
4311  }
4312 
4313  //================================================ Done
4314  return ;
4315 
4316 }
4317 
4324 {
4325  //================================================ Save the data into the output array
4326  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4327  {
4328  trsFunReal[iter] = static_cast<double> ( this->translationMap[iter][0] );
4329  }
4330 
4331  //================================================ Done
4332  return ;
4333 
4334 }
4335 
4342 {
4343  //================================================ Save the data into the output array
4344  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4345  {
4346  trsFunImag[iter] = static_cast<double> ( this->translationMap[iter][1] );
4347  }
4348 
4349  //================================================ Done
4350  return ;
4351 
4352 }
4353 
4362 void ProSHADE_internal_data::ProSHADE_data::getRotMatrixFromRotFunInds ( proshade_signed aI, proshade_signed bI, proshade_signed gI, double *rotMat, int len )
4363 {
4364  //================================================ Get Euler angles
4365  proshade_double eA, eB, eG;
4366  ProSHADE_internal_maths::getEulerZXZFromSOFTPosition ( static_cast< int > ( this->getMaxBand() ), aI, bI, gI, &eA, &eB, &eG );
4367 
4368  //================================================ Prepare internal rotation matrix memory
4369  proshade_double* rMat = nullptr;
4370  rMat = new proshade_double[9];
4371  ProSHADE_internal_misc::checkMemoryAllocation ( rMat, __FILE__, __LINE__, __func__ );
4372 
4373  //================================================ Convert to rotation matrix
4375 
4376  //================================================ Copy to output
4377  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4378  {
4379  rotMat[iter] = static_cast<double> ( rMat[iter] );
4380  }
4381 
4382  //================================================ Release internal memory
4383  delete[] rMat;
4384 
4385  //================================================ Done
4386  return ;
4387 
4388 }
4389 
4395 {
4396  //================================================ Return the value
4397  return ( settings->recommendedSymmetryType );
4398 
4399 }
4400 
4406 {
4407  //================================================ Return the value
4408  return ( settings->recommendedSymmetryFold );
4409 
4410 }
4411 
4418 {
4419  //================================================ Return the value
4420  return ( static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ) );
4421 }
4422 
4429 std::vector< std::string > ProSHADE_internal_data::ProSHADE_data::getSymmetryAxis ( ProSHADE_settings* settings, proshade_unsign axisNo )
4430 {
4431  //================================================ Sanity checks
4432  if ( static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ) <= axisNo )
4433  {
4434  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested symmetry index does not exist. Returning empty vector.", "WS00039" );
4435  return ( std::vector< std::string > ( ) );
4436  }
4437 
4438  //================================================ Initialise local variables
4439  std::vector< std::string > ret;
4440 
4441  //================================================ Input the axis data as strings
4442  std::stringstream ssHlp;
4443  ssHlp << settings->detectedSymmetry.at(axisNo)[0];
4444  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4445  ssHlp.str ( "" );
4446 
4447  ssHlp << settings->detectedSymmetry.at(axisNo)[1];
4448  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4449  ssHlp.str ( "" );
4450 
4451  ssHlp << settings->detectedSymmetry.at(axisNo)[2];
4452  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4453  ssHlp.str ( "" );
4454 
4455  ssHlp << settings->detectedSymmetry.at(axisNo)[3];
4456  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4457  ssHlp.str ( "" );
4458 
4459  ssHlp << settings->detectedSymmetry.at(axisNo)[4];
4460  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4461  ssHlp.str ( "" );
4462 
4463  ssHlp << settings->detectedSymmetry.at(axisNo)[5];
4464  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4465  ssHlp.str ( "" );
4466 
4467  ssHlp << settings->detectedSymmetry.at(axisNo)[6];
4468  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4469  ssHlp.str ( "" );
4470 
4471  //================================================ Done
4472  return ( ret );
4473 
4474 }
4475 
4488 void ProSHADE_internal_data::ProSHADE_data::writeOutOverlayFiles ( ProSHADE_settings* settings, proshade_double eulA, proshade_double eulB, proshade_double eulG, std::vector< proshade_double >* rotCentre, std::vector< proshade_double >* ultimateTranslation )
4489 {
4490  //================================================ Write out rotated map
4491  std::stringstream fNameHlp;
4492  fNameHlp << settings->overlayStructureName << ".map";
4493  this->writeMap ( fNameHlp.str() );
4494 
4495  //================================================ Write out rotated co-ordinates if possible
4496  if ( ProSHADE_internal_io::isFilePDB ( this->fileName ) )
4497  {
4498  fNameHlp.str("");
4499  fNameHlp << settings->overlayStructureName << ".pdb";
4500  this->writePdb ( fNameHlp.str(), eulA, eulB, eulG, ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2), settings->firstModelOnly );
4501  }
4502 
4503  //================================================ Write out the json file with the results
4504  ProSHADE_internal_io::writeRotationTranslationJSON ( rotCentre->at(0), rotCentre->at(1), rotCentre->at(2),
4505  eulA, eulB, eulG,
4506  ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2),
4507  settings->rotTrsJSONFile );
4508 
4509  //================================================ Done
4510  return ;
4511 
4512 }
4513 
4522 void ProSHADE_internal_data::ProSHADE_data::reportOverlayResults ( ProSHADE_settings* settings, std::vector < proshade_double >* rotationCentre, std::vector < proshade_double >* eulerAngles, std::vector < proshade_double >* finalTranslation )
4523 {
4524  //================================================ Empty line
4526 
4527  //================================================ Write out rotation centre translation results
4528  std::stringstream rotCen; rotCen << std::setprecision (3) << std::showpos << "The rotation centre to origin translation vector is: " << -rotationCentre->at(0) << " " << -rotationCentre->at(1) << " " << -rotationCentre->at(2);
4529  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotCen.str() );
4530 
4531  //================================================ Write out rotation matrix about origin
4532  proshade_double* rotMat = new proshade_double[9];
4533  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
4534  ProSHADE_internal_maths::getRotationMatrixFromEulerZXZAngles ( eulerAngles->at(0), eulerAngles->at(1), eulerAngles->at(2), rotMat );
4535 
4536  std::stringstream rotMatSS;
4537  rotMatSS << std::setprecision (3) << std::showpos << "The rotation matrix about origin is : " << rotMat[0] << " " << rotMat[1] << " " << rotMat[2] << std::endl;
4538  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[3] << " " << rotMat[4] << " " << rotMat[5] << std::endl;
4539  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[6] << " " << rotMat[7] << " " << rotMat[8];
4540  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotMatSS.str() );
4541 
4542  delete[] rotMat;
4543 
4544  //================================================ Write out origin to overlay translation results
4545  std::stringstream finTrs; finTrs << std::setprecision (3) << std::showpos << "The rotation centre to overlay translation vector is: " << finalTranslation->at(0) << " " << finalTranslation->at(1) << " " << finalTranslation->at(2);
4546  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, finTrs.str() );
4547 
4548  //================================================ Done
4549  return ;
4550 
4551 }
ProSHADE_internal_data::ProSHADE_data::findTopGroupSmooth
proshade_double findTopGroupSmooth(std::vector< proshade_double * > *CSym, size_t peakPos, proshade_double step, proshade_double sigma, proshade_signed windowSize)
This function finds the distinct group of axes with highest peak heights.
Definition: ProSHADE_data.cpp:2332
ProSHADE_internal_data::ProSHADE_data::originalMapYCom
proshade_double originalMapYCom
The COM of the first map to be loaded/computed without any furhter changes being reflacted along the ...
Definition: ProSHADE_data.hpp:92
ProSHADE_settings::maxBandwidth
proshade_unsign maxBandwidth
The bandwidth of spherical harmonics decomposition for the largest sphere.
Definition: ProSHADE_settings.hpp:58
ProSHADE_internal_mapManip::addExtraBoundSpace
void addExtraBoundSpace(proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed *&bounds, proshade_single extraSpace)
This function takes a set of bounds and adds a given number of Angstroms to them.
Definition: ProSHADE_mapManip.cpp:1139
ProSHADE_internal_data::ProSHADE_data::computeSphericalHarmonics
void computeSphericalHarmonics(ProSHADE_settings *settings)
This function computes the spherical harmonics decomposition for the whole structure.
Definition: ProSHADE_data.cpp:1756
ProSHADE_internal_data::ProSHADE_data::mapMovFromsChangeX
proshade_double mapMovFromsChangeX
When the map is translated, the xFrom and xTo values are changed. This variable holds how much they h...
Definition: ProSHADE_data.hpp:94
ProSHADE_settings::recommendedSymmetryType
std::string recommendedSymmetryType
The symmetry type that ProSHADE finds the best fitting for the structure. Possible values are "" for ...
Definition: ProSHADE_settings.hpp:125
ProSHADE_internal_data::ProSHADE_data::getEMatrixByBand
proshade_complex ** getEMatrixByBand(proshade_unsign band)
This function allows access to E matrix for a particular band.
Definition: ProSHADE_data.cpp:3827
ProSHADE_internal_mapManip::determinePDBRanges
void determinePDBRanges(gemmi::Structure pdbFile, proshade_single *xFrom, proshade_single *xTo, proshade_single *yFrom, proshade_single *yTo, proshade_single *zFrom, proshade_single *zTo, bool firstModel)
Function for finding the PDB file ranges.
Definition: ProSHADE_mapManip.cpp:72
ProSHADE_internal_data::ProSHADE_data::fileName
std::string fileName
This is the original file from which the data were obtained.
Definition: ProSHADE_data.hpp:52
ProSHADE_internal_data::ProSHADE_data::zFrom
proshade_signed zFrom
This is the starting index along the z axis.
Definition: ProSHADE_data.hpp:112
ProSHADE_settings::rotTrsJSONFile
std::string rotTrsJSONFile
The filename to which the rotation and translation operations are to be saved into.
Definition: ProSHADE_settings.hpp:137
ProSHADE_internal_data::ProSHADE_data::xDimIndices
proshade_unsign xDimIndices
This is the size of the map cell x dimension in indices.
Definition: ProSHADE_data.hpp:65
ProSHADE_internal_data::ProSHADE_data::getZDimSize
proshade_single getZDimSize(void)
This function allows access to the map size in angstroms along the Z axis.
Definition: ProSHADE_data.cpp:3929
ProSHADE_internal_mapManip::changePDBBFactors
void changePDBBFactors(gemmi::Structure *pdbFile, proshade_double newBFactorValue, bool firstModel)
Function for changing the PDB B-factor values to a specific single value.
Definition: ProSHADE_mapManip.cpp:444
ProSHADE_internal_data::ProSHADE_data::zDimSizeOriginal
proshade_single zDimSizeOriginal
This is the size of the map cell z dimension in Angstroms.
Definition: ProSHADE_data.hpp:84
ProSHADE_internal_maths::vectorMeanAndSD
void vectorMeanAndSD(std::vector< proshade_double > *vec, proshade_double *&ret)
Function to get vector mean and standard deviation.
Definition: ProSHADE_maths.cpp:121
ProSHADE_internal_data::ProSHADE_data::createNewMapFromBounds
void createNewMapFromBounds(ProSHADE_settings *settings, ProSHADE_data *&newStr, proshade_signed *newBounds)
This function creates a new structure from the calling structure and new bounds values.
Definition: ProSHADE_data.cpp:1300
ProSHADE_internal_io::isFilePDB
bool isFilePDB(std::string fName)
Function determining if the input data type is PDB.
Definition: ProSHADE_io.cpp:32
ProSHADE_internal_data::ProSHADE_data::xGridIndices
proshade_unsign xGridIndices
As far as I know, this is identical to the xDimIndices.
Definition: ProSHADE_data.hpp:68
ProSHADE_internal_data::ProSHADE_data::translationMap
proshade_complex * translationMap
This is where the translation map will be held, if at all used.
Definition: ProSHADE_data.hpp:133
ProSHADE_internal_data::joinElementsFromDifferentGroups
std::vector< std::vector< proshade_double > > joinElementsFromDifferentGroups(std::vector< std::vector< proshade_double > > *first, std::vector< std::vector< proshade_double > > *second, proshade_double matrixTolerance, bool combine)
This function joins two group element lists using only unique elements.
Definition: ProSHADE_data.cpp:3133
ProSHADE_internal_data::ProSHADE_data::xAxisOrder
proshade_unsign xAxisOrder
This is the order of the x axis.
Definition: ProSHADE_data.hpp:71
ProSHADE_internal_data::ProSHADE_data::rotSphericalHarmonics
proshade_complex ** rotSphericalHarmonics
A set of rotated spherical harmonics values arrays for each sphere, used only if map rotation is requ...
Definition: ProSHADE_data.hpp:122
ProSHADE_internal_data::ProSHADE_data::getReBoxBoundaries
void getReBoxBoundaries(ProSHADE_settings *settings, proshade_signed *&ret)
This function finds the boundaries enclosing positive map values and adds some extra space.
Definition: ProSHADE_data.cpp:1242
ProSHADE_settings::determineAllSHValues
void determineAllSHValues(proshade_unsign xDim, proshade_unsign yDim, proshade_single xDimAngs, proshade_single yDimAngs, proshade_single zDimAngs)
This function determines all the required values for spherical harmonics computation.
Definition: ProSHADE.cpp:1612
ProSHADE_internal_data::ProSHADE_data::getComparisonBand
proshade_unsign getComparisonBand(void)
This function allows access to the maximum band for the comparison.
Definition: ProSHADE_data.cpp:3879
ProSHADE_internal_data::ProSHADE_data::getRecommendedSymmetryFold
proshade_unsign getRecommendedSymmetryFold(ProSHADE_settings *settings)
This function simply returns the detected recommended symmetry fold.
Definition: ProSHADE_data.cpp:4405
ProSHADE_internal_data::ProSHADE_data::sphericalHarmonics
proshade_complex ** sphericalHarmonics
A set of spherical harmonics values arrays for each sphere.
Definition: ProSHADE_data.hpp:121
ProSHADE_internal_data::ProSHADE_data::setIntegrationWeight
void setIntegrationWeight(proshade_double intW)
This function allows setting the integration weight for the object.
Definition: ProSHADE_data.cpp:4097
ProSHADE_internal_data::ProSHADE_data::saveRecommendedSymmetry
void saveRecommendedSymmetry(ProSHADE_settings *settings, std::vector< proshade_double * > *CSym, std::vector< proshade_double * > *DSym, std::vector< proshade_double * > *TSym, std::vector< proshade_double * > *OSym, std::vector< proshade_double * > *ISym, std::vector< proshade_double * > *axes, fftw_complex *mapData, fftw_complex *origCoeffs, fftw_complex *fCoeffs, fftw_plan *planForwardFourier, proshade_signed noBins, proshade_signed *binIndexing, proshade_double **bindata, proshade_signed *binCounts)
This function takes all the detected symmetry results and decides on which are to be recommended for ...
Definition: ProSHADE_data.cpp:2627
ProSHADE_internal_data::ProSHADE_data::cAngle
proshade_single cAngle
This is the angle c of the map cell in degrees.
Definition: ProSHADE_data.hpp:64
ProSHADE_internal_data::ProSHADE_data::so3CoeffsInverse
proshade_complex * so3CoeffsInverse
The inverse coefficients obtained by inverse SO(3) Fourier Transform (SOFT) - i.e....
Definition: ProSHADE_data.hpp:130
ProSHADE_internal_data::ProSHADE_data::prepareFSCFourierMemory
void prepareFSCFourierMemory(fftw_complex *&mapData, fftw_complex *&origCoeffs, fftw_complex *&fCoeffs, proshade_signed *&binIndexing, proshade_signed *noBins, proshade_double **&bindata, proshade_signed *&binCounts, fftw_plan *planForwardFourier)
This function allocates the memory and makes all preparations required for FSC computation.
Definition: ProSHADE_data.cpp:2388
ProSHADE_internal_data::ProSHADE_data::getXAxisOrigin
proshade_signed * getXAxisOrigin(void)
This function allows access to the map X axis origin value.
Definition: ProSHADE_data.cpp:4029
ProSHADE_internal_symmetry::addAxisUnlessSame
proshade_signed addAxisUnlessSame(proshade_unsign fold, proshade_double axX, proshade_double axY, proshade_double axZ, proshade_double axHeight, proshade_double averageFSC, std::vector< proshade_double * > *prosp, proshade_double axErr)
This function simply creates a new axis from information in aruments and tests if no such axis alread...
Definition: ProSHADE_symmetry.cpp:2648
ProSHADE_internal_data::ProSHADE_data::normaliseEMatrixValue
void normaliseEMatrixValue(proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double normF)
This function allows normalising the E matrix value.
Definition: ProSHADE_data.cpp:4146
ProSHADE_internal_data::ProSHADE_data::yCom
proshade_double yCom
The COM of the map after processing along the Y-axis.
Definition: ProSHADE_data.hpp:78
ProSHADE_settings::boundsExtraSpace
proshade_single boundsExtraSpace
The number of extra angstroms to be added to all re-boxing bounds just for safety.
Definition: ProSHADE_settings.hpp:90
ProSHADE_exception
This class is the representation of ProSHADE exception.
Definition: ProSHADE_exceptions.hpp:37
ProSHADE_internal_data::ProSHADE_data::getImagTranslationFunction
void getImagTranslationFunction(double *trsFunImag, int len)
This function fills the input array with the imaginary translation function values.
Definition: ProSHADE_data.cpp:4341
ProSHADE_internal_data::ProSHADE_data::setWignerMatrixValue
void setWignerMatrixValue(proshade_complex val, proshade_unsign band, proshade_unsign order1, proshade_unsign order2)
This function allows setting the Wigner D matrix value by its band, order1 and order2 co-ordinate.
Definition: ProSHADE_data.cpp:4180
ProSHADE_settings::allDetectedDAxes
std::vector< std::vector< proshade_unsign > > allDetectedDAxes
The vector of all detected dihedral symmetry axes indices in allDetectedCAxes.
Definition: ProSHADE_settings.hpp:146
ProSHADE_settings::blurFactor
proshade_single blurFactor
This is the amount by which B-factors should be increased to create the blurred map for masking.
Definition: ProSHADE_settings.hpp:78
ProSHADE_internal_data::ProSHADE_data::saveDetectedSymmetries
void saveDetectedSymmetries(ProSHADE_settings *settings, std::vector< proshade_double * > *CSyms, std::vector< std::vector< proshade_double > > *allCs)
This function takes the results of point group searches and saves then into the output variables.
Definition: ProSHADE_data.cpp:2286
ProSHADE_settings::maskMap
bool maskMap
Should the map be masked from noise?
Definition: ProSHADE_settings.hpp:80
ProSHADE_settings::requestedSymmetryFold
proshade_unsign requestedSymmetryFold
The fold of the requested symmetry (only applicable to C and D symmetry types).
Definition: ProSHADE_settings.hpp:128
ProSHADE_settings::requestedSymmetryType
std::string requestedSymmetryType
The symmetry type requested by the user. Allowed values are C, D, T, O and I.
Definition: ProSHADE_settings.hpp:127
ProSHADE_internal_data::ProSHADE_data::getEMatrixValue
void getEMatrixValue(proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double *valueReal, proshade_double *valueImag)
This function allows access to E matrix by knowing the band, order1 and order2 indices.
Definition: ProSHADE_data.cpp:3842
ProSHADE_internal_data::ProSHADE_data::getXDimSize
proshade_single getXDimSize(void)
This function allows access to the map size in angstroms along the X axis.
Definition: ProSHADE_data.cpp:3909
ProSHADE_internal_data::ProSHADE_data::getInternalMap
proshade_double *& getInternalMap(void)
This function allows access to the first map array value address.
Definition: ProSHADE_data.cpp:4059
ProSHADE_internal_data::ProSHADE_data
This class contains all inputed and derived data for a single structure.
Definition: ProSHADE_data.hpp:49
ProSHADE_internal_data::ProSHADE_data::noSpheres
proshade_unsign noSpheres
The number of spheres with map projected onto them.
Definition: ProSHADE_data.hpp:119
ProSHADE_settings::removeNegativeDensity
bool removeNegativeDensity
Should the negative density be removed from input files?
Definition: ProSHADE_settings.hpp:47
ProSHADE_internal_data::ProSHADE_data::getYDimSize
proshade_single getYDimSize(void)
This function allows access to the map size in angstroms along the Y axis.
Definition: ProSHADE_data.cpp:3919
ProSHADE_internal_mapManip::getMaskFromBlurr
void getMaskFromBlurr(proshade_double *&blurMap, proshade_double *&outMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single noIQRs)
Function for computing mask from blurred map.
Definition: ProSHADE_mapManip.cpp:1032
ProSHADE_internal_data::ProSHADE_data::computeFSC
proshade_double computeFSC(ProSHADE_settings *settings, std::vector< proshade_double * > *CSym, size_t symIndex, fftw_complex *mapData, fftw_complex *fCoeffs, fftw_complex *origCoeffs, fftw_plan *planForwardFourier, proshade_signed noBins, proshade_signed *binIndexing, proshade_double **&bindata, proshade_signed *&binCounts)
This function computes FSC for any given axis in the supplied CSym symmetry axes vector.
Definition: ProSHADE_data.cpp:2456
ProSHADE_internal_data::ProSHADE_data::zDimSize
proshade_single zDimSize
This is the size of the map cell z dimension in Angstroms.
Definition: ProSHADE_data.hpp:61
ProSHADE_internal_data::ProSHADE_data::so3Coeffs
proshade_complex * so3Coeffs
The coefficients obtained by SO(3) Fourier Transform (SOFT), in this case derived from the E matrices...
Definition: ProSHADE_data.hpp:129
ProSHADE_internal_data::ProSHADE_data::getMaxSpheres
proshade_unsign getMaxSpheres(void)
This function returns the number of spheres which contain the whole object.
Definition: ProSHADE_data.cpp:3609
ProSHADE_internal_data::ProSHADE_data::setSO3CoeffValue
void setSO3CoeffValue(proshade_unsign position, proshade_complex val)
This function allows setting the SOFT coefficient values using array position and value.
Definition: ProSHADE_data.cpp:4162
ProSHADE_settings::saveMask
bool saveMask
Should the mask be saved?
Definition: ProSHADE_settings.hpp:84
ProSHADE_settings::requestedResolution
proshade_single requestedResolution
The resolution to which the calculations are to be done.
Definition: ProSHADE_settings.hpp:50
ProSHADE_internal_data::ProSHADE_data::mapCOMProcessChangeX
proshade_double mapCOMProcessChangeX
The change in X axis between the creation of the structure (originalMapXCom) and just before rotation...
Definition: ProSHADE_data.hpp:97
ProSHADE_internal_mapManip::findMAPCOMValues
void findMAPCOMValues(proshade_double *map, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo)
This function finds the Centre of Mass for a map.
Definition: ProSHADE_mapManip.cpp:240
ProSHADE_internal_mapManip::blurSharpenMap
void blurSharpenMap(proshade_double *&map, proshade_double *&maskedMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single blurringFactor)
Function for blurring/sharpening maps.
Definition: ProSHADE_mapManip.cpp:932
ProSHADE_internal_data::ProSHADE_data::originalMapXCom
proshade_double originalMapXCom
The COM of the first map to be loaded/computed without any furhter changes being reflacted along the ...
Definition: ProSHADE_data.hpp:91
ProSHADE_internal_data::ProSHADE_data::getRotMatrixFromRotFunInds
void getRotMatrixFromRotFunInds(proshade_signed aI, proshade_signed bI, proshade_signed gI, double *rotMat, int len)
This function takes rotation function indices, converts them to Euler angles and these to rotation ma...
Definition: ProSHADE_data.cpp:4362
ProSHADE_settings::setDetectedSymmetry
void setDetectedSymmetry(proshade_double *sym)
Sets the final detected symmetry axes information.
Definition: ProSHADE.cpp:1294
ProSHADE_internal_data::ProSHADE_data::xDimIndicesOriginal
proshade_unsign xDimIndicesOriginal
This is the size of the map cell x dimension in indices.
Definition: ProSHADE_data.hpp:85
ProSHADE_internal_mapManip::moveMapByFourier
void moveMapByFourier(proshade_double *&map, proshade_single xMov, proshade_single yMov, proshade_single zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim)
Function for moving map back to original PDB location by using Fourier transformation.
Definition: ProSHADE_mapManip.cpp:811
ProSHADE_internal_data::ProSHADE_data::getAnySphereRadius
proshade_double getAnySphereRadius(proshade_unsign shell)
This function allows access to the radius of any particular sphere.
Definition: ProSHADE_data.cpp:3780
ProSHADE_settings::progressiveSphereMapping
bool progressiveSphereMapping
If true, each shell will have its own angular resolution dependent on the actual number of map points...
Definition: ProSHADE_settings.hpp:102
ProSHADE_internal_mapManip::movePDBForMapCalc
void movePDBForMapCalc(gemmi::Structure *pdbFile, proshade_single xMov, proshade_single yMov, proshade_single zMov, bool firstModel)
Function for moving co-ordinate atoms to better suit theoretical map computation.
Definition: ProSHADE_mapManip.cpp:573
ProSHADE_internal_data::ProSHADE_data::getSO3Coeffs
proshade_complex * getSO3Coeffs(void)
This function allows access to the SO(3) coefficients array.
Definition: ProSHADE_data.cpp:3868
ProSHADE_settings::maxSphereDists
proshade_single maxSphereDists
The distance between spheres in spherical mapping for the largest sphere.
Definition: ProSHADE_settings.hpp:65
ProSHADE_internal_data::ProSHADE_data::maxShellBand
proshade_unsign maxShellBand
The maximum band for any shell of the object.
Definition: ProSHADE_data.hpp:123
ProSHADE_internal_data::ProSHADE_data::originalPdbRotCenY
proshade_double originalPdbRotCenY
The centre of rotation as it relates to the original PDB positions (and not the ProSHADE internal map...
Definition: ProSHADE_data.hpp:103
ProSHADE_internal_data::ProSHADE_data::getSpherePositions
void getSpherePositions(ProSHADE_settings *settings)
This function determines the sphere positions (radii) for sphere mapping.
Definition: ProSHADE_data.cpp:1655
ProSHADE_internal_data::ProSHADE_data::invertMirrorMap
void invertMirrorMap(ProSHADE_settings *settings)
Function for inverting the map to its mirror image.
Definition: ProSHADE_data.cpp:1101
ProSHADE_internal_maths::getRotationMatrixFromEulerZXZAngles
void getRotationMatrixFromEulerZXZAngles(proshade_double eulerAlpha, proshade_double eulerBeta, proshade_double eulerGamma, proshade_double *matrix)
Function to find the rotation matrix from Euler angles (ZXZ convention).
Definition: ProSHADE_maths.cpp:1011
checkElementsFormGroup
bool checkElementsFormGroup(std::vector< std::vector< proshade_double > > *elements, proshade_double matrixTolerance)
This function checks if all group element products produce another group element.
Definition: ProSHADE_data.cpp:3092
ProSHADE_internal_data::ProSHADE_data::getMapCOMProcessChange
std::vector< proshade_double > getMapCOMProcessChange(void)
This function allows access to the translation caused by structure processing.
Definition: ProSHADE_data.cpp:4079
ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryD
void saveRequestedSymmetryD(ProSHADE_settings *settings, std::vector< proshade_double * > *DSym, std::vector< proshade_double * > *axes, fftw_complex *mapData, fftw_complex *origCoeffs, fftw_complex *fCoeffs, fftw_plan *planForwardFourier, proshade_signed noBins, proshade_signed *binIndexing, proshade_double **bindata, proshade_signed *binCounts)
This function takes the D symmetries and searched for the requested symmetry.
Definition: ProSHADE_data.cpp:2917
ProSHADE_internal_data::ProSHADE_data::mapCOMProcessChangeZ
proshade_double mapCOMProcessChangeZ
The change in Z axis between the creation of the structure (originalMapZCom) and just before rotation...
Definition: ProSHADE_data.hpp:99
ProSHADE_settings::maskingThresholdIQRs
proshade_single maskingThresholdIQRs
Number of inter-quartile ranges from the median to be used for thresholding the blurred map for maski...
Definition: ProSHADE_settings.hpp:79
ProSHADE_settings::usePhase
bool usePhase
If true, the full data will be used, if false, Patterson maps will be used instead and phased data wi...
Definition: ProSHADE_settings.hpp:62
ProSHADE_internal_data::ProSHADE_data::xDimSizeOriginal
proshade_single xDimSizeOriginal
This is the size of the map cell x dimension in Angstroms.
Definition: ProSHADE_data.hpp:82
ProSHADE_settings::allDetectedTAxes
std::vector< proshade_unsign > allDetectedTAxes
The vector of all detected tetrahedral symmetry axes indices in allDetectedCAxes.
Definition: ProSHADE_settings.hpp:147
ProSHADE_internal_messages::printWarningMessage
void printWarningMessage(proshade_signed verbose, std::string message, std::string warnCode)
General stderr message printing (used for warnings).
Definition: ProSHADE_messages.cpp:101
ProSHADE_internal_data::ProSHADE_data::getIntegrationWeight
proshade_double getIntegrationWeight(void)
This function allows access to the integration weight for the object.
Definition: ProSHADE_data.cpp:3791
ProSHADE_internal_io::figureDataType
InputType figureDataType(std::string fName)
Function determining input data type.
Definition: ProSHADE_io.cpp:356
ProSHADE_internal_data::ProSHADE_data::setIntegrationWeightCumul
void setIntegrationWeightCumul(proshade_double intW)
This function allows setting the cumulative integration weight for the object.
Definition: ProSHADE_data.cpp:4111
ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear
void reSampleMapToResolutionTrilinear(proshade_double *&map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single *&corrs)
This function re-samples a map to conform to given resolution using tri-linear interpolation.
Definition: ProSHADE_mapManip.cpp:1175
ProSHADE_internal_data::ProSHADE_data::zAxisOriginOriginal
proshade_signed zAxisOriginOriginal
This is the origin position along the z axis.
Definition: ProSHADE_data.hpp:90
ProSHADE_internal_spheres::ProSHADE_sphere
This class contains all inputed and derived data for a single sphere.
Definition: ProSHADE_spheres.hpp:49
ProSHADE_internal_data::ProSHADE_data::getSymmetryAxis
std::vector< std::string > getSymmetryAxis(ProSHADE_settings *settings, proshade_unsign axisNo)
This function returns a single symmetry axis as a vector of strings from the recommended symmetry axe...
Definition: ProSHADE_data.cpp:4429
ProSHADE_settings::maskFileName
std::string maskFileName
The filename to which mask should be saved.
Definition: ProSHADE_settings.hpp:85
ProSHADE_settings::allDetectedOAxes
std::vector< proshade_unsign > allDetectedOAxes
The vector of all detected octahedral symmetry axes indices in allDetectedCAxes.
Definition: ProSHADE_settings.hpp:148
ProSHADE_internal_data::ProSHADE_data::eMatrices
proshade_complex *** eMatrices
The trace sigma and full rotation function c*conj(c) integral tables.
Definition: ProSHADE_data.hpp:127
ProSHADE_internal_data::ProSHADE_data::centreMapOnCOM
void centreMapOnCOM(ProSHADE_settings *settings)
This function shits the map so that its COM is in the centre of the map.
Definition: ProSHADE_data.cpp:1438
ProSHADE_internal_data::ProSHADE_data::getXFromPtr
proshade_signed * getXFromPtr(void)
This function allows access to the map start along the X axis.
Definition: ProSHADE_data.cpp:3969
ProSHADE_settings::verbose
proshade_signed verbose
Should the software report on the progress, or just be quiet? Value between -1 (nothing) and 4 (loud)
Definition: ProSHADE_settings.hpp:140
ProSHADE_internal_data::ProSHADE_data::yDimIndices
proshade_unsign yDimIndices
This is the size of the map cell y dimension in indices.
Definition: ProSHADE_data.hpp:66
ProSHADE_internal_data::ProSHADE_data::xAxisOriginOriginal
proshade_signed xAxisOriginOriginal
This is the origin position along the x axis.
Definition: ProSHADE_data.hpp:88
ProSHADE_internal_data::ProSHADE_data::deepCopyMap
void deepCopyMap(proshade_double *&saveTo, proshade_signed verbose)
This function copies the internal map into the supplied pointer, which it also allocates.
Definition: ProSHADE_data.cpp:3466
ProSHADE_internal_data::ProSHADE_data::getWignerMatrixValue
void getWignerMatrixValue(proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double *valueReal, proshade_double *valueImag)
This function allows access to the Wigner D matrix by knowing the band, order1 and order2 indices.
Definition: ProSHADE_data.cpp:3894
ProSHADE_internal_data::ProSHADE_data::getShellBandwidth
proshade_unsign getShellBandwidth(proshade_unsign shell)
This function allows access to the bandwidth of a particular shell.
Definition: ProSHADE_data.cpp:3803
ProSHADE_internal_data::ProSHADE_data::yGridIndices
proshade_unsign yGridIndices
As far as I know, this is identical to the yDimIndices.
Definition: ProSHADE_data.hpp:69
ProSHADE_settings::changeMapResolutionTriLinear
bool changeMapResolutionTriLinear
Should maps be re-sampled to obtain the required resolution?
Definition: ProSHADE_settings.hpp:52
ProSHADE_internal_data::ProSHADE_data::zAxisOrigin
proshade_signed zAxisOrigin
This is the origin position along the z axis.
Definition: ProSHADE_data.hpp:76
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_data::ProSHADE_data::getNoRecommendedSymmetryAxes
proshade_unsign getNoRecommendedSymmetryAxes(ProSHADE_settings *settings)
This function returns the number of detected recommended symmetry axes.
Definition: ProSHADE_data.cpp:4417
ProSHADE_internal_data::ProSHADE_data::setPDBMapValues
void setPDBMapValues(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:880
ProSHADE_internal_data::ProSHADE_data::findMapCOM
void findMapCOM(void)
This function finds the centre of mass of the internal map representation.
Definition: ProSHADE_data.cpp:3554
ProSHADE_internal_data::ProSHADE_data::getRealRotFunction
void getRealRotFunction(double *rotFunReal, int len)
This function fills the input array with the real rotation function values.
Definition: ProSHADE_data.cpp:4287
ProSHADE_internal_data::ProSHADE_data::yDimIndicesOriginal
proshade_unsign yDimIndicesOriginal
This is the size of the map cell y dimension in indices.
Definition: ProSHADE_data.hpp:86
ProSHADE_internal_data::ProSHADE_data::getXDim
proshade_unsign getXDim(void)
This function allows access to the map size in indices along the X axis.
Definition: ProSHADE_data.cpp:3939
ProSHADE_internal_mapManip::removeWaters
void removeWaters(gemmi::Structure *pdbFile, bool firstModel)
This function removed all waters from PDB input file.
Definition: ProSHADE_mapManip.cpp:504
ProSHADE_internal_data::ProSHADE_data::originalPdbTransX
proshade_double originalPdbTransX
The optimal translation vector as it relates to the original PDB positions (and not the ProSHADE inte...
Definition: ProSHADE_data.hpp:105
ProSHADE_data.hpp
This is the header file containing internal data representation and manipulation structures and funct...
ProSHADE_internal_data::ProSHADE_data::zTo
proshade_signed zTo
This is the final index along the z axis.
Definition: ProSHADE_data.hpp:115
ProSHADE_internal_data::ProSHADE_data::xTo
proshade_signed xTo
This is the final index along the x axis.
Definition: ProSHADE_data.hpp:113
ProSHADE_internal_data::ProSHADE_data::writeMask
void writeMask(std::string fName, proshade_double *mask)
Function for writing out a mask in MRC MAP format.
Definition: ProSHADE_data.cpp:1064
ProSHADE_internal_data::ProSHADE_data::integrationWeight
proshade_double integrationWeight
The Pearson's c.c. type weighting for the integration.
Definition: ProSHADE_data.hpp:128
ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryC
void saveRequestedSymmetryC(ProSHADE_settings *settings, std::vector< proshade_double * > *CSym, std::vector< proshade_double * > *axes)
This function takes the C symmetries and searched for the requested symmetry.
Definition: ProSHADE_data.cpp:2865
ProSHADE_settings::peakThresholdMin
proshade_double peakThresholdMin
The threshold for peak height above which axes are considered possible.
Definition: ProSHADE_settings.hpp:133
ProSHADE_internal_data::ProSHADE_data::mapToSpheres
void mapToSpheres(ProSHADE_settings *settings)
This function converts the internal map onto a set of concentric spheres.
Definition: ProSHADE_data.cpp:1712
ProSHADE_internal_peakSearch::findPeaks1D
std::vector< proshade_signed > findPeaks1D(std::vector< proshade_double > data)
This function simply finds all the peaks in a 1D data array.
Definition: ProSHADE_peakSearch.cpp:1014
ProSHADE_internal_data::ProSHADE_data::xAxisOrigin
proshade_signed xAxisOrigin
This is the origin position along the x axis.
Definition: ProSHADE_data.hpp:74
ProSHADE_internal_data::ProSHADE_data::originalPdbTransY
proshade_double originalPdbTransY
The optimal translation vector as it relates to the original PDB positions (and not the ProSHADE inte...
Definition: ProSHADE_data.hpp:106
ProSHADE_internal_maths::computeFSC
proshade_double computeFSC(fftw_complex *fCoeffs1, fftw_complex *fCoeffs2, proshade_unsign xInds, proshade_unsign yInds, proshade_unsign zInds, proshade_signed noBins, proshade_signed *binIndexing, proshade_double **&binData, proshade_signed *&binCounts)
This function computes the FSC.
Definition: ProSHADE_maths.cpp:3090
ProSHADE_internal_data::ProSHADE_data::rrpMatrices
proshade_double *** rrpMatrices
The energy levels descriptor shell correlation tables.
Definition: ProSHADE_data.hpp:126
ProSHADE_internal_data::ProSHADE_data::yTo
proshade_signed yTo
This is the final index along the y axis.
Definition: ProSHADE_data.hpp:114
ProSHADE_settings::forceP1
bool forceP1
Should the P1 spacegroup be forced on the input PDB files?
Definition: ProSHADE_settings.hpp:44
ProSHADE_internal_data::ProSHADE_data::xDimSize
proshade_single xDimSize
This is the size of the map cell x dimension in Angstroms.
Definition: ProSHADE_data.hpp:59
ProSHADE_internal_mapManip::findPDBCOMValues
void findPDBCOMValues(gemmi::Structure pdbFile, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, bool firstModel)
This function finds the Centre of Mass for the co-ordinate file.
Definition: ProSHADE_mapManip.cpp:157
ProSHADE_internal_data::ProSHADE_data::mapMovFromsChangeY
proshade_double mapMovFromsChangeY
When the map is translated, the yFrom and yTo values are changed. This variable holds how much they h...
Definition: ProSHADE_data.hpp:95
ProSHADE_internal_data::ProSHADE_data::yAxisOrigin
proshade_signed yAxisOrigin
This is the origin position along the y axis.
Definition: ProSHADE_data.hpp:75
ProSHADE_internal_misc::deepCopyAxisToDblPtrVector
void deepCopyAxisToDblPtrVector(std::vector< proshade_double * > *dblPtrVec, proshade_double *axis)
Does a deep copy of a double array to a vector of double arrays.
Definition: ProSHADE_misc.cpp:310
ProSHADE_settings::task
ProSHADE_Task task
This custom type variable determines which task to perfom (i.e. symmetry detection,...
Definition: ProSHADE_settings.hpp:40
ProSHADE_internal_data::ProSHADE_data::yAxisOrder
proshade_unsign yAxisOrder
This is the order of the y axis.
Definition: ProSHADE_data.hpp:72
ProSHADE_internal_data::ProSHADE_data::getRealSphHarmValue
proshade_double * getRealSphHarmValue(proshade_unsign band, proshade_unsign order, proshade_unsign shell)
This function allows access to the private internal real spherical harmonics values.
Definition: ProSHADE_data.cpp:3754
ProSHADE_internal_data::ProSHADE_data::internalMap
proshade_double * internalMap
The internal map data representation, which may be amended as the run progresses.
Definition: ProSHADE_data.hpp:56
ProSHADE_internal_data::ProSHADE_data::zDimIndicesOriginal
proshade_unsign zDimIndicesOriginal
This is the size of the map cell z dimension in indices.
Definition: ProSHADE_data.hpp:87
ProSHADE_internal_data::ProSHADE_data::reportOverlayResults
void reportOverlayResults(ProSHADE_settings *settings, std::vector< proshade_double > *rotationCentre, std::vector< proshade_double > *eulerAngles, std::vector< proshade_double > *finalTranslation)
This function reports the results of the overlay mode.
Definition: ProSHADE_data.cpp:4522
ProSHADE_internal_symmetry
This namespace contains the symmetry detection related code.
Definition: ProSHADE_data.cpp:75
ProSHADE_internal_data::ProSHADE_data::xFrom
proshade_signed xFrom
This is the starting index along the x axis.
Definition: ProSHADE_data.hpp:110
ProSHADE_internal_maths::getRotationMatrixFromAngleAxis
void getRotationMatrixFromAngleAxis(proshade_double *rotMat, proshade_double x, proshade_double y, proshade_double z, proshade_double ang)
This function converts the axis-angle representation to the rotation matrix representation.
Definition: ProSHADE_maths.cpp:1448
ProSHADE_internal_data::ProSHADE_data::writeMap
void writeMap(std::string fName, std::string title="Created by ProSHADE and written by GEMMI", int mode=2)
Function for writing out the internal structure representation in MRC MAP format.
Definition: ProSHADE_data.cpp:948
ProSHADE_internal_data::ProSHADE_data::shellBandExists
bool shellBandExists(proshade_unsign shell, proshade_unsign bandVal)
This function checks if particular shell has a particular band.
Definition: ProSHADE_data.cpp:3656
ProSHADE_internal_data::ProSHADE_data::getMaxBand
proshade_unsign getMaxBand(void)
This function returns the maximum band value for the object.
Definition: ProSHADE_data.cpp:3630
ProSHADE_settings::appliedMaskFileName
std::string appliedMaskFileName
The filename from which mask data will be read from.
Definition: ProSHADE_settings.hpp:86
ProSHADE_settings::normaliseMap
bool normaliseMap
Should the map be normalised to mean 0 sd 1?
Definition: ProSHADE_settings.hpp:72
ProSHADE_settings::addExtraSpace
proshade_single addExtraSpace
If this value is non-zero, this many angstroms of empty space will be added to the internal map.
Definition: ProSHADE_settings.hpp:99
ProSHADE_internal_data::ProSHADE_data::getYDim
proshade_unsign getYDim(void)
This function allows access to the map size in indices along the Y axis.
Definition: ProSHADE_data.cpp:3949
ProSHADE_internal_data::ProSHADE_data::maxCompBand
proshade_unsign maxCompBand
The largest comparison band - this variable tells how large arrays will be allocated for the comparis...
Definition: ProSHADE_data.hpp:132
ProSHADE_internal_data::ProSHADE_data::getImagEMatrixValuesForLM
void getImagEMatrixValuesForLM(proshade_signed band, proshade_signed order1, double *eMatsLMImag, int len)
This function fills the input array with the imaginary E matrix values for particular band and order1...
Definition: ProSHADE_data.cpp:4218
ProSHADE_internal_data::ProSHADE_data::maskMap
void maskMap(ProSHADE_settings *settings)
Function for computing the map mask using blurring and X IQRs from median.
Definition: ProSHADE_data.cpp:1202
ProSHADE_internal_data::ProSHADE_data::~ProSHADE_data
~ProSHADE_data(void)
Destructor for the ProSHADE_data class.
Definition: ProSHADE_data.cpp:349
ProSHADE_internal_mapManip::getNonZeroBounds
void getNonZeroBounds(proshade_double *map, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_signed *&ret)
Function for finding the map boundaries enclosing positive only values.
Definition: ProSHADE_mapManip.cpp:1082
ProSHADE_settings
This class stores all the settings and is passed to the executive classes instead of a multitude of p...
Definition: ProSHADE_settings.hpp:37
ProSHADE_internal_data::ProSHADE_data::xCom
proshade_double xCom
The COM of the map after processing along the X-axis.
Definition: ProSHADE_data.hpp:77
ProSHADE_internal_data::ProSHADE_data::getRealTranslationFunction
void getRealTranslationFunction(double *trsFunReal, int len)
This function fills the input array with the real translation function values.
Definition: ProSHADE_data.cpp:4323
ProSHADE_settings::fscThreshold
proshade_double fscThreshold
The threshold for FSC value under which the axis is considered to be likely noise.
Definition: ProSHADE_settings.hpp:132
ProSHADE_internal_maths::binReciprocalSpaceReflections
void binReciprocalSpaceReflections(proshade_unsign xInds, proshade_unsign yInds, proshade_unsign zInds, proshade_signed *noBin, proshade_signed *&binIndexing)
This function does binning of the reciprocal space reflections.
Definition: ProSHADE_maths.cpp:2943
ProSHADE_internal_data::ProSHADE_data::getImagSphHarmValue
proshade_double * getImagSphHarmValue(proshade_unsign band, proshade_unsign order, proshade_unsign shell)
This function allows access to the private internal imaginary spherical harmonics values.
Definition: ProSHADE_data.cpp:3767
ProSHADE_internal_data::ProSHADE_data::originalPdbTransZ
proshade_double originalPdbTransZ
The optimal translation vector as it relates to the original PDB positions (and not the ProSHADE inte...
Definition: ProSHADE_data.hpp:107
ProSHADE_internal_data::ProSHADE_data::writeOutOverlayFiles
void writeOutOverlayFiles(ProSHADE_settings *settings, proshade_double eulA, proshade_double eulB, proshade_double eulG, std::vector< proshade_double > *rotCentre, std::vector< proshade_double > *ultimateTranslation)
This function writes out the rotated map, co-ordinates and transformation JSON file.
Definition: ProSHADE_data.cpp:4488
ProSHADE_internal_data::ProSHADE_data::getImagRotFunction
void getImagRotFunction(double *rotFunImag, int len)
This function fills the input array with the imaginary rotation function values.
Definition: ProSHADE_data.cpp:4305
ProSHADE_internal_data::ProSHADE_data::processInternalMap
void processInternalMap(ProSHADE_settings *settings)
This function simply clusters several other functions which should be called together.
Definition: ProSHADE_data.cpp:1612
ProSHADE_internal_io::readInMapData
void readInMapData(gemmi::Ccp4< float > *gemmiMap, proshade_double *&map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder)
This function converts the gemmi Ccp4 object data to ProSHADE internal map representation.
Definition: ProSHADE_io.cpp:178
ProSHADE_internal_data::ProSHADE_data::getTranslationFnPointer
proshade_complex * getTranslationFnPointer(void)
This function allows access to the translation function through a pointer.
Definition: ProSHADE_data.cpp:4069
ProSHADE_settings::setRecommendedSymmetry
void setRecommendedSymmetry(std::string val)
Sets the ProSHADE detected symmetry type.
Definition: ProSHADE.cpp:1210
ProSHADE_internal_data::ProSHADE_data::zCom
proshade_double zCom
The COM of the map after processing along the Z-axis.
Definition: ProSHADE_data.hpp:79
ProSHADE_internal_data::ProSHADE_data::spherePos
std::vector< proshade_single > spherePos
Vector of sphere radii from the centre of the map.
Definition: ProSHADE_data.hpp:118
ProSHADE_settings::invertMap
bool invertMap
Should the map be inverted? Only use this if you think you have the wrong hand in your map.
Definition: ProSHADE_settings.hpp:75
ProSHADE_internal_maths::smoothen1D
std::vector< proshade_double > smoothen1D(proshade_double step, proshade_signed windowSize, proshade_double sigma, std::vector< proshade_double > data)
This function takes a 1D vector and computes smoothened version based on the parameters.
Definition: ProSHADE_maths.cpp:2873
ProSHADE_internal_data::ProSHADE_data::getZDim
proshade_unsign getZDim(void)
This function allows access to the map size in indices along the Z axis.
Definition: ProSHADE_data.cpp:3959
ProSHADE_internal_mapManip::removeMapPhase
void removeMapPhase(fftw_complex *&mapCoeffs, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim)
This function removes the phase from reciprocal (frequency) map.
Definition: ProSHADE_mapManip.cpp:1631
ProSHADE_settings::boundsSimilarityThreshold
proshade_signed boundsSimilarityThreshold
Number of indices which can be added just to make sure same size in indices is achieved.
Definition: ProSHADE_settings.hpp:91
ProSHADE_internal_data::ProSHADE_data::getSpherePosValue
proshade_single getSpherePosValue(proshade_unsign shell)
This function allows access to sphere positions.
Definition: ProSHADE_data.cpp:3815
ProSHADE_internal_data::ProSHADE_data::writePdb
void writePdb(std::string fName, proshade_double euA=0.0, proshade_double euB=0.0, proshade_double euG=0.0, proshade_double trsX=0.0, proshade_double trsY=0.0, proshade_double trsZ=0.0, bool firstModel=true)
This function writes out the PDB formatted file coresponding to the structure so that its COM is at s...
Definition: ProSHADE_data.cpp:1013
ProSHADE_settings::changeMapResolution
bool changeMapResolution
Should maps be re-sampled to obtain the required resolution?
Definition: ProSHADE_settings.hpp:51
ProSHADE_internal_data::ProSHADE_data::getRRPValue
proshade_double getRRPValue(proshade_unsign band, proshade_unsign sh1, proshade_unsign sh2)
This function allows access to the priva internal RRP matrices.
Definition: ProSHADE_data.cpp:3640
ProSHADE_internal_io::writeRotationTranslationJSON
void writeRotationTranslationJSON(proshade_double trsX1, proshade_double trsY1, proshade_double trsZ1, proshade_double eulA, proshade_double eulB, proshade_double eulG, proshade_double trsX2, proshade_double trsY2, proshade_double trsZ2, std::string fileName)
Function for writing out the optimal rotation and translation into a JSON file.
Definition: ProSHADE_io.cpp:398
ProSHADE_internal_data::ProSHADE_data::mapMovFromsChangeZ
proshade_double mapMovFromsChangeZ
When the map is translated, the zFrom and zTo values are changed. This variable holds how much they h...
Definition: ProSHADE_data.hpp:96
axesToGroupTypeSanityCheck
void axesToGroupTypeSanityCheck(proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType)
This function checks that the required and obtained numbers of axes are correct, printing error if th...
Definition: ProSHADE_data.cpp:3044
ProSHADE_settings::overlayStructureName
std::string overlayStructureName
The filename to which the rotated and translated moving structure is to be saved.
Definition: ProSHADE_settings.hpp:136
ProSHADE_internal_maths::isAxisUnique
bool isAxisUnique(std::vector< proshade_double * > *CSymList, proshade_double *axis, proshade_double tolerance=0.1, bool improve=false)
This function checks if new axis is unique, or already detected.
Definition: ProSHADE_maths.cpp:2721
ProSHADE_internal_data::ProSHADE_data::getMapValue
proshade_double getMapValue(proshade_unsign pos)
This function returns the internal map representation value of a particular array position.
Definition: ProSHADE_data.cpp:3620
ProSHADE_internal_data::ProSHADE_data::getImagSO3Coeffs
void getImagSO3Coeffs(double *so3CoefsImag, int len)
This function fills the input array with the imaginary SO(3) coefficient values.
Definition: ProSHADE_data.cpp:4254
ProSHADE_internal_data::ProSHADE_data::getYToPtr
proshade_signed * getYToPtr(void)
This function allows access to the map last position along the Y axis.
Definition: ProSHADE_data.cpp:4009
ProSHADE_settings::moveToCOM
bool moveToCOM
Logical value stating whether the structure should be moved to have its Centre Of Mass (COM) in the m...
Definition: ProSHADE_settings.hpp:96
ProSHADE_internal_data::ProSHADE_data::readInMAP
void readInMAP(ProSHADE_settings *settings)
Function for reading map data using gemmi library.
Definition: ProSHADE_data.cpp:554
ProSHADE_internal_data::ProSHADE_data::wignerMatrices
proshade_complex *** wignerMatrices
These matrices are computed for a particular rotation to be done in spherical harmonics.
Definition: ProSHADE_data.hpp:131
ProSHADE_internal_data::ProSHADE_data::detectSymmetryInStructure
void detectSymmetryInStructure(ProSHADE_settings *settings, std::vector< proshade_double * > *axes, std::vector< std::vector< proshade_double > > *allCs)
This function runs the symmetry detection algorithms on this structure and saves the results in the s...
Definition: ProSHADE_data.cpp:1801
ProSHADE_internal_data::ProSHADE_data::fileType
ProSHADE_internal_io::InputType fileType
This is the type of the input file.
Definition: ProSHADE_data.hpp:53
ProSHADE_internal_data::ProSHADE_data::getZAxisOrigin
proshade_signed * getZAxisOrigin(void)
This function allows access to the map Z axis origin value.
Definition: ProSHADE_data.cpp:4049
ProSHADE_internal_io::writeOutMapHeader
void writeOutMapHeader(gemmi::Ccp4< float > *map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_single xDim, proshade_single yDim, proshade_single zDim, proshade_single aAng, proshade_single bAng, proshade_single cAng, proshade_signed xFrom, proshade_signed yFrom, proshade_signed zFrom, proshade_signed xAxOrigin, proshade_signed yAxOrigin, proshade_signed zAxOrigin, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder, proshade_unsign xGridInds, proshade_unsign yGridInds, proshade_unsign zGridInds, std::string title, int mode)
This function parses the CCP4 MAP file header as read in by gemmi.
Definition: ProSHADE_io.cpp:306
ProSHADE_internal_mapManip::myRound
proshade_signed myRound(proshade_double x)
Calls the appropriate version of round function depending on compiler version.
Definition: ProSHADE_mapManip.cpp:31
ProSHADE_internal_data::ProSHADE_data::yDimSizeOriginal
proshade_single yDimSizeOriginal
This is the size of the map cell y dimension in Angstroms.
Definition: ProSHADE_data.hpp:83
ProSHADE_internal_data::ProSHADE_data::zAxisOrder
proshade_unsign zAxisOrder
This is the order of the z axis.
Definition: ProSHADE_data.hpp:73
ProSHADE_internal_mapManip::beautifyBoundaries
void beautifyBoundaries(proshade_signed *&bounds, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_signed boundsDiffThres)
Function for modifying boundaries to a mathematically more pleasant values.
Definition: ProSHADE_mapManip.cpp:1916
ProSHADE_internal_data::ProSHADE_data::reSampleMap
void reSampleMap(ProSHADE_settings *settings)
This function changes the internal map sampling to conform to particular resolution value.
Definition: ProSHADE_data.cpp:1366
ProSHADE_internal_mapManip::rotatePDBCoordinates
void rotatePDBCoordinates(gemmi::Structure *pdbFile, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double xCom, proshade_double yCom, proshade_double zCom, bool firstModel)
Function for rotating the PDB file co-ordinates by Euler angles.
Definition: ProSHADE_mapManip.cpp:296
ProSHADE_internal_mapManip::generateMapFromPDB
void generateMapFromPDB(gemmi::Structure pdbFile, proshade_double *&map, proshade_single requestedResolution, proshade_single xCell, proshade_single yCell, proshade_single zCell, proshade_signed *xTo, proshade_signed *yTo, proshade_signed *zTo, bool forceP1, bool firstModel)
This function generates a theoretical map from co-ordinate input files.
Definition: ProSHADE_mapManip.cpp:644
ProSHADE_internal_maths::rotationMatrixSimilarity
bool rotationMatrixSimilarity(std::vector< proshade_double > *mat1, std::vector< proshade_double > *mat2, proshade_double tolerance=0.1)
This function compares the distance between two rotation matrices and decides if they are similar usi...
Definition: ProSHADE_maths.cpp:2299
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:67
ProSHADE_internal_data::ProSHADE_data::getXToPtr
proshade_signed * getXToPtr(void)
This function allows access to the map last position along the X axis.
Definition: ProSHADE_data.cpp:3999
ProSHADE_internal_data::ProSHADE_data::getYFromPtr
proshade_signed * getYFromPtr(void)
This function allows access to the map start along the Y axis.
Definition: ProSHADE_data.cpp:3979
ProSHADE_internal_mapManip::translatePDBCoordinates
void translatePDBCoordinates(gemmi::Structure *pdbFile, proshade_double transX, proshade_double transY, proshade_double transZ, bool firstModel)
Function for translating the PDB file co-ordinates by given distances in Angstroms.
Definition: ProSHADE_mapManip.cpp:381
ProSHADE_internal_data::ProSHADE_data::mapCOMProcessChangeY
proshade_double mapCOMProcessChangeY
The change in Y axis between the creation of the structure (originalMapYCom) and just before rotation...
Definition: ProSHADE_data.hpp:98
ProSHADE_internal_data::ProSHADE_data::bAngle
proshade_single bAngle
This is the angle b of the map cell in degrees.
Definition: ProSHADE_data.hpp:63
ProSHADE_internal_maths::getEulerZXZFromSOFTPosition
void getEulerZXZFromSOFTPosition(proshade_signed band, proshade_signed x, proshade_signed y, proshade_signed z, proshade_double *eulerAlpha, proshade_double *eulerBeta, proshade_double *eulerGamma)
Function to find Euler angles (ZXZ convention) from index position in the inverse SOFT map.
Definition: ProSHADE_maths.cpp:963
ProSHADE_internal_data::ProSHADE_data::yAxisOriginOriginal
proshade_signed yAxisOriginOriginal
This is the origin position along the y axis.
Definition: ProSHADE_data.hpp:89
ProSHADE_internal_data::ProSHADE_data::aAngle
proshade_single aAngle
This is the angle a of the map cell in degrees.
Definition: ProSHADE_data.hpp:62
ProSHADE_internal_misc::addToDoubleVectorVector
void addToDoubleVectorVector(std::vector< std::vector< proshade_double > > *vecToAddTo, std::vector< proshade_double > elementToAdd)
Adds the element to the vector of vectors.
Definition: ProSHADE_misc.cpp:233
ProSHADE_internal_data::ProSHADE_data::reportSymmetryResults
void reportSymmetryResults(ProSHADE_settings *settings)
This function takes prints the report for symmetry detection.
Definition: ProSHADE_data.cpp:3498
ProSHADE_internal_data::ProSHADE_data::figureIndexStartStop
void figureIndexStartStop(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:926
ProSHADE_internal_data::ProSHADE_data::isEmpty
bool isEmpty
This variable stated whether the class contains any information.
Definition: ProSHADE_data.hpp:139
ProSHADE_internal_data::ProSHADE_data::getInvSO3Coeffs
proshade_complex * getInvSO3Coeffs(void)
This function allows access to the inverse SO(3) coefficients array.
Definition: ProSHADE_data.cpp:3857
ProSHADE_settings::allDetectedIAxes
std::vector< proshade_unsign > allDetectedIAxes
The vector of all detected icosahedral symmetry axes indices in allDetectedCAxes.
Definition: ProSHADE_settings.hpp:149
ProSHADE_settings::forceBounds
proshade_signed * forceBounds
These will be the boundaries to be forced upon the map.
Definition: ProSHADE_settings.hpp:93
ProSHADE_settings::detectedSymmetry
std::vector< proshade_double * > detectedSymmetry
The vector of detected symmetry axes.
Definition: ProSHADE_settings.hpp:144
ProSHADE_internal_data::ProSHADE_data::yFrom
proshade_signed yFrom
This is the starting index along the y axis.
Definition: ProSHADE_data.hpp:111
ProSHADE_settings::recommendedSymmetryFold
proshade_unsign recommendedSymmetryFold
The fold of the recommended symmetry C or D type, 0 otherwise.
Definition: ProSHADE_settings.hpp:126
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_mapManip::reSampleMapToResolutionFourier
void reSampleMapToResolutionFourier(proshade_double *&map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single *&corrs)
This function re-samples a map to conform to given resolution using Fourier.
Definition: ProSHADE_mapManip.cpp:1376
ProSHADE_internal_mapManip::copyMapByBounds
void copyMapByBounds(proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo, proshade_signed origXFrom, proshade_signed origYFrom, proshade_signed origZFrom, proshade_unsign yDimIndices, proshade_unsign zDimIndices, proshade_unsign origXDimIndices, proshade_unsign origYDimIndices, proshade_unsign origZDimIndices, proshade_double *&newMap, proshade_double *origMap)
This function copies an old map to a new map with different boundaries.
Definition: ProSHADE_mapManip.cpp:2082
ProSHADE_internal_data::ProSHADE_data::getYAxisOrigin
proshade_signed * getYAxisOrigin(void)
This function allows access to the map Y axis origin value.
Definition: ProSHADE_data.cpp:4039
ProSHADE_internal_data::ProSHADE_data::originalPdbRotCenZ
proshade_double originalPdbRotCenZ
The centre of rotation as it relates to the original PDB positions (and not the ProSHADE internal map...
Definition: ProSHADE_data.hpp:104
ProSHADE_internal_misc::addToSingleVector
void addToSingleVector(std::vector< proshade_single > *vecToAddTo, proshade_single elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:55
ProSHADE_internal_data::ProSHADE_data::ProSHADE_data
ProSHADE_data()
Constructor for getting empty ProSHADE_data class.
Definition: ProSHADE_data.cpp:93
ProSHADE_settings::firstModelOnly
bool firstModelOnly
Shoud only the first PDB model be used, or should all models be used?
Definition: ProSHADE_settings.hpp:46
sortProSHADESymmetryByFSC
bool sortProSHADESymmetryByFSC(proshade_double *a, proshade_double *b)
This function allows using std::sort to sort vectors of ProSHADE symmetry format.
Definition: ProSHADE_data.cpp:1914
ProSHADE_settings::axisErrTolerance
proshade_double axisErrTolerance
Allowed error on vector axis in in dot product ( acos ( 1 - axErr ) is the allowed difference in radi...
Definition: ProSHADE_settings.hpp:122
ProSHADE_settings::useSameBounds
bool useSameBounds
Switch to say that the same boundaries as used for the first should be used for all input maps.
Definition: ProSHADE_settings.hpp:92
ProSHADE_internal_data::ProSHADE_data::zDimIndices
proshade_unsign zDimIndices
This is the size of the map cell z dimension in indices.
Definition: ProSHADE_data.hpp:67
ProSHADE_internal_data::computeGroupElementsForGroup
std::vector< std::vector< proshade_double > > computeGroupElementsForGroup(proshade_double xAx, proshade_double yAx, proshade_double zAx, proshade_signed fold)
This function computes the group elements as rotation matrices (except for the identity element) for ...
Definition: ProSHADE_data.cpp:2980
ProSHADE_settings::pdbBFactorNewVal
proshade_double pdbBFactorNewVal
Change all PDB B-factors to this value (for smooth maps).
Definition: ProSHADE_settings.hpp:55
ProSHADE_internal_data::ProSHADE_data::getRecommendedSymmetryType
std::string getRecommendedSymmetryType(ProSHADE_settings *settings)
This function simply returns the detected recommended symmetry type.
Definition: ProSHADE_data.cpp:4394
ProSHADE_internal_data::ProSHADE_data::zGridIndices
proshade_unsign zGridIndices
As far as I know, this is identical to the zDimIndices.
Definition: ProSHADE_data.hpp:70
ProSHADE_settings::setRecommendedFold
void setRecommendedFold(proshade_unsign val)
Sets the ProSHADE detected symmetry fold.
Definition: ProSHADE.cpp:1233
ProSHADE_settings::setVariablesLeftOnAuto
void setVariablesLeftOnAuto(void)
Function to determine general values that the user left on auto-determination.
Definition: ProSHADE.cpp:333
ProSHADE_internal_data::ProSHADE_data::setEMatrixValue
void setEMatrixValue(proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_complex val)
This function allows setting the E matrix value.
Definition: ProSHADE_data.cpp:4128
ProSHADE_settings::removeWaters
bool removeWaters
Should all waters be removed from input PDB files?
Definition: ProSHADE_settings.hpp:45
ProSHADE_internal_data::ProSHADE_data::spheres
ProSHADE_internal_spheres::ProSHADE_sphere ** spheres
The set of concentric spheres to which the intermal density map has been projected.
Definition: ProSHADE_data.hpp:120
ProSHADE_internal_data::ProSHADE_data::normaliseMap
void normaliseMap(ProSHADE_settings *settings)
Function for normalising the map values to mean 0 and sd 1..
Definition: ProSHADE_data.cpp:1155
ProSHADE_internal_data::ProSHADE_data::detectSymmetryFromAngleAxisSpace
void detectSymmetryFromAngleAxisSpace(ProSHADE_settings *settings, std::vector< proshade_double * > *axes, std::vector< std::vector< proshade_double > > *allCs)
This function runs the symmetry detection algorithms on this structure using the angle-axis space and...
Definition: ProSHADE_data.cpp:1934
ProSHADE_internal_data::ProSHADE_data::originalPdbRotCenX
proshade_double originalPdbRotCenX
The centre of rotation as it relates to the original PDB positions (and not the ProSHADE internal map...
Definition: ProSHADE_data.hpp:102
ProSHADE_internal_data::ProSHADE_data::originalMapZCom
proshade_double originalMapZCom
The COM of the first map to be loaded/computed without any furhter changes being reflacted along the ...
Definition: ProSHADE_data.hpp:93
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_data::ProSHADE_data::getRealSO3Coeffs
void getRealSO3Coeffs(double *so3CoefsReal, int len)
This function fills the input array with the real SO(3) coefficient values.
Definition: ProSHADE_data.cpp:4236
ProSHADE_internal_data::ProSHADE_data::yDimSize
proshade_single yDimSize
This is the size of the map cell y dimension in Angstroms.
Definition: ProSHADE_data.hpp:60
ProSHADE_settings::setResolution
void setResolution(proshade_single resolution)
Sets the requested resolution in the appropriate variable.
Definition: ProSHADE.cpp:382
ProSHADE_settings::allDetectedCAxes
std::vector< std::vector< proshade_double > > allDetectedCAxes
The vector of all detected cyclic symmetry axes.
Definition: ProSHADE_settings.hpp:145
ProSHADE_internal_data::ProSHADE_data::removePhaseInormation
void removePhaseInormation(ProSHADE_settings *settings)
This function removes phase from the map, effectively converting it to Patterson map.
Definition: ProSHADE_data.cpp:3676
ProSHADE_internal_mapManip::moveMapByIndices
void moveMapByIndices(proshade_single *xMov, proshade_single *yMov, proshade_single *zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed *xFrom, proshade_signed *xTo, proshade_signed *yFrom, proshade_signed *yTo, proshade_signed *zFrom, proshade_signed *zTo, proshade_signed *xOrigin, proshade_signed *yOrigin, proshade_signed *zOrigin)
Function for moving map back to original PDB location by changing the indices.
Definition: ProSHADE_mapManip.cpp:763
ProSHADE_internal_io::readInMapHeader
void readInMapHeader(gemmi::Ccp4< float > *map, proshade_unsign *xDimInds, proshade_unsign *yDimInds, proshade_unsign *zDimInds, proshade_single *xDim, proshade_single *yDim, proshade_single *zDim, proshade_single *aAng, proshade_single *bAng, proshade_single *cAng, proshade_signed *xFrom, proshade_signed *yFrom, proshade_signed *zFrom, proshade_signed *xAxOrigin, proshade_signed *yAxOrigin, proshade_signed *zAxOrigin, proshade_unsign *xAxOrder, proshade_unsign *yAxOrder, proshade_unsign *zAxOrder, proshade_unsign *xGridInds, proshade_unsign *yGridInds, proshade_unsign *zGridInds)
This function parses the CCP4 MAP file header as read in by gemmi.
Definition: ProSHADE_io.cpp:109
ProSHADE_internal_maths::multiplyGroupElementMatrices
std::vector< proshade_double > multiplyGroupElementMatrices(std::vector< proshade_double > *el1, std::vector< proshade_double > *el2)
This function computes matrix multiplication using the ProSHADE group element matrix format as input ...
Definition: ProSHADE_maths.cpp:2245
ProSHADE_internal_data::ProSHADE_data::readInStructure
void readInStructure(std::string fName, proshade_unsign inputO, ProSHADE_settings *settings)
This function initialises the basic ProSHADE_data variables and reads in a single structure.
Definition: ProSHADE_data.cpp:501
ProSHADE_internal_data::ProSHADE_data::getAllGroupElements
std::vector< std::vector< proshade_double > > getAllGroupElements(ProSHADE_settings *settings, std::vector< proshade_unsign > axesList, std::string groupType="", proshade_double matrixTolerance=0.05)
This function returns the group elements as rotation matrices of any defined point group.
Definition: ProSHADE_data.cpp:3199
ProSHADE_internal_data::ProSHADE_data::addExtraSpace
void addExtraSpace(ProSHADE_settings *settings)
This function increases the size of the map so that it can add empty space around it.
Definition: ProSHADE_data.cpp:1503
ProSHADE_internal_data::ProSHADE_data::getRealEMatrixValuesForLM
void getRealEMatrixValuesForLM(proshade_signed band, proshade_signed order1, double *eMatsLMReal, int len)
This function fills the input array with the real E matrix values for particular band and order1 (l a...
Definition: ProSHADE_data.cpp:4198
ProSHADE_internal_misc::addToStringVector
void addToStringVector(std::vector< std::string > *vecToAddTo, std::string elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:33
ProSHADE_internal_sphericalHarmonics::computeSphericalHarmonics
void computeSphericalHarmonics(proshade_unsign band, proshade_double *sphereMappedData, proshade_complex *&shArray)
This function computes the spherical harmonics of a aingle shell, saving them in supplied pointer.
Definition: ProSHADE_sphericalHarmonics.cpp:394
checkElementAlreadyExists
bool checkElementAlreadyExists(std::vector< std::vector< proshade_double > > *elements, std::vector< proshade_double > *elem, proshade_double matrixTolerance)
This function checks if the element list already contains a given matrix.
Definition: ProSHADE_data.cpp:3066
ProSHADE_internal_data::ProSHADE_data::readInPDB
void readInPDB(ProSHADE_settings *settings)
Function for reading pdb data.
Definition: ProSHADE_data.cpp:725
ProSHADE_internal_data::ProSHADE_data::getZFromPtr
proshade_signed * getZFromPtr(void)
This function allows access to the map start along the Z axis.
Definition: ProSHADE_data.cpp:3989
ProSHADE_internal_data::ProSHADE_data::getZToPtr
proshade_signed * getZToPtr(void)
This function allows access to the map last position along the Z axis.
Definition: ProSHADE_data.cpp:4019
ProSHADE_internal_data::ProSHADE_data::so3CoeffsArrayIndex
int so3CoeffsArrayIndex(proshade_signed order1, proshade_signed order2, proshade_signed band)
This function gets the SO(3) coefficients array index for a particular so(3) band,...
Definition: ProSHADE_data.cpp:4276