ProSHADE  0.7.6.2 (DEC 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 
509 void ProSHADE_internal_data::ProSHADE_data::readInStructure ( std::string fName, proshade_unsign inputO, ProSHADE_settings* settings, proshade_double* maskArr, proshade_unsign maskXDim, proshade_unsign maskYDim, proshade_unsign maskZDim, proshade_double* weightsArr, proshade_unsign weigXDim, proshade_unsign weigYDim, proshade_unsign weigZDim )
510 {
511  //================================================ Report function start
512  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting to read the structure: " + fName, settings->messageShift );
513 
514  //================================================ Check if instance is empty
515  if ( !this->isEmpty )
516  {
517  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 );
518  }
519 
520  //================================================ Save the filename
521  this->fileName = fName;
522 
523  //================================================ Check what is the input format
524  this->fileType = ProSHADE_internal_io::figureDataType ( this->fileName );
525 
526  //================================================ Save input order
527  this->inputOrder = inputO;
528 
529  //================================================ Decide how to proceed
530  switch ( this->fileType )
531  {
532  case ProSHADE_internal_io::UNKNOWN:
533  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." );
534 
535  case ProSHADE_internal_io::GEMMI:
536  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." );
537 
538  case ProSHADE_internal_io::PDB:
539  this->readInPDB ( settings );
540  break;
541 
542  case ProSHADE_internal_io::MAP:
543  this->readInMAP ( settings, maskArr, maskXDim, maskYDim, maskZDim, weightsArr, weigXDim, weigYDim, weigZDim );
544  break;
545  }
546 
547  //================================================ This structure is now full
548  this->isEmpty = false;
549 
550  //================================================ Report function completion
551  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Structure read in successfully.", settings->messageShift );
552 
553  //================================================ Done
554  return ;
555 
556 }
557 
567 void ProSHADE_internal_data::ProSHADE_data::readInStructure ( gemmi::Structure gemmiStruct, proshade_unsign inputO, ProSHADE_settings* settings )
568 {
569  //================================================ Report function start
570  std::stringstream ss;
571  ss << "Starting to load the structure from Gemmi object " << inputO;
572  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
573 
574  //================================================ Check if instance is empty
575  if ( !this->isEmpty )
576  {
577  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 );
578  }
579 
580  //================================================ Save the filename
581  this->fileName = gemmiStruct.name;
582 
583  //================================================ Check what is the input format
584  this->fileType = ProSHADE_internal_io::GEMMI;
585 
586  //================================================ Save input order
587  this->inputOrder = inputO;
588 
589  //================================================ Decide how to proceed
590  this->readInGemmi ( gemmiStruct, settings );
591 
592  //================================================ This structure is now full
593  this->isEmpty = false;
594 
595  //================================================ Report function completion
596  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Structure read in successfully.", settings->messageShift );
597 
598  //================================================ Done
599  return ;
600 
601 }
602 
619 void ProSHADE_internal_data::ProSHADE_data::readInMAP ( ProSHADE_settings* settings, proshade_double* maskArr, proshade_unsign maskXDim, proshade_unsign maskYDim, proshade_unsign maskZDim, proshade_double* weightsArr, proshade_unsign weigXDim, proshade_unsign weigYDim, proshade_unsign weigZDim )
620 {
621  //================================================ Open the file
622  gemmi::Ccp4<float> map;
623  map.read_ccp4 ( gemmi::MaybeGzipped ( this->fileName.c_str() ) );
624 
625  //================================================ Convert to XYZ and create complete map, if need be
626  map.setup ( gemmi::GridSetup::ReorderOnly, NAN );
627 
628  //================================================ Read in the rest of the map file header
630  &this->xDimIndices, &this->yDimIndices, &this->zDimIndices,
631  &this->xDimSize, &this->yDimSize, &this->zDimSize,
632  &this->aAngle, &this->bAngle, &this->cAngle,
633  &this->xFrom, &this->yFrom, &this->zFrom,
634  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin,
635  &this->xAxisOrder, &this->yAxisOrder, &this->zAxisOrder,
636  &this->xGridIndices, &this->yGridIndices, &this->zGridIndices );
637 
638  //================================================ Save the map density to ProSHADE variable
639  ProSHADE_internal_io::readInMapData ( &map, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, this->xAxisOrder, this->yAxisOrder, this->zAxisOrder );
640 
641  //================================================ If mask is supplied and the correct task is used
642  ProSHADE_internal_io::applyMask ( this->internalMap, settings->appliedMaskFileName, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->verbose, settings->messageShift,
643  maskArr, maskXDim, maskYDim, maskZDim );
644 
645  //================================================ Apply Fourier weights
646  ProSHADE_internal_io::applyWeights ( this->internalMap, settings->fourierWeightsFileName, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->verbose, settings->messageShift,
647  weightsArr, weigXDim, weigYDim, weigZDim );
648 
649  //================================================ Remove negative values if so required
650  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; } } }
651 
652  //================================================ Set resolution if need be
653  if ( settings->requestedResolution < 0.0f )
654  {
655  settings->setResolution ( std::min ( static_cast<proshade_single> ( this->xDimSize ) / static_cast<proshade_single> ( this->xDimIndices ),
656  std::min ( static_cast<proshade_single> ( this->yDimSize ) / static_cast<proshade_single> ( this->yDimIndices ),
657  static_cast<proshade_single> ( this->zDimSize ) / static_cast<proshade_single> ( this->zDimIndices ) ) ) * 2.0f );
658  }
659 
660  //================================================ Set iterators from and to
661  this->figureIndexStartStop ( );
662 
663  //================================================ If specific resolution is requested, make sure the map has it
664  this->reSampleMap ( settings );
665 
666  //================================================ Save the original sizes
667  this->xDimSizeOriginal = this->xDimSize;
668  this->yDimSizeOriginal = this->yDimSize;
669  this->zDimSizeOriginal = this->zDimSize;
670 
671  //================================================ Save the original index counts
672  this->xDimIndicesOriginal = this->xDimIndices;
673  this->yDimIndicesOriginal = this->yDimIndices;
674  this->zDimIndicesOriginal = this->zDimIndices;
675 
676  //================================================ Save the original axis origins
677  this->xAxisOriginOriginal = this->xAxisOrigin;
678  this->yAxisOriginOriginal = this->yAxisOrigin;
679  this->zAxisOriginOriginal = this->zAxisOrigin;
680 
681  //================================================ Compute and save the COM
682  this->findMapCOM ( );
683  this->originalMapXCom = this->xCom;
684  this->originalMapYCom = this->yCom;
685  this->originalMapZCom = this->zCom;
686 
687  //================================================ Done
688 
689 }
690 
701 {
702  //================================================ Set resolution if need be
703  if ( settings->requestedResolution < 0.0f )
704  {
705  settings->setResolution ( 8.0 );
706  }
707 
708  //================================================ Open PDB file for reading
709  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
710 
711  //================================================ Once we have Gemmi object, run the Gemmi function
712  this->readInGemmi ( pdbFile, settings );
713 
714  //================================================ Done
715  return;
716 
717 }
718 
735 void ProSHADE_internal_data::ProSHADE_data::readInGemmi ( gemmi::Structure gemmiStruct, ProSHADE_settings* settings )
736 {
737  //================================================ Set resolution if need be
738  if ( settings->requestedResolution < 0.0f )
739  {
740  settings->setResolution ( 8.0 );
741  }
742 
743  //================================================ Change B-factors if need be
744  if ( settings->pdbBFactorNewVal >= 0.0 )
745  {
747  }
748 
749  //================================================ Remove waters if required
750  if ( settings->removeWaters )
751  {
752  ProSHADE_internal_mapManip::removeWaters ( &gemmiStruct, settings->firstModelOnly );
753  }
754 
755  //================================================ Get PDB COM values
756  proshade_double xCOMPdb, yCOMPdb, zCOMPdb;
757  ProSHADE_internal_mapManip::findPDBCOMValues ( gemmiStruct, &xCOMPdb, &yCOMPdb, &zCOMPdb, settings->firstModelOnly );
758 
759  //================================================ Find the ranges
760  proshade_single xF = 0.0f, xT = 0.0f, yF = 0.0f, yT = 0.0f, zF = 0.0f, zT = 0.0f;
761  ProSHADE_internal_mapManip::determinePDBRanges ( gemmiStruct, &xF, &xT, &yF, &yT, &zF, &zT, settings->firstModelOnly );
762 
763  //================================================ Move ranges to have all FROM values 20
764  proshade_single xMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - xF );
765  proshade_single yMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - yF );
766  proshade_single zMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - zF );
767  ProSHADE_internal_mapManip::movePDBForMapCalc ( &gemmiStruct, xMov, yMov, zMov, settings->firstModelOnly );
768 
769  //================================================ Set the angstrom sizes
770  this->xDimSize = static_cast< proshade_single > ( xT - xF + ( 2.0f * settings->coOrdsExtraSpace ) );
771  this->yDimSize = static_cast< proshade_single > ( yT - yF + ( 2.0f * settings->coOrdsExtraSpace ) );
772  this->zDimSize = static_cast< proshade_single > ( zT - zF + ( 2.0f * settings->coOrdsExtraSpace ) );
773 
774  //================================================ Generate map from nicely placed atoms (cell size will be range + 40)
775  ProSHADE_internal_mapManip::generateMapFromPDB ( gemmiStruct, this->internalMap, settings->requestedResolution, this->xDimSize, this->yDimSize, this->zDimSize, &this->xTo, &this->yTo, &this->zTo, settings->forceP1, settings->firstModelOnly );
776 
777  //================================================ Remove negative values if so required
778  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; } } }
779 
780  //================================================ Set the internal variables to correct values
781  this->setPDBMapValues ( );
782 
783  //================================================ Move map back to the original PDB location
784  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize,
785  &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
786  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
787  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
788  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ),
789  static_cast< proshade_signed > ( this->zDimIndices ) );
790 
791  //================================================ If specific resolution is requested, make sure the map has it
792  this->reSampleMap ( settings );
793 
794  //================================================ Save the original sizes
795  this->xDimSizeOriginal = this->xDimSize;
796  this->yDimSizeOriginal = this->yDimSize;
797  this->zDimSizeOriginal = this->zDimSize;
798 
799  //================================================ Save the original index counts
800  this->xDimIndicesOriginal = this->xDimIndices;
801  this->yDimIndicesOriginal = this->yDimIndices;
802  this->zDimIndicesOriginal = this->zDimIndices;
803 
804  //================================================ Save the original axis origins
805  this->xAxisOriginOriginal = this->xAxisOrigin;
806  this->yAxisOriginOriginal = this->yAxisOrigin;
807  this->zAxisOriginOriginal = this->zAxisOrigin;
808 
809  //================================================ Compute and save the COM
810  this->findMapCOM ( );
811  this->originalMapXCom = this->xCom;
812  this->originalMapYCom = this->yCom;
813  this->originalMapZCom = this->zCom;
814 
815  //================================================ Done
816  return;
817 
818 }
819 
825 {
826  //================================================ Set starts to 0
827  this->xFrom = 0;
828  this->yFrom = 0;
829  this->zFrom = 0;
830 
831  //================================================ Set angles to 90 degrees
832  this->aAngle = 90.0;
833  this->bAngle = 90.0;
834  this->cAngle = 90.0;
835 
836  //================================================ Set dimension sizes in indices
837  this->xDimIndices = static_cast< proshade_unsign > ( this->xTo );
838  this->yDimIndices = static_cast< proshade_unsign > ( this->yTo );
839  this->zDimIndices = static_cast< proshade_unsign > ( this->zTo );
840 
841  //================================================ Set the to indices properly
842  this->xTo -= 1;
843  this->yTo -= 1;
844  this->zTo -= 1;
845 
846  //================================================ Set grid indexing to cell indexing
847  this->xGridIndices = this->xDimIndices;
848  this->yGridIndices = this->yDimIndices;
849  this->zGridIndices = this->zDimIndices;
850 
851  //================================================ Set axis order
852  this->xAxisOrder = 1;
853  this->yAxisOrder = 2;
854  this->zAxisOrder = 3;
855 
856  //================================================ Set origin to the first index
857  this->xAxisOrigin = this->xFrom;
858  this->yAxisOrigin = this->yFrom;
859  this->zAxisOrigin = this->zFrom;
860 
861  //================================================ Done
862  return ;
863 
864 }
865 
871 {
872  //================================================ Set ends to origin + size - 1
873  this->xTo = this->xFrom + static_cast< proshade_signed > ( this->xDimIndices ) - 1;
874  this->yTo = this->yFrom + static_cast< proshade_signed > ( this->yDimIndices ) - 1;
875  this->zTo = this->zFrom + static_cast< proshade_signed > ( this->zDimIndices ) - 1;
876 
877  //================================================ Done
878  return ;
879 
880 }
881 
892 void ProSHADE_internal_data::ProSHADE_data::writeMap ( std::string fName, std::string title, int mode )
893 {
894  //================================================ Create and prepare new Grid gemmi object
895  gemmi::Grid<float> mapData;
896  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 ) );
897  mapData.set_size_without_checking ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ) );
898  mapData.axis_order = gemmi::AxisOrder::XYZ;
899  mapData.spacegroup = &gemmi::get_spacegroup_p1();
900 
901  //================================================ Create and prepare new Ccp4 gemmi object
902  gemmi::Ccp4<float> map;
903  map.grid = mapData;
904  map.update_ccp4_header ( mode );
905 
906  //================================================ Fill in the header
908  this->xDimIndices, this->yDimIndices, this->zDimIndices,
909  this->xDimSize, this->yDimSize, this->zDimSize,
910  this->aAngle, this->bAngle, this->cAngle,
911  this->xFrom, this->yFrom, this->zFrom,
912  this->xAxisOrigin, this->yAxisOrigin, this->zAxisOrigin,
913  this->xAxisOrder, this->yAxisOrder, this->zAxisOrder,
914  this->xGridIndices, this->yGridIndices, this->zGridIndices,
915  title, mode );
916 
917  //================================================ Copy internal map to grid
918  proshade_unsign arrPos = 0;
919  for ( proshade_unsign uIt = 0; uIt < this->xDimIndices; uIt++ )
920  {
921  for ( proshade_unsign vIt = 0; vIt < this->yDimIndices; vIt++ )
922  {
923  for ( proshade_unsign wIt = 0; wIt < this->zDimIndices; wIt++ )
924  {
925  arrPos = wIt + this->zDimIndices * ( vIt + this->yDimIndices * uIt );
926  map.grid.set_value ( static_cast< int > ( uIt ), static_cast< int > ( vIt ), static_cast< int > ( wIt ), static_cast<float> ( this->internalMap[arrPos] ) );
927  }
928  }
929  }
930 
931  //================================================ Update the statistics in the header
932  map.update_ccp4_header ( mode, true );
933 
934  //================================================ Write out the map
935  map.write_ccp4_map ( fName );
936 
937  //================================================ Done
938  return ;
939 
940 }
941 
959 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, proshade_double rotX, proshade_double rotY, proshade_double rotZ, bool firstModel )
960 {
961  //================================================ Check for co-ordinate origin
962  if ( !ProSHADE_internal_io::isFilePDB ( this->fileName ) )
963  {
964  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." );
965  }
966 
967  //================================================ Open PDB file for reading
968  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
969 
970  //================================================ Write out using the gemmi::Structure object
971  this->writeGemmi ( fName, pdbFile, euA, euB, euG, trsX, trsY, trsZ, rotX, rotY, rotZ, firstModel );
972 
973  //================================================ Done
974  return ;
975 }
976 
996 void ProSHADE_internal_data::ProSHADE_data::writeGemmi ( std::string fName, gemmi::Structure gemmiStruct, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double trsX, proshade_double trsY, proshade_double trsZ, proshade_double rotX, proshade_double rotY, proshade_double rotZ, bool firstModel )
997 {
998  //================================================ If the map was rotated, do the same for the co-ordinates, making sure we take into account the rotation centre of the map
999  if ( ( euA != 0.0 ) || ( euB != 0.0 ) || ( euG != 0.0 ) )
1000  {
1001  //============================================ Rotate the co-ordinates
1002  ProSHADE_internal_mapManip::rotatePDBCoordinates ( &gemmiStruct, euA, euB, euG, rotX, rotY, rotZ, firstModel );
1003  }
1004 
1005  //================================================ Translate by required translation and the map centering (if applied)
1006  ProSHADE_internal_mapManip::translatePDBCoordinates ( &gemmiStruct, trsX, trsY, trsZ, firstModel );
1007 
1008  //================================================ Write the PDB file
1009  std::ofstream outCoOrdFile;
1010  outCoOrdFile.open ( fName.c_str() );
1011 
1012  if ( outCoOrdFile.is_open() )
1013  {
1014  gemmi::PdbWriteOptions opt;
1015  write_pdb ( gemmiStruct, outCoOrdFile, opt );
1016  }
1017  else
1018  {
1019  std::stringstream hlpMessage;
1020  hlpMessage << "Failed to open the PDB file " << fName << " for output.";
1021  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." );
1022  }
1023 
1024  outCoOrdFile.close ( );
1025 
1026  //================================================ Done
1027  return ;
1028 }
1029 
1038 void ProSHADE_internal_data::ProSHADE_data::writeMask ( std::string fName, proshade_double* mask )
1039 {
1040  //================================================ Allocate the memory
1041  proshade_double* hlpMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1042  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1043 
1044  //================================================ Copy original map and over-write with the mask
1045  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1046  {
1047  hlpMap[iter] = this->internalMap[iter];
1048  this->internalMap[iter] = mask[iter];
1049  }
1050 
1051  //================================================ Write out the mask
1052  this->writeMap ( fName );
1053 
1054  //================================================ Copy the original map values back
1055  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1056  {
1057  this->internalMap[iter] = hlpMap[iter];
1058  }
1059 
1060  //================================================ Release memory
1061  delete[] hlpMap;
1062 
1063  //================================================ Done
1064  return ;
1065 
1066 }
1067 
1076 {
1077  //================================================ Report function start
1078  std::stringstream ss;
1079  ss << "Moving map box centre to " << settings->boxCentre.at(0) << "; " << settings->boxCentre.at(1) << "; " << settings->boxCentre.at(2) << " .";
1080  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
1081 
1082  //================================================ Figure sampling rates
1083  proshade_double xSamplingRate = static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices );
1084  proshade_double ySamplingRate = static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices );
1085  proshade_double zSamplingRate = static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices );
1086 
1087  //================================================ Figure the box centre
1088  proshade_double startCentreX = ( ( ( static_cast<proshade_double> ( this->xTo ) - static_cast<proshade_double> ( this->xFrom ) ) / 2.0 ) * xSamplingRate );
1089  proshade_double startCentreY = ( ( ( static_cast<proshade_double> ( this->yTo ) - static_cast<proshade_double> ( this->yFrom ) ) / 2.0 ) * ySamplingRate );
1090  proshade_double startCentreZ = ( ( ( static_cast<proshade_double> ( this->zTo ) - static_cast<proshade_double> ( this->zFrom ) ) / 2.0 ) * zSamplingRate );
1091 
1092  //================================================ Figure the requested point distance from box start
1093  proshade_double boxStartX = settings->boxCentre.at(0) - ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate );
1094  proshade_double boxStartY = settings->boxCentre.at(1) - ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate );
1095  proshade_double boxStartZ = settings->boxCentre.at(2) - ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate );
1096 
1097  //================================================ Figure the shift
1098  proshade_double xShift = startCentreX - boxStartX;
1099  proshade_double yShift = startCentreY - boxStartY;
1100  proshade_double zShift = startCentreZ - boxStartZ;
1101 
1102  //================================================ If requested point outside of map, complain
1103  if ( ( ( settings->boxCentre.at(0) < ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate ) ) ||
1104  ( settings->boxCentre.at(0) > ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate + static_cast<proshade_double> ( this->xDimSize ) ) ) ) ||
1105  ( ( settings->boxCentre.at(1) < ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate ) ) ||
1106  ( settings->boxCentre.at(1) > ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate + static_cast<proshade_double> ( this->yDimSize ) ) ) ) ||
1107  ( ( settings->boxCentre.at(2) < ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate ) ) ||
1108  ( settings->boxCentre.at(2) > ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate + static_cast<proshade_double> ( this->zDimSize ) ) ) ) )
1109  {
1110  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested box centre to be co-ordinate position outside of co-ordinates range. Please re-view the requested box centre position.", "WM00068" );
1111  }
1112 
1113  //================================================ Do the shift
1115  static_cast< proshade_single > ( xShift ),
1116  static_cast< proshade_single > ( yShift ),
1117  static_cast< proshade_single > ( zShift ),
1118  this->xDimSize, this->yDimSize, this->zDimSize,
1119  static_cast< proshade_signed > ( this->xDimIndices ),
1120  static_cast< proshade_signed > ( this->yDimIndices ),
1121  static_cast< proshade_signed > ( this->zDimIndices ) );
1122 
1123  //================================================ Report function completion
1124  std::stringstream ss2;
1125  ss2 << "Position " << settings->boxCentre.at(0) << "; " << settings->boxCentre.at(1) << "; " << settings->boxCentre.at(2) << " set at the centre of the map box.";
1126  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss2.str(), settings->messageShift );
1127 
1128  //================================================ Done
1129  return ;
1130 
1131 }
1132 
1141 {
1142  //================================================ Report function start
1143  std::stringstream ss;
1144  ss << "Shifting map rotation centre ( " << settings->centrePosition.at(0) << "; " << settings->centrePosition.at(1) << "; " << settings->centrePosition.at(2) << " ) to the centre of the box.";
1145  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
1146 
1147  //================================================ Do the shift
1149  static_cast< proshade_single > ( -settings->centrePosition.at(0) ),
1150  static_cast< proshade_single > ( -settings->centrePosition.at(1) ),
1151  static_cast< proshade_single > ( -settings->centrePosition.at(2) ),
1152  this->xDimSize, this->yDimSize, this->zDimSize,
1153  static_cast< proshade_signed > ( this->xDimIndices ),
1154  static_cast< proshade_signed > ( this->yDimIndices ),
1155  static_cast< proshade_signed > ( this->zDimIndices ) );
1156 
1157  //================================================ Report function completion
1158  std::stringstream ss2;
1159  ss2 << "Map shifted by " << settings->centrePosition.at(0) << "; " << settings->centrePosition.at(1) << "; " << settings->centrePosition.at(2) << " A.";
1160  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss2.str(), settings->messageShift );
1161 
1162  //================================================ Done
1163  return ;
1164 
1165 }
1166 
1176 {
1177  //================================================ Report function start
1178  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion.", settings->messageShift );
1179 
1180  //================================================ Initialise variables
1181  proshade_signed arrayPos, invPos;
1182 
1183  //================================================ Create helper map
1184  proshade_double* hlpMap = new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
1185  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1186 
1187  //================================================ Save map values to the helper map
1188  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1189  {
1190  hlpMap[iter] = this->internalMap[iter];
1191  }
1192 
1193  //================================================ Invert the values
1194  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
1195  {
1196  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
1197  {
1198  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
1199  {
1200  //==================================== Var init
1201  arrayPos = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
1202  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 ) );
1203 
1204  //==================================== And save
1205  this->internalMap[invPos] = hlpMap[arrayPos];
1206  }
1207  }
1208  }
1209 
1210  //================================================ Release memory
1211  delete[] hlpMap;
1212 
1213  //================================================ Report function completion
1214  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map inversion completed.", settings->messageShift );
1215 
1216  //================================================ Done
1217  return ;
1218 
1219 }
1220 
1230 {
1231  //================================================ Report function start
1232  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation.", settings->messageShift );
1233 
1234  //================================================ Initialise vector of map values
1235  std::vector<proshade_double> mapVals ( this->xDimIndices * this->yDimIndices * this->zDimIndices, 0.0 );
1236 
1237  //================================================ Get all map values
1238  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1239  {
1240  mapVals.at(iter) = this->internalMap[iter];
1241  }
1242 
1243  //================================================ Get mean and sd
1244  proshade_double* meanSD = new proshade_double[2];
1245  ProSHADE_internal_maths::vectorMeanAndSD ( &mapVals, meanSD );
1246 
1247  //================================================ Normalise the values
1248  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1249  {
1250  this->internalMap[iter] = ( this->internalMap[iter] - meanSD[0] ) / meanSD[1];
1251  }
1252 
1253  //================================================ Clear the vector
1254  mapVals.clear ( );
1255 
1256  //================================================ Release memory
1257  delete[] meanSD;
1258 
1259  //================================================ Report function completion
1260  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map normalisation completed.", settings->messageShift );
1261 
1262  //================================================ Done
1263  return ;
1264 
1265 }
1266 
1267 
1277 {
1278  //================================================ Report function start
1279  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Computing mask.", settings->messageShift );
1280 
1281  //================================================ Initialise the blurred map
1282  proshade_double* blurredMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1283  ProSHADE_internal_misc::checkMemoryAllocation ( blurredMap, __FILE__, __LINE__, __func__ );
1284 
1285  //================================================ Compute blurred map
1286  ProSHADE_internal_mapManip::blurSharpenMap ( this->internalMap, blurredMap, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1287  this->xDimSize, this->yDimSize, this->zDimSize, settings->blurFactor );
1288 
1289  //================================================ Compute mask from blurred map and save it into the original map
1290  ProSHADE_internal_mapManip::getMaskFromBlurr ( blurredMap, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->maskingThresholdIQRs );
1291 
1292  //================================================ Print the mask if need be
1293  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 ); } }
1294 
1295  //================================================ Release memory
1296  delete[] blurredMap;
1297 
1298  //================================================ Report function completion
1299  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Mask computed.", settings->messageShift );
1300 
1301  //================================================ Done
1302  return ;
1303 
1304 }
1305 
1317 {
1318  //================================================ Report function start
1319  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Finding new boundaries.", settings->messageShift );
1320 
1321  //================================================ If same bounds as first one are required, test if possible and return these instead
1322  if ( settings->useSameBounds && ( this->inputOrder != 0 ) )
1323  {
1324  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { ret[iter] = settings->forceBounds[iter]; }
1325  }
1326  //================================================ In this case, bounds need to be found de novo
1327  else
1328  {
1329  //============================================ Find the non-zero bounds
1331  static_cast< proshade_signed > ( this->xDimIndices ),
1332  static_cast< proshade_signed > ( this->yDimIndices ),
1333  static_cast< proshade_signed > ( this->zDimIndices ),
1334  ret );
1335 
1336  //============================================ Add the extra space
1337  ProSHADE_internal_mapManip::addExtraBoundSpace ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1338  this->xDimSize, this->yDimSize, this->zDimSize, ret, settings->boundsExtraSpace );
1339 
1340  //============================================ Beautify boundaries
1341  ProSHADE_internal_mapManip::beautifyBoundaries ( ret, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->boundsSimilarityThreshold );
1342 
1343  //============================================ Report function results
1344  std::stringstream ssHlp;
1345  ssHlp << "New boundaries are: " << ret[1] - ret[0] + 1 << " x " << ret[3] - ret[2] + 1 << " x " << ret[5] - ret[4] + 1;
1346  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, ssHlp.str(), settings->messageShift );
1347 
1348  //============================================ If need be, save boundaries to be used for all other structure
1349  if ( settings->useSameBounds && ( this->inputOrder == 0 ) )
1350  {
1351  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { settings->forceBounds[iter] = ret[iter]; }
1352  }
1353  }
1354 
1355  //================================================ Report function completion
1356  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New boundaries determined.", settings->messageShift );
1357 
1358  //================================================ Done
1359  return ;
1360 
1361 }
1362 
1375 {
1376  //================================================ Report function start
1377  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Creating new structure according to the new bounds.", settings->messageShift );
1378 
1379  //================================================ Fill in basic info
1380  newStr->fileName = "N/A";
1381  newStr->fileType = ProSHADE_internal_io::MAP;
1382 
1383  //================================================ Fill in new structure values
1384  newStr->xDimIndices = static_cast< proshade_unsign > ( newBounds[1] ) - static_cast< proshade_unsign > ( newBounds[0] ) + 1;
1385  newStr->yDimIndices = static_cast< proshade_unsign > ( newBounds[3] ) - static_cast< proshade_unsign > ( newBounds[2] ) + 1;
1386  newStr->zDimIndices = static_cast< proshade_unsign > ( newBounds[5] ) - static_cast< proshade_unsign > ( newBounds[4] ) + 1;
1387 
1388  newStr->aAngle = this->aAngle;
1389  newStr->bAngle = this->aAngle;
1390  newStr->cAngle = this->aAngle;
1391 
1392  newStr->xDimSize = static_cast<proshade_single> ( newStr->xDimIndices ) * ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) );
1393  newStr->yDimSize = static_cast<proshade_single> ( newStr->yDimIndices ) * ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) );
1394  newStr->zDimSize = static_cast<proshade_single> ( newStr->zDimIndices ) * ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) );
1395 
1396  newStr->xGridIndices = newStr->xDimIndices;
1397  newStr->yGridIndices = newStr->yDimIndices;
1398  newStr->zGridIndices = newStr->zDimIndices;
1399 
1400  newStr->xAxisOrder = this->xAxisOrder;
1401  newStr->yAxisOrder = this->yAxisOrder;
1402  newStr->zAxisOrder = this->zAxisOrder;
1403 
1404  newStr->xAxisOrigin = this->xAxisOrigin + newBounds[0];
1405  newStr->yAxisOrigin = this->yAxisOrigin + newBounds[2];
1406  newStr->zAxisOrigin = this->zAxisOrigin + newBounds[4];
1407 
1408  newStr->xFrom = this->xFrom + newBounds[0];
1409  newStr->yFrom = this->yFrom + newBounds[2];
1410  newStr->zFrom = this->zFrom + newBounds[4];
1411 
1412  newStr->xTo = this->xTo - ( static_cast< proshade_signed > ( this->xDimIndices - 1 ) - newBounds[1] );
1413  newStr->yTo = this->yTo - ( static_cast< proshade_signed > ( this->yDimIndices - 1 ) - newBounds[3] );
1414  newStr->zTo = this->zTo - ( static_cast< proshade_signed > ( this->zDimIndices - 1 ) - newBounds[5] );
1415 
1416  //================================================ Allocate new structure map
1417  newStr->internalMap = new proshade_double[newStr->xDimIndices * newStr->yDimIndices * newStr->zDimIndices];
1418  ProSHADE_internal_misc::checkMemoryAllocation ( newStr->internalMap, __FILE__, __LINE__, __func__ );
1419 
1420  //================================================ Copy the map
1421  ProSHADE_internal_mapManip::copyMapByBounds ( newStr->xFrom, newStr->xTo, newStr->yFrom, newStr->yTo, newStr->zFrom, newStr->zTo,
1422  this->xFrom, this->yFrom, this->zFrom, newStr->yDimIndices, newStr->zDimIndices,
1423  this->xDimIndices, this->yDimIndices, this->zDimIndices, newStr->internalMap, this->internalMap );
1424 
1425  //================================================ Report function completion
1426  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New structure created.", settings->messageShift );
1427 
1428  //================================================ Done
1429  return ;
1430 
1431 }
1432 
1441 {
1442  //================================================ Sanity check
1443  if ( !settings->changeMapResolution && !settings->changeMapResolutionTriLinear ) { return ; }
1444 
1445  //================================================ Initialise the internal variable
1446  proshade_single* changeVals = new proshade_single[6];
1447 
1448  //================================================ Find COM before map re-sampling
1449  proshade_double xMapCOMPreReSampl = 0.0, yMapCOMPreReSampl = 0.0, zMapCOMPreReSampl = 0.0;
1450  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 );
1451 
1452  //================================================ Now re-sample the map
1453  if ( settings->changeMapResolution )
1454  {
1455  ProSHADE_internal_mapManip::reSampleMapToResolutionFourier ( this->internalMap, settings->requestedResolution, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1456  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1457 
1458  if ( settings->changeMapResolutionTriLinear )
1459  {
1460  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" );
1461  }
1462  }
1463  if ( settings->changeMapResolutionTriLinear && !settings->changeMapResolution )
1464  {
1465  ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear ( this->internalMap, settings->requestedResolution, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1466  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1467 
1468  }
1469 
1470  //================================================ Set the internal values to reflect the new map size
1471  this->xDimIndices += static_cast<proshade_unsign> ( changeVals[0] );
1472  this->yDimIndices += static_cast<proshade_unsign> ( changeVals[1] );
1473  this->zDimIndices += static_cast<proshade_unsign> ( changeVals[2] );
1474 
1475  this->xGridIndices = this->xDimIndices;
1476  this->yGridIndices = this->yDimIndices;
1477  this->zGridIndices = this->zDimIndices;
1478 
1479  this->xTo += static_cast<proshade_unsign> ( changeVals[0] );
1480  this->yTo += static_cast<proshade_unsign> ( changeVals[1] );
1481  this->zTo += static_cast<proshade_unsign> ( changeVals[2] );
1482 
1483  this->xDimSize = changeVals[3];
1484  this->yDimSize = changeVals[4];
1485  this->zDimSize = changeVals[5];
1486 
1487  //================================================ Find COM after map re-sampling and corner move
1488  proshade_double xMapCOMPostReSampl = 0.0, yMapCOMPostReSampl = 0.0, zMapCOMPostReSampl = 0.0;
1489  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 );
1490 
1491  //================================================ Figure how much the new map moved
1492  proshade_single xMov = static_cast< proshade_single > ( xMapCOMPostReSampl - xMapCOMPreReSampl );
1493  proshade_single yMov = static_cast< proshade_single > ( yMapCOMPostReSampl - yMapCOMPreReSampl );
1494  proshade_single zMov = static_cast< proshade_single > ( zMapCOMPostReSampl - zMapCOMPreReSampl );
1495 
1496  //================================================ Move by indices (this should be sufficient)
1497  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize, &this->xFrom, &this->xTo,
1498  &this->yFrom, &this->yTo, &this->zFrom, &this->zTo, &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
1499 
1500  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
1501  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ) );
1502 
1503  //================================================ Release memory
1504  delete[] changeVals;
1505 
1506  //================================================ Done
1507  return ;
1508 
1509 }
1510 
1521 {
1522  //================================================ Report function start
1523  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Centering map onto its COM.", settings->messageShift );
1524 
1525  //================================================ Initialise local variables
1526  proshade_double xCOM = 0.0;
1527  proshade_double yCOM = 0.0;
1528  proshade_double zCOM = 0.0;
1529 
1530  //================================================ Find the COM location
1531  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xCOM, &yCOM, &zCOM,
1532  this->xDimSize, this->yDimSize, this->xDimSize, this->xFrom,
1533  this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo );
1534 
1535  //================================================ Find the sampling rates
1536  proshade_single xSampRate = static_cast< proshade_single > ( this->xDimSize ) / static_cast< proshade_single > ( this->xTo - this->xFrom );
1537  proshade_single ySampRate = static_cast< proshade_single > ( this->yDimSize ) / static_cast< proshade_single > ( this->yTo - this->yFrom );
1538  proshade_single zSampRate = static_cast< proshade_single > ( this->zDimSize ) / static_cast< proshade_single > ( this->zTo - this->zFrom );
1539 
1540  //================================================ Convert to position in indices starting from 0
1541  xCOM /= static_cast< proshade_double > ( xSampRate );
1542  yCOM /= static_cast< proshade_double > ( ySampRate );
1543  zCOM /= static_cast< proshade_double > ( zSampRate );
1544 
1545  xCOM -= static_cast< proshade_double > ( this->xFrom );
1546  yCOM -= static_cast< proshade_double > ( this->yFrom );
1547  zCOM -= static_cast< proshade_double > ( this->zFrom );
1548 
1549  //================================================ Find distance from COM to map centre in Angstroms
1550  proshade_double xDist = ( ( static_cast<proshade_double> ( this->xDimIndices ) / 2.0 ) - xCOM ) * static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices );
1551  proshade_double yDist = ( ( static_cast<proshade_double> ( this->yDimIndices ) / 2.0 ) - yCOM ) * static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices );
1552  proshade_double zDist = ( ( static_cast<proshade_double> ( this->zDimIndices ) / 2.0 ) - zCOM ) * static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices );
1553 
1554  //================================================ Move the map within the box
1556  static_cast< proshade_single > ( xDist ),
1557  static_cast< proshade_single > ( yDist ),
1558  static_cast< proshade_single > ( zDist ),
1559  this->xDimSize, this->yDimSize, this->zDimSize,
1560  static_cast< proshade_signed > ( this->xDimIndices ),
1561  static_cast< proshade_signed > ( this->yDimIndices ),
1562  static_cast< proshade_signed > ( this->zDimIndices ) );
1563 
1564  //================================================ Note the change due to centering
1565  this->mapCOMProcessChangeX -= xDist;
1566  this->mapCOMProcessChangeY -= yDist;
1567  this->mapCOMProcessChangeZ -= zDist;
1568 
1569  //================================================ Report function completion
1570  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map centered.", settings->messageShift );
1571 
1572  //================================================ Done
1573  return ;
1574 
1575 }
1576 
1586 {
1587  //================================================ Report function start
1588  std::stringstream hlpSS;
1589  hlpSS << "Adding extra " << settings->addExtraSpace << " angstroms.";
1590  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str(), settings->messageShift );
1591 
1592  //================================================ Figure how much indices need to change
1593  proshade_unsign xAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) ) ) );
1594  proshade_unsign yAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) ) ) );
1595  proshade_unsign zAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) ) ) );
1596 
1597  //================================================ Update internal data variables
1598  this->xDimSize += 2 * static_cast<proshade_single> ( xAddIndices ) * this->xDimSize / static_cast<proshade_single> ( this->xDimIndices );
1599  this->yDimSize += 2 * static_cast<proshade_single> ( yAddIndices ) * this->yDimSize / static_cast<proshade_single> ( this->yDimIndices );
1600  this->zDimSize += 2 * static_cast<proshade_single> ( zAddIndices ) * this->zDimSize / static_cast<proshade_single> ( this->zDimIndices );
1601 
1602  this->xDimIndices += 2 * xAddIndices;
1603  this->yDimIndices += 2 * yAddIndices;
1604  this->zDimIndices += 2 * zAddIndices;
1605 
1606  this->xGridIndices = this->xDimIndices;
1607  this->yGridIndices = this->yDimIndices;
1608  this->zGridIndices = this->zDimIndices;
1609 
1610  this->xAxisOrigin -= xAddIndices;
1611  this->yAxisOrigin -= yAddIndices;
1612  this->zAxisOrigin -= zAddIndices;
1613 
1614  this->xFrom -= xAddIndices;
1615  this->yFrom -= yAddIndices;
1616  this->zFrom -= zAddIndices;
1617 
1618  this->xTo += xAddIndices;
1619  this->yTo += yAddIndices;
1620  this->zTo += zAddIndices;
1621 
1622  //================================================ Allocate new map
1623  proshade_double* newMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1624  ProSHADE_internal_misc::checkMemoryAllocation ( newMap, __FILE__, __LINE__, __func__ );
1625 
1626  //================================================ Set new map to zeroes
1627  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1628  {
1629  newMap[iter] = 0.0;
1630  }
1631 
1632  //================================================ Update the map
1633  proshade_unsign newMapIndex, oldMapIndex;
1634  for ( proshade_unsign xIt = 0; xIt < (this->xDimIndices - xAddIndices); xIt++ )
1635  {
1636  //============================================ Check if point is applicable
1637  if ( xIt < xAddIndices ) { continue; }
1638 
1639  for ( proshade_unsign yIt = 0; yIt < (this->yDimIndices - yAddIndices); yIt++ )
1640  {
1641  //======================================== Check if point is applicable
1642  if ( yIt < yAddIndices ) { continue; }
1643 
1644  for ( proshade_unsign zIt = 0; zIt < (this->zDimIndices - zAddIndices); zIt++ )
1645  {
1646  //==================================== Check if point is applicable
1647  if ( zIt < zAddIndices ) { continue; }
1648 
1649  //==================================== Var init
1650  newMapIndex = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
1651  oldMapIndex = (zIt - zAddIndices) + (this->zDimIndices - ( 2 * zAddIndices ) ) * ( (yIt - yAddIndices) + (this->yDimIndices - ( 2 * yAddIndices ) ) * (xIt - xAddIndices) );
1652 
1653  newMap[newMapIndex] = this->internalMap[oldMapIndex];
1654  }
1655  }
1656  }
1657 
1658  //================================================ Copy new to old
1659  delete[] this->internalMap;
1660 
1661  this->internalMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1662  ProSHADE_internal_misc::checkMemoryAllocation ( this->internalMap, __FILE__, __LINE__, __func__ );
1663 
1664  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1665  {
1666  this->internalMap[iter] = newMap[iter];
1667  }
1668 
1669  //================================================ Release memory
1670  delete[] newMap;
1671 
1672  //================================================ Report function completion
1673  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Extra space added.", settings->messageShift );
1674 
1675  //================================================ Done
1676  return ;
1677 
1678 }
1679 
1696 {
1697  //================================================ Move given point to box centre
1698  if ( !( ( std::isinf ( settings->boxCentre.at(0) ) ) || ( std::isinf ( settings->boxCentre.at(1) ) ) || ( std::isinf ( settings->boxCentre.at(2) ) ) ) ) { this->shiftToBoxCentre ( settings ); }
1699  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map left at original position.", settings->messageShift ); }
1700 
1701  //================================================ Shift map to centre of rotation if so required
1702  if ( !( ( std::isinf ( settings->centrePosition.at(0) ) ) || ( std::isinf ( settings->centrePosition.at(1) ) ) || ( std::isinf ( settings->centrePosition.at(2) ) ) ) ) { this->shiftToRotationCentre ( settings ); }
1703  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map rotation centre not shifted.", settings->messageShift ); }
1704 
1705  //================================================ Invert map
1706  if ( settings->invertMap ) { this->invertMirrorMap ( settings ); }
1707  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion (mirror image) not requested.", settings->messageShift ); }
1708 
1709  //================================================ Normalise map
1710  if ( settings->normaliseMap ) { this->normaliseMap ( settings ); }
1711  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation not requested.", settings->messageShift ); }
1712 
1713  //================================================ Compute mask
1714  if ( settings->maskMap ) { this->maskMap ( settings ); }
1715  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Masking not requested.", settings->messageShift ); }
1716 
1717  //================================================ Centre map
1718  if ( settings->moveToCOM ) { this->centreMapOnCOM ( settings ); }
1719  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map centering not requested.", settings->messageShift ); }
1720 
1721  //================================================ Remove phase, if required
1722  if ( !settings->usePhase ) { this->removePhaseInormation ( settings ); ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information removed from the data.", settings->messageShift ); }
1723  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information retained in the data.", settings->messageShift ); }
1724 
1725  //================================================ Add extra space
1726  if ( settings->addExtraSpace != 0.0f ) { this->addExtraSpace ( settings ); }
1727  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Extra space not requested.", settings->messageShift ); }
1728 
1729  //================================================ Set settings values which were left on AUTO by user and will not be set later
1730  settings->setVariablesLeftOnAuto ( );
1731 
1732  //================================================ Done
1733  return ;
1734 
1735 }
1736 
1747 {
1748  //================================================ Check the current settings value is set to auto
1749  if ( this->spherePos.size() != 0 )
1750  {
1751  std::stringstream hlpSS;
1752  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1753  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1754  hlpSS << " Angstroms.";
1755  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str(), settings->messageShift );
1756  return ;
1757  }
1758 
1759  //================================================ Find maximum diagonal
1760  proshade_unsign maxDim = static_cast< proshade_unsign > ( std::max ( this->xDimSize, std::max ( this->yDimSize, this->zDimSize ) ) );
1761  proshade_unsign minDim = static_cast< proshade_unsign > ( std::min ( this->xDimSize, std::min ( this->yDimSize, this->zDimSize ) ) );
1762  proshade_unsign midDim = static_cast< proshade_unsign > ( 0 );
1763  if ( ( this->xDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->xDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->xDimSize ); }
1764  else if ( ( this->yDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->yDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->yDimSize ); }
1765  else { midDim = static_cast< proshade_unsign > ( this->zDimSize ); }
1766 
1767  proshade_single maxDiag = static_cast< proshade_single > ( std::sqrt ( std::pow ( static_cast<proshade_single> ( maxDim ), 2.0 ) +
1768  std::pow ( static_cast<proshade_single> ( midDim ), 2.0 ) ) );
1769 
1770  //================================================ Set between the points
1771  for ( proshade_single iter = 0.5f; ( iter * settings->maxSphereDists ) < ( maxDiag / 2.0f ); iter += 1.0f )
1772  {
1773  ProSHADE_internal_misc::addToSingleVector ( &this->spherePos, ( iter * settings->maxSphereDists ) );
1774  }
1775 
1776  //================================================ Save the number of spheres
1777  this->noSpheres = static_cast<proshade_unsign> ( this->spherePos.size() );
1778 
1779  //================================================ Report progress
1780  std::stringstream hlpSS;
1781  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1782  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1783  hlpSS << " Angstroms.";
1784  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str(), settings->messageShift );
1785 
1786  //================================================ Done
1787  return ;
1788 
1789 }
1790 
1791 
1804 {
1805  //================================================ Report progress
1806  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting sphere mapping procedure.", settings->messageShift );
1807 
1808  //================================================ Determine spherical harmonics variables
1809  settings->determineAllSHValues ( this->xDimIndices, this->yDimIndices,
1810  this->xDimSize, this->yDimSize, this->zDimSize );
1811  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere settings determined.", settings->messageShift );
1812 
1813  //================================================ Find number of spheres supported
1814  this->getSpherePositions ( settings );
1815  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere positions obtained.", settings->messageShift );
1816 
1817  //================================================ Create sphere objects and map the density
1818  this->spheres = new ProSHADE_internal_spheres::ProSHADE_sphere* [ this->noSpheres ];
1819  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ )
1820  {
1821  std::stringstream ss;
1822  ss << "Now mapping sphere " << iter << " .";
1823  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str(), settings->messageShift );
1824 
1825  this->spheres[iter] = new ProSHADE_internal_spheres::ProSHADE_sphere ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1826  this->xDimSize, this->yDimSize, this->zDimSize, iter,
1827  &this->spherePos, settings->progressiveSphereMapping, settings->maxBandwidth,
1828  this->internalMap, &this->maxShellBand );
1829  }
1830 
1831  //================================================ Report completion
1832  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere mapping procedure completed.", settings->messageShift );
1833 
1834  //================================================ Done
1835  return ;
1836 
1837 }
1838 
1848 {
1849  //================================================ Report progress
1850  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting spherical harmonics decomposition.", settings->messageShift );
1851 
1852  //================================================ Initialise memory
1853  this->sphericalHarmonics = new proshade_complex* [this->noSpheres];
1854  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics, __FILE__, __LINE__, __func__ );
1855  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1856  {
1857  this->sphericalHarmonics[iter] = new proshade_complex [(this->spheres[iter]->getLocalBandwidth() * 2) * (this->spheres[iter]->getLocalBandwidth() * 2)];
1858  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics[iter], __FILE__, __LINE__, __func__ );
1859  }
1860 
1861  //================================================ Compute the spherical harmonics
1862  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1863  {
1864  //============================================ Report progress
1865  std::stringstream ss;
1866  ss << "Now decomposing sphere " << iter << ". " << "( Band is: " << this->spheres[iter]->getLocalBandwidth() << ").";
1867  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str(), settings->messageShift );
1868 
1869  //============================================ Compute
1870  ProSHADE_internal_sphericalHarmonics::computeSphericalHarmonics ( this->spheres[iter]->getLocalBandwidth(), this->spheres[iter]->getMappedData(), this->sphericalHarmonics[iter] );
1871  }
1872 
1873  //================================================ Report completion
1874  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Spherical harmonics decomposition complete.", settings->messageShift );
1875 
1876  //======================================== Done
1877  return ;
1878 
1879 }
1880 
1887 bool sortProSHADESymmetryByFSC ( proshade_double* a, proshade_double* b)
1888 {
1889  //================================================ Done
1890  return ( a[6] > b[6] );
1891 
1892 }
1893 
1907 void ProSHADE_internal_data::ProSHADE_data::detectSymmetryFromAngleAxisSpace ( ProSHADE_settings* settings, std::vector< proshade_double* >* axes, std::vector < std::vector< proshade_double > >* allCs )
1908 {
1909  //================================================ Modify axis tolerance and matrix tolerance by sampling, if required by user
1910  if ( settings->axisErrToleranceDefault )
1911  {
1912  settings->axisErrTolerance = std::min ( std::max ( 0.01, ( ( 2.0 * M_PI ) / static_cast< proshade_double > ( this->maxShellBand ) ) / 2.0 ), 0.05 );
1913  }
1914 
1915  //================================================ Prepare FSC computation memory and variables
1916  fftw_complex *mapData, *origCoeffs, *fCoeffs;
1917  fftw_plan planForwardFourier;
1918  proshade_double **bindata, *fscByBin;
1919  proshade_signed *binIndexing, *binCounts, noBins;
1920  this->prepareFSCFourierMemory ( mapData, origCoeffs, fCoeffs, binIndexing, &noBins, bindata, binCounts, &planForwardFourier, fscByBin );
1921 
1922  //================================================ If C was requested, we will do it immediately - this allows for a significant speed-up.
1923  if ( settings->requestedSymmetryType == "C" )
1924  {
1925  //============================================ Report progress
1926  std::stringstream hlpSS;
1927  hlpSS << "Starting detection of cyclic point group C" << settings->requestedSymmetryFold;
1928  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str(), settings->messageShift );
1929 
1930  //============================================ Do simplified search only in the applicable data
1931  proshade_double symThres = 0.0;
1932  std::vector< proshade_double* > CSyms = this->findRequestedCSymmetryFromAngleAxis ( settings, settings->requestedSymmetryFold, &symThres );
1933 
1934  //============================================ Deal with the rotation function 0 1 0 PI issue
1935  bool possible010PIIssue = false;
1936  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; } }
1937  if ( possible010PIIssue )
1938  {
1939  proshade_double* addAxis = new proshade_double[7];
1940  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] = -std::numeric_limits < proshade_double >::infinity();
1942  delete[] addAxis;
1943  }
1944 
1945  //============================================ Compute FSC for all possible axes
1946  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, fscByBin ); } }
1947 
1948  //============================================ Sort by FSC
1949  std::sort ( CSyms.begin(), CSyms.end(), sortProSHADESymmetryByFSC );
1950 
1951  //============================================ Save the best axis as the recommended one
1952  if ( settings->detectedSymmetry.size() == 0 ) { if ( CSyms.size() > 0 ) { settings->setDetectedSymmetry ( CSyms.at(0) ); } }
1953  if ( CSyms.size() > 0 )
1954  {
1955  bool passedTests = false;
1956  for ( size_t cIt = 0; cIt < CSyms.size(); cIt++ )
1957  {
1958  if ( CSyms.at(0)[6] > settings->fscThreshold )
1959  {
1960  settings->setRecommendedSymmetry ( "C" );
1961  settings->setRecommendedFold ( settings->requestedSymmetryFold );
1962 
1964  this->saveDetectedSymmetries ( settings, &CSyms, allCs );
1965 
1966  passedTests = true;
1967  break;
1968  }
1969  }
1970 
1971  if ( !passedTests )
1972  {
1973  settings->setRecommendedSymmetry ( "" );
1974  settings->setRecommendedFold ( 0 );
1975  }
1976  }
1977  else
1978  {
1979  settings->setRecommendedSymmetry ( "" );
1980  settings->setRecommendedFold ( 0 );
1981  }
1982 
1983  //============================================ Release memory after FSC computation
1984  delete[] mapData;
1985  delete[] origCoeffs;
1986  delete[] fCoeffs;
1987  fftw_destroy_plan ( planForwardFourier );
1988  delete[] binIndexing;
1989  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
1990  delete[] bindata;
1991  delete[] binCounts;
1992  delete[] fscByBin;
1993 
1994  //============================================ Done
1995  return ;
1996  }
1997 
1998  //================================================ Report progress
1999  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting C symmetry detection.", settings->messageShift );
2000 
2001  //================================================ Detect cyclic symmetries
2002  std::vector< proshade_double* > CSyms = getCyclicSymmetriesListFromAngleAxis ( settings );
2003 
2004  //================================================ Report progress
2005  std::stringstream ss;
2006  ss << "Detected " << CSyms.size() << " C symmetries.";
2007  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str(), settings->messageShift );
2008 
2009  //================================================ Sanity check - was the rotation function mapped properly?
2010  if ( this->sphereMappedRotFun.size() < 1 )
2011  {
2012  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." );
2013  }
2014 
2015  //================================================ If only C syms were requested (e.g. rotation centre detection), terminate here!
2016  if ( settings->requestedSymmetryType == "onlyC" )
2017  {
2018  //============================================ Prepare threshold
2019  proshade_double bestHistPeakStart = ProSHADE_internal_maths::findTopGroupSmooth ( &CSyms, 5, 0.01, 0.03, 9 );
2020  if ( bestHistPeakStart > settings->peakThresholdMin ) { bestHistPeakStart = settings->peakThresholdMin; }
2021 
2022  //============================================ Find FSCs for C syms
2023  for ( size_t cIt = 0; cIt < CSyms.size(); cIt++ )
2024  {
2025  //======================================== Check the peak height
2026  if ( CSyms.at(cIt)[5] < bestHistPeakStart ) { continue; }
2027 
2028  //======================================== Stop at some point - it is unlikely the true axis would be this far.
2029  if ( cIt > 15 ) { break; }
2030 
2031  //======================================== Compute FSC
2032  this->computeFSC ( settings, &CSyms, cIt, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2033  }
2034 
2035  //============================================ Save the detected Cs
2036  this->saveDetectedSymmetries ( settings, &CSyms, allCs );
2037 
2038  //============================================ Done
2039  return;
2040  }
2041 
2042  //================================================ Sanity check - was any symmetry requested?
2043  if ( ( settings->requestedSymmetryType != "" ) && ( settings->requestedSymmetryType != "C" ) && ( settings->requestedSymmetryType != "D" ) && ( settings->requestedSymmetryType != "T" ) && ( settings->requestedSymmetryType != "O" ) && ( settings->requestedSymmetryType != "I" ) )
2044  {
2045  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." );
2046  }
2047 
2048  //================================================ Are we doing general search?
2049  if ( settings->requestedSymmetryType == "" )
2050  {
2051  //============================================ Run the symmetry detection functions for C, D, T, O and I symmetries
2052  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
2053  std::vector< proshade_double* > ISyms;
2054  std::vector < std::vector< proshade_double* > > ISymsHlp = this->getPredictedIcosahedralSymmetriesList ( settings, &CSyms );
2055  std::vector< proshade_double* > OSyms = this->getPredictedOctahedralSymmetriesList ( settings, &CSyms );
2056  std::vector< proshade_double* > TSyms = this->getPredictedTetrahedralSymmetriesList ( settings, &CSyms );
2057 
2058  //============================================ Find which of the I groups is the correct one
2059  proshade_double fscMax = 0.0;
2060  size_t fscMaxInd = 0;
2061 
2062  for ( size_t icoIt = 0; icoIt < ISymsHlp.size(); icoIt++ )
2063  {
2064  //======================================== Is this a complete icosahedron?
2065  if ( ISymsHlp.at(icoIt).size() != 31 ) { continue; }
2066 
2067  //======================================== Initialise decision vars
2068  proshade_double fscVal = 0.0;
2069  proshade_double fscValAvg = 0.0;
2070 
2071  //======================================== For each axis
2072  for ( size_t aIt = 0; aIt < ISymsHlp.at(icoIt).size(); aIt++ )
2073  {
2074  //==================================== Match to CSyms
2075  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 );
2076 
2077  //==================================== Compute FSC
2078  fscVal = this->computeFSC ( settings, &CSyms, static_cast< size_t > ( matchedPos ), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2079  ISymsHlp.at(fscMaxInd).at(aIt)[6] = fscVal;
2080  fscValAvg += fscVal;
2081  }
2082 
2083  //======================================== Get FSC average over all axes
2084  fscValAvg /= 31.0;
2085 
2086  //======================================== Is this the best
2087  if ( fscValAvg > fscMax )
2088  {
2089  fscMax = fscValAvg;
2090  fscMaxInd = icoIt;
2091  }
2092 
2093  if ( settings->fastISearch ) { fscMaxInd = 0; break; }
2094  }
2095 
2096  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2097  if ( fscMax >= settings->fscThreshold )
2098  {
2099  //======================================== Add predicted axes to detected C axes list and also to the settings Icosahedral symmetry list
2100  for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ISymsHlp.at(fscMaxInd).size() ); retIt++ )
2101  {
2102  //==================================== Add the correct index to the settings object
2103  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 );
2104  ProSHADE_internal_misc::addToUnsignVector ( &settings->allDetectedIAxes, static_cast < proshade_unsign > ( matchedPos ) );
2105 
2106  //==================================== Set ISyms for saving
2107  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ISyms, ISymsHlp.at(fscMaxInd).at(retIt) );
2108  }
2109  }
2110 
2111  //============================================ Decide on recommended symmetry
2112  this->saveRecommendedSymmetry ( settings, &CSyms, &DSyms, &TSyms, &OSyms, &ISyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2113  }
2114 
2115  if ( settings->requestedSymmetryType == "D" )
2116  {
2117  //============================================ Run only the D symmetry detection and search for requested fold
2118  std::vector< proshade_double* > DSyms = this->getDihedralSymmetriesList ( settings, &CSyms );
2119  this->saveRequestedSymmetryD ( settings, &DSyms, axes, mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2120  }
2121 
2122  if ( settings->requestedSymmetryType == "T" )
2123  {
2124  //============================================ Run only the T symmetry detection
2125  std::vector< proshade_double* > TSyms = this->getPredictedTetrahedralSymmetriesList ( settings, &CSyms );
2126 
2127  if ( TSyms.size() == 7 )
2128  {
2129  //======================================== Initialise decision vars
2130  proshade_double fscVal = 0.0;
2131  proshade_double fscValAvg = 0.0;
2132 
2133  //======================================== Check if axes have high enough FSC and peak height
2134  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, fscByBin ); fscValAvg += fscVal; } }
2135  fscValAvg /= 7.0;
2136 
2137  //======================================== If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2138  if ( fscValAvg >= ( settings->fscThreshold ) )
2139  {
2140  //==================================== The decision is T
2141  settings->setRecommendedSymmetry ( "T" );
2142  settings->setRecommendedFold ( 0 );
2143  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)) ); }
2144  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)) ); } }
2145  }
2146  }
2147  }
2148 
2149  if ( settings->requestedSymmetryType == "O" )
2150  {
2151  //============================================ Run only the O symmetry detection
2152  std::vector< proshade_double* > OSyms = this->getPredictedOctahedralSymmetriesList ( settings, &CSyms );
2153 
2154  if ( OSyms.size() == 13 )
2155  {
2156  //======================================== Initialise decision vars
2157  proshade_double fscVal = 0.0;
2158  proshade_double fscValAvg = 0.0;
2159 
2160  //======================================== Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2161  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, fscByBin ); fscValAvg += fscVal; } }
2162  fscValAvg /= 13.0;
2163 
2164  //======================================== If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2165  if ( fscValAvg >= ( settings->fscThreshold ) )
2166  {
2167  //==================================== The decision is O
2168  settings->setRecommendedSymmetry ( "O" );
2169  settings->setRecommendedFold ( 0 );
2170  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)) ); }
2171  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)) ); } }
2172  }
2173  }
2174  }
2175 
2176  if ( settings->requestedSymmetryType == "I" )
2177  {
2178  //============================================ Find which of the I groups is the correct one
2179  proshade_double fscMax = 0.0;
2180  size_t fscMaxInd = 0;
2181  std::vector < std::vector< proshade_double* > > ISymsHlp = this->getPredictedIcosahedralSymmetriesList ( settings, &CSyms );
2182  std::vector< proshade_double* > ISyms;
2183 
2184  for ( size_t icoIt = 0; icoIt < ISymsHlp.size(); icoIt++ )
2185  {
2186  //======================================== Is this a complete icosahedron?
2187  if ( ISymsHlp.at(icoIt).size() != 31 ) { continue; }
2188 
2189  //======================================== Initialise decision vars
2190  proshade_double fscVal = 0.0;
2191  proshade_double fscValAvg = 0.0;
2192 
2193  //======================================== For each axis
2194  for ( size_t aIt = 0; aIt < ISymsHlp.at(icoIt).size(); aIt++ )
2195  {
2196  //==================================== Match to CSyms
2197  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 );
2198 
2199  //==================================== Compute FSC
2200  fscVal = this->computeFSC ( settings, &CSyms, static_cast< size_t > ( matchedPos ), mapData, fCoeffs, origCoeffs, &planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2201  ISymsHlp.at(fscMaxInd).at(aIt)[6] = fscVal;
2202  fscValAvg += fscVal;
2203  }
2204 
2205  //======================================== Get FSC average over all axes
2206  fscValAvg /= 31.0;
2207 
2208  //======================================== Is this the best
2209  if ( fscValAvg > fscMax )
2210  {
2211  fscMax = fscValAvg;
2212  fscMaxInd = icoIt;
2213  }
2214  }
2215 
2216  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2217  if ( fscMax >= ( settings->fscThreshold ) )
2218  {
2219  //======================================== Add predicted axes to detected C axes list and also to the settings Icosahedral symmetry list
2220  for ( proshade_unsign retIt = 0; retIt < static_cast < proshade_unsign > ( ISymsHlp.at(fscMaxInd).size() ); retIt++ )
2221  {
2222  //==================================== Add the correct index to the settings object
2223  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 );
2224  ProSHADE_internal_misc::addToUnsignVector ( &settings->allDetectedIAxes, static_cast < proshade_unsign > ( matchedPos ) );
2225 
2226  //==================================== Set ISyms for saving
2227  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ISyms, ISymsHlp.at(fscMaxInd).at(retIt) );
2228  }
2229  }
2230 
2231  //============================================ Delete all memory from ISymsHlp
2232  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); } }
2233 
2234  //============================================ If C3 and C5 are found and have correct angle (must have if they are both in ISym)
2235  if ( fscMax >= ( settings->fscThreshold * 0.7 ) )
2236  {
2237  //======================================== The decision is I
2238  settings->setRecommendedSymmetry ( "I" );
2239  settings->setRecommendedFold ( 0 );
2240  for ( size_t it = 0; it < ISyms.size(); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, ISyms.at(it) ); }
2241  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)) ); } }
2242  }
2243  }
2244 
2245  //================================================ Save C symmetries to argument and if different from settings, to the settings as well
2246  this->saveDetectedSymmetries ( settings, &CSyms, allCs );
2247 
2248  //================================================ Release memory after FSC computation
2249  delete[] mapData;
2250  delete[] origCoeffs;
2251  delete[] fCoeffs;
2252  fftw_destroy_plan ( planForwardFourier );
2253  delete[] binIndexing;
2254  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2255  delete[] bindata;
2256  delete[] binCounts;
2257 
2258  //================================================ Done
2259  return ;
2260 
2261 }
2262 
2276 void ProSHADE_internal_data::ProSHADE_data::saveDetectedSymmetries ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSyms, std::vector < std::vector< proshade_double > >* allCs )
2277 {
2278  //================================================ Initialise variables
2279  bool isArgSameAsSettings = true;
2280 
2281  //================================================ For each detected point group
2282  for ( proshade_unsign cIt = 0; cIt < static_cast<proshade_unsign> ( CSyms->size() ); cIt++ )
2283  {
2284  //============================================ Create vector to replace the pointer
2285  std::vector< proshade_double > nextSym;
2286  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[0] );
2287  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[1] );
2288  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[2] );
2289  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[3] );
2290  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[4] );
2291  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[5] );
2292  ProSHADE_internal_misc::addToDoubleVector ( &nextSym, CSyms->at(cIt)[6] );
2294 
2295  //============================================ Copy the vector to output variable and if different, then also to settings object
2296  if ( ( cIt == 0 ) && ( settings->allDetectedCAxes.size() == 0 ) ) { isArgSameAsSettings = false; }
2297  if ( !isArgSameAsSettings ) { ProSHADE_internal_misc::addToDoubleVectorVector ( &settings->allDetectedCAxes, nextSym ); }
2298 
2299  //============================================ Release memory
2300  nextSym.clear ( );
2301  delete[] CSyms->at(cIt);
2302  }
2303 
2304  //================================================ Done
2305  return ;
2306 
2307 }
2308 
2320 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, proshade_double*& fscByBin )
2321 {
2322  //================================================ Decide number of bins and allocate which reflection belongs to which bin
2323  ProSHADE_internal_maths::binReciprocalSpaceReflections ( this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing );
2324 
2325  //================================================ Allocate memory for FSC sums
2326  bindata = new proshade_double*[*noBins];
2327  binCounts = new proshade_signed [*noBins];
2328  fscByBin = new proshade_double [*noBins];
2329 
2330  //================================================ Allcate memory for bin sumation
2331  for ( size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ )
2332  {
2333  bindata[binIt] = new proshade_double[12];
2334  ProSHADE_internal_misc::checkMemoryAllocation ( bindata[binIt], __FILE__, __LINE__, __func__ );
2335  }
2336 
2337  //================================================ Allocate memory for Fourier transform imputs and outputs
2338  mapData = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2339  origCoeffs = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2340  fCoeffs = new fftw_complex [this->xDimIndices * this->yDimIndices * this->zDimIndices];
2341 
2342  //================================================ Check memory allocation
2343  ProSHADE_internal_misc::checkMemoryAllocation ( mapData, __FILE__, __LINE__, __func__ );
2344  ProSHADE_internal_misc::checkMemoryAllocation ( origCoeffs, __FILE__, __LINE__, __func__ );
2345  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffs, __FILE__, __LINE__, __func__ );
2346  ProSHADE_internal_misc::checkMemoryAllocation ( bindata, __FILE__, __LINE__, __func__ );
2347  ProSHADE_internal_misc::checkMemoryAllocation ( binCounts, __FILE__, __LINE__, __func__ );
2348  ProSHADE_internal_misc::checkMemoryAllocation ( fscByBin, __FILE__, __LINE__, __func__ );
2349 
2350  //================================================ Prepare memory for Fourier transform
2351  *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 );
2352 
2353  //================================================ Compute Fourier transform of the original map
2354  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; }
2355  fftw_execute ( *planForwardFourier );
2356  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]; }
2357 
2358  //================================================ Done
2359  return ;
2360 
2361 }
2362 
2391 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, proshade_double*& fscByBin )
2392 {
2393  //================================================ Sanity check
2394  if ( symIndex >= CSym->size() )
2395  {
2396  std::cerr << "The supplied symmetry axes vector does not contain element number " << symIndex << ". Returning FSC 0.0." << std::endl;
2397  return ( -2.0 );
2398  }
2399 
2400  //================================================ Ignore if already computed
2401  if ( CSym->at(symIndex)[6] > -2.0 ) { return ( CSym->at(symIndex)[6] ); }
2402 
2403  //================================================ Report progress
2404  std::stringstream ss2;
2405  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];
2406  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str(), settings->messageShift );
2407 
2408  //================================================ Initialise local variables
2409  proshade_double *rotMap;
2410 
2411  //================================================ For each rotation along the axis
2412  proshade_double averageFSC = 0.0;
2413  for ( proshade_double rotIter = 1.0; rotIter < CSym->at(symIndex)[0]; rotIter += 1.0 )
2414  {
2415  //============================================ Get rotated map by the smallest fold angle along the symmetry axis
2416  this->rotateMapRealSpace ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) * rotIter, rotMap );
2417 
2418  //============================================ Get Fourier for the rotated map
2419  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; }
2420  fftw_execute ( *planForwardFourier );
2421 
2422  //============================================ Compute FSC
2423  averageFSC += ProSHADE_internal_maths::computeFSC ( origCoeffs, fCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing, bindata, binCounts, fscByBin );
2424 
2425  //============================================ Release memory
2426  delete[] rotMap;
2427  }
2428 
2429  //================================================ Convert sum to average
2430  averageFSC /= ( CSym->at(symIndex)[0] - 1.0 );
2431 
2432  //================================================ Save result to the axis
2433  CSym->at(symIndex)[6] = averageFSC;
2434 
2435  //================================================ Report progress
2436  std::stringstream ss3;
2437  ss3 << "FSC value is " << averageFSC << " .";
2438  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str(), settings->messageShift );
2439 
2440  //================================================ Done
2441  return ( averageFSC );
2442 
2443 }
2444 
2472 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, proshade_double*& fscByBin )
2473 {
2474  //================================================ Ignore if already computed
2475  if ( sym[6] > -2.0 ) { return ( sym[6] ); }
2476 
2477  //================================================ Report progress
2478  std::stringstream ss2;
2479  ss2 << "Computing FSC for symmetry C" << sym[0] << " ( " << sym[1] << " ; " << sym[2] << " ; " << sym[3] << " ) with peak height " << sym[5];
2480  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str(), settings->messageShift );
2481 
2482  //================================================ Initialise local variables
2483  proshade_double *rotMap;
2484 
2485  //================================================ For each rotation along the axis
2486  proshade_double averageFSC = 0.0;
2487  for ( proshade_double rotIter = 1.0; rotIter < sym[0]; rotIter += 1.0 )
2488  {
2489  //============================================ Get rotated map by the smallest fold angle along the symmetry axis
2490  this->rotateMapRealSpace ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) * rotIter, rotMap );
2491 
2492  //============================================ Get Fourier for the rotated map
2493  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; }
2494  fftw_execute ( *planForwardFourier );
2495 
2496  //============================================ Clean FSC computation memory
2497  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; } }
2498  for ( size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { binCounts[binIt] = 0; }
2499 
2500  //============================================ Compute FSC
2501  averageFSC += ProSHADE_internal_maths::computeFSC ( origCoeffs, fCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices, noBins, binIndexing, bindata, binCounts, fscByBin );
2502 
2503  //============================================ Release memory
2504  delete[] rotMap;
2505  }
2506 
2507  //================================================ Convert sum to average
2508  averageFSC /= ( sym[0] - 1.0 );
2509 
2510  //================================================ Save result to the axis
2511  sym[6] = averageFSC;
2512 
2513  //================================================ Report progress
2514  std::stringstream ss3;
2515  ss3 << "FSC value is " << averageFSC << " .";
2516  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str(), settings->messageShift );
2517 
2518  //================================================ Done
2519  return ( averageFSC );
2520 
2521 }
2522 
2558 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, proshade_double*& fscByBin )
2559 {
2560  //================================================ Report progress
2561  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting recommended symmetry decision procedure.", settings->messageShift );
2562 
2563  //================================================ If no C symmetries, nothing to save...
2564  if ( CSym->size() == 0 )
2565  {
2566  settings->setRecommendedSymmetry ( "" );
2567  settings->setRecommendedFold ( 0 );
2568  return;
2569  }
2570 
2571  //================================================ Initialise local variables
2572  proshade_double step = 0.01;
2573  proshade_double sigma = 0.03;
2574  proshade_signed windowSize = 9;
2575  proshade_double IFSCAverage = 0.0, OFSCAverage = 0.0, TFSCAverage = 0.0;
2576  bool IIsBest = false, OIsBest = false, TIsBest = false;
2577 
2578  //================================================ Find the top group minimum threshold using smoothened histogram
2579  proshade_double bestHistPeakStart = ProSHADE_internal_maths::findTopGroupSmooth ( CSym, 5, step, sigma, windowSize );
2580  if ( bestHistPeakStart > settings->peakThresholdMin ) { bestHistPeakStart = settings->peakThresholdMin; }
2581 
2582  //================================================ Report progress
2583  proshade_unsign noPassed = 0; for ( size_t cIt = 0; cIt < CSym->size(); cIt++ ) { if ( CSym->at(cIt)[5] > bestHistPeakStart ) { noPassed += 1; } }
2584  std::stringstream ss;
2585  ss << "Smoothening has resolved in " << noPassed << " C symmetries.";
2586  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str(), settings->messageShift );
2587  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Starting FSC computation to confirm the C symmetries existence.", settings->messageShift );
2588 
2589  //================================================ Decide if I is the answer
2590  bool alreadyDecided = false;
2591  if ( ISym->size() == 31 )
2592  {
2593  //============================================ Initialise decision vars
2594  proshade_double fscVal = 0.0;
2595  proshade_double fscValAvg = 0.0;
2596 
2597  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2598  for ( size_t iIt = 0; iIt < 31; iIt++ ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedIAxes.at(iIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin ); fscValAvg += fscVal; if ( fscVal < settings->fscThreshold ) { fscValAvg = 0.0; break; } }
2599  fscValAvg /= 31.0;
2600  IFSCAverage = fscValAvg;
2601  }
2602 
2603  //================================================ Decide if O is the answer
2604  if ( ( OSym->size() == 13 ) && !alreadyDecided )
2605  {
2606  //============================================ Initialise decision vars
2607  proshade_double fscVal = 0.0;
2608  proshade_double fscValAvg = 0.0;
2609 
2610  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2611  for ( size_t oIt = 0; oIt < 13; oIt++ ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedOAxes.at(oIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin ); fscValAvg += fscVal; if ( fscVal < settings->fscThreshold ) { fscValAvg = 0.0; break; } }
2612  fscValAvg /= 13.0;
2613  OFSCAverage = fscValAvg;
2614  }
2615 
2616  //================================================ Decide if T is the answer
2617  if ( ( TSym->size() == 7 ) && !alreadyDecided )
2618  {
2619  //============================================ Initialise decision vars
2620  proshade_double fscVal = 0.0;
2621  proshade_double fscValAvg = 0.0;
2622 
2623  //============================================ Check if at least one C5 and one C3 with the correct angle have high FSC and peak height
2624  for ( size_t tIt = 0; tIt < 7; tIt++ ) { fscVal = this->computeFSC ( settings, CSym, settings->allDetectedTAxes.at(tIt), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin ); fscValAvg += fscVal; if ( fscVal < settings->fscThreshold ) { fscValAvg = 0.0; break; } }
2625  fscValAvg /= 7.0;
2626  TFSCAverage = fscValAvg;
2627  }
2628 
2629  //================================================ If we are using phaseless detection, different threshold needs to be used due to large number of false positives
2630  proshade_double newThres = settings->fscThreshold;
2631  if ( !settings->usePhase )
2632  {
2633  proshade_double phaselessStep = 0.01;
2634  proshade_double phaselessSigma = 0.005;
2635  proshade_signed phaselessWSize = 5;
2636  newThres = ProSHADE_internal_maths::findTopGroupSmooth ( CSym, 6, phaselessStep, phaselessSigma, phaselessWSize, 0.94 );
2637  }
2638 
2639  //================================================ Decide between polyhedral
2640  if ( ( IFSCAverage > std::max( OFSCAverage * 0.9, TFSCAverage * 0.8 ) ) && ( IFSCAverage > newThres ) ) { IIsBest = true; }
2641  if ( ( OFSCAverage > std::max( IFSCAverage * 1.1, TFSCAverage * 0.9 ) ) && ( OFSCAverage > newThres ) ) { OIsBest = true; }
2642  if ( ( TFSCAverage > std::max( IFSCAverage * 1.2, OFSCAverage * 1.1 ) ) && ( TFSCAverage > newThres ) ) { TIsBest = true; }
2643  if ( !IIsBest && !OIsBest && !TIsBest && ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) > newThres ) )
2644  {
2645  const FloatingPoint< proshade_double > lhsPolyI ( IFSCAverage ), lhsPolyO ( OFSCAverage ), lhsPolyT ( TFSCAverage ), rhsPolyMax ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) );
2646  if ( lhsPolyI.AlmostEquals( rhsPolyMax ) ) { IIsBest = true; }
2647  if ( lhsPolyO.AlmostEquals( rhsPolyMax ) ) { OIsBest = true; }
2648  if ( lhsPolyT.AlmostEquals( rhsPolyMax ) ) { TIsBest = true; }
2649  }
2650 
2651  //================================================ Now we know I is best polyhedral and conforms to threshold
2652  if ( IIsBest )
2653  {
2654  //============================================ The decision is I
2655  settings->setRecommendedSymmetry ( "I" );
2656  settings->setRecommendedFold ( 0 );
2657  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)) ); }
2658  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)) ); } }
2659 
2660  //============================================ Done
2661  alreadyDecided = true;
2662  }
2663 
2664  //================================================ Now we know O is best polyhedral and conforms to threshold
2665  if ( OIsBest && !alreadyDecided )
2666  {
2667  //============================================ The decision is O
2668  settings->setRecommendedSymmetry ( "O" );
2669  settings->setRecommendedFold ( 0 );
2670  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)) ); }
2671  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)) ); } }
2672 
2673  //============================================ Done
2674  alreadyDecided = true;
2675  }
2676 
2677  //================================================ Now we know T is best polyhedral and conforms to threshold
2678  if ( TIsBest && !alreadyDecided )
2679  {
2680  settings->setRecommendedSymmetry ( "T" );
2681  settings->setRecommendedFold ( 0 );
2682  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)) ); }
2683  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)) ); } }
2684 
2685  //============================================ Done
2686  alreadyDecided = true;
2687  }
2688 
2689  //================================================ Decide if D is the answer
2690  if ( ( settings->allDetectedDAxes.size() > 0 ) && ( DSym->size() > 0 ) && !alreadyDecided )
2691  {
2692  //============================================ Initialise decision vars
2693  proshade_signed bestD = -1;
2694  proshade_unsign bestFold = 0;
2695 
2696  //============================================ Find FSCs
2697  for ( size_t dIt = 0; dIt < settings->allDetectedDAxes.size(); dIt++ )
2698  {
2699  //======================================== Do not consider more than top 20, takes time and is unlikely to produce anything...
2700  if ( dIt > 20 ) { continue; }
2701 
2702  //======================================== Check the peak heights
2703  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 ) );
2704  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] < bestHistPeakStart ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2705  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] < bestHistPeakStart ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2706 
2707  //======================================== Find FSCs
2708  this->computeFSC ( settings, CSym, settings->allDetectedDAxes.at(dIt).at(0), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2709  this->computeFSC ( settings, CSym, settings->allDetectedDAxes.at(dIt).at(1), mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2710  }
2711 
2712  //============================================ Find FSC top group threshold
2713  proshade_double bestHistFSCStart = ProSHADE_internal_maths::findTopGroupSmooth ( CSym, 6, step, sigma, windowSize );
2714 
2715  //============================================ Check if both C symmetries are reliable
2716  for ( size_t dIt = 0; dIt < settings->allDetectedDAxes.size(); dIt++ )
2717  {
2718  //======================================== Check the peak heights
2719  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 ) );
2720  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[5] < bestHistPeakStart ) && !( lhs999a2.AlmostEquals( rhs999 ) ) ) { continue; }
2721  if ( ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[5] < bestHistPeakStart ) && !( lhs999b2.AlmostEquals( rhs999 ) ) ) { continue; }
2722 
2723  //======================================== Does this improve the best fold?
2724  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 ) ) )
2725  {
2726  //==================================== Check the FSC vals
2727  if ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[6] < newThres ) { continue; }
2728  if ( CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[6] < newThres ) { continue; }
2729  if ( std::max ( CSym->at(settings->allDetectedDAxes.at(dIt).at(0))[6], CSym->at(settings->allDetectedDAxes.at(dIt).at(1))[6] ) < bestHistFSCStart ) { continue; }
2730 
2731  //==================================== All good!
2732  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] ) );
2733  bestD = static_cast< proshade_signed > ( dIt );
2734  }
2735  }
2736 
2737  //============================================ Anything?
2738  if ( bestD != -1 )
2739  {
2740  //======================================== The decision is D
2741  settings->setRecommendedSymmetry ( "D" );
2742  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] ) ) );
2743  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(0)) );
2744  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(1)) );
2745  if ( settings->detectedSymmetry.size() == 0 )
2746  {
2747  settings->setDetectedSymmetry ( CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(0)) );
2748  settings->setDetectedSymmetry ( CSym->at(settings->allDetectedDAxes.at( static_cast< size_t > ( bestD ) ).at(1)) );
2749  }
2750 
2751  //======================================== Done
2752  alreadyDecided = true;
2753  }
2754  }
2755 
2756  //================================================ Decide if C is the answer
2757  if ( ( CSym->size() > 0 ) && !alreadyDecided )
2758  {
2759  //============================================ Initialise decision vars
2760  proshade_signed bestC = -1;
2761  proshade_unsign bestFold = 0;
2762 
2763  //============================================ Find FSCs for C syms
2764  for ( size_t cIt = 0; cIt < CSym->size(); cIt++ )
2765  {
2766  //======================================== Do not consider more than top 20, takes time and is unlikely to produce anything...
2767  if ( cIt > 15 ) { break; }
2768 
2769  //======================================== Check the peak height
2770  if ( CSym->at(cIt)[5] < bestHistPeakStart ) { continue; }
2771 
2772  //======================================== Compute FSC
2773  this->computeFSC ( settings, CSym, cIt, mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2774  }
2775 
2776  //============================================ Find FSC top group threshold
2777  proshade_double bestHistFSCStart = ProSHADE_internal_maths::findTopGroupSmooth ( CSym, 6, step, sigma, windowSize );
2778 
2779  //============================================ Find reliable C syms
2780  for ( size_t cIt = 0; cIt < CSym->size(); cIt++ )
2781  {
2782  //======================================== Check if this improves the best already found fold
2783  if ( CSym->at(cIt)[0] > static_cast< proshade_double > ( bestFold ) )
2784  {
2785  //==================================== If FSC passes
2786  if ( ( CSym->at(cIt)[6] > newThres ) && ( CSym->at(cIt)[6] >= bestHistFSCStart ) )
2787  {
2788  bestFold = static_cast< proshade_unsign > ( CSym->at(cIt)[0] );
2789  bestC = static_cast< proshade_signed > ( cIt );
2790  }
2791  }
2792  }
2793 
2794  //============================================ Anything?
2795  if ( bestC != -1 )
2796  {
2797  //======================================== The decision is C
2798  settings->setRecommendedSymmetry ( "C" );
2799  settings->setRecommendedFold ( static_cast< proshade_unsign > ( CSym->at( static_cast< size_t > ( bestC ) )[0] ) );
2800  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at( static_cast< size_t > ( bestC ) ) );
2801  if ( settings->detectedSymmetry.size() == 0 ) { settings->setDetectedSymmetry ( CSym->at( static_cast< size_t > ( bestC ) ) ); }
2802 
2803  //======================================== Done
2804  alreadyDecided = true;
2805  }
2806  }
2807 
2808  //================================================ Done
2809  return ;
2810 
2811 }
2812 
2824 void ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryC ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSym, std::vector< proshade_double* >* axes )
2825 {
2826  //================================================ Initialise variables
2827  proshade_unsign bestIndex = 0;
2828  proshade_double highestSym = 0.0;
2829 
2830  //================================================ Search for best fold
2831  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( CSym->size() ); iter++ )
2832  {
2833  //============================================ Check if it is tbe correct fold
2834  const FloatingPoint< proshade_double > lhs1 ( CSym->at(iter)[0] ), rhs1 ( static_cast< proshade_double > ( settings->requestedSymmetryFold ) );
2835  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2836 
2837  //============================================ If correct, is it the highest found?
2838  if ( CSym->at(iter)[5] > highestSym )
2839  {
2840  highestSym = CSym->at(iter)[5];
2841  bestIndex = iter;
2842  }
2843  }
2844 
2845  //================================================ Found?
2846  if ( highestSym > 0.0 )
2847  {
2848  settings->setRecommendedSymmetry ( "C" );
2849  settings->setRecommendedFold ( static_cast< proshade_unsign > ( CSym->at(bestIndex)[0] ) );
2850  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, CSym->at(bestIndex) );
2851 
2852  if ( settings->detectedSymmetry.size() == 0 ) { settings->setDetectedSymmetry ( CSym->at(bestIndex) ); }
2853  }
2854  else
2855  {
2856  settings->setRecommendedSymmetry ( "" );
2857  settings->setRecommendedFold ( 0 );
2858  }
2859 
2860  //================================================ Done
2861  return ;
2862 
2863 }
2864 
2876 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, proshade_double*& fscByBin )
2877 {
2878  //================================================ Initialise variables
2879  proshade_unsign bestIndex = 0;
2880  proshade_double highestSym = 0.0;
2881 
2882  //================================================ Search for best fold
2883  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( DSym->size() ); iter++ )
2884  {
2885  //============================================ Check if it is tbe correct fold
2886  const FloatingPoint< proshade_double > lhs1 ( std::max ( DSym->at(iter)[0], DSym->at(iter)[7] ) ), rhs1 ( static_cast< proshade_double > ( settings->requestedSymmetryFold ) );
2887  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2888 
2889  //============================================ Check if peak height is decent
2890  const FloatingPoint< proshade_double > lhs999a ( DSym->at(iter)[5] ), lhs999b ( DSym->at(iter)[12] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2891  if ( ( DSym->at(iter)[5] < settings->peakThresholdMin ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2892  if ( ( DSym->at(iter)[12] < settings->peakThresholdMin ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2893 
2894  //============================================ If correct, compute FSC
2895  this->computeFSC ( settings, &DSym->at(iter)[0], mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2896  this->computeFSC ( settings, &DSym->at(iter)[7], mapData, fCoeffs, origCoeffs, planForwardFourier, noBins, binIndexing, bindata, binCounts, fscByBin );
2897 
2898  //============================================ If best, store it
2899  if ( ( DSym->at(iter)[6] + DSym->at(iter)[13] ) > highestSym )
2900  {
2901  highestSym = ( DSym->at(iter)[6] + DSym->at(iter)[13] );
2902  bestIndex = iter;
2903  }
2904  }
2905 
2906  //================================================ Found?
2907  if ( highestSym > 0.0 )
2908  {
2909  settings->setRecommendedSymmetry ( "D" );
2910  settings->setRecommendedFold ( static_cast< proshade_unsign > ( std::max ( DSym->at(bestIndex)[0], DSym->at(bestIndex)[7] ) ) );
2911  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, &DSym->at(bestIndex)[0] );
2912  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( axes, &DSym->at(bestIndex)[7] );
2913 
2914  if ( settings->detectedSymmetry.size() == 0 )
2915  {
2916  settings->setDetectedSymmetry ( &DSym->at(bestIndex)[0] );
2917  settings->setDetectedSymmetry ( &DSym->at(bestIndex)[7] );
2918  }
2919  }
2920  else
2921  {
2922  settings->setRecommendedSymmetry ( "" );
2923  settings->setRecommendedFold ( 0 );
2924  }
2925 
2926  //================================================ Done
2927  return ;
2928 
2929 }
2930 
2939 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::computeGroupElementsForGroup ( proshade_double xAx, proshade_double yAx, proshade_double zAx, proshade_signed fold )
2940 {
2941  //================================================ Initialise variables
2942  std::vector< proshade_double > angList;
2943  std::vector<std::vector< proshade_double > > ret;
2944 
2945  //================================================ Allocate memory
2946  proshade_double* rotMat = new proshade_double[9];
2947  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
2948 
2949 
2950  //================================================ Normalise the axis to have magnitude of 1.0
2951  proshade_double normF = std::sqrt( std::pow ( xAx, 2.0 ) + std::pow ( yAx, 2.0 ) + std::pow ( zAx, 2.0 ) );
2952  xAx /= normF;
2953  yAx /= normF;
2954  zAx /= normF;
2955 
2956  //================================================ Determine the list of angles
2957  if ( fold % 2 == 0 )
2958  {
2959  //============================================ If fold is even, add the negative angles
2960  for ( proshade_double iter = static_cast < proshade_double > ( -( ( fold / 2 ) - 1 ) ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2961  {
2962  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
2963  }
2964  }
2965  else
2966  {
2967  //============================================ If fold is odd, do the same as for even, but start one index earlier
2968  for ( proshade_double iter = static_cast < proshade_double > ( -fold / 2 ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2969  {
2970  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
2971  }
2972  }
2973 
2974  //================================================ For each detected angle
2975  for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( angList.size() ); iter++ )
2976  {
2977  //============================================ Compute the rotation matrix
2978  ProSHADE_internal_maths::getRotationMatrixFromAngleAxis ( rotMat, xAx, yAx, zAx, angList.at(iter) );
2979 
2980  //============================================ Convert to vector of vectors of doubles and save to ret
2981  std::vector < proshade_double > retEl;
2982  for ( proshade_unsign matIt = 0; matIt < 9; matIt++ )
2983  {
2984  ProSHADE_internal_misc::addToDoubleVector ( &retEl, rotMat[matIt] );
2985  }
2987  }
2988 
2989  //================================================ Release memory
2990  delete[] rotMat;
2991 
2992  //================================================ Done
2993  return ( ret );
2994 
2995 }
2996 
3003 void axesToGroupTypeSanityCheck ( proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType )
3004 {
3005  //================================================ Sanity check
3006  if ( obtainedAxes != requiredAxes )
3007  {
3008  std::stringstream hlpSS;
3009  hlpSS << "The supplied number of axes for group element\n : detection ( >" << obtainedAxes << "< ) does not match the group type ( >" << groupType << "< ).";
3010  throw ProSHADE_exception ( "Mismatch between supplied number of axes and\n : symmetry type.", "ES00059", __FILE__, __LINE__, __func__, hlpSS.str() );
3011  }
3012 
3013  //================================================ Done
3014  return ;
3015 
3016 }
3017 
3025 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance )
3026 {
3027  //================================================ Initialise variables
3028  bool elementFound = false;
3029 
3030  //================================================ For each existing element
3031  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( elements->size() ); elIt++ )
3032  {
3033  if ( ProSHADE_internal_maths::rotationMatrixSimilarity ( &elements->at(elIt), elem, matrixTolerance ) )
3034  {
3035  elementFound = true;
3036  break;
3037  }
3038  }
3039 
3040  //================================================ Done
3041  return ( elementFound );
3042 
3043 }
3044 
3051 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance )
3052 {
3053  //================================================ Initialise variables
3054  bool isGroup = true;
3055 
3056  //================================================ Multiply all group element pairs
3057  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( elements->size() ); gr1++ )
3058  {
3059  for ( proshade_unsign gr2 = 1; gr2 < static_cast<proshade_unsign> ( elements->size() ); gr2++ )
3060  {
3061  //======================================== Use unique pairs only
3062  if ( gr1 >= gr2 ) { continue; }
3063 
3064  //======================================== Multiply the two rotation matrices
3065  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &elements->at(gr1), &elements->at(gr2) );
3066 
3067  //======================================== Check the group already contains the produces as an element
3068  if ( !checkElementAlreadyExists ( elements, &product, matrixTolerance ) )
3069  {
3070  isGroup = false;
3071  break;
3072  }
3073  }
3074 
3075  //============================================ Stop if problem was found
3076  if ( !isGroup ) { break; }
3077  }
3078 
3079  //================================================ Done
3080  return ( isGroup );
3081 
3082 }
3083 
3092 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 )
3093 {
3094  //================================================ Initialise variables
3095  std::vector< std::vector< proshade_double > > ret;
3096 
3097  //================================================ Add the first list to ret, checking for uniqueness
3098  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( first->size() ); elIt++ )
3099  {
3100  if ( !checkElementAlreadyExists( &ret, &first->at(elIt), matrixTolerance ) )
3101  {
3102  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, first->at(elIt) );
3103  }
3104  }
3105 
3106  //================================================ Add the second list to ret, checking for uniqueness
3107  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( second->size() ); elIt++ )
3108  {
3109  if ( !checkElementAlreadyExists( &ret, &second->at(elIt), matrixTolerance ) )
3110  {
3111  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, second->at(elIt) );
3112  }
3113  }
3114 
3115  //================================================ Multiply all combinations of first and second and check for uniqueness
3116  if ( combine )
3117  {
3118  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( first->size() ); gr1++ )
3119  {
3120  for ( proshade_unsign gr2 = 0; gr2 < static_cast<proshade_unsign> ( second->size() ); gr2++ )
3121  {
3122  //==================================== Multiply the two rotation matrices
3123  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &first->at(gr1), &second->at(gr2) );
3124 
3125  //==================================== Add
3126  if ( !checkElementAlreadyExists( &ret, &product, matrixTolerance ) )
3127  {
3129  }
3130 
3131  }
3132  }
3133  }
3134 
3135  //================================================ Done
3136  return ( ret );
3137 
3138 }
3139 
3151 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 )
3152 {
3153  //================================================ Initialise variables
3154  std::vector<std::vector< proshade_double > > ret = this->getAllGroupElements ( &settings->allDetectedCAxes, axesList, groupType, matrixTolerance );
3155 
3156  //================================================ Done
3157  return ( ret );
3158 
3159 }
3160 
3179 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::ProSHADE_data::getAllGroupElements ( std::vector < std::vector< proshade_double > >* allCs, std::vector< proshade_unsign > axesList, std::string groupType, proshade_double matrixTolerance )
3180 {
3181  //================================================ Initialise variables
3182  std::vector<std::vector< proshade_double > > ret;
3183 
3184  //================================================ Select which symmetry type are we computing for
3185  if ( groupType == "C" )
3186  {
3187  //============================================ Sanity check
3188  axesToGroupTypeSanityCheck ( 1, static_cast< proshade_unsign > ( axesList.size() ), groupType );
3189 
3190  //============================================ Generate elements
3191  ret = computeGroupElementsForGroup ( allCs->at(axesList.at(0)).at(1),
3192  allCs->at(axesList.at(0)).at(2),
3193  allCs->at(axesList.at(0)).at(3),
3194  static_cast< proshade_signed > ( allCs->at(axesList.at(0)).at(0) ) );
3195 
3196  //============================================ Check the element to form a group
3197  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3198  else
3199  {
3200  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." );
3201  }
3202  }
3203  else if ( groupType == "D" )
3204  {
3205  //============================================ Sanity check
3206  axesToGroupTypeSanityCheck ( 2, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3207 
3208  //============================================ Generate elements for both axes
3209  std::vector<std::vector< proshade_double > > first = computeGroupElementsForGroup ( allCs->at(axesList.at(0)).at(1),
3210  allCs->at(axesList.at(0)).at(2),
3211  allCs->at(axesList.at(0)).at(3),
3212  static_cast< proshade_signed > ( allCs->at(axesList.at(0)).at(0) ) );
3213 
3214  std::vector<std::vector< proshade_double > > second = computeGroupElementsForGroup ( allCs->at(axesList.at(1)).at(1),
3215  allCs->at(axesList.at(1)).at(2),
3216  allCs->at(axesList.at(1)).at(3),
3217  static_cast< proshade_signed > ( allCs->at(axesList.at(1)).at(0) ) );
3218 
3219  //============================================ Join the element lists
3220  ret = joinElementsFromDifferentGroups ( &first, &second, matrixTolerance, true );
3221 
3222  //============================================ Check the element to form a group
3223  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3224  else
3225  {
3226  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." );
3227  }
3228  }
3229  else if ( groupType == "T" )
3230  {
3231  //============================================ Sanity check
3232  axesToGroupTypeSanityCheck ( 7, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3233 
3234  //============================================ Generate elements for all four C3 axes first
3235  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3236  {
3237  //======================================== If this is a C3 axis
3238  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3239  if ( lhs1.AlmostEquals ( rhs1 ) )
3240  {
3241  //==================================== Generate the elements
3242  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3243  allCs->at(axesList.at(grIt)).at(2),
3244  allCs->at(axesList.at(grIt)).at(3),
3245  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3246 
3247  //==================================== Join the elements to any already found
3248  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3249  }
3250  }
3251 
3252  //============================================ Generate elements for all three C2 axes second
3253  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3254  {
3255  //======================================== If this is a C3 axis
3256  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3257  if ( lhs1.AlmostEquals ( rhs1 ) )
3258  {
3259  //==================================== Generate the elements
3260  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3261  allCs->at(axesList.at(grIt)).at(2),
3262  allCs->at(axesList.at(grIt)).at(3),
3263  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3264 
3265  //==================================== Join the elements to any already found
3266  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3267  }
3268  }
3269 
3270  //============================================ Check the element to form a group
3271  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3272  else
3273  {
3274  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." );
3275  }
3276  }
3277  else if ( groupType == "O" )
3278  {
3279  //============================================ Sanity check
3280  axesToGroupTypeSanityCheck ( 13, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3281 
3282  //============================================ Generate elements for all three C4 axes first
3283  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3284  {
3285  //======================================== If this is a C3 axis
3286  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 4.0 );
3287  if ( lhs1.AlmostEquals ( rhs1 ) )
3288  {
3289  //==================================== Generate the elements
3290  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3291  allCs->at(axesList.at(grIt)).at(2),
3292  allCs->at(axesList.at(grIt)).at(3),
3293  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3294 
3295  //==================================== Join the elements to any already found
3296  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3297  }
3298  }
3299 
3300  //============================================ Generate elements for all four C3 axes first
3301  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3302  {
3303  //======================================== If this is a C3 axis
3304  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3305  if ( lhs1.AlmostEquals ( rhs1 ) )
3306  {
3307  //==================================== Generate the elements
3308  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3309  allCs->at(axesList.at(grIt)).at(2),
3310  allCs->at(axesList.at(grIt)).at(3),
3311  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3312 
3313  //==================================== Join the elements to any already found
3314  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3315  }
3316  }
3317 
3318  //============================================ Generate elements for all six C2 axes next
3319  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3320  {
3321  //======================================== If this is a C3 axis
3322  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3323  if ( lhs1.AlmostEquals ( rhs1 ) )
3324  {
3325  //==================================== Generate the elements
3326  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3327  allCs->at(axesList.at(grIt)).at(2),
3328  allCs->at(axesList.at(grIt)).at(3),
3329  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3330 
3331  //==================================== Join the elements to any already found
3332  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3333  }
3334  }
3335 
3336  //============================================ Check the element to form a group
3337  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3338  else
3339  {
3340  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." );
3341  }
3342  }
3343  else if ( groupType == "I" )
3344  {
3345  //============================================ Sanity check
3346  axesToGroupTypeSanityCheck ( 31, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3347 
3348  //============================================ Generate elements for all six C5 axes first
3349  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3350  {
3351  //======================================== If this is a C5 axis
3352  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 5.0 );
3353  if ( lhs1.AlmostEquals ( rhs1 ) )
3354  {
3355  //==================================== Generate the elements
3356  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3357  allCs->at(axesList.at(grIt)).at(2),
3358  allCs->at(axesList.at(grIt)).at(3),
3359  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3360 
3361  //==================================== Join the elements to any already found
3362  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3363  }
3364  }
3365 
3366  //============================================ Generate elements for all ten C3 axes next
3367  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3368  {
3369  //======================================== If this is a C3 axis
3370  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3371  if ( lhs1.AlmostEquals ( rhs1 ) )
3372  {
3373  //==================================== Generate the elements
3374  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3375  allCs->at(axesList.at(grIt)).at(2),
3376  allCs->at(axesList.at(grIt)).at(3),
3377  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3378 
3379  //==================================== Join the elements to any already found
3380  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3381  }
3382  }
3383 
3384  //============================================ Generate elements for all fifteen C2 axes lastly
3385  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3386  {
3387  //======================================== If this is a C3 axis
3388  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3389  if ( lhs1.AlmostEquals ( rhs1 ) )
3390  {
3391  //==================================== Generate the elements
3392  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3393  allCs->at(axesList.at(grIt)).at(2),
3394  allCs->at(axesList.at(grIt)).at(3),
3395  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3396 
3397  //==================================== Join the elements to any already found
3398  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3399  }
3400  }
3401 
3402  //============================================ Check the element to form a group
3403  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3404  else
3405  {
3406  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." );
3407  }
3408  }
3409  else if ( groupType == "X" )
3410  {
3411  //============================================ User forced no checking for unspecified symmetry
3412  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3413  {
3414  //======================================== Compute group elements
3415  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3416  allCs->at(axesList.at(grIt)).at(2),
3417  allCs->at(axesList.at(grIt)).at(3),
3418  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3419 
3420  //======================================== Join the elements to any already found
3421  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, true );
3422  }
3423 
3424  //============================================ Check the element to form a group
3425  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3426  else
3427  {
3428  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." );
3429  }
3430  }
3431  else
3432  {
3433  std::stringstream hlpSS;
3434  hlpSS << "Unknown symmetry type: >" << groupType << "<";
3435  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." );
3436  }
3437 
3438 }
3439 
3447 void ProSHADE_internal_data::ProSHADE_data::deepCopyMap ( proshade_double*& saveTo, proshade_signed verbose )
3448 {
3449  //================================================ Sanity check
3450  if ( saveTo != nullptr )
3451  {
3452  ProSHADE_internal_messages::printWarningMessage ( verbose, "!!! ProSHADE WARNING !!! The deep copy pointer is not set to NULL. Cannot proceed and returning unmodified pointer.", "WB00040" );
3453  return ;
3454  }
3455 
3456  //================================================ Allocate the memory
3457  saveTo = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3458 
3459  //================================================ Check memory allocation
3460  ProSHADE_internal_misc::checkMemoryAllocation ( saveTo, __FILE__, __LINE__, __func__ );
3461 
3462  //================================================ Copy internal map to the new pointer
3463  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
3464  {
3465  saveTo[iter] = this->internalMap[iter];
3466  }
3467 
3468  //================================================ Done
3469  return ;
3470 
3471 }
3472 
3480 {
3481  //================================================ Improve this!
3482  if ( settings->recommendedSymmetryType == "" )
3483  {
3484  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, "Did not detect any symmetry!", settings->messageShift );
3485  }
3486  else
3487  {
3488  std::stringstream ssHlp;
3489  std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3490  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 .";
3491  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3492 
3493  if ( settings->detectedSymmetry.size() > 0 )
3494  {
3495  ssHlp.clear(); ssHlp.str ( "" );
3496  ssHlp << " Fold X Y Z Angle Height Average FSC";
3497  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3498  }
3499  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ); symIt++ )
3500  {
3501  ssHlp.clear(); ssHlp.str ( "" );
3502  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];
3503  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3504  }
3505 
3506  std::stringstream hlpSS3;
3507  ssHlp.clear(); ssHlp.str ( "" );
3508  hlpSS3 << std::endl << "To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3509  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, hlpSS3.str(), settings->messageShift );
3510 
3511  if ( settings->allDetectedCAxes.size() > 0 )
3512  {
3513  ssHlp.clear(); ssHlp.str ( "" );
3514  ssHlp << " Fold X Y Z Angle Height Average FSC";
3515  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3516  }
3517  for ( proshade_unsign symIt = 0; symIt < static_cast<proshade_unsign> ( settings->allDetectedCAxes.size() ); symIt++ )
3518  {
3519  ssHlp.clear(); ssHlp.str ( "" );
3520  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];
3521  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3522  }
3523 
3524  }
3525 
3526  //================================================ Done
3527  return ;
3528 
3529 }
3530 
3536 {
3537  //================================================ Initialise variables
3538  this->xCom = 0.0;
3539  this->yCom = 0.0;
3540  this->zCom = 0.0;
3541  proshade_double totNonZeroPoints = 0.0;
3542  proshade_signed mapIt = 0;
3543 
3544  //================================================ Compute COM from 0 ; 0 ; 0
3545  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3546  {
3547  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3548  {
3549  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3550  {
3551  //==================================== Find map index
3552  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3553 
3554  //==================================== Use only positive density
3555  if ( this->internalMap[mapIt] <= 0.0 ) { continue; }
3556 
3557  //==================================== Compute Index COM
3558  this->xCom += this->internalMap[mapIt] * static_cast<proshade_double> ( xIt + this->xFrom );
3559  this->yCom += this->internalMap[mapIt] * static_cast<proshade_double> ( yIt + this->yFrom );
3560  this->zCom += this->internalMap[mapIt] * static_cast<proshade_double> ( zIt + this->zFrom );
3561  totNonZeroPoints += this->internalMap[mapIt];
3562  }
3563  }
3564  }
3565 
3566  this->xCom /= totNonZeroPoints;
3567  this->yCom /= totNonZeroPoints;
3568  this->zCom /= totNonZeroPoints;
3569 
3570  //================================================ Convert to real world
3571  this->xCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->xFrom ) * ( this->xDimSizeOriginal / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) +
3572  ( ( static_cast< proshade_single > ( this->xCom ) - static_cast< proshade_single > ( this->xFrom ) ) *
3573  ( static_cast< proshade_single > ( this->xDimSizeOriginal ) / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) );
3574  this->yCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->yFrom ) * ( this->yDimSizeOriginal / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) +
3575  ( ( static_cast< proshade_single > ( this->yCom ) - static_cast< proshade_single > ( this->yFrom ) ) *
3576  ( static_cast< proshade_single > ( this->yDimSizeOriginal ) / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) );
3577  this->zCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->zFrom ) * ( this->zDimSizeOriginal / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) +
3578  ( ( static_cast< proshade_single > ( this->zCom ) - static_cast< proshade_single > ( this->zFrom ) ) *
3579  ( static_cast< proshade_single > ( this->zDimSizeOriginal ) / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) );
3580 
3581  //================================================ Done
3582  return ;
3583 
3584 }
3585 
3591 {
3592  //================================================ Return the value
3593  return ( this->noSpheres );
3594 }
3595 
3601 proshade_double ProSHADE_internal_data::ProSHADE_data::getMapValue ( proshade_unsign pos )
3602 {
3603  //================================================ Return the value
3604  return ( this->internalMap[pos] );
3605 }
3606 
3612 {
3613  //================================================ Return the value
3614  return ( this->maxShellBand );
3615 }
3616 
3621 proshade_double ProSHADE_internal_data::ProSHADE_data::getRRPValue ( proshade_unsign band, proshade_unsign sh1, proshade_unsign sh2 )
3622 {
3623  //================================================ Return the value
3624  return ( this->rrpMatrices[band][sh1][sh2] );
3625 }
3626 
3637 bool ProSHADE_internal_data::ProSHADE_data::shellBandExists ( proshade_unsign shell, proshade_unsign bandVal )
3638 {
3639  if ( this->spheres[shell]->getLocalBandwidth( ) >= bandVal )
3640  {
3641  return ( true );
3642  }
3643  else
3644  {
3645  return ( false );
3646  }
3647 }
3648 
3658 {
3659  //================================================ Report function start
3660  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Removing phase from the map.", settings->messageShift );
3661 
3662  //================================================ Copy map for processing
3663  fftw_complex* mapCoeffs = new fftw_complex[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3664  fftw_complex* pattersonMap = new fftw_complex[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3665 
3666  //================================================ Check memory allocation
3667  ProSHADE_internal_misc::checkMemoryAllocation ( mapCoeffs, __FILE__, __LINE__, __func__ );
3668  ProSHADE_internal_misc::checkMemoryAllocation ( pattersonMap, __FILE__, __LINE__, __func__ );
3669 
3670  //================================================ Copy data to map
3671  for ( proshade_unsign iter = 0; iter < (this->xDimIndices * this->yDimIndices * this->zDimIndices); iter++ )
3672  {
3673  pattersonMap[iter][0] = this->internalMap[iter];
3674  pattersonMap[iter][1] = 0.0;
3675  }
3676 
3677  //================================================ Prepare FFTW plans
3678  fftw_plan forward = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3679  pattersonMap, mapCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3680  fftw_plan inverse = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3681  mapCoeffs, pattersonMap, FFTW_BACKWARD, FFTW_ESTIMATE );
3682 
3683  //================================================ Run forward Fourier
3684  fftw_execute ( forward );
3685 
3686  //================================================ Remove the phase
3687  ProSHADE_internal_mapManip::removeMapPhase ( mapCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices );
3688 
3689  //================================================ Run inverse Fourier
3690  fftw_execute ( inverse );
3691 
3692  //================================================ Save the results
3693  proshade_signed mapIt, patIt, patX, patY, patZ;
3694  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3695  {
3696  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3697  {
3698  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3699  {
3700  //==================================== Centre patterson map
3701  patX = xIt - ( static_cast<proshade_signed> ( this->xDimIndices ) / 2 ); if ( patX < 0 ) { patX += this->xDimIndices; }
3702  patY = yIt - ( static_cast<proshade_signed> ( this->yDimIndices ) / 2 ); if ( patY < 0 ) { patY += this->yDimIndices; }
3703  patZ = zIt - ( static_cast<proshade_signed> ( this->zDimIndices ) / 2 ); if ( patZ < 0 ) { patZ += this->zDimIndices; }
3704 
3705  //==================================== Find indices
3706  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3707  patIt = patZ + static_cast< proshade_signed > ( this->zDimIndices ) * ( patY + static_cast< proshade_signed > ( this->yDimIndices ) * patX );
3708 
3709  //==================================== Copy
3710  this->internalMap[mapIt] = pattersonMap[patIt][0];
3711  }
3712  }
3713  }
3714 
3715  //================================================ Release memory
3716  delete[] pattersonMap;
3717  delete[] mapCoeffs;
3718 
3719  //================================================ Delete FFTW plans
3720  fftw_destroy_plan ( forward );
3721  fftw_destroy_plan ( inverse );
3722 
3723  //================================================ Change settings to reflect Patterson map
3724  if ( !settings->usePhase )
3725  {
3726  this->xDimSize *= 2.0f;
3727  this->yDimSize *= 2.0f;
3728  this->zDimSize *= 2.0f;
3729  settings->setResolution ( settings->requestedResolution * 2.0f );
3730  }
3731 
3732  //================================================ Report function completion
3733  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Phase information removed.", settings->messageShift );
3734 
3735  //================================================ Done
3736  return ;
3737 
3738 }
3739 
3744 proshade_double* ProSHADE_internal_data::ProSHADE_data::getRealSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3745 {
3746  //================================================ Done
3747  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3748  static_cast< int > ( band ),
3749  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][0] );
3750 
3751 }
3752 
3757 proshade_double* ProSHADE_internal_data::ProSHADE_data::getImagSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3758 {
3759  //================================================ Done
3760  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3761  static_cast< int > ( band ),
3762  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][1] );
3763 
3764 }
3765 
3770 proshade_double ProSHADE_internal_data::ProSHADE_data::getAnySphereRadius ( proshade_unsign shell )
3771 {
3772  //================================================ Done
3773  return ( this->spheres[shell]->getShellRadius() );
3774 
3775 }
3776 
3782 {
3783  //================================================ Done
3784  return ( this->integrationWeight );
3785 
3786 }
3787 
3793 proshade_unsign ProSHADE_internal_data::ProSHADE_data::getShellBandwidth ( proshade_unsign shell )
3794 {
3795  //================================================ Done
3796  return ( this->spheres[shell]->getLocalBandwidth ( ) );
3797 
3798 }
3799 
3805 proshade_single ProSHADE_internal_data::ProSHADE_data::getSpherePosValue ( proshade_unsign shell )
3806 {
3807  //================================================ Done
3808  return ( this->spherePos.at(shell) );
3809 
3810 }
3811 
3817 proshade_complex** ProSHADE_internal_data::ProSHADE_data::getEMatrixByBand ( proshade_unsign band )
3818 {
3819  //================================================ Done
3820  return ( this->eMatrices[band] );
3821 
3822 }
3823 
3832 void ProSHADE_internal_data::ProSHADE_data::getEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
3833 {
3834  //================================================ Set pointer
3835  *valueReal = this->eMatrices[band][order1][order2][0];
3836  *valueImag = this->eMatrices[band][order1][order2][1];
3837 
3838  //================================================ Done
3839  return ;
3840 
3841 }
3842 
3848 {
3849  //================================================ Done
3850  return ( this->so3CoeffsInverse );
3851 
3852 }
3853 
3859 {
3860  //================================================ Done
3861  return ( this->so3Coeffs );
3862 
3863 }
3864 
3870 {
3871  //================================================ Done
3872  return ( this->maxCompBand );
3873 
3874 }
3875 
3884 void ProSHADE_internal_data::ProSHADE_data::getWignerMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
3885 {
3886  //================================================ Set pointer
3887  *valueReal = this->wignerMatrices[band][order1][order2][0];
3888  *valueImag = this->wignerMatrices[band][order1][order2][1];
3889 
3890  //================================================ Done
3891  return ;
3892 
3893 }
3894 
3900 {
3901  //================================================ Return the requested value
3902  return ( this->xDimSize );
3903 }
3904 
3910 {
3911  //================================================ Return the requested value
3912  return ( this->yDimSize );
3913 }
3914 
3920 {
3921  //================================================ Return the requested value
3922  return ( this->zDimSize );
3923 }
3924 
3930 {
3931  //================================================ Return the requested value
3932  return ( this->xDimIndices );
3933 }
3934 
3940 {
3941  //================================================ Return the requested value
3942  return ( this->yDimIndices );
3943 }
3944 
3950 {
3951  //================================================ Return the requested value
3952  return ( this->zDimIndices );
3953 }
3954 
3960 {
3961  //================================================ Return the requested value
3962  return ( &this->xFrom );
3963 }
3964 
3970 {
3971  //================================================ Return the requested value
3972  return ( &this->yFrom );
3973 }
3974 
3980 {
3981  //================================================ Return the requested value
3982  return ( &this->zFrom );
3983 }
3984 
3990 {
3991  //================================================ Return the requested value
3992  return ( &this->xTo );
3993 }
3994 
4000 {
4001  //================================================ Return the requested value
4002  return ( &this->yTo );
4003 }
4004 
4010 {
4011  //================================================ Return the requested value
4012  return ( &this->zTo );
4013 }
4014 
4020 {
4021  //================================================ Return the requested value
4022  return ( &this->xAxisOrigin );
4023 }
4024 
4030 {
4031  //================================================ Return the requested value
4032  return ( &this->yAxisOrigin );
4033 }
4034 
4040 {
4041  //================================================ Return the requested value
4042  return ( &this->zAxisOrigin );
4043 }
4044 
4050 {
4051  //================================================ Return the requested value
4052  return ( this->internalMap );
4053 }
4054 
4060 {
4061  //================================================ Return the requested value
4062  return ( this->translationMap );
4063 }
4064 
4070 {
4071  //================================================ Initialise local variables
4072  std::vector< proshade_double > ret;
4073 
4074  //================================================ Save the values
4075  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeX );
4076  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeY );
4077  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeZ );
4078 
4079  //================================================ Return the requested value
4080  return ( ret );
4081 }
4082 
4088 {
4089  //================================================ Mutate
4090  this->integrationWeight = intW;
4091 
4092  //================================================ Done
4093  return ;
4094 
4095 }
4096 
4102 {
4103  //================================================ Mutate
4104  this->integrationWeight += intW;
4105 
4106  //================================================ Done
4107  return ;
4108 
4109 }
4110 
4118 void ProSHADE_internal_data::ProSHADE_data::setEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_complex val )
4119 {
4120  //================================================ Mutate
4121  this->eMatrices[band][order1][order2][0] = val[0];
4122  this->eMatrices[band][order1][order2][1] = val[1];
4123 
4124  //================================================ Done
4125  return ;
4126 
4127 }
4128 
4136 void ProSHADE_internal_data::ProSHADE_data::normaliseEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double normF )
4137 {
4138  //================================================ Mutate
4139  this->eMatrices[band][order1][order2][0] /= normF;
4140  this->eMatrices[band][order1][order2][1] /= normF;
4141 
4142  //================================================ Done
4143  return ;
4144 
4145 }
4146 
4152 void ProSHADE_internal_data::ProSHADE_data::setSO3CoeffValue ( proshade_unsign position, proshade_complex val )
4153 {
4154  //================================================ Mutate
4155  this->so3Coeffs[position][0] = val[0];
4156  this->so3Coeffs[position][1] = val[1];
4157 
4158  //================================================ Done
4159  return ;
4160 
4161 }
4162 
4170 void ProSHADE_internal_data::ProSHADE_data::setWignerMatrixValue ( proshade_complex val, proshade_unsign band, proshade_unsign order1, proshade_unsign order2 )
4171 {
4172  //================================================ Mutate
4173  this->wignerMatrices[band][order1][order2][0] = val[0];
4174  this->wignerMatrices[band][order1][order2][1] = val[1];
4175 
4176  //================================================ Done
4177  return ;
4178 
4179 }
4180 
4188 void ProSHADE_internal_data::ProSHADE_data::getRealEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMReal, int len )
4189 {
4190  //================================================ Save the data into the output array
4191  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4192  {
4193  eMatsLMReal[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][0] );
4194  }
4195 
4196  //================================================ Done
4197  return ;
4198 
4199 }
4200 
4208 void ProSHADE_internal_data::ProSHADE_data::getImagEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMImag, int len )
4209 {
4210  //================================================ Save the data into the output array
4211  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4212  {
4213  eMatsLMImag[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][1] );
4214  }
4215 
4216  //================================================ Done
4217  return ;
4218 
4219 }
4220 
4226 void ProSHADE_internal_data::ProSHADE_data::getRealSO3Coeffs ( double *so3CoefsReal, int len )
4227 {
4228  //================================================ Save the data into the output array
4229  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4230  {
4231  so3CoefsReal[iter] = static_cast<double> ( this->so3Coeffs[iter][0] );
4232  }
4233 
4234  //================================================ Done
4235  return ;
4236 
4237 }
4238 
4244 void ProSHADE_internal_data::ProSHADE_data::getImagSO3Coeffs ( double *so3CoefsImag, int len )
4245 {
4246  //================================================ Save the data into the output array
4247  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4248  {
4249  so3CoefsImag[iter] = static_cast<double> ( this->so3Coeffs[iter][1] );
4250  }
4251 
4252  //================================================ Done
4253  return ;
4254 
4255 }
4256 
4266 int ProSHADE_internal_data::ProSHADE_data::so3CoeffsArrayIndex ( proshade_signed order1, proshade_signed order2, proshade_signed band )
4267 {
4268  //================================================ Return the value
4269  return ( static_cast<int> ( so3CoefLoc ( static_cast< int > ( order1 ), static_cast< int > ( order2 ), static_cast< int > ( band ), static_cast< int > ( this->getMaxBand() ) ) ) );
4270 }
4271 
4278 {
4279  //================================================ Save the data into the output array
4280  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4281  {
4282  rotFunReal[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][0] );
4283  }
4284 
4285  //================================================ Done
4286  return ;
4287 
4288 }
4289 
4296 {
4297  //================================================ Save the data into the output array
4298  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4299  {
4300  rotFunImag[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][1] );
4301  }
4302 
4303  //================================================ Done
4304  return ;
4305 
4306 }
4307 
4314 {
4315  //================================================ Save the data into the output array
4316  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4317  {
4318  trsFunReal[iter] = static_cast<double> ( this->translationMap[iter][0] );
4319  }
4320 
4321  //================================================ Done
4322  return ;
4323 
4324 }
4325 
4332 {
4333  //================================================ Save the data into the output array
4334  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4335  {
4336  trsFunImag[iter] = static_cast<double> ( this->translationMap[iter][1] );
4337  }
4338 
4339  //================================================ Done
4340  return ;
4341 
4342 }
4343 
4352 void ProSHADE_internal_data::ProSHADE_data::getRotMatrixFromRotFunInds ( proshade_signed aI, proshade_signed bI, proshade_signed gI, double *rotMat, int len )
4353 {
4354  //================================================ Get Euler angles
4355  proshade_double eA, eB, eG;
4356  ProSHADE_internal_maths::getEulerZXZFromSOFTPosition ( static_cast< int > ( this->getMaxBand() ), aI, bI, gI, &eA, &eB, &eG );
4357 
4358  //================================================ Prepare internal rotation matrix memory
4359  proshade_double* rMat = nullptr;
4360  rMat = new proshade_double[9];
4361  ProSHADE_internal_misc::checkMemoryAllocation ( rMat, __FILE__, __LINE__, __func__ );
4362 
4363  //================================================ Convert to rotation matrix
4365 
4366  //================================================ Copy to output
4367  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4368  {
4369  rotMat[iter] = static_cast<double> ( rMat[iter] );
4370  }
4371 
4372  //================================================ Release internal memory
4373  delete[] rMat;
4374 
4375  //================================================ Done
4376  return ;
4377 
4378 }
4379 
4385 {
4386  //================================================ Return the value
4387  return ( settings->recommendedSymmetryType );
4388 
4389 }
4390 
4396 {
4397  //================================================ Return the value
4398  return ( settings->recommendedSymmetryFold );
4399 
4400 }
4401 
4408 {
4409  //================================================ Return the value
4410  return ( static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ) );
4411 }
4412 
4419 std::vector< std::string > ProSHADE_internal_data::ProSHADE_data::getSymmetryAxis ( ProSHADE_settings* settings, proshade_unsign axisNo )
4420 {
4421  //================================================ Sanity checks
4422  if ( static_cast<proshade_unsign> ( settings->detectedSymmetry.size() ) <= axisNo )
4423  {
4424  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested symmetry index does not exist. Returning empty vector.", "WS00039" );
4425  return ( std::vector< std::string > ( ) );
4426  }
4427 
4428  //================================================ Initialise local variables
4429  std::vector< std::string > ret;
4430 
4431  //================================================ Input the axis data as strings
4432  std::stringstream ssHlp;
4433  ssHlp << settings->detectedSymmetry.at(axisNo)[0];
4434  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4435  ssHlp.str ( "" );
4436 
4437  ssHlp << settings->detectedSymmetry.at(axisNo)[1];
4438  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4439  ssHlp.str ( "" );
4440 
4441  ssHlp << settings->detectedSymmetry.at(axisNo)[2];
4442  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4443  ssHlp.str ( "" );
4444 
4445  ssHlp << settings->detectedSymmetry.at(axisNo)[3];
4446  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4447  ssHlp.str ( "" );
4448 
4449  ssHlp << settings->detectedSymmetry.at(axisNo)[4];
4450  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4451  ssHlp.str ( "" );
4452 
4453  ssHlp << settings->detectedSymmetry.at(axisNo)[5];
4454  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4455  ssHlp.str ( "" );
4456 
4457  ssHlp << settings->detectedSymmetry.at(axisNo)[6];
4458  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4459  ssHlp.str ( "" );
4460 
4461  //================================================ Done
4462  return ( ret );
4463 
4464 }
4465 
4478 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 )
4479 {
4480  //================================================ Write out rotated map
4481  std::stringstream fNameHlp;
4482  fNameHlp << settings->overlayStructureName << ".map";
4483  this->writeMap ( fNameHlp.str() );
4484 
4485  //================================================ Write out rotated co-ordinates if possible
4486  if ( ProSHADE_internal_io::isFilePDB ( this->fileName ) )
4487  {
4488  fNameHlp.str("");
4489  fNameHlp << settings->overlayStructureName << ".pdb";
4490  this->writePdb ( fNameHlp.str(), eulA, eulB, eulG, ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2), rotCentre->at(0), rotCentre->at(1), rotCentre->at(2), settings->firstModelOnly );
4491  }
4492 
4493  //================================================ Write out the json file with the results
4494  ProSHADE_internal_io::writeRotationTranslationJSON ( rotCentre->at(0), rotCentre->at(1), rotCentre->at(2),
4495  eulA, eulB, eulG,
4496  ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2),
4497  settings->rotTrsJSONFile );
4498 
4499  //================================================ Done
4500  return ;
4501 
4502 }
4503 
4512 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 )
4513 {
4514  //================================================ Empty line
4516 
4517  //================================================ Write out rotation centre translation results
4518  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);
4519  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotCen.str(), settings->messageShift );
4520 
4521  //================================================ Write out rotation matrix about origin
4522  proshade_double* rotMat = new proshade_double[9];
4523  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
4524  ProSHADE_internal_maths::getRotationMatrixFromEulerZXZAngles ( eulerAngles->at(0), eulerAngles->at(1), eulerAngles->at(2), rotMat );
4525 
4526  std::stringstream rotMatSS;
4527  rotMatSS << std::setprecision (3) << std::showpos << "The rotation matrix about origin is : " << rotMat[0] << " " << rotMat[1] << " " << rotMat[2] << std::endl;
4528  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[3] << " " << rotMat[4] << " " << rotMat[5] << std::endl;
4529  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[6] << " " << rotMat[7] << " " << rotMat[8];
4530  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotMatSS.str(), settings->messageShift );
4531 
4532  delete[] rotMat;
4533 
4534  //================================================ Write out origin to overlay translation results
4535  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);
4536  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, finTrs.str(), settings->messageShift );
4537 
4538  //================================================ Done
4539  return ;
4540 
4541 }
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:1181
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:1847
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:131
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:3817
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:146
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:3919
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:446
ProSHADE_internal_data::ProSHADE_data::readInMAP
void readInMAP(ProSHADE_settings *settings, proshade_double *maskArr=nullptr, proshade_unsign maskXDim=0, proshade_unsign maskYDim=0, proshade_unsign maskZDim=0, proshade_double *weightsArr=nullptr, proshade_unsign weigXDim=0, proshade_unsign weigYDim=0, proshade_unsign weigZDim=0)
Function for reading map data using gemmi library.
Definition: ProSHADE_data.cpp:619
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:1374
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:3092
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:1316
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:1853
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:3869
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:4395
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:4087
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::getXAxisOrigin
proshade_signed * getXAxisOrigin(void)
This function allows access to the map X axis origin value.
Definition: ProSHADE_data.cpp:4019
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:1657
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:4136
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:93
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:4331
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:4170
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:156
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:2276
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:134
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:133
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:3832
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:3899
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:4049
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:3909
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:1074
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:3590
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:4152
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:974
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:4352
ProSHADE_settings::setDetectedSymmetry
void setDetectedSymmetry(proshade_double *sym)
Sets the final detected symmetry axes information.
Definition: ProSHADE.cpp:1553
ProSHADE_internal_io::applyMask
void applyMask(proshade_double *&map, std::string maskFile, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_signed verbose, proshade_signed messageShift, proshade_double *maskArray=nullptr, proshade_unsign maXInds=0, proshade_unsign maYInds=0, proshade_unsign maZInds=0)
This function reads and applies the mask to the map.
Definition: ProSHADE_io.cpp:295
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:813
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:3770
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:107
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:575
ProSHADE_internal_data::ProSHADE_data::getSO3Coeffs
proshade_complex * getSO3Coeffs(void)
This function allows access to the SO(3) coefficients array.
Definition: ProSHADE_data.cpp:3858
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:1746
ProSHADE_internal_data::ProSHADE_data::invertMirrorMap
void invertMirrorMap(ProSHADE_settings *settings)
Function for inverting the map to its mirror image.
Definition: ProSHADE_data.cpp:1175
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:1020
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:3051
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:4069
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, proshade_double *&fscByBin)
This function takes the D symmetries and searched for the requested symmetry.
Definition: ProSHADE_data.cpp:2876
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:157
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:102
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:3781
ProSHADE_internal_io::figureDataType
InputType figureDataType(std::string fName)
Function determining input data type.
Definition: ProSHADE_io.cpp:923
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:4101
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:1217
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:4419
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:158
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:1520
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:3959
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:149
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:3447
ProSHADE_settings::messageShift
proshade_signed messageShift
This value allows shifting the messages to create more readable log for sub-processes.
Definition: ProSHADE_settings.hpp:150
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:3884
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:3793
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:4407
ProSHADE_internal_data::ProSHADE_data::shiftToRotationCentre
void shiftToRotationCentre(ProSHADE_settings *settings)
Function for shifting map so that its rotation centre is at the centre of the box.
Definition: ProSHADE_data.cpp:1140
ProSHADE_internal_data::ProSHADE_data::setPDBMapValues
void setPDBMapValues(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:824
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:3535
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:4277
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:3929
ProSHADE_internal_mapManip::removeWaters
void removeWaters(gemmi::Structure *pdbFile, bool firstModel)
This function removed all waters from PDB input file.
Definition: ProSHADE_mapManip.cpp:506
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::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, proshade_double *&fscByBin)
This function computes FSC for any given axis in the supplied CSym symmetry axes vector.
Definition: ProSHADE_data.cpp:2391
ProSHADE_internal_data::ProSHADE_data::readInStructure
void readInStructure(std::string fName, proshade_unsign inputO, ProSHADE_settings *settings, proshade_double *maskArr=nullptr, proshade_unsign maskXDim=0, proshade_unsign maskYDim=0, proshade_unsign maskZDim=0, proshade_double *weightsArr=nullptr, proshade_unsign weigXDim=0, proshade_unsign weigYDim=0, proshade_unsign weigZDim=0)
This function initialises the basic ProSHADE_data variables and reads in a single structure.
Definition: ProSHADE_data.cpp:509
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:1038
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:2824
ProSHADE_settings::peakThresholdMin
proshade_double peakThresholdMin
The threshold for peak height above which axes are considered possible.
Definition: ProSHADE_settings.hpp:138
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:1803
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_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_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, proshade_double *&fscByBin)
This function takes all the detected symmetry results and decides on which are to be recommended for ...
Definition: ProSHADE_data.cpp:2558
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:335
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:3744
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::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, proshade_double rotX=0.0, proshade_double rotY=0.0, proshade_double rotZ=0.0, bool firstModel=true)
This function writes out the co-ordinates file with ProSHADE type rotation and translation applied.
Definition: ProSHADE_data.cpp:959
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:4512
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:1459
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:892
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:3637
ProSHADE_internal_data::ProSHADE_data::getMaxBand
proshade_unsign getMaxBand(void)
This function returns the maximum band value for the object.
Definition: ProSHADE_data.cpp:3611
ProSHADE_internal_data::ProSHADE_data::shiftToBoxCentre
void shiftToBoxCentre(ProSHADE_settings *settings)
Function for shifting map so that its centre of box is at required position.
Definition: ProSHADE_data.cpp:1075
ProSHADE_settings::appliedMaskFileName
std::string appliedMaskFileName
The filename from which mask data will be read from.
Definition: ProSHADE_settings.hpp:86
ProSHADE_settings::coOrdsExtraSpace
proshade_single coOrdsExtraSpace
This number of Angstroms will be added before and any co-ordinates to make sure there is no atom dire...
Definition: ProSHADE_settings.hpp:104
ProSHADE_settings::normaliseMap
bool normaliseMap
Should the map be normalised to mean 0 sd 1?
Definition: ProSHADE_settings.hpp:72
ProSHADE_internal_data::ProSHADE_data::writeGemmi
void writeGemmi(std::string fName, gemmi::Structure gemmiStruct, 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, proshade_double rotX=0.0, proshade_double rotY=0.0, proshade_double rotZ=0.0, bool firstModel=true)
This function writes out the gemmi::Structure object with ProSHADE type rotation and translation appl...
Definition: ProSHADE_data.cpp:996
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:103
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:3939
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, proshade_double *&fscByBin)
This function computes the FSC.
Definition: ProSHADE_maths.cpp:3347
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:4208
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:1276
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:1124
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:4313
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:137
ProSHADE_internal_data::ProSHADE_data::readInGemmi
void readInGemmi(gemmi::Structure gemmiStruct, ProSHADE_settings *settings)
Function for reading co-ordinate data from Gemmi object.
Definition: ProSHADE_data.cpp:735
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:3199
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:3757
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:4478
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:4295
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:1695
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:4059
ProSHADE_settings::setRecommendedSymmetry
void setRecommendedSymmetry(std::string val)
Sets the ProSHADE detected symmetry type.
Definition: ProSHADE.cpp:1469
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_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:3949
ProSHADE_settings::centrePosition
std::vector< proshade_double > centrePosition
The position of the centre of the map in "real space" co-ordinates.
Definition: ProSHADE_settings.hpp:142
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:1681
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:94
ProSHADE_internal_maths::findTopGroupSmooth
proshade_double findTopGroupSmooth(std::vector< proshade_double * > *CSym, size_t peakPos, proshade_double step, proshade_double sigma, proshade_signed windowSize, proshade_double maxLim=0.9)
This function finds a subgroup of axes with distinctly higher correlation value.
Definition: ProSHADE_maths.cpp:3743
ProSHADE_internal_data::ProSHADE_data::getSpherePosValue
proshade_single getSpherePosValue(proshade_unsign shell)
This function allows access to sphere positions.
Definition: ProSHADE_data.cpp:3805
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:3621
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:965
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:3003
ProSHADE_settings::overlayStructureName
std::string overlayStructureName
The filename to which the rotated and translated moving structure is to be saved.
Definition: ProSHADE_settings.hpp:145
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:2974
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:3601
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:4244
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:3999
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:99
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::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:4039
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:873
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:1966
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:1440
ProSHADE_settings::boxCentre
std::vector< proshade_double > boxCentre
If box centre is to be in any other location, this variable will hold the real space location that sh...
Definition: ProSHADE_settings.hpp:100
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:298
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:646
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:2552
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:68
ProSHADE_internal_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:3989
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:3969
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:383
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:3479
ProSHADE_internal_data::ProSHADE_data::figureIndexStartStop
void figureIndexStartStop(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:870
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:3847
ProSHADE_settings::allDetectedIAxes
std::vector< proshade_unsign > allDetectedIAxes
The vector of all detected icosahedral symmetry axes indices in allDetectedCAxes.
Definition: ProSHADE_settings.hpp:159
ProSHADE_settings::forceBounds
proshade_signed * forceBounds
These will be the boundaries to be forced upon the map.
Definition: ProSHADE_settings.hpp:96
ProSHADE_settings::fourierWeightsFileName
std::string fourierWeightsFileName
The filename from which Fourier weights data will be read from.
Definition: ProSHADE_settings.hpp:89
ProSHADE_settings::detectedSymmetry
std::vector< proshade_double * > detectedSymmetry
The vector of detected symmetry axes.
Definition: ProSHADE_settings.hpp:154
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:132
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:1427
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:2132
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:4029
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:1887
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:128
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:95
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:2939
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:4384
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:1492
ProSHADE_internal_io::applyWeights
void applyWeights(proshade_double *&map, std::string weightsFile, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_signed verbose, proshade_signed messageShift, proshade_double *weightsArray=nullptr, proshade_unsign waXInds=0, proshade_unsign waYInds=0, proshade_unsign waZInds=0)
This function reads and applies the Fourier weights to the map.
Definition: ProSHADE_io.cpp:566
ProSHADE_settings::setVariablesLeftOnAuto
void setVariablesLeftOnAuto(void)
Function to determine general values that the user left on auto-determination.
Definition: ProSHADE.cpp:503
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:4118
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:1229
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:1907
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_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:4226
ProSHADE_internal_messages::printProgressMessage
void printProgressMessage(proshade_signed verbose, proshade_signed messageLevel, std::string message, proshade_signed messageShift=0)
General stdout message printing.
Definition: ProSHADE_messages.cpp:71
ProSHADE_internal_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:549
ProSHADE_settings::allDetectedCAxes
std::vector< std::vector< proshade_double > > allDetectedCAxes
The vector of all detected cyclic symmetry axes.
Definition: ProSHADE_settings.hpp:155
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:3657
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:765
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:2499
ProSHADE_settings::fastISearch
bool fastISearch
Should FSC be computed for all possible I matches, or just for the best one according to FR?
Definition: ProSHADE_settings.hpp:139
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:3151
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:1585
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:4188
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:3025
ProSHADE_internal_data::ProSHADE_data::readInPDB
void readInPDB(ProSHADE_settings *settings)
Function for reading pdb data.
Definition: ProSHADE_data.cpp:700
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, proshade_double *&fscByBin)
This function allocates the memory and makes all preparations required for FSC computation.
Definition: ProSHADE_data.cpp:2320
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:3979
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:4009
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:4266