ProSHADE  0.6.5 (NOV 2018)
Protein Shape Descriptors and Symmetry Detection
ProSHADE_internal.cpp
1 
20 //============================================ Clipper
21 #include <clipper/clipper.h>
22 #include <clipper/clipper-contrib.h>
23 #include <clipper/clipper-ccp4.h>
24 #include <clipper/clipper-mmdb.h>
25 #include <clipper/clipper-minimol.h>
26 
27 //============================================ FFTW3 + SOFT
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 #include <fftw3.h>
32 #include <wrap_fftw.h>
33 #include <makeweights.h>
34 #include <s2_primitive.h>
35 #include <s2_cospmls.h>
36 #include <s2_legendreTransforms.h>
37 #include <s2_semi_fly.h>
38 #include <rotate_so3_utils.h>
39 #include <utils_so3.h>
40 #include <soft_fftw.h>
41 #include <rotate_so3_fftw.h>
42 #ifdef __cplusplus
43 }
44 #endif
45 
46 //============================================ CMAPLIB
47 #include "cmaplib.h"
48 
49 //============================================ ProSHADE
50 #include "ProSHADE.h"
51 #include "ProSHADE_internal.h"
52 #include "ProSHADE_files.h"
53 #include "ProSHADE_misc.h"
54 #include "ProSHADE_legendre.h"
55 
56 //============================================ RVAPI
57 #include <rvapi_interface.h>
58 
59 
70 unsigned int ProSHADE_internal::checkFileType ( std::string fileName )
71 {
72  //======================================== Try readin as PDB
73  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
74  if ( mfile->ReadCoorFile ( fileName.c_str() ) )
75  {
76  //==================================== Not PDB, try MAP
77  clipper::CCP4MAPfile mapFile;
78 
79  try
80  {
81  mapFile.open_read( fileName );
82  }
83  catch (const clipper::Message_base &exc)
84  {
85  //================================ Not MAP either...
86  delete mfile;
87  return ( 0 );
88  }
89 
90  //==================================== This is a MAP file, report so
91  delete mfile;
92  return ( 2 );
93  }
94  else
95  {
96  //==================================== This is a PDB file, report so
97  delete mfile;
98  return ( 1 );
99  }
100 }
101 
112 {
113  //======================================== Initialise pointers
114  this->_densityMapMap = nullptr;
115  this->_densityMapCor = nullptr;
116  this->_densityMapCorCoords = nullptr;
117  this->_realSHCoeffs = nullptr;
118  this->_imagSHCoeffs = nullptr;
119  this->_sphericalHarmonicsWeights = nullptr;
120  this->_semiNaiveTable = nullptr;
121  this->_semiNaiveTableSpace = nullptr;
122  this->_shWorkspace = nullptr;
123  this->_rrpMatrices = nullptr;
124  this->_invRealData = nullptr;
125  this->_invImagData = nullptr;
126  this->_shellMappedData = nullptr;
127 
128  //======================================== Initialise checks
129  this->_densityMapComputed = false;
130  this->_phaseRemoved = false;
131  this->_firstLineCOM = false;
132  this->_sphereMapped = false;
133  this->_sphericalCoefficientsComputed = false;
134  this->_rrpMatricesPrecomputed = false;
135  this->_wasBandwithGiven = true;
136  this->_wasThetaGiven = true;
137  this->_wasPhiGiven = true;
138  this->_wasGlInterGiven = true;
139 
140  //======================================== Initialise COM
141  this->_xCorrection = 0;
142  this->_yCorrection = 0;
143  this->_zCorrection = 0;
144 
145  //======================================== Initialise map valus (to infinity)
146  this->_xFrom = std::numeric_limits<float>::infinity();
147  this->_yFrom = std::numeric_limits<float>::infinity();
148  this->_zFrom = std::numeric_limits<float>::infinity();
149  this->_xTo = std::numeric_limits<float>::infinity();
150  this->_yTo = std::numeric_limits<float>::infinity();
151  this->_zTo = std::numeric_limits<float>::infinity();
152  this->_xRange = std::numeric_limits<float>::infinity();
153  this->_yRange = std::numeric_limits<float>::infinity();
154  this->_zRange = std::numeric_limits<float>::infinity();
155 
156  //======================================== Initialise map normalisation
157  this->_mapMean = 0.0;
158  this->_mapSdev = 1.0;
159  this->_noShellsWithData = 0;
160 
161  //======================================== Done
162 
163 }
164 
175 {
176  //======================================== Variables regarding the reading in of the data
177  this->_inputFileName = copyFrom->_inputFileName;
178  this->_fromPDB = copyFrom->_fromPDB;
179 
180  //==================================== Variables regarding the shells
181  this->_shellSpacing = copyFrom->_shellSpacing;
182  this->_maxExtraCellularSpace = copyFrom->_maxExtraCellularSpace;
183  this->_xRange = copyFrom->_xRange;
184  this->_yRange = copyFrom->_yRange;
185  this->_zRange = copyFrom->_zRange;
186  this->_xSamplingRate = copyFrom->_xSamplingRate;
187  this->_ySamplingRate = copyFrom->_ySamplingRate;
188  this->_zSamplingRate = copyFrom->_zSamplingRate;
189  this->_xFrom = copyFrom->_xFrom;
190  this->_yFrom = copyFrom->_yFrom;
191  this->_zFrom = copyFrom->_zFrom;
192  this->_xTo = copyFrom->_xTo;
193  this->_yTo = copyFrom->_yTo;
194  this->_zTo = copyFrom->_zTo;
195  this->_shellPlacement = std::vector<double> ( copyFrom->_shellPlacement.size() );
196 
197  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( copyFrom->_shellPlacement.size() ); iter++ )
198  {
199  this->_shellPlacement.at(iter) = copyFrom->_shellPlacement.at(iter);
200  }
201 
202  //==================================== Variables regarding the density map
203  this->_mapResolution = copyFrom->_mapResolution;
204  this->_maxMapU = copyFrom->_maxMapU;
205  this->_maxMapV = copyFrom->_maxMapV;
206  this->_maxMapW = copyFrom->_maxMapW;
207  this->_densityMapComputed = copyFrom->_densityMapComputed;
208  this->_mapMean = copyFrom->_mapMean;
209  this->_mapSdev = copyFrom->_mapSdev;
210 
211  if ( copyFrom->_densityMapMap != nullptr )
212  {
213  this->_densityMapMap = new float[(copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1)];
214  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1) ); iter++)
215  {
216  this->_densityMapMap[iter] = copyFrom->_densityMapMap[iter];
217  }
218  }
219  else
220  {
221  this->_densityMapMap = nullptr;
222  }
223 
224  //==================================== Variables regarding the phase removal from map
225  this->_fourierCoeffPower = copyFrom->_fourierCoeffPower;
226  this->_bFactorChange = copyFrom->_bFactorChange;
227  this->_maxMapRange = copyFrom->_maxMapRange;
228  this->_phaseRemoved = copyFrom->_phaseRemoved;
229  this->_keepOrRemove = copyFrom->_keepOrRemove;
230 
231  if ( copyFrom->_densityMapCor != nullptr )
232  {
233  this->_densityMapCor = new double[(copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1)];
234  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1) ); iter++)
235  {
236  this->_densityMapCor[iter] = copyFrom->_densityMapCor[iter];
237  }
238  }
239  else
240  {
241  this->_densityMapCor = nullptr;
242  }
243 
244  if ( copyFrom->_densityMapCorCoords != nullptr )
245  {
246  this->_densityMapCorCoords = new std::array<double,3>[(copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1)];
247  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (copyFrom->_maxMapU+1) * (copyFrom->_maxMapV+1) * (copyFrom->_maxMapW+1) ); iter++)
248  {
249  this->_densityMapCorCoords[iter][0] = copyFrom->_densityMapCorCoords[iter][0];
250  this->_densityMapCorCoords[iter][1] = copyFrom->_densityMapCorCoords[iter][1];
251  this->_densityMapCorCoords[iter][2] = copyFrom->_densityMapCorCoords[iter][2];
252  }
253  }
254  else
255  {
256  this->_densityMapCorCoords = nullptr;
257  }
258 
259  //==================================== Variables regarding the sphere mapping of phaseless data
260  this->_thetaAngle = copyFrom->_thetaAngle;
261  this->_phiAngle = copyFrom->_phiAngle;
262  this->_noShellsWithData = copyFrom->_noShellsWithData;
263  this->_xCorrection = copyFrom->_xCorrection;
264  this->_yCorrection = copyFrom->_yCorrection;
265  this->_zCorrection = copyFrom->_zCorrection;
266  this->_xCorrErr = copyFrom->_xCorrErr;
267  this->_yCorrErr = copyFrom->_yCorrErr;
268  this->_zCorrErr = copyFrom->_zCorrErr;
269  this->_sphereMapped = copyFrom->_sphereMapped;
270  this->_firstLineCOM = copyFrom->_firstLineCOM;
271 
272  if ( copyFrom->_shellMappedData != nullptr )
273  {
274  this->_shellMappedData = new double*[this->_noShellsWithData];
275  for ( unsigned int sh = 0; sh < this->_noShellsWithData; sh++ )
276  {
277  this->_shellMappedData[sh] = new double[static_cast<unsigned int> ( this->_thetaAngle * this->_phiAngle )];
278  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->_thetaAngle * this->_phiAngle ); iter++ )
279  {
280  this->_shellMappedData[sh][iter] = copyFrom->_shellMappedData[sh][iter];
281  }
282  }
283  }
284  else
285  {
286  this->_shellMappedData = nullptr;
287  }
288 
289  //==================================== Variables regarding the spherical harmonics decomposition
290  this->_bandwidthLimit = copyFrom->_bandwidthLimit;
291  this->_oneDimmension = copyFrom->_oneDimmension;
292  this->_sphericalCoefficientsComputed = copyFrom->_sphericalCoefficientsComputed;
293  this->_wasBandwithGiven = copyFrom->_wasBandwithGiven;
294  this->_wasThetaGiven = copyFrom->_wasThetaGiven;
295  this->_wasPhiGiven = copyFrom->_wasPhiGiven;
296  this->_wasGlInterGiven = copyFrom->_wasGlInterGiven;
297 
298  if ( copyFrom->_realSHCoeffs != nullptr )
299  {
300  this->_realSHCoeffs = new double*[static_cast<unsigned int> ( this->_noShellsWithData )];
301  for ( unsigned int shIt = 0; shIt < this->_noShellsWithData; shIt++ )
302  {
303  this->_realSHCoeffs[shIt] = new double [static_cast<unsigned int> ( this->_oneDimmension * this->_oneDimmension )];
304  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->_oneDimmension * this->_oneDimmension ); iter++ )
305  {
306  this->_realSHCoeffs[shIt][iter] = copyFrom->_realSHCoeffs[shIt][iter];
307  }
308  }
309  }
310  else
311  {
312  this->_realSHCoeffs = nullptr;
313  }
314 
315  if ( copyFrom->_imagSHCoeffs != nullptr )
316  {
317  this->_imagSHCoeffs = new double*[static_cast<unsigned int> ( this->_noShellsWithData )];
318  for ( unsigned int shIt = 0; shIt < this->_noShellsWithData; shIt++ )
319  {
320  this->_imagSHCoeffs[shIt] = new double [static_cast<unsigned int> ( this->_oneDimmension * this->_oneDimmension )];
321  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->_oneDimmension * this->_oneDimmension ); iter++ )
322  {
323  this->_imagSHCoeffs[shIt][iter] = copyFrom->_imagSHCoeffs[shIt][iter];
324  }
325  }
326  }
327  else
328  {
329  this->_imagSHCoeffs = nullptr;
330  }
331 
332  if ( copyFrom->_sphericalHarmonicsWeights != nullptr )
333  {
334  this->_sphericalHarmonicsWeights = new double [static_cast<unsigned int> ( this->_bandwidthLimit * 4 )];
335  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->_bandwidthLimit * 4 ); iter++ )
336  {
337  this->_sphericalHarmonicsWeights[iter] = copyFrom->_sphericalHarmonicsWeights[iter];
338  }
339  }
340  else
341  {
342  this->_sphericalHarmonicsWeights = nullptr;
343  }
344 
345  if ( copyFrom->_shWorkspace != nullptr )
346  {
347  this->_shWorkspace = (fftw_complex *) fftw_malloc ( sizeof(fftw_complex) * ( ( 8 * this->_bandwidthLimit * this->_bandwidthLimit ) +
348  ( 10 * this->_bandwidthLimit ) ) );
349  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( ( 8 * this->_bandwidthLimit * this->_bandwidthLimit ) + ( 10 * this->_bandwidthLimit ) ); iter++ )
350  {
351  this->_shWorkspace[iter][0] = copyFrom->_shWorkspace[iter][0];
352  this->_shWorkspace[iter][1] = copyFrom->_shWorkspace[iter][1];
353  }
354  }
355  else
356  {
357  this->_shWorkspace = nullptr;
358  }
359 
360  if ( copyFrom->_semiNaiveTableSpace != nullptr )
361  {
362  this->_semiNaiveTableSpace = new double [static_cast<unsigned int> ( Reduced_Naive_TableSize ( this->_bandwidthLimit, this->_bandwidthLimit ) +
363  Reduced_SpharmonicTableSize ( this->_bandwidthLimit, this->_bandwidthLimit ) )];
364  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( Reduced_Naive_TableSize ( this->_bandwidthLimit, this->_bandwidthLimit ) + Reduced_SpharmonicTableSize ( this->_bandwidthLimit, this->_bandwidthLimit ) ); iter++ )
365  {
366  this->_semiNaiveTableSpace[iter] = copyFrom->_semiNaiveTableSpace[iter];
367  }
368  }
369  else
370  {
371  this->_semiNaiveTableSpace = nullptr;
372  }
373 
374  if ( copyFrom->_semiNaiveTable != nullptr )
375  {
376  this->_semiNaiveTable = nullptr;
377  this->_semiNaiveTable = SemiNaive_Naive_Pml_Table ( this->_bandwidthLimit,
378  this->_bandwidthLimit,
379  this->_semiNaiveTableSpace,
380  reinterpret_cast<double*> ( this->_shWorkspace ) );
381  }
382  else
383  {
384  this->_semiNaiveTable = nullptr;
385  }
386 
387  //==================================== Variables regarding spherical harmonics inverse
388  if ( copyFrom->_invRealData != nullptr )
389  {
390  std::cerr << "!!! ProSHADE ERROR !!! Error copying the ProSHADE_data object. This should not happen, please report this case." << std::endl;
391  exit ( -1 );
392  }
393  else
394  {
395  this->_invRealData = nullptr;
396  }
397 
398  if ( copyFrom->_invImagData != nullptr )
399  {
400  std::cerr << "!!! ProSHADE ERROR !!! Error copying the ProSHADE_data object. This should not happen, please report this case." << std::endl;
401  exit ( -1 );
402  }
403  else
404  {
405  this->_invImagData = nullptr;
406  }
407 
408  //==================================== Variables regarding the energy levels descriptor pre-calculation
409  if ( copyFrom->_rrpMatrices != nullptr )
410  {
411  this->_rrpMatrices = new double** [this->_bandwidthLimit];
412  for ( unsigned int bwIt = 0; bwIt < this->_bandwidthLimit; bwIt++ )
413  {
414  //==================================== Odd bands are 0, so just ignore them
415  if ( !this->_keepOrRemove ) { if ( ( bwIt % 2 ) != 0 ) { continue; } }
416 
417  this->_rrpMatrices[bwIt] = new double* [this->_noShellsWithData];
418  for ( unsigned int shIt = 0; shIt < this->_noShellsWithData; shIt++ )
419  {
420  this->_rrpMatrices[bwIt][shIt]= new double [this->_noShellsWithData];
421  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->_noShellsWithData ); iter++ )
422  {
423  this->_rrpMatrices[bwIt][shIt][iter] = copyFrom->_rrpMatrices[bwIt][shIt][iter];
424  }
425  }
426  }
427  }
428  else
429  {
430  this->_rrpMatrices = nullptr;
431  }
432 
433  this->_rrpMatricesPrecomputed = copyFrom->_rrpMatricesPrecomputed;
434 
435  //======================================== Done
436 
437 }
438 
447 {
448  //======================================== Free memory
449  if ( this->_densityMapMap != nullptr ) { delete[] this->_densityMapMap ; }
450  if ( this->_densityMapCor != nullptr ) { delete[] this->_densityMapCor ; }
451  if ( this->_densityMapCorCoords != nullptr ) { delete[] this->_densityMapCorCoords ; }
452  if ( this->_shellMappedData != nullptr ) { delete[] this->_shellMappedData ; }
453  if ( this->_sphericalHarmonicsWeights != nullptr ) { delete[] this->_sphericalHarmonicsWeights; }
454  if ( this->_semiNaiveTableSpace != nullptr ) { delete[] this->_semiNaiveTableSpace ; }
455 
456 
457  if ( this->_shWorkspace != nullptr ) { fftw_free ( this->_shWorkspace ) ; }
458 
459  if ( this->_rrpMatrices != nullptr ) { for ( unsigned int i = 0; i < this->_bandwidthLimit; i++ ) { if ( i % 2 == 1 ) { continue; } delete[] this->_rrpMatrices[i]; } }
460 
461  if ( this->_realSHCoeffs != nullptr && this->_imagSHCoeffs != nullptr )
462  {
463  for ( unsigned int shIt = 0; shIt < this->_noShellsWithData; shIt++ )
464  {
465  delete[] this->_realSHCoeffs[shIt];
466  delete[] this->_imagSHCoeffs[shIt];
467  }
468  delete[] this->_realSHCoeffs;
469  delete[] this->_imagSHCoeffs;
470  }
471 
472  if ( this->_invRealData != nullptr && this->_invImagData != nullptr )
473  {
474  for ( unsigned int shIt = 0; shIt < this->_noShellsWithData; shIt++ )
475  {
476  delete[] this->_invRealData[shIt];
477  delete[] this->_invImagData[shIt];
478  }
479  delete[] this->_invRealData;
480  delete[] this->_invImagData;
481  }
482 
483  //======================================== Done
484 }
485 
503  ProSHADE_data *cmpObj2,
504  double mPower,
505  std::vector<int> ignoreL,
506  unsigned int order,
507  ProSHADE::ProSHADE_settings* settings )
508 {
509  //======================================== Initialise internal values
510  this->_bothRRPsPreComputed = false;
511 
512  //======================================== Sanity checks
513  if ( cmpObj1->_bandwidthLimit != cmpObj2->_bandwidthLimit )
514  {
515  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << cmpObj1->_inputFileName << " AND " << cmpObj2->_inputFileName << " !!! The bandwidths are different, use the same bandwidth to make the strucutres comparable." << std::endl;
516  exit ( -1 );
517  }
518 
519  if ( ( cmpObj1->_thetaAngle != cmpObj2->_thetaAngle ) || ( cmpObj1->_phiAngle != cmpObj2->_phiAngle ) )
520  {
521  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << cmpObj1->_inputFileName << " AND " << cmpObj2->_inputFileName << " !!! The theta or phi angles are different, use the same theta and phi angles to make the strucutres comparable." << std::endl;
522  exit ( -1 );
523  }
524 
525  if ( ( cmpObj1->_rrpMatricesPrecomputed ) && ( cmpObj2->_rrpMatricesPrecomputed ) )
526  {
527  this->_bothRRPsPreComputed = true;
528  }
529 
530  if ( cmpObj1->_shellSpacing != cmpObj2->_shellSpacing )
531  {
532  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << cmpObj1->_inputFileName << " AND " << cmpObj2->_inputFileName << " !!! The shell spacing distances are different, use the same shell spacing distance to make the strucutres comparable." << std::endl;
533  exit ( -1 );
534  }
535 
536  if ( cmpObj1->_keepOrRemove != cmpObj2->_keepOrRemove )
537  {
538  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << cmpObj1->_inputFileName << " AND " << cmpObj2->_inputFileName << " !!! The phase treatment is different (i.e. one structure has phases removed, the other does not), use the same phase treatment to make the strucutres comparable." << std::endl;
539  exit ( -1 );
540  }
541 
542  if ( order < 2 )
543  {
544  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << cmpObj1->_inputFileName << " AND " << cmpObj2->_inputFileName << " !!! The Gauss-Legendre integration order is too low, select a higher value than 1!" << std::endl;
545  exit ( -1 );
546  }
547 
548  //======================================== Initialise internal values
549  this->_bandwidthLimit = cmpObj1->_bandwidthLimit;
550  this->_thetaAngle = cmpObj1->_thetaAngle;
551  this->_phiAngle = cmpObj1->_phiAngle;
552  this->_matrixPowerWeight = mPower;
553  this->_lsToIgnore = ignoreL;
554  this->_minShellsToUse = std::min ( cmpObj1->_noShellsWithData, cmpObj2->_noShellsWithData );
555  this->_obj1RRPs = cmpObj1->_rrpMatrices;
556  this->_obj2RRPs = cmpObj2->_rrpMatrices;
557  this->_shellSpacing = cmpObj1->_shellSpacing;
558  this->_obj1RealCoeffs = cmpObj1->_realSHCoeffs;
559  this->_obj1ImagCoeffs = cmpObj1->_imagSHCoeffs;
560  this->_obj2RealCoeffs = cmpObj2->_realSHCoeffs;
561  this->_obj2ImagCoeffs = cmpObj2->_imagSHCoeffs;
562  this->_noShellsObj1 = cmpObj1->_noShellsWithData;
563  this->_noShellsObj2 = cmpObj2->_noShellsWithData;
564  this->_maxShellsToUse = std::max ( cmpObj1->_noShellsWithData, cmpObj2->_noShellsWithData );
565  this->_keepOrRemove = cmpObj1->_keepOrRemove;
566  this->_glIntegrationOrder = order;
567 
568  this->_trSigmaEMatrix = nullptr;
569  this->_so3Coeffs = nullptr;
570  this->_so3InvCoeffs = nullptr;
571  this->_so3Workspace1 = nullptr;
572  this->_so3Workspace2 = nullptr;
573  this->_so3Workspace3 = nullptr;
574 
575  this->_distanceRotInv = 0.0;
576  this->_distanceTrSigma = 0.0;
577  this->_peakHeightThr = 0.0;
578 
579  this->_rotInvComputed = false;
580  this->_trSigmaPreComputed = false;
581  this->_trSigmaComputed = false;
582  this->_so3InvMapComputed = false;
583  this->_eulerAnglesFound = false;
584  this->_wignerMatricesComputed = false;
585  this->_CSymmsFound = false;
586  this->_DSymmsFound = false;
587 
588  //======================================== Compute weights and abscissas for GL Integration
589  this->_glAbscissas = std::vector<double> ( this->_glIntegrationOrder );
590  this->_glWeights = std::vector<double> ( this->_glIntegrationOrder );
591  ProSHADE_internal_legendre::getLegendreAbscAndWeights ( this->_glIntegrationOrder, &(this->_glAbscissas), &(this->_glWeights), settings );
592 
593  //======================================== Done
594 
595 }
596 
605 {
606  //======================================== Free memory
607  if ( this->_trSigmaEMatrix != nullptr ) { delete[] this->_trSigmaEMatrix ; }
608  if ( this->_so3Workspace3 != nullptr ) { delete[] this->_so3Workspace3 ; }
609  if ( this->_so3Coeffs != nullptr ) { fftw_free ( this->_so3Coeffs ); }
610  if ( this->_so3InvCoeffs != nullptr ) { fftw_free ( this->_so3InvCoeffs ); }
611  if ( this->_so3Workspace1 != nullptr ) { fftw_free ( this->_so3Workspace1 ); }
612  if ( this->_so3Workspace2 != nullptr ) { fftw_free ( this->_so3Workspace2 ); }
613  if ( this->_so3InvCoeffs != nullptr ) { fftw_free ( this->_so3InvCoeffs ); }
614 
615  //======================================== Done
616 
617 }
618 
631 double ProSHADE_internal::ProSHADE_comparePairwise::gl20IntRR ( std::vector<double>* vals )
632 {
633  //======================================== Initialise local variables
634  double ret;
635 
636  //======================================== Rescale to <order> points
637  std::vector< std::array<double,2> > intData ( static_cast<unsigned int> ( this->_glAbscissas.size() ) );
638  std::array<double,2> posVals;
639  unsigned int lesserPos = 0;
640  unsigned int upperPos = 0;
641  double lesserWeight = 0.0;
642  double upperWeight = 0.0;
643  for ( unsigned int absIter = 0; absIter < static_cast<unsigned int> ( this->_glAbscissas.size() ); absIter++ )
644  {
645  //==================================== Init loop
646  posVals[0] = 0.0;
647  posVals[1] = 0.0;
648 
649  //==================================== Find real position of abscissas
650  posVals[0] = ( ( this->_glAbscissas.at(absIter) + 1.0 ) / 2.0 ) * ( this->_shellSpacing * static_cast<double> ( vals->size() ) );
651 
652  //==================================== Find lesser and upper bounds
653  for ( unsigned int valIt = 0; valIt < static_cast<unsigned int> ( vals->size() ); valIt++ )
654  {
655  if ( ( (valIt*this->_shellSpacing) <= posVals[0] ) && ( ( (valIt+1)*this->_shellSpacing) > posVals[0] ) )
656  {
657  lesserPos = static_cast<unsigned int> ( valIt );
658  upperPos = static_cast<unsigned int> ( valIt + 1 );
659  break;
660  }
661  }
662 
663  //==================================== Linear Interpolation
664  lesserWeight = 0.0;
665  upperWeight = 0.0;
666  if ( lesserPos != 0 )
667  {
668  //================================ Here we realise that the lesser and upper bounds were determined on scale 1 ... N, while our values are on scale 0 ... N-1 and therefore after determining the linear interpolation weights, we subtract 1 from both lesserPos and upperPos; however ...
669  lesserWeight = upperPos - ( posVals[0] / this->_shellSpacing );
670  upperWeight = 1.0 - lesserWeight;
671 
672  posVals[1] = ( lesserWeight * vals->at(lesserPos-1) ) + ( upperWeight * vals->at(upperPos-1) );
673  }
674  else
675  {
676  //================================ ... this then means that we would require position -1 for when the integration value is between 0 and the first shell. To resolve this, we assume that the values are 0 below the first shell and proceed as follows:
677  upperWeight = 1.0 - ( upperPos - ( posVals[0] / this->_shellSpacing ) );
678 
679  posVals[1] = ( upperWeight * vals->at(upperPos-1) );
680  }
681 
682  intData.at(absIter) = posVals;
683  }
684 
685  //======================================== Integrate
686  ret = 0.0;
687 
688  for ( unsigned int absPoint = 0; absPoint < static_cast<unsigned int> ( intData.size() ); absPoint++ )
689  {
690  ret += ( this->_glWeights.at(absPoint) * intData.at(absPoint)[1] );
691  }
692 
693  //======================================== Normalise
694  ret *= ( ( static_cast<double> ( vals->size() ) * this->_shellSpacing ) / 2.0 );
695 
696  //======================================== Done
697  return ( ret );
698 
699 }
700 
713 std::array<double,2> ProSHADE_internal::ProSHADE_comparePairwise::gl20IntCR ( std::vector< std::array<double,2> >* vals )
714 {
715  //======================================== Initialise local variables
716  std::array<double,2> ret;
717 
718  //======================================== Rescale to <order> points
719  std::vector< std::array<double,3> > intData;
720  std::array<double,3> posVals;
721  unsigned int lesserPos = 0;
722  unsigned int upperPos = 0;
723  double lesserWeight = 0.0;
724  double upperWeight = 0.0;
725  for ( unsigned int absIter = 0; absIter < static_cast<unsigned int> ( this->_glAbscissas.size() ); absIter++ )
726  {
727  //==================================== Init
728  posVals[0] = 0.0; posVals[1] = 0.0; posVals[2] = 0.0;
729 
730  //==================================== Find real position of abscissas
731  posVals[0] = ( ( this->_glAbscissas.at(absIter) + 1.0 ) / 2.0 ) * ( this->_shellSpacing * static_cast<double> ( vals->size() ) );
732 
733  //==================================== Find lesser and upper bounds
734  for ( unsigned int valIt = 0; valIt < static_cast<unsigned int> ( vals->size() ); valIt++ )
735  {
736  if ( ( (valIt*this->_shellSpacing) <= posVals[0] ) && ( ( (valIt+1)*this->_shellSpacing) > posVals[0] ) )
737  {
738  lesserPos = static_cast<unsigned int> ( valIt );
739  upperPos = static_cast<unsigned int> ( valIt + 1 );
740  break;
741  }
742  }
743 
744  //==================================== Linear Interpolation
745  lesserWeight = 0.0;
746  upperWeight = 0.0;
747  if ( lesserPos != 0 )
748  {
749  //================================ Here we realise that the lesser and upper bounds were determined on scale 1 ... N, while our values are on scale 0 ... N-1 and therefore after determining the linear interpolation weights, we subtract 1 from both lesserPos and upperPos; however ...
750  lesserWeight = upperPos - ( posVals[0] / this->_shellSpacing );
751  upperWeight = 1.0 - lesserWeight;
752 
753  posVals[1] = ( lesserWeight * vals->at(lesserPos-1)[0] ) + ( upperWeight * vals->at(upperPos-1)[0] );
754  posVals[2] = ( lesserWeight * vals->at(lesserPos-1)[1] ) + ( upperWeight * vals->at(upperPos-1)[1] );
755  }
756  else
757  {
758  //================================ ... this then means that we would require position -1 for when the integration value is between 0 and the first shell. To resolve this, we assume that the values are 0 below the first shell and proceed as follows:
759  upperWeight = 1.0 - ( upperPos - ( posVals[0] / this->_shellSpacing ) );
760 
761  posVals[1] = ( upperWeight * vals->at(upperPos-1)[0] );
762  posVals[2] = ( upperWeight * vals->at(upperPos-1)[1] );
763  }
764 
765  intData.emplace_back ( posVals );
766  }
767 
768  //======================================== Integrate
769  ret[0] = 0.0;
770  ret[1] = 0.0;
771 
772  for ( unsigned int absPoint = 0; absPoint < static_cast<unsigned int> ( intData.size() ); absPoint++ )
773  {
774  ret[0] += ( this->_glWeights.at(absPoint) * intData.at(absPoint)[1] );
775  ret[1] += ( this->_glWeights.at(absPoint) * intData.at(absPoint)[2] );
776  }
777 
778  //======================================== Normalise
779  ret[0] *= ( ( static_cast<double> ( vals->size() ) * this->_shellSpacing ) / 2.0 );
780  ret[1] *= ( ( static_cast<double> ( vals->size() ) * this->_shellSpacing ) / 2.0 );
781 
782  //======================================== Done
783  return ( ret );
784 
785 }
786 
802  std::vector<ProSHADE_data*> *allStrs,
803  std::vector<int> ignoreL,
804  double matrixPowerWeight,
805  int verbose )
806 {
807  //======================================== Initialise internal values
808  this->one = oneStr;
809  this->two = nullptr;
810  this->all = allStrs;
811  std::array<double,3> emptyAngs;
812  double checkValue = 0.0;
813  emptyAngs[0] = -999.0;
814  emptyAngs[1] = -999.0;
815  emptyAngs[2] = -999.0;
816 
817  //======================================== Sanity checks
818  if ( all->size() < 1 )
819  {
820  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison !!! The compare against part has not enough entries." << std::endl;
821  exit ( -1 );
822  }
823 
824  checkValue = static_cast<double> ( this->one->_keepOrRemove );
825  for ( unsigned int strIt = 0; strIt < static_cast<unsigned int> ( this->all->size() ); strIt++ )
826  {
827  if ( checkValue != static_cast<double> ( this->all->at(strIt)->_keepOrRemove ) )
828  {
829  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << this->one->_inputFileName << " AND " << this->all->at(strIt)->_inputFileName << " !!! The phase treatment is different, use the same phase treatment (i.e. remove all, or keep all) to make the strucutres comparable." << std::endl;
830  exit ( -1 );
831  }
832  }
833 
834  //======================================== Initialise internal values
835  this->_lsToIgnore = ignoreL;
836  this->_matrixPowerWeight = matrixPowerWeight;
837 
838  this->_energyLevelsComputed = false;
839  this->_trSigmaPreComputed = false;
840  this->_trSigmaComputed = false;
841  this->_so3InvMapComputed = false;
842  this->_eulerAnglesFound = false;
843  this->_wignerMatricesComputed = false;
844  this->_fullDistComputed = false;
845 
846  //======================================== Done
847 
848 }
849 
866  ProSHADE_data *twoStr,
867  std::vector<ProSHADE_data*> *allStrs,
868  std::vector<int> ignoreL,
869  double matrixPowerWeight,
870  int verbose )
871 {
872  //======================================== Initialise internal values
873  this->one = oneStr;
874  this->two = twoStr;
875  this->all = allStrs;
876  std::array<double,3> emptyAngs;
877  double checkValue = 0.0;
878  emptyAngs[0] = -999.0;
879  emptyAngs[1] = -999.0;
880  emptyAngs[2] = -999.0;
881 
882  //======================================== Sanity checks
883  if ( all->size() < 1 )
884  {
885  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison !!! The compare against part has not enough entries." << std::endl;
886  exit ( -1 );
887  }
888 
889  checkValue = static_cast<double> ( this->one->_keepOrRemove );
890  for ( unsigned int strIt = 0; strIt < static_cast<unsigned int> ( this->all->size() ); strIt += 2 )
891  {
892  if ( checkValue != static_cast<double> ( this->all->at(strIt)->_keepOrRemove ) )
893  {
894  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << this->one->_inputFileName << " AND " << this->all->at(strIt)->_inputFileName << " !!! The phase treatment is different, use the same phase treatment (i.e. remove all, or keep all) to make the strucutres comparable." << std::endl;
895  exit ( -1 );
896  }
897  }
898 
899  checkValue = static_cast<double> ( this->two->_keepOrRemove );
900  for ( unsigned int strIt = 1; strIt < static_cast<unsigned int> ( this->all->size() ); strIt += 2 )
901  {
902  if ( checkValue != static_cast<double> ( this->all->at(strIt)->_keepOrRemove ) )
903  {
904  std::cerr << "!!! ProSHADE ERROR !!! Error in file comparison between " << this->one->_inputFileName << " AND " << this->all->at(strIt)->_inputFileName << " !!! The phase treatment is different, use the same phase treatment (i.e. remove all, or keep all) to make the strucutres comparable." << std::endl;
905  exit ( -1 );
906  }
907  }
908 
909  //======================================== Initialise internal values
910  this->_lsToIgnore = ignoreL;
911  this->_matrixPowerWeight = matrixPowerWeight;
912 
913  this->_energyLevelsComputed = false;
914  this->_trSigmaPreComputed = false;
915  this->_trSigmaComputed = false;
916  this->_so3InvMapComputed = false;
917  this->_eulerAnglesFound = false;
918  this->_wignerMatricesComputed = false;
919  this->_fullDistComputed = false;
920 
921  //======================================== Done
922 
923 }
924 
933 {
934  //======================================== Done
935  if ( this->one != nullptr ) { delete this->one; }
936  if ( this->two != nullptr ) { delete this->two; }
937 
938  this->all->clear ( );
939 }
940 
956 double ProSHADE_internal::ProSHADE_compareOneAgainstAll::glIntRR ( std::vector<double>* vals,
957  double shellSep,
958  std::vector<double>* glAbscissas,
959  std::vector<double>* glWeights )
960 {
961  //======================================== Initialise local variables
962  double ret;
963 
964  //======================================== Rescale to <order> points
965  std::vector< std::array<double,2> > intData;
966  std::array<double,2> posVals;
967  unsigned int lesserPos = 0;
968  unsigned int upperPos = 0;
969  double lesserWeight = 0.0;
970  double upperWeight = 0.0;
971 
972  for ( unsigned int absIter = 0; absIter < static_cast<unsigned int> ( glAbscissas->size() ); absIter++ )
973  {
974  //==================================== Init
975  posVals[0] = 0.0;
976  posVals[1] = 0.0;
977 
978  //==================================== Find real position of abscissas
979  posVals[0] = ( ( glAbscissas->at(absIter) + 1.0 ) / 2.0 ) * ( shellSep * static_cast<double> ( vals->size() ) );
980 
981  //==================================== Find lesser and upper bounds
982  for ( unsigned int valIt = 0; valIt < static_cast<unsigned int> ( vals->size() ); valIt++ )
983  {
984  if ( ( (valIt*shellSep) <= posVals[0] ) && ( ( (valIt+1)*shellSep) > posVals[0] ) )
985  {
986  lesserPos = static_cast<unsigned int> ( valIt );
987  upperPos = static_cast<unsigned int> ( valIt + 1 );
988  break;
989  }
990  }
991 
992  //==================================== Linear Interpolation
993  lesserWeight = 0.0;
994  upperWeight = 0.0;
995  if ( lesserPos != 0 )
996  {
997  //================================ Here we realise that the lesser and upper bounds were determined on scale 1 ... N, while our values are on scale 0 ... N-1 and therefore after determining the linear interpolation weights, we subtract 1 from both lesserPos and upperPos; however ...
998  lesserWeight = upperPos - ( posVals[0] / shellSep );
999  upperWeight = 1.0 - lesserWeight;
1000 
1001  posVals[1] = ( lesserWeight * vals->at(lesserPos-1) ) + ( upperWeight * vals->at(upperPos-1) );
1002  }
1003  else
1004  {
1005  //================================ ... this then means that we would require position -1 for when the integration value is between 0 and the first shell. To resolve this, we assume that the values are 0 below the first shell and proceed as follows:
1006  upperWeight = 1.0 - ( upperPos - ( posVals[0] / shellSep ) );
1007 
1008  posVals[1] = ( upperWeight * vals->at(upperPos-1) );
1009  }
1010 
1011  intData.emplace_back ( posVals );
1012  }
1013 
1014  //======================================== Integrate
1015  ret = 0.0;
1016 
1017  for ( unsigned int absPoint = 0; absPoint < static_cast<unsigned int> ( intData.size() ); absPoint++ )
1018  {
1019  ret += ( glWeights->at(absPoint) * intData.at(absPoint)[1] );
1020  }
1021 
1022  //======================================== Normalise
1023  ret *= ( ( static_cast<double> ( vals->size() ) * shellSep ) / 2.0 );
1024 
1025  //======================================== Done
1026  return ( ret );
1027 
1028 }
1029 
1045 std::array<double,2> ProSHADE_internal::ProSHADE_compareOneAgainstAll::glIntCR ( std::vector< std::array<double,2> >* vals,
1046  double shellSep,
1047  std::vector<double> *glAbscissas,
1048  std::vector<double> *glWeights )
1049 {
1050  //======================================== Initialise local variables
1051  std::array<double,2> ret;
1052 
1053  //======================================== Rescale to <order> points
1054  std::vector< std::array<double,3> > intData;
1055  std::array<double,3> posVals;
1056  unsigned int lesserPos = 0;
1057  unsigned int upperPos = 0;
1058  double lesserWeight = 0.0;
1059  double upperWeight = 0.0;
1060 
1061  for ( unsigned int absIter = 0; absIter < static_cast<unsigned int> ( glAbscissas->size() ); absIter++ )
1062  {
1063  //==================================== Init
1064  posVals[0] = 0.0;
1065  posVals[1] = 0.0;
1066  posVals[2] = 0.0;
1067 
1068  //==================================== Find real position of abscissas
1069  posVals[0] = ( ( glAbscissas->at(absIter) + 1.0 ) / 2.0 ) * ( shellSep * static_cast<double> ( vals->size() ) );
1070 
1071  //==================================== Find lesser and upper bounds
1072  for ( unsigned int valIt = 0; valIt < static_cast<unsigned int> ( vals->size() ); valIt++ )
1073  {
1074  if ( ( (valIt*shellSep) <= posVals[0] ) && ( ( (valIt+1)*shellSep) > posVals[0] ) )
1075  {
1076  lesserPos = static_cast<unsigned int> ( valIt );
1077  upperPos = static_cast<unsigned int> ( valIt + 1 );
1078  break;
1079  }
1080  }
1081 
1082  //==================================== Linear Interpolation
1083  lesserWeight = 0.0;
1084  upperWeight = 0.0;
1085  if ( lesserPos != 0 )
1086  {
1087  //================================ Here we realise that the lesser and upper bounds were determined on scale 1 ... N, while our values are on scale 0 ... N-1 and therefore after determining the linear interpolation weights, we subtract 1 from both lesserPos and upperPos; however ...
1088  lesserWeight = upperPos - ( posVals[0] / shellSep );
1089  upperWeight = 1.0 - lesserWeight;
1090 
1091  posVals[1] = ( lesserWeight * vals->at(lesserPos-1)[0] ) + ( upperWeight * vals->at(upperPos-1)[0] );
1092  posVals[2] = ( lesserWeight * vals->at(lesserPos-1)[1] ) + ( upperWeight * vals->at(upperPos-1)[1] );
1093  }
1094  else
1095  {
1096  //================================ ... this then means that we would require position -1 for when the integration value is between 0 and the first shell. To resolve this, we assume that the values are 0 below the first shell and proceed as follows:
1097  upperWeight = 1.0 - ( upperPos - ( posVals[0] / shellSep ) );
1098 
1099  posVals[1] = ( upperWeight * vals->at(upperPos-1)[0] );
1100  posVals[2] = ( upperWeight * vals->at(upperPos-1)[1] );
1101  }
1102 
1103  intData.emplace_back ( posVals );
1104  }
1105 
1106  //======================================== Integrate
1107  ret[0] = 0.0;
1108  ret[1] = 0.0;
1109 
1110  for ( unsigned int absPoint = 0; absPoint < static_cast<unsigned int> ( intData.size() ); absPoint++ )
1111  {
1112  ret[0] += ( glWeights->at(absPoint) * intData.at(absPoint)[1] );
1113  ret[1] += ( glWeights->at(absPoint) * intData.at(absPoint)[2] );
1114  }
1115 
1116  //======================================== Normalise
1117  ret[0] *= ( ( static_cast<double> ( vals->size() ) * shellSep ) / 2.0 );
1118  ret[1] *= ( ( static_cast<double> ( vals->size() ) * shellSep ) / 2.0 );
1119 
1120  //======================================== Done
1121  return ( ret );
1122 
1123 }
1124 
1134 {
1135  ;
1136 }
1137 
1151 {
1152  //======================================== Save the settings
1153  this->mapResolution = settings->mapResolution;
1154  this->bandwidth = std::vector<unsigned int> { { settings->bandwidth , settings->bandwidth } };
1155  this->glIntegOrder = std::vector<unsigned int> { { settings->glIntegOrder, settings->glIntegOrder } };
1156  this->theta = std::vector<unsigned int> { { settings->theta , settings->theta } };
1157  this->phi = std::vector<unsigned int> { { settings->phi , settings->phi } };
1158  this->bFactorValue = settings->bFactorValue;
1159  this->bFactorChange = settings->bFactorChange;
1160  this->noIQRsFromMap = settings->noIQRsFromMap;
1161  this->shellSpacing = settings->shellSpacing;
1162  this->manualShells = settings->manualShells;
1163  this->useCOM = settings->useCOM;
1164  this->firstLineCOM = settings->firstLineCOM;
1165  this->extraSpace = settings->extraSpace;
1166  this->alpha = settings->alpha;
1167  this->mPower = settings->mPower;
1168  this->ignoreLs = settings->ignoreLs;
1169  this->peakHeightNoIQRs = settings->peakHeightNoIQRs;
1170  this->peakDistanceForReal = settings->peakDistanceForReal;
1171  this->peakSurroundingPoints = settings->peakSurroundingPoints;
1172  this->aaErrorTolerance = settings->aaErrorTolerance;
1173  this->symGapTolerance = settings->symGapTolerance;
1174  this->printFull = false;
1175  this->structFiles = settings->structFiles;
1176 
1177  double shSpacingObj1 = settings->shellSpacing;
1178  double shSpacingObj2 = settings->shellSpacing;
1179 
1180  //======================================== In the case of simple rotation, do it instead
1181  if ( settings->taskToPerform == ProSHADE::OverlayMap )
1182  {
1183  //==================================== Sanity checks
1184  if ( settings->structFiles.size() != 2 )
1185  {
1186  std::cerr << "!!! ProSHADE ERROR !!! Not enough files/too many files detected for map overlay mode. Please supply a two structures using the -f or -i command line options. Terminating..." << std::endl;
1187 
1188  if ( settings->htmlReport )
1189  {
1190  std::stringstream hlpSS;
1191  hlpSS << "<font color=\"red\">" << "The number of input structures is not two. Do not know how to proceed." << "</font>";
1192  rvapi_set_text ( hlpSS.str().c_str(),
1193  "ProgressSection",
1194  settings->htmlReportLineProgress,
1195  1,
1196  1,
1197  1 );
1198  settings->htmlReportLineProgress += 1;
1199  rvapi_flush ( );
1200  }
1201 
1202  exit ( -1 );
1203  }
1204 
1205  bool wasMapNameGiven = true;
1206  if ( settings->clearMapFile == "" )
1207  {
1208  std::cout << "!!! ProSHADE WARNING !!! The output file name was not set. You may want to use the \'--clearMap\' option to set it. Using the default name \'rotStr\'." << std::endl;
1209 
1210  if ( settings->htmlReport )
1211  {
1212  std::stringstream hlpSS;
1213  hlpSS << "<font color=\"orange\">" << "There is no filename to which the output matching structure should be saved. Will use defaul name 'rotStr'." << "</font>";
1214  rvapi_set_text ( hlpSS.str().c_str(),
1215  "ProgressSection",
1216  settings->htmlReportLineProgress,
1217  1,
1218  1,
1219  1 );
1220  settings->htmlReportLineProgress += 1;
1221  rvapi_flush ( );
1222  }
1223 
1224  if ( ProSHADE_internal::checkFileType ( settings->structFiles.at(0) ) == 2 )
1225  {
1226  settings->clearMapFile = "rotStr";
1227  }
1228  if ( ProSHADE_internal::checkFileType ( settings->structFiles.at(0) ) == 1 )
1229  {
1230  settings->clearMapFile = "rotStr";
1231  }
1232  wasMapNameGiven = false;
1233  }
1234 
1235  if ( settings->verbose > 2 )
1236  {
1237  std::cout << ">>>>> Sanity checks passed." << std::endl;
1238  }
1239 
1240  if ( settings->htmlReport )
1241  {
1242  std::stringstream hlpSS;
1243  hlpSS << "<font color=\"green\">" << "Will move structure " << settings->structFiles.at(1) << " to match into structure " << settings->structFiles.at(0) << " .</font>";
1244  rvapi_set_text ( hlpSS.str().c_str(),
1245  "ProgressSection",
1246  settings->htmlReportLineProgress,
1247  1,
1248  1,
1249  1 );
1250  settings->htmlReportLineProgress += 1;
1251  rvapi_flush ( );
1252  }
1253 
1254  //==================================== Change default resolution for the case of two PDB files
1255  unsigned int fileType = checkFileType ( structFiles.at(0) );
1256 
1257  //==================================== Read in structure
1258  ProSHADE_data* pattStr1 = new ProSHADE_data ();
1259  if ( fileType == 2 )
1260  {
1261  pattStr1->getDensityMapFromMAP ( this->structFiles.at(0),
1262  &shSpacingObj1,
1263  this->mapResolution,
1264  &this->bandwidth.at(0),
1265  &this->theta.at(0),
1266  &this->phi.at(0),
1267  &this->glIntegOrder.at(0),
1268  &this->extraSpace,
1269  settings->mapResDefault,
1270  settings->rotChangeDefault,
1271  settings,
1272  settings->overlayDefaults );
1273  }
1274  else if ( fileType == 1 )
1275  {
1276  pattStr1->getDensityMapFromPDB ( this->structFiles.at(0),
1277  &shSpacingObj1,
1278  this->mapResolution,
1279  &this->bandwidth.at(0),
1280  &this->theta.at(0),
1281  &this->phi.at(0),
1282  &this->glIntegOrder.at(0),
1283  &this->extraSpace,
1284  settings->mapResDefault,
1285  settings,
1286  this->bFactorValue,
1287  this->firstLineCOM,
1288  settings->overlayDefaults );
1289  }
1290  else
1291  {
1292  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1293 
1294  if ( settings->htmlReport )
1295  {
1296  std::stringstream hlpSS;
1297  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(0) << " ." << "</font>";
1298  rvapi_set_text ( hlpSS.str().c_str(),
1299  "ProgressSection",
1300  settings->htmlReportLineProgress,
1301  1,
1302  1,
1303  1 );
1304  settings->htmlReportLineProgress += 1;
1305  rvapi_flush ( );
1306  }
1307 
1308  exit ( -1 );
1309  }
1310 
1311  if ( settings->verbose > 0 )
1312  {
1313  std::cout << "Structure 1 loaded." << std::endl;
1314  }
1315 
1316  //==================================== Read in structure 2
1317  fileType = checkFileType ( structFiles.at(1) );
1318  ProSHADE_data* pattStr2 = new ProSHADE_data ();
1319  if ( fileType == 2 )
1320  {
1321  pattStr2->getDensityMapFromMAP ( this->structFiles.at(1),
1322  &shSpacingObj2,
1323  this->mapResolution,
1324  &this->bandwidth.at(1),
1325  &this->theta.at(1),
1326  &this->phi.at(1),
1327  &this->glIntegOrder.at(1),
1328  &this->extraSpace,
1329  settings->mapResDefault,
1330  settings->rotChangeDefault,
1331  settings,
1332  settings->overlayDefaults );
1333  }
1334  else if ( fileType == 1 )
1335  {
1336  pattStr2->getDensityMapFromPDB ( this->structFiles.at(1),
1337  &shSpacingObj2,
1338  this->mapResolution,
1339  &this->bandwidth.at(1),
1340  &this->theta.at(1),
1341  &this->phi.at(1),
1342  &this->glIntegOrder.at(1),
1343  &this->extraSpace,
1344  settings->mapResDefault,
1345  settings,
1346  this->bFactorValue,
1347  this->firstLineCOM,
1348  settings->overlayDefaults );
1349  }
1350  else
1351  {
1352  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(1) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1353 
1354  if ( settings->htmlReport )
1355  {
1356  std::stringstream hlpSS;
1357  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(1) << " ." << "</font>";
1358  rvapi_set_text ( hlpSS.str().c_str(),
1359  "ProgressSection",
1360  settings->htmlReportLineProgress,
1361  1,
1362  1,
1363  1 );
1364  settings->htmlReportLineProgress += 1;
1365  rvapi_flush ( );
1366  }
1367 
1368  exit ( -1 );
1369  }
1370 
1371  if ( settings->verbose > 0 )
1372  {
1373  std::cout << "Structure 2 loaded." << std::endl;
1374  }
1375 
1376  //==================================== Force same band, theta, phi and glInteg
1377  unsigned int maxBand = std::max ( this->bandwidth.at(0) , this->bandwidth.at(1) );
1378  unsigned int maxTheta = std::max ( this->theta.at(0) , this->theta.at(1) );
1379  unsigned int maxPhi = std::max ( this->phi.at(0) , this->phi.at(1) );
1380  unsigned int maxGlInteg = std::max ( this->glIntegOrder.at(0), this->glIntegOrder.at(1) );
1381  double maxSpacing = std::max ( shSpacingObj1, shSpacingObj2 );
1382 
1383  if ( ( shSpacingObj1 != shSpacingObj2 ) || ( this->bandwidth.at(0) != this->bandwidth.at(1) ) ||
1384  ( this->theta.at(0) != this->theta.at(1) ) || ( this->phi.at(0) != this->phi.at(1) ) ||
1385  ( this->glIntegOrder.at(0) != this->glIntegOrder.at(1) ) )
1386  {
1387  this->bandwidth.at(0) = maxBand;
1388  this->bandwidth.at(1) = maxBand;
1389  this->theta.at(0) = maxTheta;
1390  this->theta.at(1) = maxTheta;
1391  this->phi.at(0) = maxPhi;
1392  this->phi.at(1) = maxPhi;
1393  this->glIntegOrder.at(0) = maxGlInteg;
1394  this->glIntegOrder.at(1) = maxGlInteg;
1395  shSpacingObj1 = maxSpacing;
1396  shSpacingObj2 = maxSpacing;
1397 
1398  //================================ Re-read in structure 1
1399  delete pattStr1;
1400  shSpacingObj1 = shSpacingObj2;
1401 
1402  pattStr1 = new ProSHADE_data ();
1403  fileType = checkFileType ( structFiles.at(0) );
1404  if ( fileType == 2 )
1405  {
1406  pattStr1->getDensityMapFromMAP ( this->structFiles.at(0),
1407  &shSpacingObj1,
1408  this->mapResolution,
1409  &this->bandwidth.at(0),
1410  &this->theta.at(0),
1411  &this->phi.at(0),
1412  &this->glIntegOrder.at(0),
1413  &this->extraSpace,
1414  settings->mapResDefault,
1415  settings->rotChangeDefault,
1416  settings,
1417  settings->overlayDefaults );
1418  }
1419  else if ( fileType == 1 )
1420  {
1421  pattStr1->getDensityMapFromPDB ( this->structFiles.at(0),
1422  &shSpacingObj1,
1423  this->mapResolution,
1424  &this->bandwidth.at(0),
1425  &this->theta.at(0),
1426  &this->phi.at(0),
1427  &this->glIntegOrder.at(0),
1428  &this->extraSpace,
1429  settings->mapResDefault,
1430  settings,
1431  this->bFactorValue,
1432  this->firstLineCOM,
1433  settings->overlayDefaults );
1434  }
1435  else
1436  {
1437  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1438 
1439  if ( settings->htmlReport )
1440  {
1441  std::stringstream hlpSS;
1442  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(0) << " ." << "</font>";
1443  rvapi_set_text ( hlpSS.str().c_str(),
1444  "ProgressSection",
1445  settings->htmlReportLineProgress,
1446  1,
1447  1,
1448  1 );
1449  settings->htmlReportLineProgress += 1;
1450  rvapi_flush ( );
1451  }
1452 
1453  exit ( -1 );
1454  }
1455 
1456  //============================ Re-read in structure 2
1457  delete pattStr2;
1458  shSpacingObj2 = shSpacingObj1;
1459 
1460  fileType = checkFileType ( structFiles.at(1) );
1461  pattStr2 = new ProSHADE_data ();
1462  if ( fileType == 2 )
1463  {
1464  pattStr2->getDensityMapFromMAP ( this->structFiles.at(1),
1465  &shSpacingObj2,
1466  this->mapResolution,
1467  &this->bandwidth.at(1),
1468  &this->theta.at(1),
1469  &this->phi.at(1),
1470  &this->glIntegOrder.at(1),
1471  &this->extraSpace,
1472  settings->mapResDefault,
1473  settings->rotChangeDefault,
1474  settings,
1475  settings->overlayDefaults );
1476  }
1477  else if ( fileType == 1 )
1478  {
1479  pattStr2->getDensityMapFromPDB ( this->structFiles.at(1),
1480  &shSpacingObj2,
1481  this->mapResolution,
1482  &this->bandwidth.at(1),
1483  &this->theta.at(1),
1484  &this->phi.at(1),
1485  &this->glIntegOrder.at(1),
1486  &this->extraSpace,
1487  settings->mapResDefault,
1488  settings,
1489  this->bFactorValue,
1490  this->firstLineCOM,
1491  settings->overlayDefaults );
1492  }
1493  else
1494  {
1495  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(1) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1496 
1497  if ( settings->htmlReport )
1498  {
1499  std::stringstream hlpSS;
1500  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(1) << " ." << "</font>";
1501  rvapi_set_text ( hlpSS.str().c_str(),
1502  "ProgressSection",
1503  settings->htmlReportLineProgress,
1504  1,
1505  1,
1506  1 );
1507  settings->htmlReportLineProgress += 1;
1508  rvapi_flush ( );
1509  }
1510 
1511  exit ( -1 );
1512  }
1513  }
1514 
1515  if ( settings->htmlReport )
1516  {
1517  std::stringstream hlpSS;
1518  hlpSS << "<font color=\"green\">" << "Loaded structures in Patterson mode for rotation computation." << "</font>";
1519  rvapi_set_text ( hlpSS.str().c_str(),
1520  "ProgressSection",
1521  settings->htmlReportLineProgress,
1522  1,
1523  1,
1524  1 );
1525  settings->htmlReportLineProgress += 1;
1526  rvapi_flush ( );
1527  }
1528 
1529  //==================================== Remove models (if any) from the map
1530  if ( settings->deleteModels.size() > 0 )
1531  {
1532  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( settings->deleteModels.size() ); iter++ )
1533  {
1534  pattStr1->deleteModel ( settings->deleteModels.at(iter) );
1535  }
1536  }
1537 
1538  //==================================== Remove phase and get spherical coordinatse
1539  pattStr1->normaliseMap ( settings );
1540  pattStr1->removePhaseFromMapOverlay ( this->alpha,
1541  this->bFactorChange,
1542  settings );
1543 
1544  pattStr1->mapPhaselessToSphere ( settings,
1545  this->theta.at(0),
1546  this->phi.at(0),
1547  shSpacingObj1,
1548  this->manualShells );
1549 
1550  pattStr1->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
1551  if ( settings->verbose > 1 )
1552  {
1553  std::cout << ">> Structure 1 spherical harmonics computed." << std::endl;
1554  }
1555 
1556  pattStr2->normaliseMap ( settings );
1557  pattStr2->removePhaseFromMapOverlay ( this->alpha,
1558  this->bFactorChange,
1559  settings );
1560 
1561  pattStr2->mapPhaselessToSphere ( settings,
1562  this->theta.at(1),
1563  this->phi.at(1),
1564  shSpacingObj2,
1565  this->manualShells );
1566 
1567  pattStr2->getSphericalHarmonicsCoeffs ( this->bandwidth.at(1), settings );
1568  if ( settings->verbose > 1 )
1569  {
1570  std::cout << ">> Structure 2 spherical harmonics computed." << std::endl;
1571  }
1572 
1573  if ( settings->htmlReport )
1574  {
1575  std::stringstream hlpSS;
1576  hlpSS << "<font color=\"green\">" << "Spherical harmonics for Patterson maps computed." << "</font>";
1577  rvapi_set_text ( hlpSS.str().c_str(),
1578  "ProgressSection",
1579  settings->htmlReportLineProgress,
1580  1,
1581  1,
1582  1 );
1583  settings->htmlReportLineProgress += 1;
1584  rvapi_flush ( );
1585  }
1586 
1587  //==================================== Get the Compare_Pairwise object to compute E matrices and find the maximum SOFT peak
1588  ProSHADE_comparePairwise* cmpObj = new ProSHADE_comparePairwise ( pattStr1,
1589  pattStr2,
1590  this->mPower,
1591  this->ignoreLs,
1592  std::max ( this->glIntegOrder.at(0),
1593  this->glIntegOrder.at(1) ),
1594  settings );
1595 
1596  //==================================== Get the angles
1597  cmpObj->precomputeTrSigmaDescriptor ( );
1598  if ( settings->verbose > 2 )
1599  {
1600  std::cout << ">>>>> E matrices constructed." << std::endl;
1601  }
1602 
1603  cmpObj->getSO3InverseMap ( settings );
1604  if ( settings->verbose > 2 )
1605  {
1606  std::cout << ">>>>> Inverse SO(3) Fourier transform map obtained." << std::endl;
1607  }
1608 
1609  if ( settings->htmlReport )
1610  {
1611  std::stringstream hlpSS;
1612  hlpSS << "<font color=\"green\">" << "Rotation function map computed." << "</font>";
1613  rvapi_set_text ( hlpSS.str().c_str(),
1614  "ProgressSection",
1615  settings->htmlReportLineProgress,
1616  1,
1617  1,
1618  1 );
1619  settings->htmlReportLineProgress += 1;
1620  rvapi_flush ( );
1621  }
1622 
1623  double pattCorrelation = 0.0;
1624 
1625  std::array<double,3> euAngs = cmpObj->getEulerAngles ( settings, &pattCorrelation );
1626 
1627  if ( settings->verbose > 1 )
1628  {
1629  std::cout << ">> Patterson map based rotation angles obtained ( " << euAngs[0] << ", " << euAngs[1] << " and " << euAngs[2] << " )." << std::endl;
1630  }
1631 
1632  if ( settings->htmlReport )
1633  {
1634  std::stringstream hlpSS;
1635  hlpSS << "<font color=\"green\">" << "Found optimal overlay rotation angles." << "</font>";
1636  rvapi_set_text ( hlpSS.str().c_str(),
1637  "ProgressSection",
1638  settings->htmlReportLineProgress,
1639  1,
1640  1,
1641  1 );
1642  settings->htmlReportLineProgress += 1;
1643  rvapi_flush ( );
1644  }
1645 
1646  if ( settings->htmlReport )
1647  {
1648  //==================================== Create section
1649  rvapi_add_section ( "RotationSection",
1650  "Rotation information",
1651  "body",
1652  settings->htmlReportLine,
1653  0,
1654  1,
1655  1,
1656  false );
1657  settings->htmlReportLine += 1;
1658 
1659  rvapi_flush ( );
1660 
1661  std::stringstream hlpSS;
1662  hlpSS << "<pre>" << "Rotation in Euler Angles: ";
1663  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1664  for ( int iter = 0; iter < hlpIt; iter++ )
1665  {
1666  hlpSS << ".";
1667  }
1668 
1669  std::stringstream hlpSS2;
1670  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[0] * 1000.0 ) / 1000.0;
1671  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1672  hlpSS << " " << hlpSS2.str() << " ";
1673  hlpSS2.str( std::string ( ) );
1674  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[1] * 1000.0 ) / 1000.0;
1675  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1676  hlpSS << hlpSS2.str() << " ";
1677  hlpSS2.str( std::string ( ) );
1678  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[2] * 1000.0 ) / 1000.0;
1679  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1680  hlpSS << hlpSS2.str() << "</pre>";
1681 
1682  rvapi_set_text ( hlpSS.str().c_str(),
1683  "RotationSection",
1684  0,
1685  1,
1686  1,
1687  1 );
1688 
1689  hlpSS.str ( std::string ( ) );
1690  hlpSS << "<pre>" << "Rotation in Angle-Axis: ";
1691  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1692  for ( int iter = 0; iter < hlpIt; iter++ )
1693  {
1694  hlpSS << ".";
1695  }
1696 
1697  double X, Y, Z, Ang;
1698  ProSHADE_internal_misc::getAxisAngleFromEuler ( euAngs[0], euAngs[1], euAngs[2], &X, &Y, &Z, &Ang, false );
1699 
1700  hlpSS2.str( std::string ( ) );
1701  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( X * 1000.0 ) / 1000.0;
1702  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1703  hlpSS << " " << hlpSS2.str() << " ";
1704  hlpSS2.str( std::string ( ) );
1705  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Y * 1000.0 ) / 1000.0;
1706  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1707  hlpSS << hlpSS2.str() << " ";
1708  hlpSS2.str( std::string ( ) );
1709  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Z * 1000.0 ) / 1000.0;
1710  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1711  hlpSS << hlpSS2.str() << " ";
1712  hlpSS2.str( std::string ( ) );
1713  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Ang * 1000.0 ) / 1000.0;
1714  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1715  hlpSS << hlpSS2.str() << "</pre>";
1716 
1717  rvapi_set_text ( hlpSS.str().c_str(),
1718  "RotationSection",
1719  1,
1720  1,
1721  1,
1722  1 );
1723 
1724  std::array<double,5> arrHlp;
1725  arrHlp[0] = Ang;
1726  arrHlp[1] = X;
1727  arrHlp[2] = Y;
1728  arrHlp[3] = Z;
1729  arrHlp[4] = 0.0;
1730  std::vector< std::vector<double> > rMat = ProSHADE_internal_misc::getMatrixFromAxisAngle ( arrHlp );
1731 
1732  hlpSS.str ( std::string ( ) );
1733  hlpSS << "<pre>" << "Rotation as Rotation Matrix: ";
1734  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1735  for ( int iter = 0; iter < hlpIt; iter++ )
1736  {
1737  hlpSS << ".";
1738  }
1739 
1740  hlpSS2.str( std::string ( ) );
1741  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(0) * 1000.0 ) / 1000.0;
1742  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1743  hlpSS << " " << hlpSS2.str() << " ";
1744  hlpSS2.str( std::string ( ) );
1745  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(1) * 1000.0 ) / 1000.0;
1746  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1747  hlpSS << hlpSS2.str() << " ";
1748  hlpSS2.str( std::string ( ) );
1749  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(2) * 1000.0 ) / 1000.0;
1750  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1751  hlpSS << hlpSS2.str() << "</pre>";
1752 
1753  rvapi_set_text ( hlpSS.str().c_str(),
1754  "RotationSection",
1755  2,
1756  1,
1757  1,
1758  1 );
1759 
1760  hlpSS.str ( std::string ( ) );
1761  hlpSS << "<pre>" << " ... ";
1762  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1763  for ( int iter = 0; iter < hlpIt; iter++ )
1764  {
1765  hlpSS << " ";
1766  }
1767 
1768  hlpSS2.str( std::string ( ) );
1769  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(0) * 1000.0 ) / 1000.0;
1770  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1771  hlpSS << " " << hlpSS2.str() << " ";
1772  hlpSS2.str( std::string ( ) );
1773  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(1) * 1000.0 ) / 1000.0;
1774  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1775  hlpSS << hlpSS2.str() << " ";
1776  hlpSS2.str( std::string ( ) );
1777  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(2) * 1000.0 ) / 1000.0;
1778  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1779  hlpSS << hlpSS2.str() << "</pre>";
1780 
1781  rvapi_set_text ( hlpSS.str().c_str(),
1782  "RotationSection",
1783  3,
1784  1,
1785  1,
1786  1 );
1787 
1788  hlpSS.str ( std::string ( ) );
1789  hlpSS << "<pre>" << " ... ";
1790  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1791  for ( int iter = 0; iter < hlpIt; iter++ )
1792  {
1793  hlpSS << " ";
1794  }
1795 
1796  hlpSS2.str( std::string ( ) );
1797  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(0) * 1000.0 ) / 1000.0;
1798  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1799  hlpSS << " " << hlpSS2.str() << " ";
1800  hlpSS2.str( std::string ( ) );
1801  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(1) * 1000.0 ) / 1000.0;
1802  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1803  hlpSS << hlpSS2.str() << " ";
1804  hlpSS2.str( std::string ( ) );
1805  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(2) * 1000.0 ) / 1000.0;
1806  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1807  hlpSS << hlpSS2.str() << "</pre>";
1808 
1809  rvapi_set_text ( hlpSS.str().c_str(),
1810  "RotationSection",
1811  4,
1812  1,
1813  1,
1814  1 );
1815 
1816  rvapi_flush ( );
1817  }
1818 
1819  //==================================== Free memory
1820  delete cmpObj;
1821  delete pattStr1;
1822  delete pattStr2;
1823 
1824  //==================================== Prepare vatiables
1825  std::array<double,4> translationVec;
1826  double xMapMov = 0.0;
1827  double yMapMov = 0.0;
1828  double zMapMov = 0.0;
1829  double xMapTotMov = 0.0;
1830  double yMapTotMov = 0.0;
1831  double zMapTotMov = 0.0;
1832 
1833  while ( true )
1834  {
1835  //================================ Load structure 2 with phases
1836  pattStr2 = new ProSHADE_data ();
1837  fileType = checkFileType ( structFiles.at(1) );
1838  if ( fileType == 2 )
1839  {
1840  pattStr2->getDensityMapFromMAP ( this->structFiles.at(1),
1841  &shSpacingObj2,
1842  this->mapResolution,
1843  &this->bandwidth.at(1),
1844  &this->theta.at(1),
1845  &this->phi.at(1),
1846  &this->glIntegOrder.at(1),
1847  &this->extraSpace,
1848  settings->mapResDefault,
1849  settings->rotChangeDefault,
1850  settings,
1851  settings->overlayDefaults );
1852  }
1853  else if ( fileType == 1 )
1854  {
1855  pattStr2->getDensityMapFromPDB ( this->structFiles.at(1),
1856  &shSpacingObj2,
1857  this->mapResolution,
1858  &this->bandwidth.at(1),
1859  &this->theta.at(1),
1860  &this->phi.at(1),
1861  &this->glIntegOrder.at(1),
1862  &this->extraSpace,
1863  settings->mapResDefault,
1864  settings,
1865  this->bFactorValue,
1866  this->firstLineCOM,
1867  settings->overlayDefaults );
1868  }
1869  else
1870  {
1871  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(1) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1872 
1873  if ( settings->htmlReport )
1874  {
1875  std::stringstream hlpSS;
1876  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(1) << " ." << "</font>";
1877  rvapi_set_text ( hlpSS.str().c_str(),
1878  "ProgressSection",
1879  settings->htmlReportLineProgress,
1880  1,
1881  1,
1882  1 );
1883  settings->htmlReportLineProgress += 1;
1884  rvapi_flush ( );
1885  }
1886 
1887  exit ( -1 );
1888  }
1889 
1890  pattStr2->normaliseMap ( settings );
1891  std::array<double,4> str2CandD = pattStr2->getCOMandDist ( settings );
1892  pattStr2->keepPhaseInMap ( this->alpha,
1893  this->bFactorChange,
1894  &this->bandwidth.at(1),
1895  &this->theta.at(1),
1896  &this->phi.at(1),
1897  &this->glIntegOrder.at(1),
1898  settings,
1899  this->useCOM,
1900  settings->noIQRsFromMap,
1901  settings->verbose,
1902  settings->clearMapData,
1903  settings->rotChangeDefault,
1904  settings->overlayDefaults,
1905  settings->maskBlurFactor,
1906  settings->maskBlurFactorGiven );
1907 
1908  pattStr2->mapPhaselessToSphere ( settings,
1909  this->theta.at(1),
1910  this->phi.at(1),
1911  shSpacingObj2,
1912  this->manualShells,
1913  true,
1914  true );
1915 
1916  pattStr2->getSphericalHarmonicsCoeffs ( this->bandwidth.at(1), settings );
1917  if ( settings->verbose > 1 )
1918  {
1919  std::cout << ">> Structure 2 spherical harmonics computed with phase." << std::endl;
1920  }
1921 
1922  //================================ Read in structure 1, this time with phases
1923  fileType = checkFileType ( structFiles.at(0) );
1924  pattStr1 = new ProSHADE_data ();
1925 
1926  if ( fileType == 2 )
1927  {
1928  pattStr1->getDensityMapFromMAP ( this->structFiles.at(0),
1929  &shSpacingObj1,
1930  this->mapResolution,
1931  &this->bandwidth.at(0),
1932  &this->theta.at(0),
1933  &this->phi.at(0),
1934  &this->glIntegOrder.at(0),
1935  &this->extraSpace,
1936  settings->mapResDefault,
1937  settings->rotChangeDefault,
1938  settings,
1939  settings->overlayDefaults );
1940  }
1941  else if ( fileType == 1 )
1942  {
1943  pattStr1->getDensityMapFromPDB ( this->structFiles.at(0),
1944  &shSpacingObj1,
1945  this->mapResolution,
1946  &this->bandwidth.at(0),
1947  &this->theta.at(0),
1948  &this->phi.at(0),
1949  &this->glIntegOrder.at(0),
1950  &this->extraSpace,
1951  settings->mapResDefault,
1952  settings,
1953  this->bFactorValue,
1954  this->firstLineCOM,
1955  settings->overlayDefaults );
1956  }
1957  else
1958  {
1959  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
1960 
1961  if ( settings->htmlReport )
1962  {
1963  std::stringstream hlpSS;
1964  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(0) << " ." << "</font>";
1965  rvapi_set_text ( hlpSS.str().c_str(),
1966  "ProgressSection",
1967  settings->htmlReportLineProgress,
1968  1,
1969  1,
1970  1 );
1971  settings->htmlReportLineProgress += 1;
1972  rvapi_flush ( );
1973  }
1974 
1975  exit ( -1 );
1976  }
1977 
1978  pattStr1->normaliseMap ( settings );
1979  pattStr1->keepPhaseInMap ( this->alpha,
1980  this->bFactorChange,
1981  &this->bandwidth.at(0),
1982  &this->theta.at(0),
1983  &this->phi.at(0),
1984  &this->glIntegOrder.at(0),
1985  settings,
1986  this->useCOM,
1987  settings->noIQRsFromMap,
1988  settings->verbose,
1989  settings->clearMapData,
1990  settings->rotChangeDefault,
1991  settings->overlayDefaults,
1992  settings->maskBlurFactor,
1993  settings->maskBlurFactorGiven );
1994 
1995  pattStr1->mapPhaselessToSphere ( settings,
1996  this->theta.at(0),
1997  this->phi.at(0),
1998  shSpacingObj1,
1999  this->manualShells,
2000  true,
2001  true );
2002 
2003  pattStr1->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2004  if ( settings->verbose > 1 )
2005  {
2006  std::cout << ">> Structure 1 spherical harmonics computed with phase." << std::endl;
2007  }
2008 
2009  if ( settings->htmlReport )
2010  {
2011  std::stringstream hlpSS;
2012  hlpSS << "<font color=\"green\">" << "Spherical harmonics computed for translation computation (with phases)." << "</font>";
2013  rvapi_set_text ( hlpSS.str().c_str(),
2014  "ProgressSection",
2015  settings->htmlReportLineProgress,
2016  1,
2017  1,
2018  1 );
2019  settings->htmlReportLineProgress += 1;
2020  rvapi_flush ( );
2021  }
2022 
2023  if ( settings->htmlReport )
2024  {
2025  std::stringstream hlpSS;
2026  hlpSS << "<pre>" << "Rotation about coordinate location (A): ";
2027  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2028  for ( int iter = 0; iter < hlpIt; iter++ )
2029  {
2030  hlpSS << ".";
2031  }
2032 
2033  std::stringstream hlpSS2;
2034  double pos = ( ( pattStr2->_xFrom * pattStr2->_xSamplingRate ) + pattStr2->_xRange ) / 2.0;
2035  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2036  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2037  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2038  hlpSS << " " << hlpSS2.str() << " ";
2039  hlpSS2.str( std::string ( ) );
2040  pos = ( ( pattStr2->_yFrom * pattStr2->_ySamplingRate ) + pattStr2->_yRange ) / 2.0;
2041  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2042  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2043  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2044  hlpSS << hlpSS2.str() << " ";
2045  hlpSS2.str( std::string ( ) );
2046  pos = ( ( pattStr2->_zFrom * pattStr2->_zSamplingRate ) + pattStr2->_zRange ) / 2.0;
2047  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2048  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2049  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2050  hlpSS << hlpSS2.str() << "</pre>";
2051 
2052  rvapi_set_text ( hlpSS.str().c_str(),
2053  "RotationSection",
2054  5,
2055  1,
2056  1,
2057  1 );
2058  rvapi_flush ( );
2059  }
2060 
2061  //================================ Find rotation angles
2062  cmpObj = new ProSHADE_comparePairwise ( pattStr2,
2063  pattStr2,
2064  this->mPower,
2065  this->ignoreLs,
2066  std::max ( this->glIntegOrder.at(0),
2067  this->glIntegOrder.at(1) ),
2068  settings );
2069 
2070  //================================ Find 'opposite' Euler angles and set them
2071  // Get mat from Euler
2072  double mat22 = cos ( euAngs[1] );
2073  double mat02 = -sin ( euAngs[1] ) * cos ( euAngs[2] );
2074  double mat12 = sin ( euAngs[1] ) * sin ( euAngs[2] );
2075  double mat20 = cos ( euAngs[0] ) * sin ( euAngs[1] );
2076  double mat21 = sin ( euAngs[0] ) * sin ( euAngs[1] );
2077 
2078  // Transpose
2079  double rMat02 = mat20;
2080  double rMat20 = mat02;
2081  double rMat21 = mat12;
2082  double rMat12 = mat21;
2083 
2084  // Get Euler from map
2085  euAngs[0] = atan2 ( rMat21, rMat20 );
2086  euAngs[1] = acos ( mat22 );
2087  euAngs[2] = atan2 ( rMat12, -rMat02 );
2088 
2089  if ( euAngs[0] < 0.0 ) { euAngs[0]= 2.0 * M_PI + euAngs[0]; }
2090  if ( euAngs[1] < 0.0 ) { euAngs[1]= M_PI + euAngs[1]; }
2091  if ( euAngs[2] < 0.0 ) { euAngs[2]= 2.0 * M_PI + euAngs[2]; }
2092 
2093  cmpObj->setEulerAngles ( euAngs[0], euAngs[1], euAngs[2] );
2094 
2095  //================================ Rotate by the Euler
2096  cmpObj->rotateStructure ( pattStr2,
2097  settings,
2098  settings->clearMapFile,
2099  settings->verbose,
2100  settings->axisOrder,
2101  true );
2102 
2103  //================================ Find optimal translation
2104  ProSHADE_data str1Copy = ProSHADE_data ( pattStr1 );
2105  translationVec = cmpObj->getTranslationFunctionMap ( &str1Copy, pattStr2, &xMapMov, &yMapMov, &zMapMov );
2106 
2107  if ( settings->htmlReport )
2108  {
2109  std::stringstream hlpSS;
2110  hlpSS << "<font color=\"green\">" << "Translation computed." << "</font>";
2111  rvapi_set_text ( hlpSS.str().c_str(),
2112  "ProgressSection",
2113  settings->htmlReportLineProgress,
2114  1,
2115  1,
2116  1 );
2117  settings->htmlReportLineProgress += 1;
2118  rvapi_flush ( );
2119  }
2120 
2121  if ( settings->htmlReport )
2122  {
2123  //==================================== Create section
2124  rvapi_add_section ( "TranslationSection",
2125  "Translation information",
2126  "body",
2127  settings->htmlReportLine,
2128  0,
2129  1,
2130  1,
2131  false );
2132  settings->htmlReportLine += 1;
2133 
2134  rvapi_flush ( );
2135 
2136  std::stringstream hlpSS;
2137  hlpSS << "<pre>" << "Translation from lowest indices (A): ";
2138  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2139  for ( int iter = 0; iter < hlpIt; iter++ )
2140  {
2141  hlpSS << ".";
2142  }
2143 
2144  std::stringstream hlpSS2;
2145  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[0] * 1000.0 ) / 1000.0;
2146  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2147  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2148  hlpSS << " " << hlpSS2.str() << " ";
2149  hlpSS2.str( std::string ( ) );
2150  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[1] * 1000.0 ) / 1000.0;
2151  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2152  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2153  hlpSS << hlpSS2.str() << " ";
2154  hlpSS2.str( std::string ( ) );
2155  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[2] * 1000.0 ) / 1000.0;
2156  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2157  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2158  hlpSS << hlpSS2.str() << "</pre>";
2159 
2160  rvapi_set_text ( hlpSS.str().c_str(),
2161  "TranslationSection",
2162  0,
2163  1,
2164  1,
2165  1 );
2166 
2167  hlpSS.str( std::string () );
2168  hlpSS << "<pre>" << "Translation from lowest indices (index): ";
2169  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2170  for ( int iter = 0; iter < hlpIt; iter++ )
2171  {
2172  hlpSS << ".";
2173  }
2174 
2175  hlpSS2.str( std::string ( ) );
2176  int pos = static_cast<int> ( ( -translationVec[0] / pattStr2->_xSamplingRate ) );
2177  hlpSS2 << std::showpos << pos;
2178  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2179  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2180  hlpSS << " " << hlpSS2.str() << " ";
2181  hlpSS2.str( std::string ( ) );
2182  pos = static_cast<int> ( ( -translationVec[1] / pattStr2->_ySamplingRate ) );
2183  hlpSS2 << std::showpos << pos;
2184  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2185  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2186  hlpSS << hlpSS2.str() << " ";
2187  hlpSS2.str( std::string ( ) );
2188  pos = static_cast<int> ( ( -translationVec[2] / pattStr2->_zSamplingRate ) );
2189  hlpSS2 << std::showpos << pos;
2190  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2191  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2192  hlpSS << hlpSS2.str() << "</pre>";
2193 
2194  rvapi_set_text ( hlpSS.str().c_str(),
2195  "TranslationSection",
2196  1,
2197  1,
2198  1,
2199  1 );
2200 
2201  hlpSS.str ( std::string ( ) );
2202  hlpSS << "<pre>" << "Shift for visualisation (A): ";
2203  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2204  for ( int iter = 0; iter < hlpIt; iter++ )
2205  {
2206  hlpSS << ".";
2207  }
2208 
2209  hlpSS2.str ( std::string ( ) );
2210  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (xMapTotMov * pattStr2->_xSamplingRate) * 1000.0 ) / 1000.0;
2211  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2212  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2213  hlpSS << " " << hlpSS2.str() << " ";
2214  hlpSS2.str( std::string ( ) );
2215  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (yMapTotMov * pattStr2->_ySamplingRate) * 1000.0 ) / 1000.0;
2216  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2217  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2218  hlpSS << hlpSS2.str() << " ";
2219  hlpSS2.str( std::string ( ) );
2220  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (zMapTotMov * pattStr2->_zSamplingRate) * 1000.0 ) / 1000.0;
2221  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2222  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2223  hlpSS << hlpSS2.str() << "</pre>";
2224 
2225  rvapi_set_text ( hlpSS.str().c_str(),
2226  "TranslationSection",
2227  2,
2228  1,
2229  1,
2230  1 );
2231 
2232  hlpSS.str( std::string () );
2233  hlpSS << "<pre>" << "Shift for visualisation (index): ";
2234  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2235  for ( int iter = 0; iter < hlpIt; iter++ )
2236  {
2237  hlpSS << ".";
2238  }
2239 
2240  hlpSS2.str( std::string ( ) );
2241  pos = static_cast<int> ( xMapTotMov );
2242  hlpSS2 << std::showpos << pos;
2243  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2244  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2245  hlpSS << " " << hlpSS2.str() << " ";
2246  hlpSS2.str( std::string ( ) );
2247  pos = static_cast<int> ( yMapTotMov );
2248  hlpSS2 << std::showpos << pos;
2249  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2250  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2251  hlpSS << hlpSS2.str() << " ";
2252  hlpSS2.str( std::string ( ) );
2253  pos = static_cast<int> ( zMapTotMov );
2254  hlpSS2 << std::showpos << pos;
2255  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2256  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2257  hlpSS << hlpSS2.str() << "</pre>";
2258 
2259  rvapi_set_text ( hlpSS.str().c_str(),
2260  "TranslationSection",
2261  3,
2262  1,
2263  1,
2264  1 );
2265 
2266 
2267  rvapi_flush ( );
2268  }
2269 
2270  if ( settings->verbose > 2 )
2271  {
2272  std::cout << ">>>>> Translation vector obtained from translation function ( " << translationVec[0] << ", " << translationVec[1] << " and " << translationVec[2] << " )." << std::endl;
2273  }
2274 
2275  //================================ No need to repeated attempts, this is part of mapSearch
2276  if ( settings->dbDistOverlay )
2277  {
2278  break;
2279  }
2280  else
2281  {
2282  break;
2283  if ( settings->extraSpace == -777.7 )
2284  {
2285  settings->extraSpace = 0.0;
2286  this->extraSpace = 0.0;
2287  }
2288 
2289  double transVecLen = sqrt ( pow ( translationVec[0], 2.0 ) + pow ( translationVec[1], 2.0 ) + pow ( translationVec[2], 2.0 ) );
2290  double str2COMVecLen = str2CandD[3] + settings->extraSpace;
2291 
2292  //============================ If translation is larger than 20% of the cell size, increase cell size and try again.
2293  if ( transVecLen > ( 0.2 * str2COMVecLen ) )
2294  {
2295  std::cout << "!!! ProSHADE WARNING !!! The required translation vector is larger than 20% of the static structure cell size. This is likely to result in translation artefacts - increasing the cell size and trying again." << std::endl;
2296 
2297  //======================== Add the extra space to settings and internal value
2298  this->extraSpace += 20.0;
2299  settings->extraSpace += 20.0;
2300 
2301  //======================== Free memory
2302  delete cmpObj;
2303  delete pattStr1;
2304  delete pattStr2;
2305  }
2306  else
2307  {
2308  //======================== Translation is small enough
2309  break;
2310  }
2311  }
2312  }
2313 
2314  //==================================== Translate map
2315  pattStr2->translateMap ( -translationVec[0],
2316  -translationVec[1],
2317  -translationVec[2] );
2318 
2319  if ( settings->verbose > 0 )
2320  {
2321  std::cout << "Resulting structure translated." << std::endl;
2322  }
2323 
2324  //==================================== Re-cut and re-sample str2
2325  if ( settings->resizeMovingStructure )
2326  {
2327  pattStr2->matchMap ( pattStr1 );
2328  }
2329 
2330  //==================================== Write the matched map and pdb outputs
2331  if ( !pattStr2->_fromPDB )
2332  {
2333  if ( !wasMapNameGiven )
2334  {
2335  std::stringstream strStr;
2336  strStr << settings->clearMapFile << ".map";
2337  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2338  }
2339  else
2340  {
2341  if ( ( settings->clearMapFile.find ( ".map" ) != std::string::npos ) || ( settings->clearMapFile.find ( ".mrc" ) != std::string::npos ) )
2342  {
2343  pattStr2->writeMap ( settings->clearMapFile, pattStr2->_densityMapCor );
2344  }
2345  else
2346  {
2347  if ( settings->clearMapFile.find ( ".pdb" ) != std::string::npos )
2348  {
2349  std::stringstream strStr;
2350  strStr << settings->clearMapFile << "_errOut.map";
2351  std::cerr << "!!! ProSHADE ERROR !!! Requested to output PDB file for MAP output. ProSHADE cannot convert MAP to PDB - outputting map into file " << strStr.str() << " ." << std::endl;
2352  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2353  }
2354  else
2355  {
2356  std::stringstream strStr;
2357  strStr << settings->clearMapFile << ".map";
2358  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2359  }
2360  }
2361  }
2362  }
2363  else
2364  {
2365  if ( !wasMapNameGiven )
2366  {
2367  std::stringstream strStr;
2368  strStr << settings->clearMapFile << ".map";
2369  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2370 
2371  strStr.str ( std::string ( ) );
2372  strStr.clear();
2373  strStr << settings->clearMapFile << ".pdb";
2374  pattStr2->writePDB ( this->structFiles.at(1),
2375  strStr.str(),
2376  euAngs[0],
2377  euAngs[1],
2378  euAngs[2],
2379  translationVec[0] + xMapMov,
2380  translationVec[1] + yMapMov,
2381  translationVec[2] + zMapMov );
2382  }
2383  else
2384  {
2385  if ( ( settings->clearMapFile.find ( ".map" ) != std::string::npos ) || ( settings->clearMapFile.find ( ".mrc" ) != std::string::npos ) )
2386  {
2387  pattStr2->writeMap ( settings->clearMapFile, pattStr2->_densityMapCor );
2388  }
2389  else
2390  {
2391  if ( settings->clearMapFile.find ( ".pdb" ) != std::string::npos )
2392  {
2393  pattStr2->writePDB ( this->structFiles.at(1),
2394  settings->clearMapFile,
2395  euAngs[0],
2396  euAngs[1],
2397  euAngs[2],
2398  translationVec[0] + xMapMov,
2399  translationVec[1] + yMapMov,
2400  translationVec[2] + zMapMov );
2401  }
2402  else
2403  {
2404  std::stringstream strStr;
2405  strStr << settings->clearMapFile << ".map";
2406  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2407  strStr.str ( std::string ( ) );
2408  strStr.clear();
2409  strStr << settings->clearMapFile << ".pdb";
2410  pattStr2->writePDB ( this->structFiles.at(1),
2411  strStr.str(),
2412  euAngs[0],
2413  euAngs[1],
2414  euAngs[2],
2415  translationVec[0] + xMapMov,
2416  translationVec[1] + yMapMov,
2417  translationVec[2] + zMapMov );
2418  }
2419  }
2420  }
2421  }
2422 
2423  if ( settings->htmlReport )
2424  {
2425  std::stringstream hlpSS;
2426  hlpSS << "<font color=\"green\">" << "Overlay structure saved to " << settings->clearMapFile << " ." << "</font>";
2427  rvapi_set_text ( hlpSS.str().c_str(),
2428  "ProgressSection",
2429  settings->htmlReportLineProgress,
2430  1,
2431  1,
2432  1 );
2433  settings->htmlReportLineProgress += 1;
2434  rvapi_flush ( );
2435  }
2436 
2437  //==================================== Clear memory
2438  delete cmpObj;
2439  delete pattStr2;
2440  delete pattStr1;
2441 
2442  //==================================== End report
2443  if ( settings->verbose > 0 )
2444  {
2445  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2446  std::cout << "| COMPLETED |" << std::endl;
2447  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2448  }
2449 
2450  if ( settings->htmlReport )
2451  {
2452  std::stringstream hlpSS;
2453  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
2454  rvapi_set_text ( hlpSS.str().c_str(),
2455  "ProgressSection",
2456  settings->htmlReportLineProgress,
2457  1,
2458  1,
2459  1 );
2460  settings->htmlReportLineProgress += 1;
2461  rvapi_flush ( );
2462  }
2463 
2464  if ( settings->verbose > 0 )
2465  {
2466  std::cout << "Rotated structure written to file: " << settings->clearMapFile << " as required." << std::endl << std::endl;
2467  }
2468 
2469  if ( settings->htmlReport )
2470  {
2471  //==================================== Create section
2472  rvapi_add_section ( "ResultsSection",
2473  "Results",
2474  "body",
2475  settings->htmlReportLine,
2476  0,
2477  1,
2478  1,
2479  true );
2480  settings->htmlReportLine += 1;
2481 
2482  std::stringstream hlpSS;
2483  hlpSS << "<pre><b>" << "Patterson maps optimal rotation (Euler angles): ";
2484  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2485  for ( int iter = 0; iter < hlpIt; iter++ )
2486  {
2487  hlpSS << ".";
2488  }
2489 
2490  std::stringstream hlpSS2;
2491  double pos = euAngs[0];
2492  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2493  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2494  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2495  hlpSS << " " << hlpSS2.str() << " ";
2496 
2497  hlpSS2.str( std::string ( ) );
2498  pos = euAngs[1];
2499  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2500  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2501  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2502  hlpSS << hlpSS2.str() << " ";
2503 
2504  hlpSS2.str( std::string ( ) );
2505  pos = euAngs[2];
2506  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2507  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2508  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2509  hlpSS << hlpSS2.str() << "</b></pre>";
2510 
2511  rvapi_set_text ( hlpSS.str().c_str(),
2512  "ResultsSection",
2513  0,
2514  0,
2515  1,
2516  1 );
2517 
2518  hlpSS.str ( std::string ( ) );
2519  hlpSS << "<pre><b>" << "Phased maps optimal translation (A): ";
2520  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2521  for ( int iter = 0; iter < hlpIt; iter++ )
2522  {
2523  hlpSS << ".";
2524  }
2525 
2526  hlpSS2.str( std::string ( ) );
2527  pos = translationVec[0];
2528  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2529  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2530  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2531  hlpSS << " " << hlpSS2.str() << " ";
2532 
2533  hlpSS2.str( std::string ( ) );
2534  pos = translationVec[1];
2535  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2536  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2537  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2538  hlpSS << hlpSS2.str() << " ";
2539 
2540  hlpSS2.str( std::string ( ) );
2541  pos = translationVec[2];
2542  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2543  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2544  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2545  hlpSS << hlpSS2.str() << "</b></pre>";
2546 
2547  rvapi_set_text ( hlpSS.str().c_str(),
2548  "ResultsSection",
2549  1,
2550  0,
2551  1,
2552  1 );
2553 
2554  hlpSS.str ( std::string ( ) );
2555  hlpSS << "<pre><b>" << "Correlation between rotated Patterson maps: ";
2556  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2557  for ( int iter = 0; iter < hlpIt; iter++ )
2558  {
2559  hlpSS << ".";
2560  }
2561 
2562  hlpSS2.str( std::string ( ) );
2563  pos = pattCorrelation;
2564  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2565  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2566  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2567  hlpSS << " " << hlpSS2.str() << "</b></pre>";
2568 
2569  rvapi_set_text ( hlpSS.str().c_str(),
2570  "ResultsSection",
2571  2,
2572  0,
2573  1,
2574  1 );
2575 
2576  hlpSS.str ( std::string ( ) );
2577  hlpSS << "<pre><b>" << "Correlation between translated maps with phases: ";
2578  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2579  for ( int iter = 0; iter < hlpIt; iter++ )
2580  {
2581  hlpSS << ".";
2582  }
2583 
2584  hlpSS2.str( std::string ( ) );
2585  pos = translationVec[3];
2586  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2587  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2588  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2589  hlpSS << " " << hlpSS2.str() << "</b></pre>";
2590 
2591  rvapi_set_text ( hlpSS.str().c_str(),
2592  "ResultsSection",
2593  3,
2594  0,
2595  1,
2596  1 );
2597 
2598  rvapi_flush ( );
2599  }
2600 
2601  //==================================== Done
2602  return ;
2603  }
2604 
2605  //======================================== In the case of simple rotation, do it instead
2606  if ( settings->taskToPerform == ProSHADE::RotateMap )
2607  {
2608  //==================================== Sanity checks
2609  if ( settings->structFiles.size() != 1 )
2610  {
2611  std::cerr << "!!! ProSHADE ERROR !!! No files/too many files detected for map rotation mode. Please supply a single map file using the -f or -i command line options. Terminating..." << std::endl;
2612  exit ( -1 );
2613  }
2614 
2615  if ( checkFileType ( settings->structFiles.at(0) ) != 2 )
2616  {
2617  std::cerr << "!!! ProSHADE ERROR !!! The input file is corrupted or not a ccp4 MAP file formatted. Terminating..." << std::endl;
2618  exit ( -1 );
2619  }
2620 
2621  if ( settings->clearMapFile == "" )
2622  {
2623  std::cout << "!!! ProSHADE WARNING !!! The output file name was not set. You may want to use the \'--clearMap\' option to set it. Using the default name \'rotMap.map\'." << std::endl;
2624  settings->clearMapFile = "rotMap.map";
2625  }
2626 
2627  if ( ( settings->rotAngle == 0.0 ) && ( settings->rotXAxis == 0.0 ) && ( settings->rotYAxis == 0.0 ) && ( settings->rotZAxis == 0.0 ) )
2628  {
2629  std::cout << "!!! ProSHADE WARNING !!! There is no rotation to be done, but will progress as if there were. It would be faster just to copy the input..." << std::endl;
2630  }
2631 
2632  if ( settings->verbose > 2 )
2633  {
2634  std::cout << ">>>>> Sanity checks passed." << std::endl;
2635  }
2636 
2637  //==================================== Load the structure
2638  ProSHADE_data* rotStr = new ProSHADE_data ();
2639  rotStr->getDensityMapFromMAP ( this->structFiles.at(0),
2640  &this->shellSpacing,
2641  this->mapResolution,
2642  &this->bandwidth.at(0),
2643  &this->theta.at(0),
2644  &this->phi.at(0),
2645  &this->glIntegOrder.at(0),
2646  &this->extraSpace,
2647  settings->mapResDefault,
2648  settings->rotChangeDefault,
2649  settings,
2650  settings->overlayDefaults );
2651  if ( settings->verbose > 0 )
2652  {
2653  std::cout << "Structure loaded." << std::endl;
2654  }
2655 
2656  rotStr->translateMap ( settings->xTranslation,
2657  settings->yTranslation,
2658  settings->zTranslation );
2659 
2660  //==================================== Decompose structure to SH
2661  rotStr->keepPhaseInMap ( this->alpha,
2662  this->bFactorChange,
2663  &this->bandwidth.at(0),
2664  &this->theta.at(0),
2665  &this->phi.at(0),
2666  &this->glIntegOrder.at(0),
2667  settings,
2668  this->useCOM,
2669  settings->noIQRsFromMap,
2670  settings->verbose,
2671  settings->clearMapData,
2672  settings->rotChangeDefault,
2673  settings->overlayDefaults,
2674  settings->maskBlurFactor,
2675  settings->maskBlurFactorGiven );
2676 
2677  ProSHADE_comparePairwise* cmpObj = nullptr;
2678  if ( settings->rotAngle != 0.0 )
2679  {
2680  rotStr->mapPhaselessToSphere ( settings,
2681  this->theta.at(0),
2682  this->phi.at(0),
2683  this->shellSpacing,
2684  this->manualShells,
2685  true,
2686  settings->rotChangeDefault );
2687  rotStr->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2688  if ( settings->verbose > 1 )
2689  {
2690  std::cout << ">> Structure spherical harmonics computed." << std::endl;
2691  }
2692 
2693  //================================ Get comparison object
2694  cmpObj = new ProSHADE_comparePairwise ( rotStr,
2695  rotStr,
2696  this->mPower,
2697  this->ignoreLs,
2698  this->glIntegOrder.at(0),
2699  settings );
2700 
2701  //================================ Convert Axis-angle to Euler
2702  double euAlpha = 0.0;
2703  double euBeta = 0.0;
2704  double euGamma = 0.0;
2705 
2706  ProSHADE_internal_misc::getEulerFromAxisAngle ( &euAlpha,
2707  &euBeta,
2708  &euGamma,
2709  settings->rotXAxis,
2710  settings->rotYAxis,
2711  settings->rotZAxis,
2712  settings->rotAngle );
2713 
2714  cmpObj->setEulerAngles ( euAlpha, euBeta, euGamma );
2715 
2716  if ( settings->verbose > 2 )
2717  {
2718  printf ( ">>>>> Preparation for rotation complete. Euler angles are %+.3f ; %+.3f ; %+.3f\n", euAlpha, euBeta, euGamma );
2719  }
2720  }
2721  else
2722  {
2723  //================================ Get comparison object
2724  cmpObj = new ProSHADE_comparePairwise ( rotStr,
2725  rotStr,
2726  this->mPower,
2727  this->ignoreLs,
2728  this->glIntegOrder.at(0),
2729  settings );
2730 
2731  cmpObj->setEulerAngles ( 0.0, 0.0, 0.0 );
2732 
2733  if ( settings->verbose > 2 )
2734  {
2735  printf ( ">>>>> Preparation for rotation complete. Euler angles are 0.000 ; 0.000 ; 0.000\n" );
2736  }
2737  }
2738 
2739  //==================================== Rotate by the Euler
2740  cmpObj->rotateStructure ( rotStr,
2741  settings,
2742  settings->clearMapFile,
2743  settings->verbose,
2744  settings->axisOrder,
2745  false );
2746 
2747  //==================================== Clear memory
2748  delete cmpObj;
2749  delete rotStr;
2750 
2751  if ( settings->verbose > 0 )
2752  {
2753  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2754  std::cout << "| COMPLETED |" << std::endl;
2755  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2756  }
2757 
2758  if ( settings->verbose > 0 )
2759  {
2760  std::cout << "Rotated structure written to file: " << settings->clearMapFile << " as required." << std::endl << std::endl;
2761  }
2762 
2763  //==================================== Done
2764  return ;
2765  }
2766 
2767  //======================================== Report progress
2768  if ( settings->verbose > 0 )
2769  {
2770  std::cout << "-----------------------------------------------------------" << std::endl;
2771  std::cout << "| MODE: Symmetry |" << std::endl;
2772  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2773  }
2774 
2775  if ( settings->htmlReport )
2776  {
2777  //================================ Report title
2778  rvapi_set_text ( "<h1>ProSHADE Results: Symmetry</h1>",
2779  "body",
2780  settings->htmlReportLine,
2781  0,
2782  1,
2783  1 );
2784  settings->htmlReportLine += 1;
2785 
2786  //==================================== Create section
2787  rvapi_add_section ( "ProgressSection",
2788  "Progress",
2789  "body",
2790  settings->htmlReportLine,
2791  0,
2792  1,
2793  1,
2794  true );
2795  settings->htmlReportLine += 1;
2796 
2797  std::stringstream hlpSS;
2798  hlpSS << "<font color=\"green\">" << "Starting computation of symmetry for the input structure." << "</font>";
2799  rvapi_set_text ( hlpSS.str().c_str(),
2800  "ProgressSection",
2801  settings->htmlReportLineProgress,
2802  1,
2803  1,
2804  1 );
2805  settings->htmlReportLineProgress += 1;
2806 
2807  rvapi_flush ( );
2808  }
2809 
2810  //======================================== Sanity checks
2811  if ( settings->structFiles.size() != 1 )
2812  {
2813  std::cerr << "!!! ProSHADE ERROR !!! No files/too many files detected for map symmetry mode. Please supply a single map file using the -f or -i command line options. Terminating..." << std::endl;
2814  if ( settings->htmlReport )
2815  {
2816  std::stringstream hlpSS;
2817  hlpSS << "<font color=\"red\"><b>" << "Incorrect number of input files detected. The symmetry mode can process only a single structure at a time." << "<b></font>";
2818  rvapi_set_text ( hlpSS.str().c_str(),
2819  "ProgressSection",
2820  settings->htmlReportLineProgress,
2821  1,
2822  1,
2823  1 );
2824  settings->htmlReportLineProgress += 1;
2825  rvapi_flush ( );
2826  }
2827  exit ( -1 );
2828  }
2829 
2830  //======================================== Create the structure object
2831  unsigned int fileType = checkFileType ( structFiles.at(0) );
2832  ProSHADE_data* symStr = new ProSHADE_data ();
2833  if ( fileType == 2 )
2834  {
2835  symStr->getDensityMapFromMAP ( this->structFiles.at(0),
2836  &this->shellSpacing,
2837  this->mapResolution,
2838  &this->bandwidth.at(0),
2839  &this->theta.at(0),
2840  &this->phi.at(0),
2841  &this->glIntegOrder.at(0),
2842  &this->extraSpace,
2843  settings->mapResDefault,
2844  settings->rotChangeDefault,
2845  settings,
2846  settings->overlayDefaults );
2847  }
2848  else if ( fileType == 1 )
2849  {
2850  symStr->getDensityMapFromPDB ( this->structFiles.at(0),
2851  &this->shellSpacing,
2852  this->mapResolution,
2853  &this->bandwidth.at(0),
2854  &this->theta.at(0),
2855  &this->phi.at(0),
2856  &this->glIntegOrder.at(0),
2857  &this->extraSpace,
2858  settings->mapResDefault,
2859  settings,
2860  this->bFactorValue,
2861  this->firstLineCOM );
2862  }
2863  else
2864  {
2865  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file. Terminating ..." << std::endl;
2866  if ( settings->htmlReport )
2867  {
2868  std::stringstream hlpSS;
2869  hlpSS << "<font color=\"red\"><b>" << "Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file." << "<b></font>";
2870  rvapi_set_text ( hlpSS.str().c_str(),
2871  "ProgressSection",
2872  settings->htmlReportLineProgress,
2873  1,
2874  1,
2875  1 );
2876  settings->htmlReportLineProgress += 1;
2877  rvapi_flush ( );
2878  }
2879  exit ( -1 );
2880  }
2881  if ( settings->verbose > 0 )
2882  {
2883  std::cout << "Structure loaded." << std::endl;
2884  }
2885 
2886  if ( settings->htmlReport )
2887  {
2888  std::stringstream hlpSS;
2889  hlpSS << "<font color=\"green\">" << "Structure " << settings->structFiles.at(0) << " loaded." << "</font>";
2890  rvapi_set_text ( hlpSS.str().c_str(),
2891  "ProgressSection",
2892  settings->htmlReportLineProgress,
2893  1,
2894  1,
2895  1 );
2896  settings->htmlReportLineProgress += 1;
2897  rvapi_flush ( );
2898  }
2899 
2900  //======================================== Write file if so required
2901  if ( settings->clearMapFile != "" )
2902  {
2903  if ( settings->verbose > 1 )
2904  {
2905  std::cout << ">> Saving the structure into the requested location ( " << settings->clearMapFile << " )." << std::endl;
2906  }
2907 
2908  symStr->writeMap ( settings->clearMapFile, symStr->_densityMapMap );
2909  }
2910 
2911  symStr->keepPhaseInMap ( this->alpha,
2912  this->bFactorChange,
2913  &this->bandwidth.at(0),
2914  &this->theta.at(0),
2915  &this->phi.at(0),
2916  &this->glIntegOrder.at(0),
2917  settings,
2918  this->useCOM,
2919  settings->noIQRsFromMap,
2920  settings->verbose,
2921  settings->clearMapData,
2922  settings->rotChangeDefault,
2923  settings->overlayDefaults,
2924  settings->maskBlurFactor,
2925  settings->maskBlurFactorGiven );
2926 
2927  symStr->mapPhaselessToSphere ( settings,
2928  this->theta.at(0),
2929  this->phi.at(0),
2930  this->shellSpacing,
2931  this->manualShells );
2932  symStr->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2933  if ( settings->verbose > 1 )
2934  {
2935  std::cout << ">> Structure spherical harmonics computed." << std::endl;
2936  }
2937  if ( settings->htmlReport )
2938  {
2939  std::stringstream hlpSS;
2940  hlpSS << "<font color=\"green\">" << "Spherical harmonics decomposition computed." << "</font>";
2941  rvapi_set_text ( hlpSS.str().c_str(),
2942  "ProgressSection",
2943  settings->htmlReportLineProgress,
2944  1,
2945  1,
2946  1 );
2947  settings->htmlReportLineProgress += 1;
2948  rvapi_flush ( );
2949  }
2950 
2951  //======================================== Find the rotation function peaks
2952  ProSHADE_comparePairwise* cmpObj = new ProSHADE_comparePairwise ( symStr,
2953  symStr,
2954  this->mPower,
2955  this->ignoreLs,
2956  this->glIntegOrder.at(0),
2957  settings );
2958 
2959  cmpObj->precomputeTrSigmaDescriptor ( );
2960  if ( settings->verbose > 2 )
2961  {
2962  std::cout << ">>>>> E matrices constructed." << std::endl;
2963  }
2964  if ( settings->htmlReport )
2965  {
2966  std::stringstream hlpSS;
2967  hlpSS << "<font color=\"green\">" << "Shell integration complete." << "</font>";
2968  rvapi_set_text ( hlpSS.str().c_str(),
2969  "ProgressSection",
2970  settings->htmlReportLineProgress,
2971  1,
2972  1,
2973  1 );
2974  settings->htmlReportLineProgress += 1;
2975  rvapi_flush ( );
2976  }
2977 
2978  cmpObj->getSO3InverseMap ( settings );
2979  if ( settings->verbose > 2 )
2980  {
2981  std::cout << ">>>>> Inverse SO(3) Fourier transform map obtained." << std::endl;
2982  }
2983  if ( settings->htmlReport )
2984  {
2985  std::stringstream hlpSS;
2986  hlpSS << "<font color=\"green\">" << "SO(3) Fourier Transform computed." << "</font>";
2987  rvapi_set_text ( hlpSS.str().c_str(),
2988  "ProgressSection",
2989  settings->htmlReportLineProgress,
2990  1,
2991  1,
2992  1 );
2993  settings->htmlReportLineProgress += 1;
2994  rvapi_flush ( );
2995  }
2996 
2997  this->rfPeaks = cmpObj->getSO3Peaks ( settings,
2998  this->peakHeightNoIQRs,
2999  false,
3000  this->peakSurroundingPoints,
3001  this->peakDistanceForReal,
3002  settings->verbose );
3003  if ( settings->verbose > 1 )
3004  {
3005  std::cout << ">> Peaks obtained." << std::endl;
3006  }
3007  if ( settings->htmlReport )
3008  {
3009  std::stringstream hlpSS;
3010  hlpSS << "<font color=\"green\">" << "Rotation map peaks detection complete." << "</font>";
3011  rvapi_set_text ( hlpSS.str().c_str(),
3012  "ProgressSection",
3013  settings->htmlReportLineProgress,
3014  1,
3015  1,
3016  1 );
3017  settings->htmlReportLineProgress += 1;
3018  rvapi_flush ( );
3019  }
3020 
3021  //======================================== Find C symmetries
3022  this->cnSymm = cmpObj->findCnSymmetry ( this->rfPeaks,
3023  settings,
3024  this->aaErrorTolerance,
3025  false,
3026  0.33,
3027  settings->verbose );
3028 
3029  if ( settings->verbose > 0 )
3030  {
3031  std::cout << "C symmetries detected." << std::endl;
3032  }
3033  if ( settings->htmlReport )
3034  {
3035  std::stringstream hlpSS;
3036  hlpSS << "<font color=\"green\">" << "Cyclic symmetries detected." << "</font>";
3037  rvapi_set_text ( hlpSS.str().c_str(),
3038  "ProgressSection",
3039  settings->htmlReportLineProgress,
3040  1,
3041  1,
3042  1 );
3043  settings->htmlReportLineProgress += 1;
3044  rvapi_flush ( );
3045  }
3046 
3047  if ( settings->symmetryFold != 0 )
3048  {
3049  bool foundFold = false;
3050  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cnSymm.size() ); iter++ )
3051  {
3052  if ( this->cnSymm.at(iter)[0] == settings->symmetryFold ) { foundFold = true; }
3053  }
3054 
3055  if ( !foundFold )
3056  {
3057  if ( settings->verbose > 2 )
3058  {
3059  std::cout << ">>>>> The requested fold was not found. Searching for it specifically." << std::endl;
3060  }
3061 
3062  double mapPeakHeight = 0.0;
3063  double mapPeakMax = 0.0;
3064  unsigned int iterMax = 0;
3065  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cnSymm.size() ); iter++ )
3066  {
3067  mapPeakHeight = cmpObj->maxAvgPeakForSymmetry ( this->cnSymm.at(iter)[1],
3068  this->cnSymm.at(iter)[2],
3069  this->cnSymm.at(iter)[3],
3070  static_cast<double> ( settings->symmetryFold ),
3071  settings );
3072  if ( mapPeakMax < mapPeakHeight ) { mapPeakMax = mapPeakHeight; iterMax = iter; }
3073  }
3074 
3075  if ( this->cnSymm.size() > 0 )
3076  {
3077  if ( mapPeakMax > ( this->cnSymm.at(iterMax)[4] * ( 1.0 - settings->symGapTolerance ) ) )
3078  {
3079  std::array<double,5> hlpArr;
3080  hlpArr[0] = static_cast<double> ( settings->symmetryFold );
3081  hlpArr[1] = this->cnSymm.at(iterMax)[1];
3082  hlpArr[2] = this->cnSymm.at(iterMax)[2];
3083  hlpArr[3] = this->cnSymm.at(iterMax)[3];
3084  hlpArr[4] = mapPeakMax;
3085  this->cnSymm.emplace_back ( hlpArr );
3086  }
3087  }
3088  }
3089  }
3090 
3091  //======================================== Find D Symmetries
3092  this->dnSymm = cmpObj->findDnSymmetry ( this->cnSymm , this->aaErrorTolerance );
3093  if ( this->cnSymm.size() != 0 )
3094  {
3095  this->cnSymmClear = cmpObj->findCnSymmetryClear ( this->cnSymm, settings, this->symGapTolerance, &this->printFull );
3096  }
3097  if ( this->dnSymm.size() != 0 )
3098  {
3099  this->dnSymmClear = cmpObj->findDnSymmetryClear ( this->dnSymm, settings, this->symGapTolerance, &this->printFull );
3100  }
3101  if ( settings->verbose > 0 )
3102  {
3103  std::cout << "D symmetries detected." << std::endl;
3104  }
3105  if ( settings->htmlReport )
3106  {
3107  std::stringstream hlpSS;
3108  hlpSS << "<font color=\"green\">" << "Dihedral symmetries detected." << "</font>";
3109  rvapi_set_text ( hlpSS.str().c_str(),
3110  "ProgressSection",
3111  settings->htmlReportLineProgress,
3112  1,
3113  1,
3114  1 );
3115  settings->htmlReportLineProgress += 1;
3116  rvapi_flush ( );
3117  }
3118 
3119  //======================================== Find polyhedral symmetries
3120  this->icosSymm = cmpObj->findIcosSymmetry ( this->cnSymm, &this->icosSymmPeakAvg, this->aaErrorTolerance );
3121  this->octaSymm = cmpObj->findOctaSymmetry ( this->cnSymm, &this->octaSymmPeakAvg, this->aaErrorTolerance );
3122  this->tetrSymm = cmpObj->findTetrSymmetry ( this->cnSymm, &this->tetrSymmPeakAvg, this->aaErrorTolerance );
3123  if ( settings->verbose > 0 )
3124  {
3125  std::cout << "T, O and I symmetries detected." << std::endl;
3126  }
3127  if ( settings->htmlReport )
3128  {
3129  std::stringstream hlpSS;
3130  hlpSS << "<font color=\"green\">" << "Tetrahedral, Octahedral and Icosahedral symmetries detected." << "</font>";
3131  rvapi_set_text ( hlpSS.str().c_str(),
3132  "ProgressSection",
3133  settings->htmlReportLineProgress,
3134  1,
3135  1,
3136  1 );
3137  settings->htmlReportLineProgress += 1;
3138  rvapi_flush ( );
3139  }
3140 
3141  if ( this->icosSymm.size() > 0 )
3142  {
3143  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosSymm.size() ); icoIt++ )
3144  {
3145  this->icosAxes = this->generateIcosAxes ( cmpObj, settings, this->icosSymm.at(icoIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3146 
3147  if ( this->icosAxes.size() == 31 )
3148  {
3149  break;
3150  }
3151  }
3152  if ( this->icosAxes.size() != 31 )
3153  {
3154  std::cout << "!!! ProSHADE WARNING !!! It looks like icosahedral symmetry, but cannot find all the elements. Please report this case. Sorry for the inconvenience." << std::endl;
3155  }
3156  else
3157  {
3158  this->icosElems = this->generateIcosElements ( this->icosAxes, settings, settings->verbose );
3159  }
3160  }
3161 
3162  if ( ( ( this->octaSymm.size() > 0 ) && ( this->icosAxes.size() == 0 ) ) ||
3163  ( ( settings->symmetryType == "O" ) && ( this->octaSymm.size() > 0 ) ) )
3164  {
3165  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaSymm.size() ); octIt++ )
3166  {
3167  this->octaAxes = this->generateOctaAxes ( cmpObj, settings, this->octaSymm.at(octIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3168 
3169  if ( this->octaAxes.size() == 13 )
3170  {
3171  break;
3172  }
3173  }
3174  if ( this->octaAxes.size() != 13 )
3175  {
3176  std::cout << "!!! ProSHADE WARNING !!! It looks like (cub)octahedral symmetry, but cannot find all the elements. Please report this case. Sorry for the inconvenience." << std::endl;
3177  }
3178  else
3179  {
3180  this->octaElems = this->generateOctaElements ( this->octaAxes, settings, settings->verbose );
3181  }
3182  }
3183 
3184  if ( ( ( this->tetrSymm.size() > 0 ) && ( this->octaAxes.size() == 0 ) && ( this->icosAxes.size() == 0 ) ) ||
3185  ( ( settings->symmetryType == "T" ) && ( this->tetrSymm.size() > 0 ) ) )
3186  {
3187  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrSymm.size() ); tetIt++ )
3188  {
3189  this->tetrAxes = this->generateTetrAxes ( cmpObj, settings, this->tetrSymm.at(tetIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3190 
3191  if ( this->tetrAxes.size() == 6 )
3192  {
3193  break;
3194  }
3195  }
3196  if ( this->tetrAxes.size() != 6 )
3197  {
3198  std::cout << "!!! ProSHADE WARNING !!! It looks like tetrahedral symmetry, but cannot find all the elements. Please report this case. Sorry for the inconvenience." << std::endl;
3199  }
3200  else
3201  {
3202  this->tetrElems = this->generateTetrElements ( this->tetrAxes, settings, settings->verbose );
3203  }
3204  }
3205 
3206  if ( settings->verbose > 0 )
3207  {
3208  std::cout << ">> Generation of T, O and I symmetry group elements complete." << std::endl;
3209  }
3210 
3211  if ( settings->verbose > 0 )
3212  {
3213  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
3214  std::cout << "| COMPLETED |" << std::endl;
3215  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
3216  }
3217 
3218  if ( settings->htmlReport )
3219  {
3220  std::stringstream hlpSS;
3221  hlpSS << "<font color=\"green\">" << "Symmetry detection completed." << "</font>";
3222  rvapi_set_text ( hlpSS.str().c_str(),
3223  "ProgressSection",
3224  settings->htmlReportLineProgress,
3225  1,
3226  1,
3227  1 );
3228  settings->htmlReportLineProgress += 1;
3229  rvapi_flush ( );
3230  }
3231 
3232  //======================================== Keep data type in memory
3233  this->inputStructureDataType = symStr->_fromPDB;
3234 
3235  //======================================== Free memory
3236  cmpObj->freeInvMap ( );
3237  delete cmpObj;
3238  delete symStr;
3239 
3240  //======================================== Done
3241  return ;
3242 
3243 }
3244 
3257 void ProSHADE_internal::ProSHADE_symmetry::printResultsRequest ( std::string symmetryType, unsigned int symmetryFold, int verbose )
3258 {
3259  //======================================== Claim the symmetry to be the highest detected
3260  if ( verbose > 0 )
3261  {
3262  printf ( "-----------------------------------------------------------\n" );
3263  printf ( "| RESULTS |\n" );
3264  printf ( "-----------------------------------------------------------\n\n" );
3265  }
3266 
3267  if ( symmetryType == "I" )
3268  {
3269  if ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 )
3270  {
3271  printf ( "Detected Icosahedral symmetry as requested\n\n" );
3272  printf ( "Symmetry axes table:\n" );
3273  printf ( "-----------------------------------------------------------\n" );
3274  printf ( "Symmetry Fold x y z Angle Peak\n" );
3275  printf ( " Type height\n" );
3276  printf ( "-----------------------------------------------------------\n" );
3277 
3278  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3279  {
3280  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->icosAxes.at(icoIt)[0] ), this->icosAxes.at(icoIt)[1], this->icosAxes.at(icoIt)[2], this->icosAxes.at(icoIt)[3], static_cast<int> ( this->icosAxes.at(icoIt)[0] ), this->icosAxes.at(icoIt)[4] );
3281  }
3282  printf ( "\n" );
3283 
3284  printf ( "Symmetry elements table:\n" );
3285  printf ( "-----------------------------------------------------------\n" );
3286  printf ( "Symmetry x y z Angle \n" );
3287  printf ( " Type (deg) \n" );
3288  printf ( "-----------------------------------------------------------\n" );
3289 
3290  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3291  {
3292  if ( this->icosElems.at(icoIt)[0] != 1.0 )
3293  {
3294  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->icosElems.at(icoIt)[0] ), this->icosElems.at(icoIt)[1], this->icosElems.at(icoIt)[2], this->icosElems.at(icoIt)[3], this->icosElems.at(icoIt)[4] );
3295  }
3296  else
3297  {
3298  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->icosElems.at(icoIt)[1], this->icosElems.at(icoIt)[2], this->icosElems.at(icoIt)[3], this->icosElems.at(icoIt)[4] );
3299  }
3300  }
3301  printf ( "\n" );
3302  }
3303  else
3304  {
3305  std::cout << "!!! ProSHADE WARNING !!! Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << std::endl << std::endl;
3306  }
3307  }
3308 
3309  if ( symmetryType == "O" )
3310  {
3311  if ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 )
3312  {
3313  printf ( "Detected (Cub)octahedral symmetry as requested\n\n" );
3314  printf ( "Symmetry axes table:\n" );
3315  printf ( "-----------------------------------------------------------\n" );
3316  printf ( "Symmetry Fold x y z Angle Peak\n" );
3317  printf ( " Type height\n" );
3318  printf ( "-----------------------------------------------------------\n" );
3319 
3320  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaAxes.size() ); octIt++ )
3321  {
3322  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->octaAxes.at(octIt)[0] ), this->octaAxes.at(octIt)[1], this->octaAxes.at(octIt)[2], this->octaAxes.at(octIt)[3], static_cast<int> ( this->octaAxes.at(octIt)[0] ), this->octaAxes.at(octIt)[4] );
3323  }
3324  printf ( "\n" );
3325 
3326  printf ( "Symmetry elements table:\n" );
3327  printf ( "-----------------------------------------------------------\n" );
3328  printf ( "Symmetry x y z Angle \n" );
3329  printf ( " Type (deg) \n" );
3330  printf ( "-----------------------------------------------------------\n" );
3331 
3332  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaElems.size() ); octIt++ )
3333  {
3334  if ( this->octaElems.at(octIt)[0] != 1.0 )
3335  {
3336  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->octaElems.at(octIt)[0] ), this->octaElems.at(octIt)[1], this->octaElems.at(octIt)[2], this->octaElems.at(octIt)[3], this->octaElems.at(octIt)[4] );
3337  }
3338  else
3339  {
3340  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->octaElems.at(octIt)[1], this->octaElems.at(octIt)[2], this->octaElems.at(octIt)[3], this->octaElems.at(octIt)[4] );
3341  }
3342  }
3343  printf ( "\n" );
3344  }
3345  else
3346  {
3347  std::cout << "!!! ProSHADE WARNING !!! Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below.\n\n" << std::endl << std::endl;
3348  }
3349  }
3350 
3351  if ( symmetryType == "T" )
3352  {
3353  if ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 )
3354  {
3355  printf ( "Detected Tetrahedral symmetry as requested\n\n" );
3356  printf ( "Symmetry axes table:\n" );
3357  printf ( "-----------------------------------------------------------\n" );
3358  printf ( "Symmetry Fold x y z Angle Peak\n" );
3359  printf ( " Type height\n" );
3360  printf ( "-----------------------------------------------------------\n" );
3361 
3362  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrAxes.size() ); tetIt++ )
3363  {
3364  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->tetrAxes.at(tetIt)[0] ), this->tetrAxes.at(tetIt)[1], this->tetrAxes.at(tetIt)[2], this->tetrAxes.at(tetIt)[3], static_cast<int> ( this->tetrAxes.at(tetIt)[0] ), this->tetrAxes.at(tetIt)[4] );
3365  }
3366  printf ( "\n" );
3367 
3368  printf ( "Symmetry elements table:\n" );
3369  printf ( "-----------------------------------------------------------\n" );
3370  printf ( "Symmetry x y z Angle \n" );
3371  printf ( " Type (deg) \n" );
3372  printf ( "-----------------------------------------------------------\n" );
3373 
3374  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrElems.size() ); tetIt++ )
3375  {
3376  if ( this->tetrElems.at(tetIt)[0] != 1.0 )
3377  {
3378  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->tetrElems.at(tetIt)[0] ), this->tetrElems.at(tetIt)[1], this->tetrElems.at(tetIt)[2], this->tetrElems.at(tetIt)[3], this->tetrElems.at(tetIt)[4] );
3379  }
3380  else
3381  {
3382  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->tetrElems.at(tetIt)[1], this->tetrElems.at(tetIt)[2], this->tetrElems.at(tetIt)[3], this->tetrElems.at(tetIt)[4] );
3383  }
3384  }
3385  printf ( "\n" );
3386  }
3387  else
3388  {
3389  std::cout << "!!! ProSHADE WARNING !!! Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below.\n\n" << std::endl << std::endl;
3390  }
3391  }
3392 
3393  if ( symmetryType == "D" )
3394  {
3395  if ( static_cast<unsigned int> ( this->dnSymm.size() ) > 0 )
3396  {
3397  bool reqFound = false;
3398  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->dnSymm.size() ); dIt++ )
3399  {
3400  if ( reqFound ) { break; }
3401  unsigned int howManyTwos = 0;
3402  for ( unsigned int dItt = 0; dItt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); dItt++ )
3403  {
3404  if ( reqFound ) { break; }
3405  if ( symmetryFold != 2 )
3406  {
3407  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold )
3408  {
3409  printf ( "Detected Dihedral symmetry as requested\n\n" );
3410  printf ( "Symmetry axes table:\n" );
3411  printf ( "-----------------------------------------------------------\n" );
3412  printf ( "Symmetry Fold x y z Angle Peak\n" );
3413  printf ( " Type height\n" );
3414  printf ( "-----------------------------------------------------------\n" );
3415  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
3416  {
3417  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[4] );
3418  }
3419 
3420  printf ( "\n" );
3421 
3422  printf ( "Symmetry elements table:\n" );
3423  printf ( "-----------------------------------------------------------\n" );
3424  printf ( "Symmetry x y z Angle \n" );
3425  printf ( " Type (deg) \n" );
3426  printf ( "-----------------------------------------------------------\n" );
3427 
3428  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3429  for ( unsigned int it = 0; it < 2; it++ )
3430  {
3431  if ( static_cast<int> ( this->dnSymm.at(0).at(it)[0] ) % 2 == 0 )
3432  {
3433  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
3434  {
3435  if ( iter == 0 ) { continue; }
3436  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
3437  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) );
3438  }
3439  }
3440  else
3441  {
3442  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
3443  {
3444  if ( iter == 0 ) { continue; }
3445  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) );
3446  }
3447  }
3448  }
3449 
3450  printf ( "\n" );
3451  reqFound = true;
3452  break;
3453  }
3454  else
3455  {
3456  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
3457  {
3458  continue;
3459  }
3460  else
3461  {
3462  break;
3463  }
3464  }
3465  }
3466  if ( symmetryFold == 2 )
3467  {
3468  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
3469  {
3470  howManyTwos += 1;
3471  }
3472  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold && howManyTwos == 2 )
3473  {
3474  printf ( "Detected Dihedral symmetry as requested\n\n" );
3475  printf ( "Symmetry axes table:\n" );
3476  printf ( "-----------------------------------------------------------\n" );
3477  printf ( "Symmetry Fold x y z Angle Peak\n" );
3478  printf ( " Type height\n" );
3479  printf ( "-----------------------------------------------------------\n" );
3480  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
3481  {
3482  if ( this->dnSymm.at(dIt).at(it)[0] == 2.0 )
3483  {
3484  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[4] );
3485  }
3486  }
3487 
3488  printf ( "\n" );
3489 
3490  printf ( "Symmetry elements table:\n" );
3491  printf ( "-----------------------------------------------------------\n" );
3492  printf ( "Symmetry x y z Angle \n" );
3493  printf ( " Type (deg) \n" );
3494  printf ( "-----------------------------------------------------------\n" );
3495 
3496  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3497  for ( unsigned int it = 0; it < 2; it++ )
3498  {
3499  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
3500  {
3501  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
3502  {
3503  if ( iter == 0 ) { continue; }
3504  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
3505  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) );
3506  }
3507  }
3508  else
3509  {
3510  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
3511  {
3512  if ( iter == 0 ) { continue; }
3513  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ), this->dnSymm.at(dIt).at(it)[1], this->dnSymm.at(dIt).at(it)[2], this->dnSymm.at(dIt).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) );
3514  }
3515  }
3516  }
3517 
3518  printf ( "\n" );
3519  reqFound = true;
3520  break;
3521  }
3522  }
3523  }
3524  }
3525  if ( !reqFound )
3526  {
3527  std::cout << "!!! ProSHADE WARNING !!! Could not detect the requested dihedral symmetry, but detected dihedral symmetries with different fold. You can try changing the resolution or selecting one of the alternative symmetries printed below.\n\n" << std::endl << std::endl;
3528  }
3529  }
3530  else
3531  {
3532  std::cerr << "!!! Warning !!! Could not detect the requested dihedral symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below.\n\n" << std::endl << std::endl;
3533  }
3534  }
3535 
3536  if ( symmetryType == "C" )
3537  {
3538  if ( static_cast<unsigned int> ( this->cnSymm.size() ) > 0 )
3539  {
3540  bool reqFound = false;
3541  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->cnSymm.size() ); dIt++ )
3542  {
3543  if ( this->cnSymm.at(dIt)[0] == symmetryFold )
3544  {
3545  printf ( "Detected Cyclic symmetry as requested\n\n" );
3546  printf ( "Symmetry axes table:\n" );
3547  printf ( "-----------------------------------------------------------\n" );
3548  printf ( "Symmetry Fold x y z Angle Peak\n" );
3549  printf ( " Type height\n" );
3550  printf ( "-----------------------------------------------------------\n" );
3551  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n\n", static_cast<int> ( this->cnSymm.at(dIt)[0] ), this->cnSymm.at(dIt)[1], this->cnSymm.at(dIt)[2], this->cnSymm.at(dIt)[3], static_cast<int> ( this->cnSymm.at(dIt)[0] ), static_cast<double> ( this->cnSymm.at(dIt)[4] ) );
3552 
3553  printf ( "\n" );
3554 
3555  printf ( "Symmetry elements table:\n" );
3556  printf ( "-----------------------------------------------------------\n" );
3557  printf ( "Symmetry x y z Angle \n" );
3558  printf ( " Type (deg) \n" );
3559  printf ( "-----------------------------------------------------------\n" );
3560 
3561  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3562  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
3563  {
3564  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
3565  {
3566  if ( iter == 0 ) { continue; }
3567  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
3568  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->cnSymm.at(dIt)[0] ), this->cnSymm.at(dIt)[1], this->cnSymm.at(dIt)[2], this->cnSymm.at(dIt)[3], iter * ( 360.0 / static_cast<double> ( this->cnSymm.at(dIt)[0] ) ) );
3569  }
3570  }
3571  else
3572  {
3573  for ( int iter = -std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
3574  {
3575  if ( iter == 0 ) { continue; }
3576  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->cnSymm.at(dIt)[0] ), this->cnSymm.at(dIt)[1], this->cnSymm.at(dIt)[2], this->cnSymm.at(dIt)[3], iter * ( 360.0 / static_cast<double> ( this->cnSymm.at(dIt)[0] ) ) );
3577  }
3578  }
3579  printf ( "\n" );
3580  reqFound = true;
3581  break;
3582  }
3583  }
3584  if ( !reqFound )
3585  {
3586  std::cout << "!!! ProSHADE WARNING !!! Could not detect the requested cyclic symmetry, but detected cyclic symmetries with different folds. You can try changing the resolution or selecting one of the alternative symmetries printed below.\n\n" << std::endl << std::endl;
3587  }
3588  }
3589  else
3590  {
3591  std::cerr << "!!! Warning !!! Could not detect the requested cyclic symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below.\n\n" << std::endl << std::endl;
3592  }
3593  }
3594 
3595  //======================================== Print alternativs
3596  printf ( "Alternatives:\n" );
3597  printf ( "-----------------------------------------------------------\n" );
3598  printf ( "Symmetry Fold x y z Angle Peak\n" );
3599  printf ( " Type height\n" );
3600  printf ( "-----------------------------------------------------------\n" );
3601  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
3602  {
3603  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->cnSymm.at(gNo)[0] ), this->cnSymm.at(gNo)[1], this->cnSymm.at(gNo)[2], this->cnSymm.at(gNo)[3], static_cast<int> ( this->cnSymm.at(gNo)[0] ), static_cast<double> ( this->cnSymm.at(gNo)[4] ) );
3604  }
3605 
3606  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
3607  {
3608  printf ( " D %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ), this->dnSymm.at(iter).at(0)[1], this->dnSymm.at(iter).at(0)[2], this->dnSymm.at(iter).at(0)[3], static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ), this->dnSymm.at(iter).at(0)[5] );
3609 
3610  for ( unsigned int mem = 1; mem < static_cast<unsigned int> ( this->dnSymm.at(iter).size() ); mem++ )
3611  {
3612  printf ( " %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(iter).at(mem)[0] ), this->dnSymm.at(iter).at(mem)[1], this->dnSymm.at(iter).at(mem)[2], this->dnSymm.at(iter).at(mem)[3], static_cast<int> ( this->dnSymm.at(iter).at(mem)[0] ), this->dnSymm.at(iter).at(mem)[5] );
3613  }
3614  }
3615 
3616  if ( this->tetrElems.size() > 0 )
3617  {
3618  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->tetrSymm.size() ); iter++ )
3619  {
3620  printf ( " T %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->tetrSymm.at(iter).at(0)[0] ), this->tetrSymm.at(iter).at(0)[1], this->tetrSymm.at(iter).at(0)[2], this->tetrSymm.at(iter).at(0)[3], static_cast<int> ( this->tetrSymm.at(iter).at(0)[0] ), this->tetrSymm.at(iter).at(0)[4] );
3621  printf ( " %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->tetrSymm.at(iter).at(1)[0] ), this->tetrSymm.at(iter).at(1)[1], this->tetrSymm.at(iter).at(1)[2], this->tetrSymm.at(iter).at(1)[3], static_cast<int> ( this->tetrSymm.at(iter).at(1)[0] ), this->tetrSymm.at(iter).at(1)[4] );
3622  }
3623  }
3624 
3625  if ( this->octaElems.size() > 0 )
3626  {
3627  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->octaSymm.size() ); iter++ )
3628  {
3629  printf ( " O %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->octaSymm.at(iter).at(0)[0] ), this->octaSymm.at(iter).at(0)[1], this->octaSymm.at(iter).at(0)[2], this->octaSymm.at(iter).at(0)[3], static_cast<int> ( this->octaSymm.at(iter).at(0)[0] ), this->octaSymm.at(iter).at(0)[4] );
3630  printf ( " %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->octaSymm.at(iter).at(1)[0] ), this->octaSymm.at(iter).at(1)[1], this->octaSymm.at(iter).at(1)[2], this->octaSymm.at(iter).at(1)[3], static_cast<int> ( this->octaSymm.at(iter).at(1)[0] ), this->octaSymm.at(iter).at(1)[4] );
3631  }
3632  }
3633 
3634  if ( this->icosElems.size() > 0 )
3635  {
3636  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->icosSymm.size() ); iter++ )
3637  {
3638  printf ( " I %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->icosSymm.at(iter).at(0)[0] ), this->icosSymm.at(iter).at(0)[1], this->icosSymm.at(iter).at(0)[2], this->icosSymm.at(iter).at(0)[3], static_cast<int> ( this->icosSymm.at(iter).at(0)[0] ), this->icosSymm.at(iter).at(0)[4] );
3639  printf ( " %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->icosSymm.at(iter).at(1)[0] ), this->icosSymm.at(iter).at(1)[1], this->icosSymm.at(iter).at(1)[2], this->icosSymm.at(iter).at(1)[3], static_cast<int> ( this->icosSymm.at(iter).at(1)[0] ), this->icosSymm.at(iter).at(1)[4] );
3640  }
3641  }
3642  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
3643 
3644  //======================================== Done
3645  return ;
3646 
3647 }
3648 
3662  unsigned int symmetryFold,
3663  ProSHADE::ProSHADE_settings* settings )
3664 {
3665  //======================================== Claim the symmetry to be the requested one
3666  if ( settings->htmlReport )
3667  {
3668  //==================================== Create review section
3669  rvapi_add_section ( "ReviewSection",
3670  "Review",
3671  "body",
3672  settings->htmlReportLine,
3673  0,
3674  1,
3675  1,
3676  false );
3677  settings->htmlReportLine += 1;
3678 
3679  std::stringstream hlpSS;
3680  hlpSS << "<pre>" << "Requested symmetry : ";
3681  if ( symmetryType == "I" )
3682  {
3683  hlpSS << "Icosahedral" << "</pre>";
3684  }
3685  if ( symmetryType == "O" )
3686  {
3687  hlpSS << "Octahedral" << "</pre>";
3688  }
3689  if ( symmetryType == "T" )
3690  {
3691  hlpSS << "Tetrahedral" << "</pre>";
3692  }
3693  if ( symmetryType == "D" )
3694  {
3695  hlpSS << "Dihedral with fold " << ProSHADE_internal_misc::to_string_with_precision ( symmetryFold ) << "</pre>";
3696  }
3697  if ( symmetryType == "C" )
3698  {
3699  hlpSS << "Cyclic with fold " << ProSHADE_internal_misc::to_string_with_precision ( symmetryFold ) << "</pre>";
3700  }
3701 
3702 
3703  rvapi_set_text ( hlpSS.str().c_str(),
3704  "ReviewSection",
3705  0,
3706  0,
3707  1,
3708  1 );
3709 
3710  hlpSS.str ( std::string ( ) );
3711  hlpSS << "<pre>" << "Input structure : " << this->structFiles.at(0) << "</pre>";
3712  rvapi_set_text ( hlpSS.str().c_str(),
3713  "ReviewSection",
3714  1,
3715  0,
3716  1,
3717  1 );
3718  rvapi_flush ( );
3719 
3720  //==================================== Create results section
3721  rvapi_add_section ( "ResultsSection",
3722  "Results",
3723  "body",
3724  settings->htmlReportLine,
3725  0,
3726  1,
3727  1,
3728  true );
3729  settings->htmlReportLine += 1;
3730  }
3731 
3732  int totTabRows = 0;
3733  bool foundRequest = true;
3734 
3735  if ( symmetryType == "I" )
3736  {
3737  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
3738  {
3739  std::stringstream hlpSS;
3740  hlpSS << "<b>" << "Detected <i>ICOSAHEDRAL<i> symmetry as requested." << "</b>";
3741  rvapi_set_text ( hlpSS.str().c_str(),
3742  "ResultsSection",
3743  0,
3744  0,
3745  1,
3746  1 );
3747  rvapi_flush ( );
3748 
3749  //==================================== Symmetry axes table
3750  rvapi_add_table ( "SymmetryTypeTable",
3751  "Detected symmetry axes",
3752  "ResultsSection",
3753  1,
3754  0,
3755  static_cast<unsigned int> ( this->icosAxes.size() ),
3756  8,
3757  1 );
3758 
3759  // ... Column headers
3760  int columnIter = 0;
3761 
3762  hlpSS.str ( std::string ( ) );
3763  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
3764  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
3765  columnIter += 1;
3766 
3767  hlpSS.str ( std::string ( ) );
3768  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
3769  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
3770  columnIter += 1;
3771 
3772  hlpSS.str ( std::string ( ) );
3773  hlpSS << "This column states the x-axis element of the symmetry axis.";
3774  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3775  columnIter += 1;
3776 
3777  hlpSS.str ( std::string ( ) );
3778  hlpSS << "This column states the y-axis element of the symmetry axis.";
3779  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3780  columnIter += 1;
3781 
3782  hlpSS.str ( std::string ( ) );
3783  hlpSS << "This column states the z-axis element of the symmetry axis.";
3784  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3785  columnIter += 1;
3786 
3787  hlpSS.str ( std::string ( ) );
3788  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
3789  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
3790  columnIter += 1;
3791 
3792  hlpSS.str ( std::string ( ) );
3793  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
3794  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
3795  columnIter += 1;
3796 
3797  // ... Row headers
3798  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3799  {
3800  std::stringstream hlpSS2;
3801  hlpSS2 << "Symmetry axis #" << icoIt+1;
3802  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
3803  }
3804 
3805  // ... Fill in data
3806  int prec = 4;
3807  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3808  {
3809  std::stringstream hlpSS2;
3810  hlpSS2 << "C";
3811  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
3812 
3813  hlpSS2.str ( std::string ( ) );
3814  hlpSS2 << static_cast<int> ( this->icosAxes.at(icoIt)[0] );
3815  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
3816 
3817  hlpSS2.str ( std::string ( ) );
3818  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[1], prec );
3819  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
3820 
3821  hlpSS2.str ( std::string ( ) );
3822  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[2], prec );
3823  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
3824 
3825  hlpSS2.str ( std::string ( ) );
3826  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[3], prec );
3827  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
3828 
3829  hlpSS2.str ( std::string ( ) );
3830  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->icosAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
3831  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
3832 
3833  hlpSS2.str ( std::string ( ) );
3834  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[4], prec );
3835  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
3836  }
3837 
3838  //==================================== Symmetry elements table
3839  rvapi_add_table ( "SymmetryElementsTable",
3840  "Detected symmetry elements",
3841  "ResultsSection",
3842  static_cast<unsigned int> ( this->icosAxes.size() ) + 1,
3843  0,
3844  static_cast<unsigned int> ( this->icosElems.size() ),
3845  7,
3846  -1 );
3847  totTabRows = static_cast<unsigned int> ( this->icosAxes.size() ) + 1 + static_cast<unsigned int> ( this->icosElems.size() );
3848 
3849  // ... Column headers
3850  columnIter = 0;
3851 
3852  hlpSS.str ( std::string ( ) );
3853  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
3854  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
3855  columnIter += 1;
3856 
3857  hlpSS.str ( std::string ( ) );
3858  hlpSS << "This column states the symmetry element fold.";
3859  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
3860  columnIter += 1;
3861 
3862  hlpSS.str ( std::string ( ) );
3863  hlpSS << "This column states the x-axis element of the symmetry element axis.";
3864  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3865  columnIter += 1;
3866 
3867  hlpSS.str ( std::string ( ) );
3868  hlpSS << "This column states the y-axis element of the symmetry element axis.";
3869  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3870  columnIter += 1;
3871 
3872  hlpSS.str ( std::string ( ) );
3873  hlpSS << "This column states the z-axis element of the symmetry element axis.";
3874  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3875  columnIter += 1;
3876 
3877  hlpSS.str ( std::string ( ) );
3878  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
3879  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
3880  columnIter += 1;
3881 
3882  // ... Row headers
3883  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3884  {
3885  std::stringstream hlpSS2;
3886  hlpSS2 << "Symmetry element #" << icoIt+1;
3887  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
3888  }
3889 
3890  // ... Fill in data
3891  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3892  {
3893  if ( this->icosElems.at(icoIt)[0] != 1.0 )
3894  {
3895  std::stringstream hlpSS3;
3896  hlpSS3 << "C";
3897  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
3898  }
3899  else
3900  {
3901  std::stringstream hlpSS3;
3902  hlpSS3 << "E";
3903  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
3904  }
3905 
3906  std::stringstream hlpSS2;
3907  hlpSS2 << static_cast<int> ( this->icosElems.at(icoIt)[0] );
3908  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
3909 
3910  hlpSS2.str ( std::string ( ) );
3911  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[1], prec );
3912  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
3913 
3914  hlpSS2.str ( std::string ( ) );
3915  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[2], prec );
3916  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
3917 
3918  hlpSS2.str ( std::string ( ) );
3919  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[3], prec );
3920  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
3921 
3922  hlpSS2.str ( std::string ( ) );
3923  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[4], prec );
3924  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
3925  }
3926 
3927  rvapi_flush ( );
3928  }
3929  else
3930  {
3931  std::stringstream hlpSS;
3932  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << "</font></b>";
3933  rvapi_set_text ( hlpSS.str().c_str(),
3934  "ResultsSection",
3935  0,
3936  0,
3937  1,
3938  1 );
3939  rvapi_flush ( );
3940  foundRequest = false;
3941  }
3942  }
3943 
3944  if ( symmetryType == "O" )
3945  {
3946  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->octaElems.size() ) > 0 ) )
3947  {
3948  //================================ State result
3949  std::stringstream hlpSS;
3950  hlpSS << "<b>" << "Detected <i>OCTAHEDRAL</i> symmetry as requested." << "</b>";
3951  rvapi_set_text ( hlpSS.str().c_str(),
3952  "ResultsSection",
3953  0,
3954  0,
3955  1,
3956  1 );
3957  rvapi_flush ( );
3958 
3959  //================================ Symmetry axes table
3960  rvapi_add_table ( "SymmetryTypeTable",
3961  "Detected symmetry axes",
3962  "ResultsSection",
3963  1,
3964  0,
3965  static_cast<unsigned int> ( this->octaAxes.size() ),
3966  8,
3967  1 );
3968 
3969  // ... Column headers
3970  int columnIter = 0;
3971 
3972  hlpSS.str ( std::string ( ) );
3973  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
3974  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
3975  columnIter += 1;
3976 
3977  hlpSS.str ( std::string ( ) );
3978  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
3979  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
3980  columnIter += 1;
3981 
3982  hlpSS.str ( std::string ( ) );
3983  hlpSS << "This column states the x-axis element of the symmetry axis.";
3984  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3985  columnIter += 1;
3986 
3987  hlpSS.str ( std::string ( ) );
3988  hlpSS << "This column states the y-axis element of the symmetry axis.";
3989  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3990  columnIter += 1;
3991 
3992  hlpSS.str ( std::string ( ) );
3993  hlpSS << "This column states the z-axis element of the symmetry axis.";
3994  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3995  columnIter += 1;
3996 
3997  hlpSS.str ( std::string ( ) );
3998  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
3999  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4000  columnIter += 1;
4001 
4002  hlpSS.str ( std::string ( ) );
4003  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
4004  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4005  columnIter += 1;
4006 
4007  // ... Row headers
4008  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
4009  {
4010  std::stringstream hlpSS2;
4011  hlpSS2 << "Symmetry axis #" << icoIt+1;
4012  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
4013  }
4014 
4015  // ... Fill in data
4016  int prec = 4;
4017  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
4018  {
4019  std::stringstream hlpSS2;
4020  hlpSS2 << "C";
4021  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
4022 
4023  hlpSS2.str ( std::string ( ) );
4024  hlpSS2 << static_cast<int> ( this->octaAxes.at(icoIt)[0] );
4025  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
4026 
4027  hlpSS2.str ( std::string ( ) );
4028  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[1], prec );
4029  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
4030 
4031  hlpSS2.str ( std::string ( ) );
4032  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[2], prec );
4033  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
4034 
4035  hlpSS2.str ( std::string ( ) );
4036  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[3], prec );
4037  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
4038 
4039  hlpSS2.str ( std::string ( ) );
4040  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->octaAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
4041  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
4042 
4043  hlpSS2.str ( std::string ( ) );
4044  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[4], prec );
4045  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
4046  }
4047 
4048  //================================ Symmetry elements table
4049  rvapi_add_table ( "SymmetryElementsTable",
4050  "Detected symmetry elements",
4051  "ResultsSection",
4052  static_cast<unsigned int> ( this->octaAxes.size() ) + 1,
4053  0,
4054  static_cast<unsigned int> ( this->octaElems.size() ),
4055  7,
4056  -1 );
4057  totTabRows = static_cast<unsigned int> ( this->octaAxes.size() ) + 1 + static_cast<unsigned int> ( this->octaElems.size() );
4058 
4059  // ... Column headers
4060  columnIter = 0;
4061 
4062  hlpSS.str ( std::string ( ) );
4063  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4064  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4065  columnIter += 1;
4066 
4067  hlpSS.str ( std::string ( ) );
4068  hlpSS << "This column states the symmetry element fold.";
4069  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4070  columnIter += 1;
4071 
4072  hlpSS.str ( std::string ( ) );
4073  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4074  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4075  columnIter += 1;
4076 
4077  hlpSS.str ( std::string ( ) );
4078  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4079  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4080  columnIter += 1;
4081 
4082  hlpSS.str ( std::string ( ) );
4083  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4084  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4085  columnIter += 1;
4086 
4087  hlpSS.str ( std::string ( ) );
4088  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4089  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4090  columnIter += 1;
4091 
4092  // ... Row headers
4093  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
4094  {
4095  std::stringstream hlpSS2;
4096  hlpSS2 << "Symmetry element #" << icoIt+1;
4097  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4098  }
4099 
4100  // ... Fill in data
4101  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
4102  {
4103  if ( this->octaElems.at(icoIt)[0] != 1.0 )
4104  {
4105  std::stringstream hlpSS3;
4106  hlpSS3 << "C";
4107  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
4108  }
4109  else
4110  {
4111  std::stringstream hlpSS3;
4112  hlpSS3 << "E";
4113  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
4114  }
4115 
4116  std::stringstream hlpSS2;
4117  hlpSS2 << static_cast<int> ( this->octaElems.at(icoIt)[0] );
4118  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
4119 
4120  hlpSS2.str ( std::string ( ) );
4121  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[1], prec );
4122  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
4123 
4124  hlpSS2.str ( std::string ( ) );
4125  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[2], prec );
4126  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
4127 
4128  hlpSS2.str ( std::string ( ) );
4129  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[3], prec );
4130  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
4131 
4132  hlpSS2.str ( std::string ( ) );
4133  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[4], prec );
4134  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
4135  }
4136 
4137  rvapi_flush ( );
4138  }
4139  else
4140  {
4141  std::stringstream hlpSS;
4142  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << "</font></b>";
4143  rvapi_set_text ( hlpSS.str().c_str(),
4144  "ResultsSection",
4145  0,
4146  0,
4147  1,
4148  1 );
4149  rvapi_flush ( );
4150  foundRequest = false;
4151  }
4152  }
4153 
4154  if ( symmetryType == "T" )
4155  {
4156  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
4157  {
4158  //============================ State result
4159  std::stringstream hlpSS;
4160  hlpSS << "<b>" << "Detected <i>TETRAHEDRAL</i> symmetry as requested." << "</b>";
4161  rvapi_set_text ( hlpSS.str().c_str(),
4162  "ResultsSection",
4163  0,
4164  0,
4165  1,
4166  1 );
4167  rvapi_flush ( );
4168 
4169  //============================ Symmetry axes table
4170  rvapi_add_table ( "SymmetryTypeTable",
4171  "Detected symmetry axes",
4172  "ResultsSection",
4173  1,
4174  0,
4175  static_cast<unsigned int> ( this->tetrAxes.size() ),
4176  8,
4177  1 );
4178 
4179  // ... Column headers
4180  int columnIter = 0;
4181 
4182  hlpSS.str ( std::string ( ) );
4183  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4184  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4185  columnIter += 1;
4186 
4187  hlpSS.str ( std::string ( ) );
4188  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4189  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4190  columnIter += 1;
4191 
4192  hlpSS.str ( std::string ( ) );
4193  hlpSS << "This column states the x-axis element of the symmetry axis.";
4194  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4195  columnIter += 1;
4196 
4197  hlpSS.str ( std::string ( ) );
4198  hlpSS << "This column states the y-axis element of the symmetry axis.";
4199  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4200  columnIter += 1;
4201 
4202  hlpSS.str ( std::string ( ) );
4203  hlpSS << "This column states the z-axis element of the symmetry axis.";
4204  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4205  columnIter += 1;
4206 
4207  hlpSS.str ( std::string ( ) );
4208  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4209  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4210  columnIter += 1;
4211 
4212  hlpSS.str ( std::string ( ) );
4213  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
4214  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4215  columnIter += 1;
4216 
4217  // ... Row headers
4218  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
4219  {
4220  std::stringstream hlpSS2;
4221  hlpSS2 << "Symmetry axis #" << icoIt+1;
4222  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
4223  }
4224 
4225  // ... Fill in data
4226  int prec = 4;
4227  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
4228  {
4229  std::stringstream hlpSS2;
4230  hlpSS2 << "C";
4231  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
4232 
4233  hlpSS2.str ( std::string ( ) );
4234  hlpSS2 << static_cast<int> ( this->tetrAxes.at(icoIt)[0] );
4235  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
4236 
4237  hlpSS2.str ( std::string ( ) );
4238  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[1], prec );
4239  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
4240 
4241  hlpSS2.str ( std::string ( ) );
4242  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[2], prec );
4243  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
4244 
4245  hlpSS2.str ( std::string ( ) );
4246  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[3], prec );
4247  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
4248 
4249  hlpSS2.str ( std::string ( ) );
4250  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->tetrAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
4251  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
4252 
4253  hlpSS2.str ( std::string ( ) );
4254  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[4], prec );
4255  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
4256  }
4257 
4258  //============================ Symmetry elements table
4259  rvapi_add_table ( "SymmetryElementsTable",
4260  "Detected symmetry elements",
4261  "ResultsSection",
4262  static_cast<unsigned int> ( this->tetrAxes.size() ) + 1,
4263  0,
4264  static_cast<unsigned int> ( this->tetrElems.size() ),
4265  7,
4266  -1 );
4267  totTabRows = static_cast<unsigned int> ( this->tetrAxes.size() ) + 1 + static_cast<unsigned int> ( this->tetrElems.size() );
4268 
4269  // ... Column headers
4270  columnIter = 0;
4271 
4272  hlpSS.str ( std::string ( ) );
4273  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4274  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4275  columnIter += 1;
4276 
4277  hlpSS.str ( std::string ( ) );
4278  hlpSS << "This column states the symmetry element fold.";
4279  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4280  columnIter += 1;
4281 
4282  hlpSS.str ( std::string ( ) );
4283  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4284  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4285  columnIter += 1;
4286 
4287  hlpSS.str ( std::string ( ) );
4288  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4289  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4290  columnIter += 1;
4291 
4292  hlpSS.str ( std::string ( ) );
4293  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4294  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4295  columnIter += 1;
4296 
4297  hlpSS.str ( std::string ( ) );
4298  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4299  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4300  columnIter += 1;
4301 
4302  // ... Row headers
4303  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
4304  {
4305  std::stringstream hlpSS2;
4306  hlpSS2 << "Symmetry element #" << icoIt+1;
4307  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4308  }
4309 
4310  // ... Fill in data
4311  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
4312  {
4313  std::stringstream hlpSS3;
4314  if ( this->tetrElems.at(icoIt)[0] != 1.0 )
4315  {
4316  std::stringstream hlpSS2;
4317  hlpSS2 << "C";
4318  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
4319  }
4320  else
4321  {
4322  std::stringstream hlpSS2;
4323  hlpSS2 << "E";
4324  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
4325  }
4326 
4327  hlpSS3.str ( std::string ( ) );
4328  hlpSS3 << static_cast<int> ( this->tetrElems.at(icoIt)[0] );
4329  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 1 );
4330 
4331  hlpSS3.str ( std::string ( ) );
4332  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[1], prec );
4333  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 2 );
4334 
4335  hlpSS3.str ( std::string ( ) );
4336  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[2], prec );
4337  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 3 );
4338 
4339  hlpSS3.str ( std::string ( ) );
4340  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[3], prec );
4341  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 4 );
4342 
4343  hlpSS3.str ( std::string ( ) );
4344  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[4], prec );
4345  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 5 );
4346  }
4347 
4348  rvapi_flush ( );
4349  }
4350  else
4351  {
4352  std::stringstream hlpSS;
4353  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << "</font></b>";
4354  rvapi_set_text ( hlpSS.str().c_str(),
4355  "ResultsSection",
4356  0,
4357  0,
4358  1,
4359  1 );
4360  rvapi_flush ( );
4361  foundRequest = false;
4362  }
4363  }
4364 
4365  if ( symmetryType == "D" )
4366  {
4367  if ( static_cast<unsigned int> ( this->dnSymm.size() ) > 0 )
4368  {
4369  bool reqFound = false;
4370  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->dnSymm.size() ); dIt++ )
4371  {
4372  if ( reqFound ) { break; }
4373  unsigned int howManyTwos = 0;
4374  for ( unsigned int dItt = 0; dItt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); dItt++ )
4375  {
4376  if ( reqFound ) { break; }
4377  if ( symmetryFold != 2 )
4378  {
4379  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold )
4380  {
4381  std::stringstream hlpSS;
4382  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry as requested." << "</b>";
4383  rvapi_set_text ( hlpSS.str().c_str(),
4384  "ResultsSection",
4385  0,
4386  0,
4387  1,
4388  1 );
4389  rvapi_flush ( );
4390 
4391  //======================== Symmetry axes table
4392  rvapi_add_table ( "SymmetryTypeTable",
4393  "Detected symmetry axes",
4394  "ResultsSection",
4395  1,
4396  0,
4397  this->dnSymm.at(dIt).size(),
4398  8,
4399  1 );
4400 
4401  // ... Column headers
4402  int columnIter = 0;
4403 
4404  hlpSS.str ( std::string ( ) );
4405  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4406  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4407  columnIter += 1;
4408 
4409  hlpSS.str ( std::string ( ) );
4410  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4411  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4412  columnIter += 1;
4413 
4414  hlpSS.str ( std::string ( ) );
4415  hlpSS << "This column states the x-axis element of the symmetry axis.";
4416  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4417  columnIter += 1;
4418 
4419  hlpSS.str ( std::string ( ) );
4420  hlpSS << "This column states the y-axis element of the symmetry axis.";
4421  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4422  columnIter += 1;
4423 
4424  hlpSS.str ( std::string ( ) );
4425  hlpSS << "This column states the z-axis element of the symmetry axis.";
4426  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4427  columnIter += 1;
4428 
4429  hlpSS.str ( std::string ( ) );
4430  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4431  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4432  columnIter += 1;
4433 
4434  hlpSS.str ( std::string ( ) );
4435  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
4436  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4437  columnIter += 1;
4438 
4439  // ... Row headers
4440  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); icoIt++ )
4441  {
4442  hlpSS.str ( std::string ( ) );
4443  hlpSS << "Symmetry axis #" << icoIt+1;
4444  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", icoIt );
4445  }
4446 
4447  // ... Fill in data
4448  int prec = 4;
4449  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4450  {
4451  std::stringstream hlpSS2;
4452  hlpSS2 << "C";
4453  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 0 );
4454 
4455  hlpSS2.str ( std::string ( ) );
4456  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4457  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 1 );
4458 
4459  hlpSS2.str ( std::string ( ) );
4460  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4461  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 2 );
4462 
4463  hlpSS2.str ( std::string ( ) );
4464  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4465  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 3 );
4466 
4467  hlpSS2.str ( std::string ( ) );
4468  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4469  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 4 );
4470 
4471  hlpSS2.str ( std::string ( ) );
4472  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) * ( 180.0 / M_PI ), prec );
4473  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 5 );
4474 
4475  hlpSS2.str ( std::string ( ) );
4476  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[4], prec );
4477  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 6 );
4478  }
4479 
4480  //======================== Symmetry elements table
4481  int totRows = 0;
4482  for ( unsigned int it = 0; it < 2; it++ )
4483  {
4484  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4485  {
4486  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4487  {
4488  if ( iter == 0 ) { continue; }
4489  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4490 
4491  totRows += 1;
4492  }
4493  }
4494  else
4495  {
4496  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4497  {
4498  if ( iter == 0 ) { continue; }
4499 
4500  totRows += 1;
4501  }
4502  }
4503  }
4504  totRows += 1;
4505 
4506  rvapi_add_table ( "SymmetryElementsTable",
4507  "Detected symmetry elements",
4508  "ResultsSection",
4509  this->dnSymm.at(dIt).size() + 1,
4510  0,
4511  totRows,
4512  7,
4513  -1 );
4514  totTabRows = static_cast<unsigned int> ( totRows ) + this->dnSymm.at(dIt).size() + 1;
4515 
4516  // ... Column headers
4517  columnIter = 0;
4518 
4519  hlpSS.str ( std::string ( ) );
4520  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4521  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4522  columnIter += 1;
4523 
4524  hlpSS.str ( std::string ( ) );
4525  hlpSS << "This column states the symmetry element fold.";
4526  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4527  columnIter += 1;
4528 
4529  hlpSS.str ( std::string ( ) );
4530  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4531  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4532  columnIter += 1;
4533 
4534  hlpSS.str ( std::string ( ) );
4535  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4536  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4537  columnIter += 1;
4538 
4539  hlpSS.str ( std::string ( ) );
4540  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4541  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4542  columnIter += 1;
4543 
4544  hlpSS.str ( std::string ( ) );
4545  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4546  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4547  columnIter += 1;
4548 
4549  // ... Row headers
4550  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
4551  {
4552  std::stringstream hlpSS2;
4553  hlpSS2 << "Symmetry element #" << icoIt+1;
4554  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4555  }
4556 
4557  // ... Fill in data
4558  int rowCount = 1;
4559 
4560  hlpSS.str ( std::string ( ) );
4561  hlpSS << "E";
4562  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
4563 
4564  hlpSS.str ( std::string ( ) );
4565  hlpSS << static_cast<int> ( 1 );
4566  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
4567 
4568  hlpSS.str ( std::string ( ) );
4569  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
4570  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
4571 
4572  hlpSS.str ( std::string ( ) );
4573  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4574  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
4575 
4576  hlpSS.str ( std::string ( ) );
4577  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4578  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
4579 
4580  hlpSS.str ( std::string ( ) );
4581  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4582  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
4583 
4584  for ( unsigned int it = 0; it < 2; it++ )
4585  {
4586  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4587  {
4588  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4589  {
4590  if ( iter == 0 ) { continue; }
4591  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4592 
4593  std::stringstream hlpSS2;
4594  hlpSS2 << "C";
4595  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4596 
4597  hlpSS2.str ( std::string ( ) );
4598  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4599  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4600 
4601  hlpSS2.str ( std::string ( ) );
4602  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4603  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4604 
4605  hlpSS2.str ( std::string ( ) );
4606  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4607  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4608 
4609  hlpSS2.str ( std::string ( ) );
4610  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4611  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4612 
4613  hlpSS2.str ( std::string ( ) );
4614  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ), prec );
4615  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4616  rowCount += 1;
4617  }
4618  }
4619  else
4620  {
4621  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4622  {
4623  if ( iter == 0 ) { continue; }
4624 
4625  std::stringstream hlpSS2;
4626  hlpSS2 << "C";
4627  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4628 
4629  hlpSS2.str ( std::string ( ) );
4630  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4631  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4632 
4633  hlpSS2.str ( std::string ( ) );
4634  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4635  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4636 
4637  hlpSS2.str ( std::string ( ) );
4638  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4639  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4640 
4641  hlpSS2.str ( std::string ( ) );
4642  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4643  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4644 
4645  hlpSS2.str ( std::string ( ) );
4646  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ), prec );
4647  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4648  rowCount += 1;
4649  }
4650  }
4651  }
4652 
4653  rvapi_flush ( );
4654  reqFound = true;
4655  break;
4656  }
4657  else
4658  {
4659  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
4660  {
4661  continue;
4662  }
4663  else
4664  {
4665  break;
4666  }
4667  }
4668  }
4669  if ( symmetryFold == 2 )
4670  {
4671  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
4672  {
4673  howManyTwos += 1;
4674  }
4675  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold && howManyTwos == 2 )
4676  {
4677  std::stringstream hlpSS;
4678  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry as requested." << "</b>";
4679  rvapi_set_text ( hlpSS.str().c_str(),
4680  "ResultsSection",
4681  0,
4682  0,
4683  1,
4684  1 );
4685  rvapi_flush ( );
4686 
4687  //======================== Symmetry axes table
4688  rvapi_add_table ( "SymmetryTypeTable",
4689  "Detected symmetry axes",
4690  "ResultsSection",
4691  1,
4692  0,
4693  2,
4694  8,
4695  1 );
4696 
4697  // ... Column headers
4698  int columnIter = 0;
4699 
4700  hlpSS.str ( std::string ( ) );
4701  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4702  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4703  columnIter += 1;
4704 
4705  hlpSS.str ( std::string ( ) );
4706  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4707  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4708  columnIter += 1;
4709 
4710  hlpSS.str ( std::string ( ) );
4711  hlpSS << "This column states the x-axis element of the symmetry axis.";
4712  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4713  columnIter += 1;
4714 
4715  hlpSS.str ( std::string ( ) );
4716  hlpSS << "This column states the y-axis element of the symmetry axis.";
4717  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4718  columnIter += 1;
4719 
4720  hlpSS.str ( std::string ( ) );
4721  hlpSS << "This column states the z-axis element of the symmetry axis.";
4722  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4723  columnIter += 1;
4724 
4725  hlpSS.str ( std::string ( ) );
4726  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4727  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4728  columnIter += 1;
4729 
4730  hlpSS.str ( std::string ( ) );
4731  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
4732  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4733  columnIter += 1;
4734 
4735  // ... Row headers
4736  int rCount = 1;
4737  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); icoIt++ )
4738  {
4739  if ( this->dnSymm.at(dIt).at(icoIt)[0] != 2 ) { continue; }
4740  hlpSS.str ( std::string ( ) );
4741  hlpSS << "Symmetry axis #" << rCount;
4742  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", rCount-1 );
4743  rCount += 1;
4744  }
4745 
4746  // ... Fill in data
4747  int prec = 4;
4748  rCount = 0;
4749  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4750  {
4751  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4752 
4753  std::stringstream hlpSS2;
4754  hlpSS2 << "C";
4755  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 0 );
4756 
4757  hlpSS2.str ( std::string ( ) );
4758  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4759  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 1 );
4760 
4761  hlpSS2.str ( std::string ( ) );
4762  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4763  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 2 );
4764 
4765  hlpSS2.str ( std::string ( ) );
4766  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4767  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 3 );
4768 
4769  hlpSS2.str ( std::string ( ) );
4770  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4771  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 4 );
4772 
4773  hlpSS2.str ( std::string ( ) );
4774  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ) * ( 180.0 / M_PI ), prec );
4775  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 5 );
4776 
4777  hlpSS2.str ( std::string ( ) );
4778  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[4], prec );
4779  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 6 );
4780 
4781  rCount += 1;
4782  }
4783 
4784  //======================== Symmetry elements table
4785  int totRows = 0;
4786  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4787  {
4788  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4789 
4790  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4791  {
4792  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4793  {
4794  if ( iter == 0 ) { continue; }
4795  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4796 
4797  totRows += 1;
4798  }
4799  }
4800  else
4801  {
4802  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4803  {
4804  if ( iter == 0 ) { continue; }
4805 
4806  totRows += 1;
4807  }
4808  }
4809  }
4810  totRows += 1;
4811 
4812  rvapi_add_table ( "SymmetryElementsTable",
4813  "Detected symmetry elements",
4814  "ResultsSection",
4815  this->dnSymm.at(dIt).size() + 1,
4816  0,
4817  totRows,
4818  7,
4819  -1 );
4820  totTabRows = static_cast<unsigned int> ( totRows ) + this->dnSymm.at(dIt).size() + 1;
4821 
4822  // ... Column headers
4823  columnIter = 0;
4824 
4825  hlpSS.str ( std::string ( ) );
4826  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4827  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4828  columnIter += 1;
4829 
4830  hlpSS.str ( std::string ( ) );
4831  hlpSS << "This column states the symmetry element fold.";
4832  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4833  columnIter += 1;
4834 
4835  hlpSS.str ( std::string ( ) );
4836  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4837  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4838  columnIter += 1;
4839 
4840  hlpSS.str ( std::string ( ) );
4841  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4842  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4843  columnIter += 1;
4844 
4845  hlpSS.str ( std::string ( ) );
4846  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4847  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4848  columnIter += 1;
4849 
4850  hlpSS.str ( std::string ( ) );
4851  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4852  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4853  columnIter += 1;
4854 
4855  // ... Row headers
4856  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
4857  {
4858  std::stringstream hlpSS2;
4859  hlpSS2 << "Symmetry element #" << icoIt+1;
4860  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4861  }
4862 
4863  // ... Fill in data
4864  int rowCount = 1;
4865 
4866  hlpSS.str ( std::string ( ) );
4867  hlpSS << "E";
4868  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
4869 
4870  hlpSS.str ( std::string ( ) );
4871  hlpSS << static_cast<int> ( 1 );
4872  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
4873 
4874  hlpSS.str ( std::string ( ) );
4875  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
4876  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
4877 
4878  hlpSS.str ( std::string ( ) );
4879  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4880  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
4881 
4882  hlpSS.str ( std::string ( ) );
4883  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4884  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
4885 
4886  hlpSS.str ( std::string ( ) );
4887  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4888  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
4889 
4890  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4891  {
4892  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4893  {
4894  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4895 
4896  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4897  {
4898  if ( iter == 0 ) { continue; }
4899  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4900 
4901  std::stringstream hlpSS2;
4902  hlpSS2 << "C";
4903  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4904 
4905  hlpSS2.str ( std::string ( ) );
4906  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4907  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4908 
4909  hlpSS2.str ( std::string ( ) );
4910  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4911  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4912 
4913  hlpSS2.str ( std::string ( ) );
4914  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4915  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4916 
4917  hlpSS2.str ( std::string ( ) );
4918  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4919  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4920 
4921  hlpSS2.str ( std::string ( ) );
4922  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ), prec );
4923  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4924  rowCount += 1;
4925  }
4926  }
4927  else
4928  {
4929  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4930 
4931  for ( int iter = -std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ); iter++ )
4932  {
4933  if ( iter == 0 ) { continue; }
4934 
4935  std::stringstream hlpSS2;
4936  hlpSS2 << "C";
4937  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4938 
4939  hlpSS2.str ( std::string ( ) );
4940  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4941  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4942 
4943  hlpSS2.str ( std::string ( ) );
4944  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4945  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4946 
4947  hlpSS2.str ( std::string ( ) );
4948  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4949  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4950 
4951  hlpSS2.str ( std::string ( ) );
4952  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4953  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4954 
4955  hlpSS2.str ( std::string ( ) );
4956  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymm.at(dIt).at(it)[0] ) ), prec );
4957  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4958  rowCount += 1;
4959  }
4960  }
4961  }
4962 
4963  rvapi_flush ( );
4964  reqFound = true;
4965  break;
4966  }
4967  }
4968  }
4969  }
4970  if ( !reqFound )
4971  {
4972  std::stringstream hlpSS;
4973  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested dihedral symmetry, but detected dihedral symmetries with different fold. You can try changing the resolution or selecting one of the alternative symmetries printed below." << "</font></b>";
4974  rvapi_set_text ( hlpSS.str().c_str(),
4975  "ResultsSection",
4976  0,
4977  0,
4978  1,
4979  1 );
4980  rvapi_flush ( );
4981  foundRequest = false;
4982  }
4983  }
4984  else
4985  {
4986  std::stringstream hlpSS;
4987  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << "</font></b>";
4988  rvapi_set_text ( hlpSS.str().c_str(),
4989  "ResultsSection",
4990  0,
4991  0,
4992  1,
4993  1 );
4994  rvapi_flush ( );
4995  foundRequest = false;
4996  }
4997  }
4998 
4999  if ( symmetryType == "C" )
5000  {
5001  if ( static_cast<unsigned int> ( this->cnSymm.size() ) > 0 )
5002  {
5003  bool reqFound = false;
5004  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->cnSymm.size() ); dIt++ )
5005  {
5006  if ( this->cnSymm.at(dIt)[0] == symmetryFold )
5007  {
5008  //==================== State result
5009  std::stringstream hlpSS;
5010  hlpSS << "<b>" << "Detected <i>CYCLIC</i> symmetry as requested." << "</b>";
5011  rvapi_set_text ( hlpSS.str().c_str(),
5012  "ResultsSection",
5013  0,
5014  0,
5015  1,
5016  1 );
5017  rvapi_flush ( );
5018 
5019  //==================== Symmetry axes table
5020  rvapi_add_table ( "SymmetryTypeTable",
5021  "Detected symmetry axes",
5022  "ResultsSection",
5023  1,
5024  0,
5025  2,
5026  8,
5027  2 );
5028 
5029  // ... Column headers
5030  int columnIter = 0;
5031 
5032  hlpSS.str ( std::string ( ) );
5033  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
5034  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
5035  columnIter += 1;
5036 
5037  hlpSS.str ( std::string ( ) );
5038  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
5039  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
5040  columnIter += 1;
5041 
5042  hlpSS.str ( std::string ( ) );
5043  hlpSS << "This column states the x-axis element of the symmetry axis.";
5044  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5045  columnIter += 1;
5046 
5047  hlpSS.str ( std::string ( ) );
5048  hlpSS << "This column states the y-axis element of the symmetry axis.";
5049  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5050  columnIter += 1;
5051 
5052  hlpSS.str ( std::string ( ) );
5053  hlpSS << "This column states the z-axis element of the symmetry axis.";
5054  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5055  columnIter += 1;
5056 
5057  hlpSS.str ( std::string ( ) );
5058  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5059  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5060  columnIter += 1;
5061 
5062  hlpSS.str ( std::string ( ) );
5063  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
5064  rvapi_put_horz_theader( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
5065  columnIter += 1;
5066 
5067  // ... Row headers
5068  hlpSS.str ( std::string ( ) );
5069  hlpSS << "Symmetry axis #" << 1;
5070  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS.str().c_str(), "", 0 );
5071 
5072  // ... Fill in data
5073  int prec = 4;
5074  hlpSS.str ( std::string ( ) );
5075  hlpSS << "C";
5076  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 0 );
5077 
5078  hlpSS.str ( std::string ( ) );
5079  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5080  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 1 );
5081 
5082  hlpSS.str ( std::string ( ) );
5083  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5084  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 2 );
5085 
5086  hlpSS.str ( std::string ( ) );
5087  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5088  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 3 );
5089 
5090  hlpSS.str ( std::string ( ) );
5091  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5092  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 4 );
5093 
5094  hlpSS.str ( std::string ( ) );
5095  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->cnSymm.at(dIt)[0] ) ) * ( 180.0 / M_PI ), prec );
5096  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 5 );
5097 
5098  hlpSS.str ( std::string ( ) );
5099  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[4], prec );
5100  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 6 );
5101 
5102  //==================== Symmetry elements table
5103  int totRows = 0;
5104  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
5105  {
5106  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
5107  {
5108  if ( iter == 0 ) { continue; }
5109  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
5110 
5111  totRows += 1;
5112  }
5113  }
5114  else
5115  {
5116  for ( int iter = -std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
5117  {
5118  if ( iter == 0 ) { continue; }
5119 
5120  totRows += 1;
5121  }
5122  }
5123  totRows += 1;
5124 
5125  rvapi_add_table ( "SymmetryElementsTable",
5126  "Detected symmetry elements",
5127  "ResultsSection",
5128  3,
5129  0,
5130  totRows,
5131  7,
5132  -1 );
5133  totTabRows = static_cast<unsigned int> ( totRows ) + 3;
5134 
5135  // ... Column headers
5136  columnIter = 0;
5137 
5138  hlpSS.str ( std::string ( ) );
5139  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
5140  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
5141  columnIter += 1;
5142 
5143  hlpSS.str ( std::string ( ) );
5144  hlpSS << "This column states the symmetry element fold.";
5145  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
5146  columnIter += 1;
5147 
5148  hlpSS.str ( std::string ( ) );
5149  hlpSS << "This column states the x-axis element of the symmetry element axis.";
5150  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5151  columnIter += 1;
5152 
5153  hlpSS.str ( std::string ( ) );
5154  hlpSS << "This column states the y-axis element of the symmetry element axis.";
5155  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5156  columnIter += 1;
5157 
5158  hlpSS.str ( std::string ( ) );
5159  hlpSS << "This column states the z-axis element of the symmetry element axis.";
5160  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5161  columnIter += 1;
5162 
5163  hlpSS.str ( std::string ( ) );
5164  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
5165  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5166  columnIter += 1;
5167 
5168  // ... Row headers
5169  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
5170  {
5171  std::stringstream hlpSS2;
5172  hlpSS2 << "Symmetry element #" << std::to_string ( icoIt+1 );
5173  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
5174  }
5175 
5176  // ... Fill in data
5177  int rowCount = 1;
5178 
5179  hlpSS.str ( std::string ( ) );
5180  hlpSS << "E";
5181  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
5182 
5183  hlpSS.str ( std::string ( ) );
5184  hlpSS << static_cast<int> ( 1 );
5185  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
5186 
5187  hlpSS.str ( std::string ( ) );
5188  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
5189  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
5190 
5191  hlpSS.str ( std::string ( ) );
5192  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5193  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
5194 
5195  hlpSS.str ( std::string ( ) );
5196  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5197  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
5198 
5199  hlpSS.str ( std::string ( ) );
5200  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5201  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
5202 
5203  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
5204  {
5205  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
5206  {
5207  if ( iter == 0 ) { continue; }
5208  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
5209 
5210  hlpSS.str ( std::string ( ) );
5211  hlpSS << "C";
5212  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
5213 
5214  hlpSS.str ( std::string ( ) );
5215  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5216  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
5217 
5218  hlpSS.str ( std::string ( ) );
5219  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5220  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
5221 
5222  hlpSS.str ( std::string ( ) );
5223  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5224  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
5225 
5226  hlpSS.str ( std::string ( ) );
5227  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5228  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
5229 
5230  hlpSS.str ( std::string ( ) );
5231  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->cnSymm.at(dIt)[0] ) ), prec );
5232  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
5233  rowCount += 1;
5234  }
5235  }
5236  else
5237  {
5238  for ( int iter = -std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ); iter++ )
5239  {
5240  if ( iter == 0 ) { continue; }
5241 
5242  hlpSS.str ( std::string ( ) );
5243  hlpSS << "C";
5244  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
5245 
5246  hlpSS.str ( std::string ( ) );
5247  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5248  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
5249 
5250  hlpSS.str ( std::string ( ) );
5251  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5252  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
5253 
5254  hlpSS.str ( std::string ( ) );
5255  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5256  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
5257 
5258  hlpSS.str ( std::string ( ) );
5259  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5260  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
5261 
5262  hlpSS.str ( std::string ( ) );
5263  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->cnSymm.at(dIt)[0] ) ), prec );
5264  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
5265  rowCount += 1;
5266  }
5267  }
5268 
5269  rvapi_flush ( );
5270  reqFound = true;
5271  break;
5272  }
5273  }
5274  if ( !reqFound )
5275  {
5276  std::stringstream hlpSS;
5277  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested cyclic symmetry, but detected other cyclic symmetries with different fold. You can try changing the resolution or selecting one of the alternative symmetries printed below." << "</font></b>";
5278  rvapi_set_text ( hlpSS.str().c_str(),
5279  "ResultsSection",
5280  0,
5281  0,
5282  1,
5283  1 );
5284  rvapi_flush ( );
5285  foundRequest = false;
5286  }
5287  }
5288  else
5289  {
5290  std::stringstream hlpSS;
5291  hlpSS << "<b><font color=\"orange\">" << "Could not detect the requested symmetry. You can try changing the resolution or searching for different symmetry from the alternatives list printed below." << "</font></b>";
5292  rvapi_set_text ( hlpSS.str().c_str(),
5293  "ResultsSection",
5294  0,
5295  0,
5296  1,
5297  1 );
5298  rvapi_flush ( );
5299  foundRequest = false;
5300  }
5301  }
5302 
5303  //======================================== Print alternatives
5304  if ( foundRequest )
5305  {
5306  rvapi_add_table ( "AlternativesTable",
5307  "Alternative Symmetries Detected",
5308  "ResultsSection",
5309  totTabRows,
5310  0,
5311  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ) +
5312  static_cast<unsigned int> ( this->tetrSymm.size() ) + static_cast<unsigned int> ( this->octaSymm.size() ) +
5313  static_cast<unsigned int> ( this->icosSymm.size() ),
5314  7,
5315  -1 );
5316  }
5317  else
5318  {
5319  rvapi_add_table ( "AlternativesTable",
5320  "Alternative Symmetries Detected",
5321  "ResultsSection",
5322  totTabRows,
5323  0,
5324  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ) +
5325  static_cast<unsigned int> ( this->tetrSymm.size() ) + static_cast<unsigned int> ( this->octaSymm.size() ) +
5326  static_cast<unsigned int> ( this->icosSymm.size() ),
5327  7,
5328  1 );
5329  }
5330 
5331  // ... Column headers
5332  int columnIter = 0;
5333 
5334  std::stringstream hlpSS;
5335  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D).";
5336  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
5337  columnIter += 1;
5338 
5339  hlpSS.str ( std::string ( ) );
5340  hlpSS << "This column states the symmetry fold.";
5341  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
5342  columnIter += 1;
5343 
5344  hlpSS.str ( std::string ( ) );
5345  hlpSS << "This column states the x-axis element of the symmetry axis.";
5346  rvapi_put_horz_theader ( "AlternativesTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5347  columnIter += 1;
5348 
5349  hlpSS.str ( std::string ( ) );
5350  hlpSS << "This column states the y-axis element of the symmetry axis.";
5351  rvapi_put_horz_theader ( "AlternativesTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5352  columnIter += 1;
5353 
5354  hlpSS.str ( std::string ( ) );
5355  hlpSS << "This column states the z-axis element of the symmetry axis.";
5356  rvapi_put_horz_theader ( "AlternativesTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5357  columnIter += 1;
5358 
5359  hlpSS.str ( std::string ( ) );
5360  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5361  rvapi_put_horz_theader ( "AlternativesTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5362  columnIter += 1;
5363 
5364  hlpSS.str ( std::string ( ) );
5365  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
5366  rvapi_put_horz_theader ( "AlternativesTable", "Peak Height", hlpSS.str().c_str(), columnIter );
5367  columnIter += 1;
5368 
5369  // ... Row headers
5370  int maxCAlts = 0;
5371  int maxDAlts = 0;
5372  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5373  {
5374  std::stringstream hlpSS2;
5375  hlpSS2 << "Alternative Symmetry #" << gNo+1;
5376  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", gNo );
5377  maxCAlts = gNo;
5378  }
5379  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5380  {
5381  std::stringstream hlpSS2;
5382  hlpSS2 << "Alternative Symmetry #" << iter + maxCAlts + 2;
5383  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", iter + maxCAlts + 1 );
5384  maxDAlts = iter + maxCAlts;
5385  }
5386  maxDAlts += 1;
5387  if ( static_cast<int> ( this->tetrElems.size() ) > 0 )
5388  {
5389  std::stringstream hlpSS2;
5390  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5391  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5392  maxDAlts += 1;
5393  }
5394  if ( static_cast<int> ( this->octaElems.size() ) > 0 )
5395  {
5396  std::stringstream hlpSS2;
5397  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5398  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5399  maxDAlts += 1;
5400  }
5401  if ( static_cast<int> ( this->icosElems.size() ) > 0 )
5402  {
5403  std::stringstream hlpSS2;
5404  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5405  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5406  maxDAlts += 1;
5407  }
5408 
5409  int rowCount = 0;
5410  int prec = 4;
5411  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5412  {
5413  std::stringstream hlpSS2;
5414  hlpSS2 << "C";
5415  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5416 
5417  hlpSS2.str ( std::string ( ) );
5418  hlpSS2 << static_cast<int> ( static_cast<int> ( this->cnSymm.at(gNo)[0] ) );
5419  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5420 
5421  hlpSS2.str ( std::string ( ) );
5422  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[1], prec );
5423  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5424 
5425  hlpSS2.str ( std::string ( ) );
5426  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[2], prec );
5427  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5428 
5429  hlpSS2.str ( std::string ( ) );
5430  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[3], prec );
5431  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5432 
5433  hlpSS2.str ( std::string ( ) );
5434  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->cnSymm.at(gNo)[0] ) ) * ( 180.0 / M_PI ), prec );
5435  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5436 
5437  hlpSS2.str ( std::string ( ) );
5438  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->cnSymm.at(gNo)[4] ), prec );
5439  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5440  rowCount += 1;
5441  }
5442 
5443  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5444  {
5445  std::stringstream hlpSS2;
5446  hlpSS2 << "D";
5447  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5448 
5449  hlpSS2.str ( std::string ( ) );
5450  hlpSS2 << static_cast<int> ( static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ) );
5451  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5452 
5453  hlpSS2.str ( std::string ( ) );
5454  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[1], prec );
5455  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5456 
5457  hlpSS2.str ( std::string ( ) );
5458  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[2], prec );
5459  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5460 
5461  hlpSS2.str ( std::string ( ) );
5462  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[3], prec );
5463  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5464 
5465  hlpSS2.str ( std::string ( ) );
5466  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->dnSymm.at(iter).at(0)[0] ) ) * ( 180.0 / M_PI ), prec );
5467  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5468 
5469  hlpSS2.str ( std::string ( ) );
5470  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->dnSymm.at(iter).at(0)[4] ), prec );
5471  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5472  rowCount += 1;
5473  }
5474 
5475  if ( static_cast<int> ( this->tetrElems.size() ) > 0 )
5476  {
5477  std::stringstream hlpSS2;
5478  hlpSS2 << "T";
5479  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5480 
5481  hlpSS2.str ( std::string ( ) );
5482  hlpSS2 << "N/A";
5483  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5484 
5485  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5486 
5487  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5488 
5489  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5490 
5491  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5492 
5493  hlpSS2.str ( std::string ( ) );
5494  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->tetrSymm.at(0).at(0)[4] ), prec );
5495  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5496  rowCount += 1;
5497  }
5498 
5499  if ( static_cast<int> ( this->octaElems.size() ) > 0 )
5500  {
5501  std::stringstream hlpSS2;
5502  hlpSS2 << "O";
5503  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5504 
5505  hlpSS2.str ( std::string ( ) );
5506  hlpSS2 << "N/A";
5507  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5508 
5509  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5510 
5511  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5512 
5513  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5514 
5515  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5516 
5517  hlpSS2.str ( std::string ( ) );
5518  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->octaSymm.at(0).at(0)[4] ), prec );
5519  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5520  rowCount += 1;
5521  }
5522 
5523  if ( static_cast<int> ( this->icosElems.size() ) > 0 )
5524  {
5525  std::stringstream hlpSS2;
5526  hlpSS2 << "I";
5527  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5528 
5529  hlpSS2.str ( std::string ( ) );
5530  hlpSS2 << "N/A";
5531  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5532 
5533  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5534 
5535  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5536 
5537  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5538 
5539  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5540 
5541  hlpSS2.str ( std::string ( ) );
5542  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->icosSymm.at(0).at(0)[4] ), prec );
5543  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5544  rowCount += 1;
5545  }
5546 
5547  rvapi_flush ( );
5548 
5549  //======================================== Done
5550  return ;
5551 
5552 }
5553 
5565 {
5566  //======================================== Claim the symmetry to be the highest detected
5567  if ( verbose > 0 )
5568  {
5569  printf ( "-----------------------------------------------------------\n" );
5570  printf ( "| RESULTS |\n" );
5571  printf ( "-----------------------------------------------------------\n\n" );
5572  }
5573 
5574  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->icosElems.size() ) == 0 ) )
5575  {
5576  printf ( "This appears like icosahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely.\n\n" );
5577  }
5578 
5579  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
5580  {
5581  printf ( "Detected Icosahedral symmetry\n\n" );
5582  printf ( "Symmetry axes table:\n" );
5583  printf ( "-----------------------------------------------------------\n" );
5584  printf ( "Symmetry Fold x y z Angle Peak\n" );
5585  printf ( " Type height\n" );
5586  printf ( "-----------------------------------------------------------\n" );
5587 
5588  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5589  {
5590  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->icosAxes.at(icoIt)[0] ), this->icosAxes.at(icoIt)[1], this->icosAxes.at(icoIt)[2], this->icosAxes.at(icoIt)[3], static_cast<int> ( this->icosAxes.at(icoIt)[0] ), this->icosAxes.at(icoIt)[4] );
5591  }
5592  printf ( "\n" );
5593 
5594  printf ( "Symmetry elements table:\n" );
5595  printf ( "-----------------------------------------------------------\n" );
5596  printf ( "Symmetry x y z Angle \n" );
5597  printf ( " Type (deg) \n" );
5598  printf ( "-----------------------------------------------------------\n" );
5599 
5600  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
5601  {
5602  if ( this->icosElems.at(icoIt)[0] != 1.0 )
5603  {
5604  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->icosElems.at(icoIt)[0] ), this->icosElems.at(icoIt)[1], this->icosElems.at(icoIt)[2], this->icosElems.at(icoIt)[3], this->icosElems.at(icoIt)[4] );
5605  }
5606  else
5607  {
5608  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->icosElems.at(icoIt)[1], this->icosElems.at(icoIt)[2], this->icosElems.at(icoIt)[3], this->icosElems.at(icoIt)[4] );
5609  }
5610  }
5611  printf ( "\n" );
5612  }
5613  else
5614  {
5615  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
5616  {
5617  printf ( "This appears like octahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely.\n\n" );
5618  }
5619 
5620  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) > 0 ) )
5621  {
5622  printf ( "Detected (Cub)octahedral symmetry\n\n" );
5623  printf ( "Symmetry axes table:\n" );
5624  printf ( "-----------------------------------------------------------\n" );
5625  printf ( "Symmetry Fold x y z Angle Peak\n" );
5626  printf ( " Type height\n" );
5627  printf ( "-----------------------------------------------------------\n" );
5628 
5629  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaAxes.size() ); octIt++ )
5630  {
5631  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->octaAxes.at(octIt)[0] ), this->octaAxes.at(octIt)[1], this->octaAxes.at(octIt)[2], this->octaAxes.at(octIt)[3], static_cast<int> ( this->octaAxes.at(octIt)[0] ), this->octaAxes.at(octIt)[4] );
5632  }
5633  printf ( "\n" );
5634 
5635  printf ( "Symmetry elements table:\n" );
5636  printf ( "-----------------------------------------------------------\n" );
5637  printf ( "Symmetry x y z Angle \n" );
5638  printf ( " Type (deg) \n" );
5639  printf ( "-----------------------------------------------------------\n" );
5640 
5641  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaElems.size() ); octIt++ )
5642  {
5643  if ( this->octaElems.at(octIt)[0] != 1.0 )
5644  {
5645  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->octaElems.at(octIt)[0] ), this->octaElems.at(octIt)[1], this->octaElems.at(octIt)[2], this->octaElems.at(octIt)[3], this->octaElems.at(octIt)[4] );
5646  }
5647  else
5648  {
5649  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->octaElems.at(octIt)[1], this->octaElems.at(octIt)[2], this->octaElems.at(octIt)[3], this->octaElems.at(octIt)[4] );
5650  }
5651  }
5652  printf ( "\n" );
5653  }
5654  else
5655  {
5656  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) == 0 ) )
5657  {
5658  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
5659  {
5660  printf ( "This appears like tetrahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely.\n\n" );
5661  }
5662  }
5663 
5664  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
5665  {
5666  printf ( "Detected Tetrahedral symmetry\n\n" );
5667  printf ( "Symmetry axes table:\n" );
5668  printf ( "-----------------------------------------------------------\n" );
5669  printf ( "Symmetry Fold x y z Angle Peak\n" );
5670  printf ( " Type height\n" );
5671  printf ( "-----------------------------------------------------------\n" );
5672 
5673  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrAxes.size() ); tetIt++ )
5674  {
5675  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->tetrAxes.at(tetIt)[0] ), this->tetrAxes.at(tetIt)[1], this->tetrAxes.at(tetIt)[2], this->tetrAxes.at(tetIt)[3], static_cast<int> ( this->tetrAxes.at(tetIt)[0] ), this->tetrAxes.at(tetIt)[4] );
5676  }
5677  printf ( "\n" );
5678 
5679  printf ( "Symmetry elements table:\n" );
5680  printf ( "-----------------------------------------------------------\n" );
5681  printf ( "Symmetry x y z Angle \n" );
5682  printf ( " Type (deg) \n" );
5683  printf ( "-----------------------------------------------------------\n" );
5684 
5685  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrElems.size() ); tetIt++ )
5686  {
5687  if ( this->tetrElems.at(tetIt)[0] != 1.0 )
5688  {
5689  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->tetrElems.at(tetIt)[0] ), this->tetrElems.at(tetIt)[1], this->tetrElems.at(tetIt)[2], this->tetrElems.at(tetIt)[3], this->tetrElems.at(tetIt)[4] );
5690  }
5691  else
5692  {
5693  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", this->tetrElems.at(tetIt)[1], this->tetrElems.at(tetIt)[2], this->tetrElems.at(tetIt)[3], this->tetrElems.at(tetIt)[4] );
5694  }
5695  }
5696  printf ( "\n" );
5697  }
5698  else
5699  {
5700  if ( static_cast<unsigned int> ( this->dnSymmClear.size() ) > 0 )
5701  {
5702  printf ( "Detected Dihedral symmetry\n\n" );
5703  printf ( "Symmetry axes table:\n" );
5704  printf ( "-----------------------------------------------------------\n" );
5705  printf ( "Symmetry Fold x y z Angle Peak\n" );
5706  printf ( " Type height\n" );
5707  printf ( "-----------------------------------------------------------\n" );
5708  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymmClear.at(0).at(0)[0] ), this->dnSymmClear.at(0).at(0)[1], this->dnSymmClear.at(0).at(0)[2], this->dnSymmClear.at(0).at(0)[3], static_cast<int> ( this->dnSymmClear.at(0).at(0)[0] ), this->dnSymmClear.at(0).at(0)[4] );
5709  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n\n", static_cast<int> ( this->dnSymmClear.at(0).at(1)[0] ), this->dnSymmClear.at(0).at(1)[1], this->dnSymmClear.at(0).at(1)[2], this->dnSymmClear.at(0).at(1)[3], static_cast<int> ( this->dnSymmClear.at(0).at(1)[0] ), this->dnSymmClear.at(0).at(1)[4] );
5710 
5711  printf ( "\n" );
5712 
5713  printf ( "Symmetry elements table:\n" );
5714  printf ( "-----------------------------------------------------------\n" );
5715  printf ( "Symmetry x y z Angle \n" );
5716  printf ( " Type (deg) \n" );
5717  printf ( "-----------------------------------------------------------\n" );
5718 
5719  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
5720  for ( unsigned int it = 0; it < 2; it++ )
5721  {
5722  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
5723  {
5724  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
5725  {
5726  if ( iter == 0 ) { continue; }
5727  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
5728  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ), this->dnSymmClear.at(0).at(it)[1], this->dnSymmClear.at(0).at(it)[2], this->dnSymmClear.at(0).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymmClear.at(0).at(it)[0] ) ) );
5729  }
5730  }
5731  else
5732  {
5733  for ( int iter = -std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
5734  {
5735  if ( iter == 0 ) { continue; }
5736  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ), this->dnSymmClear.at(0).at(it)[1], this->dnSymmClear.at(0).at(it)[2], this->dnSymmClear.at(0).at(it)[3], iter * ( 360.0 / static_cast<double> ( this->dnSymmClear.at(0).at(it)[0] ) ) );
5737  }
5738  }
5739  }
5740 
5741  printf ( "\n" );
5742  }
5743  else
5744  {
5745  if ( static_cast<unsigned int> ( this->cnSymmClear.size() ) > 0 )
5746  {
5747  printf ( "Detected Cyclic symmetry\n\n" );
5748  printf ( "Symmetry axes table:\n" );
5749  printf ( "-----------------------------------------------------------\n" );
5750  printf ( "Symmetry Fold x y z Angle Peak\n" );
5751  printf ( " Type height\n" );
5752  printf ( "-----------------------------------------------------------\n" );
5753  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n\n", static_cast<int> ( this->cnSymmClear.at(0)[0] ), this->cnSymmClear.at(0)[1], this->cnSymmClear.at(0)[2], this->cnSymmClear.at(0)[3], static_cast<int> ( this->cnSymmClear.at(0)[0] ), static_cast<double> ( this->cnSymmClear.at(0)[4] ) );
5754 
5755  printf ( "\n" );
5756 
5757  printf ( "Symmetry elements table:\n" );
5758  printf ( "-----------------------------------------------------------\n" );
5759  printf ( "Symmetry x y z Angle \n" );
5760  printf ( " Type (deg) \n" );
5761  printf ( "-----------------------------------------------------------\n" );
5762 
5763  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
5764  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
5765  {
5766  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
5767  {
5768  if ( iter == 0 ) { continue; }
5769  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
5770  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->cnSymmClear.at(0)[0] ), this->cnSymmClear.at(0)[1], this->cnSymmClear.at(0)[2], this->cnSymmClear.at(0)[3], iter * ( 360.0 / static_cast<double> ( this->cnSymmClear.at(0)[0] ) ) );
5771  }
5772  }
5773  else
5774  {
5775  for ( int iter = -std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
5776  {
5777  if ( iter == 0 ) { continue; }
5778  printf ( " C%d %+.2f %+.2f %+.2f %+.1f \n", static_cast<int> ( this->cnSymmClear.at(0)[0] ), this->cnSymmClear.at(0)[1], this->cnSymmClear.at(0)[2], this->cnSymmClear.at(0)[3], iter * ( 360.0 / static_cast<double> ( this->cnSymmClear.at(0)[0] ) ) );
5779  }
5780  }
5781  printf ( "\n" );
5782  }
5783  else
5784  {
5785  printf ( "Detected no symmetry.\n\n" );
5786  }
5787  }
5788  }
5789  }
5790  }
5791 
5792  //======================================== Print alternativs
5793  printf ( "Alternatives:\n" );
5794  printf ( "-----------------------------------------------------------\n" );
5795  printf ( "Symmetry Fold x y z Angle Peak\n" );
5796  printf ( " Type height\n" );
5797  printf ( "-----------------------------------------------------------\n" );
5798  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5799  {
5800  printf ( " C %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->cnSymm.at(gNo)[0] ), this->cnSymm.at(gNo)[1], this->cnSymm.at(gNo)[2], this->cnSymm.at(gNo)[3], static_cast<int> ( this->cnSymm.at(gNo)[0] ), static_cast<double> ( this->cnSymm.at(gNo)[4] ) );
5801  }
5802 
5803  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5804  {
5805  printf ( " D %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ), this->dnSymm.at(iter).at(0)[1], this->dnSymm.at(iter).at(0)[2], this->dnSymm.at(iter).at(0)[3], static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ), this->dnSymm.at(iter).at(0)[5] );
5806 
5807  for ( unsigned int mem = 1; mem < static_cast<unsigned int> ( this->dnSymm.at(iter).size() ); mem++ )
5808  {
5809  printf ( " %d %+.2f %+.2f %+.2f 2pi / %d %+.3f\n", static_cast<int> ( this->dnSymm.at(iter).at(mem)[0] ), this->dnSymm.at(iter).at(mem)[1], this->dnSymm.at(iter).at(mem)[2], this->dnSymm.at(iter).at(mem)[3], static_cast<int> ( this->dnSymm.at(iter).at(mem)[0] ), this->dnSymm.at(iter).at(mem)[5] );
5810  }
5811  }
5812 
5813  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
5814 
5815  //======================================== Done
5816  return ;
5817 
5818 }
5819 
5831 {
5832  //======================================== Claim the symmetry to be the highest detected
5833  if ( settings->htmlReport )
5834  {
5835  //==================================== Create review section
5836  rvapi_add_section ( "ReviewSection",
5837  "Review",
5838  "body",
5839  settings->htmlReportLine,
5840  0,
5841  1,
5842  1,
5843  false );
5844  settings->htmlReportLine += 1;
5845 
5846  std::stringstream hlpSS;
5847  hlpSS << "<pre>" << "Requested symmetry : " << "N/A" << "</pre>";
5848  rvapi_set_text ( hlpSS.str().c_str(),
5849  "ReviewSection",
5850  0,
5851  0,
5852  1,
5853  1 );
5854 
5855  hlpSS.str ( std::string ( ) );
5856  hlpSS << "<pre>" << "Input structure : " << this->structFiles.at(0) << "</pre>";
5857  rvapi_set_text ( hlpSS.str().c_str(),
5858  "ReviewSection",
5859  1,
5860  0,
5861  1,
5862  1 );
5863  rvapi_flush ( );
5864 
5865  //==================================== Create results section
5866  rvapi_add_section ( "ResultsSection",
5867  "Results",
5868  "body",
5869  settings->htmlReportLine,
5870  0,
5871  1,
5872  1,
5873  true );
5874  settings->htmlReportLine += 1;
5875  }
5876 
5877  int totTabRows = 0;
5878 
5879  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) == 0 ) )
5880  {
5881  //==================================== State result
5882  std::stringstream hlpSS;
5883  hlpSS << "<b><font color=\"orange\">" << "This appears like icosahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely." << "</font></b>";
5884  rvapi_set_text ( hlpSS.str().c_str(),
5885  "ResultsSection",
5886  0,
5887  0,
5888  1,
5889  1 );
5890  rvapi_flush ( );
5891  }
5892 
5893  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
5894  {
5895  //==================================== State result
5896  std::stringstream hlpSS;
5897  hlpSS << "<b>" << "Detected <i>ICOSAHEDRAL</i> symmetry." << "</b>";
5898  rvapi_set_text ( hlpSS.str().c_str(),
5899  "ResultsSection",
5900  1,
5901  0,
5902  1,
5903  1 );
5904  rvapi_flush ( );
5905 
5906  //==================================== Symmetry axes table
5907  rvapi_add_table ( "SymmetryTypeTable",
5908  "Detected symmetry axes",
5909  "ResultsSection",
5910  2,
5911  0,
5912  static_cast<unsigned int> ( this->icosAxes.size() ),
5913  8,
5914  1 );
5915 
5916  // ... Column headers
5917  int columnIter = 0;
5918 
5919  hlpSS.str ( std::string ( ) );
5920  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
5921  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
5922  columnIter += 1;
5923 
5924  hlpSS.str ( std::string ( ) );
5925  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
5926  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
5927  columnIter += 1;
5928 
5929  hlpSS.str ( std::string ( ) );
5930  hlpSS << "This column states the x-axis element of the symmetry axis.";
5931  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5932  columnIter += 1;
5933 
5934  hlpSS.str ( std::string ( ) );
5935  hlpSS << "This column states the y-axis element of the symmetry axis.";
5936  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5937  columnIter += 1;
5938 
5939  hlpSS.str ( std::string ( ) );
5940  hlpSS << "This column states the z-axis element of the symmetry axis.";
5941  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5942  columnIter += 1;
5943 
5944  hlpSS.str ( std::string ( ) );
5945  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5946  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5947  columnIter += 1;
5948 
5949  hlpSS.str ( std::string ( ) );
5950  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
5951  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
5952  columnIter += 1;
5953 
5954  // ... Row headers
5955  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5956  {
5957  std::stringstream hlpSS2;
5958  hlpSS2 << "Symmetry axis #" << icoIt+1;
5959  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
5960  }
5961 
5962  // ... Fill in data
5963  int prec = 4;
5964  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5965  {
5966  std::stringstream hlpSS2;
5967  hlpSS2 << "C";
5968  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
5969 
5970  hlpSS2.str ( std::string ( ) );
5971  hlpSS2 << static_cast<int> ( this->icosAxes.at(icoIt)[0] );
5972  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
5973 
5974  hlpSS2.str ( std::string ( ) );
5975  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[1], prec );
5976  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
5977 
5978  hlpSS2.str ( std::string ( ) );
5979  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[2], prec );
5980  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
5981 
5982  hlpSS2.str ( std::string ( ) );
5983  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[3], prec );
5984  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
5985 
5986  hlpSS2.str ( std::string ( ) );
5987  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->icosAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
5988  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
5989 
5990  hlpSS2.str ( std::string ( ) );
5991  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[4], prec );
5992  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
5993  }
5994 
5995  //==================================== Symmetry elements table
5996  rvapi_add_table ( "SymmetryElementsTable",
5997  "Detected symmetry elements",
5998  "ResultsSection",
5999  static_cast<unsigned int> ( this->icosAxes.size() ) + 2,
6000  0,
6001  static_cast<unsigned int> ( this->icosElems.size() ),
6002  7,
6003  -1 );
6004  totTabRows = static_cast<unsigned int> ( this->icosAxes.size() ) + 2 + static_cast<unsigned int> ( this->icosElems.size() );
6005 
6006  // ... Column headers
6007  columnIter = 0;
6008 
6009  hlpSS.str ( std::string ( ) );
6010  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6011  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6012  columnIter += 1;
6013 
6014  hlpSS.str ( std::string ( ) );
6015  hlpSS << "This column states the symmetry element fold.";
6016  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6017  columnIter += 1;
6018 
6019  hlpSS.str ( std::string ( ) );
6020  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6021  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6022  columnIter += 1;
6023 
6024  hlpSS.str ( std::string ( ) );
6025  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6026  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6027  columnIter += 1;
6028 
6029  hlpSS.str ( std::string ( ) );
6030  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6031  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6032  columnIter += 1;
6033 
6034  hlpSS.str ( std::string ( ) );
6035  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6036  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6037  columnIter += 1;
6038 
6039  // ... Row headers
6040  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
6041  {
6042  std::stringstream hlpSS2;
6043  hlpSS2 << "Symmetry element #" << icoIt+1;
6044  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6045  }
6046 
6047  // ... Fill in data
6048  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
6049  {
6050  if ( this->icosElems.at(icoIt)[0] != 1.0 )
6051  {
6052  std::stringstream hlpSS3;
6053  hlpSS3 << "C";
6054  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6055  }
6056  else
6057  {
6058  std::stringstream hlpSS3;
6059  hlpSS3 << "E";
6060  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6061  }
6062 
6063  std::stringstream hlpSS2;
6064  hlpSS2 << static_cast<int> ( this->icosElems.at(icoIt)[0] );
6065  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
6066 
6067  hlpSS2.str ( std::string ( ) );
6068  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[1], prec );
6069  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
6070 
6071  hlpSS2.str ( std::string ( ) );
6072  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[2], prec );
6073  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
6074 
6075  hlpSS2.str ( std::string ( ) );
6076  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[3], prec );
6077  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
6078 
6079  hlpSS2.str ( std::string ( ) );
6080  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[4], prec );
6081  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
6082  }
6083 
6084  rvapi_flush ( );
6085  }
6086  else
6087  {
6088  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
6089  {
6090  //==================================== State result
6091  std::stringstream hlpSS;
6092  hlpSS << "<b><font color=\"orange\">" << "This appears like octahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely." << "</font></b>";
6093  rvapi_set_text ( hlpSS.str().c_str(),
6094  "ResultsSection",
6095  0,
6096  0,
6097  1,
6098  1 );
6099  rvapi_flush ( );
6100  }
6101 
6102  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) )
6103  {
6104  //================================ State result
6105  std::stringstream hlpSS;
6106  hlpSS << "<b>" << "Detected <i>OCTAHEDRAL</i> symmetry." << "</b>";
6107  rvapi_set_text ( hlpSS.str().c_str(),
6108  "ResultsSection",
6109  1,
6110  0,
6111  1,
6112  1 );
6113  rvapi_flush ( );
6114 
6115  //================================ Symmetry axes table
6116  rvapi_add_table ( "SymmetryTypeTable",
6117  "Detected symmetry axes",
6118  "ResultsSection",
6119  2,
6120  0,
6121  static_cast<unsigned int> ( this->octaAxes.size() ),
6122  8,
6123  1 );
6124 
6125  // ... Column headers
6126  int columnIter = 0;
6127 
6128  hlpSS.str ( std::string ( ) );
6129  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6130  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6131  columnIter += 1;
6132 
6133  hlpSS.str ( std::string ( ) );
6134  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6135  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6136  columnIter += 1;
6137 
6138  hlpSS.str ( std::string ( ) );
6139  hlpSS << "This column states the x-axis element of the symmetry axis.";
6140  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6141  columnIter += 1;
6142 
6143  hlpSS.str ( std::string ( ) );
6144  hlpSS << "This column states the y-axis element of the symmetry axis.";
6145  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6146  columnIter += 1;
6147 
6148  hlpSS.str ( std::string ( ) );
6149  hlpSS << "This column states the z-axis element of the symmetry axis.";
6150  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6151  columnIter += 1;
6152 
6153  hlpSS.str ( std::string ( ) );
6154  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6155  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6156  columnIter += 1;
6157 
6158  hlpSS.str ( std::string ( ) );
6159  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
6160  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6161  columnIter += 1;
6162 
6163  // ... Row headers
6164  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
6165  {
6166  std::stringstream hlpSS2;
6167  hlpSS2 << "Symmetry axis #" << icoIt+1;
6168  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
6169  }
6170 
6171  // ... Fill in data
6172  int prec = 4;
6173  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
6174  {
6175  std::stringstream hlpSS2;
6176  hlpSS2 << "C";
6177  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6178 
6179  hlpSS2.str ( std::string ( ) );
6180  hlpSS2 << static_cast<int> ( this->octaAxes.at(icoIt)[0] );
6181  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6182 
6183  hlpSS2.str ( std::string ( ) );
6184  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[1], prec );
6185  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6186 
6187  hlpSS2.str ( std::string ( ) );
6188  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[2], prec );
6189  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6190 
6191  hlpSS2.str ( std::string ( ) );
6192  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[3], prec );
6193  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6194 
6195  hlpSS2.str ( std::string ( ) );
6196  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->octaAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
6197  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6198 
6199  hlpSS2.str ( std::string ( ) );
6200  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[4], prec );
6201  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6202  }
6203 
6204  //================================ Symmetry elements table
6205  rvapi_add_table ( "SymmetryElementsTable",
6206  "Detected symmetry elements",
6207  "ResultsSection",
6208  static_cast<unsigned int> ( this->octaAxes.size() ) + 2,
6209  0,
6210  static_cast<unsigned int> ( this->octaElems.size() ),
6211  7,
6212  -1 );
6213  totTabRows = static_cast<unsigned int> ( this->octaAxes.size() ) + 2 + static_cast<unsigned int> ( this->octaElems.size() );
6214 
6215  // ... Column headers
6216  columnIter = 0;
6217 
6218  hlpSS.str ( std::string ( ) );
6219  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6220  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6221  columnIter += 1;
6222 
6223  hlpSS.str ( std::string ( ) );
6224  hlpSS << "This column states the symmetry element fold.";
6225  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6226  columnIter += 1;
6227 
6228  hlpSS.str ( std::string ( ) );
6229  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6230  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6231  columnIter += 1;
6232 
6233  hlpSS.str ( std::string ( ) );
6234  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6235  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6236  columnIter += 1;
6237 
6238  hlpSS.str ( std::string ( ) );
6239  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6240  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6241  columnIter += 1;
6242 
6243  hlpSS.str ( std::string ( ) );
6244  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6245  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6246  columnIter += 1;
6247 
6248  // ... Row headers
6249  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
6250  {
6251  std::stringstream hlpSS2;
6252  hlpSS2 << "Symmetry element #" << icoIt+1;
6253  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6254  }
6255 
6256  // ... Fill in data
6257  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
6258  {
6259  if ( this->octaElems.at(icoIt)[0] != 1.0 )
6260  {
6261  std::stringstream hlpSS3;
6262  hlpSS3 << "C";
6263  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6264  }
6265  else
6266  {
6267  std::stringstream hlpSS3;
6268  hlpSS3 << "E";
6269  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6270  }
6271 
6272  std::stringstream hlpSS2;
6273  hlpSS2 << static_cast<int> ( this->octaElems.at(icoIt)[0] );
6274  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
6275 
6276  hlpSS2.str ( std::string ( ) );
6277  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[1], prec );
6278  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
6279 
6280  hlpSS2.str ( std::string ( ) );
6281  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[2], prec );
6282  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
6283 
6284  hlpSS2.str ( std::string ( ) );
6285  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[3], prec );
6286  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
6287 
6288  hlpSS2.str ( std::string ( ) );
6289  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[4], prec );
6290  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
6291  }
6292 
6293  rvapi_flush ( );
6294  }
6295  else
6296  {
6297  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) == 0 ) )
6298  {
6299  //==================================== State result
6300  std::stringstream hlpSS;
6301  hlpSS << "<b><font color=\"orange\">" << "This appears like tetrahedral symmetry, but not all axes could be detected. Maybe decreasing resolution or relaxing the peak similarity requirement would improve the detection. Proceeding this what was detected completely." << "</font></b>";
6302  rvapi_set_text ( hlpSS.str().c_str(),
6303  "ResultsSection",
6304  0,
6305  0,
6306  1,
6307  1 );
6308  rvapi_flush ( );
6309  }
6310 
6311 
6312  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
6313  {
6314  //============================ State result
6315  std::stringstream hlpSS;
6316  hlpSS << "<b>" << "Detected <i>TETRAHEDRAL</i> symmetry." << "</b>";
6317  rvapi_set_text ( hlpSS.str().c_str(),
6318  "ResultsSection",
6319  1,
6320  0,
6321  1,
6322  1 );
6323  rvapi_flush ( );
6324 
6325  //============================ Symmetry axes table
6326  rvapi_add_table ( "SymmetryTypeTable",
6327  "Detected symmetry axes",
6328  "ResultsSection",
6329  2,
6330  0,
6331  static_cast<unsigned int> ( this->tetrAxes.size() ),
6332  8,
6333  1 );
6334 
6335  // ... Column headers
6336  int columnIter = 0;
6337 
6338  hlpSS.str ( std::string ( ) );
6339  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6340  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6341  columnIter += 1;
6342 
6343  hlpSS.str ( std::string ( ) );
6344  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6345  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6346  columnIter += 1;
6347 
6348  hlpSS.str ( std::string ( ) );
6349  hlpSS << "This column states the x-axis element of the symmetry axis.";
6350  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6351  columnIter += 1;
6352 
6353  hlpSS.str ( std::string ( ) );
6354  hlpSS << "This column states the y-axis element of the symmetry axis.";
6355  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6356  columnIter += 1;
6357 
6358  hlpSS.str ( std::string ( ) );
6359  hlpSS << "This column states the z-axis element of the symmetry axis.";
6360  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6361  columnIter += 1;
6362 
6363  hlpSS.str ( std::string ( ) );
6364  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6365  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6366  columnIter += 1;
6367 
6368  hlpSS.str ( std::string ( ) );
6369  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
6370  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6371  columnIter += 1;
6372 
6373  // ... Row headers
6374  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
6375  {
6376  std::stringstream hlpSS2;
6377  hlpSS2 << "Symmetry axis #" << icoIt+1;
6378  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
6379  }
6380 
6381  // ... Fill in data
6382  int prec = 4;
6383  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
6384  {
6385  std::stringstream hlpSS2;
6386  hlpSS2 << "C";
6387  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6388 
6389  hlpSS2.str ( std::string ( ) );
6390  hlpSS2 << static_cast<int> ( this->tetrAxes.at(icoIt)[0] );
6391  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6392 
6393  hlpSS2.str ( std::string ( ) );
6394  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[1], prec );
6395  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6396 
6397  hlpSS2.str ( std::string ( ) );
6398  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[2], prec );
6399  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6400 
6401  hlpSS2.str ( std::string ( ) );
6402  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[3], prec );
6403  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6404 
6405  hlpSS2.str ( std::string ( ) );
6406  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->tetrAxes.at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
6407  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6408 
6409  hlpSS2.str ( std::string ( ) );
6410  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[4], prec );
6411  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6412  }
6413 
6414  //============================ Symmetry elements table
6415  rvapi_add_table ( "SymmetryElementsTable",
6416  "Detected symmetry elements",
6417  "ResultsSection",
6418  static_cast<unsigned int> ( this->tetrAxes.size() ) + 2,
6419  0,
6420  static_cast<unsigned int> ( this->tetrElems.size() ),
6421  7,
6422  -1 );
6423  totTabRows = static_cast<unsigned int> ( this->tetrAxes.size() ) + 2 + static_cast<unsigned int> ( this->tetrElems.size() );
6424 
6425  // ... Column headers
6426  columnIter = 0;
6427 
6428  hlpSS.str ( std::string ( ) );
6429  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6430  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6431  columnIter += 1;
6432 
6433  hlpSS.str ( std::string ( ) );
6434  hlpSS << "This column states the symmetry element fold.";
6435  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6436  columnIter += 1;
6437 
6438  hlpSS.str ( std::string ( ) );
6439  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6440  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6441  columnIter += 1;
6442 
6443  hlpSS.str ( std::string ( ) );
6444  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6445  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6446  columnIter += 1;
6447 
6448  hlpSS.str ( std::string ( ) );
6449  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6450  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6451  columnIter += 1;
6452 
6453  hlpSS.str ( std::string ( ) );
6454  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6455  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6456  columnIter += 1;
6457 
6458  // ... Row headers
6459  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
6460  {
6461  std::stringstream hlpSS2;
6462  hlpSS2 << "Symmetry element #" << icoIt+1;
6463  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6464  }
6465 
6466  // ... Fill in data
6467  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
6468  {
6469  std::stringstream hlpSS3;
6470  if ( this->tetrElems.at(icoIt)[0] != 1.0 )
6471  {
6472  std::stringstream hlpSS2;
6473  hlpSS2 << "C";
6474  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
6475  }
6476  else
6477  {
6478  std::stringstream hlpSS2;
6479  hlpSS2 << "E";
6480  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
6481  }
6482 
6483  hlpSS3.str ( std::string ( ) );
6484  hlpSS3 << static_cast<int> ( this->tetrElems.at(icoIt)[0] );
6485  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 1 );
6486 
6487  hlpSS3.str ( std::string ( ) );
6488  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[1], prec );
6489  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 2 );
6490 
6491  hlpSS3.str ( std::string ( ) );
6492  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[2], prec );
6493  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 3 );
6494 
6495  hlpSS3.str ( std::string ( ) );
6496  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[3], prec );
6497  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 4 );
6498 
6499  hlpSS3.str ( std::string ( ) );
6500  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[4], prec );
6501  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 5 );
6502  }
6503 
6504  rvapi_flush ( );
6505  }
6506  else
6507  {
6508  if ( ( static_cast<unsigned int> ( this->dnSymmClear.size() ) > 0 ) && ( settings->htmlReport ) )
6509  {
6510  //======================== State result
6511  std::stringstream hlpSS;
6512  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry." << "</b>";
6513  rvapi_set_text ( hlpSS.str().c_str(),
6514  "ResultsSection",
6515  1,
6516  0,
6517  1,
6518  1 );
6519  rvapi_flush ( );
6520 
6521  //======================== Symmetry axes table
6522  rvapi_add_table ( "SymmetryTypeTable",
6523  "Detected symmetry axes",
6524  "ResultsSection",
6525  2,
6526  0,
6527  3,
6528  8,
6529  1 );
6530 
6531  // ... Column headers
6532  int columnIter = 0;
6533 
6534  hlpSS.str ( std::string ( ) );
6535  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6536  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6537  columnIter += 1;
6538 
6539  hlpSS.str ( std::string ( ) );
6540  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6541  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6542  columnIter += 1;
6543 
6544  hlpSS.str ( std::string ( ) );
6545  hlpSS << "This column states the x-axis element of the symmetry axis.";
6546  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6547  columnIter += 1;
6548 
6549  hlpSS.str ( std::string ( ) );
6550  hlpSS << "This column states the y-axis element of the symmetry axis.";
6551  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6552  columnIter += 1;
6553 
6554  hlpSS.str ( std::string ( ) );
6555  hlpSS << "This column states the z-axis element of the symmetry axis.";
6556  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6557  columnIter += 1;
6558 
6559  hlpSS.str ( std::string ( ) );
6560  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6561  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6562  columnIter += 1;
6563 
6564  hlpSS.str ( std::string ( ) );
6565  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
6566  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6567  columnIter += 1;
6568 
6569  // ... Row headers
6570  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymmClear.at(0).size() ); icoIt++ )
6571  {
6572  hlpSS.str ( std::string ( ) );
6573  hlpSS << "Symmetry axis #" << icoIt+1;
6574  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", icoIt );
6575  }
6576 
6577  // ... Fill in data
6578  int prec = 4;
6579  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymmClear.at(0).size() ); icoIt++ )
6580  {
6581  std::stringstream hlpSS2;
6582  hlpSS2 << "C";
6583  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6584 
6585  hlpSS2.str ( std::string ( ) );
6586  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(icoIt)[0] );
6587  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6588 
6589  hlpSS2.str ( std::string ( ) );
6590  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[1], prec );
6591  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6592 
6593  hlpSS2.str ( std::string ( ) );
6594  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[2], prec );
6595  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6596 
6597  hlpSS2.str ( std::string ( ) );
6598  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[3], prec );
6599  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6600 
6601  hlpSS2.str ( std::string ( ) );
6602  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->dnSymmClear.at(0).at(icoIt)[0] ) ) * ( 180.0 / M_PI ), prec );
6603  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6604 
6605  hlpSS2.str ( std::string ( ) );
6606  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[4], prec );
6607  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6608  }
6609 
6610  //======================== Symmetry elements table
6611  int totRows = 0;
6612  for ( unsigned int it = 0; it < 2; it++ )
6613  {
6614  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
6615  {
6616  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
6617  {
6618  if ( iter == 0 ) { continue; }
6619  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
6620 
6621  totRows += 1;
6622  }
6623  }
6624  else
6625  {
6626  for ( int iter = -std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
6627  {
6628  if ( iter == 0 ) { continue; }
6629 
6630  totRows += 1;
6631  }
6632  }
6633  }
6634  totRows += 1;
6635  totTabRows = static_cast<unsigned int> ( totRows ) + 6;
6636 
6637  rvapi_add_table ( "SymmetryElementsTable",
6638  "Detected symmetry elements",
6639  "ResultsSection",
6640  6,
6641  0,
6642  totRows,
6643  7,
6644  -1 );
6645 
6646  // ... Column headers
6647  columnIter = 0;
6648 
6649  hlpSS.str ( std::string ( ) );
6650  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6651  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6652  columnIter += 1;
6653 
6654  hlpSS.str ( std::string ( ) );
6655  hlpSS << "This column states the symmetry element fold.";
6656  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6657  columnIter += 1;
6658 
6659  hlpSS.str ( std::string ( ) );
6660  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6661  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6662  columnIter += 1;
6663 
6664  hlpSS.str ( std::string ( ) );
6665  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6666  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6667  columnIter += 1;
6668 
6669  hlpSS.str ( std::string ( ) );
6670  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6671  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6672  columnIter += 1;
6673 
6674  hlpSS.str ( std::string ( ) );
6675  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6676  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6677  columnIter += 1;
6678 
6679  // ... Row headers
6680  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
6681  {
6682  std::stringstream hlpSS2;
6683  hlpSS2 << "Symmetry element #" << icoIt+1;
6684  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6685  }
6686 
6687  // ... Fill in data
6688  int rowCount = 1;
6689 
6690  hlpSS.str ( std::string ( ) );
6691  hlpSS << "E";
6692  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
6693 
6694  hlpSS.str ( std::string ( ) );
6695  hlpSS << static_cast<int> ( 1 );
6696  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
6697 
6698  hlpSS.str ( std::string ( ) );
6699  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
6700  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
6701 
6702  hlpSS.str ( std::string ( ) );
6703  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6704  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
6705 
6706  hlpSS.str ( std::string ( ) );
6707  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6708  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
6709 
6710  hlpSS.str ( std::string ( ) );
6711  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6712  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
6713 
6714  for ( unsigned int it = 0; it < 2; it++ )
6715  {
6716  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
6717  {
6718  for ( int iter = -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
6719  {
6720  if ( iter == 0 ) { continue; }
6721  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
6722 
6723  std::stringstream hlpSS2;
6724  hlpSS2 << "C";
6725  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
6726 
6727  hlpSS2.str ( std::string ( ) );
6728  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] );
6729  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
6730 
6731  hlpSS2.str ( std::string ( ) );
6732  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[1], prec );
6733  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
6734 
6735  hlpSS2.str ( std::string ( ) );
6736  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[2], prec );
6737  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
6738 
6739  hlpSS2.str ( std::string ( ) );
6740  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[3], prec );
6741  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
6742 
6743  hlpSS2.str ( std::string ( ) );
6744  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymmClear.at(0).at(it)[0] ) ), prec );
6745  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
6746  rowCount += 1;
6747  }
6748  }
6749  else
6750  {
6751  for ( int iter = -std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
6752  {
6753  if ( iter == 0 ) { continue; }
6754 
6755  std::stringstream hlpSS2;
6756  hlpSS2 << "C";
6757  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
6758 
6759  hlpSS2.str ( std::string ( ) );
6760  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] );
6761  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
6762 
6763  hlpSS2.str ( std::string ( ) );
6764  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[1], prec );
6765  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
6766 
6767  hlpSS2.str ( std::string ( ) );
6768  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[2], prec );
6769  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
6770 
6771  hlpSS2.str ( std::string ( ) );
6772  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[3], prec );
6773  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
6774 
6775  hlpSS2.str ( std::string ( ) );
6776  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->dnSymmClear.at(0).at(it)[0] ) ), prec );
6777  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
6778  rowCount += 1;
6779  }
6780  }
6781  }
6782 
6783  rvapi_flush ( );
6784  }
6785  else
6786  {
6787  if ( ( static_cast<unsigned int> ( this->cnSymmClear.size() ) > 0 ) && ( settings->htmlReport ) )
6788  {
6789  //==================== State result
6790  std::stringstream hlpSS;
6791  hlpSS << "<b>" << "Detected <i>CYCLIC</i> symmetry." << "</b>";
6792  rvapi_set_text ( hlpSS.str().c_str(),
6793  "ResultsSection",
6794  1,
6795  0,
6796  1,
6797  1 );
6798  rvapi_flush ( );
6799 
6800  //==================== Symmetry axes table
6801  rvapi_add_table ( "SymmetryTypeTable",
6802  "Detected symmetry axes",
6803  "ResultsSection",
6804  2,
6805  0,
6806  3,
6807  8,
6808  2 );
6809 
6810  // ... Column headers
6811  int columnIter = 0;
6812 
6813  hlpSS.str ( std::string ( ) );
6814  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6815  rvapi_put_horz_theader( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6816  columnIter += 1;
6817 
6818  hlpSS.str ( std::string ( ) );
6819  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6820  rvapi_put_horz_theader( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6821  columnIter += 1;
6822 
6823  hlpSS.str ( std::string ( ) );
6824  hlpSS << "This column states the x-axis element of the symmetry axis.";
6825  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6826  columnIter += 1;
6827 
6828  hlpSS.str ( std::string ( ) );
6829  hlpSS << "This column states the y-axis element of the symmetry axis.";
6830  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6831  columnIter += 1;
6832 
6833  hlpSS.str ( std::string ( ) );
6834  hlpSS << "This column states the z-axis element of the symmetry axis.";
6835  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6836  columnIter += 1;
6837 
6838  hlpSS.str ( std::string ( ) );
6839  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6840  rvapi_put_horz_theader( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6841  columnIter += 1;
6842 
6843  hlpSS.str ( std::string ( ) );
6844  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
6845  rvapi_put_horz_theader( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6846  columnIter += 1;
6847 
6848  // ... Row headers
6849  hlpSS.str ( std::string ( ) );
6850  hlpSS << "Symmetry axis #" << 1;
6851  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", 0 );
6852 
6853  // ... Fill in data
6854  int prec = 4;
6855  hlpSS.str ( std::string ( ) );
6856  hlpSS << "C";
6857  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 0 );
6858 
6859  hlpSS.str ( std::string ( ) );
6860  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
6861  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 1 );
6862 
6863  hlpSS.str ( std::string ( ) );
6864  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
6865  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 2 );
6866 
6867  hlpSS.str ( std::string ( ) );
6868  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
6869  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 3 );
6870 
6871  hlpSS.str ( std::string ( ) );
6872  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
6873  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 4 );
6874 
6875  hlpSS.str ( std::string ( ) );
6876  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->cnSymmClear.at(0)[0] ) ) * ( 180.0 / M_PI ), prec );
6877  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 5 );
6878 
6879  hlpSS.str ( std::string ( ) );
6880  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[4], prec );
6881  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 6 );
6882 
6883  //==================== Symmetry elements table
6884  int totRows = 0;
6885  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
6886  {
6887  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
6888  {
6889  if ( iter == 0 ) { continue; }
6890  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
6891 
6892  totRows += 1;
6893  }
6894  }
6895  else
6896  {
6897  for ( int iter = -std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
6898  {
6899  if ( iter == 0 ) { continue; }
6900 
6901  totRows += 1;
6902  }
6903  }
6904  totRows += 1;
6905  totTabRows = static_cast<unsigned int> ( totRows ) + 5;
6906 
6907  rvapi_add_table ( "SymmetryElementsTable",
6908  "Detected symmetry elements",
6909  "ResultsSection",
6910  5,
6911  0,
6912  totRows,
6913  7,
6914  -1 );
6915 
6916  // ... Column headers
6917  columnIter = 0;
6918 
6919  hlpSS.str ( std::string ( ) );
6920  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6921  rvapi_put_horz_theader( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6922  columnIter += 1;
6923 
6924  hlpSS.str ( std::string ( ) );
6925  hlpSS << "This column states the symmetry element fold.";
6926  rvapi_put_horz_theader( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6927  columnIter += 1;
6928 
6929  hlpSS.str ( std::string ( ) );
6930  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6931  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6932  columnIter += 1;
6933 
6934  hlpSS.str ( std::string ( ) );
6935  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6936  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6937  columnIter += 1;
6938 
6939  hlpSS.str ( std::string ( ) );
6940  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6941  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6942  columnIter += 1;
6943 
6944  hlpSS.str ( std::string ( ) );
6945  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6946  rvapi_put_horz_theader( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6947  columnIter += 1;
6948 
6949  // ... Row headers
6950  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
6951  {
6952  std::stringstream hlpSS2;
6953  hlpSS2 << "Symmetry element #" << std::to_string ( icoIt+1 );
6954  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6955  }
6956 
6957  // ... Fill in data
6958  int rowCount = 1;
6959 
6960  hlpSS.str ( std::string ( ) );
6961  hlpSS << "E";
6962  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
6963 
6964  hlpSS.str ( std::string ( ) );
6965  hlpSS << static_cast<int> ( 1 );
6966  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
6967 
6968  hlpSS.str ( std::string ( ) );
6969  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
6970  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
6971 
6972  hlpSS.str ( std::string ( ) );
6973  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6974  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
6975 
6976  hlpSS.str ( std::string ( ) );
6977  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6978  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
6979 
6980  hlpSS.str ( std::string ( ) );
6981  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6982  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
6983 
6984  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
6985  {
6986  for ( int iter = -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
6987  {
6988  if ( iter == 0 ) { continue; }
6989  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
6990 
6991  hlpSS.str ( std::string ( ) );
6992  hlpSS << "C";
6993  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
6994 
6995  hlpSS.str ( std::string ( ) );
6996  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
6997  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
6998 
6999  hlpSS.str ( std::string ( ) );
7000  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
7001  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
7002 
7003  hlpSS.str ( std::string ( ) );
7004  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
7005  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
7006 
7007  hlpSS.str ( std::string ( ) );
7008  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
7009  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
7010 
7011  hlpSS.str ( std::string ( ) );
7012  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->cnSymmClear.at(0)[0] ) ), prec );
7013  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
7014  rowCount += 1;
7015  }
7016  }
7017  else
7018  {
7019  for ( int iter = -std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ); iter++ )
7020  {
7021  if ( iter == 0 ) { continue; }
7022 
7023  hlpSS.str ( std::string ( ) );
7024  hlpSS << "C";
7025  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
7026 
7027  hlpSS.str ( std::string ( ) );
7028  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
7029  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
7030 
7031  hlpSS.str ( std::string ( ) );
7032  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
7033  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
7034 
7035  hlpSS.str ( std::string ( ) );
7036  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
7037  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
7038 
7039  hlpSS.str ( std::string ( ) );
7040  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
7041  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
7042 
7043  hlpSS.str ( std::string ( ) );
7044  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( iter * ( 360.0 / static_cast<double> ( this->cnSymmClear.at(0)[0] ) ), prec );
7045  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
7046  rowCount += 1;
7047  }
7048  }
7049 
7050  rvapi_flush ( );
7051  }
7052  else
7053  {
7054  printf ( "Detected no symmetry.\n\n" );
7055  }
7056  }
7057  }
7058  }
7059  }
7060 
7061  //======================================== Print alternatives
7062  rvapi_add_table ( "AlternativesTable",
7063  "Alternative Symmetries Detected",
7064  "ResultsSection",
7065  totTabRows,
7066  0,
7067  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ),
7068  7,
7069  -1 );
7070 
7071  // ... Column headers
7072  int columnIter = 0;
7073 
7074  std::stringstream hlpSS;
7075  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D).";
7076  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
7077  columnIter += 1;
7078 
7079  hlpSS.str ( std::string ( ) );
7080  hlpSS << "This column states the symmetry fold.";
7081  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
7082  columnIter += 1;
7083 
7084  hlpSS.str ( std::string ( ) );
7085  hlpSS << "This column states the x-axis element of the symmetry axis.";
7086  rvapi_put_horz_theader ( "AlternativesTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
7087  columnIter += 1;
7088 
7089  hlpSS.str ( std::string ( ) );
7090  hlpSS << "This column states the y-axis element of the symmetry axis.";
7091  rvapi_put_horz_theader ( "AlternativesTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
7092  columnIter += 1;
7093 
7094  hlpSS.str ( std::string ( ) );
7095  hlpSS << "This column states the z-axis element of the symmetry axis.";
7096  rvapi_put_horz_theader ( "AlternativesTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
7097  columnIter += 1;
7098 
7099  hlpSS.str ( std::string ( ) );
7100  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
7101  rvapi_put_horz_theader ( "AlternativesTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
7102  columnIter += 1;
7103 
7104  hlpSS.str ( std::string ( ) );
7105  hlpSS << "This column states the average peak height (correlation after rotation) for all the symmetry rotations. The closer this number is to 1.0, the more reliable the symmetry existence is.";
7106  rvapi_put_horz_theader ( "AlternativesTable", "Peak Height", hlpSS.str().c_str(), columnIter );
7107  columnIter += 1;
7108 
7109  // ... Row headers
7110  int maxCAlts = 0;
7111  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
7112  {
7113  std::stringstream hlpSS2;
7114  hlpSS2 << "Alternative Symmetry #" << gNo+1;
7115  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", gNo );
7116  maxCAlts = gNo;
7117  }
7118  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
7119  {
7120  std::stringstream hlpSS2;
7121  hlpSS2 << "Alternative Symmetry #" << iter + maxCAlts + 2;
7122  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", iter + maxCAlts + 1 );
7123  }
7124 
7125  int rowCount = 0;
7126  int prec = 4;
7127  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
7128  {
7129  std::stringstream hlpSS2;
7130  hlpSS2 << "C";
7131  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
7132 
7133  hlpSS2.str ( std::string ( ) );
7134  hlpSS2 << static_cast<int> ( static_cast<int> ( this->cnSymm.at(gNo)[0] ) );
7135  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
7136 
7137  hlpSS2.str ( std::string ( ) );
7138  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[1], prec );
7139  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
7140 
7141  hlpSS2.str ( std::string ( ) );
7142  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[2], prec );
7143  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
7144 
7145  hlpSS2.str ( std::string ( ) );
7146  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[3], prec );
7147  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
7148 
7149  hlpSS2.str ( std::string ( ) );
7150  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->cnSymm.at(gNo)[0] ) ) * ( 180.0 / M_PI ), prec );
7151  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
7152 
7153  hlpSS2.str ( std::string ( ) );
7154  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->cnSymm.at(gNo)[4] ), prec );
7155  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
7156  rowCount += 1;
7157  }
7158 
7159  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
7160  {
7161  std::stringstream hlpSS2;
7162  hlpSS2 << "D";
7163  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
7164 
7165  hlpSS2.str ( std::string ( ) );
7166  hlpSS2 << static_cast<int> ( static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ) );
7167  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
7168 
7169  hlpSS2.str ( std::string ( ) );
7170  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[1], prec );
7171  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
7172 
7173  hlpSS2.str ( std::string ( ) );
7174  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[2], prec );
7175  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
7176 
7177  hlpSS2.str ( std::string ( ) );
7178  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[3], prec );
7179  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
7180 
7181  hlpSS2.str ( std::string ( ) );
7182  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( ( ( 2.0 * M_PI ) / static_cast<double> ( this->dnSymm.at(iter).at(0)[0] ) ) * ( 180.0 / M_PI ), prec );
7183  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
7184 
7185  hlpSS2.str ( std::string ( ) );
7186  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->dnSymm.at(iter).at(0)[4] ), prec );
7187  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
7188  rowCount += 1;
7189  }
7190  rvapi_flush ( );
7191 
7192  //======================================== Done
7193  return ;
7194 
7195 }
7196 
7218 std::vector< std::array<double,8> > ProSHADE_internal::ProSHADE_symmetry::getRotFnPeaks ( )
7219 {
7220  //======================================== Return
7221  return ( this->rfPeaks );
7222 
7223 }
7224 
7241 std::vector< std::array<double,5> > ProSHADE_internal::ProSHADE_symmetry::getCSymmetries ( )
7242 {
7243  //======================================== Return
7244  return ( this->cnSymm );
7245 
7246 }
7247 
7266 std::vector< std::vector< std::array<double,6> > > ProSHADE_internal::ProSHADE_symmetry::getDSymmetries ( )
7267 {
7268  //======================================== Return
7269  return ( this->dnSymm );
7270 
7271 }
7272 
7285 {
7286  //======================================== Initialise pointers
7287  this->cmpObj = nullptr;
7288 
7289  //======================================== If this is called only to save database, redirect to the proper function and quit
7290  if ( settings->taskToPerform == ProSHADE::BuildDB )
7291  {
7292  //==================================== Report progress
7293  if ( settings->verbose > 0 )
7294  {
7295  std::cout << "-----------------------------------------------------------" << std::endl;
7296  std::cout << "| MODE: BuildDB |" << std::endl;
7297  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
7298  }
7299 
7300  saveDatabase ( settings );
7301 
7302  if ( settings->verbose > 0 )
7303  {
7304  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
7305  std::cout << "| COMPLETED |" << std::endl;
7306  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
7307 
7308  std::cout << "Database saved to: " << settings->databaseName << std::endl << std::endl;
7309 
7310  if ( settings->htmlReport )
7311  {
7312  std::stringstream hlpSS;
7313  hlpSS << "<font color=\"green\">" << "Database saved to " << settings->databaseName << " ." << "</font>";
7314  rvapi_set_text ( hlpSS.str().c_str(),
7315  "ProgressSection",
7316  settings->htmlReportLineProgress,
7317  1,
7318  1,
7319  1 );
7320  settings->htmlReportLineProgress += 1;
7321 
7322  rvapi_flush ( );
7323  }
7324  }
7325  return ;
7326  }
7327 
7328  //======================================== If this is called to fragment and compare one structure against database, redirect to the proper function and quit
7329  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() == 1 ) && ( settings->taskToPerform == ProSHADE::DistancesFrag ) )
7330  {
7331  //==================================== Load the database and compare
7332  compareFragAgainstDatabase ( settings, &settings->structFiles );
7333 
7334  //==================================== Save the settings
7335  this->mapResolution = settings->mapResolution;
7336  this->bandwidth = settings->bandwidth;
7337  this->glIntegOrder = settings->glIntegOrder;
7338  this->theta = settings->theta;
7339  this->phi = settings->phi;
7340  this->bFactorValue = settings->bFactorValue;
7341  this->bFactorChange = settings->bFactorChange;
7342  this->noIQRsFromMap = settings->noIQRsFromMap;
7343  this->shellSpacing = settings->shellSpacing;
7344  this->manualShells = settings->manualShells;
7345  this->useCOM = settings->useCOM;
7346  this->firstLineCOM = settings->firstLineCOM;
7347  this->extraSpace = settings->extraSpace;
7348  this->alpha = settings->alpha;
7349  this->mPower = settings->mPower;
7350  this->ignoreLs = settings->ignoreLs;
7351  this->energyLevelDist = settings->energyLevelDist;
7352  this->traceSigmaDist = settings->traceSigmaDist;
7353  this->fullRotFnDist = settings->fullRotFnDist;
7354  this->usePhase = settings->usePhase;
7355  this->saveWithAndWithout = settings->saveWithAndWithout;
7356  this->enLevelsThreshold = settings->enLevelsThreshold;
7357  this->trSigmaThreshold = settings->trSigmaThreshold;
7358  this->structFiles = settings->structFiles;
7359 
7360  //==================================== Done
7361  return ;
7362  }
7363 
7364  //======================================== If this is called to compare one structure against database, redirect to the proper function and quit
7365  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() == 1 ) )
7366  {
7367  //==================================== Load the database and compare, keeping the task value unchanged by the database reading
7368  ProSHADE::Task origTask = settings->taskToPerform;
7369  compareAgainstDatabase ( settings, &settings->structFiles );
7370 
7371  settings->taskToPerform = origTask;
7372 
7373  //==================================== Save the settings
7374  this->mapResolution = settings->mapResolution;
7375  this->bandwidth = settings->bandwidth;
7376  this->glIntegOrder = settings->glIntegOrder;
7377  this->theta = settings->theta;
7378  this->phi = settings->phi;
7379  this->bFactorValue = settings->bFactorValue;
7380  this->bFactorChange = settings->bFactorChange;
7381  this->noIQRsFromMap = settings->noIQRsFromMap;
7382  this->shellSpacing = settings->shellSpacing;
7383  this->manualShells = settings->manualShells;
7384  this->useCOM = settings->useCOM;
7385  this->firstLineCOM = settings->firstLineCOM;
7386  this->extraSpace = settings->extraSpace;
7387  this->alpha = settings->alpha;
7388  this->mPower = settings->mPower;
7389  this->ignoreLs = settings->ignoreLs;
7390  this->energyLevelDist = settings->energyLevelDist;
7391  this->traceSigmaDist = settings->traceSigmaDist;
7392  this->fullRotFnDist = settings->fullRotFnDist;
7393  this->usePhase = settings->usePhase;
7394  this->saveWithAndWithout = settings->saveWithAndWithout;
7395  this->enLevelsThreshold = settings->enLevelsThreshold;
7396  this->trSigmaThreshold = settings->trSigmaThreshold;
7397  this->structFiles = settings->structFiles;
7398 
7399  //==================================== Done
7400  return ;
7401  }
7402 
7403  //======================================== Check for ambiguity
7404  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() > 1 ) )
7405  {
7406  std::cerr << "!!! ProSHADE ERROR !!! Ambiguity detected. There is a database name supplied, suggesting that you want to compare something against it. However, there is also multiple files supplied, suggesting you want to compare them against each other. Note, that to compare to databse, only a single file can be supplied - this is to remove this ambiguity. Terminating..." << std::endl;
7407 
7408  if ( settings->htmlReport )
7409  {
7410  //==================================== Record progress
7411  std::stringstream hlpSS;
7412  hlpSS << "<font color=\"red\">" << "Ambiguity detected. There is a database name supplied, suggesting that you want to compare something against it. However, there is also multiple files supplied, suggesting you want to compare them against each other. Please note that to compare to databse, only a single file can be supplied - this is to remove this ambiguity." << "</font>";
7413  rvapi_set_text ( hlpSS.str().c_str(),
7414  "ProgressSection",
7415  settings->htmlReportLineProgress,
7416  1,
7417  1,
7418  1 );
7419  settings->htmlReportLineProgress += 1;
7420  rvapi_flush ( );
7421  }
7422 
7423  exit ( -1 );
7424  }
7425 
7426  //======================================== Save the settings
7427  this->mapResolution = settings->mapResolution;
7428  this->bandwidth = settings->bandwidth;
7429  this->glIntegOrder = settings->glIntegOrder;
7430  this->theta = settings->theta;
7431  this->phi = settings->phi;
7432  this->bFactorValue = settings->bFactorValue;
7433  this->bFactorChange = settings->bFactorChange;
7434  this->noIQRsFromMap = settings->noIQRsFromMap;
7435  this->shellSpacing = settings->shellSpacing;
7436  this->manualShells = settings->manualShells;
7437  this->useCOM = settings->useCOM;
7438  this->firstLineCOM = settings->firstLineCOM;
7439  this->extraSpace = settings->extraSpace;
7440  this->alpha = settings->alpha;
7441  this->mPower = settings->mPower;
7442  this->ignoreLs = settings->ignoreLs;
7443  this->energyLevelDist = settings->energyLevelDist;
7444  this->traceSigmaDist = settings->traceSigmaDist;
7445  this->fullRotFnDist = settings->fullRotFnDist;
7446  this->usePhase = settings->usePhase;
7447  this->saveWithAndWithout = settings->saveWithAndWithout;
7448  this->enLevelsThreshold = settings->enLevelsThreshold;
7449  this->trSigmaThreshold = settings->trSigmaThreshold;
7450  this->structFiles = settings->structFiles;
7451 
7452  //======================================== Sanity checks
7453  if ( !this->energyLevelDist && !this->traceSigmaDist && !this->fullRotFnDist )
7454  {
7455  //==================================== No distances required
7456  std::cerr << "!!! ProSHADE ERROR !!! Initialising ProSHADE_distances object with no distances required! Terminating..." << std::endl;
7457 
7458  if ( settings->htmlReport )
7459  {
7460  //==================================== Record progress
7461  std::stringstream hlpSS;
7462  hlpSS << "<font color=\"red\">" << "There are no required distances to be computed and therefore nothing to do..." << "</font>";
7463  rvapi_set_text ( hlpSS.str().c_str(),
7464  "ProgressSection",
7465  settings->htmlReportLineProgress,
7466  1,
7467  1,
7468  1 );
7469  settings->htmlReportLineProgress += 1;
7470  rvapi_flush ( );
7471  }
7472 
7473  exit ( -1 );
7474  }
7475 
7476  if ( this->structFiles.size() < 2 )
7477  {
7478  //==================================== Not enough structures
7479  std::cerr << "!!! ProSHADE ERROR !!! There are less than two structures submitted to the ProSHADE_distances class, cannot compute distances! Did you forget to supply the database file name? Terminating..." << std::endl;
7480 
7481  if ( settings->htmlReport )
7482  {
7483  //==================================== Record progress
7484  std::stringstream hlpSS;
7485  hlpSS << "<font color=\"red\">" << "There are less than two structures submitted to the distance computing functionality." << "</font>";
7486  rvapi_set_text ( hlpSS.str().c_str(),
7487  "ProgressSection",
7488  settings->htmlReportLineProgress,
7489  1,
7490  1,
7491  1 );
7492  settings->htmlReportLineProgress += 1;
7493  rvapi_flush ( );
7494  }
7495 
7496  exit ( -1 );
7497  }
7498 
7499  if ( ( this->enLevelsThreshold != -999.9 ) && ( !this->energyLevelDist ) )
7500  {
7501  //==================================== Invalid settings
7502  std::cerr << "!!! ProSHADE ERROR!!! Energy levels descriptor is not required, but its threshold for hierarchical distance computation was set. This makes no sense! Terminating..." << std::endl;
7503 
7504  if ( settings->htmlReport )
7505  {
7506  //==================================== Record progress
7507  std::stringstream hlpSS;
7508  hlpSS << "<font color=\"red\">" << "Energy levels descriptor is not required, but its threshold for hierarchical distance computation was set. Either you set these values, in which case please decide what should be done, or you did not, in which case this is an internal bug and in this case please report this case." << "</font>";
7509  rvapi_set_text ( hlpSS.str().c_str(),
7510  "ProgressSection",
7511  settings->htmlReportLineProgress,
7512  1,
7513  1,
7514  1 );
7515  settings->htmlReportLineProgress += 1;
7516  rvapi_flush ( );
7517  }
7518 
7519  exit ( -1 );
7520  }
7521 
7522  if ( ( this->trSigmaThreshold != -999.9 ) && ( !this->traceSigmaDist ) )
7523  {
7524  //==================================== Invalid settings
7525  std::cerr << "!!! ProSHADE ERROR !!! Trace sigma descriptor is not required, but its threshold for hierarchical distance computation was set. This makes no sense! Terminating..." << std::endl;
7526 
7527  if ( settings->htmlReport )
7528  {
7529  //==================================== Record progress
7530  std::stringstream hlpSS;
7531  hlpSS << "<font color=\"red\">" << "Trace sigma descriptor is not required, but its threshold for hierarchical distance computation was set. Either you set these values, in which case please decide what should be done, or you did not, in which case this is an internal bug and in this case please report this case." << "</font>";
7532  rvapi_set_text ( hlpSS.str().c_str(),
7533  "ProgressSection",
7534  settings->htmlReportLineProgress,
7535  1,
7536  1,
7537  1 );
7538  settings->htmlReportLineProgress += 1;
7539  rvapi_flush ( );
7540  }
7541 
7542  exit ( -1 );
7543  }
7544 
7545  if ( settings->verbose > 0 )
7546  {
7547  std::cout << "Finding distances between the structure " << settings->structFiles.at(0) << " against all other structures." << std::endl;
7548  }
7549 
7550  if ( settings->verbose > 3 )
7551  {
7552  std::cout << ">>>>>>>> Sanity checks passed." << std::endl;
7553  }
7554 
7555  if ( settings->htmlReport )
7556  {
7557  //==================================== Record progress
7558  std::stringstream hlpSS;
7559  hlpSS << "<font color=\"green\">" << "Sanity checks passed" << "</font>";
7560  rvapi_set_text ( hlpSS.str().c_str(),
7561  "ProgressSection",
7562  settings->htmlReportLineProgress,
7563  1,
7564  1,
7565  1 );
7566  settings->htmlReportLineProgress += 1;
7567  rvapi_flush ( );
7568  }
7569 
7570  if ( settings->htmlReport )
7571  {
7572  //==================================== Create section
7573  rvapi_add_section ( "InputFilesSection",
7574  "List of input structures",
7575  "body",
7576  settings->htmlReportLine-1,
7577  0,
7578  1,
7579  1,
7580  false );
7581  settings->htmlReportLine += 1;
7582  rvapi_flush();
7583 
7584  // Record structure 0
7585  std::stringstream hlpSS;
7586  hlpSS << "<b>" << settings->structFiles.at(0) << "</b>";
7587  rvapi_set_text ( hlpSS.str().c_str(),
7588  "InputFilesSection",
7589  0,
7590  1,
7591  1,
7592  1 );
7593 
7594  for ( unsigned int vecIt = 1; vecIt < static_cast<unsigned int> ( this->structFiles.size() ); vecIt++ )
7595  {
7596  hlpSS.str ( std::string ( ) );
7597  hlpSS << settings->structFiles.at(vecIt);
7598  rvapi_set_text ( hlpSS.str().c_str(),
7599  "InputFilesSection",
7600  vecIt,
7601  1,
7602  1,
7603  1 );
7604  }
7605 
7606 
7607  rvapi_flush ( );
7608  }
7609 
7610  //======================================== Initialise vectors
7611  this->bandwidthVec = std::vector<unsigned int> ( this->structFiles.size(), this->bandwidth );
7612  this->thetaVec = std::vector<unsigned int> ( this->structFiles.size(), this->theta );
7613  this->phiVec = std::vector<unsigned int> ( this->structFiles.size(), this->phi );
7614  this->glIntegOrderVec = std::vector<unsigned int> ( this->structFiles.size(), this->glIntegOrder );
7615  this->extraSpaceVec = std::vector<double> ( this->structFiles.size(), this->extraSpace );
7616 
7617  //======================================== Create the one object to compare everything else against
7618  ProSHADE_data* one = new ProSHADE_data ();
7619 
7620  //======================================== Read in the structure into one
7621  unsigned int fileType = checkFileType ( structFiles.at(0) );
7622  if ( fileType == 2 )
7623  {
7624  one->getDensityMapFromMAP ( this->structFiles.at(0),
7625  &this->shellSpacing,
7626  this->mapResolution,
7627  &this->bandwidthVec.at(0),
7628  &this->thetaVec.at(0),
7629  &this->phiVec.at(0),
7630  &this->glIntegOrderVec.at(0),
7631  &this->extraSpaceVec.at(0),
7632  settings->mapResDefault,
7633  settings->rotChangeDefault,
7634  settings,
7635  settings->overlayDefaults );
7636  }
7637  else if ( fileType == 1 )
7638  {
7639  one->getDensityMapFromPDB ( this->structFiles.at(0),
7640  &this->shellSpacing,
7641  this->mapResolution,
7642  &this->bandwidthVec.at(0),
7643  &this->thetaVec.at(0),
7644  &this->phiVec.at(0),
7645  &this->glIntegOrderVec.at(0),
7646  &this->extraSpaceVec.at(0),
7647  settings->mapResDefault,
7648  settings,
7649  this->bFactorValue,
7650  this->firstLineCOM );
7651  }
7652  else
7653  {
7654  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file." << std::endl;
7655  exit ( -1 );
7656  }
7657  if ( settings->verbose > 1 )
7658  {
7659  std::cout << ">> Structure " << this->structFiles.at(0) << " loaded." << std::endl;
7660  }
7661 
7662  if ( settings->htmlReport )
7663  {
7664  //==================================== Record progress
7665  std::stringstream hlpSS;
7666  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(0) << " loaded." << "</font>";
7667  rvapi_set_text ( hlpSS.str().c_str(),
7668  "ProgressSection",
7669  settings->htmlReportLineProgress,
7670  1,
7671  1,
7672  1 );
7673  settings->htmlReportLineProgress += 1;
7674  rvapi_flush ( );
7675  }
7676 
7677  //======================================== Deal with the centering and MAP data format, if applicable
7678  one->normaliseMap ( settings );
7679  if ( this->usePhase )
7680  {
7681  one->keepPhaseInMap ( this->alpha,
7682  this->bFactorChange,
7683  &this->bandwidthVec.at(0),
7684  &this->thetaVec.at(0),
7685  &this->phiVec.at(0),
7686  &this->glIntegOrderVec.at(0),
7687  settings,
7688  this->useCOM,
7689  settings->noIQRsFromMap,
7690  settings->verbose,
7691  settings->clearMapData,
7692  settings->rotChangeDefault,
7693  settings->overlayDefaults,
7694  settings->maskBlurFactor,
7695  settings->maskBlurFactorGiven );
7696  }
7697  else
7698  {
7699  one->removePhaseFromMap ( this->alpha,
7700  this->bFactorChange,
7701  settings );
7702  }
7703 
7704  //======================================== Map the density onto spheres
7705  one->mapPhaselessToSphere ( settings,
7706  this->thetaVec.at(0),
7707  this->phiVec.at(0),
7708  this->shellSpacing,
7709  this->manualShells );
7710 
7711  //======================================== Compute the Spherical Harmonics (SH) coefficients
7712  one->getSphericalHarmonicsCoeffs ( this->bandwidthVec.at(0), settings );
7713 
7714  //======================================== If required, pre-compute the energy levels distance descriptor
7715  if ( this->energyLevelDist )
7716  {
7717  one->precomputeRotInvDescriptor ( settings );
7718  }
7719 
7720  if ( settings->verbose > 2 )
7721  {
7722  std::cout << ">>>>> Structure " << this->structFiles.at(0) << " spherical harmonics computed." << std::endl;
7723  }
7724 
7725  if ( settings->htmlReport )
7726  {
7727  //==================================== Record progress
7728  std::stringstream hlpSS;
7729  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(0) << " spherical harmonics computed." << "</font>";
7730  rvapi_set_text ( hlpSS.str().c_str(),
7731  "ProgressSection",
7732  settings->htmlReportLineProgress,
7733  1,
7734  1,
7735  1 );
7736  settings->htmlReportLineProgress += 1;
7737  rvapi_flush ( );
7738  }
7739 
7740  //======================================== Initialise comparison values
7741  for ( unsigned int vecIt = 1; vecIt < static_cast<unsigned int> ( this->structFiles.size() ); vecIt++ )
7742  {
7743  this->bandwidthVec.at(vecIt) = this->bandwidthVec.at(0);
7744  this->thetaVec.at(vecIt) = this->thetaVec.at(0);
7745  this->phiVec.at(vecIt) = this->phiVec.at(0);
7746  this->glIntegOrderVec.at(vecIt) = this->glIntegOrderVec.at(0);
7747  this->extraSpaceVec.at(vecIt) = this->extraSpaceVec.at(0);
7748  }
7749 
7750  //======================================== Read in the objects to compare against one and get SH Coeffs
7751  std::vector<ProSHADE_data*> objs ( this->structFiles.size() - 1 );
7752  for ( unsigned int strIt = 0; strIt < static_cast<unsigned int> ( this->structFiles.size() - 1 ); strIt++ )
7753  {
7754  //==================================== Initialise the object
7755  objs.at(strIt) = new ProSHADE_data ();
7756 
7757  //==================================== Read in the objects and determine maximum band, theta, phi, integration order and extra cell space, if not specified by user
7758  fileType = checkFileType ( structFiles.at(strIt+1) );
7759  if ( fileType == 2 )
7760  {
7761  objs.at(strIt)->getDensityMapFromMAP ( this->structFiles.at(strIt+1),
7762  &this->shellSpacing,
7763  this->mapResolution,
7764  &this->bandwidthVec.at(strIt+1),
7765  &this->thetaVec.at(strIt+1),
7766  &this->phiVec.at(strIt+1),
7767  &this->glIntegOrderVec.at(strIt+1),
7768  &this->extraSpaceVec.at(strIt+1),
7769  settings->mapResDefault,
7770  settings->rotChangeDefault,
7771  settings,
7772  settings->overlayDefaults );
7773  }
7774  else if ( fileType == 1 )
7775  {
7776  objs.at(strIt)->getDensityMapFromPDB ( this->structFiles.at(strIt+1),
7777  &this->shellSpacing,
7778  this->mapResolution,
7779  &this->bandwidthVec.at(strIt+1),
7780  &this->thetaVec.at(strIt+1),
7781  &this->phiVec.at(strIt+1),
7782  &this->glIntegOrderVec.at(strIt+1),
7783  &this->extraSpaceVec.at(strIt+1),
7784  settings->mapResDefault,
7785  settings,
7786  this->bFactorValue,
7787  this->firstLineCOM );
7788  }
7789  else
7790  {
7791  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << this->structFiles.at(strIt+1) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file." << std::endl;
7792  exit ( -1 );
7793  }
7794 
7795  if ( settings->verbose > 1 )
7796  {
7797  std::cout << ">> Structure " << this->structFiles.at(strIt+1) << " loaded." << std::endl;
7798  }
7799 
7800  if ( settings->htmlReport )
7801  {
7802  //================================ Record progress
7803  std::stringstream hlpSS;
7804  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(strIt+1) << " loaded." << "</font>";
7805  rvapi_set_text ( hlpSS.str().c_str(),
7806  "ProgressSection",
7807  settings->htmlReportLineProgress,
7808  1,
7809  1,
7810  1 );
7811  settings->htmlReportLineProgress += 1;
7812  rvapi_flush ( );
7813  }
7814 
7815  //==================================== Deal with phase and MAP format data in general
7816  objs.at(strIt)->normaliseMap ( settings );
7817  if ( this->usePhase )
7818  {
7819  objs.at(strIt)->keepPhaseInMap ( this->alpha,
7820  this->bFactorChange,
7821  &this->bandwidthVec.at(strIt+1),
7822  &this->thetaVec.at(strIt+1),
7823  &this->phiVec.at(strIt+1),
7824  &this->glIntegOrderVec.at(strIt+1),
7825  settings,
7826  this->useCOM,
7827  settings->noIQRsFromMap,
7828  settings->verbose,
7829  settings->clearMapData,
7830  settings->rotChangeDefault,
7831  settings->overlayDefaults,
7832  settings->maskBlurFactor,
7833  settings->maskBlurFactorGiven );
7834  }
7835  else
7836  {
7837  objs.at(strIt)->removePhaseFromMap ( this->alpha,
7838  this->bFactorChange,
7839  settings );
7840  }
7841 
7842  //==================================== Map the density onto spheres
7843  objs.at(strIt)->mapPhaselessToSphere ( settings,
7844  this->thetaVec.at(strIt+1),
7845  this->phiVec.at(strIt+1),
7846  this->shellSpacing,
7847  this->manualShells );
7848 
7849  //==================================== Now compute the Spherical Harmonics (SH) coefficients
7850  objs.at(strIt)->getSphericalHarmonicsCoeffs( this->bandwidthVec.at(strIt+1), settings );
7851 
7852  //==================================== And if required, the energy levels distance pre-computation
7853  if ( this->energyLevelDist )
7854  {
7855  objs.at(strIt)->precomputeRotInvDescriptor ( settings );
7856  }
7857 
7858  if ( settings->verbose > 2 )
7859  {
7860  std::cout << ">>>>> Structure " << this->structFiles.at(strIt+1) << " spherical harmonics computed." << std::endl;
7861  }
7862 
7863  if ( settings->htmlReport )
7864  {
7865  //==================================== Record progress
7866  std::stringstream hlpSS;
7867  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(strIt+1) << " spherical harmonics computed." << "</font>";
7868  rvapi_set_text ( hlpSS.str().c_str(),
7869  "ProgressSection",
7870  settings->htmlReportLineProgress,
7871  1,
7872  1,
7873  1 );
7874  settings->htmlReportLineProgress += 1;
7875  rvapi_flush ( );
7876  }
7877  }
7878 
7879  //======================================== Create the compare against all object
7880  this->cmpObj = new ProSHADE_compareOneAgainstAll ( one, &objs, this->ignoreLs, this->mPower, settings->verbose );
7881 
7882  //======================================== Save the decision whether to use phases or not
7883  if ( one->_keepOrRemove ) { this->cmpObj->_keepOrRemove = true; }
7884  else { this->cmpObj->_keepOrRemove = false; }
7885 
7886  //======================================== If required, compute the energy levels distances
7887  if ( this->energyLevelDist )
7888  {
7889  if ( settings->verbose > 0 )
7890  {
7891  std::cout << "Computing the cross-correlation distances." << std::endl;
7892  }
7893 
7894  if ( settings->htmlReport )
7895  {
7896  //================================ Record progress
7897  std::stringstream hlpSS;
7898  hlpSS << "<font color=\"green\">" << "Computing the cross-correlation distances." << "</font>";
7899  rvapi_set_text ( hlpSS.str().c_str(),
7900  "ProgressSection",
7901  settings->htmlReportLineProgress,
7902  1,
7903  1,
7904  1 );
7905  settings->htmlReportLineProgress += 1;
7906  rvapi_flush ( );
7907  }
7908  this->energyLevelsDistances = this->cmpObj->getEnergyLevelsDistance ( settings->verbose, settings );
7909 
7910  //==================================== ... and set which pairs not to follow further
7911  if ( this->enLevelsThreshold != -999.9 )
7912  {
7913  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7914  {
7915  if ( this->enLevelsThreshold > this->energyLevelsDistances.at(iter) )
7916  {
7917  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 1 );
7918  }
7919  else
7920  {
7921  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7922  }
7923  }
7924  }
7925  else
7926  {
7927  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7928  {
7929  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7930  }
7931  }
7932  }
7933  else
7934  {
7935  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7936  {
7937  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7938  }
7939  }
7940 
7941  //======================================== Pre-compute the E matrices in case either the trace sigmal or full rotation distance are required
7942  if ( this->traceSigmaDist || this->fullRotFnDist )
7943  {
7944  this->cmpObj->precomputeTrSigmaDescriptor ( this->shellSpacing, &this->glIntegOrderVec, settings );
7945  }
7946 
7947  //======================================== Compute the trace sigma distances, if required
7948  if ( this->traceSigmaDist )
7949  {
7950  if ( settings->verbose > 0 )
7951  {
7952  std::cout << "Computing the trace sigma distances." << std::endl;
7953  }
7954  if ( settings->htmlReport )
7955  {
7956  //================================ Record progress
7957  std::stringstream hlpSS;
7958  hlpSS << "<font color=\"green\">" << "Computing the trace sigma distances." << "</font>";
7959  rvapi_set_text ( hlpSS.str().c_str(),
7960  "ProgressSection",
7961  settings->htmlReportLineProgress,
7962  1,
7963  1,
7964  1 );
7965  settings->htmlReportLineProgress += 1;
7966  rvapi_flush ( );
7967  }
7968 
7969  this->traceSigmaDistances = this->cmpObj->getTrSigmaDistance ( settings->verbose, settings );
7970 
7971  if ( this->trSigmaThreshold == -999.9 )
7972  {
7973  this->cmpObj->_trSigmaDoNotFollow = this->cmpObj->_enLevelsDoNotFollow;
7974  }
7975  else
7976  {
7977  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->traceSigmaDistances.size() ); iter++ )
7978  {
7979  if ( this->trSigmaThreshold > this->traceSigmaDistances.at(iter) )
7980  {
7981  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 1 );
7982  }
7983  else
7984  {
7985  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 0 );
7986  }
7987  }
7988  }
7989  }
7990  else
7991  {
7992  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7993  {
7994  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 0 );
7995  }
7996  }
7997 
7998  //======================================== If full rotation distance is required, pre-compute the requirements
7999  if ( this->fullRotFnDist )
8000  {
8001  if ( settings->verbose > 0 )
8002  {
8003  std::cout << "Computing the rotation function distances." << std::endl;
8004  }
8005  if ( settings->htmlReport )
8006  {
8007  //================================ Record progress
8008  std::stringstream hlpSS;
8009  hlpSS << "<font color=\"green\">" << "Computing the rotation function distances." << "</font>";
8010  rvapi_set_text ( hlpSS.str().c_str(),
8011  "ProgressSection",
8012  settings->htmlReportLineProgress,
8013  1,
8014  1,
8015  1 );
8016  settings->htmlReportLineProgress += 1;
8017  rvapi_flush ( );
8018  }
8019 
8020  this->cmpObj->getSO3InverseMap ( settings );
8021  if ( settings->verbose > 2 )
8022  {
8023  std::cout << ">>>>> Inverse SO(3) Fourier transform maps obtained." << std::endl;
8024  }
8025 
8026  this->cmpObj->getEulerAngles ( settings );
8027  if ( settings->verbose > 3 )
8028  {
8029  std::cout << ">>>>>>>> Optimal Euler angles calculated." << std::endl;
8030  }
8031 
8032  this->cmpObj->generateWignerMatrices ( settings );
8033  if ( settings->verbose > 2 )
8034  {
8035  std::cout << ">>>>> Wigner matrices computed." << std::endl;
8036  }
8037 
8038  this->fullRotationDistances = this->cmpObj->getRotCoeffDistance ( settings->verbose, settings );
8039  }
8040 
8041  //======================================== Free memory
8042  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( objs.size() ); iter++ )
8043  {
8044  if ( objs.at(iter) != nullptr )
8045  {
8046  delete objs.at(iter);
8047  }
8048  }
8049  objs.clear ( );
8050 
8051  delete cmpObj;
8052  cmpObj = nullptr;
8053 }
8054 
8063 {
8064  if ( this->cmpObj != nullptr ) { delete this->cmpObj; }
8065 }
8066 
8078 {
8079  //======================================== Sanity check
8080  if ( !this->energyLevelDist )
8081  {
8082  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The energy level distances were not required when the ProSHADE_distances object was initialised (the setUp structure parameter) and therefore they cannot now be obtained." << std::endl;
8083  exit ( -1 );
8084  }
8085 
8086  if ( this->cmpObj != nullptr )
8087  {
8088  if ( !this->cmpObj->_energyLevelsComputed )
8089  {
8090  std::cerr << " !!! ProSHADE ERROR !!! Error in structure comparison. !!! The energy level distances were not computed before their values are required." << std::endl;
8091  exit ( -1 );
8092  }
8093  }
8094 
8095  //======================================== Return
8096  return ( this->energyLevelsDistances );
8097 
8098 }
8099 
8111 {
8112  //======================================== Sanity check
8113  if ( !this->energyLevelDist )
8114  {
8115  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The energy level distances were not required when the ProSHADE_distances object was initialised (the setUp structure parameter) and therefore they cannot now be obtained." << std::endl;
8116  exit ( -1 );
8117  }
8118 
8119  //======================================== Return
8120  return ( this->fragEnergyLevelsDistances );
8121 
8122 }
8123 
8137 {
8138  //======================================== Sanity check
8139  if ( !this->traceSigmaDist )
8140  {
8141  std::cerr << "!!! ProSHADE ERROR!!! Error in structure comparison. !!! The trace sigma distances were not required when the ProSHADE_distances object was initialised (the setUp structure parameter) and therefore they cannot now be obtained." << std::endl;
8142  exit ( -1 );
8143  }
8144 
8145  if ( this->cmpObj != nullptr )
8146  {
8147  if ( !this->cmpObj->_trSigmaComputed )
8148  {
8149  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The trace sigma distances were not computed before their values are required." << std::endl;
8150  exit ( -1 );
8151  }
8152  }
8153 
8154  //======================================== Return
8155  return ( this->traceSigmaDistances );
8156 
8157 }
8158 
8170 {
8171  //======================================== Sanity check
8172  if ( !this->cmpObj->_trSigmaComputed )
8173  {
8174  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The trace sigma distances were not computed before their values are required." << std::endl;
8175  exit ( -1 );
8176  }
8177 
8178  //======================================== Return
8179  return ( this->fragTraceSigmaDistances );
8180 
8181 }
8182 
8196 {
8197  //======================================== Sanity check
8198  if ( !this->fullRotFnDist )
8199  {
8200  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The full rotation function distances were not required when the ProSHADE_distances object was initialised (the setUp structure parameter) and therefore they cannot now be obtained." << std::endl;
8201  exit ( -1 );
8202  }
8203 
8204  if ( this->cmpObj != nullptr )
8205  {
8206  if ( !this->cmpObj->_fullDistComputed )
8207  {
8208  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The full rotation function distances were not computed before their values are required." << std::endl;
8209  exit ( -1 );
8210  }
8211  }
8212 
8213  //======================================== Return
8214  return ( this->fullRotationDistances );
8215 
8216 }
8217 
8229 {
8230  //======================================== Sanity check
8231  if ( !this->cmpObj->_fullDistComputed )
8232  {
8233  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The full rotation function distances were not computed before their values are required." << std::endl;
8234  exit ( -1 );
8235  }
8236 
8237  //======================================== Return
8238  return ( this->fragfullRotationDistances );
8239 
8240 }
8241 
8252 {
8253  //======================================== Default values
8254  this->fragFilesExist = false;
8255  this->fragFiles.clear ( );
8256  this->one = nullptr;
8257 
8258  //======================================== Retain settings
8259  this->fragBoxSize = settings->mapFragBoxSize;
8260  this->mapFragName = settings->mapFragName;
8261  this->mapFragBoxFraction = settings->mapFragBoxFraction;
8262 
8263  //======================================== If half-maps processing is required, do it
8264  if ( settings->taskToPerform == ProSHADE::HalfMaps )
8265  {
8266  if ( settings->verbose != 0 )
8267  {
8268  std::cout << "-----------------------------------------------------------" << std::endl;
8269  std::cout << "| MODE: HalfMaps |" << std::endl;
8270  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8271  }
8272 
8273  //==================================== Sanity checks
8274  if ( settings->structFiles.size() != 2 )
8275  {
8276  std::cerr << "!!! ProSHADE ERROR !!! Attempted to process half-maps, but did supply ";
8277  if ( settings->structFiles.size() < 2 ) { std::cerr << "less "; }
8278  if ( settings->structFiles.size() > 2 ) { std::cerr << "more "; }
8279  std::cerr << "than 2 files. Please use the \'-f\' option to supply only the two half-maps map files. Terminating ..." << std::endl << std::endl;
8280 
8281  if ( settings->htmlReport )
8282  {
8283  std::stringstream hlpSS;
8284  hlpSS << "<font color=\"red\">" << "There are not exactly two input structures. Please supply only two files to the half-maps re-boxing functionality." << "</font>";
8285  rvapi_set_text ( hlpSS.str().c_str(),
8286  "ProgressSection",
8287  settings->htmlReportLineProgress,
8288  1,
8289  1,
8290  1 );
8291  settings->htmlReportLineProgress += 1;
8292  rvapi_flush ( );
8293  }
8294 
8295  exit ( -1 );
8296  }
8297 
8298  if ( settings->clearMapFile == "" )
8299  {
8300  std::cout << "!!! ProSHADE WARNING !!! Missing the file name as to where the new half-maps are to be saved. Will use \"proshade_reboxed_half1.map\" and \"proshade_reboxed_half2.map\", however, if these files already exist, they will be over-written." << std::endl << std::endl;
8301  settings->clearMapFile = "proshade_reboxed";
8302 
8303  if ( settings->htmlReport )
8304  {
8305  std::stringstream hlpSS;
8306  hlpSS << "<font color=\"orange\">" << "Missing the file name as to where the new half-maps are to be saved. Will use 'proshade_reboxed_half1.map' and 'proshade_reboxed_half2.map', however, if these files already exist, they will be over-written." << "</font>";
8307  rvapi_set_text ( hlpSS.str().c_str(),
8308  "ProgressSection",
8309  settings->htmlReportLineProgress,
8310  1,
8311  1,
8312  1 );
8313  settings->htmlReportLineProgress += 1;
8314  rvapi_flush ( );
8315  }
8316  }
8317 
8318  unsigned int fileTy1 = checkFileType ( settings->structFiles.at(0) );
8319  unsigned int fileTy2 = checkFileType ( settings->structFiles.at(1) );
8320  if ( ( fileTy1 != 2 ) || ( fileTy2 != 2 ) )
8321  {
8322  std::cerr << "!!! ProSHADE ERROR !!! Cannot recognise one or both of the half-maps format - are you sure these are in the CCP4 MAP format? Terminating..." << std::endl << std::endl;
8323 
8324  if ( settings->htmlReport )
8325  {
8326  std::stringstream hlpSS;
8327  hlpSS << "<font color=\"red\">" << "Cannot recognise the file format of the input file ";
8328 
8329  if ( ( fileTy1 != 2 ) && ( fileTy2 = 2 ) )
8330  {
8331  hlpSS << settings->structFiles.at(0) << "</font>";
8332  }
8333  if ( ( fileTy1 = 2 ) && ( fileTy2 != 2 ) )
8334  {
8335  hlpSS << settings->structFiles.at(1) << "</font>";
8336  }
8337  if ( ( fileTy1 != 2 ) && ( fileTy2 != 2 ) )
8338  {
8339  hlpSS << settings->structFiles.at(0) << " and " << settings->structFiles.at(1) << "</font>";
8340  }
8341 
8342  rvapi_set_text ( hlpSS.str().c_str(),
8343  "ProgressSection",
8344  settings->htmlReportLineProgress,
8345  1,
8346  1,
8347  1 );
8348  settings->htmlReportLineProgress += 1;
8349  rvapi_flush ( );
8350  }
8351 
8352  exit ( -1 );
8353  }
8354 
8355  //==================================== Deal with the maps
8356  double xTrans, yTrans, zTrans;
8357  dealWithHalfMaps ( settings, &xTrans, &yTrans, &zTrans );
8358 
8359  if ( settings->verbose > 0 )
8360  {
8361  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8362  std::cout << "| COMPLETED |" << std::endl;
8363  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8364  }
8365 
8366  if ( settings->htmlReport )
8367  {
8368  std::stringstream hlpSS;
8369  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8370  rvapi_set_text ( hlpSS.str().c_str(),
8371  "ProgressSection",
8372  settings->htmlReportLineProgress,
8373  1,
8374  1,
8375  1 );
8376  settings->htmlReportLineProgress += 1;
8377  rvapi_flush ( );
8378  }
8379 
8380  if ( settings->verbose > 0 )
8381  {
8382  std::cout << "-----------------------------------------------------------" << std::endl;
8383  std::cout << "| RESULTS |" << std::endl;
8384  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8385 
8386  std::cout << "Half maps saved into files:" << std::endl << " " << settings->clearMapFile << "_half1.map" << std::endl << " " << settings->clearMapFile << "_half2.map" << std::endl << std::endl;
8387  }
8388 
8389  //==================================== Done
8390  return ;
8391  }
8392 
8393  if ( settings->taskToPerform == ProSHADE::SimpleRebox )
8394  {
8395  unsigned int fileType = checkFileType ( settings->structFiles.at(0) );
8396  if ( fileType != 2 )
8397  {
8398  std::cerr << "!!! ProSHADE ERROR !!! The file supplied ( " << settings->structFiles.at(0) << " ) is not recognised as a map formatted file. Please check for file corruption and make sure that it is a MAP formatted file. Terminating ..." << std::endl << std::endl;
8399 
8400  if ( settings->htmlReport )
8401  {
8402  std::stringstream hlpSS;
8403  hlpSS << "<font color=\"red\">" << "The file supplied ( " << settings->structFiles.at(0) << " ) is not recognised as a map formatted file. Please check for file corruption and make sure that it is a MAP formatted file." << "</font>";
8404  rvapi_set_text ( hlpSS.str().c_str(),
8405  "ProgressSection",
8406  settings->htmlReportLineProgress,
8407  1,
8408  1,
8409  1 );
8410  settings->htmlReportLineProgress += 1;
8411  rvapi_flush ( );
8412  }
8413 
8414  exit ( -1 );
8415  }
8416 
8417  if ( settings->clearMapFile == "" )
8418  {
8419  std::cout << "!!! ProSHADE WARNING !!! Missing the file name as to where the new re-boxed map is to be saved. Will use \"proshade_reboxed.map\", however, if this file already exists, it will be over-written. To supply the file name, please use the \"--clearMap\" command line option." << std::endl << std::endl;
8420  settings->clearMapFile = "proshade_reboxed.map";
8421 
8422  if ( settings->htmlReport )
8423  {
8424  std::stringstream hlpSS;
8425  hlpSS << "<font color=\"orange\">" << "Missing the file name as to where the new re-boxed map is to be saved. Will use 'proshade_reboxed.map', however, if this file already exists, it will be over-written." << "</font>";
8426  rvapi_set_text ( hlpSS.str().c_str(),
8427  "ProgressSection",
8428  settings->htmlReportLineProgress,
8429  1,
8430  1,
8431  1 );
8432  settings->htmlReportLineProgress += 1;
8433  rvapi_flush ( );
8434  }
8435  }
8436 
8437  if ( settings->verbose > 3 )
8438  {
8439  std::cout << ">>>>>>>> Sanity checks passed." << std::endl;
8440  }
8441 
8442  if ( settings->htmlReport )
8443  {
8444  std::stringstream hlpSS;
8445  hlpSS << "<font color=\"green\">" << "Sanity checks passed." << "</font>";
8446  rvapi_set_text ( hlpSS.str().c_str(),
8447  "ProgressSection",
8448  settings->htmlReportLineProgress,
8449  1,
8450  1,
8451  1 );
8452  settings->htmlReportLineProgress += 1;
8453  rvapi_flush ( );
8454  }
8455 
8456  //==================================== Create the structure object
8457  this->one = new ProSHADE_data ();
8458 
8459  //==================================== Run re-boxing
8460  if ( settings->verbose != 0 )
8461  {
8462  std::cout << "Applying the re-boxing algorithm." << std::endl;
8463  }
8464 
8465  std::array<double,6> dims = one->getDensityMapFromMAPRebox ( settings->structFiles.at(0),
8466  settings->noIQRsFromMap,
8467  settings->extraSpace,
8468  settings->verbose,
8469  settings->useCubicMaps,
8470  settings->maskBlurFactor,
8471  settings->maskBlurFactorGiven,
8472  settings );
8473 
8474  //==================================== Report progress
8475  if ( settings->verbose > 0 )
8476  {
8477  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8478  std::cout << "| COMPLETED |" << std::endl;
8479  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8480  }
8481 
8482  //======================================== Write out map
8483  one->writeMap ( settings->clearMapFile, one->_densityMapCor );
8484 
8485  if ( settings->verbose > 0 )
8486  {
8487  std::cout << "The re-boxed map has been saved to the " << settings->clearMapFile << " file." << std::endl << std::endl;
8488  }
8489 
8490  if ( settings->htmlReport )
8491  {
8492  std::stringstream hlpSS;
8493  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8494  rvapi_set_text ( hlpSS.str().c_str(),
8495  "ProgressSection",
8496  settings->htmlReportLineProgress,
8497  1,
8498  1,
8499  1 );
8500  settings->htmlReportLineProgress += 1;
8501  rvapi_flush ( );
8502  }
8503 
8504  if ( settings->htmlReport )
8505  {
8506  rvapi_add_section ( "ResultsSection",
8507  "Results",
8508  "body",
8509  settings->htmlReportLine,
8510  0,
8511  1,
8512  1,
8513  true );
8514  settings->htmlReportLine += 1;
8515 
8516  std::stringstream hlpSS;
8517  hlpSS << "<pre><b>" << "The re-boxed structure is available at: </b>" << settings->clearMapFile << "</pre>";
8518  rvapi_set_text ( hlpSS.str().c_str(),
8519  "ResultsSection",
8520  0,
8521  0,
8522  1,
8523  1 );
8524 
8525  hlpSS.str ( std::string ( ) );
8526  hlpSS << "<pre><b>" << "Original structure dims: </b>" << dims[0] << " x " << dims[1] << " x " << dims[2] << "</pre>";
8527  rvapi_set_text ( hlpSS.str().c_str(),
8528  "ResultsSection",
8529  1,
8530  0,
8531  1,
8532  1 );
8533 
8534  hlpSS.str ( std::string ( ) );
8535  hlpSS << "<pre><b>" << "Re-boxed structure dims: </b>" << dims[3] << " x " << dims[4] << " x " << dims[5] << "</pre>";
8536  rvapi_set_text ( hlpSS.str().c_str(),
8537  "ResultsSection",
8538  2,
8539  0,
8540  1,
8541  1 );
8542 
8543  hlpSS.str ( std::string ( ) );
8544  hlpSS << "<pre><b>" << "New volume as percentage of old volume: </b>" << ( ( dims[3] * dims[4] * dims[5] ) / ( dims[0] * dims[1] * dims[2] ) ) * 100 << " %</pre>";
8545  rvapi_set_text ( hlpSS.str().c_str(),
8546  "ResultsSection",
8547  3,
8548  0,
8549  1,
8550  1 );
8551 
8552  hlpSS.str ( std::string ( ) );
8553  hlpSS << "<pre><b>" << "Linear processing speed-up: </b>" << ( ( dims[0] * dims[1] * dims[2] ) / ( dims[3] * dims[4] * dims[5] ) ) - 1.0 << " times</pre>";
8554  rvapi_set_text ( hlpSS.str().c_str(),
8555  "ResultsSection",
8556  4,
8557  0,
8558  1,
8559  1 );
8560  }
8561 
8562  //==================================== Done
8563  return ;
8564  }
8565 
8566  //======================================== Report progress
8567  if ( settings->verbose > -1 )
8568  {
8569  std::cout << "-----------------------------------------------------------" << std::endl;
8570  std::cout << "| MODE: Features |" << std::endl;
8571  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8572  }
8573 
8574  //======================================== Initialise valies
8575  this->maxMapU = 0.0;
8576  this->maxMapV = 0.0;
8577  this->maxMapW = 0.0;
8578  this->xRange = 0.0;
8579  this->yRange = 0.0;
8580  this->zRange = 0.0;
8581 
8582  //======================================== Create the structure object
8583  this->one = new ProSHADE_data ();
8584 
8585  //======================================== Read in the structure into one
8586  unsigned int fileType = checkFileType ( settings->structFiles.at(0) );
8587  if ( fileType == 2 )
8588  {
8589  if ( settings->verbose != 0 )
8590  {
8591  std::cout << "Computing the map features." << std::endl;
8592  }
8593  one->getDensityMapFromMAPFeatures ( settings->structFiles.at(0),
8594  &this->minDensPreNorm,
8595  &this->maxDensPreNorm,
8596  &this->minDensPostNorm,
8597  &this->maxDensPostNorm,
8598  &this->postNormMean,
8599  &this->postNormSdev,
8600  &this->maskVolume,
8601  &this->totalVolume,
8602  &this->maskMean,
8603  &this->maskSdev,
8604  &this->maskMin,
8605  &this->maskMax,
8606  &this->maskDensityRMS,
8607  &this->allDensityRMS,
8608  &this->origRanges,
8609  &this->origDims,
8610  settings->noIQRsFromMap,
8611  settings->extraSpace,
8612  settings->verbose,
8613  settings->useCubicMaps,
8614  settings->maskBlurFactor,
8615  settings->maskBlurFactorGiven,
8616  true,
8617  settings );
8618  }
8619  else if ( fileType == 1 )
8620  {
8621  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << settings->structFiles.at(0) << " !!! Attempted to obtain map features on PDB file. This is not possible - MAP file is required." << std::endl;
8622  exit ( -1 );
8623  }
8624  else
8625  {
8626  std::cerr << "!!! ProSHADE ERROR !!! Error loading file " << settings->structFiles.at(0) << " !!! Cannot detect the extension (currently, only PDB or MAP are allowed) and therefore cannot read the file." << std::endl;
8627  exit ( -1 );
8628  }
8629 
8630  if ( settings->verbose > 0 )
8631  {
8632  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8633  std::cout << "| COMPLETED |" << std::endl;
8634  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8635  }
8636 
8637  if ( settings->htmlReport )
8638  {
8639  std::stringstream hlpSS;
8640  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8641  rvapi_set_text ( hlpSS.str().c_str(),
8642  "ProgressSection",
8643  settings->htmlReportLineProgress,
8644  1,
8645  1,
8646  1 );
8647  settings->htmlReportLineProgress += 1;
8648  rvapi_flush ( );
8649  }
8650 
8651  //======================================== Write out map, if needed
8652  if ( settings->clearMapFile != "" )
8653  {
8654  one->writeMap ( settings->clearMapFile, one->_densityMapCor );
8655 
8656  if ( settings->htmlReport )
8657  {
8658  //==================================== Create section
8659  rvapi_add_section ( "FilenameSection",
8660  "Saved file",
8661  "body",
8662  settings->htmlReportLine,
8663  0,
8664  1,
8665  1,
8666  false );
8667  settings->htmlReportLine += 1;
8668 
8669  std::stringstream hlpSS;
8670  hlpSS << "<pre>" << "File saved as: " << settings->clearMapFile << "</pre>";
8671  rvapi_set_text ( hlpSS.str().c_str(),
8672  "FilenameSection",
8673  0,
8674  1,
8675  1,
8676  1 );
8677 
8678  rvapi_flush ( );
8679  }
8680  }
8681 
8682  //======================================== Done
8683 
8684 }
8685 
8694 {
8695  //======================================== Free memory
8696  if ( this->one != nullptr )
8697  {
8698  delete this->one;
8699  }
8700 }
8701 
8712 {
8713  //======================================== Sanity check
8714  if ( !this->fragFilesExist )
8715  {
8716  std::cerr << "!!! ProSHADE ERROR !!! Attempted to obtain the list of fragment files without doing the fragmentation first. Terminating..." << std::endl;
8717  exit ( -1 );
8718  }
8719 
8720  //======================================== If valid, return
8721  return ( this->fragFiles );
8722 }
8723 
8724 /* \brief This function writes out a map in the CCP4 MAP format.
8725 
8726  This function writes a density map (given as array of doubles by the second argument) to the file specified by the first argument. It makes use of all the default values in the object,
8727  if they are present and will stop execution and print error if they are not. While all the other parameters do have default values in this sense, they can all be set by the user to
8728  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
8729 
8730  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
8731  \param[in] map Double pointer to array of map values in the U, V, W order.
8732  \param[in] axOrder String with the order of the axes. Must have three letters containing any permutation of 'x', 'y' and 'z'. Default value is 'xyz'.
8733  \param[in] xFrom A value from which the x-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8734  \param[in] yFrom A value from which the y-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8735  \param[in] zFrom A value from which the z-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8736  \param[in] xTo A value to which the x-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8737  \param[in] yTo A value to which the y-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8738  \param[in] zTo A value to which the z-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8739  \param[in] xRange Dimension size (x-axis) in angstroms.
8740  \param[in] yRange Dimension size (y-axis) in angstroms.
8741  \param[in] zRange Dimension size (z-axis) in angstroms.
8742 
8743  \warning This is an internal function which should not be used by the user.
8744  */
8745 void ProSHADE_internal::ProSHADE_data::writeMap ( std::string fileName,
8746  double* map,
8747  std::string axOrder,
8748  float xFrom,
8749  float yFrom,
8750  float zFrom,
8751  float xTo,
8752  float yTo,
8753  float zTo,
8754  float xRange,
8755  float yRange,
8756  float zRange )
8757 {
8758  //======================================== Open file for writing
8759  int myMapMode = 1;
8760  CMap_io::CMMFile *mapFile = nullptr;
8761  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
8762  if ( mapFile == NULL )
8763  {
8764  std::cerr << "!!! ProSHADE ERROR !!! Cannot open file " << fileName << " for writing. Terminating..." << std::endl;
8765  exit ( -1 );
8766  }
8767 
8768  //======================================== Header: Initialisation
8769  const char* title = "ProSHADE genrated map ";
8770  int grid[3];
8771  int axisOrder[3];
8772  int dims[3];
8773  int axFrom[3];
8774  int axTo[3];
8775  float cell[6];
8776 
8777  //======================================== Header: Decide axis order
8778  for ( unsigned int iter = 0; iter < 3; iter++ )
8779  {
8780  if ( axOrder[iter] == 'x' ) { axisOrder[iter] = 1; }
8781  if ( axOrder[iter] == 'y' ) { axisOrder[iter] = 2; }
8782  if ( axOrder[iter] == 'z' ) { axisOrder[iter] = 3; }
8783  }
8784 
8785  //======================================== Header: Default or identical limits?
8786  if ( std::isinf ( xFrom ) )
8787  {
8788  xFrom = this->_xFrom;
8789  if ( std::isinf ( xFrom ) )
8790  {
8791  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8792  exit ( -1 );
8793  }
8794  }
8795  if ( std::isinf ( yFrom ) )
8796  {
8797  yFrom = this->_yFrom;
8798  if ( std::isinf ( yFrom ) )
8799  {
8800  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8801  exit ( -1 );
8802  }
8803  }
8804  if ( std::isinf ( zFrom ) )
8805  {
8806  zFrom = this->_zFrom;
8807  if ( std::isinf ( zFrom ) )
8808  {
8809  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8810  exit ( -1 );
8811  }
8812  }
8813  if ( std::isinf ( xTo ) )
8814  {
8815  xTo = this->_xTo;
8816  if ( std::isinf ( xTo ) )
8817  {
8818  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8819  exit ( -1 );
8820  }
8821  }
8822  if ( std::isinf ( yTo ) )
8823  {
8824  yTo = this->_yTo;
8825  if ( std::isinf ( yTo ) )
8826  {
8827  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8828  exit ( -1 );
8829  }
8830  }
8831  if ( std::isinf ( zTo ) )
8832  {
8833  zTo = this->_zTo;
8834  if ( std::isinf ( zTo ) )
8835  {
8836  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8837  exit ( -1 );
8838  }
8839  }
8840 
8841  //======================================== Header: Decide axis order, grid, axis limits and dimentions
8842  grid[axisOrder[0]-1] = xTo - xFrom + 1;
8843  grid[axisOrder[1]-1] = yTo - yFrom + 1;
8844  grid[axisOrder[2]-1] = zTo - zFrom + 1;
8845 
8846  axFrom[axisOrder[0]-1] = xFrom;
8847  axFrom[axisOrder[1]-1] = yFrom;
8848  axFrom[axisOrder[2]-1] = zFrom;
8849 
8850  axTo[axisOrder[0]-1] = xTo;
8851  axTo[axisOrder[1]-1] = yTo;
8852  axTo[axisOrder[2]-1] = zTo;
8853 
8854  dims[0] = axTo[0] - axFrom[0] + 1;
8855  dims[1] = axTo[1] - axFrom[1] + 1;
8856  dims[2] = axTo[2] - axFrom[2] + 1;
8857 
8858  //======================================== Header: Get cell parameters
8859  if ( std::isinf ( xRange ) )
8860  {
8861  xRange = this->_xRange;
8862  if ( std::isinf ( xRange ) )
8863  {
8864  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8865  exit ( -1 );
8866  }
8867  }
8868  if ( std::isinf ( yRange ) )
8869  {
8870  yRange = this->_yRange;
8871  if ( std::isinf ( yRange ) )
8872  {
8873  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8874  exit ( -1 );
8875  }
8876  }
8877  if ( std::isinf ( zRange ) )
8878  {
8879  zRange = this->_zRange;
8880  if ( std::isinf ( zRange ) )
8881  {
8882  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
8883  exit ( -1 );
8884  }
8885  }
8886 
8887  cell[0] = xRange;
8888  cell[1] = yRange;
8889  cell[2] = zRange;
8890  cell[3] = static_cast<float> ( 90.0 );
8891  cell[4] = static_cast<float> ( 90.0 );
8892  cell[5] = static_cast<float> ( 90.0 );
8893 
8894  //======================================== Header: Write the map header
8895  CMap_io::ccp4_cmap_set_cell ( mapFile, cell );
8896  CMap_io::ccp4_cmap_set_grid ( mapFile, grid );
8897  CMap_io::ccp4_cmap_set_order ( mapFile, axisOrder );
8898  CMap_io::ccp4_cmap_set_dim ( mapFile, dims );
8899  CMap_io::ccp4_cmap_set_origin ( mapFile, axFrom );
8900 
8901  CMap_io::ccp4_cmap_set_spacegroup ( mapFile, 1 );
8902  CMap_io::ccp4_cmap_set_title ( mapFile, title );
8903  CMap_io::ccp4_cmap_set_datamode ( mapFile, 2 );
8904 
8905  //======================================== Data: Write the map data
8906  int fastestDim = ( axTo[0] - axFrom[0] + 1 );
8907  int middleDim = ( axTo[1] - axFrom[1] + 1 ) * fastestDim;
8908  int newU, newV, newW;
8909  std::vector<float> section( middleDim );
8910  int index;
8911  int iters[3];
8912  int arrPos;
8913 
8914  for ( iters[2] = axFrom[2]; iters[2] <= axTo[2]; iters[2]++ )
8915  {
8916  index = 0;
8917 
8918  for ( iters[1] = axFrom[1]; iters[1] <= axTo[1]; iters[1]++ )
8919  {
8920  for ( iters[0] = axFrom[0]; iters[0] <= axTo[0]; iters[0]++ )
8921  {
8922  newU = iters[axisOrder[0]-1] - axFrom[axisOrder[0]-1];
8923  newV = iters[axisOrder[1]-1] - axFrom[axisOrder[1]-1];
8924  newW = iters[axisOrder[2]-1] - axFrom[axisOrder[2]-1];
8925  arrPos = newW + grid[axisOrder[2]-1] * ( newV + grid[axisOrder[1]-1] * newU );
8926 
8927  section[ index++ ] = static_cast<float> ( map[arrPos] );
8928  }
8929  }
8930 
8931  CMap_io::ccp4_cmap_write_section( mapFile, &section[0] );
8932  }
8933 
8934  CMap_io::ccp4_cmap_close ( mapFile );
8935 
8936  //======================================== Done
8937  return ;
8938 
8939 }
8940 
8941 /* \brief This function writes out a map in the CCP4 MAP format.
8942 
8943  This function writes a density map (given as array of floats by the second argument) to the file specified by the first argument. It makes use of all the default values in the object,
8944  if they are present and will stop execution and print error if they are not. While all the other parameters do have default values in this sense, they can all be set by the user to
8945  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
8946 
8947  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
8948  \param[in] map Float pointer to array of map values in the U, V, W order.
8949  \param[in] axOrder String with the order of the axes. Must have three letters containing any permutation of 'x', 'y' and 'z'. Default value is 'xyz'.
8950  \param[in] xFrom A value from which the x-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8951  \param[in] yFrom A value from which the y-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8952  \param[in] zFrom A value from which the z-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
8953  \param[in] xTo A value to which the x-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8954  \param[in] yTo A value to which the y-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8955  \param[in] zTo A value to which the z-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
8956  \param[in] xRange Dimension size (x-axis) in angstroms.
8957  \param[in] yRange Dimension size (y-axis) in angstroms.
8958  \param[in] zRange Dimension size (z-axis) in angstroms.
8959 
8960  \warning This is an internal function which should not be used by the user.
8961  */
8962 void ProSHADE_internal::ProSHADE_data::writeMap ( std::string fileName,
8963  float* map,
8964  std::string axOrder,
8965  float xFrom,
8966  float yFrom,
8967  float zFrom,
8968  float xTo,
8969  float yTo,
8970  float zTo,
8971  float xRange,
8972  float yRange,
8973  float zRange )
8974 {
8975  //======================================== Open file for writing
8976  int myMapMode = 1;
8977  CMap_io::CMMFile *mapFile = nullptr;
8978  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
8979  if ( mapFile == NULL )
8980  {
8981  std::cerr << "!!! ProSHADE ERROR !!! Cannot open file " << fileName << " for writing. Terminating..." << std::endl;
8982  exit ( -1 );
8983  }
8984 
8985  //======================================== Header: Initialisation
8986  const char* title = "ProSHADE genrated map ";
8987  int grid[3];
8988  int axisOrder[3];
8989  int dims[3];
8990  int axFrom[3];
8991  int axTo[3];
8992  float cell[6];
8993 
8994  //======================================== Header: Decide axis order
8995  for ( unsigned int iter = 0; iter < 3; iter++ )
8996  {
8997  if ( axOrder[iter] == 'x' ) { axisOrder[iter] = 1; }
8998  if ( axOrder[iter] == 'y' ) { axisOrder[iter] = 2; }
8999  if ( axOrder[iter] == 'z' ) { axisOrder[iter] = 3; }
9000  }
9001 
9002  //======================================== Header: Default or identical limits?
9003  if ( std::isinf ( xFrom ) )
9004  {
9005  xFrom = this->_xFrom;
9006  if ( std::isinf ( xFrom ) )
9007  {
9008  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9009  exit ( -1 );
9010  }
9011  }
9012  if ( std::isinf ( yFrom ) )
9013  {
9014  yFrom = this->_yFrom;
9015  if ( std::isinf ( yFrom ) )
9016  {
9017  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9018  exit ( -1 );
9019  }
9020  }
9021  if ( std::isinf ( zFrom ) )
9022  {
9023  zFrom = this->_zFrom;
9024  if ( std::isinf ( zFrom ) )
9025  {
9026  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zFrom parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9027  exit ( -1 );
9028  }
9029  }
9030  if ( std::isinf ( xTo ) )
9031  {
9032  xTo = this->_xTo;
9033  if ( std::isinf ( xTo ) )
9034  {
9035  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9036  exit ( -1 );
9037  }
9038  }
9039  if ( std::isinf ( yTo ) )
9040  {
9041  yTo = this->_yTo;
9042  if ( std::isinf ( yTo ) )
9043  {
9044  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9045  exit ( -1 );
9046  }
9047  }
9048  if ( std::isinf ( zTo ) )
9049  {
9050  zTo = this->_zTo;
9051  if ( std::isinf ( zTo ) )
9052  {
9053  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zTo parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9054  exit ( -1 );
9055  }
9056  }
9057 
9058  //======================================== Header: Decide axis order, grid, axis limits and dimentions
9059  grid[axisOrder[0]-1] = xTo - xFrom + 1;
9060  grid[axisOrder[1]-1] = yTo - yFrom + 1;
9061  grid[axisOrder[2]-1] = zTo - zFrom + 1;
9062 
9063  axFrom[axisOrder[0]-1] = xFrom;
9064  axFrom[axisOrder[1]-1] = yFrom;
9065  axFrom[axisOrder[2]-1] = zFrom;
9066 
9067  axTo[axisOrder[0]-1] = xTo;
9068  axTo[axisOrder[1]-1] = yTo;
9069  axTo[axisOrder[2]-1] = zTo;
9070 
9071  dims[0] = axTo[0] - axFrom[0] + 1;
9072  dims[1] = axTo[1] - axFrom[1] + 1;
9073  dims[2] = axTo[2] - axFrom[2] + 1;
9074 
9075  //======================================== Header: Get cell parameters
9076  if ( std::isinf ( xRange ) )
9077  {
9078  xRange = this->_xRange;
9079  if ( std::isinf ( xRange ) )
9080  {
9081  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the xRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9082  exit ( -1 );
9083  }
9084  }
9085  if ( std::isinf ( yRange ) )
9086  {
9087  yRange = this->_yRange;
9088  if ( std::isinf ( yRange ) )
9089  {
9090  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the yRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9091  exit ( -1 );
9092  }
9093  }
9094  if ( std::isinf ( zRange ) )
9095  {
9096  zRange = this->_zRange;
9097  if ( std::isinf ( zRange ) )
9098  {
9099  std::cerr << "!!! ProSHADE ERROR !!! Did not supply the zRange parameter to the writeMap function and there is no suitable default in the object. Terminating ..." << std::endl;
9100  exit ( -1 );
9101  }
9102  }
9103 
9104  cell[0] = xRange;
9105  cell[1] = yRange;
9106  cell[2] = zRange;
9107  cell[3] = static_cast<float> ( 90.0 );
9108  cell[4] = static_cast<float> ( 90.0 );
9109  cell[5] = static_cast<float> ( 90.0 );
9110 
9111  //======================================== Header: Write the map header
9112  CMap_io::ccp4_cmap_set_cell ( mapFile, cell );
9113  CMap_io::ccp4_cmap_set_grid ( mapFile, grid );
9114  CMap_io::ccp4_cmap_set_order ( mapFile, axisOrder );
9115  CMap_io::ccp4_cmap_set_dim ( mapFile, dims );
9116  CMap_io::ccp4_cmap_set_origin ( mapFile, axFrom );
9117 
9118  CMap_io::ccp4_cmap_set_spacegroup ( mapFile, 1 );
9119  CMap_io::ccp4_cmap_set_title ( mapFile, title );
9120  CMap_io::ccp4_cmap_set_datamode ( mapFile, 2 );
9121 
9122  //======================================== Data: Write the map data
9123  int fastestDim = ( axTo[0] - axFrom[0] + 1 );
9124  int middleDim = ( axTo[1] - axFrom[1] + 1 ) * fastestDim;
9125  int newU, newV, newW;
9126  std::vector<float> section ( middleDim );
9127  int index;
9128  int iters[3];
9129  int arrPos;
9130 
9131 
9132  for ( iters[2] = axFrom[2]; iters[2] <= axTo[2]; iters[2]++ )
9133  {
9134  index = 0;
9135 
9136  for ( iters[1] = axFrom[1]; iters[1] <= axTo[1]; iters[1]++ )
9137  {
9138  for ( iters[0] = axFrom[0]; iters[0] <= axTo[0]; iters[0]++ )
9139  {
9140  newU = iters[axisOrder[0]-1] - axFrom[axisOrder[0]-1];
9141  newV = iters[axisOrder[1]-1] - axFrom[axisOrder[1]-1];
9142  newW = iters[axisOrder[2]-1] - axFrom[axisOrder[2]-1];
9143  arrPos = newW + grid[axisOrder[2]-1] * ( newV + grid[axisOrder[1]-1] * newU );
9144 
9145  section[ index++ ] = static_cast<float> ( map[arrPos] );
9146  }
9147  }
9148 
9149  CMap_io::ccp4_cmap_write_section( mapFile, &section[0] );
9150  }
9151 
9152  CMap_io::ccp4_cmap_close ( mapFile );
9153 
9154  //======================================== Done
9155  return ;
9156 
9157 }
9158 
9159 /* \brief This function writes out a map in the CCP4 MAP format.
9160 
9161  This function writes a density map (given as array of floats by the second argument) to the file specified by the first argument. It makes use of all the default values in the object,
9162  if they are present and will stop execution and print error if they are not. While all the other parameters do have default values in this sense, they can all be set by the user to
9163  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
9164 
9165  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
9166  \param[in] map Float pointer to array of map values in the U, V, W order.
9167  \param[in] axOrder String with the order of the axes. Must have three letters containing any permutation of 'x', 'y' and 'z'. Default value is 'xyz'.
9168  \param[in] xFrom A value from which the x-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
9169  \param[in] yFrom A value from which the y-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
9170  \param[in] zFrom A value from which the z-axis should start. Can be negative, but should be integer. Float is used for internal purposes only!
9171  \param[in] xTo A value to which the x-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
9172  \param[in] yTo A value to which the y-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
9173  \param[in] zTo A value to which the z-axis should run to. Can be negative, but should be integer. Float is used for internal purposes only!
9174  \param[in] xRange Dimension size (x-axis) in angstroms.
9175  \param[in] yRange Dimension size (y-axis) in angstroms.
9176  \param[in] zRange Dimension size (z-axis) in angstroms.
9177 
9178  \warning This is an internal function which should not be used by the user.
9179  */
9180 
9181 void ProSHADE_internal::ProSHADE_data::writePDB ( std::string templateName,
9182  std::string outputName,
9183  double rotEulA,
9184  double rotEulB,
9185  double rotEulG,
9186  double trsX,
9187  double trsY,
9188  double trsZ )
9189 {
9190  //======================================== Read in PDB template file
9191  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
9192  if ( mfile->ReadCoorFile ( templateName.c_str() ) )
9193  {
9194  std::cerr << "!!! ProSHADE ERROR !!! Cannot read file: " << templateName.c_str() << std::endl;
9195  exit ( -1 );
9196  }
9197 
9198  //======================================== Initialise Centre location
9199  double maxX = 0.0;
9200  double minX = 0.0;
9201  double maxY = 0.0;
9202  double minY = 0.0;
9203  double maxZ = 0.0;
9204  double minZ = 0.0;
9205  bool firstAtom = true;
9206 
9207  //======================================== Initialise MMDB crawl
9208  int noChains = 0;
9209  int noResidues = 0;
9210  int noAtoms = 0;
9211 
9212  clipper::mmdb::PPCChain chain;
9213  clipper::mmdb::PPCResidue residue;
9214  clipper::mmdb::PPCAtom atom;
9215 
9216  std::vector < std::array<double,3> > atCoords;
9217  std::array<double,3> hlpArr;
9218 
9219  //======================================== Get all chains
9220  mfile->GetChainTable ( 1, chain, noChains );
9221  firstAtom = true;
9222  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9223  {
9224  if ( chain[nCh] )
9225  {
9226  //================================ Get all residues
9227  chain[nCh]->GetResidueTable ( residue, noResidues );
9228 
9229  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9230  {
9231  if ( residue[nRes] )
9232  {
9233  //======================== Get all atoms
9234  residue[nRes]->GetAtomTable ( atom, noAtoms );
9235 
9236  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9237  {
9238  if ( atom[aNo] )
9239  {
9240  //================ Check for termination 'residue'
9241  if ( atom[aNo]->Ter ) { continue; }
9242 
9243  //================ Save coords for easier manipulation
9244  hlpArr[0] = atom[aNo]->x;
9245  hlpArr[1] = atom[aNo]->y;
9246  hlpArr[2] = atom[aNo]->z;
9247  atCoords.emplace_back ( hlpArr );
9248 
9249  //================ Find axis maxs and mins
9250  if ( firstAtom )
9251  {
9252  maxX = atom[aNo]->x;
9253  minX = atom[aNo]->x;
9254  maxY = atom[aNo]->y;
9255  minY = atom[aNo]->y;
9256  maxZ = atom[aNo]->z;
9257  minZ = atom[aNo]->z;
9258  firstAtom = false;
9259  }
9260  else
9261  {
9262  if ( atom[aNo]->x > maxX ) { maxX = atom[aNo]->x; } if ( atom[aNo]->x < minX ) { minX = atom[aNo]->x; }
9263  if ( atom[aNo]->y > maxY ) { maxY = atom[aNo]->y; } if ( atom[aNo]->y < minY ) { minY = atom[aNo]->y; }
9264  if ( atom[aNo]->z > maxZ ) { maxZ = atom[aNo]->z; } if ( atom[aNo]->z < minZ ) { minZ = atom[aNo]->z; }
9265  }
9266  }
9267  }
9268  }
9269  }
9270  }
9271  }
9272 
9273  //======================================== Apply the rotation if need be
9274  if ( ( rotEulA != 0.0 ) || ( rotEulB != 0.0 ) || ( rotEulG != 0.0 ) )
9275  {
9276  // ... center on centre of cell
9277  double xRng = ( maxX - minX ) / 2.0;
9278  double yRng = ( maxY - minY ) / 2.0;
9279  double zRng = ( maxZ - minZ ) / 2.0;
9280  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9281  {
9282  atCoords.at(iter)[0] = ( atCoords.at(iter)[0] - minX ) - xRng;
9283  atCoords.at(iter)[1] = ( atCoords.at(iter)[1] - minY ) - yRng;
9284  atCoords.at(iter)[2] = ( atCoords.at(iter)[2] - minZ ) - zRng;
9285  }
9286 
9287  // ... get rotation matrix
9288  std::vector< std::vector < double > > rMat;
9289  std::vector< double > hlpVec;
9290  hlpVec.emplace_back ( cos ( rotEulA ) * cos ( rotEulB ) * cos ( rotEulG ) - sin ( rotEulA ) * sin ( rotEulG ) );
9291  hlpVec.emplace_back ( sin ( rotEulA ) * cos ( rotEulB ) * cos ( rotEulG ) + cos ( rotEulA ) * sin ( rotEulG ) );
9292  hlpVec.emplace_back ( -sin ( rotEulB ) * cos ( rotEulG ) );
9293  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9294 
9295  hlpVec.emplace_back ( -cos ( rotEulA ) * cos ( rotEulB ) * sin ( rotEulG ) - sin ( rotEulA ) * cos ( rotEulG ) );
9296  hlpVec.emplace_back ( -sin ( rotEulA ) * cos ( rotEulB ) * sin ( rotEulG ) + cos ( rotEulA ) * cos ( rotEulG ) );
9297  hlpVec.emplace_back ( sin ( rotEulB ) * sin ( rotEulG ) );
9298  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9299 
9300  hlpVec.emplace_back ( cos ( rotEulA ) * sin ( rotEulB ) );
9301  hlpVec.emplace_back ( sin ( rotEulA ) * sin ( rotEulB ) );
9302  hlpVec.emplace_back ( cos ( rotEulB ) );
9303  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9304 
9305  // ... rotate coords
9306  double hlpXVal = 0.0;
9307  double hlpYVal = 0.0;
9308  double hlpZVal = 0.0;
9309  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9310  {
9311  hlpXVal = ( atCoords.at(iter)[0] * rMat.at(0).at(0) ) + ( atCoords.at(iter)[1] * rMat.at(1).at(0) ) + ( atCoords.at(iter)[2] * rMat.at(2).at(0) );
9312  hlpYVal = ( atCoords.at(iter)[0] * rMat.at(0).at(1) ) + ( atCoords.at(iter)[1] * rMat.at(1).at(1) ) + ( atCoords.at(iter)[2] * rMat.at(2).at(1) );
9313  hlpZVal = ( atCoords.at(iter)[0] * rMat.at(0).at(2) ) + ( atCoords.at(iter)[1] * rMat.at(1).at(2) ) + ( atCoords.at(iter)[2] * rMat.at(2).at(2) );
9314 
9315  atCoords.at(iter)[0] = hlpXVal;
9316  atCoords.at(iter)[1] = hlpYVal;
9317  atCoords.at(iter)[2] = hlpZVal;
9318  }
9319 
9320  // ... move coords back to original positions
9321  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9322  {
9323  atCoords.at(iter)[0] = ( atCoords.at(iter)[0] + xRng ) + minX;
9324  atCoords.at(iter)[1] = ( atCoords.at(iter)[1] + yRng ) + minY;
9325  atCoords.at(iter)[2] = ( atCoords.at(iter)[2] + zRng ) + minZ;
9326  }
9327  }
9328 
9329  //======================================== Translate coordinates as required
9330  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9331  {
9332  atCoords.at(iter)[0] = atCoords.at(iter)[0] + trsX;
9333  atCoords.at(iter)[1] = atCoords.at(iter)[1] + trsY;
9334  atCoords.at(iter)[2] = atCoords.at(iter)[2] + trsZ;
9335  }
9336 
9337  //======================================== Save coords back to the PDB structure
9338  unsigned int atIt = 0;
9339  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9340  {
9341  if ( chain[nCh] )
9342  {
9343  //================================ Get all residues
9344  chain[nCh]->GetResidueTable ( residue, noResidues );
9345 
9346  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9347  {
9348  if ( residue[nRes] )
9349  {
9350  //======================== Get all atoms
9351  residue[nRes]->GetAtomTable ( atom, noAtoms );
9352 
9353  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9354  {
9355  if ( atom[aNo] )
9356  {
9357  //================ Check for termination 'residue'
9358  if ( atom[aNo]->Ter ) { continue; }
9359 
9360  //================ Save coords for easier manipulation
9361  atom[aNo]->SetCoordinates ( atCoords.at(atIt)[0],
9362  atCoords.at(atIt)[1],
9363  atCoords.at(atIt)[2],
9364  atom[aNo]->occupancy,
9365  atom[aNo]->tempFactor );
9366  atIt += 1;
9367 
9368  }
9369  }
9370  }
9371  }
9372  }
9373  }
9374 
9375  //======================================== Write the PDB file
9376  if ( mfile->WritePDBASCII ( outputName.c_str() ) )
9377  {
9378  std::cerr << "!!! ProSHADE ERROR !!! Failed to write out PDB file " << outputName.c_str() << "." << std::endl;
9379  exit ( -1 );
9380  }
9381 
9382  //======================================== Done
9383  return ;
9384 }
9385 
9386 /* \brief This function deletes a PDB model from the map densiry.
9387 
9388  This function takes a PDB file and deletes its density from the map density saved in this ProSHADE_data object. This is used to stop ProSHADE from searching matches between locations
9389  which may already have model assigned.
9390  .
9391  \param[in] modelPath The path to the PDB file containing the model.
9392 
9393  \warning This is an internal function which should not be used by the user.
9394  */
9395 
9396 void ProSHADE_internal::ProSHADE_data::deleteModel ( std::string modelPath )
9397 {
9398  //======================================== Init
9399  double atDistMax = 3.0;
9400 
9401  //======================================== Read in file
9402  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
9403  if ( mfile->ReadCoorFile ( modelPath.c_str() ) )
9404  {
9405  std::cerr << "!!! ProSHADE ERROR !!! Cannot read model file: " << modelPath.c_str() << std::endl;
9406  exit ( -1 );
9407  }
9408 
9409  //======================================== Initialise MMDB crawl
9410  int noChains = 0;
9411  int noResidues = 0;
9412  int noAtoms = 0;
9413  std::vector<std::array<double,3>> coords;
9414  std::array<double,3> hlpArr;
9415 
9416  clipper::mmdb::PPCChain chain;
9417  clipper::mmdb::PPCResidue residue;
9418  clipper::mmdb::PPCAtom atom;
9419 
9420  //======================================== Get all chains
9421  mfile->GetChainTable ( 1, chain, noChains );
9422  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9423  {
9424  if ( chain[nCh] )
9425  {
9426  //================================ Get all residues
9427  chain[nCh]->GetResidueTable ( residue, noResidues );
9428 
9429  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9430  {
9431  if ( residue[nRes] )
9432  {
9433  //======================== Get all atoms
9434  residue[nRes]->GetAtomTable ( atom, noAtoms );
9435 
9436  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9437  {
9438  if ( atom[aNo] )
9439  {
9440  //================ Check for termination 'residue'
9441  if ( atom[aNo]->Ter ) { continue; }
9442 
9443  //================ Save the coords
9444  hlpArr[0] = atom[aNo]->x;
9445  hlpArr[1] = atom[aNo]->y;
9446  hlpArr[2] = atom[aNo]->z;
9447 
9448  //================ And save to vector
9449  coords.emplace_back ( hlpArr );
9450  }
9451  }
9452  }
9453  }
9454  }
9455  }
9456 
9457  //======================================== Free memory
9458  delete mfile;
9459 
9460  //======================================== Allocate and pre-set bew mask
9461  double* remMask = new double[(this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1)];
9462  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1) ); iter++ )
9463  {
9464  remMask[iter] = HUGE_VAL;
9465  }
9466 
9467  //======================================== For each map position
9468  double xRealStart = ( this->_xFrom / static_cast<double>( this->_maxMapU + 1 ) ) * this->_xRange;
9469  double yRealStart = ( this->_yFrom / static_cast<double>( this->_maxMapV + 1 ) ) * this->_yRange;
9470  double zRealStart = ( this->_zFrom / static_cast<double>( this->_maxMapW + 1 ) ) * this->_zRange;
9471 
9472  double xRealStep = 1.0 / static_cast<double>( this->_maxMapU + 1 ) * this->_xRange;
9473  double yRealStep = 1.0 / static_cast<double>( this->_maxMapV + 1 ) * this->_yRange;
9474  double zRealStep = 1.0 / static_cast<double>( this->_maxMapW + 1 ) * this->_zRange;
9475 
9476  double xHlp = 0.0;
9477  double yHlp = 0.0;
9478  double zHlp = 0.0;
9479 
9480  double dist = 0.0;
9481 
9482  int arrPos = 0;
9483  int uIter = 0;
9484  int vIter = 0;
9485  int wIter = 0;
9486  for ( int cIt = 0; cIt < static_cast<int> ( coords.size() ); cIt++ )
9487  {
9488  uIter = 0;
9489  for ( double uIt = xRealStart; uIt < static_cast<double> ( ( this->_xTo / static_cast<double>( this->_maxMapU + 1 ) ) * this->_xRange ); uIt += xRealStep )
9490  {
9491  if ( std::abs ( uIt - coords.at(cIt)[0] ) > atDistMax ) { uIter += 1; continue; }
9492  xHlp = pow ( uIt - coords.at(cIt)[0], 2.0 );
9493 
9494  vIter = 0;
9495  for ( double vIt = yRealStart; vIt < static_cast<double> ( ( this->_yTo / static_cast<double>( this->_maxMapV + 1 ) ) * this->_yRange ); vIt += yRealStep )
9496  {
9497  if ( std::abs ( vIt - coords.at(cIt)[1] ) > atDistMax ) { vIter += 1; continue; }
9498  yHlp = pow ( vIt - coords.at(cIt)[1], 2.0 );
9499 
9500  wIter = 0;
9501  for ( double wIt = zRealStart; wIt < static_cast<double> ( ( this->_zTo / static_cast<double>( this->_maxMapW + 1 ) ) * this->_zRange ); wIt += zRealStep )
9502  {
9503  if ( std::abs ( wIt - coords.at(cIt)[2] ) > atDistMax ) { wIter += 1; continue; }
9504  zHlp = pow ( wIt - coords.at(cIt)[2], 2.0 );
9505 
9506  arrPos = wIter + (this->_maxMapW + 1) * ( vIter + (this->_maxMapV + 1) * uIter );
9507  dist = sqrt ( xHlp + yHlp + zHlp );
9508 
9509  if ( remMask[arrPos] == HUGE_VAL ) { remMask[arrPos] = dist; }
9510  else { if ( dist < remMask[arrPos] ) { remMask[arrPos] = dist; } }
9511 
9512  wIter += 1;
9513  }
9514 
9515  vIter += 1;
9516  }
9517 
9518  uIter += 1;
9519  }
9520  }
9521 
9522  //======================================== Delete and see?
9523  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1) ); iter++ )
9524  {
9525  if ( remMask[iter] != HUGE_VAL )
9526  {
9527  this->_densityMapMap[iter] = 0.0;
9528  }
9529  }
9530 
9531  //======================================== Free memory
9532  delete[] remMask;
9533 
9534  //======================================== Done
9535  return ;
9536 
9537 }
double aaErrorTolerance
The tolerance parameter on matching axes for the angle-axis representation of rotations.
Definition: ProSHADE.h:128
This class deals with reading in the data and computing structure specific information including the ...
std::vector< std::vector< double > > getFragFullRotationDistances()
This function returns a vector of vectors of full rotation function distances between each fragment a...
std::string symmetryType
The required symmetry type. If no symmetry is required, leave empty. Possible values are: C...
Definition: ProSHADE.h:163
double mapResolution
This is the internal resolution at which the calculations are done, not necessarily the resolution of...
Definition: ProSHADE.h:78
double noIQRsFromMap
This is the number of interquartile distances from mean that is used to threshold the map masking...
Definition: ProSHADE.h:93
std::vector< std::array< double, 8 > > getSO3Peaks(ProSHADE::ProSHADE_settings *settings, double noIQRs=1.5, bool freeMem=true, int peakSize=1, double realDist=0.4, int verbose=1)
This function detects &#39;true&#39; peaks from the background of the SO3 inverse transform map...
bool clearMapData
This value is used to decide whether the input maps should be cleared again, or not.
Definition: ProSHADE.h:146
unsigned int theta
This parameter is the longitude of the spherical grid mapping. It should be 2 * bandwidth unless ther...
Definition: ProSHADE.h:83
std::vector< std::vector< std::array< double, 5 > > > findTetrSymmetry(std::vector< std::array< double, 5 > > CnSymm, double *tetrSymmPeakAvg, double axisErrorTolerance=0.1)
This function detects the tetrahedral symmetries in the structure.
unsigned int checkFileType(std::string fileName)
This function checks the input file for being either PDB or MAP formatted.
bool dbDistOverlay
This value is false in all conditions, unless programatically changed. If changed, distance computations will use the phaseless database to compute overlay before distances computation. This is computationally expensive and requires phaseless as well as phased database.
Definition: ProSHADE.h:177
void rotateStructure(ProSHADE_data *cmpObj1, ProSHADE::ProSHADE_settings *settings, std::string saveName, int verbose=0, std::string axOrd="xyz", bool internalUse=false)
Rotates the density map be given Angle-Axis rotation using the Wigner matrices and inverse spharical ...
double bFactorValue
This is the value to which all B-factors of PDB files will be changed to.
Definition: ProSHADE.h:88
std::string clearMapFile
If map features are to be extracted, should the clear map be saved (then give file name here)...
Definition: ProSHADE.h:144
void translateMap(double xShift, double yShift, double zShift)
This function translates the data along the three coordinate axis by the amount given by the three pa...
std::vector< std::vector< std::array< double, 5 > > > findIcosSymmetry(std::vector< std::array< double, 5 > > CnSymm, double *icosSymmPeakAvg, double axisErrorTolerance=0.1)
This function detects the icosahedral symmetries in the structure.
std::string databaseName
The name of the bin file to which the database should be saved.
Definition: ProSHADE.h:156
void mapPhaselessToSphere(ProSHADE::ProSHADE_settings *settings, double theta, double phi, double shellSz, unsigned int manualShells=0, bool keepInMemory=false, bool rotDefaults=false)
This function assumes the data have been processed and maps them onto a set of concentric spheres wit...
double zTranslation
The number of angstroms by which the structure should be translated along the Z axis.
Definition: ProSHADE.h:173
bool overlayDefaults
If true, the shell spacing and distances will be doube to their typical values. This is to speed up m...
Definition: ProSHADE.h:176
bool usePhase
Here the user can decide whether to use phase information or whether to ignore it completely...
Definition: ProSHADE.h:101
double mapFragBoxFraction
Fraction of box that needs to have density in order to be passed on.
Definition: ProSHADE.h:153
std::vector< std::string > deleteModels
The filenames listed here consist of models which should have their density deleted from the map befo...
Definition: ProSHADE.h:180
unsigned int bandwidth
This parameter determines the angular resolution of the spherical harmonics decomposition.
Definition: ProSHADE.h:80
void keepPhaseInMap(double alpha, double bFac, unsigned int *bandwidth, unsigned int *theta, unsigned int *phi, unsigned int *glIntegOrder, ProSHADE::ProSHADE_settings *settings, bool useCom=true, double maxMapIQR=10.0, int verbose=0, bool clearMapData=true, bool rotDefaults=false, bool overlapDefaults=false, double blurFactor=500.0, bool maskBlurFactorGiven=false)
This function keeps the phase information from the density map and prepares the data for SH coefficie...
std::vector< std::vector< double > > getFragTraceSigmaDistances()
This function returns a vector of vectors of trace sigma distances between each fragment and the whol...
bool htmlReport
Should HTML report for the run be created?
Definition: ProSHADE.h:186
std::vector< std::array< double, 5 > > findCnSymmetry(std::vector< std::array< double, 8 > > peaks, ProSHADE::ProSHADE_settings *settings, double axisErrorTolerance=0.0, bool freeMem=true, double percAllowedToMiss=0.33, int verbose=1)
This function attempts to detect the C-symmetries present in the list of overlay peaks.
void setEulerAngles(double alpha, double beta, double gamma)
This function is used to set the Euler angles for further processing.
int verbose
Should the software report on the progress, or just be quiet? Value between 0 (quiet) and 4 (loud) ...
Definition: ProSHADE.h:189
double rotAngle
The angle of the rotation to be done to the map structure in the map rotation mode.
Definition: ProSHADE.h:166
void printResultsClear(int verbose)
This function prints the cleared results to the screen.
bool saveWithAndWithout
This option decides whether both with and without phase spherical harmonics should be saved...
Definition: ProSHADE.h:102
The main header file containing all declarations the user of the library needs.
double trSigmaThreshold
All structure pairs with trace sigma descriptor value less than this will not be subjected to any fur...
Definition: ProSHADE.h:138
double alpha
This parameter determines the power to which the |F|&#39;s should be raised.
Definition: ProSHADE.h:113
bool firstLineCOM
This is a special option for metal detection, please leave false.
Definition: ProSHADE.h:106
void precomputeTrSigmaDescriptor()
This function computes the E matrices required for the trace sigma descriptor, the rotation function ...
bool fullRotFnDist
Should the full rotation function distances descriptor be computed.
Definition: ProSHADE.h:134
bool useCubicMaps
When saving clear maps, should the rectangular or cubic (older versions of refmac need this) maps be ...
Definition: ProSHADE.h:145
bool maskBlurFactorGiven
Was a specific value of the blurring factor requested by the user?
Definition: ProSHADE.h:148
std::vector< std::vector< std::array< double, 5 > > > findOctaSymmetry(std::vector< std::array< double, 5 > > CnSymm, double *octaSymmPeakAvg, double axisErrorTolerance=0.1)
This function detects the octahedral symmetries in the structure.
std::vector< double > getFullRotationDistances()
This function returns a vector of full rotation function distances between the first and all other st...
double maxAvgPeakForSymmetry(double X, double Y, double Z, double Angle, ProSHADE::ProSHADE_settings *settings)
This function takes angle and axis and checks the SO(3) map for this specific symmetry only...
std::vector< int > ignoreLs
This vector lists all the bandwidth values which should be ignored and not part of the computations...
Definition: ProSHADE.h:117
int peakSurroundingPoints
For a peak to exist, how many points in every direction need to be smalled than the middle value...
Definition: ProSHADE.h:125
double rotXAxis
The X-axis element of the rotation axis along which the rotation is to be done in the map rotation mo...
Definition: ProSHADE.h:167
double shellSpacing
This parameter determines how far the radial shells should be from each other.
Definition: ProSHADE.h:96
This file contains all the functions related to computing the Gauss-Legendre integration variables...
double rotYAxis
The Y-axis element of the rotation axis along which the rotation is to be done in the map rotation mo...
Definition: ProSHADE.h:168
ProSHADE_compareOneAgainstAll(ProSHADE_data *oneStr, std::vector< ProSHADE_data *> *allStrs, std::vector< int > ignoreL, double matrixPowerWeight, int verbose)
Contructor for the ProSHADE_compareOneAgainstAll class.
std::vector< std::vector< std::array< double, 6 > > > findDnSymmetry(std::vector< std::array< double, 5 > > CnSymm, double axisErrorTolerance=0.1)
This function detects dihedral (D) symmetries from the list of already detected C symmetries...
double rotZAxis
The Z-axis element of the rotation axis along which the rotation is to be done in the map rotation mo...
Definition: ProSHADE.h:169
double peakDistanceForReal
Threshold for determining &#39;missing peaks&#39; existence.
Definition: ProSHADE.h:124
bool mapResDefault
This variable states if default resolution should be used, or whether the user has supplied a differe...
Definition: ProSHADE.h:85
bool traceSigmaDist
Should the trace sigma distances descriptor be computed.
Definition: ProSHADE.h:133
std::vector< std::vector< double > > getFragEnergyLevelsDistances()
This function returns a vector of vectors of energy level distances between each fragment and the who...
This is the executive class responsible for comparing strictly two structures.
std::vector< std::string > getFragmentsList(void)
This function returns the paths to all fragment files saved by fragmentation functionality.
bool rotChangeDefault
If map rotation is selected, the default automatic parameter decision is changed. This variable state...
Definition: ProSHADE.h:170
std::vector< std::array< double, 5 > > findCnSymmetryClear(std::vector< std::array< double, 5 > > CnSymm, ProSHADE::ProSHADE_settings *settings, double maxGap=0.2, bool *pf=nullptr)
This function takes the detected C-symmetries list, removes low probability symmetries and sorts as t...
~ProSHADE_compareOneAgainstAll()
Destructor for the ProSHADE_compareOneAgainstAll class.
void getSphericalHarmonicsCoeffs(unsigned int bandwidth, ProSHADE::ProSHADE_settings *settings)
This function takes the sphere mapped data and computes spherical harmoncis decomposition for each sh...
unsigned int phi
This parameter is the latitudd of the spherical grid mapping. It should be 2 * bandwidth unless there...
Definition: ProSHADE.h:84
void getSO3InverseMap(ProSHADE::ProSHADE_settings *settings)
This function is responsible for computing the SO3 inverse transform.
~ProSHADE_distances()
This is the destructor for the ProSHADE_distances class.
void printResultsClearHTML(ProSHADE::ProSHADE_settings *settings)
This function prints the cleared results to the HTML file.
unsigned int symmetryFold
The required fold of the sought symmetry. Applicable to C and D symmetries, otherwise leave 0...
Definition: ProSHADE.h:162
std::string axisOrder
A string specifying the order of the axis. Must have three characters and any permutation of &#39;x&#39;...
Definition: ProSHADE.h:183
The main header file containing all declarations for the innter workings of the library.
int htmlReportLine
Iterator for current HTML line.
Definition: ProSHADE.h:187
bool energyLevelDist
Should the energy level distances descriptor be computed.
Definition: ProSHADE.h:132
~ProSHADE_data()
Destructor for the ProSHADE_data class.
std::vector< std::array< double, 5 > > getCSymmetries()
This function gives the user programmatical access to the detected C-symmetries.
double xTranslation
The number of angstroms by which the structure should be translated along the X axis.
Definition: ProSHADE.h:171
int htmlReportLineProgress
Iterator for current HTML line in the progress bar.
Definition: ProSHADE.h:188
This header file contains function and globals required for platform-independent file detection...
double bFactorChange
This value will be used to change the B-factors if required by the user.
Definition: ProSHADE.h:89
ProSHADE_comparePairwise(ProSHADE_data *cmpObj1, ProSHADE_data *cmpObj2, double mPower, std::vector< int > ignoreL, unsigned int order, ProSHADE::ProSHADE_settings *settings)
Contructor for the ProSHADE_comparePairwise class.
std::vector< std::array< double, 8 > > getRotFnPeaks()
This function gives the user programmatical access to the symmetry peaks of the symmetry detection pr...
double peakHeightNoIQRs
How many interquartile ranges should be used to distinguish &#39;false&#39; peaks from the true ones...
Definition: ProSHADE.h:123
std::vector< double > getTraceSigmaDistances()
This function returns a vector of trace sigma distances between the first and all other structures...
std::vector< double > getEnergyLevelsDistances()
This function returns a vector of energy level distances between the first and all other structures...
std::vector< std::vector< std::array< double, 6 > > > findDnSymmetryClear(std::vector< std::vector< std::array< double, 6 > > > DnSymm, ProSHADE::ProSHADE_settings *settings, double maxGap=0.2, bool *pf=nullptr)
This function sorts the D symmetries and removed low probability ones.
void printResultsRequestHTML(std::string symmetryType, unsigned int symmetryFold, ProSHADE::ProSHADE_settings *settings)
This function prints the cleared results to the HTML report file.
ProSHADE_symmetry()
Contructor for the ProSHADE_symmetry class.
void getDensityMapFromMAP(std::string fileName, double *shellDistance, double resolution, unsigned int *bandwidth, unsigned int *theta, unsigned int *phi, unsigned int *glIntegOrder, double *extraSpace, bool mapResDefault, bool rotDefaults, ProSHADE::ProSHADE_settings *settings, bool overlayDefaults=false)
Function to read in the MAP file and provide the basic processing.
~ProSHADE_comparePairwise()
Destructor for the ProSHADE_comparePairwise class.
This is the executive class responsible for comparing two or more structures.
~ProSHADE_mapFeatures()
This is the ProSHADE_mapFeatures class destructor responsible for releasing memory.
double yTranslation
The number of angstroms by which the structure should be translated along the Y axis.
Definition: ProSHADE.h:172
double mapFragBoxSize
Should the clear map be fragmented into boxes? If so, put box size here, otherwise leave 0...
Definition: ProSHADE.h:151
ProSHADE_data()
Contructor for the ProSHADE_data class.
double symGapTolerance
For C-symmetries - if there are many, only those with average peak height - parameter * top symmetry ...
Definition: ProSHADE.h:129
This class stores all the settings and is passed to the executive classes instead of multitude of par...
Definition: ProSHADE.h:74
void freeInvMap()
This function frees the SOFT inverse map.
double mPower
This parameter determines the scaling for trace sigma descriptor.
Definition: ProSHADE.h:114
unsigned int manualShells
Should the user require so, the maximum number of radial shells can be set.
Definition: ProSHADE.h:98
ProSHADE_distances(ProSHADE::ProSHADE_settings *settings)
This is the constructor for the ProSHADE_distances executive class the user should use to compute and...
std::vector< std::vector< std::array< double, 6 > > > getDSymmetries()
This function gives the user programmatical access to the detected D-symmetries.
bool useCOM
Should the Centre of Mass (COM) be used to center the structure in the cell?
Definition: ProSHADE.h:105
void printResultsRequest(std::string symmetryType, unsigned int symmetryFold, int verbose)
This function prints the cleared results to the screen.
double maskBlurFactor
The is the amount of blurring to be used to create masks for maps.
Definition: ProSHADE.h:147
ProSHADE_mapFeatures(ProSHADE::ProSHADE_settings *settings)
This is the constructor for the ProSHADE_mapFeatures executive class the user should use to compute a...
std::vector< std::string > structFiles
This vector should contain all the structures that are being dealt with, but this does not yet work! ...
Definition: ProSHADE.h:120
double enLevelsThreshold
All structure pairs with energy level descriptor value less than this will not be subjected to any fu...
Definition: ProSHADE.h:137
Task taskToPerform
This custom type variable determines which task to perfom (i.e. symmetry detection, distances computation or map features extraction).
Definition: ProSHADE.h:141
std::array< double, 4 > getTranslationFunctionMap(ProSHADE_data *obj1, ProSHADE_data *obj2, double *ob2XMov=nullptr, double *ob2YMov=nullptr, double *ob2ZMov=nullptr)
Computes the translation function for the two objects and returns the position of the highest peak...
This file contains the ProSHADE_internal_misc namespace and its miscellaneous functions.
std::array< double, 3 > getEulerAngles(ProSHADE::ProSHADE_settings *settings, double *correlation=nullptr)
This function finds the highest peak in the SO3 inverse transform map and sets it as the optimal over...
std::string mapFragName
The prefix of the files with the cut out boxes.
Definition: ProSHADE.h:152
double extraSpace
What should be the distance added on both sides to the structure, so that the next cell density would...
Definition: ProSHADE.h:109
unsigned int glIntegOrder
This parameter controls the Gauss-Legendre integration order and so the radial resolution.
Definition: ProSHADE.h:82