ProSHADE  0.7.6.6 (JUL 2022)
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  void findPredictedAxesHeights ( std::vector< proshade_double* >* ret, ProSHADE_internal_data::ProSHADE_data* dataObj, ProSHADE_settings* settings );
78 }
79 
80 //==================================================== Local functions prototypes
81 void axesToGroupTypeSanityCheck ( proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType );
82 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance );
83 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance );
84 bool sortProSHADESymmetryByFSC ( proshade_double* a, proshade_double* b );
85 
95 {
96  //================================================ Initialise variables
97  // ... Variables regarding input file
98  this->fileName = "";
99  this->fileType = ProSHADE_internal_io::UNKNOWN;
100 
101  // ... Variables regarding map
102  this->internalMap = nullptr;
103 
104  // ... Variables regarding map information
105  this->xDimSize = 0.0;
106  this->yDimSize = 0.0;
107  this->zDimSize = 0.0;
108  this->aAngle = 0.0;
109  this->bAngle = 0.0;
110  this->cAngle = 0.0;
111  this->xDimIndices = 0;
112  this->yDimIndices = 0;
113  this->zDimIndices = 0;
114  this->xGridIndices = 0;
115  this->yGridIndices = 0;
116  this->zGridIndices = 0;
117  this->xAxisOrder = 1;
118  this->yAxisOrder = 2;
119  this->zAxisOrder = 3;
120  this->xAxisOrigin = 0;
121  this->yAxisOrigin = 0;
122  this->zAxisOrigin = 0;
123  this->xCom = 0.0;
124  this->yCom = 0.0;
125  this->zCom = 0.0;
126 
127  // ... Variables regarding original input values (i.e. these do not change with ProSHADE manipulations)
128  this->xDimSizeOriginal = 0.0;
129  this->yDimSizeOriginal = 0.0;
130  this->zDimSizeOriginal = 0.0;
131  this->xDimIndicesOriginal = 0;
132  this->yDimIndicesOriginal = 0;
133  this->zDimIndicesOriginal = 0;
134  this->xAxisOriginOriginal = 0;
135  this->yAxisOriginOriginal = 0;
136  this->zAxisOriginOriginal = 0;
137  this->originalMapXCom = 0.0;
138  this->originalMapYCom = 0.0;
139  this->originalMapZCom = 0.0;
140  this->mapMovFromsChangeX = 0.0;
141  this->mapMovFromsChangeY = 0.0;
142  this->mapMovFromsChangeZ = 0.0;
143  this->mapCOMProcessChangeX = 0.0;
144  this->mapCOMProcessChangeY = 0.0;
145  this->mapCOMProcessChangeZ = 0.0;
146 
147  // ... Variables regarding rotation and translation of original input files
148  this->originalPdbRotCenX = 0.0;
149  this->originalPdbRotCenY = 0.0;
150  this->originalPdbRotCenZ = 0.0;
151  this->originalPdbTransX = 0.0;
152  this->originalPdbTransY = 0.0;
153  this->originalPdbTransZ = 0.0;
154 
155  // ... Variables regarding iterator positions
156  this->xFrom = 0;
157  this->yFrom = 0;
158  this->zFrom = 0;
159  this->xTo = 0;
160  this->yTo = 0;
161  this->zTo = 0;
162 
163  // ... Variables regarding SH mapping spheres
164  this->spherePos = std::vector<proshade_single> ( );
165  this->noSpheres = 0;
166  this->spheres = nullptr;
167  this->sphericalHarmonics = nullptr;
168  this->rotSphericalHarmonics = nullptr;
169  this->maxShellBand = 0;
170 
171  // ... Variables regarding shape distance computations
172  this->rrpMatrices = nullptr;
173  this->eMatrices = nullptr;
174  this->so3Coeffs = nullptr;
175  this->so3CoeffsInverse = nullptr;
176  this->wignerMatrices = nullptr;
177  this->integrationWeight = 0.0;
178  this->maxEMatDim = 0;
179  this->translationMap = nullptr;
180 
181  // ... Symmetry detectino
182  this->recommendedSymmetryFold = 1;
183  this->recommendedSymmetryType = 'C';
184 
185  // ... Control variables
186  this->isEmpty = true;
187 
188  //================================================ Done
189 
190 }
191 
218 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 )
219 {
220  //================================================ Initialise variables
221  // ... Variables regarding input file
222  this->fileName = strName;
223  this->fileType = ProSHADE_internal_io::MAP;
224 
225  // ... Variables regarding map
226  this->internalMap = nullptr;
227 
228  // ... Variables regarding map information
229  this->xDimSize = xDmSz;
230  this->yDimSize = yDmSz;
231  this->zDimSize = zDmSz;
232  this->aAngle = 90.0;
233  this->bAngle = 90.0;
234  this->cAngle = 90.0;
235  this->xDimIndices = xDmInd;
236  this->yDimIndices = yDmInd;
237  this->zDimIndices = zDmInd;
238  this->xGridIndices = xDmInd;
239  this->yGridIndices = yDmInd;
240  this->zGridIndices = zDmInd;
241  this->xAxisOrder = 1;
242  this->yAxisOrder = 2;
243  this->zAxisOrder = 3;
244  this->xAxisOrigin = xFr;
245  this->yAxisOrigin = yFr;
246  this->zAxisOrigin = zFr;
247  this->xCom = 0.0;
248  this->yCom = 0.0;
249  this->zCom = 0.0;
250 
251  // ... Variables regarding original input values (i.e. these do not change with ProSHADE manipulations)
252  this->xDimSizeOriginal = 0.0;
253  this->yDimSizeOriginal = 0.0;
254  this->zDimSizeOriginal = 0.0;
255  this->xDimIndicesOriginal = 0;
256  this->yDimIndicesOriginal = 0;
257  this->zDimIndicesOriginal = 0;
258  this->xAxisOriginOriginal = 0;
259  this->yAxisOriginOriginal = 0;
260  this->zAxisOriginOriginal = 0;
261  this->originalMapXCom = 0.0;
262  this->originalMapYCom = 0.0;
263  this->originalMapZCom = 0.0;
264  this->mapMovFromsChangeX = 0.0;
265  this->mapMovFromsChangeY = 0.0;
266  this->mapMovFromsChangeZ = 0.0;
267  this->mapCOMProcessChangeX = 0.0;
268  this->mapCOMProcessChangeY = 0.0;
269  this->mapCOMProcessChangeZ = 0.0;
270 
271  // ... Variables regarding rotation and translation of original input files
272  this->originalPdbRotCenX = 0.0;
273  this->originalPdbRotCenY = 0.0;
274  this->originalPdbRotCenZ = 0.0;
275  this->originalPdbTransX = 0.0;
276  this->originalPdbTransY = 0.0;
277  this->originalPdbTransZ = 0.0;
278 
279  // ... Variables regarding iterator positions
280  this->xFrom = xFr;
281  this->yFrom = yFr;
282  this->zFrom = zFr;
283  this->xTo = xT;
284  this->yTo = yT;
285  this->zTo = zT;
286 
287  // ... Variables regarding SH mapping spheres
288  this->spherePos = std::vector<proshade_single> ( );
289  this->noSpheres = 0;
290  this->spheres = nullptr;
291  this->sphericalHarmonics = nullptr;
292  this->rotSphericalHarmonics = nullptr;
293  this->maxShellBand = 0;
294 
295  // ... Variables regarding shape distance computations
296  this->rrpMatrices = nullptr;
297  this->eMatrices = nullptr;
298  this->so3Coeffs = nullptr;
299  this->so3CoeffsInverse = nullptr;
300  this->wignerMatrices = nullptr;
301  this->integrationWeight = 0.0;
302  this->maxEMatDim = 0;
303  this->translationMap = nullptr;
304 
305  // ... Control variables
306  this->isEmpty = false;
307  this->inputOrder = inputO;
308 
309  //================================================ Sanity checks
310  if ( static_cast<proshade_unsign> ( len ) != ( xDmInd * yDmInd * zDmInd ) )
311  {
312  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." );
313  }
314 
315  if ( ( static_cast<proshade_signed> ( xT - xFr ) != static_cast<proshade_signed> ( xDmInd - 1 ) ) ||
316  ( static_cast<proshade_signed> ( yT - yFr ) != static_cast<proshade_signed> ( yDmInd - 1 ) ) ||
317  ( static_cast<proshade_signed> ( zT - zFr ) != static_cast<proshade_signed> ( zDmInd - 1 ) ) )
318  {
319  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." );
320  }
321 
322  //================================================ Allocate the map memory
323  this->internalMap = new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
324  ProSHADE_internal_misc::checkMemoryAllocation ( this->internalMap, __FILE__, __LINE__, __func__ );
325 
326  //================================================ Copy the values into the map
327  proshade_unsign arrPos = 0;
328  for ( proshade_unsign xIt = 0; xIt < this->xDimIndices; xIt++ )
329  {
330  for ( proshade_unsign yIt = 0; yIt < this->yDimIndices; yIt++ )
331  {
332  for ( proshade_unsign zIt = 0; zIt < this->zDimIndices; zIt++ )
333  {
334  arrPos = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
335  this->internalMap[arrPos] = static_cast<proshade_double> ( mapVals[arrPos] );
336  }
337  }
338  }
339 
340  //================================================ Release memory (it was allocated by the PyBind11 lambda function and needs to be released)
341  delete[] mapVals;
342  mapVals = nullptr;
343 
344  //================================================ Done
345 
346 }
347 
355 {
356  //================================================ Release the internal map
357  if ( this->internalMap != nullptr )
358  {
359  delete[] this->internalMap;
360  this->internalMap = nullptr;
361  }
362 
363  //================================================ Release the sphere mapping
364  if ( this->spheres != nullptr )
365  {
366  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
367  {
368  if ( this->spheres[iter] != nullptr )
369  {
370  delete this->spheres[iter];
371  this->spheres[iter] = nullptr;
372  }
373  }
374  delete[] this->spheres;
375  }
376 
377  //================================================ Release the spherical harmonics
378  if ( this->sphericalHarmonics != nullptr )
379  {
380  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
381  {
382  if ( this->sphericalHarmonics[iter] != nullptr )
383  {
384  delete[] this->sphericalHarmonics[iter];
385  this->sphericalHarmonics[iter] = nullptr;
386  }
387  }
388  delete[] this->sphericalHarmonics;
389  }
390 
391  //================================================ Release the rotated spherical harmonics
392  if ( this->rotSphericalHarmonics != nullptr )
393  {
394  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
395  {
396  if ( this->rotSphericalHarmonics[iter] != nullptr )
397  {
398  delete[] this->rotSphericalHarmonics[iter];
399  this->rotSphericalHarmonics[iter] = nullptr;
400  }
401  }
402  delete[] this->rotSphericalHarmonics;
403  }
404 
405  //================================================ Release the RRP matrices (pre-computation for the energy levels descriptor)
406  if ( this->rrpMatrices != nullptr )
407  {
408  for ( proshade_unsign bwIt = 0; bwIt < this->maxShellBand; bwIt++ )
409  {
410  if ( this->rrpMatrices[bwIt] != nullptr )
411  {
412  for ( proshade_unsign shIt = 0; shIt < this->noSpheres; shIt++ )
413  {
414  if ( this->rrpMatrices[bwIt][shIt] != nullptr )
415  {
416  delete[] this->rrpMatrices[bwIt][shIt];
417  this->rrpMatrices[bwIt][shIt] = nullptr;
418  }
419  }
420 
421  delete[] this->rrpMatrices[bwIt];
422  }
423  }
424 
425  delete[] this->rrpMatrices;
426  }
427 
428  //================================================ Release the E matrices
429  if ( this->eMatrices != nullptr )
430  {
431  for ( proshade_unsign bandIter = 0; bandIter < this->getEMatDim ( ); bandIter++ )
432  {
433  if ( this->eMatrices[bandIter] != nullptr )
434  {
435  for ( proshade_unsign band2Iter = 0; band2Iter < static_cast<proshade_unsign> ( ( bandIter * 2 ) + 1 ); band2Iter++ )
436  {
437  if ( this->eMatrices[bandIter][band2Iter] != nullptr )
438  {
439  delete[] this->eMatrices[bandIter][band2Iter];
440  this->eMatrices[bandIter][band2Iter] = nullptr;
441  }
442  }
443 
444  delete[] this->eMatrices[bandIter];
445  }
446  }
447 
448  delete[] this->eMatrices;
449  }
450 
451  //================================================ Release SOFT and inverse SOFT coefficients
452  if ( this->so3Coeffs != nullptr )
453  {
454  fftw_free ( this->so3Coeffs );
455  }
456  if ( this->so3CoeffsInverse != nullptr )
457  {
458  fftw_free ( this->so3CoeffsInverse );
459  }
460 
461  //================================================ Release Wigner matrices
462  if ( this->wignerMatrices != nullptr )
463  {
464  for ( proshade_unsign bandIter = 1; bandIter < this->maxEMatDim; bandIter++ )
465  {
466  if ( this->wignerMatrices[bandIter] != nullptr )
467  {
468  for ( proshade_unsign order1Iter = 0; order1Iter < ( (bandIter * 2) + 1 ); order1Iter++ )
469  {
470  if ( this->wignerMatrices[bandIter][order1Iter] != nullptr )
471  {
472  delete[] this->wignerMatrices[bandIter][order1Iter];
473  }
474  }
475  delete[] this->wignerMatrices[bandIter];
476  }
477  }
478  delete[] wignerMatrices;
479  }
480 
481  //================================================ Release translation map
482  if ( this->translationMap != nullptr )
483  {
484  fftw_free ( this->translationMap );
485  }
486 
487  //================================================ Release the angle-axis space rotation function
488  if ( this->sphereMappedRotFun.size() > 0 )
489  {
490  for ( proshade_unsign spIt = 0; spIt < static_cast<proshade_unsign> ( this->sphereMappedRotFun.size() ); spIt++ )
491  {
492  delete this->sphereMappedRotFun.at(spIt);
493  }
494  }
495 
496  //================================================ Release symmetry result holders
497  for ( size_t vIt = 0; vIt < this->cyclicSymmetries.size(); vIt++ ) { if ( this->cyclicSymmetries.at(vIt) != nullptr ) { delete[] this->cyclicSymmetries.at(vIt); } }
498  for ( size_t vIt = 0; vIt < this->recommendedSymmetryValues.size(); vIt++ ) { if ( this->recommendedSymmetryValues.at(vIt) != nullptr ) { delete[] this->recommendedSymmetryValues.at(vIt); } }
499  for ( size_t vIt = 0; vIt < this->tetrahedralSymmetries.size(); vIt++ ) { if ( this->tetrahedralSymmetries.at(vIt) != nullptr ) { delete[] this->tetrahedralSymmetries.at(vIt); } }
500  for ( size_t vIt = 0; vIt < this->octahedralSymmetries.size(); vIt++ ) { if ( this->octahedralSymmetries.at(vIt) != nullptr ) { delete[] this->octahedralSymmetries.at(vIt); } }
501  for ( size_t vIt = 0; vIt < this->icosahedralSymmetries.size(); vIt++ ) { if ( this->icosahedralSymmetries.at(vIt) != nullptr ) { delete[] this->icosahedralSymmetries.at(vIt); } }
502  for ( size_t vIt = 0; vIt < this->dihedralSymmetries.size(); vIt++ ) { for ( size_t vIt2 = 0; vIt2 < this->dihedralSymmetries.at(vIt).size(); vIt2++ ) { if ( this->dihedralSymmetries.at(vIt).at(vIt2) != nullptr ) { delete[] this->dihedralSymmetries.at(vIt).at(vIt2); } } }
503 
504  //================================================ Done
505 
506 }
507 
525 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 )
526 {
527  //================================================ Report function start
528  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting to read the structure: " + fName, settings->messageShift );
529 
530  //================================================ Check if instance is empty
531  if ( !this->isEmpty )
532  {
533  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 );
534  }
535 
536  //================================================ Save the filename
537  this->fileName = fName;
538 
539  //================================================ Check what is the input format
540  this->fileType = ProSHADE_internal_io::figureDataType ( this->fileName );
541 
542  //================================================ Save input order
543  this->inputOrder = inputO;
544 
545  //================================================ Decide how to proceed
546  switch ( this->fileType )
547  {
548  case ProSHADE_internal_io::UNKNOWN:
549  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." );
550 
551  case ProSHADE_internal_io::GEMMI:
552  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." );
553 
554  case ProSHADE_internal_io::PDB:
555  this->readInPDB ( settings );
556  break;
557 
558  case ProSHADE_internal_io::MAP:
559  this->readInMAP ( settings, maskArr, maskXDim, maskYDim, maskZDim, weightsArr, weigXDim, weigYDim, weigZDim );
560  break;
561  }
562 
563  //================================================ This structure is now full
564  this->isEmpty = false;
565 
566  //================================================ Report function completion
567  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Structure read in successfully.", settings->messageShift );
568 
569  //================================================ Done
570  return ;
571 
572 }
573 
583 void ProSHADE_internal_data::ProSHADE_data::readInStructure ( gemmi::Structure* gemmiStruct, proshade_unsign inputO, ProSHADE_settings* settings )
584 {
585  //================================================ Report function start
586  std::stringstream ss;
587  ss << "Starting to load the structure from Gemmi object " << inputO;
588  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
589 
590  //================================================ Check if instance is empty
591  if ( !this->isEmpty )
592  {
593  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 );
594  }
595 
596  //================================================ Save the filename
597  this->fileName = gemmiStruct->name;
598 
599  //================================================ Check what is the input format
600  this->fileType = ProSHADE_internal_io::GEMMI;
601 
602  //================================================ Save input order
603  this->inputOrder = inputO;
604 
605  //================================================ Decide how to proceed
606  this->readInGemmi ( gemmiStruct, settings );
607 
608  //================================================ This structure is now full
609  this->isEmpty = false;
610 
611  //================================================ Report function completion
612  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Structure read in successfully.", settings->messageShift );
613 
614  //================================================ Done
615  return ;
616 
617 }
618 
635 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 )
636 {
637  //================================================ Open the file
638  gemmi::Ccp4<float> map;
639  map.read_ccp4 ( gemmi::MaybeGzipped ( this->fileName.c_str() ) );
640 
641  //================================================ Convert to XYZ and create complete map, if need be
642  map.setup ( 0.0f, gemmi::MapSetup::ReorderOnly );
643 
644  //================================================ Read in the rest of the map file header
646  &this->xDimIndices, &this->yDimIndices, &this->zDimIndices,
647  &this->xDimSize, &this->yDimSize, &this->zDimSize,
648  &this->aAngle, &this->bAngle, &this->cAngle,
649  &this->xFrom, &this->yFrom, &this->zFrom,
650  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin,
651  &this->xAxisOrder, &this->yAxisOrder, &this->zAxisOrder,
652  &this->xGridIndices, &this->yGridIndices, &this->zGridIndices );
653 
654  //================================================ Save the map density to ProSHADE variable
655  ProSHADE_internal_io::readInMapData ( &map, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, this->xAxisOrder, this->yAxisOrder, this->zAxisOrder );
656 
657  //================================================ If mask is supplied and the correct task is used
658  ProSHADE_internal_io::applyMask ( this->internalMap, settings->appliedMaskFileName, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->verbose, settings->messageShift, &settings->calcBounds,
659  maskArr, maskXDim, maskYDim, maskZDim );
660 
661  //================================================ Convert mask boundaries to angstroms using original sampling
662  if ( !std::isinf ( settings->calcBounds.at(0) ) && !std::isinf ( settings->calcBounds.at(1) ) && !std::isinf ( settings->calcBounds.at(2) ) )
663  {
664  settings->calcBounds.at(0) *= ( static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices ) );
665  settings->calcBounds.at(1) *= ( static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices ) );
666  settings->calcBounds.at(2) *= ( static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices ) );
667  }
668 
669  //================================================ Apply Fourier weights
670  ProSHADE_internal_io::applyWeights ( this->internalMap, settings->fourierWeightsFileName, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->verbose, settings->messageShift,
671  weightsArr, weigXDim, weigYDim, weigZDim );
672 
673  //================================================ Remove negative values if so required
674  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; } } }
675 
676  //================================================ Set resolution if need be
677  if ( settings->requestedResolution < 0.0f )
678  {
679  settings->setResolution ( std::min ( static_cast<proshade_single> ( this->xDimSize ) / static_cast<proshade_single> ( this->xDimIndices ),
680  std::min ( static_cast<proshade_single> ( this->yDimSize ) / static_cast<proshade_single> ( this->yDimIndices ),
681  static_cast<proshade_single> ( this->zDimSize ) / static_cast<proshade_single> ( this->zDimIndices ) ) ) * 2.0f );
682  }
683 
684  //================================================ Set iterators from and to
685  this->figureIndexStartStop ( );
686 
687  //================================================ If specific resolution is requested, make sure the map has it
688  this->reSampleMap ( settings );
689 
690  //================================================ Save the original sizes
691  this->xDimSizeOriginal = this->xDimSize;
692  this->yDimSizeOriginal = this->yDimSize;
693  this->zDimSizeOriginal = this->zDimSize;
694 
695  //================================================ Save the original index counts
696  this->xDimIndicesOriginal = this->xDimIndices;
697  this->yDimIndicesOriginal = this->yDimIndices;
698  this->zDimIndicesOriginal = this->zDimIndices;
699 
700  //================================================ Save the original axis origins
701  this->xAxisOriginOriginal = this->xAxisOrigin;
702  this->yAxisOriginOriginal = this->yAxisOrigin;
703  this->zAxisOriginOriginal = this->zAxisOrigin;
704 
705  //================================================ Compute and save the COM
706  this->findMapCOM ( );
707  this->originalMapXCom = this->xCom;
708  this->originalMapYCom = this->yCom;
709  this->originalMapZCom = this->zCom;
710 
711  //================================================ Done
712 
713 }
714 
725 {
726  //================================================ Set resolution if need be
727  if ( settings->requestedResolution < 0.0f )
728  {
729  settings->setResolution ( 8.0 );
730  }
731 
732  //================================================ Open PDB file for reading
733  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
734 
735  //================================================ Once we have Gemmi object, run the Gemmi function
736  this->readInGemmi ( &pdbFile, settings );
737 
738  //================================================ Done
739  return;
740 
741 }
742 
759 void ProSHADE_internal_data::ProSHADE_data::readInGemmi ( gemmi::Structure* gemmiStruct, ProSHADE_settings* settings )
760 {
761  //================================================ Set resolution if need be
762  if ( settings->requestedResolution < 0.0f )
763  {
764  settings->setResolution ( 8.0 );
765  }
766 
767  //================================================ Change B-factors if need be
768  if ( settings->pdbBFactorNewVal >= 0.0 )
769  {
771  }
772 
773  //================================================ Remove waters if required
774  if ( settings->removeWaters )
775  {
776  ProSHADE_internal_mapManip::removeWaters ( gemmiStruct, settings->firstModelOnly );
777  }
778 
779  //================================================ Get PDB COM values
780  proshade_double xCOMPdb, yCOMPdb, zCOMPdb;
781  ProSHADE_internal_mapManip::findPDBCOMValues ( gemmiStruct, &xCOMPdb, &yCOMPdb, &zCOMPdb, settings->firstModelOnly );
782 
783  //================================================ Find the ranges
784  proshade_single xF = 0.0f, xT = 0.0f, yF = 0.0f, yT = 0.0f, zF = 0.0f, zT = 0.0f;
785  ProSHADE_internal_mapManip::determinePDBRanges ( *gemmiStruct, &xF, &xT, &yF, &yT, &zF, &zT, settings->firstModelOnly );
786 
787  //================================================ Move ranges to have all FROM values 20
788  proshade_single xMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - xF );
789  proshade_single yMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - yF );
790  proshade_single zMov = static_cast< proshade_single > ( settings->coOrdsExtraSpace - zF );
791  ProSHADE_internal_mapManip::movePDBForMapCalc ( gemmiStruct, xMov, yMov, zMov, settings->firstModelOnly );
792 
793  //================================================ Set the angstrom sizes
794  this->xDimSize = static_cast< proshade_single > ( xT - xF + ( 2.0f * settings->coOrdsExtraSpace ) );
795  this->yDimSize = static_cast< proshade_single > ( yT - yF + ( 2.0f * settings->coOrdsExtraSpace ) );
796  this->zDimSize = static_cast< proshade_single > ( zT - zF + ( 2.0f * settings->coOrdsExtraSpace ) );
797 
798  //================================================ Generate map from nicely placed atoms (cell size will be range + 40)
799  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 );
800 
801  //================================================ Remove negative values if so required
802  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; } } }
803 
804  //================================================ Set the internal variables to correct values
805  this->setPDBMapValues ( );
806 
807  //================================================ Move map back to the original PDB location
808  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize,
809  &this->xFrom, &this->xTo, &this->yFrom, &this->yTo, &this->zFrom, &this->zTo,
810  &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
811  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
812  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ),
813  static_cast< proshade_signed > ( this->zDimIndices ) );
814 
815  //================================================ If specific resolution is requested, make sure the map has it
816  this->reSampleMap ( settings );
817 
818  //================================================ Save the original sizes
819  this->xDimSizeOriginal = this->xDimSize;
820  this->yDimSizeOriginal = this->yDimSize;
821  this->zDimSizeOriginal = this->zDimSize;
822 
823  //================================================ Save the original index counts
824  this->xDimIndicesOriginal = this->xDimIndices;
825  this->yDimIndicesOriginal = this->yDimIndices;
826  this->zDimIndicesOriginal = this->zDimIndices;
827 
828  //================================================ Save the original axis origins
829  this->xAxisOriginOriginal = this->xAxisOrigin;
830  this->yAxisOriginOriginal = this->yAxisOrigin;
831  this->zAxisOriginOriginal = this->zAxisOrigin;
832 
833  //================================================ Compute and save the COM
834  this->findMapCOM ( );
835  this->originalMapXCom = this->xCom;
836  this->originalMapYCom = this->yCom;
837  this->originalMapZCom = this->zCom;
838 
839  //================================================ Done
840  return;
841 
842 }
843 
849 {
850  //================================================ Set starts to 0
851  this->xFrom = 0;
852  this->yFrom = 0;
853  this->zFrom = 0;
854 
855  //================================================ Set angles to 90 degrees
856  this->aAngle = 90.0;
857  this->bAngle = 90.0;
858  this->cAngle = 90.0;
859 
860  //================================================ Set dimension sizes in indices
861  this->xDimIndices = static_cast< proshade_unsign > ( this->xTo );
862  this->yDimIndices = static_cast< proshade_unsign > ( this->yTo );
863  this->zDimIndices = static_cast< proshade_unsign > ( this->zTo );
864 
865  //================================================ Set the to indices properly
866  this->xTo -= 1;
867  this->yTo -= 1;
868  this->zTo -= 1;
869 
870  //================================================ Set grid indexing to cell indexing
871  this->xGridIndices = this->xDimIndices;
872  this->yGridIndices = this->yDimIndices;
873  this->zGridIndices = this->zDimIndices;
874 
875  //================================================ Set axis order
876  this->xAxisOrder = 1;
877  this->yAxisOrder = 2;
878  this->zAxisOrder = 3;
879 
880  //================================================ Set origin to the first index
881  this->xAxisOrigin = this->xFrom;
882  this->yAxisOrigin = this->yFrom;
883  this->zAxisOrigin = this->zFrom;
884 
885  //================================================ Done
886  return ;
887 
888 }
889 
895 {
896  //================================================ Set ends to origin + size - 1
897  this->xTo = this->xFrom + static_cast< proshade_signed > ( this->xDimIndices ) - 1;
898  this->yTo = this->yFrom + static_cast< proshade_signed > ( this->yDimIndices ) - 1;
899  this->zTo = this->zFrom + static_cast< proshade_signed > ( this->zDimIndices ) - 1;
900 
901  //================================================ Done
902  return ;
903 
904 }
905 
916 void ProSHADE_internal_data::ProSHADE_data::writeMap ( std::string fName, std::string title, int mode )
917 {
918  //================================================ Create and prepare new Grid gemmi object
919  gemmi::Grid<float> mapData;
920  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 ) );
921  mapData.set_size_without_checking ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ) );
922  mapData.axis_order = gemmi::AxisOrder::XYZ;
923  mapData.spacegroup = &gemmi::get_spacegroup_p1();
924 
925  //================================================ Create and prepare new Ccp4 gemmi object
926  gemmi::Ccp4<float> map;
927  map.grid = mapData;
928  map.update_ccp4_header ( mode );
929 
930  //================================================ Fill in the header
932  this->xDimIndices, this->yDimIndices, this->zDimIndices,
933  this->xDimSize, this->yDimSize, this->zDimSize,
934  this->aAngle, this->bAngle, this->cAngle,
935  this->xFrom, this->yFrom, this->zFrom,
936  this->xAxisOrigin, this->yAxisOrigin, this->zAxisOrigin,
937  this->xAxisOrder, this->yAxisOrder, this->zAxisOrder,
938  this->xGridIndices, this->yGridIndices, this->zGridIndices,
939  title, mode );
940 
941  //================================================ Copy internal map to grid
942  proshade_unsign arrPos = 0;
943  for ( proshade_unsign uIt = 0; uIt < this->xDimIndices; uIt++ )
944  {
945  for ( proshade_unsign vIt = 0; vIt < this->yDimIndices; vIt++ )
946  {
947  for ( proshade_unsign wIt = 0; wIt < this->zDimIndices; wIt++ )
948  {
949  arrPos = wIt + this->zDimIndices * ( vIt + this->yDimIndices * uIt );
950  map.grid.set_value ( static_cast< int > ( uIt ), static_cast< int > ( vIt ), static_cast< int > ( wIt ), static_cast<float> ( this->internalMap[arrPos] ) );
951  }
952  }
953  }
954 
955  //================================================ Update the statistics in the header
956  map.update_ccp4_header ( mode, true );
957 
958  //================================================ Write out the map
959  map.write_ccp4_map ( fName );
960 
961  //================================================ Done
962  return ;
963 
964 }
965 
983 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 )
984 {
985  //================================================ Check for co-ordinate origin
986  if ( !ProSHADE_internal_io::isFilePDB ( this->fileName ) )
987  {
988  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." );
989  }
990 
991  //================================================ Open PDB file for reading
992  gemmi::Structure pdbFile = gemmi::read_structure ( gemmi::MaybeGzipped ( this->fileName ) );
993 
994  //================================================ Write out using the gemmi::Structure object
995  this->writeGemmi ( fName, pdbFile, euA, euB, euG, trsX, trsY, trsZ, rotX, rotY, rotZ, firstModel );
996 
997  //================================================ Done
998  return ;
999 }
1000 
1020 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 )
1021 {
1022  //================================================ If the map was rotated, do the same for the co-ordinates, making sure we take into account the rotation centre of the map
1023  if ( ( euA != 0.0 ) || ( euB != 0.0 ) || ( euG != 0.0 ) )
1024  {
1025  //============================================ Rotate the co-ordinates
1026  ProSHADE_internal_mapManip::rotatePDBCoordinates ( &gemmiStruct, euA, euB, euG, rotX, rotY, rotZ, firstModel );
1027  }
1028 
1029  //================================================ Translate by required translation and the map centering (if applied)
1030  ProSHADE_internal_mapManip::translatePDBCoordinates ( &gemmiStruct, trsX, trsY, trsZ, firstModel );
1031 
1032  //================================================ Write the PDB file
1033  std::ofstream outCoOrdFile;
1034  outCoOrdFile.open ( fName.c_str() );
1035 
1036  if ( outCoOrdFile.is_open() )
1037  {
1038  gemmi::PdbWriteOptions opt;
1039  write_pdb ( gemmiStruct, outCoOrdFile, opt );
1040  }
1041  else
1042  {
1043  std::stringstream hlpMessage;
1044  hlpMessage << "Failed to open the PDB file " << fName << " for output.";
1045  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." );
1046  }
1047 
1048  outCoOrdFile.close ( );
1049 
1050  //================================================ Done
1051  return ;
1052 }
1053 
1062 void ProSHADE_internal_data::ProSHADE_data::writeMask ( std::string fName, proshade_double* mask )
1063 {
1064  //================================================ Allocate the memory
1065  proshade_double* hlpMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1066  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1067 
1068  //================================================ Copy original map and over-write with the mask
1069  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1070  {
1071  hlpMap[iter] = this->internalMap[iter];
1072  this->internalMap[iter] = mask[iter];
1073  }
1074 
1075  //================================================ Write out the mask
1076  this->writeMap ( fName );
1077 
1078  //================================================ Copy the original map values back
1079  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1080  {
1081  this->internalMap[iter] = hlpMap[iter];
1082  }
1083 
1084  //================================================ Release memory
1085  delete[] hlpMap;
1086 
1087  //================================================ Done
1088  return ;
1089 
1090 }
1091 
1100 {
1101  //================================================ Report function start
1102  std::stringstream ss;
1103  ss << "Moving map box centre to " << settings->boxCentre.at(0) << "; " << settings->boxCentre.at(1) << "; " << settings->boxCentre.at(2) << " .";
1104  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
1105 
1106  //================================================ Figure sampling rates
1107  proshade_double xSamplingRate = static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices );
1108  proshade_double ySamplingRate = static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices );
1109  proshade_double zSamplingRate = static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices );
1110 
1111  //================================================ Figure the box centre
1112  proshade_double startCentreX = ( ( ( static_cast<proshade_double> ( this->xTo ) - static_cast<proshade_double> ( this->xFrom ) ) / 2.0 ) * xSamplingRate );
1113  proshade_double startCentreY = ( ( ( static_cast<proshade_double> ( this->yTo ) - static_cast<proshade_double> ( this->yFrom ) ) / 2.0 ) * ySamplingRate );
1114  proshade_double startCentreZ = ( ( ( static_cast<proshade_double> ( this->zTo ) - static_cast<proshade_double> ( this->zFrom ) ) / 2.0 ) * zSamplingRate );
1115 
1116  //================================================ Figure the requested point distance from box start
1117  proshade_double boxStartX = settings->boxCentre.at(0) - ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate );
1118  proshade_double boxStartY = settings->boxCentre.at(1) - ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate );
1119  proshade_double boxStartZ = settings->boxCentre.at(2) - ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate );
1120 
1121  //================================================ Figure the shift
1122  proshade_double xShift = startCentreX - boxStartX;
1123  proshade_double yShift = startCentreY - boxStartY;
1124  proshade_double zShift = startCentreZ - boxStartZ;
1125 
1126  //================================================ If requested point outside of map, complain
1127  if ( ( ( settings->boxCentre.at(0) < ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate ) ) ||
1128  ( settings->boxCentre.at(0) > ( static_cast<proshade_double> ( this->xFrom ) * xSamplingRate + static_cast<proshade_double> ( this->xDimSize ) ) ) ) ||
1129  ( ( settings->boxCentre.at(1) < ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate ) ) ||
1130  ( settings->boxCentre.at(1) > ( static_cast<proshade_double> ( this->yFrom ) * ySamplingRate + static_cast<proshade_double> ( this->yDimSize ) ) ) ) ||
1131  ( ( settings->boxCentre.at(2) < ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate ) ) ||
1132  ( settings->boxCentre.at(2) > ( static_cast<proshade_double> ( this->zFrom ) * zSamplingRate + static_cast<proshade_double> ( this->zDimSize ) ) ) ) )
1133  {
1134  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" );
1135  }
1136 
1137  //================================================ Do the shift
1139  static_cast< proshade_single > ( xShift ),
1140  static_cast< proshade_single > ( yShift ),
1141  static_cast< proshade_single > ( zShift ),
1142  this->xDimSize, this->yDimSize, this->zDimSize,
1143  static_cast< proshade_signed > ( this->xDimIndices ),
1144  static_cast< proshade_signed > ( this->yDimIndices ),
1145  static_cast< proshade_signed > ( this->zDimIndices ) );
1146 
1147  //================================================ Report function completion
1148  std::stringstream ss2;
1149  ss2 << "Position " << settings->boxCentre.at(0) << "; " << settings->boxCentre.at(1) << "; " << settings->boxCentre.at(2) << " set at the centre of the map box.";
1150  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss2.str(), settings->messageShift );
1151 
1152  //================================================ Done
1153  return ;
1154 
1155 }
1156 
1165 {
1166  //================================================ Report function start
1167  std::stringstream ss;
1168  ss << "Shifting map rotation centre ( " << settings->centrePosition.at(0) << "; " << settings->centrePosition.at(1) << "; " << settings->centrePosition.at(2) << " ) to the centre of the box.";
1169  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, ss.str(), settings->messageShift );
1170 
1171  //================================================ Do the shift
1173  static_cast< proshade_single > ( -settings->centrePosition.at(0) ),
1174  static_cast< proshade_single > ( -settings->centrePosition.at(1) ),
1175  static_cast< proshade_single > ( -settings->centrePosition.at(2) ),
1176  this->xDimSize, this->yDimSize, this->zDimSize,
1177  static_cast< proshade_signed > ( this->xDimIndices ),
1178  static_cast< proshade_signed > ( this->yDimIndices ),
1179  static_cast< proshade_signed > ( this->zDimIndices ) );
1180 
1181  //================================================ Save the shift
1182  this->mapCOMProcessChangeX += settings->centrePosition.at(0);
1183  this->mapCOMProcessChangeY += settings->centrePosition.at(1);
1184  this->mapCOMProcessChangeZ += settings->centrePosition.at(2);
1185 
1186  //================================================ Report function completion
1187  std::stringstream ss2;
1188  ss2 << "Map rotation centre shifted.";
1189  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss2.str(), settings->messageShift );
1190 
1191  //================================================ Do not do COM centering if this was done
1192  if ( settings->moveToCOM )
1193  {
1194  settings->moveToCOM = false;
1195  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested both symmetry centre detection and COM centering. COM centering turned off.", "WS00073" );
1196  }
1197 
1198  //================================================ Done
1199  return ;
1200 
1201 }
1202 
1212 {
1213  //================================================ Report function start
1214  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion.", settings->messageShift );
1215 
1216  //================================================ Initialise variables
1217  proshade_signed arrayPos, invPos;
1218 
1219  //================================================ Create helper map
1220  proshade_double* hlpMap = new proshade_double [this->xDimIndices * this->yDimIndices * this->zDimIndices];
1221  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1222 
1223  //================================================ Save map values to the helper map
1224  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1225  {
1226  hlpMap[iter] = this->internalMap[iter];
1227  }
1228 
1229  //================================================ Invert the values
1230  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
1231  {
1232  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
1233  {
1234  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
1235  {
1236  //==================================== Var init
1237  arrayPos = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
1238  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 ) );
1239 
1240  //==================================== And save
1241  this->internalMap[invPos] = hlpMap[arrayPos];
1242  }
1243  }
1244  }
1245 
1246  //================================================ Release memory
1247  delete[] hlpMap;
1248 
1249  //================================================ Report function completion
1250  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map inversion completed.", settings->messageShift );
1251 
1252  //================================================ Done
1253  return ;
1254 
1255 }
1256 
1266 {
1267  //================================================ Report function start
1268  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation.", settings->messageShift );
1269 
1270  //================================================ Initialise vector of map values
1271  std::vector<proshade_double> mapVals ( this->xDimIndices * this->yDimIndices * this->zDimIndices, 0.0 );
1272 
1273  //================================================ Get all map values
1274  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1275  {
1276  mapVals.at(iter) = this->internalMap[iter];
1277  }
1278 
1279  //================================================ Get mean and sd
1280  proshade_double* meanSD = new proshade_double[2];
1281  ProSHADE_internal_maths::vectorMeanAndSD ( &mapVals, meanSD );
1282 
1283  //================================================ Normalise the values
1284  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1285  {
1286  this->internalMap[iter] = ( this->internalMap[iter] - meanSD[0] ) / meanSD[1];
1287  }
1288 
1289  //================================================ Clear the vector
1290  mapVals.clear ( );
1291 
1292  //================================================ Release memory
1293  delete[] meanSD;
1294 
1295  //================================================ Report function completion
1296  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map normalisation completed.", settings->messageShift );
1297 
1298  //================================================ Done
1299  return ;
1300 
1301 }
1302 
1303 
1313 {
1314  //================================================ Report function start
1315  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Computing mask.", settings->messageShift );
1316 
1317  //================================================ Initialise the blurred map
1318  proshade_double* blurredMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1319  ProSHADE_internal_misc::checkMemoryAllocation ( blurredMap, __FILE__, __LINE__, __func__ );
1320 
1321  //================================================ Compute blurred map
1322  ProSHADE_internal_mapManip::blurSharpenMap ( this->internalMap, blurredMap, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1323  this->xDimSize, this->yDimSize, this->zDimSize, settings->blurFactor );
1324 
1325  //================================================ Compute mask from blurred map and save it into the original map
1326  ProSHADE_internal_mapManip::getMaskFromBlurr ( blurredMap, this->internalMap, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->maskingThresholdIQRs );
1327 
1328  //================================================ Print the mask if need be
1329  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 ); } }
1330 
1331  //================================================ Release memory
1332  delete[] blurredMap;
1333 
1334  //================================================ Report function completion
1335  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Mask computed.", settings->messageShift );
1336 
1337  //================================================ Done
1338  return ;
1339 
1340 }
1341 
1353 {
1354  //================================================ Report function start
1355  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Finding new boundaries.", settings->messageShift );
1356 
1357  //================================================ If same bounds as first one are required, test if possible and return these instead
1358  if ( settings->useSameBounds && ( this->inputOrder != 0 ) )
1359  {
1360  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { ret[iter] = settings->forceBounds[iter]; }
1361  }
1362  //================================================ In this case, bounds need to be found de novo
1363  else
1364  {
1365  //============================================ Find the non-zero bounds
1367  static_cast< proshade_signed > ( this->xDimIndices ),
1368  static_cast< proshade_signed > ( this->yDimIndices ),
1369  static_cast< proshade_signed > ( this->zDimIndices ),
1370  ret );
1371 
1372  //============================================ Add the extra space
1373  ProSHADE_internal_mapManip::addExtraBoundSpace ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1374  this->xDimSize, this->yDimSize, this->zDimSize, ret, settings->boundsExtraSpace );
1375 
1376  //============================================ Beautify boundaries
1377  ProSHADE_internal_mapManip::beautifyBoundaries ( ret, this->xDimIndices, this->yDimIndices, this->zDimIndices, settings->boundsSimilarityThreshold );
1378 
1379  //============================================ Report function results
1380  std::stringstream ssHlp;
1381  ssHlp << "New boundaries are: " << ret[1] - ret[0] + 1 << " x " << ret[3] - ret[2] + 1 << " x " << ret[5] - ret[4] + 1;
1382  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, ssHlp.str(), settings->messageShift );
1383 
1384  //============================================ If need be, save boundaries to be used for all other structure
1385  if ( settings->useSameBounds && ( this->inputOrder == 0 ) )
1386  {
1387  for ( proshade_unsign iter = 0; iter < 6; iter++ ) { settings->forceBounds[iter] = ret[iter]; }
1388  }
1389  }
1390 
1391  //================================================ Report function completion
1392  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New boundaries determined.", settings->messageShift );
1393 
1394  //================================================ Done
1395  return ;
1396 
1397 }
1398 
1411 {
1412  //================================================ Report function start
1413  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Creating new structure according to the new bounds.", settings->messageShift );
1414 
1415  //================================================ Fill in basic info
1416  newStr->fileName = "N/A";
1417  newStr->fileType = ProSHADE_internal_io::MAP;
1418 
1419  //================================================ Fill in new structure values
1420  newStr->xDimIndices = static_cast< proshade_unsign > ( newBounds[1] ) - static_cast< proshade_unsign > ( newBounds[0] ) + 1;
1421  newStr->yDimIndices = static_cast< proshade_unsign > ( newBounds[3] ) - static_cast< proshade_unsign > ( newBounds[2] ) + 1;
1422  newStr->zDimIndices = static_cast< proshade_unsign > ( newBounds[5] ) - static_cast< proshade_unsign > ( newBounds[4] ) + 1;
1423 
1424  newStr->aAngle = this->aAngle;
1425  newStr->bAngle = this->aAngle;
1426  newStr->cAngle = this->aAngle;
1427 
1428  newStr->xDimSize = static_cast<proshade_single> ( newStr->xDimIndices ) * ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) );
1429  newStr->yDimSize = static_cast<proshade_single> ( newStr->yDimIndices ) * ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) );
1430  newStr->zDimSize = static_cast<proshade_single> ( newStr->zDimIndices ) * ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) );
1431 
1432  newStr->xGridIndices = newStr->xDimIndices;
1433  newStr->yGridIndices = newStr->yDimIndices;
1434  newStr->zGridIndices = newStr->zDimIndices;
1435 
1436  newStr->xAxisOrder = this->xAxisOrder;
1437  newStr->yAxisOrder = this->yAxisOrder;
1438  newStr->zAxisOrder = this->zAxisOrder;
1439 
1440  newStr->xAxisOrigin = this->xAxisOrigin + newBounds[0];
1441  newStr->yAxisOrigin = this->yAxisOrigin + newBounds[2];
1442  newStr->zAxisOrigin = this->zAxisOrigin + newBounds[4];
1443 
1444  newStr->xFrom = this->xFrom + newBounds[0];
1445  newStr->yFrom = this->yFrom + newBounds[2];
1446  newStr->zFrom = this->zFrom + newBounds[4];
1447 
1448  newStr->xTo = this->xTo - ( static_cast< proshade_signed > ( this->xDimIndices - 1 ) - newBounds[1] );
1449  newStr->yTo = this->yTo - ( static_cast< proshade_signed > ( this->yDimIndices - 1 ) - newBounds[3] );
1450  newStr->zTo = this->zTo - ( static_cast< proshade_signed > ( this->zDimIndices - 1 ) - newBounds[5] );
1451 
1452  //================================================ Allocate new structure map
1453  newStr->internalMap = new proshade_double[newStr->xDimIndices * newStr->yDimIndices * newStr->zDimIndices];
1454  ProSHADE_internal_misc::checkMemoryAllocation ( newStr->internalMap, __FILE__, __LINE__, __func__ );
1455 
1456  //================================================ Copy the map
1457  ProSHADE_internal_mapManip::copyMapByBounds ( newStr->xFrom, newStr->xTo, newStr->yFrom, newStr->yTo, newStr->zFrom, newStr->zTo,
1458  this->xFrom, this->yFrom, this->zFrom, newStr->yDimIndices, newStr->zDimIndices,
1459  this->xDimIndices, this->yDimIndices, this->zDimIndices, newStr->internalMap, this->internalMap );
1460 
1461  //================================================ Report function completion
1462  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "New structure created.", settings->messageShift );
1463 
1464  //================================================ Done
1465  return ;
1466 
1467 }
1468 
1477 {
1478  //================================================ Sanity check
1479  if ( !settings->changeMapResolution && !settings->changeMapResolutionTriLinear ) { return ; }
1480 
1481  //================================================ Initialise the internal variable
1482  proshade_single* changeVals = new proshade_single[6];
1483 
1484  //================================================ Find COM before map re-sampling
1485  proshade_double xMapCOMPreReSampl = 0.0, yMapCOMPreReSampl = 0.0, zMapCOMPreReSampl = 0.0;
1486  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, settings->removeNegativeDensity );
1487 
1488  //================================================ Now re-sample the map
1489  if ( settings->changeMapResolution )
1490  {
1491  ProSHADE_internal_mapManip::reSampleMapToResolutionFourier ( this->internalMap, settings->requestedResolution * settings->resolutionOversampling, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1492  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1493 
1494  if ( settings->changeMapResolutionTriLinear )
1495  {
1496  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" );
1497  }
1498  }
1499  if ( settings->changeMapResolutionTriLinear && !settings->changeMapResolution )
1500  {
1501  ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear ( this->internalMap, settings->requestedResolution * settings->resolutionOversampling, this->xDimIndices, this->yDimIndices, this->zDimIndices,
1502  this->xDimSize, this->yDimSize, this->zDimSize, changeVals );
1503 
1504  }
1505 
1506  //================================================ Set the internal values to reflect the new map size
1507  this->xDimIndices += static_cast<proshade_unsign> ( changeVals[0] );
1508  this->yDimIndices += static_cast<proshade_unsign> ( changeVals[1] );
1509  this->zDimIndices += static_cast<proshade_unsign> ( changeVals[2] );
1510 
1511  this->xGridIndices = this->xDimIndices;
1512  this->yGridIndices = this->yDimIndices;
1513  this->zGridIndices = this->zDimIndices;
1514 
1515  this->xTo += static_cast<proshade_unsign> ( changeVals[0] );
1516  this->yTo += static_cast<proshade_unsign> ( changeVals[1] );
1517  this->zTo += static_cast<proshade_unsign> ( changeVals[2] );
1518 
1519  this->xDimSize = changeVals[3];
1520  this->yDimSize = changeVals[4];
1521  this->zDimSize = changeVals[5];
1522 
1523  //================================================ Find COM after map re-sampling and corner move
1524  proshade_double xMapCOMPostReSampl = 0.0, yMapCOMPostReSampl = 0.0, zMapCOMPostReSampl = 0.0;
1525  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, settings->removeNegativeDensity );
1526 
1527  //================================================ Figure how much the new map moved
1528  proshade_single xMov = static_cast< proshade_single > ( xMapCOMPostReSampl - xMapCOMPreReSampl );
1529  proshade_single yMov = static_cast< proshade_single > ( yMapCOMPostReSampl - yMapCOMPreReSampl );
1530  proshade_single zMov = static_cast< proshade_single > ( zMapCOMPostReSampl - zMapCOMPreReSampl );
1531 
1532  //================================================ Move by indices (this should be sufficient)
1533  ProSHADE_internal_mapManip::moveMapByIndices ( &xMov, &yMov, &zMov, this->xDimSize, this->yDimSize, this->zDimSize, &this->xFrom, &this->xTo,
1534  &this->yFrom, &this->yTo, &this->zFrom, &this->zTo, &this->xAxisOrigin, &this->yAxisOrigin, &this->zAxisOrigin );
1535 
1536  ProSHADE_internal_mapManip::moveMapByFourier ( this->internalMap, xMov, yMov, zMov, this->xDimSize, this->yDimSize, this->zDimSize,
1537  static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ) );
1538 
1539  //================================================ Release memory
1540  delete[] changeVals;
1541 
1542  //================================================ Done
1543  return ;
1544 
1545 }
1546 
1557 {
1558  //================================================ Sanity check
1559  if ( !( ( std::isinf ( settings->centrePosition.at(0) ) ) || ( std::isinf ( settings->centrePosition.at(1) ) ) || ( std::isinf ( settings->centrePosition.at(2) ) ) ) )
1560  {
1561  settings->moveToCOM = false;
1562  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested both symmetry centre detection and COM centering. COM centering turned off.", "WS00073" );
1563  return ;
1564  }
1565 
1566  //================================================ Report function start
1567  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Centering map onto its COM.", settings->messageShift );
1568 
1569  //================================================ Initialise local variables
1570  proshade_double xCOM = 0.0;
1571  proshade_double yCOM = 0.0;
1572  proshade_double zCOM = 0.0;
1573 
1574  //================================================ Find the COM location
1575  ProSHADE_internal_mapManip::findMAPCOMValues ( this->internalMap, &xCOM, &yCOM, &zCOM,
1576  this->xDimSize, this->yDimSize, this->zDimSize, this->xFrom,
1577  this->xTo, this->yFrom, this->yTo, this->zFrom, this->zTo, settings->removeNegativeDensity );
1578 
1579  //================================================ Find the sampling rates
1580  proshade_single xSampRate = static_cast< proshade_single > ( this->xDimSize ) / static_cast< proshade_single > ( this->xTo - this->xFrom + 1 );
1581  proshade_single ySampRate = static_cast< proshade_single > ( this->yDimSize ) / static_cast< proshade_single > ( this->yTo - this->yFrom + 1 );
1582  proshade_single zSampRate = static_cast< proshade_single > ( this->zDimSize ) / static_cast< proshade_single > ( this->zTo - this->zFrom + 1 );
1583 
1584  //================================================ Convert to position in indices starting from 0
1585  xCOM /= static_cast< proshade_double > ( xSampRate );
1586  yCOM /= static_cast< proshade_double > ( ySampRate );
1587  zCOM /= static_cast< proshade_double > ( zSampRate );
1588 
1589  xCOM -= static_cast< proshade_double > ( this->xFrom );
1590  yCOM -= static_cast< proshade_double > ( this->yFrom );
1591  zCOM -= static_cast< proshade_double > ( this->zFrom );
1592 
1593  //================================================ Find distance from COM to map centre in Angstroms
1594  proshade_double xDist = ( ( static_cast<proshade_double> ( this->xDimIndices ) / 2.0 ) - xCOM ) * static_cast<proshade_double> ( this->xDimSize ) / static_cast<proshade_double> ( this->xDimIndices );
1595  proshade_double yDist = ( ( static_cast<proshade_double> ( this->yDimIndices ) / 2.0 ) - yCOM ) * static_cast<proshade_double> ( this->yDimSize ) / static_cast<proshade_double> ( this->yDimIndices );
1596  proshade_double zDist = ( ( static_cast<proshade_double> ( this->zDimIndices ) / 2.0 ) - zCOM ) * static_cast<proshade_double> ( this->zDimSize ) / static_cast<proshade_double> ( this->zDimIndices );
1597 
1598  //================================================ Move the map within the box
1600  static_cast< proshade_single > ( xDist ),
1601  static_cast< proshade_single > ( yDist ),
1602  static_cast< proshade_single > ( zDist ),
1603  this->xDimSize, this->yDimSize, this->zDimSize,
1604  static_cast< proshade_signed > ( this->xDimIndices ),
1605  static_cast< proshade_signed > ( this->yDimIndices ),
1606  static_cast< proshade_signed > ( this->zDimIndices ) );
1607 
1608  //================================================ Note the change due to centering
1609  this->mapCOMProcessChangeX -= xDist;
1610  this->mapCOMProcessChangeY -= yDist;
1611  this->mapCOMProcessChangeZ -= zDist;
1612 
1613  //================================================ Report function completion
1614  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Map centered.", settings->messageShift );
1615 
1616  //================================================ Done
1617  return ;
1618 
1619 }
1620 
1630 {
1631  //================================================ Report function start
1632  std::stringstream hlpSS;
1633  hlpSS << "Adding extra " << settings->addExtraSpace << " angstroms.";
1634  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str(), settings->messageShift );
1635 
1636  //================================================ Figure how much indices need to change
1637  proshade_unsign xAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->xDimSize / static_cast<proshade_single> ( this->xDimIndices ) ) ) );
1638  proshade_unsign yAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->yDimSize / static_cast<proshade_single> ( this->yDimIndices ) ) ) );
1639  proshade_unsign zAddIndices = static_cast< proshade_unsign > ( ProSHADE_internal_mapManip::myRound ( settings->addExtraSpace / ( this->zDimSize / static_cast<proshade_single> ( this->zDimIndices ) ) ) );
1640 
1641  //================================================ Update internal data variables
1642  this->xDimSize += 2 * static_cast<proshade_single> ( xAddIndices ) * this->xDimSize / static_cast<proshade_single> ( this->xDimIndices );
1643  this->yDimSize += 2 * static_cast<proshade_single> ( yAddIndices ) * this->yDimSize / static_cast<proshade_single> ( this->yDimIndices );
1644  this->zDimSize += 2 * static_cast<proshade_single> ( zAddIndices ) * this->zDimSize / static_cast<proshade_single> ( this->zDimIndices );
1645 
1646  this->xDimIndices += 2 * xAddIndices;
1647  this->yDimIndices += 2 * yAddIndices;
1648  this->zDimIndices += 2 * zAddIndices;
1649 
1650  this->xGridIndices = this->xDimIndices;
1651  this->yGridIndices = this->yDimIndices;
1652  this->zGridIndices = this->zDimIndices;
1653 
1654  this->xAxisOrigin -= xAddIndices;
1655  this->yAxisOrigin -= yAddIndices;
1656  this->zAxisOrigin -= zAddIndices;
1657 
1658  this->xFrom -= xAddIndices;
1659  this->yFrom -= yAddIndices;
1660  this->zFrom -= zAddIndices;
1661 
1662  this->xTo += xAddIndices;
1663  this->yTo += yAddIndices;
1664  this->zTo += zAddIndices;
1665 
1666  //================================================ Allocate new map
1667  proshade_double* newMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1668  ProSHADE_internal_misc::checkMemoryAllocation ( newMap, __FILE__, __LINE__, __func__ );
1669 
1670  //================================================ Set new map to zeroes
1671  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1672  {
1673  newMap[iter] = 0.0;
1674  }
1675 
1676  //================================================ Update the map
1677  proshade_unsign newMapIndex, oldMapIndex;
1678  for ( proshade_unsign xIt = 0; xIt < (this->xDimIndices - xAddIndices); xIt++ )
1679  {
1680  //============================================ Check if point is applicable
1681  if ( xIt < xAddIndices ) { continue; }
1682 
1683  for ( proshade_unsign yIt = 0; yIt < (this->yDimIndices - yAddIndices); yIt++ )
1684  {
1685  //======================================== Check if point is applicable
1686  if ( yIt < yAddIndices ) { continue; }
1687 
1688  for ( proshade_unsign zIt = 0; zIt < (this->zDimIndices - zAddIndices); zIt++ )
1689  {
1690  //==================================== Check if point is applicable
1691  if ( zIt < zAddIndices ) { continue; }
1692 
1693  //==================================== Var init
1694  newMapIndex = zIt + this->zDimIndices * ( yIt + this->yDimIndices * xIt );
1695  oldMapIndex = (zIt - zAddIndices) + (this->zDimIndices - ( 2 * zAddIndices ) ) * ( (yIt - yAddIndices) + (this->yDimIndices - ( 2 * yAddIndices ) ) * (xIt - xAddIndices) );
1696 
1697  newMap[newMapIndex] = this->internalMap[oldMapIndex];
1698  }
1699  }
1700  }
1701 
1702  //================================================ Copy new to old
1703  delete[] this->internalMap;
1704 
1705  this->internalMap = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
1706  ProSHADE_internal_misc::checkMemoryAllocation ( this->internalMap, __FILE__, __LINE__, __func__ );
1707 
1708  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
1709  {
1710  this->internalMap[iter] = newMap[iter];
1711  }
1712 
1713  //================================================ Release memory
1714  delete[] newMap;
1715 
1716  //================================================ Report function completion
1717  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Extra space added.", settings->messageShift );
1718 
1719  //================================================ Done
1720  return ;
1721 
1722 }
1723 
1740 {
1741  //================================================ Move given point to box centre
1742  if ( !( ( std::isinf ( settings->boxCentre.at(0) ) ) || ( std::isinf ( settings->boxCentre.at(1) ) ) || ( std::isinf ( settings->boxCentre.at(2) ) ) ) ) { this->shiftToBoxCentre ( settings ); }
1743  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map left at original position.", settings->messageShift ); }
1744 
1745  //================================================ Shift map to centre of rotation if so required
1746  if ( !( ( std::isinf ( settings->centrePosition.at(0) ) ) || ( std::isinf ( settings->centrePosition.at(1) ) ) || ( std::isinf ( settings->centrePosition.at(2) ) ) ) ) { this->shiftToRotationCentre ( settings ); }
1747  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map rotation centre not shifted.", settings->messageShift ); }
1748 
1749  //================================================ Invert map
1750  if ( settings->invertMap ) { this->invertMirrorMap ( settings ); }
1751  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map inversion (mirror image) not requested.", settings->messageShift ); }
1752 
1753  //================================================ Normalise map
1754  if ( settings->normaliseMap ) { this->normaliseMap ( settings ); }
1755  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map normalisation not requested.", settings->messageShift ); }
1756 
1757  //================================================ Compute mask
1758  if ( settings->maskMap ) { this->maskMap ( settings ); }
1759  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Masking not requested.", settings->messageShift ); }
1760 
1761  //================================================ Centre map
1762  if ( settings->moveToCOM ) { this->centreMapOnCOM ( settings ); }
1763  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Map centering not requested.", settings->messageShift ); }
1764 
1765  //================================================ Remove phase, if required
1766  if ( !settings->usePhase ) { this->removePhaseInormation ( settings ); ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information removed from the data.", settings->messageShift ); }
1767  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Phase information retained in the data.", settings->messageShift ); }
1768 
1769  //================================================ Add extra space
1770  if ( settings->addExtraSpace != 0.0f ) { this->addExtraSpace ( settings ); }
1771  else { ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Extra space not requested.", settings->messageShift ); }
1772 
1773  //================================================ Set settings values which were left on AUTO by user and will not be set later
1774  settings->setVariablesLeftOnAuto ( );
1775 
1776  //================================================ Done
1777  return ;
1778 
1779 }
1780 
1791 {
1792  //================================================ Check the current settings value is set to auto
1793  if ( this->spherePos.size() != 0 )
1794  {
1795  std::stringstream hlpSS;
1796  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1797  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1798  hlpSS << " Angstroms.";
1799  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str(), settings->messageShift );
1800  return ;
1801  }
1802 
1803  //================================================ Find maximum diagonal
1804  proshade_unsign maxDim = static_cast< proshade_unsign > ( std::max ( this->xDimSize, std::max ( this->yDimSize, this->zDimSize ) ) );
1805  proshade_unsign minDim = static_cast< proshade_unsign > ( std::min ( this->xDimSize, std::min ( this->yDimSize, this->zDimSize ) ) );
1806  proshade_unsign midDim = static_cast< proshade_unsign > ( 0 );
1807  if ( ( this->xDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->xDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->xDimSize ); }
1808  else if ( ( this->yDimSize < static_cast< proshade_single > ( maxDim ) ) && ( this->yDimSize > static_cast< proshade_single > ( minDim ) ) ) { midDim = static_cast< proshade_unsign > ( this->yDimSize ); }
1809  else { midDim = static_cast< proshade_unsign > ( this->zDimSize ); }
1810 
1811  proshade_single maxDiag = static_cast< proshade_single > ( std::sqrt ( std::pow ( static_cast<proshade_single> ( maxDim ), 2.0 ) +
1812  std::pow ( static_cast<proshade_single> ( midDim ), 2.0 ) ) );
1813 
1814  //================================================ Set between the points
1815  for ( proshade_single iter = 0.5f; ( iter * settings->maxSphereDists ) < ( maxDiag / 2.0f ); iter += 1.0f )
1816  {
1817  //============================================ Do not go over max radius
1818  if ( ( settings->maxRadius > 0.0 ) && ( settings->maxRadius < static_cast< proshade_double > ( maxDiag ) ) && ( static_cast< proshade_double > ( iter * settings->maxSphereDists ) > settings->maxRadius ) ) { break; }
1819 
1820  //============================================ Save value
1821  ProSHADE_internal_misc::addToSingleVector ( &this->spherePos, ( iter * settings->maxSphereDists ) );
1822  }
1823 
1824  //================================================ Save the number of spheres
1825  this->noSpheres = static_cast<proshade_unsign> ( this->spherePos.size() );
1826 
1827  //================================================ Report progress
1828  std::stringstream hlpSS;
1829  hlpSS << "The sphere distances were determined as " << this->spherePos.at(0);
1830  for ( proshade_unsign iter = 1; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ ) { hlpSS << "; " << this->spherePos.at(iter); }
1831  hlpSS << " Angstroms.";
1832  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 3, hlpSS.str(), settings->messageShift );
1833 
1834  //================================================ Done
1835  return ;
1836 
1837 }
1838 
1839 
1852 {
1853  //================================================ Report progress
1854  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting sphere mapping procedure.", settings->messageShift );
1855 
1856  //================================================ Determine spherical harmonics variables
1857  settings->determineAllSHValues ( this->xDimIndices, this->yDimIndices,
1858  this->xDimSize, this->yDimSize, this->zDimSize );
1859  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere settings determined.", settings->messageShift );
1860 
1861  //================================================ Find number of spheres supported
1862  this->getSpherePositions ( settings );
1863  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere positions obtained.", settings->messageShift );
1864 
1865  //================================================ Create sphere objects and map the density
1866  this->spheres = new ProSHADE_internal_spheres::ProSHADE_sphere* [ this->noSpheres ];
1867  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->spherePos.size() ); iter++ )
1868  {
1869  std::stringstream ss;
1870  ss << "Now mapping sphere " << iter << " .";
1871  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str(), settings->messageShift );
1872 
1873  this->spheres[iter] = new ProSHADE_internal_spheres::ProSHADE_sphere ( this->xDimIndices, this->yDimIndices, this->zDimIndices,
1874  this->xDimSize, this->yDimSize, this->zDimSize, iter,
1875  &this->spherePos, settings->progressiveSphereMapping, settings->maxBandwidth,
1876  this->internalMap, &this->maxShellBand, &this->maxEMatDim );
1877  }
1878 
1879  //================================================ Report completion
1880  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Sphere mapping procedure completed.", settings->messageShift );
1881 
1882  //================================================ Done
1883  return ;
1884 
1885 }
1886 
1896 {
1897  //================================================ Report progress
1898  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting spherical harmonics decomposition.", settings->messageShift );
1899 
1900  //================================================ Initialise memory
1901  this->sphericalHarmonics = new proshade_complex* [this->noSpheres];
1902  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics, __FILE__, __LINE__, __func__ );
1903  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1904  {
1905  this->sphericalHarmonics[iter] = new proshade_complex [( this->spheres[iter]->getLocalAngRes() ) * ( this->spheres[iter]->getLocalAngRes() )];
1906  ProSHADE_internal_misc::checkMemoryAllocation ( this->sphericalHarmonics[iter], __FILE__, __LINE__, __func__ );
1907  for ( size_t it = 0; it < ( ( this->spheres[iter]->getLocalAngRes() ) * ( this->spheres[iter]->getLocalAngRes() ) ); it++ ) { this->sphericalHarmonics[iter][it][0] = 0.0; this->sphericalHarmonics[iter][it][1] = 0.0; }
1908  }
1909 
1910  //================================================ Compute the spherical harmonics
1911  for ( proshade_unsign iter = 0; iter < this->noSpheres; iter++ )
1912  {
1913  //============================================ Report progress
1914  std::stringstream ss;
1915  ss << "Now decomposing sphere " << iter << ". " << "( Band is: " << this->spheres[iter]->getLocalBandwidth() << ").";
1916  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss.str(), settings->messageShift );
1917 
1918  //============================================ Compute
1919  ProSHADE_internal_sphericalHarmonics::computeSphericalHarmonics ( this->spheres[iter]->getLocalBandwidth(), this->spheres[iter]->getMappedData(), this->sphericalHarmonics[iter] );
1920  }
1921 
1922  //================================================ Report completion
1923  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Spherical harmonics decomposition complete.", settings->messageShift );
1924 
1925  //======================================== Done
1926  return ;
1927 
1928 }
1929 
1936 bool sortProSHADESymmetryByFSC ( proshade_double* a, proshade_double* b)
1937 {
1938  //================================================ Done
1939  return ( a[6] > b[6] );
1940 
1941 }
1942 
1955 {
1956  //================================================ Modify axis tolerance and matrix tolerance by sampling, if required by user
1957  if ( settings->axisErrToleranceDefault )
1958  {
1959  settings->axisErrTolerance = std::min ( std::max ( 0.01, ( ( 2.0 * M_PI ) / static_cast< proshade_double > ( this->maxShellBand ) ) / 2.0 ), 0.05 );
1960  }
1961 
1962  //================================================ Prepare FSC computation memory and variables
1963  fftw_complex* fCoeffsCut;
1964  proshade_double **bindata, *fscByBin;
1965  proshade_signed *cutIndices, *binCounts, noBins, cutXDim, cutYDim, cutZDim;
1966  this->prepareFSCFourierMemory ( cutIndices, fCoeffsCut, &noBins, bindata, binCounts, fscByBin, settings->requestedResolution, &cutXDim, &cutYDim, &cutZDim );
1967 
1968  //================================================ If C was requested, we will do it immediately - this allows for a significant speed-up.
1969  if ( settings->requestedSymmetryType == "C" )
1970  {
1971  //============================================ Report progress
1972  std::stringstream hlpSS;
1973  hlpSS << "Starting detection of cyclic point group C" << settings->requestedSymmetryFold;
1974  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, hlpSS.str(), settings->messageShift );
1975 
1976  //============================================ Do simplified search only in the applicable data
1977  proshade_double symThres = 0.0;
1978  this->cyclicSymmetries = this->findRequestedCSymmetryFromAngleAxis ( settings, settings->requestedSymmetryFold, &symThres );
1979 
1980  //============================================ Compute FSC for all possible axes
1981  for ( size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
1982  {
1983  const FloatingPoint< proshade_double > lhs ( this->cyclicSymmetries.at(cIt)[5] ), rhs ( -999.9 );
1984  if ( ( this->cyclicSymmetries.at(cIt)[5] > settings->peakThresholdMin ) || ( lhs.AlmostEquals ( rhs ) ) )
1985  {
1986  this->computeFSC ( settings, &this->cyclicSymmetries, cIt, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
1987  }
1988  }
1989 
1990  //============================================ Sort by FSC
1991  std::sort ( this->cyclicSymmetries.begin(), this->cyclicSymmetries.end(), sortProSHADESymmetryByFSC );
1992 
1993  //============================================ Save the best axis as the recommended one
1994  if ( this->cyclicSymmetries.size() > 0 )
1995  {
1996  bool passedTests = false;
1997  for ( size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
1998  {
1999  if ( this->cyclicSymmetries.at(0)[6] > settings->fscThreshold )
2000  {
2001  this->recommendedSymmetryType = "C";
2002  this->recommendedSymmetryFold = settings->requestedSymmetryFold;
2003 
2004  proshade_double* hlpSym = new proshade_double[7];
2005  ProSHADE_internal_misc::checkMemoryAllocation ( hlpSym, __FILE__, __LINE__, __func__ );
2006  for ( size_t iter = 0; iter < 7; iter++ ) { hlpSym[iter] = this->cyclicSymmetries.at(cIt)[iter]; }
2007  ProSHADE_internal_misc::addToDblPtrVector ( &this->recommendedSymmetryValues, hlpSym );
2008 
2009  passedTests = true;
2010  break;
2011  }
2012  }
2013 
2014  if ( !passedTests )
2015  {
2016  this->recommendedSymmetryType = "C";
2017  this->recommendedSymmetryFold = 1;
2018  }
2019  }
2020  else
2021  {
2022  this->recommendedSymmetryType = "C";
2023  this->recommendedSymmetryFold = 1;
2024  }
2025 
2026  //============================================ Release memory after FSC computation
2027  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2028  delete[] bindata;
2029  delete[] binCounts;
2030  delete[] fscByBin;
2031  delete[] cutIndices;
2032  fftw_free ( fCoeffsCut );
2033 
2034  //============================================ Done
2035  return ;
2036  }
2037 
2038  //================================================ Report progress
2039  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting C symmetry detection.", settings->messageShift );
2040 
2041  //================================================ Detect cyclic symmetries
2042  this->cyclicSymmetries = getCyclicSymmetriesListFromAngleAxis ( settings );
2043 
2044  //================================================ Report progress
2045  std::stringstream ss;
2046  ss << "Detected " << this->cyclicSymmetries.size() << " C symmetries.";
2047  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str(), settings->messageShift );
2048 
2049  //================================================ Sanity check - was the rotation function mapped properly?
2050  if ( this->sphereMappedRotFun.size() < 1 )
2051  {
2052  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." );
2053  }
2054 
2055  //================================================ If only C syms were requested (e.g. rotation centre detection), terminate here!
2056  if ( settings->requestedSymmetryType == "onlyCandD" )
2057  {
2058  //============================================ Detect the Ds
2059  this->getDihedralSymmetriesList ( settings, &this->cyclicSymmetries );
2060 
2061 
2062  //============================================ Release memory
2063  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2064  delete[] bindata;
2065  delete[] binCounts;
2066  delete[] fscByBin;
2067  delete[] cutIndices;
2068  fftw_free ( fCoeffsCut );
2069 
2070  //============================================ Done
2071  return;
2072  }
2073 
2074  //================================================ Sanity check - was any symmetry requested?
2075  if ( ( settings->requestedSymmetryType != "" ) && ( settings->requestedSymmetryType != "C" ) && ( settings->requestedSymmetryType != "D" ) && ( settings->requestedSymmetryType != "T" ) && ( settings->requestedSymmetryType != "O" ) && ( settings->requestedSymmetryType != "I" ) )
2076  {
2077  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." );
2078  }
2079 
2080  //================================================ Are we doing general search?
2081  if ( settings->requestedSymmetryType == "" )
2082  {
2083  //============================================ Decide on recommended symmetry
2084  this->determineRecommendedSymmetry ( settings, -2.0, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2085  }
2086 
2087  if ( settings->requestedSymmetryType == "D" )
2088  {
2089  //============================================ Run only the D symmetry detection and search for requested fold
2090  this->getDihedralSymmetriesList ( settings, &this->cyclicSymmetries );
2091  this->saveRequestedSymmetryD ( settings, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2092  }
2093 
2094  if ( settings->requestedSymmetryType == "T" )
2095  {
2096  //============================================ Run only the T symmetry detection
2097  this->getPredictedTetrahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2098 
2099  if ( this->tetrahedralSymmetries.size() == 7 )
2100  {
2101  //======================================== Initialise decision vars
2102  proshade_double fscVal = 0.0;
2103  proshade_double fscValAvg = 0.0;
2104 
2105  //======================================== Check if axes have high enough FSC and peak height
2106  for ( size_t tIt = 0; tIt < this->tetrahedralSymmetries.size(); tIt++ ) { if ( this->tetrahedralSymmetries.at(tIt)[5] > settings->peakThresholdMin ) { fscVal = this->computeFSC ( settings, &this->tetrahedralSymmetries.at(tIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2107  fscValAvg /= 7.0;
2108 
2109  //======================================== If the average is over the threshold, save it
2110  if ( fscValAvg >= settings->fscThreshold )
2111  {
2112  //==================================== The decision is T
2113  this->recommendedSymmetryType = "T";
2114  this->recommendedSymmetryFold = 0;
2115  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->tetrahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->tetrahedralSymmetries.at(it)[0] ); }
2116  }
2117  }
2118  }
2119 
2120  if ( settings->requestedSymmetryType == "O" )
2121  {
2122  //============================================ Run only the O symmetry detection
2123  this->getPredictedOctahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2124 
2125  if ( this->octahedralSymmetries.size() == 13 )
2126  {
2127  //======================================== Initialise decision vars
2128  proshade_double fscVal = 0.0;
2129  proshade_double fscValAvg = 0.0;
2130 
2131  //======================================== Find the average FSC
2132  for ( size_t oIt = 0; oIt < this->octahedralSymmetries.size(); oIt++ ) { if ( this->octahedralSymmetries.at(oIt)[5] > settings->peakThresholdMin ) { fscVal = this->computeFSC ( settings, &this->octahedralSymmetries.at(oIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2133  fscValAvg /= 13.0;
2134 
2135  //======================================== If the average FSC is over the threshold, save it.
2136  if ( fscValAvg >= ( settings->fscThreshold ) )
2137  {
2138  //==================================== The decision is O
2139  this->recommendedSymmetryType = "O";
2140  this->recommendedSymmetryFold = 0;
2141  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->octahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->octahedralSymmetries.at(it)[0] ); }
2142  }
2143  }
2144  }
2145 
2146  if ( settings->requestedSymmetryType == "I" )
2147  {
2148  //============================================ Run only the I symmetry detection
2149  this->getPredictedIcosahedralSymmetriesList ( settings, &this->cyclicSymmetries, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2150 
2151  if ( this->icosahedralSymmetries.size() == 31 )
2152  {
2153  //======================================== Initialise decision vars
2154  proshade_double fscVal = 0.0;
2155  proshade_double fscValAvg = 0.0;
2156 
2157  //======================================== Compute FSC average over all detected axes
2158  for ( size_t iIt = 0; iIt < this->icosahedralSymmetries.size(); iIt++ ) { if ( this->icosahedralSymmetries.at(iIt)[5] > settings->peakThresholdMin ) { fscVal = this->computeFSC ( settings, &this->icosahedralSymmetries.at(iIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); fscValAvg += fscVal; } }
2159  fscValAvg /= 31.0;
2160 
2161  //======================================== If the axes averaged FSC is over the threshold, save it
2162  if ( fscValAvg >= ( settings->fscThreshold ) )
2163  {
2164  //==================================== The decision is I
2165  this->recommendedSymmetryType = "I";
2166  this->recommendedSymmetryFold = 0;
2167  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->icosahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues , &this->icosahedralSymmetries.at(it)[0] ); }
2168  }
2169  }
2170  }
2171 
2172  //================================================ Release memory after FSC computation
2173  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
2174  delete[] bindata;
2175  delete[] binCounts;
2176  delete[] cutIndices;
2177  fftw_free ( fCoeffsCut );
2178 
2179  //================================================ Done
2180  return ;
2181 
2182 }
2183 
2202 void ProSHADE_internal_data::ProSHADE_data::prepareFSCFourierMemory ( proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed* noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_single resolution, proshade_signed* cutXDim, proshade_signed* cutYDim, proshade_signed* cutZDim )
2203 {
2204  //================================================ Decide number of bins and allocate which reflection belongs to which bin
2205  std::vector< proshade_single > *resArray;
2206  proshade_signed* binIndexing = nullptr;
2207  ProSHADE_internal_maths::binReciprocalSpaceReflections ( this->xDimIndices, this->yDimIndices, this->zDimIndices, this->xDimSize, this->yDimSize, this->zDimSize, noBins, binIndexing, resArray );
2208 
2209  //================================================ Cut the indices to contain only up to the requested resolution
2210  ProSHADE_internal_maths::cutIndicesToResolution ( static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ),
2211  resolution * 1.1f,
2212  binIndexing,
2213  resArray,
2214  cutXDim, cutYDim, cutZDim,
2215  cutIndices,
2216  noBins );
2217 
2218  //================================================ Release binning memory
2219  delete[] binIndexing;
2220 
2221  //================================================ Allocate memory for FSC sums and Fourier transform imputs and outputs
2222  bindata = new proshade_double*[*noBins];
2223  binCounts = new proshade_signed [*noBins];
2224  fscByBin = new proshade_double [*noBins];
2225  fftw_complex* mapData = reinterpret_cast< fftw_complex* > ( fftw_malloc ( sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
2226  fftw_complex* fCoeffs = reinterpret_cast< fftw_complex* > ( fftw_malloc ( sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
2227  fCoeffsCut = reinterpret_cast< fftw_complex* > ( fftw_malloc ( sizeof ( fftw_complex ) * static_cast< proshade_unsign > ( (*cutXDim) * (*cutYDim) * (*cutZDim) ) ) );
2228 
2229  //================================================ Check memory allocation
2230  ProSHADE_internal_misc::checkMemoryAllocation ( mapData, __FILE__, __LINE__, __func__ );
2231  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffs, __FILE__, __LINE__, __func__ );
2232  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffsCut, __FILE__, __LINE__, __func__ );
2233  ProSHADE_internal_misc::checkMemoryAllocation ( bindata, __FILE__, __LINE__, __func__ );
2234  ProSHADE_internal_misc::checkMemoryAllocation ( binCounts, __FILE__, __LINE__, __func__ );
2235  ProSHADE_internal_misc::checkMemoryAllocation ( fscByBin, __FILE__, __LINE__, __func__ );
2236 
2237  //================================================ Allcate memory for bin sumation
2238  for ( size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ )
2239  {
2240  bindata[binIt] = new proshade_double[12];
2241  ProSHADE_internal_misc::checkMemoryAllocation ( bindata[binIt], __FILE__, __LINE__, __func__ );
2242  }
2243 
2244  //================================================ Zeroes
2245  for ( size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ ) { for ( size_t it = 0; it < 12; it++ ) { bindata[binIt][it] = 0.0; } }
2246  for ( size_t binIt = 0; binIt < static_cast< size_t > ( *noBins ); binIt++ ) { binCounts[binIt] = 0; fscByBin[binIt] = 0.0; }
2247  for ( size_t mapIt = 0; mapIt < static_cast< size_t > ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); mapIt++ ) { mapData[mapIt][0] = 0.0; mapData[mapIt][1] = 0.0; fCoeffs[mapIt][0] = 0.0; fCoeffs[mapIt][1] = 0.0; }
2248  for ( size_t mapIt = 0; mapIt < static_cast< size_t > ( (*cutXDim) * (*cutYDim) * (*cutZDim) ); mapIt++ ) { fCoeffsCut[mapIt][0] = 0.0; fCoeffsCut[mapIt][1] = 0.0; }
2249 
2250  //================================================ Prepare memory for Fourier transform
2251  fftw_plan 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 );
2252 
2253  //================================================ Compute Fourier transform of the original map
2254  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; }
2255  ProSHADE_internal_mapManip::changeFourierOrder ( mapData, static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ), true );
2256  fftw_execute ( planForwardFourier );
2257  ProSHADE_internal_mapManip::changeFourierOrder ( fCoeffs, static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ), true );
2258 
2259  //================================================ Cut Fourier coeffs
2260  ProSHADE_internal_maths::cutArrayToResolution ( static_cast< proshade_signed > ( this->xDimIndices ), static_cast< proshade_signed > ( this->yDimIndices ), static_cast< proshade_signed > ( this->zDimIndices ), *noBins, fCoeffs, fCoeffsCut );
2261 
2262  //================================================ Set bins outside of max bin to zero
2263  proshade_unsign arrPos = 0;
2264  for ( proshade_unsign xIt = 0; xIt < static_cast< proshade_unsign > ( *cutXDim ); xIt++ )
2265  {
2266  for ( proshade_unsign yIt = 0; yIt < static_cast< proshade_unsign > ( *cutYDim ); yIt++ )
2267  {
2268  for ( proshade_unsign zIt = 0; zIt < static_cast< proshade_unsign > ( *cutZDim ); zIt++ )
2269  {
2270  arrPos = zIt + static_cast< proshade_unsign > ( *cutZDim ) * ( yIt + static_cast< proshade_unsign > ( *cutYDim ) * xIt );
2271  if ( ( cutIndices[arrPos] < 0 ) || ( cutIndices[arrPos] > (*noBins) ) ) { fCoeffsCut[arrPos][0] = 0.0; fCoeffsCut[arrPos][1] = 0.0; }
2272  }
2273  }
2274  }
2275 
2276  //================================================ Release internal memory
2277  fftw_destroy_plan ( planForwardFourier );
2278  fftw_free ( mapData );
2279  fftw_free ( fCoeffs );
2280 
2281  //================================================ Done
2282  return ;
2283 
2284 }
2285 
2312 proshade_double ProSHADE_internal_data::ProSHADE_data::computeFSC ( ProSHADE_settings* settings, std::vector< proshade_double* >* CSym, size_t symIndex, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_unsign rotNumber )
2313 {
2314  //================================================ Sanity check
2315  if ( symIndex >= CSym->size() )
2316  {
2317  std::cerr << "The supplied symmetry axes vector does not contain element number " << symIndex << ". Returning FSC 0.0." << std::endl;
2318  return ( -2.0 );
2319  }
2320 
2321  //================================================ Ignore if already computed
2322  if ( CSym->at(symIndex)[6] > -2.0 ) { return ( CSym->at(symIndex)[6] ); }
2323 
2324  //================================================ Report progress
2325  std::stringstream ss2;
2326  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];
2327  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str(), settings->messageShift );
2328 
2329  //================================================ Initialise local variables
2330  fftw_complex *rotCoeffs;
2331  proshade_double averageFSC = 0.0;
2332 
2333  //================================================ If no rotation number is given, use all rotations and average
2334  if ( rotNumber == 0 )
2335  {
2336  for ( proshade_unsign rotIndex = 1; rotIndex < static_cast< proshade_unsign > ( CSym->at(symIndex)[0] ); rotIndex++ )
2337  {
2338  //======================================== Get rotated Fourier coefficients
2339  this->rotateFourierCoeffs ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) * static_cast< proshade_double > ( rotIndex ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2340 
2341  //======================================== Compute FSC and sum it
2342  averageFSC += ProSHADE_internal_maths::computeFSC ( fCoeffsCut, rotCoeffs, xDim, yDim, zDim, noBins, cutIndices, bindata, binCounts, fscByBin );
2343 
2344  //======================================== Release memory
2345  fftw_free ( rotCoeffs );
2346  }
2347 
2348  //============================================ Average the summed FSCs
2349  averageFSC /= ( CSym->at(symIndex)[0] - 1.0 );
2350  }
2351  else
2352  {
2353  //============================================ Get rotated Fourier coefficients
2354  this->rotateFourierCoeffs ( CSym->at(symIndex)[1], CSym->at(symIndex)[2], CSym->at(symIndex)[3], ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) * static_cast< proshade_double > ( rotNumber ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2355 
2356  //============================================ Compute FSC
2357  averageFSC = ProSHADE_internal_maths::computeFSC ( fCoeffsCut, rotCoeffs, xDim, yDim, zDim, noBins, cutIndices, bindata, binCounts, fscByBin );
2358 
2359  //============================================ Release memory
2360  fftw_free ( rotCoeffs );
2361  }
2362 
2363  //================================================ Save result to the axis
2364  CSym->at(symIndex)[6] = averageFSC;
2365 
2366  //================================================ Report progress
2367  std::stringstream ss3;
2368  if ( rotNumber != 0 )
2369  {
2370  ss3 << "FSC value for structure rotated by " << ( ( 2.0 * M_PI ) / CSym->at(symIndex)[0] ) * static_cast< proshade_double > ( rotNumber ) << " radians is " << averageFSC << " .";
2371  }
2372  else
2373  {
2374  ss3 << "FSC value averaged over all " << static_cast< proshade_unsign > ( CSym->at(symIndex)[0] - 1 ) << " rotations is " << averageFSC << " .";
2375  }
2376  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str(), settings->messageShift );
2377 
2378  //================================================ Done
2379  return ( averageFSC );
2380 
2381 }
2382 
2408 proshade_double ProSHADE_internal_data::ProSHADE_data::computeFSC ( ProSHADE_settings* settings, proshade_double* sym, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_unsign rotNumber )
2409 {
2410  //================================================ Ignore if already computed
2411  if ( sym[6] > -2.0 ) { return ( sym[6] ); }
2412 
2413  //================================================ Report progress
2414  std::stringstream ss2;
2415  ss2 << "Computing FSC for symmetry C" << sym[0] << " ( " << sym[1] << " ; " << sym[2] << " ; " << sym[3] << " ) with peak height " << sym[5];
2416  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 4, ss2.str(), settings->messageShift );
2417 
2418  //================================================ Initialise local variables
2419  fftw_complex *rotCoeffs;
2420  proshade_double averageFSC = 0.0;
2421 
2422  //================================================ If no rotation number is given, use all rotations and average
2423  if ( rotNumber == 0 )
2424  {
2425  for ( proshade_unsign rotIndex = 1; rotIndex < static_cast< proshade_unsign > ( sym[0] ); rotIndex++ )
2426  {
2427  //======================================== Get rotated Fourier coefficients
2428  this->rotateFourierCoeffs ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) * static_cast< proshade_double > ( rotIndex ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2429 
2430  //======================================== Compute FSC and sum it
2431  averageFSC += ProSHADE_internal_maths::computeFSC ( fCoeffsCut, rotCoeffs, xDim, yDim, zDim, noBins, cutIndices, bindata, binCounts, fscByBin );
2432 
2433  //======================================== Release memory
2434  fftw_free ( rotCoeffs );
2435  }
2436 
2437  //============================================ Average the summed FSCs
2438  averageFSC /= ( sym[0] - 1.0 );
2439  }
2440  else
2441  {
2442  //============================================ Get rotated Fourier coefficients
2443  this->rotateFourierCoeffs ( sym[1], sym[2], sym[3], ( ( 2.0 * M_PI ) / sym[0] ) * static_cast< proshade_double > ( rotNumber ), fCoeffsCut, rotCoeffs, xDim, yDim, zDim );
2444 
2445  //============================================ Compute FSC
2446  averageFSC = ProSHADE_internal_maths::computeFSC ( fCoeffsCut, rotCoeffs, xDim, yDim, zDim, noBins, cutIndices, bindata, binCounts, fscByBin );
2447 
2448  //============================================ Release memory
2449  fftw_free ( rotCoeffs );
2450  }
2451 
2452  //================================================ Save result to the axis
2453  sym[6] = averageFSC;
2454 
2455  //================================================ Report progress
2456  std::stringstream ss3;
2457  if ( rotNumber != 0 )
2458  {
2459  ss3 << "FSC value for structure rotated by " << ( ( 2.0 * M_PI ) / sym[0] ) * static_cast< proshade_double > ( rotNumber ) << " radians is " << averageFSC << " .";
2460  }
2461  else
2462  {
2463  ss3 << "FSC value averaged over all " << static_cast< proshade_unsign > ( sym[0] - 1 ) << " rotations is " << averageFSC << " .";
2464  }
2465  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 5, ss3.str(), settings->messageShift );
2466 
2467  //================================================ Done
2468  return ( averageFSC );
2469 
2470 }
2471 
2502 void ProSHADE_internal_data::ProSHADE_data::determineRecommendedSymmetry ( ProSHADE_settings* settings, proshade_double threshold, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim )
2503 {
2504  //================================================ Report progress
2505  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Starting recommended symmetry decision procedure.", settings->messageShift );
2506 
2507  //================================================ If no C symmetries, nothing to save...
2508  if ( this->cyclicSymmetries.size() == 0 )
2509  {
2510  this->recommendedSymmetryType = "C";
2511  this->recommendedSymmetryFold = 1;
2512  return;
2513  }
2514 
2515  //================================================ Are we in default mode?
2516  if ( threshold < -1.0 ) { threshold = settings->fscThreshold; }
2517 
2518  //================================================ Empty detected values in case this is not the first call to the function
2519  this->recommendedSymmetryType = "C";
2520  this->recommendedSymmetryFold = 1;
2521  for ( size_t it = 0; it < this->recommendedSymmetryValues.size(); it++ ) { if ( this->recommendedSymmetryValues.at(it) != nullptr ) { delete[] this->recommendedSymmetryValues.at(it); this->recommendedSymmetryValues.at(it) = nullptr; } }
2522  this->recommendedSymmetryValues.clear ( );
2523 
2524  //================================================ Apply threshold to new C axes
2525  std::vector< proshade_double* > thresholdedCs;
2526  for ( size_t axIt = 0; axIt < this->cyclicSymmetries.size(); axIt++ ) { if ( this->cyclicSymmetries.at(axIt)[6] >= threshold ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &thresholdedCs, &this->cyclicSymmetries.at(axIt)[0] ); } }
2527 
2528  //================================================ Run the symmetry detection functions for C, D, T, O and I symmetries
2529  this->getDihedralSymmetriesList ( settings, &thresholdedCs );
2530  this->getPredictedTetrahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2531  this->getPredictedOctahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2532  this->getPredictedIcosahedralSymmetriesList ( settings, &thresholdedCs, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
2533 
2534  //================================================ Initialise local variables
2535  proshade_double step = 0.01;
2536  proshade_double sigma = 0.3;
2537  proshade_signed windowSize = 9;
2538  proshade_double IFSCAverage = 0.0, OFSCAverage = 0.0, TFSCAverage = 0.0;
2539  bool IIsBest = false, OIsBest = false, TIsBest = false;
2540 
2541  //================================================ Find the top group minimum threshold using smoothened histogram
2542  proshade_double bestHistPeakStart = ProSHADE_internal_maths::findTopGroupSmooth ( &thresholdedCs, 5, step, sigma, windowSize );
2543  if ( bestHistPeakStart > settings->peakThresholdMin ) { bestHistPeakStart = settings->peakThresholdMin; }
2544 
2545  //================================================ Report progress
2546  proshade_unsign noPassed = 0; for ( size_t cIt = 0; cIt < thresholdedCs.size(); cIt++ ) { if ( thresholdedCs.at(cIt)[5] > bestHistPeakStart ) { noPassed += 1; } }
2547  std::stringstream ss;
2548  ss << "Smoothening has resolved in " << noPassed << " C symmetries.";
2549  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, ss.str(), settings->messageShift );
2550  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Starting FSC computation to confirm the C symmetries existence.", settings->messageShift );
2551 
2552  //================================================ Decide if I is the answer
2553  bool alreadyDecided = false;
2554  if ( this->icosahedralSymmetries.size() == 31 )
2555  {
2556  //============================================ Initialise decision vars
2557  proshade_double fscVal = 0.0;
2558  proshade_double fscValAvg = 0.0;
2559  proshade_unsign lowFSC = 0;
2560 
2561  //============================================ Find FSCs and their average
2562  for ( size_t iIt = 0; iIt < this->icosahedralSymmetries.size(); iIt++ ) { if ( !std::isinf ( this->icosahedralSymmetries.at(iIt)[6] ) ) { fscVal = this->icosahedralSymmetries.at(iIt)[6]; } else { fscVal = this->computeFSC ( settings, &this->icosahedralSymmetries.at(iIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal; if ( fscVal < threshold ) { lowFSC++; } }
2563  fscValAvg /= 31.0;
2564  IFSCAverage = fscValAvg;
2565  if ( ( IFSCAverage < threshold ) || ( lowFSC > 10 ) ) { IFSCAverage = 0.0; }
2566  }
2567 
2568  //================================================ Decide if O is the answer
2569  if ( ( this->octahedralSymmetries.size() == 13 ) && !alreadyDecided )
2570  {
2571  //============================================ Initialise decision vars
2572  proshade_double fscVal = 0.0;
2573  proshade_double fscValAvg = 0.0;
2574  proshade_unsign lowFSC = 0;
2575 
2576  //============================================ Find FSCs and their average
2577  for ( size_t oIt = 0; oIt < this->octahedralSymmetries.size(); oIt++ ) { if ( !std::isinf ( this->octahedralSymmetries.at(oIt)[6] ) ) { fscVal = this->octahedralSymmetries.at(oIt)[6]; } else { fscVal = this->computeFSC ( settings, &this->octahedralSymmetries.at(oIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal; if ( fscVal < threshold ) { lowFSC++; } }
2578  fscValAvg /= 13.0;
2579  OFSCAverage = fscValAvg;
2580  if ( ( OFSCAverage < threshold ) || ( lowFSC > 5 ) ) { OFSCAverage = 0.0; }
2581  }
2582 
2583  //================================================ Decide if T is the answer
2584  if ( ( this->tetrahedralSymmetries.size() == 7 ) && !alreadyDecided )
2585  {
2586  //============================================ Initialise decision vars
2587  proshade_double fscVal = 0.0;
2588  proshade_double fscValAvg = 0.0;
2589  proshade_unsign lowFSC = 0;
2590 
2591  //============================================ Find FSCs and their average
2592  for ( size_t tIt = 0; tIt < this->tetrahedralSymmetries.size(); tIt++ ) { if ( !std::isinf ( this->tetrahedralSymmetries.at(tIt)[6] ) ) { fscVal = this->tetrahedralSymmetries.at(tIt)[6]; } else { fscVal = this->computeFSC ( settings, &this->tetrahedralSymmetries.at(tIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); } fscValAvg += fscVal; if ( fscVal < threshold ) { lowFSC++; } }
2593  fscValAvg /= 7.0;
2594  TFSCAverage = fscValAvg;
2595  if ( ( TFSCAverage < threshold ) || ( lowFSC > 2 ) ) { TFSCAverage = 0.0; }
2596  }
2597 
2598  //================================================ If we are using phaseless detection, different threshold needs to be used due to large number of false positives
2599  proshade_double newThres = threshold;
2600  if ( !settings->usePhase )
2601  {
2602  proshade_double phaselessStep = 0.01;
2603  proshade_double phaselessSigma = 0.005;
2604  proshade_signed phaselessWSize = 5;
2605  newThres = ProSHADE_internal_maths::findTopGroupSmooth ( &thresholdedCs, 6, phaselessStep, phaselessSigma, phaselessWSize );
2606  }
2607 
2608  //================================================ Decide between polyhedral
2609  if ( ( IFSCAverage > std::max( OFSCAverage * 0.9, TFSCAverage * 0.7 ) ) && ( IFSCAverage > newThres ) ) { IIsBest = true; }
2610  if ( ( OFSCAverage > std::max( IFSCAverage * 1.2, TFSCAverage * 0.7 ) ) && ( OFSCAverage > newThres ) ) { OIsBest = true; }
2611  if ( ( TFSCAverage > std::max( IFSCAverage * 1.2, OFSCAverage * 1.1 ) ) && ( TFSCAverage > newThres ) ) { TIsBest = true; }
2612  if ( !IIsBest && !OIsBest && !TIsBest && ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) > newThres ) )
2613  {
2614  const FloatingPoint< proshade_double > lhsPolyI ( IFSCAverage ), lhsPolyO ( OFSCAverage ), lhsPolyT ( TFSCAverage ), rhsPolyMax ( std::max( IFSCAverage, std::max( OFSCAverage, TFSCAverage ) ) );
2615  if ( lhsPolyI.AlmostEquals( rhsPolyMax ) ) { IIsBest = true; }
2616  if ( lhsPolyO.AlmostEquals( rhsPolyMax ) ) { OIsBest = true; }
2617  if ( lhsPolyT.AlmostEquals( rhsPolyMax ) ) { TIsBest = true; }
2618  }
2619 
2620  //================================================ Now we know I is best polyhedral and conforms to threshold
2621  if ( IIsBest )
2622  {
2623  //============================================ The decision is I
2624  this->recommendedSymmetryType = "I";
2625  this->recommendedSymmetryFold = 0;
2626  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->icosahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues , &this->icosahedralSymmetries.at(it)[0] ); }
2627 
2628  //============================================ Done
2629  alreadyDecided = true;
2630  }
2631 
2632  //================================================ Now we know O is best polyhedral and conforms to threshold
2633  if ( OIsBest && !alreadyDecided )
2634  {
2635  //============================================ The decision is O
2636  this->recommendedSymmetryType = "O";
2637  this->recommendedSymmetryFold = 0;
2638  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->octahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->octahedralSymmetries.at(it)[0] ); }
2639 
2640  //============================================ Done
2641  alreadyDecided = true;
2642  }
2643 
2644  //================================================ Now we know T is best polyhedral and conforms to threshold
2645  if ( TIsBest && !alreadyDecided )
2646  {
2647  //============================================ The decision is T
2648  this->recommendedSymmetryType = "T";
2649  this->recommendedSymmetryFold = 0;
2650  for ( proshade_unsign it = 0; it < static_cast<proshade_unsign> ( this->tetrahedralSymmetries.size() ); it++ ) { ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->tetrahedralSymmetries.at(it)[0] ); }
2651 
2652  //============================================ Done
2653  alreadyDecided = true;
2654  }
2655 
2656  //================================================ Decide if D is the answer
2657  proshade_signed bestD = -1;
2658  if ( ( this->dihedralSymmetries.size() > 0 ) && !alreadyDecided )
2659  {
2660  //============================================ Initialise local variables
2661  proshade_unsign bestFold = 0;
2662  proshade_double bestValFSC = -std::numeric_limits < proshade_double >::infinity();
2663  proshade_double bestValPeak = -std::numeric_limits < proshade_double >::infinity();
2664 
2665  //============================================ Find FSCs
2666  for ( size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2667  {
2668  //======================================== Check the peak heights
2669  const FloatingPoint< proshade_double > lhs999a ( this->dihedralSymmetries.at(dIt).at(0)[5] ), lhs999b ( this->dihedralSymmetries.at(dIt).at(1)[5] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2670  if ( ( this->dihedralSymmetries.at(dIt).at(0)[5] < bestHistPeakStart ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2671  if ( ( this->dihedralSymmetries.at(dIt).at(1)[5] < bestHistPeakStart ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2672 
2673  //======================================== Find FSCs
2674  if ( std::isinf ( this->dihedralSymmetries.at(dIt).at(0)[6] ) ) { this->computeFSC ( settings, &this->dihedralSymmetries.at(dIt).at(0)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2675  if ( std::isinf ( this->dihedralSymmetries.at(dIt).at(1)[6] ) ) { this->computeFSC ( settings, &this->dihedralSymmetries.at(dIt).at(1)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2676  }
2677 
2678  //============================================ Prepare vector to get the smoothened threshold for D's only
2679  std::vector< proshade_double* > smootheningHlp;
2680  for ( size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2681  {
2682  //======================================== Apply thresholding
2683  if ( this->dihedralSymmetries.at(dIt).at(0)[6] < threshold ) { continue; }
2684  if ( this->dihedralSymmetries.at(dIt).at(1)[6] < threshold ) { continue; }
2685 
2686  //======================================== Create helper axis
2687  proshade_double* sym = new proshade_double[7];
2688  ProSHADE_internal_misc::checkMemoryAllocation ( sym, __FILE__, __LINE__, __func__ );
2689 
2690  sym[0] = 0.0; sym[1] = 0.0; sym[2] = 0.0; sym[3] = 0.0; sym[4] = 0.0;
2691  sym[5] = ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0;
2692  sym[6] = ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0;
2693 
2694  //======================================== Deep copy to a vector
2695  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &smootheningHlp, sym );
2696 
2697  //======================================== Release the helper axis memory
2698  delete[] sym;
2699  }
2700 
2701  //============================================ Get smoothened threshold for D's only
2702  proshade_double onlyDPeakThreshold = ProSHADE_internal_maths::findTopGroupSmooth ( &smootheningHlp, 5, step, sigma, windowSize );
2703  proshade_double onlyDFSCThreshold = ProSHADE_internal_maths::findTopGroupSmooth ( &smootheningHlp, 6, step, sigma, windowSize );
2704 
2705  //============================================ Release the helper memory
2706  for ( size_t axIt = 0; axIt < smootheningHlp.size(); axIt++ ) { if ( smootheningHlp.at(axIt) != nullptr ) { delete[] smootheningHlp.at(axIt); } }
2707 
2708  //============================================ Check if both C symmetries are reliable
2709  for ( size_t dIt = 0; dIt < this->dihedralSymmetries.size(); dIt++ )
2710  {
2711  //======================================== Apply thresholding
2712  if ( this->dihedralSymmetries.at(dIt).at(0)[6] < threshold ) { continue; }
2713  if ( this->dihedralSymmetries.at(dIt).at(1)[6] < threshold ) { continue; }
2714 
2715  //======================================== Check the peak heights
2716  const FloatingPoint< proshade_double > lhs999a2 ( this->dihedralSymmetries.at(dIt).at(0)[5] ), lhs999b2 ( this->dihedralSymmetries.at(dIt).at(1)[5] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2717  if ( ( this->dihedralSymmetries.at(dIt).at(0)[5] < bestHistPeakStart ) && !( lhs999a2.AlmostEquals( rhs999 ) ) ) { continue; }
2718  if ( ( this->dihedralSymmetries.at(dIt).at(1)[5] < bestHistPeakStart ) && !( lhs999b2.AlmostEquals( rhs999 ) ) ) { continue; }
2719  if ( std::min ( this->dihedralSymmetries.at(dIt).at(0)[5], this->dihedralSymmetries.at(dIt).at(1)[5] ) < ( std::max ( settings->peakThresholdMin, onlyDPeakThreshold ) * 0.90 ) ) { continue; }
2720 
2721  //======================================== Does this improve the best fold?
2722  if ( ( this->dihedralSymmetries.at(dIt).at(0)[0] > static_cast< proshade_double > ( bestFold ) ) ||
2723  ( this->dihedralSymmetries.at(dIt).at(1)[0] > static_cast< proshade_double > ( bestFold ) ) )
2724  {
2725  //==================================== Check the FSC vals
2726  if ( ( this->dihedralSymmetries.at(dIt).at(0)[6] < std::max ( threshold, onlyDFSCThreshold ) ) &&
2727  ( this->dihedralSymmetries.at(dIt).at(1)[6] < std::max ( threshold, onlyDFSCThreshold ) ) ) { continue; }
2728  if ( std::min ( this->dihedralSymmetries.at(dIt).at(0)[6], this->dihedralSymmetries.at(dIt).at(1)[6] ) < ( std::max ( threshold, onlyDFSCThreshold ) * 0.70 ) ) { continue; }
2729 
2730  //==================================== All good!
2731  bestValPeak = ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 );
2732  bestValFSC = ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 );
2733  bestFold = static_cast< proshade_unsign > ( std::max ( this->dihedralSymmetries.at(dIt).at(0)[0], this->dihedralSymmetries.at(dIt).at(1)[0] ) );
2734  bestD = static_cast< proshade_signed > ( dIt );
2735  }
2736  else
2737  {
2738  //==================================== If not, is the FSC sum better?
2739  const FloatingPoint< proshade_double > lhs1 ( this->dihedralSymmetries.at(dIt).at(0)[0] ), lhs2 ( this->dihedralSymmetries.at(dIt).at(1)[0] ), rhs ( static_cast< proshade_double > ( bestFold ) );
2740  if ( ( ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 ) > ( bestValFSC * 1.00 ) ) &&
2741  ( ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 ) > ( bestValPeak * 0.95 ) ) &&
2742  ( ( lhs1.AlmostEquals ( rhs ) ) || ( lhs2.AlmostEquals ( rhs ) ) ) )
2743  {
2744  bestValPeak = ( ( this->dihedralSymmetries.at(dIt).at(0)[5] + this->dihedralSymmetries.at(dIt).at(1)[5] ) / 2.0 );
2745  bestValFSC = ( ( this->dihedralSymmetries.at(dIt).at(0)[6] + this->dihedralSymmetries.at(dIt).at(1)[6] ) / 2.0 );
2746  bestFold = static_cast< proshade_unsign > ( std::max ( this->dihedralSymmetries.at(dIt).at(0)[0], this->dihedralSymmetries.at(dIt).at(1)[0] ) );
2747  bestD = static_cast< proshade_signed > ( dIt );
2748  }
2749  }
2750  }
2751 
2752  //============================================ Anything?
2753  if ( bestD != -1 )
2754  {
2755  //======================================== The decision is D
2756  this->recommendedSymmetryType = "D";
2757  this->recommendedSymmetryFold = static_cast< proshade_unsign > ( std::max ( this->dihedralSymmetries.at( static_cast< size_t> ( bestD ) ).at(0)[0], this->dihedralSymmetries.at( static_cast< size_t> ( bestD ) ).at(0)[1] ) );
2758  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->dihedralSymmetries.at( static_cast< size_t> ( bestD ) ).at(0)[0] );
2759  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->dihedralSymmetries.at( static_cast< size_t> ( bestD ) ).at(1)[0] );
2760  }
2761  }
2762 
2763  //================================================ Decide if C is the answer
2764  if ( ( this->cyclicSymmetries.size() > 0 ) && !alreadyDecided )
2765  {
2766  //============================================ Initialise decision vars
2767  proshade_signed bestC = -1;
2768  proshade_unsign bestFold = 0;
2769 
2770  //============================================ Find FSCs for C syms
2771  for ( size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
2772  {
2773  //======================================== Do not consider more than top 20, takes time and is unlikely to produce anything...
2774  if ( ( cIt > 20 ) && ( this->cyclicSymmetries.at(cIt)[5] < 0.95 ) ) { break; }
2775 
2776  //======================================== Check the peak height
2777  if ( this->cyclicSymmetries.at(cIt)[5] < bestHistPeakStart ) { continue; }
2778 
2779  //======================================== Compute FSC
2780  if ( std::isinf ( this->cyclicSymmetries.at(cIt)[6] ) ) { this->computeFSC ( settings, &this->cyclicSymmetries.at(cIt)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim ); }
2781  }
2782 
2783  //============================================ Find FSC top group threshold
2784  proshade_double bestHistFSCStart = ProSHADE_internal_maths::findTopGroupSmooth ( &this->cyclicSymmetries, 6, step, sigma, windowSize );
2785  if ( static_cast< proshade_signed > ( threshold * 100.0 ) > static_cast< proshade_signed > ( settings->fscThreshold * 100.0 ) ) { bestHistFSCStart = threshold; }
2786 
2787  //============================================ Find reliable C syms (this makes the assumption that the input C axes list is FSC sorted!)
2788  for ( size_t cIt = 0; cIt < this->cyclicSymmetries.size(); cIt++ )
2789  {
2790  //======================================== Check if this improves the best already found fold
2791  if ( this->cyclicSymmetries.at(cIt)[0] > static_cast< proshade_double > ( bestFold ) )
2792  {
2793  //==================================== If FSC passes
2794  if ( this->cyclicSymmetries.at(cIt)[6] > std::max ( bestHistFSCStart, threshold ) )
2795  {
2796  bestFold = static_cast< proshade_unsign > ( this->cyclicSymmetries.at(cIt)[0] );
2797  bestC = static_cast< proshade_signed > ( cIt );
2798  }
2799  }
2800  }
2801 
2802  //============================================ Anything?
2803  if ( ( bestC != -1 ) && ( this->recommendedSymmetryType == "D" ) )
2804  {
2805  //======================================== Decide if C or D is more appropriate
2806  if ( ( ( this->cyclicSymmetries.at( static_cast< size_t > ( bestC ) )[6] * 0.80 ) > std::min ( this->dihedralSymmetries.at( static_cast< size_t > ( bestD ) ).at(0)[6], this->dihedralSymmetries.at( static_cast< size_t > ( bestD ) ).at(1)[6] ) ) &&
2807  ( ( this->cyclicSymmetries.at( static_cast< size_t > ( bestC ) )[5] * 0.95 ) > std::min ( this->dihedralSymmetries.at( static_cast< size_t > ( bestD ) ).at(0)[5], this->dihedralSymmetries.at( static_cast< size_t > ( bestD ) ).at(1)[5] ) ) )
2808  {
2809  this->recommendedSymmetryType = "C";
2810  this->recommendedSymmetryFold = 1;
2811  for ( size_t iter = 0; iter < this->recommendedSymmetryValues.size(); iter++ ) { if ( this->recommendedSymmetryValues.at(iter) != nullptr ) { delete[] this->recommendedSymmetryValues.at(iter); this->recommendedSymmetryValues.at(iter) = nullptr; } }
2812  this->recommendedSymmetryValues.clear ( );
2813  }
2814  }
2815  if ( ( bestC != -1 ) && ( this->recommendedSymmetryType != "D" ) )
2816  {
2817  //======================================== The decision is C
2818  this->recommendedSymmetryType = "C";
2819  this->recommendedSymmetryFold = static_cast< proshade_unsign > ( this->cyclicSymmetries.at( static_cast< size_t > ( bestC ) )[0] );
2820  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->cyclicSymmetries.at( static_cast< size_t > ( bestC ) )[0] );
2821 
2822  //======================================== Done
2823  alreadyDecided = true;
2824  }
2825  }
2826 
2827  //================================================ Release memory
2828  for ( size_t iter = 0; iter < thresholdedCs.size(); iter++ ) { if ( thresholdedCs.at(iter) != nullptr ) { delete[] thresholdedCs.at(iter); } }
2829 
2830  //================================================ Done
2831  return ;
2832 
2833 }
2834 
2853 void ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryD ( ProSHADE_settings* settings, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
2854 {
2855  //================================================ Initialise variables
2856  proshade_unsign bestIndex = 0;
2857  proshade_double highestSym = 0.0;
2858 
2859  //================================================ Search for best fold
2860  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( this->dihedralSymmetries.size() ); iter++ )
2861  {
2862  //============================================ Check if it is tbe correct fold
2863  const FloatingPoint< proshade_double > lhs1 ( std::max ( this->dihedralSymmetries.at(iter).at(0)[0], this->dihedralSymmetries.at(iter).at(1)[0] ) ), rhs1 ( static_cast< proshade_double > ( settings->requestedSymmetryFold ) );
2864  if ( !lhs1.AlmostEquals ( rhs1 ) ) { continue; }
2865 
2866  //============================================ Check if peak height is decent
2867  const FloatingPoint< proshade_double > lhs999a ( this->dihedralSymmetries.at(iter).at(0)[5] ), lhs999b ( this->dihedralSymmetries.at(iter).at(1)[5] ), rhs999 ( static_cast< proshade_double > ( -999.9 ) );
2868  if ( ( this->dihedralSymmetries.at(iter).at(0)[5] < settings->peakThresholdMin ) && !( lhs999a.AlmostEquals( rhs999 ) ) ) { continue; }
2869  if ( ( this->dihedralSymmetries.at(iter).at(1)[5] < settings->peakThresholdMin ) && !( lhs999b.AlmostEquals( rhs999 ) ) ) { continue; }
2870 
2871  //============================================ If correct, compute FSC
2872  this->computeFSC ( settings, &this->dihedralSymmetries.at(iter).at(0)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
2873  this->computeFSC ( settings, &this->dihedralSymmetries.at(iter).at(1)[0], cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, xDim, yDim, zDim );
2874 
2875  //============================================ If best, store it
2876  if ( ( this->dihedralSymmetries.at(iter).at(0)[6] + this->dihedralSymmetries.at(iter).at(1)[6] ) > highestSym )
2877  {
2878  highestSym = ( this->dihedralSymmetries.at(iter).at(0)[6] + this->dihedralSymmetries.at(iter).at(1)[6] );
2879  bestIndex = iter;
2880  }
2881  }
2882 
2883  //================================================ Found?
2884  if ( highestSym > 0.0 )
2885  {
2886  this->recommendedSymmetryType = "D";
2887  this->recommendedSymmetryFold = static_cast< proshade_unsign > ( std::max ( this->dihedralSymmetries.at(bestIndex).at(0)[0], this->dihedralSymmetries.at(bestIndex).at(1)[0] ) );
2888 
2889  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->dihedralSymmetries.at(bestIndex).at(0)[0] );
2890  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &this->recommendedSymmetryValues, &this->dihedralSymmetries.at(bestIndex).at(1)[0] );
2891  }
2892  else
2893  {
2894  this->recommendedSymmetryType = "C";
2895  this->recommendedSymmetryFold = 1;
2896  }
2897 
2898  //================================================ Done
2899  return ;
2900 
2901 }
2902 
2911 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::computeGroupElementsForGroup ( proshade_double xAx, proshade_double yAx, proshade_double zAx, proshade_signed fold )
2912 {
2913  //================================================ Initialise variables
2914  std::vector< proshade_double > angList;
2915  std::vector<std::vector< proshade_double > > ret;
2916 
2917  //================================================ Allocate memory
2918  proshade_double* rotMat = new proshade_double[9];
2919  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
2920 
2921 
2922  //================================================ Normalise the axis to have magnitude of 1.0
2923  proshade_double normF = std::sqrt( std::pow ( xAx, 2.0 ) + std::pow ( yAx, 2.0 ) + std::pow ( zAx, 2.0 ) );
2924  xAx /= normF;
2925  yAx /= normF;
2926  zAx /= normF;
2927 
2928  //================================================ Determine the list of angles
2929  if ( fold % 2 == 0 )
2930  {
2931  //============================================ If fold is even, add the negative angles
2932  for ( proshade_double iter = static_cast < proshade_double > ( -( ( fold / 2 ) - 1 ) ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2933  {
2934  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
2935  }
2936  }
2937  else
2938  {
2939  //============================================ If fold is odd, do the same as for even, but start one index earlier
2940  for ( proshade_double iter = static_cast < proshade_double > ( -fold / 2 ); iter <= static_cast < proshade_double > ( fold / 2 ); iter++ )
2941  {
2942  ProSHADE_internal_misc::addToDoubleVector ( &angList, ( ( 2.0 * M_PI ) / static_cast<proshade_double> ( fold ) ) * iter );
2943  }
2944  }
2945 
2946  //================================================ For each detected angle
2947  for ( proshade_unsign iter = 0; iter < static_cast < proshade_unsign > ( angList.size() ); iter++ )
2948  {
2949  //============================================ Compute the rotation matrix
2950  ProSHADE_internal_maths::getRotationMatrixFromAngleAxis ( rotMat, xAx, yAx, zAx, angList.at(iter) );
2951 
2952  //============================================ Convert to vector of vectors of doubles and save to ret
2953  std::vector < proshade_double > retEl;
2954  for ( proshade_unsign matIt = 0; matIt < 9; matIt++ )
2955  {
2956  ProSHADE_internal_misc::addToDoubleVector ( &retEl, rotMat[matIt] );
2957  }
2959  }
2960 
2961  //================================================ Release memory
2962  delete[] rotMat;
2963 
2964  //================================================ Done
2965  return ( ret );
2966 
2967 }
2968 
2975 void axesToGroupTypeSanityCheck ( proshade_unsign requiredAxes, proshade_unsign obtainedAxes, std::string groupType )
2976 {
2977  //================================================ Sanity check
2978  if ( obtainedAxes != requiredAxes )
2979  {
2980  std::stringstream hlpSS;
2981  hlpSS << "The supplied number of axes for group element\n : detection ( >" << obtainedAxes << "< ) does not match the group type ( >" << groupType << "< ).";
2982  throw ProSHADE_exception ( "Mismatch between supplied number of axes and\n : symmetry type.", "ES00059", __FILE__, __LINE__, __func__, hlpSS.str() );
2983  }
2984 
2985  //================================================ Done
2986  return ;
2987 
2988 }
2989 
2997 bool checkElementAlreadyExists ( std::vector<std::vector< proshade_double > >* elements, std::vector< proshade_double >* elem, proshade_double matrixTolerance )
2998 {
2999  //================================================ Initialise variables
3000  bool elementFound = false;
3001 
3002  //================================================ For each existing element
3003  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( elements->size() ); elIt++ )
3004  {
3005  if ( ProSHADE_internal_maths::rotationMatrixSimilarity ( &elements->at(elIt), elem, matrixTolerance ) )
3006  {
3007  elementFound = true;
3008  break;
3009  }
3010  }
3011 
3012  //================================================ Done
3013  return ( elementFound );
3014 
3015 }
3016 
3023 bool checkElementsFormGroup ( std::vector<std::vector< proshade_double > >* elements, proshade_double matrixTolerance )
3024 {
3025  //================================================ Initialise variables
3026  bool isGroup = true;
3027 
3028  //================================================ Multiply all group element pairs
3029  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( elements->size() ); gr1++ )
3030  {
3031  for ( proshade_unsign gr2 = 1; gr2 < static_cast<proshade_unsign> ( elements->size() ); gr2++ )
3032  {
3033  //======================================== Use unique pairs only
3034  if ( gr1 >= gr2 ) { continue; }
3035 
3036  //======================================== Multiply the two rotation matrices
3037  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &elements->at(gr1), &elements->at(gr2) );
3038 
3039  //======================================== Check the group already contains the produces as an element
3040  if ( !checkElementAlreadyExists ( elements, &product, matrixTolerance ) )
3041  {
3042  isGroup = false;
3043  break;
3044  }
3045  }
3046 
3047  //============================================ Stop if problem was found
3048  if ( !isGroup ) { break; }
3049  }
3050 
3051  //================================================ Done
3052  return ( isGroup );
3053 
3054 }
3055 
3064 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 )
3065 {
3066  //================================================ Initialise variables
3067  std::vector< std::vector< proshade_double > > ret;
3068 
3069  //================================================ Add the first list to ret, checking for uniqueness
3070  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( first->size() ); elIt++ )
3071  {
3072  if ( !checkElementAlreadyExists( &ret, &first->at(elIt), matrixTolerance ) )
3073  {
3074  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, first->at(elIt) );
3075  }
3076  }
3077 
3078  //================================================ Add the second list to ret, checking for uniqueness
3079  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( second->size() ); elIt++ )
3080  {
3081  if ( !checkElementAlreadyExists( &ret, &second->at(elIt), matrixTolerance ) )
3082  {
3083  ProSHADE_internal_misc::addToDoubleVectorVector ( &ret, second->at(elIt) );
3084  }
3085  }
3086 
3087  //================================================ Multiply all combinations of first and second and check for uniqueness
3088  if ( combine )
3089  {
3090  for ( proshade_unsign gr1 = 0; gr1 < static_cast<proshade_unsign> ( first->size() ); gr1++ )
3091  {
3092  for ( proshade_unsign gr2 = 0; gr2 < static_cast<proshade_unsign> ( second->size() ); gr2++ )
3093  {
3094  //==================================== Multiply the two rotation matrices
3095  std::vector< proshade_double > product = ProSHADE_internal_maths::multiplyGroupElementMatrices ( &first->at(gr1), &second->at(gr2) );
3096 
3097  //==================================== Add
3098  if ( !checkElementAlreadyExists( &ret, &product, matrixTolerance ) )
3099  {
3101  }
3102 
3103  }
3104  }
3105  }
3106 
3107  //================================================ Done
3108  return ( ret );
3109 
3110 }
3111 
3122 std::vector<std::vector< proshade_double > > ProSHADE_internal_data::ProSHADE_data::getAllGroupElements ( std::vector< proshade_unsign > axesList, std::string groupType, proshade_double matrixTolerance )
3123 {
3124  //================================================ Initialise variables
3125  std::vector< std::vector< proshade_double > > hlpVec;
3126  std::vector< proshade_double > hlpVec2;
3127  for ( size_t it1 = 0; it1 < this->cyclicSymmetries.size(); it1++ )
3128  {
3129  hlpVec2.clear ( );
3130  for ( size_t it2 = 0; it2 < 7; it2++ )
3131  {
3132  ProSHADE_internal_misc::addToDoubleVector ( &hlpVec2, this->cyclicSymmetries.at(it1)[it2] );
3133  }
3135  }
3136 
3137  //================================================ Get group elements
3138  std::vector< std::vector< proshade_double > > ret = this->getAllGroupElements ( &hlpVec, axesList, groupType, matrixTolerance );
3139 
3140  //================================================ Done
3141  return ( ret );
3142 
3143 }
3144 
3163 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 )
3164 {
3165  //================================================ Initialise variables
3166  std::vector<std::vector< proshade_double > > ret;
3167 
3168  //================================================ Select which symmetry type are we computing for
3169  if ( groupType == "C" )
3170  {
3171  //============================================ Sanity check
3172  axesToGroupTypeSanityCheck ( 1, static_cast< proshade_unsign > ( axesList.size() ), groupType );
3173 
3174  //============================================ Generate elements
3175  ret = computeGroupElementsForGroup ( allCs->at(axesList.at(0)).at(1),
3176  allCs->at(axesList.at(0)).at(2),
3177  allCs->at(axesList.at(0)).at(3),
3178  static_cast< proshade_signed > ( allCs->at(axesList.at(0)).at(0) ) );
3179 
3180  //============================================ Check the element to form a group
3181  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3182  else
3183  {
3184  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." );
3185  }
3186  }
3187  else if ( groupType == "D" )
3188  {
3189  //============================================ Sanity check
3190  axesToGroupTypeSanityCheck ( 2, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3191 
3192  //============================================ Generate elements for both axes
3193  std::vector<std::vector< proshade_double > > first = computeGroupElementsForGroup ( allCs->at(axesList.at(0)).at(1),
3194  allCs->at(axesList.at(0)).at(2),
3195  allCs->at(axesList.at(0)).at(3),
3196  static_cast< proshade_signed > ( allCs->at(axesList.at(0)).at(0) ) );
3197 
3198  std::vector<std::vector< proshade_double > > second = computeGroupElementsForGroup ( allCs->at(axesList.at(1)).at(1),
3199  allCs->at(axesList.at(1)).at(2),
3200  allCs->at(axesList.at(1)).at(3),
3201  static_cast< proshade_signed > ( allCs->at(axesList.at(1)).at(0) ) );
3202 
3203  //============================================ Join the element lists
3204  ret = joinElementsFromDifferentGroups ( &first, &second, matrixTolerance, true );
3205 
3206  //============================================ Check the element to form a group
3207  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3208  else
3209  {
3210  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." );
3211  }
3212  }
3213  else if ( groupType == "T" )
3214  {
3215  //============================================ Sanity check
3216  axesToGroupTypeSanityCheck ( 7, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3217 
3218  //============================================ Generate elements for all four C3 axes first
3219  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3220  {
3221  //======================================== If this is a C3 axis
3222  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3223  if ( lhs1.AlmostEquals ( rhs1 ) )
3224  {
3225  //==================================== Generate the elements
3226  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3227  allCs->at(axesList.at(grIt)).at(2),
3228  allCs->at(axesList.at(grIt)).at(3),
3229  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3230 
3231  //==================================== Join the elements to any already found
3232  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3233  }
3234  }
3235 
3236  //============================================ Generate elements for all three C2 axes second
3237  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3238  {
3239  //======================================== If this is a C3 axis
3240  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3241  if ( lhs1.AlmostEquals ( rhs1 ) )
3242  {
3243  //==================================== Generate the elements
3244  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3245  allCs->at(axesList.at(grIt)).at(2),
3246  allCs->at(axesList.at(grIt)).at(3),
3247  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3248 
3249  //==================================== Join the elements to any already found
3250  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3251  }
3252  }
3253 
3254  //============================================ Check the element to form a group
3255  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3256  else
3257  {
3258  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." );
3259  }
3260  }
3261  else if ( groupType == "O" )
3262  {
3263  //============================================ Sanity check
3264  axesToGroupTypeSanityCheck ( 13, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3265 
3266  //============================================ Generate elements for all three C4 axes first
3267  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3268  {
3269  //======================================== If this is a C3 axis
3270  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 4.0 );
3271  if ( lhs1.AlmostEquals ( rhs1 ) )
3272  {
3273  //==================================== Generate the elements
3274  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3275  allCs->at(axesList.at(grIt)).at(2),
3276  allCs->at(axesList.at(grIt)).at(3),
3277  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3278 
3279  //==================================== Join the elements to any already found
3280  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3281  }
3282  }
3283 
3284  //============================================ Generate elements for all four C3 axes first
3285  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3286  {
3287  //======================================== If this is a C3 axis
3288  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3289  if ( lhs1.AlmostEquals ( rhs1 ) )
3290  {
3291  //==================================== Generate the elements
3292  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3293  allCs->at(axesList.at(grIt)).at(2),
3294  allCs->at(axesList.at(grIt)).at(3),
3295  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3296 
3297  //==================================== Join the elements to any already found
3298  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3299  }
3300  }
3301 
3302  //============================================ Generate elements for all six C2 axes next
3303  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3304  {
3305  //======================================== If this is a C3 axis
3306  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3307  if ( lhs1.AlmostEquals ( rhs1 ) )
3308  {
3309  //==================================== Generate the elements
3310  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3311  allCs->at(axesList.at(grIt)).at(2),
3312  allCs->at(axesList.at(grIt)).at(3),
3313  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3314 
3315  //==================================== Join the elements to any already found
3316  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3317  }
3318  }
3319 
3320  //============================================ Check the element to form a group
3321  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3322  else
3323  {
3324  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." );
3325  }
3326  }
3327  else if ( groupType == "I" )
3328  {
3329  //============================================ Sanity check
3330  axesToGroupTypeSanityCheck ( 31, static_cast<proshade_unsign> ( axesList.size() ), groupType );
3331 
3332  //============================================ Generate elements for all six C5 axes first
3333  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3334  {
3335  //======================================== If this is a C5 axis
3336  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 5.0 );
3337  if ( lhs1.AlmostEquals ( rhs1 ) )
3338  {
3339  //==================================== Generate the elements
3340  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3341  allCs->at(axesList.at(grIt)).at(2),
3342  allCs->at(axesList.at(grIt)).at(3),
3343  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3344 
3345  //==================================== Join the elements to any already found
3346  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3347  }
3348  }
3349 
3350  //============================================ Generate elements for all ten C3 axes next
3351  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3352  {
3353  //======================================== If this is a C3 axis
3354  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 3.0 );
3355  if ( lhs1.AlmostEquals ( rhs1 ) )
3356  {
3357  //==================================== Generate the elements
3358  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3359  allCs->at(axesList.at(grIt)).at(2),
3360  allCs->at(axesList.at(grIt)).at(3),
3361  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3362 
3363  //==================================== Join the elements to any already found
3364  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3365  }
3366  }
3367 
3368  //============================================ Generate elements for all fifteen C2 axes lastly
3369  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3370  {
3371  //======================================== If this is a C3 axis
3372  const FloatingPoint< proshade_double > lhs1 ( allCs->at(axesList.at(grIt)).at(0) ), rhs1 ( 2.0 );
3373  if ( lhs1.AlmostEquals ( rhs1 ) )
3374  {
3375  //==================================== Generate the elements
3376  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3377  allCs->at(axesList.at(grIt)).at(2),
3378  allCs->at(axesList.at(grIt)).at(3),
3379  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3380 
3381  //==================================== Join the elements to any already found
3382  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, false );
3383  }
3384  }
3385 
3386  //============================================ Check the element to form a group
3387  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3388  else
3389  {
3390  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." );
3391  }
3392  }
3393  else if ( groupType == "X" )
3394  {
3395  //============================================ User forced no checking for unspecified symmetry
3396  for ( proshade_unsign grIt = 0; grIt < static_cast<proshade_unsign> ( axesList.size() ); grIt++ )
3397  {
3398  //======================================== Compute group elements
3399  std::vector<std::vector< proshade_double > > els = computeGroupElementsForGroup ( allCs->at(axesList.at(grIt)).at(1),
3400  allCs->at(axesList.at(grIt)).at(2),
3401  allCs->at(axesList.at(grIt)).at(3),
3402  static_cast< proshade_signed > ( allCs->at(axesList.at(grIt)).at(0) ) );
3403 
3404  //======================================== Join the elements to any already found
3405  ret = joinElementsFromDifferentGroups ( &els, &ret, matrixTolerance, true );
3406  }
3407 
3408  //============================================ Check the element to form a group
3409  if ( checkElementsFormGroup ( &ret, matrixTolerance ) ) { return ( ret ); }
3410  else
3411  {
3412  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." );
3413  }
3414  }
3415  else
3416  {
3417  std::stringstream hlpSS;
3418  hlpSS << "Unknown symmetry type: >" << groupType << "<";
3419  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." );
3420  }
3421 
3422 }
3423 
3431 void ProSHADE_internal_data::ProSHADE_data::deepCopyMap ( proshade_double*& saveTo, proshade_signed verbose )
3432 {
3433  //================================================ Sanity check
3434  if ( saveTo != nullptr )
3435  {
3436  ProSHADE_internal_messages::printWarningMessage ( verbose, "!!! ProSHADE WARNING !!! The deep copy pointer is not set to NULL. Cannot proceed and returning unmodified pointer.", "WB00040" );
3437  return ;
3438  }
3439 
3440  //================================================ Allocate the memory
3441  saveTo = new proshade_double[this->xDimIndices * this->yDimIndices * this->zDimIndices];
3442 
3443  //================================================ Check memory allocation
3444  ProSHADE_internal_misc::checkMemoryAllocation ( saveTo, __FILE__, __LINE__, __func__ );
3445 
3446  //================================================ Copy internal map to the new pointer
3447  for ( proshade_unsign iter = 0; iter < ( this->xDimIndices * this->yDimIndices * this->zDimIndices ); iter++ )
3448  {
3449  saveTo[iter] = this->internalMap[iter];
3450  }
3451 
3452  //================================================ Done
3453  return ;
3454 
3455 }
3456 
3464 {
3465  //================================================ Improve this!
3466  if ( this->recommendedSymmetryType == "" || ( this->recommendedSymmetryType == "C" && this->recommendedSymmetryFold == 1 ) )
3467  {
3469  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, "Cannot predict any symmetry! There may still be symmetries detected, but ProSHADE algorithm does not consider them reliable.", settings->messageShift );
3470  }
3471  else
3472  {
3473  std::stringstream ssHlp;
3474  std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3475  ssHlp << std::endl << "Detected " << this->recommendedSymmetryType << " symmetry with fold " << this->recommendedSymmetryFold << " about point [" << comMove.at(0) << " , " << comMove.at(1) << " , " << comMove.at(2) << "] away from centre of mass .";
3476  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3477 
3478  if ( this->recommendedSymmetryValues.size() > 0 )
3479  {
3480  ssHlp.clear(); ssHlp.str ( "" );
3481  ssHlp << " Fold X Y Z Angle Height Average FSC";
3482  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3483  }
3484  for ( size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3485  {
3486  ssHlp.clear(); ssHlp.str ( "" );
3487  ssHlp << std::showpos << std::fixed << std::setprecision(0) << " " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) << " " << this->recommendedSymmetryValues.at(symIt)[1] << " " << this->recommendedSymmetryValues.at(symIt)[2] << " " << this->recommendedSymmetryValues.at(symIt)[3] << " " << this->recommendedSymmetryValues.at(symIt)[4] << " " << this->recommendedSymmetryValues.at(symIt)[5] << " " << this->recommendedSymmetryValues.at(symIt)[6];
3488  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3489  }
3490  }
3491 
3492  std::stringstream ssHlp, hlpSS3;
3493  ssHlp.clear(); ssHlp.str ( "" );
3494  hlpSS3 << std::endl << "To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3495  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, hlpSS3.str(), settings->messageShift );
3496 
3497  if ( this->cyclicSymmetries.size() > 0 )
3498  {
3499  ssHlp.clear(); ssHlp.str ( "" );
3500  ssHlp << " Fold X Y Z Angle Height Average FSC";
3501  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3502  }
3503  for ( size_t symIt = 0; symIt < this->cyclicSymmetries.size(); symIt++ )
3504  {
3505  ssHlp.clear(); ssHlp.str ( "" );
3506  ssHlp << std::showpos << std::fixed << std::setprecision(0) << " " << this->cyclicSymmetries.at(symIt)[0] << std::setprecision(5) << " " << this->cyclicSymmetries.at(symIt)[1] << " " << this->cyclicSymmetries.at(symIt)[2] << " " << this->cyclicSymmetries.at(symIt)[3] << " " << this->cyclicSymmetries.at(symIt)[4] << " " << this->cyclicSymmetries.at(symIt)[5] << " " << this->cyclicSymmetries.at(symIt)[6];
3507  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3508  }
3509 
3510  //================================================ Done
3511  return ;
3512 
3513 }
3514 
3531 void ProSHADE_internal_data::ProSHADE_data::reportCurrentSymmetryResults ( ProSHADE_settings* settings, proshade_double threshold, proshade_signed*& cutIndices, fftw_complex*& fCoeffsCut, proshade_signed noBins, proshade_double**& bindata, proshade_signed*& binCounts, proshade_double*& fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim )
3532 {
3533  //================================================ Find results for the given threshold
3534  proshade_signed origVerbose = settings->verbose;
3535  settings->verbose = -999;
3536  this->determineRecommendedSymmetry ( settings, threshold, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3537  settings->verbose = origVerbose;
3538 
3539  //================================================ Improve this!
3540  if ( this->recommendedSymmetryType == "" || ( this->recommendedSymmetryType == "C" && this->recommendedSymmetryFold == 1 ) )
3541  {
3542  std::stringstream ssHlp;
3543  ssHlp << std::showpos << std::fixed << std::setprecision(2) << " " << threshold << " C +1 +0.00000 +0.00000 +0.00000 +0.00000 +1.00000 +1.00000" << std::endl << "===========================================================================================================";
3544  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3545  }
3546  else
3547  {
3548  for ( size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3549  {
3550  std::stringstream ssHlp;
3551  ssHlp << std::showpos << std::fixed << std::setprecision(2) << " " << threshold << " " << this->recommendedSymmetryType << " " << std::showpos << std::fixed << std::setprecision(0) << " " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) << " " << this->recommendedSymmetryValues.at(symIt)[1] << " " << this->recommendedSymmetryValues.at(symIt)[2] << " " << this->recommendedSymmetryValues.at(symIt)[3] << " " << this->recommendedSymmetryValues.at(symIt)[4] << " " << this->recommendedSymmetryValues.at(symIt)[5] << " " << this->recommendedSymmetryValues.at(symIt)[6];
3552  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3553  }
3554  std::stringstream ssHlp;
3555  ssHlp << "===========================================================================================================";
3556  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3557  }
3558 
3559  //================================================ Done
3560  return ;
3561 }
3562 
3570 {
3571  //================================================ Initialise variables
3572  std::stringstream ssHlp;
3573  std::vector< proshade_double > thrLevels;
3574  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.95 );
3575  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.90 );
3576  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.80 );
3577  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.70 );
3578  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.60 );
3579  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.50 );
3580  ProSHADE_internal_misc::addToDoubleVector ( &thrLevels, 0.40 );
3581 
3582  //================================================ Prepare FSC computation memory and variables
3583  fftw_complex* fCoeffsCut;
3584  proshade_double **bindata, *fscByBin;
3585  proshade_signed *cutIndices, *binCounts, noBins, cutXDim, cutYDim, cutZDim;
3586  this->prepareFSCFourierMemory ( cutIndices, fCoeffsCut, &noBins, bindata, binCounts, fscByBin, settings->requestedResolution, &cutXDim, &cutYDim, &cutZDim );
3587 
3588  //================================================ Print intro to symmetry detection
3589  ssHlp.clear(); ssHlp.str ( "" );
3590  std::vector< proshade_double > comMove = this->getMapCOMProcessChange ( );
3591  ssHlp << std::endl << "Detecting symmetries about point [" << comMove.at(0) << " , " << comMove.at(1) << " , " << comMove.at(2) << "] away from centre of mass .";
3592  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3593 
3594  //================================================ Run default detection in silence
3595  proshade_signed origVerbose = settings->verbose;
3596  settings->verbose = -999;
3597  this->determineRecommendedSymmetry ( settings, settings->fscThreshold, cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3598  settings->verbose = origVerbose;
3599 
3600  //================================================ Print intro to proshade default
3601  ssHlp.clear(); ssHlp.str ( "" );
3602  ssHlp << std::endl << "ProSHADE default symmetry detection algorithm claims the symmetry to be " << this->recommendedSymmetryType << "-" << this->recommendedSymmetryFold << " with axes:" << std::endl << "======================================================================================";
3603  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3604 
3605  if ( this->recommendedSymmetryValues.size() > 0 )
3606  {
3607  ssHlp.clear(); ssHlp.str ( "" );
3608  ssHlp << " Type Fold X Y Z Angle Height Average FSC";
3609  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3610  }
3611  else
3612  {
3613  ssHlp.clear(); ssHlp.str ( "" );
3614  ssHlp << " Type Fold X Y Z Angle Height Average FSC" << std::endl << " C +1 +0.00000 +0.00000 +0.00000 +0.00000 +1.00000 +1.00000";
3615  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3616  }
3617  for ( size_t symIt = 0; symIt < this->recommendedSymmetryValues.size(); symIt++ )
3618  {
3619  ssHlp.clear(); ssHlp.str ( "" );
3620  ssHlp << " " << this->recommendedSymmetryType << " " << std::showpos << std::fixed << std::setprecision(0) << " " << this->recommendedSymmetryValues.at(symIt)[0] << std::setprecision(5) << " " << this->recommendedSymmetryValues.at(symIt)[1] << " " << this->recommendedSymmetryValues.at(symIt)[2] << " " << this->recommendedSymmetryValues.at(symIt)[3] << " " << this->recommendedSymmetryValues.at(symIt)[4] << " " << this->recommendedSymmetryValues.at(symIt)[5] << " " << this->recommendedSymmetryValues.at(symIt)[6];
3621  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3622  }
3623 
3624  //================================================ Print intro to table
3625  ssHlp.clear(); ssHlp.str ( "" );
3626  ssHlp << std::endl << std::endl << "Symmetry detection results per FSC threshold levels:" << std::endl << "====================================================";;
3627  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3628 
3629  ssHlp.clear(); ssHlp.str ( "" );
3630  ssHlp << std::endl << " Threshold Type Fold X Y Z Angle Height Average FSC" << std::endl << "===========================================================================================================";
3631  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3632 
3633  //================================================ For each requested level, get the results
3634  for ( size_t lIt = 0; lIt < thrLevels.size(); lIt++ )
3635  {
3636  this->reportCurrentSymmetryResults ( settings, thrLevels.at(lIt), cutIndices, fCoeffsCut, noBins, bindata, binCounts, fscByBin, cutXDim, cutYDim, cutZDim );
3637  }
3638 
3639  //================================================ Release FSC computation memory
3640  for (size_t binIt = 0; binIt < static_cast< size_t > ( noBins ); binIt++ ) { delete[] bindata[binIt]; }
3641  delete[] bindata;
3642  delete[] binCounts;
3643  delete[] cutIndices;
3644  fftw_free ( fCoeffsCut );
3645 
3646  //================================================ Print all axes
3647  ssHlp.clear(); ssHlp.str ( "" );
3648  ssHlp << std::endl << std::endl << "To facilitate manual checking for symmetries, the following is a list of all detected C symmetries:";
3649  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3650 
3651  if ( this->cyclicSymmetries.size() > 0 )
3652  {
3653  ssHlp.clear(); ssHlp.str ( "" );
3654  ssHlp << " Type Fold X Y Z Angle Height Average FSC";
3655  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3656  }
3657  for ( size_t symIt = 0; symIt < this->cyclicSymmetries.size(); symIt++ )
3658  {
3659  ssHlp.clear(); ssHlp.str ( "" );
3660  ssHlp << " C " << std::showpos << std::fixed << std::setprecision(0) << " " << this->cyclicSymmetries.at(symIt)[0] << std::setprecision(5) << " " << this->cyclicSymmetries.at(symIt)[1] << " " << this->cyclicSymmetries.at(symIt)[2] << " " << this->cyclicSymmetries.at(symIt)[3] << " " << this->cyclicSymmetries.at(symIt)[4] << " " << this->cyclicSymmetries.at(symIt)[5] << " " << this->cyclicSymmetries.at(symIt)[6];
3661  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, ssHlp.str(), settings->messageShift );
3662  }
3663 
3664  //================================================ Done
3665  return ;
3666 }
3667 
3673 {
3674  //================================================ Initialise variables
3675  this->xCom = 0.0;
3676  this->yCom = 0.0;
3677  this->zCom = 0.0;
3678  proshade_double totNonZeroPoints = 0.0;
3679  proshade_signed mapIt = 0;
3680 
3681  //================================================ Compute COM from 0 ; 0 ; 0
3682  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3683  {
3684  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3685  {
3686  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3687  {
3688  //==================================== Find map index
3689  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3690 
3691  //==================================== Use only positive density
3692  if ( this->internalMap[mapIt] <= 0.0 ) { continue; }
3693 
3694  //==================================== Compute Index COM
3695  this->xCom += this->internalMap[mapIt] * static_cast<proshade_double> ( xIt + this->xFrom );
3696  this->yCom += this->internalMap[mapIt] * static_cast<proshade_double> ( yIt + this->yFrom );
3697  this->zCom += this->internalMap[mapIt] * static_cast<proshade_double> ( zIt + this->zFrom );
3698  totNonZeroPoints += this->internalMap[mapIt];
3699  }
3700  }
3701  }
3702 
3703  this->xCom /= totNonZeroPoints;
3704  this->yCom /= totNonZeroPoints;
3705  this->zCom /= totNonZeroPoints;
3706 
3707  //================================================ Convert to real world
3708  this->xCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->xFrom ) * ( this->xDimSizeOriginal / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) +
3709  ( ( static_cast< proshade_single > ( this->xCom ) - static_cast< proshade_single > ( this->xFrom ) ) *
3710  ( static_cast< proshade_single > ( this->xDimSizeOriginal ) / static_cast< proshade_single > ( this->xDimIndicesOriginal ) ) ) );
3711  this->yCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->yFrom ) * ( this->yDimSizeOriginal / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) +
3712  ( ( static_cast< proshade_single > ( this->yCom ) - static_cast< proshade_single > ( this->yFrom ) ) *
3713  ( static_cast< proshade_single > ( this->yDimSizeOriginal ) / static_cast< proshade_single > ( this->yDimIndicesOriginal ) ) ) );
3714  this->zCom = static_cast< proshade_double > ( ( static_cast< proshade_single > ( this->zFrom ) * ( this->zDimSizeOriginal / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) +
3715  ( ( static_cast< proshade_single > ( this->zCom ) - static_cast< proshade_single > ( this->zFrom ) ) *
3716  ( static_cast< proshade_single > ( this->zDimSizeOriginal ) / static_cast< proshade_single > ( this->zDimIndicesOriginal ) ) ) );
3717 
3718  //================================================ Done
3719  return ;
3720 
3721 }
3722 
3728 {
3729  //================================================ Return the value
3730  return ( this->noSpheres );
3731 }
3732 
3738 proshade_double ProSHADE_internal_data::ProSHADE_data::getMapValue ( proshade_unsign pos )
3739 {
3740  //================================================ Return the value
3741  return ( this->internalMap[pos] );
3742 }
3743 
3749 {
3750  //================================================ Return the value
3751  return ( this->maxShellBand );
3752 }
3753 
3758 proshade_double ProSHADE_internal_data::ProSHADE_data::getRRPValue ( proshade_unsign band, proshade_unsign sh1, proshade_unsign sh2 )
3759 {
3760  //================================================ Return the value
3761  return ( this->rrpMatrices[band][sh1][sh2] );
3762 }
3763 
3774 bool ProSHADE_internal_data::ProSHADE_data::shellBandExists ( proshade_unsign shell, proshade_unsign bandVal )
3775 {
3776  if ( this->spheres[shell]->getLocalBandwidth( ) >= bandVal )
3777  {
3778  return ( true );
3779  }
3780  else
3781  {
3782  return ( false );
3783  }
3784 }
3785 
3795 {
3796  //================================================ Report function start
3797  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 1, "Removing phase from the map.", settings->messageShift );
3798 
3799  //================================================ Copy map for processing
3800  fftw_complex* mapCoeffs = reinterpret_cast< fftw_complex* > ( fftw_malloc ( sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
3801  fftw_complex* pattersonMap = reinterpret_cast< fftw_complex* > ( fftw_malloc ( sizeof ( fftw_complex ) * this->xDimIndices * this->yDimIndices * this->zDimIndices ) );
3802 
3803  //================================================ Check memory allocation
3804  ProSHADE_internal_misc::checkMemoryAllocation ( mapCoeffs, __FILE__, __LINE__, __func__ );
3805  ProSHADE_internal_misc::checkMemoryAllocation ( pattersonMap, __FILE__, __LINE__, __func__ );
3806 
3807  //================================================ Copy data to map
3808  for ( proshade_unsign iter = 0; iter < (this->xDimIndices * this->yDimIndices * this->zDimIndices); iter++ )
3809  {
3810  pattersonMap[iter][0] = this->internalMap[iter];
3811  pattersonMap[iter][1] = 0.0;
3812  }
3813 
3814  //================================================ Prepare FFTW plans
3815  fftw_plan forward = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3816  pattersonMap, mapCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
3817  fftw_plan inverse = fftw_plan_dft_3d ( static_cast< int > ( this->xDimIndices ), static_cast< int > ( this->yDimIndices ), static_cast< int > ( this->zDimIndices ),
3818  mapCoeffs, pattersonMap, FFTW_BACKWARD, FFTW_ESTIMATE );
3819 
3820  //================================================ Run forward Fourier
3821  fftw_execute ( forward );
3822 
3823  //================================================ Remove the phase
3824  ProSHADE_internal_mapManip::removeMapPhase ( mapCoeffs, this->xDimIndices, this->yDimIndices, this->zDimIndices );
3825 
3826  //================================================ Run inverse Fourier
3827  fftw_execute ( inverse );
3828 
3829  //================================================ Save the results
3830  proshade_signed mapIt, patIt, patX, patY, patZ;
3831  for ( proshade_signed xIt = 0; xIt < static_cast<proshade_signed> ( this->xDimIndices ); xIt++ )
3832  {
3833  for ( proshade_signed yIt = 0; yIt < static_cast<proshade_signed> ( this->yDimIndices ); yIt++ )
3834  {
3835  for ( proshade_signed zIt = 0; zIt < static_cast<proshade_signed> ( this->zDimIndices ); zIt++ )
3836  {
3837  //==================================== Centre patterson map
3838  patX = xIt - ( static_cast<proshade_signed> ( this->xDimIndices ) / 2 ); if ( patX < 0 ) { patX += this->xDimIndices; }
3839  patY = yIt - ( static_cast<proshade_signed> ( this->yDimIndices ) / 2 ); if ( patY < 0 ) { patY += this->yDimIndices; }
3840  patZ = zIt - ( static_cast<proshade_signed> ( this->zDimIndices ) / 2 ); if ( patZ < 0 ) { patZ += this->zDimIndices; }
3841 
3842  //==================================== Find indices
3843  mapIt = zIt + static_cast< proshade_signed > ( this->zDimIndices ) * ( yIt + static_cast< proshade_signed > ( this->yDimIndices ) * xIt );
3844  patIt = patZ + static_cast< proshade_signed > ( this->zDimIndices ) * ( patY + static_cast< proshade_signed > ( this->yDimIndices ) * patX );
3845 
3846  //==================================== Copy
3847  this->internalMap[mapIt] = pattersonMap[patIt][0];
3848  }
3849  }
3850  }
3851 
3852  //================================================ Release memory
3853  fftw_free ( mapCoeffs );
3854  fftw_free ( pattersonMap );
3855 
3856  //================================================ Delete FFTW plans
3857  fftw_destroy_plan ( forward );
3858  fftw_destroy_plan ( inverse );
3859 
3860  //================================================ Change settings to reflect Patterson map
3861  if ( !settings->usePhase )
3862  {
3863  this->xDimSize *= 2.0f;
3864  this->yDimSize *= 2.0f;
3865  this->zDimSize *= 2.0f;
3866  settings->setResolution ( settings->requestedResolution * 2.0f );
3867  }
3868 
3869  //================================================ Report function completion
3870  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 2, "Phase information removed.", settings->messageShift );
3871 
3872  //================================================ Done
3873  return ;
3874 
3875 }
3876 
3885 proshade_double* ProSHADE_internal_data::ProSHADE_data::getRealSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3886 {
3887  //================================================ Done
3888  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3889  static_cast< int > ( band ),
3890  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][0] );
3891 
3892 }
3893 
3902 proshade_double* ProSHADE_internal_data::ProSHADE_data::getImagSphHarmValue ( proshade_unsign band, proshade_unsign order, proshade_unsign shell )
3903 {
3904  //================================================ Done
3905  return ( &this->sphericalHarmonics[shell][seanindex ( static_cast< int > ( order ) - static_cast< int > ( band ),
3906  static_cast< int > ( band ),
3907  static_cast< int > ( this->spheres[shell]->getLocalBandwidth() ) )][1] );
3908 
3909 }
3910 
3915 proshade_double ProSHADE_internal_data::ProSHADE_data::getAnySphereRadius ( proshade_unsign shell )
3916 {
3917  //================================================ Done
3918  return ( this->spheres[shell]->getShellRadius() );
3919 
3920 }
3921 
3927 {
3928  //================================================ Done
3929  return ( this->integrationWeight );
3930 
3931 }
3932 
3938 proshade_unsign ProSHADE_internal_data::ProSHADE_data::getShellBandwidth ( proshade_unsign shell )
3939 {
3940  //================================================ Done
3941  return ( this->spheres[shell]->getLocalBandwidth ( ) );
3942 
3943 }
3944 
3950 proshade_single ProSHADE_internal_data::ProSHADE_data::getSpherePosValue ( proshade_unsign shell )
3951 {
3952  //================================================ Done
3953  return ( this->spherePos.at(shell) );
3954 
3955 }
3956 
3962 proshade_complex** ProSHADE_internal_data::ProSHADE_data::getEMatrixByBand ( proshade_unsign band )
3963 {
3964  //================================================ Done
3965  return ( this->eMatrices[band] );
3966 
3967 }
3968 
3977 void ProSHADE_internal_data::ProSHADE_data::getEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
3978 {
3979  //================================================ Set pointer
3980  *valueReal = this->eMatrices[band][order1][order2][0];
3981  *valueImag = this->eMatrices[band][order1][order2][1];
3982 
3983  //================================================ Done
3984  return ;
3985 
3986 }
3987 
3993 {
3994  //================================================ Done
3995  return ( this->so3CoeffsInverse );
3996 
3997 }
3998 
4004 {
4005  //================================================ Done
4006  return ( this->so3Coeffs );
4007 
4008 }
4009 
4015 {
4016  //================================================ Done
4017  return ( this->maxEMatDim );
4018 
4019 }
4020 
4029 void ProSHADE_internal_data::ProSHADE_data::getWignerMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double* valueReal, proshade_double* valueImag )
4030 {
4031  //================================================ Set pointer
4032  *valueReal = this->wignerMatrices[band][order1][order2][0];
4033  *valueImag = this->wignerMatrices[band][order1][order2][1];
4034 
4035  //================================================ Done
4036  return ;
4037 
4038 }
4039 
4045 {
4046  //================================================ Return the requested value
4047  return ( this->xDimSize );
4048 }
4049 
4055 {
4056  //================================================ Return the requested value
4057  return ( this->yDimSize );
4058 }
4059 
4065 {
4066  //================================================ Return the requested value
4067  return ( this->zDimSize );
4068 }
4069 
4075 {
4076  //================================================ Return the requested value
4077  return ( this->xDimIndices );
4078 }
4079 
4085 {
4086  //================================================ Return the requested value
4087  return ( this->yDimIndices );
4088 }
4089 
4095 {
4096  //================================================ Return the requested value
4097  return ( this->zDimIndices );
4098 }
4099 
4105 {
4106  //================================================ Return the requested value
4107  return ( &this->xFrom );
4108 }
4109 
4115 {
4116  //================================================ Return the requested value
4117  return ( &this->yFrom );
4118 }
4119 
4125 {
4126  //================================================ Return the requested value
4127  return ( &this->zFrom );
4128 }
4129 
4135 {
4136  //================================================ Return the requested value
4137  return ( &this->xTo );
4138 }
4139 
4145 {
4146  //================================================ Return the requested value
4147  return ( &this->yTo );
4148 }
4149 
4155 {
4156  //================================================ Return the requested value
4157  return ( &this->zTo );
4158 
4159 }
4160 
4166 {
4167  //================================================ Return the requested value
4168  return ( &this->xAxisOrigin );
4169 
4170 }
4171 
4177 {
4178  //================================================ Return the requested value
4179  return ( &this->yAxisOrigin );
4180 
4181 }
4182 
4188 {
4189  //================================================ Return the requested value
4190  return ( &this->zAxisOrigin );
4191 
4192 }
4193 
4199 {
4200  //================================================ Return the requested value
4201  return ( this->internalMap );
4202 
4203 }
4204 
4210 {
4211  //================================================ Return the requested value
4212  return ( this->translationMap );
4213 
4214 }
4215 
4221 {
4222  //================================================ Initialise local variables
4223  std::vector< proshade_double > ret;
4224 
4225  //================================================ Save the values
4226  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeX );
4227  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeY );
4228  ProSHADE_internal_misc::addToDoubleVector ( &ret, this->mapCOMProcessChangeZ );
4229 
4230  //================================================ Return the requested value
4231  return ( ret );
4232 
4233 }
4234 
4239 std::vector< proshade_double* >* ProSHADE_internal_data::ProSHADE_data::getCyclicAxes ( void )
4240 {
4241  //================================================ Return the requested value
4242  return ( &this->cyclicSymmetries );
4243 
4244 }
4245 
4246 
4251 std::vector< proshade_double* > ProSHADE_internal_data::ProSHADE_data::getCyclicAxesCopy ( void )
4252 {
4253  //================================================ Initialise variables
4254  std::vector< proshade_double* > ret;
4255 
4256  //================================================ Copy values
4257  for ( size_t aIt = 0; aIt < this->cyclicSymmetries.size(); aIt++ )
4258  {
4259  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ret, &this->cyclicSymmetries.at( aIt )[0] );
4260  }
4261 
4262  //================================================ Return the requested value
4263  return ( ret );
4264 
4265 }
4266 
4271 std::vector< std::vector< proshade_double* > >* ProSHADE_internal_data::ProSHADE_data::getDihedralAxes ( void )
4272 {
4273  //================================================ Return the requested value
4274  return ( &this->dihedralSymmetries );
4275 
4276 }
4277 
4282 std::vector< std::vector< proshade_double* > > ProSHADE_internal_data::ProSHADE_data::getDihedralAxesCopy ( void )
4283 {
4284  //================================================ Initialise variables
4285  std::vector< std::vector< proshade_double* > > ret;
4286 
4287  //================================================ Copy values
4288  for ( size_t aIt = 0; aIt < this->dihedralSymmetries.size(); aIt++ )
4289  {
4290  std::vector< proshade_double* > hlpVec;
4291  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &hlpVec, &this->dihedralSymmetries.at( aIt ).at(0)[0] );
4292  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &hlpVec, &this->dihedralSymmetries.at( aIt ).at(1)[0] );
4294  }
4295 
4296  //================================================ Return the requested value
4297  return ( ret );
4298 
4299 }
4300 
4306 {
4307  //================================================ Mutate
4308  this->integrationWeight = intW;
4309 
4310  //================================================ Done
4311  return ;
4312 
4313 }
4314 
4320 {
4321  //================================================ Mutate
4322  this->integrationWeight += intW;
4323 
4324  //================================================ Done
4325  return ;
4326 
4327 }
4328 
4336 void ProSHADE_internal_data::ProSHADE_data::setEMatrixValue ( int band, int order1, int order2, proshade_complex val )
4337 {
4338  //================================================ Mutate
4339  this->eMatrices[band][order1][order2][0] = val[0];
4340  this->eMatrices[band][order1][order2][1] = val[1];
4341 
4342  //================================================ Done
4343  return ;
4344 
4345 }
4346 
4354 void ProSHADE_internal_data::ProSHADE_data::normaliseEMatrixValue ( proshade_unsign band, proshade_unsign order1, proshade_unsign order2, proshade_double normF )
4355 {
4356  //================================================ Mutate
4357  this->eMatrices[band][order1][order2][0] /= normF;
4358  this->eMatrices[band][order1][order2][1] /= normF;
4359 
4360  //================================================ Done
4361  return ;
4362 
4363 }
4364 
4370 void ProSHADE_internal_data::ProSHADE_data::setSO3CoeffValue ( proshade_unsign position, proshade_complex val )
4371 {
4372  //================================================ Mutate
4373  this->so3Coeffs[position][0] = val[0];
4374  this->so3Coeffs[position][1] = val[1];
4375 
4376  //================================================ Done
4377  return ;
4378 
4379 }
4380 
4388 void ProSHADE_internal_data::ProSHADE_data::setWignerMatrixValue ( proshade_complex val, proshade_unsign band, proshade_unsign order1, proshade_unsign order2 )
4389 {
4390  //================================================ Mutate
4391  this->wignerMatrices[band][order1][order2][0] = val[0];
4392  this->wignerMatrices[band][order1][order2][1] = val[1];
4393 
4394  //================================================ Done
4395  return ;
4396 
4397 }
4398 
4406 void ProSHADE_internal_data::ProSHADE_data::getRealEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMReal, int len )
4407 {
4408  //================================================ Save the data into the output array
4409  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4410  {
4411  eMatsLMReal[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][0] );
4412  }
4413 
4414  //================================================ Done
4415  return ;
4416 
4417 }
4418 
4426 void ProSHADE_internal_data::ProSHADE_data::getImagEMatrixValuesForLM ( proshade_signed band, proshade_signed order1, double *eMatsLMImag, int len )
4427 {
4428  //================================================ Save the data into the output array
4429  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4430  {
4431  eMatsLMImag[iter] = static_cast<double> ( this->eMatrices[band][order1][iter][1] );
4432  }
4433 
4434  //================================================ Done
4435  return ;
4436 
4437 }
4438 
4444 void ProSHADE_internal_data::ProSHADE_data::getRealSO3Coeffs ( double *so3CoefsReal, int len )
4445 {
4446  //================================================ Save the data into the output array
4447  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4448  {
4449  so3CoefsReal[iter] = static_cast<double> ( this->so3Coeffs[iter][0] );
4450  }
4451 
4452  //================================================ Done
4453  return ;
4454 
4455 }
4456 
4462 void ProSHADE_internal_data::ProSHADE_data::getImagSO3Coeffs ( double *so3CoefsImag, int len )
4463 {
4464  //================================================ Save the data into the output array
4465  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4466  {
4467  so3CoefsImag[iter] = static_cast<double> ( this->so3Coeffs[iter][1] );
4468  }
4469 
4470  //================================================ Done
4471  return ;
4472 
4473 }
4474 
4484 int ProSHADE_internal_data::ProSHADE_data::so3CoeffsArrayIndex ( proshade_signed order1, proshade_signed order2, proshade_signed band )
4485 {
4486  //================================================ Return the value
4487  return ( static_cast<int> ( so3CoefLoc ( static_cast< int > ( order1 ), static_cast< int > ( order2 ), static_cast< int > ( band ), static_cast< int > ( this->getEMatDim() ) ) ) );
4488 }
4489 
4496 {
4497  //================================================ Save the data into the output array
4498  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4499  {
4500  rotFunReal[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][0] );
4501  }
4502 
4503  //================================================ Done
4504  return ;
4505 
4506 }
4507 
4514 {
4515  //================================================ Save the data into the output array
4516  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4517  {
4518  rotFunImag[iter] = static_cast<double> ( this->so3CoeffsInverse[iter][1] );
4519  }
4520 
4521  //================================================ Done
4522  return ;
4523 
4524 }
4525 
4532 {
4533  //================================================ Save the data into the output array
4534  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4535  {
4536  trsFunReal[iter] = static_cast<double> ( this->translationMap[iter][0] );
4537  }
4538 
4539  //================================================ Done
4540  return ;
4541 
4542 }
4543 
4550 {
4551  //================================================ Save the data into the output array
4552  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4553  {
4554  trsFunImag[iter] = static_cast<double> ( this->translationMap[iter][1] );
4555  }
4556 
4557  //================================================ Done
4558  return ;
4559 
4560 }
4561 
4570 void ProSHADE_internal_data::ProSHADE_data::getRotMatrixFromRotFunInds ( proshade_signed aI, proshade_signed bI, proshade_signed gI, double *rotMat, int len )
4571 {
4572  //================================================ Get Euler angles
4573  proshade_double eA, eB, eG;
4574  ProSHADE_internal_maths::getEulerZYZFromSOFTPosition ( static_cast< int > ( this->getMaxBand() ), aI, bI, gI, &eA, &eB, &eG );
4575 
4576  //================================================ Prepare internal rotation matrix memory
4577  proshade_double* rMat = nullptr;
4578  rMat = new proshade_double[9];
4579  ProSHADE_internal_misc::checkMemoryAllocation ( rMat, __FILE__, __LINE__, __func__ );
4580 
4581  //================================================ Convert to rotation matrix
4583 
4584  //================================================ Copy to output
4585  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( len ); iter++ )
4586  {
4587  rotMat[iter] = static_cast<double> ( rMat[iter] );
4588  }
4589 
4590  //================================================ Release internal memory
4591  delete[] rMat;
4592 
4593  //================================================ Done
4594  return ;
4595 
4596 }
4597 
4601 {
4602  //================================================ Return the value
4603  return ( this->recommendedSymmetryType );
4604 
4605 }
4606 
4610 {
4611  //================================================ Return the value
4612  return ( this->recommendedSymmetryFold );
4613 
4614 }
4615 
4619 {
4620  //================================================ Initialise variables
4621  std::vector< proshade_double* > ret;
4622 
4623  //================================================ Copy results
4624  for ( size_t aIt = 0; aIt < this->recommendedSymmetryValues.size(); aIt++ )
4625  {
4626  ProSHADE_internal_misc::deepCopyAxisToDblPtrVector ( &ret, &this->recommendedSymmetryValues.at( aIt )[0] );
4627  }
4628 
4629  //================================================ Return the value
4630  return ( ret );
4631 
4632 }
4633 
4639 {
4640  //================================================ Return the value
4641  return ( static_cast< proshade_unsign > ( this->recommendedSymmetryValues.size() ) );
4642 }
4643 
4650 std::vector< std::string > ProSHADE_internal_data::ProSHADE_data::getSymmetryAxis ( ProSHADE_settings* settings, proshade_unsign axisNo )
4651 {
4652  //================================================ Sanity checks
4653  if ( static_cast<proshade_unsign> ( this->recommendedSymmetryValues.size() ) <= axisNo )
4654  {
4655  ProSHADE_internal_messages::printWarningMessage ( settings->verbose, "!!! ProSHADE WARNING !!! Requested symmetry index does not exist. Returning empty vector.", "WS00039" );
4656  return ( std::vector< std::string > ( ) );
4657  }
4658 
4659  //================================================ Initialise local variables
4660  std::vector< std::string > ret;
4661 
4662  //================================================ Input the axis data as strings
4663  std::stringstream ssHlp;
4664  ssHlp << this->recommendedSymmetryValues.at(axisNo)[0];
4665  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4666  ssHlp.str ( "" );
4667 
4668  ssHlp << this->recommendedSymmetryValues.at(axisNo)[1];
4669  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4670  ssHlp.str ( "" );
4671 
4672  ssHlp << this->recommendedSymmetryValues.at(axisNo)[2];
4673  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4674  ssHlp.str ( "" );
4675 
4676  ssHlp << this->recommendedSymmetryValues.at(axisNo)[3];
4677  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4678  ssHlp.str ( "" );
4679 
4680  ssHlp << this->recommendedSymmetryValues.at(axisNo)[4];
4681  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4682  ssHlp.str ( "" );
4683 
4684  ssHlp << this->recommendedSymmetryValues.at(axisNo)[5];
4685  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4686  ssHlp.str ( "" );
4687 
4688  ssHlp << this->recommendedSymmetryValues.at(axisNo)[6];
4689  ProSHADE_internal_misc::addToStringVector ( &ret, ssHlp.str() );
4690  ssHlp.str ( "" );
4691 
4692  //================================================ Done
4693  return ( ret );
4694 
4695 }
4696 
4709 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 )
4710 {
4711  //================================================ Write out rotated map
4712  std::stringstream fNameHlp;
4713  fNameHlp << settings->overlayStructureName << ".map";
4714  this->writeMap ( fNameHlp.str() );
4715 
4716  //================================================ Write out rotated co-ordinates if possible
4717  if ( ProSHADE_internal_io::isFilePDB ( this->fileName ) )
4718  {
4719  fNameHlp.str("");
4720  fNameHlp << settings->overlayStructureName << ".pdb";
4721  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 );
4722  }
4723 
4724  //================================================ Write out the json file with the results
4725  ProSHADE_internal_io::writeRotationTranslationJSON ( rotCentre->at(0), rotCentre->at(1), rotCentre->at(2),
4726  eulA, eulB, eulG,
4727  ultimateTranslation->at(0), ultimateTranslation->at(1), ultimateTranslation->at(2),
4728  settings->rotTrsJSONFile );
4729 
4730  //================================================ Done
4731  return ;
4732 
4733 }
4734 
4743 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 )
4744 {
4745  //================================================ Empty line
4747 
4748  //================================================ Write out rotation centre translation results
4749  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);
4750  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotCen.str(), settings->messageShift );
4751 
4752  //================================================ Write out rotation matrix about origin
4753  proshade_double* rotMat = new proshade_double[9];
4754  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
4755  ProSHADE_internal_maths::getRotationMatrixFromEulerZYZAngles ( eulerAngles->at(0), eulerAngles->at(1), eulerAngles->at(2), rotMat );
4756 
4757  std::stringstream rotMatSS;
4758  rotMatSS << std::setprecision (3) << std::showpos << "The rotation matrix about origin is : " << rotMat[0] << " " << rotMat[1] << " " << rotMat[2] << std::endl;
4759  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[3] << " " << rotMat[4] << " " << rotMat[5] << std::endl;
4760  rotMatSS << std::setprecision (3) << std::showpos << " : " << rotMat[6] << " " << rotMat[7] << " " << rotMat[8];
4761  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, rotMatSS.str(), settings->messageShift );
4762 
4763  delete[] rotMat;
4764 
4765  //================================================ Write out origin to overlay translation results
4766  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);
4767  ProSHADE_internal_messages::printProgressMessage ( settings->verbose, 0, finTrs.str(), settings->messageShift );
4768 
4769  //================================================ Done
4770  return ;
4771 
4772 }
ProSHADE_internal_misc::addToDblPtrVectorVector
void addToDblPtrVectorVector(std::vector< std::vector< proshade_double * > > *vecToAddTo, std::vector< proshade_double * > elementToAdd)
Adds the element to the vector of vectors of double pointers.
Definition: ProSHADE_misc.cpp:255
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:59
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:1193
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:1895
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_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:3962
ProSHADE_internal_data::ProSHADE_data::getCyclicAxesCopy
std::vector< proshade_double * > getCyclicAxesCopy(void)
This function allows access to the list of detected cyclic axes in non-overwrite fashion.
Definition: ProSHADE_data.cpp:4251
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:149
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:4064
ProSHADE_internal_maths::getEulerZYZFromSOFTPosition
void getEulerZYZFromSOFTPosition(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 (ZYZ convention) from index position in the inverse SOFT map.
Definition: ProSHADE_maths.cpp:966
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:458
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:635
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_misc::addToDblPtrVector
void addToDblPtrVector(std::vector< proshade_double * > *vecToAddTo, proshade_double *elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:143
ProSHADE_internal_data::ProSHADE_data::determineRecommendedSymmetry
void determineRecommendedSymmetry(ProSHADE_settings *settings, proshade_double threshold, proshade_signed *&cutIndices, fftw_complex *&fCoeffsCut, proshade_signed noBins, proshade_double **&bindata, proshade_signed *&binCounts, proshade_double *&fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim)
This function takes all the detected symmetry results and decides on which are to be recommended for ...
Definition: ProSHADE_data.cpp:2502
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:1410
ProSHADE_internal_io::isFilePDB
bool isFilePDB(std::string fName)
Function determining if the input data type is PDB.
Definition: ProSHADE_io.cpp:38
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:3064
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::getRecommendedSymmetryValues
std::vector< proshade_double * > getRecommendedSymmetryValues(void)
This function simply returns the detected recommended symmetry axes.
Definition: ProSHADE_data.cpp:4618
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:1352
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:1817
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:4305
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::getDihedralAxes
std::vector< std::vector< proshade_double * > > * getDihedralAxes(void)
This function allows access to the list of detected dihedral axes.
Definition: ProSHADE_data.cpp:4271
ProSHADE_internal_maths::computeFSC
proshade_double computeFSC(fftw_complex *fCoeffs1, fftw_complex *fCoeffs2, proshade_signed xInds, proshade_signed yInds, proshade_signed zInds, proshade_signed noBins, proshade_signed *binIndexing, proshade_double **&binData, proshade_signed *&binCounts, proshade_double *&fscByBin, bool averageByBinSize=false)
This function computes the FSC.
Definition: ProSHADE_maths.cpp:3693
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:131
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:4165
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:1511
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:4354
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:97
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:4549
ProSHADE_internal_symmetry::findPredictedAxesHeights
void findPredictedAxesHeights(std::vector< proshade_double * > *ret, ProSHADE_internal_data::ProSHADE_data *dataObj, ProSHADE_settings *settings)
This function finds the rotation function value for all axes supplied in the ret parameter.
Definition: ProSHADE_symmetry.cpp:3063
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:4388
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:81
ProSHADE_settings::maskMap
bool maskMap
Should the map be masked from noise?
Definition: ProSHADE_settings.hpp:83
ProSHADE_settings::requestedSymmetryFold
proshade_unsign requestedSymmetryFold
The fold of the requested symmetry (only applicable to C and D symmetry types).
Definition: ProSHADE_settings.hpp:136
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:135
ProSHADE_internal_maths::getRotationMatrixFromEulerZYZAngles
void getRotationMatrixFromEulerZYZAngles(proshade_double eulerAlpha, proshade_double eulerBeta, proshade_double eulerGamma, proshade_double *matrix)
Function to find the rotation matrix from Euler angles (ZYZ convention).
Definition: ProSHADE_maths.cpp:1019
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:3977
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:4044
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:4198
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:4054
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:1086
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:130
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:3727
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:4370
ProSHADE_settings::saveMask
bool saveMask
Should the mask be saved?
Definition: ProSHADE_settings.hpp:87
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::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:986
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:4570
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:825
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:3915
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:111
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:587
ProSHADE_internal_data::ProSHADE_data::getSO3Coeffs
proshade_complex * getSO3Coeffs(void)
This function allows access to the SO(3) coefficients array.
Definition: ProSHADE_data.cpp:4003
ProSHADE_internal_data::ProSHADE_data::saveRequestedSymmetryD
void saveRequestedSymmetryD(ProSHADE_settings *settings, proshade_signed *&cutIndices, fftw_complex *&fCoeffsCut, proshade_signed noBins, proshade_double **&bindata, proshade_signed *&binCounts, proshade_double *&fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim)
This function takes the D symmetries and searched for the requested symmetry.
Definition: ProSHADE_data.cpp:2853
ProSHADE_settings::maxSphereDists
proshade_single maxSphereDists
The distance between spheres in spherical mapping for the largest sphere.
Definition: ProSHADE_settings.hpp:67
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:1790
ProSHADE_internal_data::ProSHADE_data::invertMirrorMap
void invertMirrorMap(ProSHADE_settings *settings)
Function for inverting the map to its mirror image.
Definition: ProSHADE_data.cpp:1211
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:3023
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:4220
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:82
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:64
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_internal_data::ProSHADE_data::getRecommendedSymmetryFold
proshade_unsign getRecommendedSymmetryFold(void)
This function simply returns the detected recommended symmetry fold.
Definition: ProSHADE_data.cpp:4609
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:3926
ProSHADE_internal_io::figureDataType
InputType figureDataType(std::string fName)
Function determining input data type.
Definition: ProSHADE_io.cpp:945
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:4319
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:1229
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_data::ProSHADE_data::getDihedralAxesCopy
std::vector< std::vector< proshade_double * > > getDihedralAxesCopy(void)
This function allows access to the list of detected dihedral axes in a non-over-write fashion.
Definition: ProSHADE_data.cpp:4282
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:4650
ProSHADE_settings::maskFileName
std::string maskFileName
The filename to which mask should be saved.
Definition: ProSHADE_settings.hpp:88
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:128
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:1556
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:4104
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:152
ProSHADE_internal_data::ProSHADE_data::getAllGroupElements
std::vector< std::vector< proshade_double > > getAllGroupElements(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:3122
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:3431
ProSHADE_settings::messageShift
proshade_signed messageShift
This value allows shifting the messages to create more readable log for sub-processes.
Definition: ProSHADE_settings.hpp:153
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:4029
ProSHADE_internal_mapManip::changeFourierOrder
void changeFourierOrder(fftw_complex *&fCoeffs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, bool negativeFirst)
This function changes the order of Fourier coefficients in a 3D array between positive first (default...
Definition: ProSHADE_mapManip.cpp:1618
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:759
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:3938
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::getRecommendedSymmetryType
std::string getRecommendedSymmetryType(void)
This function simply returns the detected recommended symmetry type.
Definition: ProSHADE_data.cpp:4600
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:1164
ProSHADE_internal_data::ProSHADE_data::setPDBMapValues
void setPDBMapValues(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:848
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:3672
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:4495
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:4074
ProSHADE_internal_mapManip::removeWaters
void removeWaters(gemmi::Structure *pdbFile, bool firstModel)
This function removed all waters from PDB input file.
Definition: ProSHADE_mapManip.cpp:518
ProSHADE_internal_data::ProSHADE_data::getCyclicAxes
std::vector< proshade_double * > * getCyclicAxes(void)
This function allows access to the list of detected cyclic axes.
Definition: ProSHADE_data.cpp:4239
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_maths::cutIndicesToResolution
void cutIndicesToResolution(proshade_signed xInds, proshade_signed yInds, proshade_signed zInds, proshade_single resolution, proshade_signed *binIndexing, std::vector< proshade_single > *resArray, proshade_signed *cutXDim, proshade_signed *cutYDim, proshade_signed *cutZDim, proshade_signed *&cutBinIndices, proshade_signed *&noBins)
This function cuts the bin assignment array into a smaller array containing all bins up to a given re...
Definition: ProSHADE_maths.cpp:3563
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::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:525
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:1062
ProSHADE_internal_data::ProSHADE_data::integrationWeight
proshade_double integrationWeight
The Pearson's c.c. type weighting for the integration.
Definition: ProSHADE_data.hpp:129
ProSHADE_settings::peakThresholdMin
proshade_double peakThresholdMin
The threshold for peak height above which axes are considered possible.
Definition: ProSHADE_settings.hpp:141
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:1851
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:127
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_settings::calcBounds
std::vector< proshade_double > calcBounds
The boundaries to be used for deciding the calculation thresholds (band, integration order,...
Definition: ProSHADE_settings.hpp:90
ProSHADE_internal_data::ProSHADE_data::prepareFSCFourierMemory
void prepareFSCFourierMemory(proshade_signed *&cutIndices, fftw_complex *&fCoeffsCut, proshade_signed *noBins, proshade_double **&bindata, proshade_signed *&binCounts, proshade_double *&fscByBin, proshade_single resolution, proshade_signed *cutXDim, proshade_signed *cutYDim, proshade_signed *cutZDim)
This function allocates the memory and makes all preparations required for FSC computation.
Definition: ProSHADE_data.cpp:2202
ProSHADE_internal_data::ProSHADE_data::mapMovFromsChangeY
proshade_double mapMovFromsChangeY
When the map is translated, the yFrom and yTo values are changed. This variable holds how much they h...
Definition: ProSHADE_data.hpp:95
ProSHADE_internal_data::ProSHADE_data::yAxisOrigin
proshade_signed yAxisOrigin
This is the origin position along the y axis.
Definition: ProSHADE_data.hpp:75
ProSHADE_internal_misc::deepCopyAxisToDblPtrVector
void deepCopyAxisToDblPtrVector(std::vector< proshade_double * > *dblPtrVec, proshade_double *axis)
Does a deep copy of a double array to a vector of double arrays.
Definition: ProSHADE_misc.cpp:433
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:3885
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:983
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:4743
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_data::ProSHADE_data::computeFSC
proshade_double computeFSC(ProSHADE_settings *settings, std::vector< proshade_double * > *CSym, size_t symIndex, proshade_signed *&cutIndices, fftw_complex *&fCoeffsCut, proshade_signed noBins, proshade_double **&bindata, proshade_signed *&binCounts, proshade_double *&fscByBin, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_unsign rotNumber=1)
This function computes FSC for any given axis in the supplied CSym symmetry axes vector.
Definition: ProSHADE_data.cpp:2312
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:1458
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:916
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:3774
ProSHADE_internal_data::ProSHADE_data::getMaxBand
proshade_unsign getMaxBand(void)
This function returns the maximum band value for the object.
Definition: ProSHADE_data.cpp:3748
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:1099
ProSHADE_settings::appliedMaskFileName
std::string appliedMaskFileName
The filename from which mask data will be read from.
Definition: ProSHADE_settings.hpp:89
ProSHADE_settings::resolutionOversampling
proshade_single resolutionOversampling
How much (%) should the requested resolution be over-sampled by map re-sampling?
Definition: ProSHADE_settings.hpp:53
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:108
ProSHADE_settings::normaliseMap
bool normaliseMap
Should the map be normalised to mean 0 sd 1?
Definition: ProSHADE_settings.hpp:75
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:1020
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:107
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:4084
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:4426
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:1312
ProSHADE_internal_data::ProSHADE_data::~ProSHADE_data
~ProSHADE_data(void)
Destructor for the ProSHADE_data class.
Definition: ProSHADE_data.cpp:354
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:1136
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:4531
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:140
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:3902
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:4709
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:4513
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:1739
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:184
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:4209
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, bool removeNegDens)
This function finds the Centre of Mass for a map.
Definition: ProSHADE_mapManip.cpp:243
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:78
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:4094
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:145
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:1691
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:98
ProSHADE_internal_data::ProSHADE_data::getSpherePosValue
proshade_single getSpherePosValue(proshade_unsign shell)
This function allows access to sphere positions.
Definition: ProSHADE_data.cpp:3950
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:3758
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:987
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:2975
ProSHADE_internal_data::ProSHADE_data::recommendedSymmetryFold
proshade_unsign recommendedSymmetryFold
The fold of the recommended symmetry C or D type, 0 otherwise.
Definition: ProSHADE_data.hpp:151
ProSHADE_settings::overlayStructureName
std::string overlayStructureName
The filename to which the rotated and translated moving structure is to be saved.
Definition: ProSHADE_settings.hpp:148
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:3738
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:4462
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:4144
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:103
ProSHADE_settings::maxRadius
proshade_double maxRadius
The maximum distance from centre in Angstroms for a map value to still be used.
Definition: ProSHADE_settings.hpp:61
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:132
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:4187
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:895
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_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::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:1976
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:1476
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:104
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:310
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:658
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:2576
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:73
ProSHADE_internal_data::ProSHADE_data::maxEMatDim
proshade_unsign maxEMatDim
The band (l) value for E matrix (i.e. the smallest of the two bands).
Definition: ProSHADE_data.hpp:124
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:4134
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:4114
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:395
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_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 prints the report for symmetry detection.
Definition: ProSHADE_data.cpp:3463
ProSHADE_internal_data::ProSHADE_data::figureIndexStartStop
void figureIndexStartStop(void)
Function for determining iterator start and stop positions.
Definition: ProSHADE_data.cpp:894
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::reportCurrentSymmetryResults
void reportCurrentSymmetryResults(ProSHADE_settings *settings, proshade_double threshold, proshade_signed *&cutIndices, fftw_complex *&fCoeffsCut, proshade_signed noBins, proshade_double **&bindata, proshade_signed *&binCounts, proshade_double *&fscByBin, proshade_signed cutXDim, proshade_signed cutYDim, proshade_signed cutZDim)
This function prints a single line of the symmetry detection results for a particular threshold.
Definition: ProSHADE_data.cpp:3531
ProSHADE_internal_data::ProSHADE_data::setEMatrixValue
void setEMatrixValue(int band, int order1, int order2, proshade_complex val)
This function allows setting the E matrix value.
Definition: ProSHADE_data.cpp:4336
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:3992
ProSHADE_internal_data::ProSHADE_data::getEMatDim
proshade_unsign getEMatDim(void)
This function allows access to the maximum band for the E matrix.
Definition: ProSHADE_data.cpp:4014
ProSHADE_settings::forceBounds
proshade_signed * forceBounds
These will be the boundaries to be forced upon the map.
Definition: ProSHADE_settings.hpp:100
ProSHADE_settings::fourierWeightsFileName
std::string fourierWeightsFileName
The filename from which Fourier weights data will be read from.
Definition: ProSHADE_settings.hpp:93
ProSHADE_internal_data::ProSHADE_data::recommendedSymmetryType
std::string recommendedSymmetryType
The symmetry type that ProSHADE finds the best fitting for the structure. Possible values are "" for ...
Definition: ProSHADE_data.hpp:150
ProSHADE_internal_data::ProSHADE_data::yFrom
proshade_signed yFrom
This is the starting index along the y axis.
Definition: ProSHADE_data.hpp:111
ProSHADE_internal_maths::cutArrayToResolution
void cutArrayToResolution(proshade_signed xInds, proshade_signed yInds, proshade_signed zInds, proshade_signed noBins, fftw_complex *inputMap, fftw_complex *&cutMap)
This function re-sizes data array to contain only values up to a particular resolution bin.
Definition: ProSHADE_maths.cpp:3628
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:1439
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:2142
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:4176
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:94
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:1936
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, std::vector< proshade_double > *calcBounds, 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:302
ProSHADE_internal_data::ProSHADE_data::getNoRecommendedSymmetryAxes
proshade_unsign getNoRecommendedSymmetryAxes(void)
This function returns the number of detected recommended symmetry axes.
Definition: ProSHADE_data.cpp:4638
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:132
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:99
ProSHADE_internal_data::ProSHADE_data::reportSymmetryResultsList
void reportSymmetryResultsList(ProSHADE_settings *settings)
This function takes prints the report for symmetry detection using multiple thresholds....
Definition: ProSHADE_data.cpp:3569
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:2911
ProSHADE_settings::pdbBFactorNewVal
proshade_double pdbBFactorNewVal
Change all PDB B-factors to this value (for smooth maps).
Definition: ProSHADE_settings.hpp:56
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_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:588
ProSHADE_settings::setVariablesLeftOnAuto
void setVariablesLeftOnAuto(void)
Function to determine general values that the user left on auto-determination.
Definition: ProSHADE.cpp:506
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=1.0)
This function finds a subgroup of axes with distinctly higher correlation value.
Definition: ProSHADE_maths.cpp:4113
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:1265
ProSHADE_internal_data::ProSHADE_data::detectSymmetryFromAngleAxisSpace
void detectSymmetryFromAngleAxisSpace(ProSHADE_settings *settings)
This function runs the symmetry detection algorithms on this structure using the angle-axis space and...
Definition: ProSHADE_data.cpp:1954
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:4444
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:552
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:3794
ProSHADE_internal_maths::binReciprocalSpaceReflections
void binReciprocalSpaceReflections(proshade_unsign xInds, proshade_unsign yInds, proshade_unsign zInds, proshade_single xSize, proshade_single ySize, proshade_single zSize, proshade_signed *noBin, proshade_signed *&binIndexing, std::vector< proshade_single > *&resArray)
This function does binning of the reciprocal space reflections.
Definition: ProSHADE_maths.cpp:3397
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:777
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:115
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:2523
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:1629
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:4406
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:403
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:2997
ProSHADE_internal_data::ProSHADE_data::readInPDB
void readInPDB(ProSHADE_settings *settings)
Function for reading pdb data.
Definition: ProSHADE_data.cpp:724
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:4124
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:4154
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:4484