ProSHADE  0.6.6 (DEC 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->removePhaseFromMapOverlay ( this->alpha,
1540  this->bFactorChange,
1541  settings );
1542 
1543  pattStr1->mapPhaselessToSphere ( settings,
1544  this->theta.at(0),
1545  this->phi.at(0),
1546  shSpacingObj1,
1547  settings->manualShells );
1548 
1549  pattStr1->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
1550  if ( settings->verbose > 1 )
1551  {
1552  std::cout << ">> Structure 1 spherical harmonics computed." << std::endl;
1553  }
1554 
1555  pattStr2->removePhaseFromMapOverlay ( this->alpha,
1556  this->bFactorChange,
1557  settings );
1558 
1559  pattStr2->mapPhaselessToSphere ( settings,
1560  this->theta.at(1),
1561  this->phi.at(1),
1562  shSpacingObj2,
1563  settings->manualShells );
1564 
1565  pattStr2->getSphericalHarmonicsCoeffs ( this->bandwidth.at(1), settings );
1566  if ( settings->verbose > 1 )
1567  {
1568  std::cout << ">> Structure 2 spherical harmonics computed." << std::endl;
1569  }
1570 
1571  if ( settings->htmlReport )
1572  {
1573  std::stringstream hlpSS;
1574  hlpSS << "<font color=\"green\">" << "Spherical harmonics for Patterson maps computed." << "</font>";
1575  rvapi_set_text ( hlpSS.str().c_str(),
1576  "ProgressSection",
1577  settings->htmlReportLineProgress,
1578  1,
1579  1,
1580  1 );
1581  settings->htmlReportLineProgress += 1;
1582  rvapi_flush ( );
1583  }
1584 
1585  //==================================== Get the Compare_Pairwise object to compute E matrices and find the maximum SOFT peak
1586  ProSHADE_comparePairwise* cmpObj = new ProSHADE_comparePairwise ( pattStr1,
1587  pattStr2,
1588  this->mPower,
1589  this->ignoreLs,
1590  std::max ( this->glIntegOrder.at(0),
1591  this->glIntegOrder.at(1) ),
1592  settings );
1593 
1594  //==================================== Get the angles
1595  cmpObj->precomputeTrSigmaDescriptor ( );
1596  if ( settings->verbose > 2 )
1597  {
1598  std::cout << ">>>>> E matrices constructed." << std::endl;
1599  }
1600 
1601  cmpObj->getSO3InverseMap ( settings );
1602  if ( settings->verbose > 2 )
1603  {
1604  std::cout << ">>>>> Inverse SO(3) Fourier transform map obtained." << std::endl;
1605  }
1606 
1607  if ( settings->htmlReport )
1608  {
1609  std::stringstream hlpSS;
1610  hlpSS << "<font color=\"green\">" << "Rotation function map computed." << "</font>";
1611  rvapi_set_text ( hlpSS.str().c_str(),
1612  "ProgressSection",
1613  settings->htmlReportLineProgress,
1614  1,
1615  1,
1616  1 );
1617  settings->htmlReportLineProgress += 1;
1618  rvapi_flush ( );
1619  }
1620 
1621  double pattCorrelation = 0.0;
1622 
1623  std::array<double,3> euAngs = cmpObj->getEulerAngles ( settings, &pattCorrelation );
1624 
1625  if ( settings->verbose > 1 )
1626  {
1627  std::cout << ">> Patterson map based rotation angles obtained ( " << euAngs[0] << ", " << euAngs[1] << " and " << euAngs[2] << " )." << std::endl;
1628  }
1629 
1630  if ( settings->htmlReport )
1631  {
1632  std::stringstream hlpSS;
1633  hlpSS << "<font color=\"green\">" << "Found optimal overlay rotation angles." << "</font>";
1634  rvapi_set_text ( hlpSS.str().c_str(),
1635  "ProgressSection",
1636  settings->htmlReportLineProgress,
1637  1,
1638  1,
1639  1 );
1640  settings->htmlReportLineProgress += 1;
1641  rvapi_flush ( );
1642  }
1643 
1644  if ( settings->htmlReport )
1645  {
1646  //==================================== Create section
1647  rvapi_add_section ( "RotationSection",
1648  "Rotation information",
1649  "body",
1650  settings->htmlReportLine,
1651  0,
1652  1,
1653  1,
1654  false );
1655  settings->htmlReportLine += 1;
1656 
1657  rvapi_flush ( );
1658 
1659  std::stringstream hlpSS;
1660  hlpSS << "<pre>" << "Rotation in Euler Angles: ";
1661  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1662  for ( int iter = 0; iter < hlpIt; iter++ )
1663  {
1664  hlpSS << ".";
1665  }
1666 
1667  std::stringstream hlpSS2;
1668  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[0] * 1000.0 ) / 1000.0;
1669  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1670  hlpSS << " " << hlpSS2.str() << " ";
1671  hlpSS2.str( std::string ( ) );
1672  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[1] * 1000.0 ) / 1000.0;
1673  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1674  hlpSS << hlpSS2.str() << " ";
1675  hlpSS2.str( std::string ( ) );
1676  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( euAngs[2] * 1000.0 ) / 1000.0;
1677  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1678  hlpSS << hlpSS2.str() << "</pre>";
1679 
1680  rvapi_set_text ( hlpSS.str().c_str(),
1681  "RotationSection",
1682  0,
1683  1,
1684  1,
1685  1 );
1686 
1687  hlpSS.str ( std::string ( ) );
1688  hlpSS << "<pre>" << "Rotation in Angle-Axis: ";
1689  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1690  for ( int iter = 0; iter < hlpIt; iter++ )
1691  {
1692  hlpSS << ".";
1693  }
1694 
1695  double X, Y, Z, Ang;
1696  ProSHADE_internal_misc::getAxisAngleFromEuler ( euAngs[0], euAngs[1], euAngs[2], &X, &Y, &Z, &Ang, false );
1697 
1698  hlpSS2.str( std::string ( ) );
1699  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( X * 1000.0 ) / 1000.0;
1700  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1701  hlpSS << " " << hlpSS2.str() << " ";
1702  hlpSS2.str( std::string ( ) );
1703  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Y * 1000.0 ) / 1000.0;
1704  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1705  hlpSS << hlpSS2.str() << " ";
1706  hlpSS2.str( std::string ( ) );
1707  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Z * 1000.0 ) / 1000.0;
1708  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1709  hlpSS << hlpSS2.str() << " ";
1710  hlpSS2.str( std::string ( ) );
1711  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( Ang * 1000.0 ) / 1000.0;
1712  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1713  hlpSS << hlpSS2.str() << "</pre>";
1714 
1715  rvapi_set_text ( hlpSS.str().c_str(),
1716  "RotationSection",
1717  1,
1718  1,
1719  1,
1720  1 );
1721 
1722  std::array<double,5> arrHlp;
1723  arrHlp[0] = Ang;
1724  arrHlp[1] = X;
1725  arrHlp[2] = Y;
1726  arrHlp[3] = Z;
1727  arrHlp[4] = 0.0;
1728  std::vector< std::vector<double> > rMat = ProSHADE_internal_misc::getMatrixFromAxisAngle ( arrHlp );
1729 
1730  hlpSS.str ( std::string ( ) );
1731  hlpSS << "<pre>" << "Rotation as Rotation Matrix: ";
1732  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1733  for ( int iter = 0; iter < hlpIt; iter++ )
1734  {
1735  hlpSS << ".";
1736  }
1737 
1738  hlpSS2.str( std::string ( ) );
1739  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(0) * 1000.0 ) / 1000.0;
1740  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1741  hlpSS << " " << hlpSS2.str() << " ";
1742  hlpSS2.str( std::string ( ) );
1743  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(1) * 1000.0 ) / 1000.0;
1744  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1745  hlpSS << hlpSS2.str() << " ";
1746  hlpSS2.str( std::string ( ) );
1747  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(0).at(2) * 1000.0 ) / 1000.0;
1748  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1749  hlpSS << hlpSS2.str() << "</pre>";
1750 
1751  rvapi_set_text ( hlpSS.str().c_str(),
1752  "RotationSection",
1753  2,
1754  1,
1755  1,
1756  1 );
1757 
1758  hlpSS.str ( std::string ( ) );
1759  hlpSS << "<pre>" << " ... ";
1760  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1761  for ( int iter = 0; iter < hlpIt; iter++ )
1762  {
1763  hlpSS << " ";
1764  }
1765 
1766  hlpSS2.str( std::string ( ) );
1767  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(0) * 1000.0 ) / 1000.0;
1768  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1769  hlpSS << " " << hlpSS2.str() << " ";
1770  hlpSS2.str( std::string ( ) );
1771  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(1) * 1000.0 ) / 1000.0;
1772  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1773  hlpSS << hlpSS2.str() << " ";
1774  hlpSS2.str( std::string ( ) );
1775  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(1).at(2) * 1000.0 ) / 1000.0;
1776  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1777  hlpSS << hlpSS2.str() << "</pre>";
1778 
1779  rvapi_set_text ( hlpSS.str().c_str(),
1780  "RotationSection",
1781  3,
1782  1,
1783  1,
1784  1 );
1785 
1786  hlpSS.str ( std::string ( ) );
1787  hlpSS << "<pre>" << " ... ";
1788  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
1789  for ( int iter = 0; iter < hlpIt; iter++ )
1790  {
1791  hlpSS << " ";
1792  }
1793 
1794  hlpSS2.str( std::string ( ) );
1795  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(0) * 1000.0 ) / 1000.0;
1796  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1797  hlpSS << " " << hlpSS2.str() << " ";
1798  hlpSS2.str( std::string ( ) );
1799  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(1) * 1000.0 ) / 1000.0;
1800  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1801  hlpSS << hlpSS2.str() << " ";
1802  hlpSS2.str( std::string ( ) );
1803  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( rMat.at(2).at(2) * 1000.0 ) / 1000.0;
1804  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
1805  hlpSS << hlpSS2.str() << "</pre>";
1806 
1807  rvapi_set_text ( hlpSS.str().c_str(),
1808  "RotationSection",
1809  4,
1810  1,
1811  1,
1812  1 );
1813 
1814  rvapi_flush ( );
1815  }
1816 
1817  //==================================== Free memory
1818  delete cmpObj;
1819  delete pattStr1;
1820  delete pattStr2;
1821 
1822  //==================================== Prepare vatiables
1823  std::array<double,4> translationVec;
1824  double xMapMov = 0.0;
1825  double yMapMov = 0.0;
1826  double zMapMov = 0.0;
1827  double xMapTotMov = 0.0;
1828  double yMapTotMov = 0.0;
1829  double zMapTotMov = 0.0;
1830 
1831  while ( true )
1832  {
1833  //================================ Load structure 2 with phases
1834  pattStr2 = new ProSHADE_data ();
1835  fileType = checkFileType ( structFiles.at(1) );
1836  if ( fileType == 2 )
1837  {
1838  pattStr2->getDensityMapFromMAP ( this->structFiles.at(1),
1839  &shSpacingObj2,
1840  this->mapResolution,
1841  &this->bandwidth.at(1),
1842  &this->theta.at(1),
1843  &this->phi.at(1),
1844  &this->glIntegOrder.at(1),
1845  &this->extraSpace,
1846  settings->mapResDefault,
1847  settings->rotChangeDefault,
1848  settings,
1849  settings->overlayDefaults );
1850  }
1851  else if ( fileType == 1 )
1852  {
1853  pattStr2->getDensityMapFromPDB ( this->structFiles.at(1),
1854  &shSpacingObj2,
1855  this->mapResolution,
1856  &this->bandwidth.at(1),
1857  &this->theta.at(1),
1858  &this->phi.at(1),
1859  &this->glIntegOrder.at(1),
1860  &this->extraSpace,
1861  settings->mapResDefault,
1862  settings,
1863  this->bFactorValue,
1864  this->firstLineCOM,
1865  settings->overlayDefaults );
1866  }
1867  else
1868  {
1869  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;
1870 
1871  if ( settings->htmlReport )
1872  {
1873  std::stringstream hlpSS;
1874  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(1) << " ." << "</font>";
1875  rvapi_set_text ( hlpSS.str().c_str(),
1876  "ProgressSection",
1877  settings->htmlReportLineProgress,
1878  1,
1879  1,
1880  1 );
1881  settings->htmlReportLineProgress += 1;
1882  rvapi_flush ( );
1883  }
1884 
1885  exit ( -1 );
1886  }
1887 
1888 // std::array<double,4> str2CandD = pattStr2->getCOMandDist ( settings );
1889  pattStr2->keepPhaseInMap ( this->alpha,
1890  this->bFactorChange,
1891  &this->bandwidth.at(1),
1892  &this->theta.at(1),
1893  &this->phi.at(1),
1894  &this->glIntegOrder.at(1),
1895  settings,
1896  this->useCOM,
1897  settings->noIQRsFromMap,
1898  settings->verbose,
1899  settings->clearMapData,
1900  settings->rotChangeDefault,
1901  settings->overlayDefaults,
1902  settings->maskBlurFactor,
1903  settings->maskBlurFactorGiven );
1904 
1905  pattStr2->mapPhaselessToSphere ( settings,
1906  this->theta.at(1),
1907  this->phi.at(1),
1908  shSpacingObj2,
1909  settings->manualShells,
1910  true,
1911  true );
1912 
1913  pattStr2->getSphericalHarmonicsCoeffs ( this->bandwidth.at(1), settings );
1914  if ( settings->verbose > 1 )
1915  {
1916  std::cout << ">> Structure 2 spherical harmonics computed with phase." << std::endl;
1917  }
1918 
1919  //================================ Read in structure 1, this time with phases
1920  fileType = checkFileType ( structFiles.at(0) );
1921  pattStr1 = new ProSHADE_data ();
1922 
1923  if ( fileType == 2 )
1924  {
1925  pattStr1->getDensityMapFromMAP ( this->structFiles.at(0),
1926  &shSpacingObj1,
1927  this->mapResolution,
1928  &this->bandwidth.at(0),
1929  &this->theta.at(0),
1930  &this->phi.at(0),
1931  &this->glIntegOrder.at(0),
1932  &this->extraSpace,
1933  settings->mapResDefault,
1934  settings->rotChangeDefault,
1935  settings,
1936  settings->overlayDefaults );
1937  }
1938  else if ( fileType == 1 )
1939  {
1940  pattStr1->getDensityMapFromPDB ( this->structFiles.at(0),
1941  &shSpacingObj1,
1942  this->mapResolution,
1943  &this->bandwidth.at(0),
1944  &this->theta.at(0),
1945  &this->phi.at(0),
1946  &this->glIntegOrder.at(0),
1947  &this->extraSpace,
1948  settings->mapResDefault,
1949  settings,
1950  this->bFactorValue,
1951  this->firstLineCOM,
1952  settings->overlayDefaults );
1953  }
1954  else
1955  {
1956  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;
1957 
1958  if ( settings->htmlReport )
1959  {
1960  std::stringstream hlpSS;
1961  hlpSS << "<font color=\"red\">" << "Cannot read file " << settings->structFiles.at(0) << " ." << "</font>";
1962  rvapi_set_text ( hlpSS.str().c_str(),
1963  "ProgressSection",
1964  settings->htmlReportLineProgress,
1965  1,
1966  1,
1967  1 );
1968  settings->htmlReportLineProgress += 1;
1969  rvapi_flush ( );
1970  }
1971 
1972  exit ( -1 );
1973  }
1974 
1975  pattStr1->keepPhaseInMap ( this->alpha,
1976  this->bFactorChange,
1977  &this->bandwidth.at(0),
1978  &this->theta.at(0),
1979  &this->phi.at(0),
1980  &this->glIntegOrder.at(0),
1981  settings,
1982  this->useCOM,
1983  settings->noIQRsFromMap,
1984  settings->verbose,
1985  settings->clearMapData,
1986  settings->rotChangeDefault,
1987  settings->overlayDefaults,
1988  settings->maskBlurFactor,
1989  settings->maskBlurFactorGiven );
1990 
1991  pattStr1->mapPhaselessToSphere ( settings,
1992  this->theta.at(0),
1993  this->phi.at(0),
1994  shSpacingObj1,
1995  settings->manualShells,
1996  true,
1997  true );
1998 
1999  pattStr1->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2000  if ( settings->verbose > 1 )
2001  {
2002  std::cout << ">> Structure 1 spherical harmonics computed with phase." << std::endl;
2003  }
2004 
2005  if ( settings->htmlReport )
2006  {
2007  std::stringstream hlpSS;
2008  hlpSS << "<font color=\"green\">" << "Spherical harmonics computed for translation computation (with phases)." << "</font>";
2009  rvapi_set_text ( hlpSS.str().c_str(),
2010  "ProgressSection",
2011  settings->htmlReportLineProgress,
2012  1,
2013  1,
2014  1 );
2015  settings->htmlReportLineProgress += 1;
2016  rvapi_flush ( );
2017  }
2018 
2019  if ( settings->htmlReport )
2020  {
2021  std::stringstream hlpSS;
2022  hlpSS << "<pre>" << "Rotation about coordinate location (A): ";
2023  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2024  for ( int iter = 0; iter < hlpIt; iter++ )
2025  {
2026  hlpSS << ".";
2027  }
2028 
2029  std::stringstream hlpSS2;
2030  double pos = ( ( pattStr2->_xFrom * pattStr2->_xSamplingRate ) + pattStr2->_xRange ) / 2.0;
2031  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2032  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2033  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2034  hlpSS << " " << hlpSS2.str() << " ";
2035  hlpSS2.str( std::string ( ) );
2036  pos = ( ( pattStr2->_yFrom * pattStr2->_ySamplingRate ) + pattStr2->_yRange ) / 2.0;
2037  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2038  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2039  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2040  hlpSS << hlpSS2.str() << " ";
2041  hlpSS2.str( std::string ( ) );
2042  pos = ( ( pattStr2->_zFrom * pattStr2->_zSamplingRate ) + pattStr2->_zRange ) / 2.0;
2043  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2044  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2045  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2046  hlpSS << hlpSS2.str() << "</pre>";
2047 
2048  rvapi_set_text ( hlpSS.str().c_str(),
2049  "RotationSection",
2050  5,
2051  1,
2052  1,
2053  1 );
2054  rvapi_flush ( );
2055  }
2056 
2057  //================================ Find rotation angles
2058  cmpObj = new ProSHADE_comparePairwise ( pattStr2,
2059  pattStr2,
2060  this->mPower,
2061  this->ignoreLs,
2062  std::max ( this->glIntegOrder.at(0),
2063  this->glIntegOrder.at(1) ),
2064  settings );
2065 
2066  //================================ Find 'opposite' Euler angles and set them
2067  // Get mat from Euler
2068  double mat22 = cos ( euAngs[1] );
2069  double mat02 = -sin ( euAngs[1] ) * cos ( euAngs[2] );
2070  double mat12 = sin ( euAngs[1] ) * sin ( euAngs[2] );
2071  double mat20 = cos ( euAngs[0] ) * sin ( euAngs[1] );
2072  double mat21 = sin ( euAngs[0] ) * sin ( euAngs[1] );
2073 
2074  // Transpose
2075  double rMat02 = mat20;
2076  double rMat20 = mat02;
2077  double rMat21 = mat12;
2078  double rMat12 = mat21;
2079 
2080  // Get Euler from map
2081  euAngs[0] = atan2 ( rMat21, rMat20 );
2082  euAngs[1] = acos ( mat22 );
2083  euAngs[2] = atan2 ( rMat12, -rMat02 );
2084 
2085  if ( euAngs[0] < 0.0 ) { euAngs[0]= 2.0 * M_PI + euAngs[0]; }
2086  if ( euAngs[1] < 0.0 ) { euAngs[1]= M_PI + euAngs[1]; }
2087  if ( euAngs[2] < 0.0 ) { euAngs[2]= 2.0 * M_PI + euAngs[2]; }
2088 
2089  cmpObj->setEulerAngles ( euAngs[0], euAngs[1], euAngs[2] );
2090 
2091  //================================ Rotate by the Euler
2092  cmpObj->rotateStructure ( pattStr2,
2093  settings,
2094  settings->clearMapFile,
2095  settings->verbose,
2096  settings->axisOrder,
2097  true );
2098 
2099  //================================ Find optimal translation
2100  ProSHADE_data str1Copy = ProSHADE_data ( pattStr1 );
2101  translationVec = cmpObj->getTranslationFunctionMap ( &str1Copy, pattStr2, &xMapMov, &yMapMov, &zMapMov );
2102 
2103  if ( settings->htmlReport )
2104  {
2105  std::stringstream hlpSS;
2106  hlpSS << "<font color=\"green\">" << "Translation computed." << "</font>";
2107  rvapi_set_text ( hlpSS.str().c_str(),
2108  "ProgressSection",
2109  settings->htmlReportLineProgress,
2110  1,
2111  1,
2112  1 );
2113  settings->htmlReportLineProgress += 1;
2114  rvapi_flush ( );
2115  }
2116 
2117  if ( settings->htmlReport )
2118  {
2119  //==================================== Create section
2120  rvapi_add_section ( "TranslationSection",
2121  "Translation information",
2122  "body",
2123  settings->htmlReportLine,
2124  0,
2125  1,
2126  1,
2127  false );
2128  settings->htmlReportLine += 1;
2129 
2130  rvapi_flush ( );
2131 
2132  std::stringstream hlpSS;
2133  hlpSS << "<pre>" << "Translation from lowest indices (A): ";
2134  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2135  for ( int iter = 0; iter < hlpIt; iter++ )
2136  {
2137  hlpSS << ".";
2138  }
2139 
2140  std::stringstream hlpSS2;
2141  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[0] * 1000.0 ) / 1000.0;
2142  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2143  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2144  hlpSS << " " << hlpSS2.str() << " ";
2145  hlpSS2.str( std::string ( ) );
2146  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[1] * 1000.0 ) / 1000.0;
2147  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2148  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2149  hlpSS << hlpSS2.str() << " ";
2150  hlpSS2.str( std::string ( ) );
2151  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( -translationVec[2] * 1000.0 ) / 1000.0;
2152  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2153  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2154  hlpSS << hlpSS2.str() << "</pre>";
2155 
2156  rvapi_set_text ( hlpSS.str().c_str(),
2157  "TranslationSection",
2158  0,
2159  1,
2160  1,
2161  1 );
2162 
2163  hlpSS.str( std::string () );
2164  hlpSS << "<pre>" << "Translation from lowest indices (index): ";
2165  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2166  for ( int iter = 0; iter < hlpIt; iter++ )
2167  {
2168  hlpSS << ".";
2169  }
2170 
2171  hlpSS2.str( std::string ( ) );
2172  int pos = static_cast<int> ( ( -translationVec[0] / pattStr2->_xSamplingRate ) );
2173  hlpSS2 << std::showpos << pos;
2174  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2175  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2176  hlpSS << " " << hlpSS2.str() << " ";
2177  hlpSS2.str( std::string ( ) );
2178  pos = static_cast<int> ( ( -translationVec[1] / pattStr2->_ySamplingRate ) );
2179  hlpSS2 << std::showpos << pos;
2180  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2181  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2182  hlpSS << hlpSS2.str() << " ";
2183  hlpSS2.str( std::string ( ) );
2184  pos = static_cast<int> ( ( -translationVec[2] / pattStr2->_zSamplingRate ) );
2185  hlpSS2 << std::showpos << pos;
2186  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2187  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2188  hlpSS << hlpSS2.str() << "</pre>";
2189 
2190  rvapi_set_text ( hlpSS.str().c_str(),
2191  "TranslationSection",
2192  1,
2193  1,
2194  1,
2195  1 );
2196 
2197  hlpSS.str ( std::string ( ) );
2198  hlpSS << "<pre>" << "Shift for visualisation (A): ";
2199  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2200  for ( int iter = 0; iter < hlpIt; iter++ )
2201  {
2202  hlpSS << ".";
2203  }
2204 
2205  hlpSS2.str ( std::string ( ) );
2206  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (xMapTotMov * pattStr2->_xSamplingRate) * 1000.0 ) / 1000.0;
2207  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2208  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2209  hlpSS << " " << hlpSS2.str() << " ";
2210  hlpSS2.str( std::string ( ) );
2211  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (yMapTotMov * pattStr2->_ySamplingRate) * 1000.0 ) / 1000.0;
2212  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2213  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2214  hlpSS << hlpSS2.str() << " ";
2215  hlpSS2.str( std::string ( ) );
2216  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( (zMapTotMov * pattStr2->_zSamplingRate) * 1000.0 ) / 1000.0;
2217  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2218  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2219  hlpSS << hlpSS2.str() << "</pre>";
2220 
2221  rvapi_set_text ( hlpSS.str().c_str(),
2222  "TranslationSection",
2223  2,
2224  1,
2225  1,
2226  1 );
2227 
2228  hlpSS.str( std::string () );
2229  hlpSS << "<pre>" << "Shift for visualisation (index): ";
2230  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2231  for ( int iter = 0; iter < hlpIt; iter++ )
2232  {
2233  hlpSS << ".";
2234  }
2235 
2236  hlpSS2.str( std::string ( ) );
2237  pos = static_cast<int> ( xMapTotMov );
2238  hlpSS2 << std::showpos << pos;
2239  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2240  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2241  hlpSS << " " << hlpSS2.str() << " ";
2242  hlpSS2.str( std::string ( ) );
2243  pos = static_cast<int> ( yMapTotMov );
2244  hlpSS2 << std::showpos << pos;
2245  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2246  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2247  hlpSS << hlpSS2.str() << " ";
2248  hlpSS2.str( std::string ( ) );
2249  pos = static_cast<int> ( zMapTotMov );
2250  hlpSS2 << std::showpos << pos;
2251  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2252  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2253  hlpSS << hlpSS2.str() << "</pre>";
2254 
2255  rvapi_set_text ( hlpSS.str().c_str(),
2256  "TranslationSection",
2257  3,
2258  1,
2259  1,
2260  1 );
2261 
2262 
2263  rvapi_flush ( );
2264  }
2265 
2266  if ( settings->verbose > 2 )
2267  {
2268  std::cout << ">>>>> Translation vector obtained from translation function ( " << translationVec[0] << ", " << translationVec[1] << " and " << translationVec[2] << " )." << std::endl;
2269  }
2270 
2271  //================================ Done
2272  break;
2273  }
2274 
2275  //==================================== Translate map
2276  pattStr2->translateMap ( -translationVec[0],
2277  -translationVec[1],
2278  -translationVec[2] );
2279 
2280  if ( settings->verbose > 0 )
2281  {
2282  std::cout << "Resulting structure translated." << std::endl;
2283  }
2284 
2285  //==================================== Write the matched map and pdb outputs
2286  if ( !pattStr2->_fromPDB )
2287  {
2288  if ( !wasMapNameGiven )
2289  {
2290  std::stringstream strStr;
2291  strStr << settings->clearMapFile << ".map";
2292  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2293  }
2294  else
2295  {
2296  if ( ( settings->clearMapFile.find ( ".map" ) != std::string::npos ) || ( settings->clearMapFile.find ( ".mrc" ) != std::string::npos ) )
2297  {
2298  pattStr2->writeMap ( settings->clearMapFile, pattStr2->_densityMapCor );
2299  }
2300  else
2301  {
2302  if ( settings->clearMapFile.find ( ".pdb" ) != std::string::npos )
2303  {
2304  std::stringstream strStr;
2305  strStr << settings->clearMapFile << "_errOut.map";
2306  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;
2307  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2308  }
2309  else
2310  {
2311  std::stringstream strStr;
2312  strStr << settings->clearMapFile << ".map";
2313  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2314  }
2315  }
2316  }
2317  }
2318  else
2319  {
2320  if ( !wasMapNameGiven )
2321  {
2322  std::stringstream strStr;
2323  strStr << settings->clearMapFile << ".map";
2324  std::cout << "!!! here" << std::endl;
2325  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2326  std::cout << "!!! here 2" << std::endl;
2327  strStr.str ( std::string ( ) );
2328  strStr.clear();
2329  strStr << settings->clearMapFile << ".pdb";
2330  std::cout << "!!! here 3" << std::endl;
2331  pattStr2->writePDB ( this->structFiles.at(1),
2332  strStr.str(),
2333  euAngs[0],
2334  euAngs[1],
2335  euAngs[2],
2336  translationVec[0] + xMapMov,
2337  translationVec[1] + yMapMov,
2338  translationVec[2] + zMapMov );
2339  std::cout << "!!! still here" << std::endl;
2340  }
2341  else
2342  {
2343  if ( ( settings->clearMapFile.find ( ".map" ) != std::string::npos ) || ( settings->clearMapFile.find ( ".mrc" ) != std::string::npos ) )
2344  {
2345  pattStr2->writeMap ( settings->clearMapFile, pattStr2->_densityMapCor );
2346  }
2347  else
2348  {
2349  if ( settings->clearMapFile.find ( ".pdb" ) != std::string::npos )
2350  {
2351  pattStr2->writePDB ( this->structFiles.at(1),
2352  settings->clearMapFile,
2353  euAngs[0],
2354  euAngs[1],
2355  euAngs[2],
2356  translationVec[0] + xMapMov,
2357  translationVec[1] + yMapMov,
2358  translationVec[2] + zMapMov );
2359  }
2360  else
2361  {
2362  std::stringstream strStr;
2363  strStr << settings->clearMapFile << ".map";
2364  pattStr2->writeMap ( strStr.str(), pattStr2->_densityMapCor );
2365  strStr.str ( std::string ( ) );
2366  strStr.clear();
2367  strStr << settings->clearMapFile << ".pdb";
2368  pattStr2->writePDB ( this->structFiles.at(1),
2369  strStr.str(),
2370  euAngs[0],
2371  euAngs[1],
2372  euAngs[2],
2373  translationVec[0] + xMapMov,
2374  translationVec[1] + yMapMov,
2375  translationVec[2] + zMapMov );
2376  }
2377  }
2378  }
2379  }
2380 
2381  if ( settings->htmlReport )
2382  {
2383  std::stringstream hlpSS;
2384  hlpSS << "<font color=\"green\">" << "Overlay structure saved to " << settings->clearMapFile << " ." << "</font>";
2385  rvapi_set_text ( hlpSS.str().c_str(),
2386  "ProgressSection",
2387  settings->htmlReportLineProgress,
2388  1,
2389  1,
2390  1 );
2391  settings->htmlReportLineProgress += 1;
2392  rvapi_flush ( );
2393  }
2394 
2395  //==================================== Clear memory
2396  delete cmpObj;
2397  delete pattStr2;
2398  delete pattStr1;
2399 
2400  //==================================== End report
2401  if ( settings->verbose > 0 )
2402  {
2403  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2404  std::cout << "| COMPLETED |" << std::endl;
2405  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2406  }
2407 
2408  if ( settings->htmlReport )
2409  {
2410  std::stringstream hlpSS;
2411  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
2412  rvapi_set_text ( hlpSS.str().c_str(),
2413  "ProgressSection",
2414  settings->htmlReportLineProgress,
2415  1,
2416  1,
2417  1 );
2418  settings->htmlReportLineProgress += 1;
2419  rvapi_flush ( );
2420  }
2421 
2422  if ( settings->verbose > 0 )
2423  {
2424  std::cout << "Rotated structure written to file: " << settings->clearMapFile << " as required." << std::endl << std::endl;
2425  }
2426 
2427  if ( settings->htmlReport )
2428  {
2429  //==================================== Create section
2430  rvapi_add_section ( "ResultsSection",
2431  "Results",
2432  "body",
2433  settings->htmlReportLine,
2434  0,
2435  1,
2436  1,
2437  true );
2438  settings->htmlReportLine += 1;
2439 
2440  std::stringstream hlpSS;
2441  hlpSS << "<pre><b>" << "Patterson maps optimal rotation (Euler angles): ";
2442  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2443  for ( int iter = 0; iter < hlpIt; iter++ )
2444  {
2445  hlpSS << ".";
2446  }
2447 
2448  std::stringstream hlpSS2;
2449  double pos = euAngs[0];
2450  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2451  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2452  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2453  hlpSS << " " << hlpSS2.str() << " ";
2454 
2455  hlpSS2.str( std::string ( ) );
2456  pos = euAngs[1];
2457  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2458  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2459  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2460  hlpSS << hlpSS2.str() << " ";
2461 
2462  hlpSS2.str( std::string ( ) );
2463  pos = euAngs[2];
2464  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2465  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2466  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2467  hlpSS << hlpSS2.str() << "</b></pre>";
2468 
2469  rvapi_set_text ( hlpSS.str().c_str(),
2470  "ResultsSection",
2471  0,
2472  0,
2473  1,
2474  1 );
2475 
2476  hlpSS.str ( std::string ( ) );
2477  hlpSS << "<pre><b>" << "Phased maps optimal translation (A): ";
2478  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2479  for ( int iter = 0; iter < hlpIt; iter++ )
2480  {
2481  hlpSS << ".";
2482  }
2483 
2484  hlpSS2.str( std::string ( ) );
2485  pos = translationVec[0];
2486  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2487  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2488  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2489  hlpSS << " " << hlpSS2.str() << " ";
2490 
2491  hlpSS2.str( std::string ( ) );
2492  pos = translationVec[1];
2493  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2494  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2495  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2496  hlpSS << hlpSS2.str() << " ";
2497 
2498  hlpSS2.str( std::string ( ) );
2499  pos = translationVec[2];
2500  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2501  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2502  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2503  hlpSS << hlpSS2.str() << "</b></pre>";
2504 
2505  rvapi_set_text ( hlpSS.str().c_str(),
2506  "ResultsSection",
2507  1,
2508  0,
2509  1,
2510  1 );
2511 
2512  hlpSS.str ( std::string ( ) );
2513  hlpSS << "<pre><b>" << "Correlation between rotated Patterson maps: ";
2514  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2515  for ( int iter = 0; iter < hlpIt; iter++ )
2516  {
2517  hlpSS << ".";
2518  }
2519 
2520  hlpSS2.str( std::string ( ) );
2521  pos = pattCorrelation;
2522  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2523  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2524  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2525  hlpSS << " " << hlpSS2.str() << "</b></pre>";
2526 
2527  rvapi_set_text ( hlpSS.str().c_str(),
2528  "ResultsSection",
2529  2,
2530  0,
2531  1,
2532  1 );
2533 
2534  hlpSS.str ( std::string ( ) );
2535  hlpSS << "<pre><b>" << "Correlation between translated maps with phases: ";
2536  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
2537  for ( int iter = 0; iter < hlpIt; iter++ )
2538  {
2539  hlpSS << ".";
2540  }
2541 
2542  hlpSS2.str( std::string ( ) );
2543  pos = translationVec[3];
2544  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( pos * 1000.0 ) / 1000.0;
2545  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
2546  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
2547  hlpSS << " " << hlpSS2.str() << "</b></pre>";
2548 
2549  rvapi_set_text ( hlpSS.str().c_str(),
2550  "ResultsSection",
2551  3,
2552  0,
2553  1,
2554  1 );
2555 
2556  rvapi_flush ( );
2557  }
2558 
2559  //==================================== Done
2560  return ;
2561  }
2562 
2563  //======================================== In the case of simple rotation, do it instead
2564  if ( settings->taskToPerform == ProSHADE::RotateMap )
2565  {
2566  //==================================== Sanity checks
2567  if ( settings->structFiles.size() != 1 )
2568  {
2569  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;
2570  exit ( -1 );
2571  }
2572 
2573  if ( checkFileType ( settings->structFiles.at(0) ) != 2 )
2574  {
2575  std::cerr << "!!! ProSHADE ERROR !!! The input file is corrupted or not a ccp4 MAP file formatted. Terminating..." << std::endl;
2576  exit ( -1 );
2577  }
2578 
2579  if ( settings->clearMapFile == "" )
2580  {
2581  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;
2582  settings->clearMapFile = "rotMap.map";
2583  }
2584 
2585  if ( ( settings->rotAngle == 0.0 ) && ( settings->rotXAxis == 0.0 ) && ( settings->rotYAxis == 0.0 ) && ( settings->rotZAxis == 0.0 ) )
2586  {
2587  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;
2588  }
2589 
2590  if ( settings->verbose > 2 )
2591  {
2592  std::cout << ">>>>> Sanity checks passed." << std::endl;
2593  }
2594 
2595  //==================================== Load the structure
2596  ProSHADE_data* rotStr = new ProSHADE_data ();
2597  rotStr->getDensityMapFromMAP ( this->structFiles.at(0),
2598  &this->shellSpacing,
2599  this->mapResolution,
2600  &this->bandwidth.at(0),
2601  &this->theta.at(0),
2602  &this->phi.at(0),
2603  &this->glIntegOrder.at(0),
2604  &this->extraSpace,
2605  settings->mapResDefault,
2606  settings->rotChangeDefault,
2607  settings,
2608  settings->overlayDefaults );
2609  if ( settings->verbose > 0 )
2610  {
2611  std::cout << "Structure loaded." << std::endl;
2612  }
2613 
2614  rotStr->translateMap ( settings->xTranslation,
2615  settings->yTranslation,
2616  settings->zTranslation );
2617 
2618  //==================================== Decompose structure to SH
2619  rotStr->keepPhaseInMap ( this->alpha,
2620  this->bFactorChange,
2621  &this->bandwidth.at(0),
2622  &this->theta.at(0),
2623  &this->phi.at(0),
2624  &this->glIntegOrder.at(0),
2625  settings,
2626  this->useCOM,
2627  settings->noIQRsFromMap,
2628  settings->verbose,
2629  settings->clearMapData,
2630  settings->rotChangeDefault,
2631  settings->overlayDefaults,
2632  settings->maskBlurFactor,
2633  settings->maskBlurFactorGiven );
2634 
2635  ProSHADE_comparePairwise* cmpObj = nullptr;
2636  if ( settings->rotAngle != 0.0 )
2637  {
2638  rotStr->mapPhaselessToSphere ( settings,
2639  this->theta.at(0),
2640  this->phi.at(0),
2641  this->shellSpacing,
2642  settings->manualShells,
2643  true,
2644  settings->rotChangeDefault );
2645  rotStr->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2646  if ( settings->verbose > 1 )
2647  {
2648  std::cout << ">> Structure spherical harmonics computed." << std::endl;
2649  }
2650 
2651  //================================ Get comparison object
2652  cmpObj = new ProSHADE_comparePairwise ( rotStr,
2653  rotStr,
2654  this->mPower,
2655  this->ignoreLs,
2656  this->glIntegOrder.at(0),
2657  settings );
2658 
2659  //================================ Convert Axis-angle to Euler
2660  double euAlpha = 0.0;
2661  double euBeta = 0.0;
2662  double euGamma = 0.0;
2663 
2664  ProSHADE_internal_misc::getEulerFromAxisAngle ( &euAlpha,
2665  &euBeta,
2666  &euGamma,
2667  settings->rotXAxis,
2668  settings->rotYAxis,
2669  settings->rotZAxis,
2670  settings->rotAngle );
2671 
2672  cmpObj->setEulerAngles ( euAlpha, euBeta, euGamma );
2673 
2674  if ( settings->verbose > 2 )
2675  {
2676  printf ( ">>>>> Preparation for rotation complete. Euler angles are %+.3f ; %+.3f ; %+.3f\n", euAlpha, euBeta, euGamma );
2677  }
2678  }
2679  else
2680  {
2681  //================================ Get comparison object
2682  cmpObj = new ProSHADE_comparePairwise ( rotStr,
2683  rotStr,
2684  this->mPower,
2685  this->ignoreLs,
2686  this->glIntegOrder.at(0),
2687  settings );
2688 
2689  cmpObj->setEulerAngles ( 0.0, 0.0, 0.0 );
2690 
2691  if ( settings->verbose > 2 )
2692  {
2693  printf ( ">>>>> Preparation for rotation complete. Euler angles are 0.000 ; 0.000 ; 0.000\n" );
2694  }
2695  }
2696 
2697  //==================================== Rotate by the Euler
2698  cmpObj->rotateStructure ( rotStr,
2699  settings,
2700  settings->clearMapFile,
2701  settings->verbose,
2702  settings->axisOrder,
2703  false );
2704 
2705  //==================================== Clear memory
2706  delete cmpObj;
2707  delete rotStr;
2708 
2709  if ( settings->verbose > 0 )
2710  {
2711  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2712  std::cout << "| COMPLETED |" << std::endl;
2713  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2714  }
2715 
2716  if ( settings->verbose > 0 )
2717  {
2718  std::cout << "Rotated structure written to file: " << settings->clearMapFile << " as required." << std::endl << std::endl;
2719  }
2720 
2721  //==================================== Done
2722  return ;
2723  }
2724 
2725  //======================================== Report progress
2726  if ( settings->verbose > 0 )
2727  {
2728  std::cout << "-----------------------------------------------------------" << std::endl;
2729  std::cout << "| MODE: Symmetry |" << std::endl;
2730  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2731  }
2732 
2733  if ( settings->htmlReport )
2734  {
2735  //================================ Report title
2736  rvapi_set_text ( "<h1>ProSHADE Results: Symmetry</h1>",
2737  "body",
2738  settings->htmlReportLine,
2739  0,
2740  1,
2741  1 );
2742  settings->htmlReportLine += 1;
2743 
2744  //==================================== Create section
2745  rvapi_add_section ( "ProgressSection",
2746  "Progress",
2747  "body",
2748  settings->htmlReportLine,
2749  0,
2750  1,
2751  1,
2752  true );
2753  settings->htmlReportLine += 1;
2754 
2755  std::stringstream hlpSS;
2756  hlpSS << "<font color=\"green\">" << "Starting computation of symmetry for the input structure." << "</font>";
2757  rvapi_set_text ( hlpSS.str().c_str(),
2758  "ProgressSection",
2759  settings->htmlReportLineProgress,
2760  1,
2761  1,
2762  1 );
2763  settings->htmlReportLineProgress += 1;
2764 
2765  rvapi_flush ( );
2766  }
2767 
2768  //======================================== Sanity checks
2769  if ( settings->structFiles.size() != 1 )
2770  {
2771  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;
2772  if ( settings->htmlReport )
2773  {
2774  std::stringstream hlpSS;
2775  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>";
2776  rvapi_set_text ( hlpSS.str().c_str(),
2777  "ProgressSection",
2778  settings->htmlReportLineProgress,
2779  1,
2780  1,
2781  1 );
2782  settings->htmlReportLineProgress += 1;
2783  rvapi_flush ( );
2784  }
2785  exit ( -1 );
2786  }
2787 
2788  //======================================== Create the structure object
2789  unsigned int fileType = checkFileType ( structFiles.at(0) );
2790  ProSHADE_data* symStr = new ProSHADE_data ();
2791  if ( fileType == 2 )
2792  {
2793  symStr->getDensityMapFromMAP ( this->structFiles.at(0),
2794  &this->shellSpacing,
2795  this->mapResolution,
2796  &this->bandwidth.at(0),
2797  &this->theta.at(0),
2798  &this->phi.at(0),
2799  &this->glIntegOrder.at(0),
2800  &this->extraSpace,
2801  settings->mapResDefault,
2802  settings->rotChangeDefault,
2803  settings,
2804  settings->overlayDefaults );
2805  }
2806  else if ( fileType == 1 )
2807  {
2808  symStr->getDensityMapFromPDB ( this->structFiles.at(0),
2809  &this->shellSpacing,
2810  this->mapResolution,
2811  &this->bandwidth.at(0),
2812  &this->theta.at(0),
2813  &this->phi.at(0),
2814  &this->glIntegOrder.at(0),
2815  &this->extraSpace,
2816  settings->mapResDefault,
2817  settings,
2818  this->bFactorValue,
2819  this->firstLineCOM );
2820  }
2821  else
2822  {
2823  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;
2824  if ( settings->htmlReport )
2825  {
2826  std::stringstream hlpSS;
2827  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>";
2828  rvapi_set_text ( hlpSS.str().c_str(),
2829  "ProgressSection",
2830  settings->htmlReportLineProgress,
2831  1,
2832  1,
2833  1 );
2834  settings->htmlReportLineProgress += 1;
2835  rvapi_flush ( );
2836  }
2837  exit ( -1 );
2838  }
2839  if ( settings->verbose > 0 )
2840  {
2841  std::cout << "Structure loaded." << std::endl;
2842  }
2843 
2844  if ( settings->htmlReport )
2845  {
2846  std::stringstream hlpSS;
2847  hlpSS << "<font color=\"green\">" << "Structure " << settings->structFiles.at(0) << " loaded." << "</font>";
2848  rvapi_set_text ( hlpSS.str().c_str(),
2849  "ProgressSection",
2850  settings->htmlReportLineProgress,
2851  1,
2852  1,
2853  1 );
2854  settings->htmlReportLineProgress += 1;
2855  rvapi_flush ( );
2856  }
2857 
2858  //======================================== Write file if so required
2859  if ( settings->clearMapFile != "" )
2860  {
2861  if ( settings->verbose > 1 )
2862  {
2863  std::cout << ">> Saving the structure into the requested location ( " << settings->clearMapFile << " )." << std::endl;
2864  }
2865 
2866  symStr->writeMap ( settings->clearMapFile, symStr->_densityMapMap );
2867  }
2868 
2869  symStr->keepPhaseInMap ( this->alpha,
2870  this->bFactorChange,
2871  &this->bandwidth.at(0),
2872  &this->theta.at(0),
2873  &this->phi.at(0),
2874  &this->glIntegOrder.at(0),
2875  settings,
2876  this->useCOM,
2877  settings->noIQRsFromMap,
2878  settings->verbose,
2879  settings->clearMapData,
2880  settings->rotChangeDefault,
2881  settings->overlayDefaults,
2882  settings->maskBlurFactor,
2883  settings->maskBlurFactorGiven );
2884 
2885  symStr->mapPhaselessToSphere ( settings,
2886  this->theta.at(0),
2887  this->phi.at(0),
2888  this->shellSpacing,
2889  settings->manualShells, true );
2890  symStr->getSphericalHarmonicsCoeffs ( this->bandwidth.at(0), settings );
2891  if ( settings->verbose > 1 )
2892  {
2893  std::cout << ">> Structure spherical harmonics computed." << std::endl;
2894  }
2895  if ( settings->htmlReport )
2896  {
2897  std::stringstream hlpSS;
2898  hlpSS << "<font color=\"green\">" << "Spherical harmonics decomposition computed." << "</font>";
2899  rvapi_set_text ( hlpSS.str().c_str(),
2900  "ProgressSection",
2901  settings->htmlReportLineProgress,
2902  1,
2903  1,
2904  1 );
2905  settings->htmlReportLineProgress += 1;
2906  rvapi_flush ( );
2907  }
2908 
2909  //======================================== Find the rotation function peaks
2910  ProSHADE_comparePairwise* cmpObj = new ProSHADE_comparePairwise ( symStr,
2911  symStr,
2912  this->mPower,
2913  this->ignoreLs,
2914  this->glIntegOrder.at(0),
2915  settings );
2916 
2917  cmpObj->precomputeTrSigmaDescriptor ( );
2918  if ( settings->verbose > 2 )
2919  {
2920  std::cout << ">>>>> E matrices constructed." << std::endl;
2921  }
2922  if ( settings->htmlReport )
2923  {
2924  std::stringstream hlpSS;
2925  hlpSS << "<font color=\"green\">" << "Shell integration complete." << "</font>";
2926  rvapi_set_text ( hlpSS.str().c_str(),
2927  "ProgressSection",
2928  settings->htmlReportLineProgress,
2929  1,
2930  1,
2931  1 );
2932  settings->htmlReportLineProgress += 1;
2933  rvapi_flush ( );
2934  }
2935 
2936  cmpObj->getSO3InverseMap ( settings );
2937  if ( settings->verbose > 2 )
2938  {
2939  std::cout << ">>>>> Inverse SO(3) Fourier transform map obtained." << std::endl;
2940  }
2941  if ( settings->htmlReport )
2942  {
2943  std::stringstream hlpSS;
2944  hlpSS << "<font color=\"green\">" << "SO(3) Fourier Transform computed." << "</font>";
2945  rvapi_set_text ( hlpSS.str().c_str(),
2946  "ProgressSection",
2947  settings->htmlReportLineProgress,
2948  1,
2949  1,
2950  1 );
2951  settings->htmlReportLineProgress += 1;
2952  rvapi_flush ( );
2953  }
2954 
2955  this->rfPeaks = cmpObj->getSO3Peaks ( settings,
2956  this->peakHeightNoIQRs,
2957  false,
2958  this->peakSurroundingPoints,
2959  this->peakDistanceForReal,
2960  settings->verbose );
2961  if ( settings->verbose > 1 )
2962  {
2963  std::cout << ">> Peaks obtained." << std::endl;
2964  }
2965  if ( settings->htmlReport )
2966  {
2967  std::stringstream hlpSS;
2968  hlpSS << "<font color=\"green\">" << "Rotation map peaks detection complete." << "</font>";
2969  rvapi_set_text ( hlpSS.str().c_str(),
2970  "ProgressSection",
2971  settings->htmlReportLineProgress,
2972  1,
2973  1,
2974  1 );
2975  settings->htmlReportLineProgress += 1;
2976  rvapi_flush ( );
2977  }
2978 
2979  //======================================== Find C symmetries
2980  this->cnSymm = cmpObj->findCnSymmetry ( this->rfPeaks,
2981  settings,
2982  this->aaErrorTolerance,
2983  false,
2984  0.33,
2985  settings->verbose );
2986 
2987  if ( settings->verbose > 0 )
2988  {
2989  std::cout << "C symmetries detected." << std::endl;
2990  }
2991  if ( settings->htmlReport )
2992  {
2993  std::stringstream hlpSS;
2994  hlpSS << "<font color=\"green\">" << "Cyclic symmetries detected." << "</font>";
2995  rvapi_set_text ( hlpSS.str().c_str(),
2996  "ProgressSection",
2997  settings->htmlReportLineProgress,
2998  1,
2999  1,
3000  1 );
3001  settings->htmlReportLineProgress += 1;
3002  rvapi_flush ( );
3003  }
3004 
3005  if ( settings->symmetryFold != 0 )
3006  {
3007  bool foundFold = false;
3008  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cnSymm.size() ); iter++ )
3009  {
3010  if ( this->cnSymm.at(iter)[0] == settings->symmetryFold ) { foundFold = true; }
3011  }
3012 
3013  if ( !foundFold )
3014  {
3015  if ( settings->verbose > 2 )
3016  {
3017  std::cout << ">>>>> The requested fold was not found. Searching for it specifically." << std::endl;
3018  }
3019 
3020  double mapPeakHeight = 0.0;
3021  double mapPeakMax = 0.0;
3022  unsigned int iterMax = 0;
3023  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cnSymm.size() ); iter++ )
3024  {
3025  mapPeakHeight = cmpObj->maxAvgPeakForSymmetry ( this->cnSymm.at(iter)[1],
3026  this->cnSymm.at(iter)[2],
3027  this->cnSymm.at(iter)[3],
3028  static_cast<double> ( settings->symmetryFold ),
3029  settings );
3030  if ( mapPeakMax < mapPeakHeight ) { mapPeakMax = mapPeakHeight; iterMax = iter; }
3031  }
3032 
3033  if ( this->cnSymm.size() > 0 )
3034  {
3035  if ( mapPeakMax > ( this->cnSymm.at(iterMax)[4] * ( 1.0 - settings->symGapTolerance ) ) )
3036  {
3037  std::array<double,5> hlpArr;
3038  hlpArr[0] = static_cast<double> ( settings->symmetryFold );
3039  hlpArr[1] = this->cnSymm.at(iterMax)[1];
3040  hlpArr[2] = this->cnSymm.at(iterMax)[2];
3041  hlpArr[3] = this->cnSymm.at(iterMax)[3];
3042  hlpArr[4] = mapPeakMax;
3043  this->cnSymm.emplace_back ( hlpArr );
3044  }
3045  }
3046  }
3047  }
3048 
3049  //======================================== Find D Symmetries
3050  this->dnSymm = cmpObj->findDnSymmetry ( this->cnSymm , this->aaErrorTolerance );
3051  if ( this->cnSymm.size() != 0 )
3052  {
3053  this->cnSymmClear = cmpObj->findCnSymmetryClear ( this->cnSymm, settings, this->symGapTolerance, &this->printFull );
3054  }
3055  if ( this->dnSymm.size() != 0 )
3056  {
3057  this->dnSymmClear = cmpObj->findDnSymmetryClear ( this->dnSymm, settings, this->symGapTolerance, &this->printFull );
3058  }
3059  if ( settings->verbose > 0 )
3060  {
3061  std::cout << "D symmetries detected." << std::endl;
3062  }
3063  if ( settings->htmlReport )
3064  {
3065  std::stringstream hlpSS;
3066  hlpSS << "<font color=\"green\">" << "Dihedral symmetries detected." << "</font>";
3067  rvapi_set_text ( hlpSS.str().c_str(),
3068  "ProgressSection",
3069  settings->htmlReportLineProgress,
3070  1,
3071  1,
3072  1 );
3073  settings->htmlReportLineProgress += 1;
3074  rvapi_flush ( );
3075  }
3076 
3077  //======================================== Find polyhedral symmetries
3078  this->icosSymm = cmpObj->findIcosSymmetry ( this->cnSymm, &this->icosSymmPeakAvg, this->aaErrorTolerance );
3079  this->octaSymm = cmpObj->findOctaSymmetry ( this->cnSymm, &this->octaSymmPeakAvg, this->aaErrorTolerance );
3080  this->tetrSymm = cmpObj->findTetrSymmetry ( this->cnSymm, &this->tetrSymmPeakAvg, this->aaErrorTolerance );
3081  if ( settings->verbose > 0 )
3082  {
3083  std::cout << "T, O and I symmetries detected." << std::endl;
3084  }
3085  if ( settings->htmlReport )
3086  {
3087  std::stringstream hlpSS;
3088  hlpSS << "<font color=\"green\">" << "Tetrahedral, Octahedral and Icosahedral symmetries detected." << "</font>";
3089  rvapi_set_text ( hlpSS.str().c_str(),
3090  "ProgressSection",
3091  settings->htmlReportLineProgress,
3092  1,
3093  1,
3094  1 );
3095  settings->htmlReportLineProgress += 1;
3096  rvapi_flush ( );
3097  }
3098 
3099  if ( this->icosSymm.size() > 0 )
3100  {
3101  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosSymm.size() ); icoIt++ )
3102  {
3103  this->icosAxes = this->generateIcosAxes ( cmpObj, settings, this->icosSymm.at(icoIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3104 
3105  if ( this->icosAxes.size() == 31 )
3106  {
3107  break;
3108  }
3109  }
3110  if ( this->icosAxes.size() != 31 )
3111  {
3112  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;
3113  }
3114  else
3115  {
3116  this->icosElems = this->generateIcosElements ( this->icosAxes, settings, settings->verbose );
3117  }
3118  }
3119 
3120  if ( ( ( this->octaSymm.size() > 0 ) && ( this->icosAxes.size() == 0 ) ) ||
3121  ( ( settings->symmetryType == "O" ) && ( this->octaSymm.size() > 0 ) ) )
3122  {
3123  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaSymm.size() ); octIt++ )
3124  {
3125  this->octaAxes = this->generateOctaAxes ( cmpObj, settings, this->octaSymm.at(octIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3126 
3127  if ( this->octaAxes.size() == 13 )
3128  {
3129  break;
3130  }
3131  }
3132  if ( this->octaAxes.size() != 13 )
3133  {
3134  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;
3135  }
3136  else
3137  {
3138  this->octaElems = this->generateOctaElements ( this->octaAxes, settings, settings->verbose );
3139  }
3140  }
3141 
3142  if ( ( ( this->tetrSymm.size() > 0 ) && ( this->octaAxes.size() == 0 ) && ( this->icosAxes.size() == 0 ) ) ||
3143  ( ( settings->symmetryType == "T" ) && ( this->tetrSymm.size() > 0 ) ) )
3144  {
3145  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrSymm.size() ); tetIt++ )
3146  {
3147  this->tetrAxes = this->generateTetrAxes ( cmpObj, settings, this->tetrSymm.at(tetIt), this->cnSymm, this->aaErrorTolerance, settings->verbose );
3148 
3149  if ( this->tetrAxes.size() == 6 )
3150  {
3151  break;
3152  }
3153  }
3154  if ( this->tetrAxes.size() != 6 )
3155  {
3156  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;
3157  }
3158  else
3159  {
3160  this->tetrElems = this->generateTetrElements ( this->tetrAxes, settings, settings->verbose );
3161  }
3162  }
3163 
3164  if ( settings->verbose > 0 )
3165  {
3166  std::cout << ">> Generation of T, O and I symmetry group elements complete." << std::endl;
3167  }
3168 
3169  if ( settings->verbose > 0 )
3170  {
3171  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
3172  std::cout << "| COMPLETED |" << std::endl;
3173  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
3174  }
3175 
3176  if ( settings->htmlReport )
3177  {
3178  std::stringstream hlpSS;
3179  hlpSS << "<font color=\"green\">" << "Symmetry detection completed." << "</font>";
3180  rvapi_set_text ( hlpSS.str().c_str(),
3181  "ProgressSection",
3182  settings->htmlReportLineProgress,
3183  1,
3184  1,
3185  1 );
3186  settings->htmlReportLineProgress += 1;
3187  rvapi_flush ( );
3188  }
3189 
3190  //======================================== Keep data type in memory
3191  this->inputStructureDataType = symStr->_fromPDB;
3192 
3193  //======================================== Free memory
3194  cmpObj->freeInvMap ( );
3195  delete cmpObj;
3196  delete symStr;
3197 
3198  //======================================== Done
3199  return ;
3200 
3201 }
3202 
3215 void ProSHADE_internal::ProSHADE_symmetry::printResultsRequest ( std::string symmetryType, unsigned int symmetryFold, int verbose )
3216 {
3217  //======================================== Claim the symmetry to be the highest detected
3218  if ( verbose > 0 )
3219  {
3220  printf ( "-----------------------------------------------------------\n" );
3221  printf ( "| RESULTS |\n" );
3222  printf ( "-----------------------------------------------------------\n\n" );
3223  }
3224 
3225  if ( symmetryType == "I" )
3226  {
3227  if ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 )
3228  {
3229  printf ( "Detected Icosahedral symmetry as requested\n\n" );
3230  printf ( "Symmetry axes table:\n" );
3231  printf ( "-----------------------------------------------------------\n" );
3232  printf ( "Symmetry Fold x y z Angle Peak\n" );
3233  printf ( " Type height\n" );
3234  printf ( "-----------------------------------------------------------\n" );
3235 
3236  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3237  {
3238  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] );
3239  }
3240  printf ( "\n" );
3241 
3242  printf ( "Symmetry elements table:\n" );
3243  printf ( "-----------------------------------------------------------\n" );
3244  printf ( "Symmetry x y z Angle \n" );
3245  printf ( " Type (deg) \n" );
3246  printf ( "-----------------------------------------------------------\n" );
3247 
3248  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3249  {
3250  if ( this->icosElems.at(icoIt)[0] != 1.0 )
3251  {
3252  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] );
3253  }
3254  else
3255  {
3256  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] );
3257  }
3258  }
3259  printf ( "\n" );
3260  }
3261  else
3262  {
3263  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;
3264  }
3265  }
3266 
3267  if ( symmetryType == "O" )
3268  {
3269  if ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 )
3270  {
3271  printf ( "Detected (Cub)octahedral 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 octIt = 0; octIt < static_cast<unsigned int> ( this->octaAxes.size() ); octIt++ )
3279  {
3280  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] );
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 octIt = 0; octIt < static_cast<unsigned int> ( this->octaElems.size() ); octIt++ )
3291  {
3292  if ( this->octaElems.at(octIt)[0] != 1.0 )
3293  {
3294  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] );
3295  }
3296  else
3297  {
3298  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] );
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.\n\n" << std::endl << std::endl;
3306  }
3307  }
3308 
3309  if ( symmetryType == "T" )
3310  {
3311  if ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 )
3312  {
3313  printf ( "Detected Tetrahedral 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 tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrAxes.size() ); tetIt++ )
3321  {
3322  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] );
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 tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrElems.size() ); tetIt++ )
3333  {
3334  if ( this->tetrElems.at(tetIt)[0] != 1.0 )
3335  {
3336  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] );
3337  }
3338  else
3339  {
3340  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] );
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 == "D" )
3352  {
3353  if ( static_cast<unsigned int> ( this->dnSymm.size() ) > 0 )
3354  {
3355  bool reqFound = false;
3356  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->dnSymm.size() ); dIt++ )
3357  {
3358  if ( reqFound ) { break; }
3359  unsigned int howManyTwos = 0;
3360  for ( unsigned int dItt = 0; dItt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); dItt++ )
3361  {
3362  if ( reqFound ) { break; }
3363  if ( symmetryFold != 2 )
3364  {
3365  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold )
3366  {
3367  printf ( "Detected Dihedral symmetry as requested\n\n" );
3368  printf ( "Symmetry axes table:\n" );
3369  printf ( "-----------------------------------------------------------\n" );
3370  printf ( "Symmetry Fold x y z Angle Peak\n" );
3371  printf ( " Type height\n" );
3372  printf ( "-----------------------------------------------------------\n" );
3373  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
3374  {
3375  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] );
3376  }
3377 
3378  printf ( "\n" );
3379 
3380  printf ( "Symmetry elements table:\n" );
3381  printf ( "-----------------------------------------------------------\n" );
3382  printf ( "Symmetry x y z Angle \n" );
3383  printf ( " Type (deg) \n" );
3384  printf ( "-----------------------------------------------------------\n" );
3385 
3386  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3387  for ( unsigned int it = 0; it < 2; it++ )
3388  {
3389  if ( static_cast<int> ( this->dnSymm.at(0).at(it)[0] ) % 2 == 0 )
3390  {
3391  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++ )
3392  {
3393  if ( iter == 0 ) { continue; }
3394  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
3395  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] ) ) );
3396  }
3397  }
3398  else
3399  {
3400  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++ )
3401  {
3402  if ( iter == 0 ) { continue; }
3403  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] ) ) );
3404  }
3405  }
3406  }
3407 
3408  printf ( "\n" );
3409  reqFound = true;
3410  break;
3411  }
3412  else
3413  {
3414  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
3415  {
3416  continue;
3417  }
3418  else
3419  {
3420  break;
3421  }
3422  }
3423  }
3424  if ( symmetryFold == 2 )
3425  {
3426  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
3427  {
3428  howManyTwos += 1;
3429  }
3430  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold && howManyTwos == 2 )
3431  {
3432  printf ( "Detected Dihedral symmetry as requested\n\n" );
3433  printf ( "Symmetry axes table:\n" );
3434  printf ( "-----------------------------------------------------------\n" );
3435  printf ( "Symmetry Fold x y z Angle Peak\n" );
3436  printf ( " Type height\n" );
3437  printf ( "-----------------------------------------------------------\n" );
3438  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
3439  {
3440  if ( this->dnSymm.at(dIt).at(it)[0] == 2.0 )
3441  {
3442  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] );
3443  }
3444  }
3445 
3446  printf ( "\n" );
3447 
3448  printf ( "Symmetry elements table:\n" );
3449  printf ( "-----------------------------------------------------------\n" );
3450  printf ( "Symmetry x y z Angle \n" );
3451  printf ( " Type (deg) \n" );
3452  printf ( "-----------------------------------------------------------\n" );
3453 
3454  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3455  for ( unsigned int it = 0; it < 2; it++ )
3456  {
3457  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
3458  {
3459  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++ )
3460  {
3461  if ( iter == 0 ) { continue; }
3462  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
3463  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] ) ) );
3464  }
3465  }
3466  else
3467  {
3468  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++ )
3469  {
3470  if ( iter == 0 ) { continue; }
3471  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] ) ) );
3472  }
3473  }
3474  }
3475 
3476  printf ( "\n" );
3477  reqFound = true;
3478  break;
3479  }
3480  }
3481  }
3482  }
3483  if ( !reqFound )
3484  {
3485  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;
3486  }
3487  }
3488  else
3489  {
3490  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;
3491  }
3492  }
3493 
3494  if ( symmetryType == "C" )
3495  {
3496  if ( static_cast<unsigned int> ( this->cnSymm.size() ) > 0 )
3497  {
3498  bool reqFound = false;
3499  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->cnSymm.size() ); dIt++ )
3500  {
3501  if ( this->cnSymm.at(dIt)[0] == symmetryFold )
3502  {
3503  printf ( "Detected Cyclic symmetry as requested\n\n" );
3504  printf ( "Symmetry axes table:\n" );
3505  printf ( "-----------------------------------------------------------\n" );
3506  printf ( "Symmetry Fold x y z Angle Peak\n" );
3507  printf ( " Type height\n" );
3508  printf ( "-----------------------------------------------------------\n" );
3509  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] ) );
3510 
3511  printf ( "\n" );
3512 
3513  printf ( "Symmetry elements table:\n" );
3514  printf ( "-----------------------------------------------------------\n" );
3515  printf ( "Symmetry x y z Angle \n" );
3516  printf ( " Type (deg) \n" );
3517  printf ( "-----------------------------------------------------------\n" );
3518 
3519  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
3520  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
3521  {
3522  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++ )
3523  {
3524  if ( iter == 0 ) { continue; }
3525  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
3526  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] ) ) );
3527  }
3528  }
3529  else
3530  {
3531  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++ )
3532  {
3533  if ( iter == 0 ) { continue; }
3534  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] ) ) );
3535  }
3536  }
3537  printf ( "\n" );
3538  reqFound = true;
3539  break;
3540  }
3541  }
3542  if ( !reqFound )
3543  {
3544  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;
3545  }
3546  }
3547  else
3548  {
3549  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;
3550  }
3551  }
3552 
3553  //======================================== Print alternativs
3554  printf ( "Alternatives:\n" );
3555  printf ( "-----------------------------------------------------------\n" );
3556  printf ( "Symmetry Fold x y z Angle Peak\n" );
3557  printf ( " Type height\n" );
3558  printf ( "-----------------------------------------------------------\n" );
3559  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
3560  {
3561  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] ) );
3562  }
3563 
3564  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
3565  {
3566  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] );
3567 
3568  for ( unsigned int mem = 1; mem < static_cast<unsigned int> ( this->dnSymm.at(iter).size() ); mem++ )
3569  {
3570  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] );
3571  }
3572  }
3573 
3574  if ( this->tetrElems.size() > 0 )
3575  {
3576  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->tetrSymm.size() ); iter++ )
3577  {
3578  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] );
3579  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] );
3580  }
3581  }
3582 
3583  if ( this->octaElems.size() > 0 )
3584  {
3585  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->octaSymm.size() ); iter++ )
3586  {
3587  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] );
3588  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] );
3589  }
3590  }
3591 
3592  if ( this->icosElems.size() > 0 )
3593  {
3594  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->icosSymm.size() ); iter++ )
3595  {
3596  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] );
3597  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] );
3598  }
3599  }
3600  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
3601 
3602  //======================================== Done
3603  return ;
3604 
3605 }
3606 
3620  unsigned int symmetryFold,
3621  ProSHADE::ProSHADE_settings* settings )
3622 {
3623  //======================================== Claim the symmetry to be the requested one
3624  if ( settings->htmlReport )
3625  {
3626  //==================================== Create review section
3627  rvapi_add_section ( "ReviewSection",
3628  "Review",
3629  "body",
3630  settings->htmlReportLine,
3631  0,
3632  1,
3633  1,
3634  false );
3635  settings->htmlReportLine += 1;
3636 
3637  std::stringstream hlpSS;
3638  hlpSS << "<pre>" << "Requested symmetry : ";
3639  if ( symmetryType == "I" )
3640  {
3641  hlpSS << "Icosahedral" << "</pre>";
3642  }
3643  if ( symmetryType == "O" )
3644  {
3645  hlpSS << "Octahedral" << "</pre>";
3646  }
3647  if ( symmetryType == "T" )
3648  {
3649  hlpSS << "Tetrahedral" << "</pre>";
3650  }
3651  if ( symmetryType == "D" )
3652  {
3653  hlpSS << "Dihedral with fold " << ProSHADE_internal_misc::to_string_with_precision ( symmetryFold ) << "</pre>";
3654  }
3655  if ( symmetryType == "C" )
3656  {
3657  hlpSS << "Cyclic with fold " << ProSHADE_internal_misc::to_string_with_precision ( symmetryFold ) << "</pre>";
3658  }
3659 
3660 
3661  rvapi_set_text ( hlpSS.str().c_str(),
3662  "ReviewSection",
3663  0,
3664  0,
3665  1,
3666  1 );
3667 
3668  hlpSS.str ( std::string ( ) );
3669  hlpSS << "<pre>" << "Input structure : " << this->structFiles.at(0) << "</pre>";
3670  rvapi_set_text ( hlpSS.str().c_str(),
3671  "ReviewSection",
3672  1,
3673  0,
3674  1,
3675  1 );
3676  rvapi_flush ( );
3677 
3678  //==================================== Create results section
3679  rvapi_add_section ( "ResultsSection",
3680  "Results",
3681  "body",
3682  settings->htmlReportLine,
3683  0,
3684  1,
3685  1,
3686  true );
3687  settings->htmlReportLine += 1;
3688  }
3689 
3690  int totTabRows = 0;
3691  bool foundRequest = true;
3692 
3693  if ( symmetryType == "I" )
3694  {
3695  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
3696  {
3697  std::stringstream hlpSS;
3698  hlpSS << "<b>" << "Detected <i>ICOSAHEDRAL<i> symmetry as requested." << "</b>";
3699  rvapi_set_text ( hlpSS.str().c_str(),
3700  "ResultsSection",
3701  0,
3702  0,
3703  1,
3704  1 );
3705  rvapi_flush ( );
3706 
3707  //==================================== Symmetry axes table
3708  rvapi_add_table ( "SymmetryTypeTable",
3709  "Detected symmetry axes",
3710  "ResultsSection",
3711  1,
3712  0,
3713  static_cast<unsigned int> ( this->icosAxes.size() ),
3714  8,
3715  1 );
3716 
3717  // ... Column headers
3718  int columnIter = 0;
3719 
3720  hlpSS.str ( std::string ( ) );
3721  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
3722  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
3723  columnIter += 1;
3724 
3725  hlpSS.str ( std::string ( ) );
3726  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
3727  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
3728  columnIter += 1;
3729 
3730  hlpSS.str ( std::string ( ) );
3731  hlpSS << "This column states the x-axis element of the symmetry axis.";
3732  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3733  columnIter += 1;
3734 
3735  hlpSS.str ( std::string ( ) );
3736  hlpSS << "This column states the y-axis element of the symmetry axis.";
3737  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3738  columnIter += 1;
3739 
3740  hlpSS.str ( std::string ( ) );
3741  hlpSS << "This column states the z-axis element of the symmetry axis.";
3742  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3743  columnIter += 1;
3744 
3745  hlpSS.str ( std::string ( ) );
3746  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
3747  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
3748  columnIter += 1;
3749 
3750  hlpSS.str ( std::string ( ) );
3751  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.";
3752  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
3753  columnIter += 1;
3754 
3755  // ... Row headers
3756  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3757  {
3758  std::stringstream hlpSS2;
3759  hlpSS2 << "Symmetry axis #" << icoIt+1;
3760  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
3761  }
3762 
3763  // ... Fill in data
3764  int prec = 4;
3765  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
3766  {
3767  std::stringstream hlpSS2;
3768  hlpSS2 << "C";
3769  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
3770 
3771  hlpSS2.str ( std::string ( ) );
3772  hlpSS2 << static_cast<int> ( this->icosAxes.at(icoIt)[0] );
3773  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
3774 
3775  hlpSS2.str ( std::string ( ) );
3776  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[1], prec );
3777  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
3778 
3779  hlpSS2.str ( std::string ( ) );
3780  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[2], prec );
3781  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
3782 
3783  hlpSS2.str ( std::string ( ) );
3784  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[3], prec );
3785  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
3786 
3787  hlpSS2.str ( std::string ( ) );
3788  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 );
3789  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
3790 
3791  hlpSS2.str ( std::string ( ) );
3792  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[4], prec );
3793  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
3794  }
3795 
3796  //==================================== Symmetry elements table
3797  rvapi_add_table ( "SymmetryElementsTable",
3798  "Detected symmetry elements",
3799  "ResultsSection",
3800  static_cast<unsigned int> ( this->icosAxes.size() ) + 1,
3801  0,
3802  static_cast<unsigned int> ( this->icosElems.size() ),
3803  7,
3804  -1 );
3805  totTabRows = static_cast<unsigned int> ( this->icosAxes.size() ) + 1 + static_cast<unsigned int> ( this->icosElems.size() );
3806 
3807  // ... Column headers
3808  columnIter = 0;
3809 
3810  hlpSS.str ( std::string ( ) );
3811  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
3812  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
3813  columnIter += 1;
3814 
3815  hlpSS.str ( std::string ( ) );
3816  hlpSS << "This column states the symmetry element fold.";
3817  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
3818  columnIter += 1;
3819 
3820  hlpSS.str ( std::string ( ) );
3821  hlpSS << "This column states the x-axis element of the symmetry element axis.";
3822  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3823  columnIter += 1;
3824 
3825  hlpSS.str ( std::string ( ) );
3826  hlpSS << "This column states the y-axis element of the symmetry element axis.";
3827  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3828  columnIter += 1;
3829 
3830  hlpSS.str ( std::string ( ) );
3831  hlpSS << "This column states the z-axis element of the symmetry element axis.";
3832  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3833  columnIter += 1;
3834 
3835  hlpSS.str ( std::string ( ) );
3836  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
3837  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
3838  columnIter += 1;
3839 
3840  // ... Row headers
3841  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3842  {
3843  std::stringstream hlpSS2;
3844  hlpSS2 << "Symmetry element #" << icoIt+1;
3845  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
3846  }
3847 
3848  // ... Fill in data
3849  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
3850  {
3851  if ( this->icosElems.at(icoIt)[0] != 1.0 )
3852  {
3853  std::stringstream hlpSS3;
3854  hlpSS3 << "C";
3855  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
3856  }
3857  else
3858  {
3859  std::stringstream hlpSS3;
3860  hlpSS3 << "E";
3861  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
3862  }
3863 
3864  std::stringstream hlpSS2;
3865  hlpSS2 << static_cast<int> ( this->icosElems.at(icoIt)[0] );
3866  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
3867 
3868  hlpSS2.str ( std::string ( ) );
3869  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[1], prec );
3870  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
3871 
3872  hlpSS2.str ( std::string ( ) );
3873  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[2], prec );
3874  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
3875 
3876  hlpSS2.str ( std::string ( ) );
3877  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[3], prec );
3878  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
3879 
3880  hlpSS2.str ( std::string ( ) );
3881  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[4], prec );
3882  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
3883  }
3884 
3885  rvapi_flush ( );
3886  }
3887  else
3888  {
3889  std::stringstream hlpSS;
3890  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>";
3891  rvapi_set_text ( hlpSS.str().c_str(),
3892  "ResultsSection",
3893  0,
3894  0,
3895  1,
3896  1 );
3897  rvapi_flush ( );
3898  foundRequest = false;
3899  }
3900  }
3901 
3902  if ( symmetryType == "O" )
3903  {
3904  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->octaElems.size() ) > 0 ) )
3905  {
3906  //================================ State result
3907  std::stringstream hlpSS;
3908  hlpSS << "<b>" << "Detected <i>OCTAHEDRAL</i> symmetry as requested." << "</b>";
3909  rvapi_set_text ( hlpSS.str().c_str(),
3910  "ResultsSection",
3911  0,
3912  0,
3913  1,
3914  1 );
3915  rvapi_flush ( );
3916 
3917  //================================ Symmetry axes table
3918  rvapi_add_table ( "SymmetryTypeTable",
3919  "Detected symmetry axes",
3920  "ResultsSection",
3921  1,
3922  0,
3923  static_cast<unsigned int> ( this->octaAxes.size() ),
3924  8,
3925  1 );
3926 
3927  // ... Column headers
3928  int columnIter = 0;
3929 
3930  hlpSS.str ( std::string ( ) );
3931  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
3932  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
3933  columnIter += 1;
3934 
3935  hlpSS.str ( std::string ( ) );
3936  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
3937  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
3938  columnIter += 1;
3939 
3940  hlpSS.str ( std::string ( ) );
3941  hlpSS << "This column states the x-axis element of the symmetry axis.";
3942  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
3943  columnIter += 1;
3944 
3945  hlpSS.str ( std::string ( ) );
3946  hlpSS << "This column states the y-axis element of the symmetry axis.";
3947  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
3948  columnIter += 1;
3949 
3950  hlpSS.str ( std::string ( ) );
3951  hlpSS << "This column states the z-axis element of the symmetry axis.";
3952  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
3953  columnIter += 1;
3954 
3955  hlpSS.str ( std::string ( ) );
3956  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
3957  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
3958  columnIter += 1;
3959 
3960  hlpSS.str ( std::string ( ) );
3961  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.";
3962  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
3963  columnIter += 1;
3964 
3965  // ... Row headers
3966  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
3967  {
3968  std::stringstream hlpSS2;
3969  hlpSS2 << "Symmetry axis #" << icoIt+1;
3970  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
3971  }
3972 
3973  // ... Fill in data
3974  int prec = 4;
3975  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
3976  {
3977  std::stringstream hlpSS2;
3978  hlpSS2 << "C";
3979  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
3980 
3981  hlpSS2.str ( std::string ( ) );
3982  hlpSS2 << static_cast<int> ( this->octaAxes.at(icoIt)[0] );
3983  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
3984 
3985  hlpSS2.str ( std::string ( ) );
3986  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[1], prec );
3987  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
3988 
3989  hlpSS2.str ( std::string ( ) );
3990  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[2], prec );
3991  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
3992 
3993  hlpSS2.str ( std::string ( ) );
3994  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[3], prec );
3995  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
3996 
3997  hlpSS2.str ( std::string ( ) );
3998  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 );
3999  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
4000 
4001  hlpSS2.str ( std::string ( ) );
4002  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[4], prec );
4003  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
4004  }
4005 
4006  //================================ Symmetry elements table
4007  rvapi_add_table ( "SymmetryElementsTable",
4008  "Detected symmetry elements",
4009  "ResultsSection",
4010  static_cast<unsigned int> ( this->octaAxes.size() ) + 1,
4011  0,
4012  static_cast<unsigned int> ( this->octaElems.size() ),
4013  7,
4014  -1 );
4015  totTabRows = static_cast<unsigned int> ( this->octaAxes.size() ) + 1 + static_cast<unsigned int> ( this->octaElems.size() );
4016 
4017  // ... Column headers
4018  columnIter = 0;
4019 
4020  hlpSS.str ( std::string ( ) );
4021  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4022  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4023  columnIter += 1;
4024 
4025  hlpSS.str ( std::string ( ) );
4026  hlpSS << "This column states the symmetry element fold.";
4027  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4028  columnIter += 1;
4029 
4030  hlpSS.str ( std::string ( ) );
4031  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4032  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4033  columnIter += 1;
4034 
4035  hlpSS.str ( std::string ( ) );
4036  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4037  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4038  columnIter += 1;
4039 
4040  hlpSS.str ( std::string ( ) );
4041  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4042  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4043  columnIter += 1;
4044 
4045  hlpSS.str ( std::string ( ) );
4046  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4047  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4048  columnIter += 1;
4049 
4050  // ... Row headers
4051  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
4052  {
4053  std::stringstream hlpSS2;
4054  hlpSS2 << "Symmetry element #" << icoIt+1;
4055  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4056  }
4057 
4058  // ... Fill in data
4059  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
4060  {
4061  if ( this->octaElems.at(icoIt)[0] != 1.0 )
4062  {
4063  std::stringstream hlpSS3;
4064  hlpSS3 << "C";
4065  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
4066  }
4067  else
4068  {
4069  std::stringstream hlpSS3;
4070  hlpSS3 << "E";
4071  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
4072  }
4073 
4074  std::stringstream hlpSS2;
4075  hlpSS2 << static_cast<int> ( this->octaElems.at(icoIt)[0] );
4076  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
4077 
4078  hlpSS2.str ( std::string ( ) );
4079  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[1], prec );
4080  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
4081 
4082  hlpSS2.str ( std::string ( ) );
4083  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[2], prec );
4084  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
4085 
4086  hlpSS2.str ( std::string ( ) );
4087  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[3], prec );
4088  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
4089 
4090  hlpSS2.str ( std::string ( ) );
4091  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[4], prec );
4092  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
4093  }
4094 
4095  rvapi_flush ( );
4096  }
4097  else
4098  {
4099  std::stringstream hlpSS;
4100  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>";
4101  rvapi_set_text ( hlpSS.str().c_str(),
4102  "ResultsSection",
4103  0,
4104  0,
4105  1,
4106  1 );
4107  rvapi_flush ( );
4108  foundRequest = false;
4109  }
4110  }
4111 
4112  if ( symmetryType == "T" )
4113  {
4114  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
4115  {
4116  //============================ State result
4117  std::stringstream hlpSS;
4118  hlpSS << "<b>" << "Detected <i>TETRAHEDRAL</i> symmetry as requested." << "</b>";
4119  rvapi_set_text ( hlpSS.str().c_str(),
4120  "ResultsSection",
4121  0,
4122  0,
4123  1,
4124  1 );
4125  rvapi_flush ( );
4126 
4127  //============================ Symmetry axes table
4128  rvapi_add_table ( "SymmetryTypeTable",
4129  "Detected symmetry axes",
4130  "ResultsSection",
4131  1,
4132  0,
4133  static_cast<unsigned int> ( this->tetrAxes.size() ),
4134  8,
4135  1 );
4136 
4137  // ... Column headers
4138  int columnIter = 0;
4139 
4140  hlpSS.str ( std::string ( ) );
4141  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4142  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4143  columnIter += 1;
4144 
4145  hlpSS.str ( std::string ( ) );
4146  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4147  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4148  columnIter += 1;
4149 
4150  hlpSS.str ( std::string ( ) );
4151  hlpSS << "This column states the x-axis element of the symmetry axis.";
4152  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4153  columnIter += 1;
4154 
4155  hlpSS.str ( std::string ( ) );
4156  hlpSS << "This column states the y-axis element of the symmetry axis.";
4157  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4158  columnIter += 1;
4159 
4160  hlpSS.str ( std::string ( ) );
4161  hlpSS << "This column states the z-axis element of the symmetry axis.";
4162  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4163  columnIter += 1;
4164 
4165  hlpSS.str ( std::string ( ) );
4166  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4167  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4168  columnIter += 1;
4169 
4170  hlpSS.str ( std::string ( ) );
4171  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.";
4172  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4173  columnIter += 1;
4174 
4175  // ... Row headers
4176  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
4177  {
4178  std::stringstream hlpSS2;
4179  hlpSS2 << "Symmetry axis #" << icoIt+1;
4180  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
4181  }
4182 
4183  // ... Fill in data
4184  int prec = 4;
4185  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
4186  {
4187  std::stringstream hlpSS2;
4188  hlpSS2 << "C";
4189  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
4190 
4191  hlpSS2.str ( std::string ( ) );
4192  hlpSS2 << static_cast<int> ( this->tetrAxes.at(icoIt)[0] );
4193  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
4194 
4195  hlpSS2.str ( std::string ( ) );
4196  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[1], prec );
4197  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
4198 
4199  hlpSS2.str ( std::string ( ) );
4200  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[2], prec );
4201  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
4202 
4203  hlpSS2.str ( std::string ( ) );
4204  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[3], prec );
4205  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
4206 
4207  hlpSS2.str ( std::string ( ) );
4208  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 );
4209  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
4210 
4211  hlpSS2.str ( std::string ( ) );
4212  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[4], prec );
4213  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
4214  }
4215 
4216  //============================ Symmetry elements table
4217  rvapi_add_table ( "SymmetryElementsTable",
4218  "Detected symmetry elements",
4219  "ResultsSection",
4220  static_cast<unsigned int> ( this->tetrAxes.size() ) + 1,
4221  0,
4222  static_cast<unsigned int> ( this->tetrElems.size() ),
4223  7,
4224  -1 );
4225  totTabRows = static_cast<unsigned int> ( this->tetrAxes.size() ) + 1 + static_cast<unsigned int> ( this->tetrElems.size() );
4226 
4227  // ... Column headers
4228  columnIter = 0;
4229 
4230  hlpSS.str ( std::string ( ) );
4231  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4232  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4233  columnIter += 1;
4234 
4235  hlpSS.str ( std::string ( ) );
4236  hlpSS << "This column states the symmetry element fold.";
4237  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4238  columnIter += 1;
4239 
4240  hlpSS.str ( std::string ( ) );
4241  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4242  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4243  columnIter += 1;
4244 
4245  hlpSS.str ( std::string ( ) );
4246  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4247  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4248  columnIter += 1;
4249 
4250  hlpSS.str ( std::string ( ) );
4251  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4252  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4253  columnIter += 1;
4254 
4255  hlpSS.str ( std::string ( ) );
4256  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4257  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4258  columnIter += 1;
4259 
4260  // ... Row headers
4261  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
4262  {
4263  std::stringstream hlpSS2;
4264  hlpSS2 << "Symmetry element #" << icoIt+1;
4265  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4266  }
4267 
4268  // ... Fill in data
4269  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
4270  {
4271  std::stringstream hlpSS3;
4272  if ( this->tetrElems.at(icoIt)[0] != 1.0 )
4273  {
4274  std::stringstream hlpSS2;
4275  hlpSS2 << "C";
4276  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
4277  }
4278  else
4279  {
4280  std::stringstream hlpSS2;
4281  hlpSS2 << "E";
4282  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
4283  }
4284 
4285  hlpSS3.str ( std::string ( ) );
4286  hlpSS3 << static_cast<int> ( this->tetrElems.at(icoIt)[0] );
4287  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 1 );
4288 
4289  hlpSS3.str ( std::string ( ) );
4290  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[1], prec );
4291  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 2 );
4292 
4293  hlpSS3.str ( std::string ( ) );
4294  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[2], prec );
4295  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 3 );
4296 
4297  hlpSS3.str ( std::string ( ) );
4298  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[3], prec );
4299  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 4 );
4300 
4301  hlpSS3.str ( std::string ( ) );
4302  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[4], prec );
4303  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 5 );
4304  }
4305 
4306  rvapi_flush ( );
4307  }
4308  else
4309  {
4310  std::stringstream hlpSS;
4311  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>";
4312  rvapi_set_text ( hlpSS.str().c_str(),
4313  "ResultsSection",
4314  0,
4315  0,
4316  1,
4317  1 );
4318  rvapi_flush ( );
4319  foundRequest = false;
4320  }
4321  }
4322 
4323  if ( symmetryType == "D" )
4324  {
4325  if ( static_cast<unsigned int> ( this->dnSymm.size() ) > 0 )
4326  {
4327  bool reqFound = false;
4328  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->dnSymm.size() ); dIt++ )
4329  {
4330  if ( reqFound ) { break; }
4331  unsigned int howManyTwos = 0;
4332  for ( unsigned int dItt = 0; dItt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); dItt++ )
4333  {
4334  if ( reqFound ) { break; }
4335  if ( symmetryFold != 2 )
4336  {
4337  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold )
4338  {
4339  std::stringstream hlpSS;
4340  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry as requested." << "</b>";
4341  rvapi_set_text ( hlpSS.str().c_str(),
4342  "ResultsSection",
4343  0,
4344  0,
4345  1,
4346  1 );
4347  rvapi_flush ( );
4348 
4349  //======================== Symmetry axes table
4350  rvapi_add_table ( "SymmetryTypeTable",
4351  "Detected symmetry axes",
4352  "ResultsSection",
4353  1,
4354  0,
4355  this->dnSymm.at(dIt).size(),
4356  8,
4357  1 );
4358 
4359  // ... Column headers
4360  int columnIter = 0;
4361 
4362  hlpSS.str ( std::string ( ) );
4363  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4364  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4365  columnIter += 1;
4366 
4367  hlpSS.str ( std::string ( ) );
4368  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4369  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4370  columnIter += 1;
4371 
4372  hlpSS.str ( std::string ( ) );
4373  hlpSS << "This column states the x-axis element of the symmetry axis.";
4374  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4375  columnIter += 1;
4376 
4377  hlpSS.str ( std::string ( ) );
4378  hlpSS << "This column states the y-axis element of the symmetry axis.";
4379  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4380  columnIter += 1;
4381 
4382  hlpSS.str ( std::string ( ) );
4383  hlpSS << "This column states the z-axis element of the symmetry axis.";
4384  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4385  columnIter += 1;
4386 
4387  hlpSS.str ( std::string ( ) );
4388  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4389  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4390  columnIter += 1;
4391 
4392  hlpSS.str ( std::string ( ) );
4393  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.";
4394  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4395  columnIter += 1;
4396 
4397  // ... Row headers
4398  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); icoIt++ )
4399  {
4400  hlpSS.str ( std::string ( ) );
4401  hlpSS << "Symmetry axis #" << icoIt+1;
4402  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", icoIt );
4403  }
4404 
4405  // ... Fill in data
4406  int prec = 4;
4407  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4408  {
4409  std::stringstream hlpSS2;
4410  hlpSS2 << "C";
4411  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 0 );
4412 
4413  hlpSS2.str ( std::string ( ) );
4414  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4415  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 1 );
4416 
4417  hlpSS2.str ( std::string ( ) );
4418  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4419  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 2 );
4420 
4421  hlpSS2.str ( std::string ( ) );
4422  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4423  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 3 );
4424 
4425  hlpSS2.str ( std::string ( ) );
4426  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4427  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 4 );
4428 
4429  hlpSS2.str ( std::string ( ) );
4430  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 );
4431  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 5 );
4432 
4433  hlpSS2.str ( std::string ( ) );
4434  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[4], prec );
4435  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), it, 6 );
4436  }
4437 
4438  //======================== Symmetry elements table
4439  int totRows = 0;
4440  for ( unsigned int it = 0; it < 2; it++ )
4441  {
4442  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4443  {
4444  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++ )
4445  {
4446  if ( iter == 0 ) { continue; }
4447  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4448 
4449  totRows += 1;
4450  }
4451  }
4452  else
4453  {
4454  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++ )
4455  {
4456  if ( iter == 0 ) { continue; }
4457 
4458  totRows += 1;
4459  }
4460  }
4461  }
4462  totRows += 1;
4463 
4464  rvapi_add_table ( "SymmetryElementsTable",
4465  "Detected symmetry elements",
4466  "ResultsSection",
4467  this->dnSymm.at(dIt).size() + 1,
4468  0,
4469  totRows,
4470  7,
4471  -1 );
4472  totTabRows = static_cast<unsigned int> ( totRows ) + this->dnSymm.at(dIt).size() + 1;
4473 
4474  // ... Column headers
4475  columnIter = 0;
4476 
4477  hlpSS.str ( std::string ( ) );
4478  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4479  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4480  columnIter += 1;
4481 
4482  hlpSS.str ( std::string ( ) );
4483  hlpSS << "This column states the symmetry element fold.";
4484  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4485  columnIter += 1;
4486 
4487  hlpSS.str ( std::string ( ) );
4488  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4489  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4490  columnIter += 1;
4491 
4492  hlpSS.str ( std::string ( ) );
4493  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4494  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4495  columnIter += 1;
4496 
4497  hlpSS.str ( std::string ( ) );
4498  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4499  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4500  columnIter += 1;
4501 
4502  hlpSS.str ( std::string ( ) );
4503  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4504  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4505  columnIter += 1;
4506 
4507  // ... Row headers
4508  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
4509  {
4510  std::stringstream hlpSS2;
4511  hlpSS2 << "Symmetry element #" << icoIt+1;
4512  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4513  }
4514 
4515  // ... Fill in data
4516  int rowCount = 1;
4517 
4518  hlpSS.str ( std::string ( ) );
4519  hlpSS << "E";
4520  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
4521 
4522  hlpSS.str ( std::string ( ) );
4523  hlpSS << static_cast<int> ( 1 );
4524  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
4525 
4526  hlpSS.str ( std::string ( ) );
4527  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
4528  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
4529 
4530  hlpSS.str ( std::string ( ) );
4531  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4532  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
4533 
4534  hlpSS.str ( std::string ( ) );
4535  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4536  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
4537 
4538  hlpSS.str ( std::string ( ) );
4539  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4540  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
4541 
4542  for ( unsigned int it = 0; it < 2; it++ )
4543  {
4544  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4545  {
4546  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++ )
4547  {
4548  if ( iter == 0 ) { continue; }
4549  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4550 
4551  std::stringstream hlpSS2;
4552  hlpSS2 << "C";
4553  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4554 
4555  hlpSS2.str ( std::string ( ) );
4556  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4557  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4558 
4559  hlpSS2.str ( std::string ( ) );
4560  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4561  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4562 
4563  hlpSS2.str ( std::string ( ) );
4564  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4565  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4566 
4567  hlpSS2.str ( std::string ( ) );
4568  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4569  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4570 
4571  hlpSS2.str ( std::string ( ) );
4572  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 );
4573  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4574  rowCount += 1;
4575  }
4576  }
4577  else
4578  {
4579  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++ )
4580  {
4581  if ( iter == 0 ) { continue; }
4582 
4583  std::stringstream hlpSS2;
4584  hlpSS2 << "C";
4585  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4586 
4587  hlpSS2.str ( std::string ( ) );
4588  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4589  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4590 
4591  hlpSS2.str ( std::string ( ) );
4592  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4593  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4594 
4595  hlpSS2.str ( std::string ( ) );
4596  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4597  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4598 
4599  hlpSS2.str ( std::string ( ) );
4600  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4601  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4602 
4603  hlpSS2.str ( std::string ( ) );
4604  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 );
4605  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4606  rowCount += 1;
4607  }
4608  }
4609  }
4610 
4611  rvapi_flush ( );
4612  reqFound = true;
4613  break;
4614  }
4615  else
4616  {
4617  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
4618  {
4619  continue;
4620  }
4621  else
4622  {
4623  break;
4624  }
4625  }
4626  }
4627  if ( symmetryFold == 2 )
4628  {
4629  if ( this->dnSymm.at(dIt).at(dItt)[0] == 2 )
4630  {
4631  howManyTwos += 1;
4632  }
4633  if ( this->dnSymm.at(dIt).at(dItt)[0] == symmetryFold && howManyTwos == 2 )
4634  {
4635  std::stringstream hlpSS;
4636  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry as requested." << "</b>";
4637  rvapi_set_text ( hlpSS.str().c_str(),
4638  "ResultsSection",
4639  0,
4640  0,
4641  1,
4642  1 );
4643  rvapi_flush ( );
4644 
4645  //======================== Symmetry axes table
4646  rvapi_add_table ( "SymmetryTypeTable",
4647  "Detected symmetry axes",
4648  "ResultsSection",
4649  1,
4650  0,
4651  2,
4652  8,
4653  1 );
4654 
4655  // ... Column headers
4656  int columnIter = 0;
4657 
4658  hlpSS.str ( std::string ( ) );
4659  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4660  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4661  columnIter += 1;
4662 
4663  hlpSS.str ( std::string ( ) );
4664  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4665  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4666  columnIter += 1;
4667 
4668  hlpSS.str ( std::string ( ) );
4669  hlpSS << "This column states the x-axis element of the symmetry axis.";
4670  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4671  columnIter += 1;
4672 
4673  hlpSS.str ( std::string ( ) );
4674  hlpSS << "This column states the y-axis element of the symmetry axis.";
4675  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4676  columnIter += 1;
4677 
4678  hlpSS.str ( std::string ( ) );
4679  hlpSS << "This column states the z-axis element of the symmetry axis.";
4680  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4681  columnIter += 1;
4682 
4683  hlpSS.str ( std::string ( ) );
4684  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
4685  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4686  columnIter += 1;
4687 
4688  hlpSS.str ( std::string ( ) );
4689  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.";
4690  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
4691  columnIter += 1;
4692 
4693  // ... Row headers
4694  int rCount = 1;
4695  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); icoIt++ )
4696  {
4697  if ( this->dnSymm.at(dIt).at(icoIt)[0] != 2 ) { continue; }
4698  hlpSS.str ( std::string ( ) );
4699  hlpSS << "Symmetry axis #" << rCount;
4700  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", rCount-1 );
4701  rCount += 1;
4702  }
4703 
4704  // ... Fill in data
4705  int prec = 4;
4706  rCount = 0;
4707  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4708  {
4709  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4710 
4711  std::stringstream hlpSS2;
4712  hlpSS2 << "C";
4713  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 0 );
4714 
4715  hlpSS2.str ( std::string ( ) );
4716  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4717  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 1 );
4718 
4719  hlpSS2.str ( std::string ( ) );
4720  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4721  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 2 );
4722 
4723  hlpSS2.str ( std::string ( ) );
4724  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4725  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 3 );
4726 
4727  hlpSS2.str ( std::string ( ) );
4728  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4729  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 4 );
4730 
4731  hlpSS2.str ( std::string ( ) );
4732  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 );
4733  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 5 );
4734 
4735  hlpSS2.str ( std::string ( ) );
4736  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[4], prec );
4737  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), rCount, 6 );
4738 
4739  rCount += 1;
4740  }
4741 
4742  //======================== Symmetry elements table
4743  int totRows = 0;
4744  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4745  {
4746  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4747 
4748  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4749  {
4750  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++ )
4751  {
4752  if ( iter == 0 ) { continue; }
4753  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4754 
4755  totRows += 1;
4756  }
4757  }
4758  else
4759  {
4760  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++ )
4761  {
4762  if ( iter == 0 ) { continue; }
4763 
4764  totRows += 1;
4765  }
4766  }
4767  }
4768  totRows += 1;
4769 
4770  rvapi_add_table ( "SymmetryElementsTable",
4771  "Detected symmetry elements",
4772  "ResultsSection",
4773  this->dnSymm.at(dIt).size() + 1,
4774  0,
4775  totRows,
4776  7,
4777  -1 );
4778  totTabRows = static_cast<unsigned int> ( totRows ) + this->dnSymm.at(dIt).size() + 1;
4779 
4780  // ... Column headers
4781  columnIter = 0;
4782 
4783  hlpSS.str ( std::string ( ) );
4784  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
4785  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
4786  columnIter += 1;
4787 
4788  hlpSS.str ( std::string ( ) );
4789  hlpSS << "This column states the symmetry element fold.";
4790  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
4791  columnIter += 1;
4792 
4793  hlpSS.str ( std::string ( ) );
4794  hlpSS << "This column states the x-axis element of the symmetry element axis.";
4795  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
4796  columnIter += 1;
4797 
4798  hlpSS.str ( std::string ( ) );
4799  hlpSS << "This column states the y-axis element of the symmetry element axis.";
4800  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
4801  columnIter += 1;
4802 
4803  hlpSS.str ( std::string ( ) );
4804  hlpSS << "This column states the z-axis element of the symmetry element axis.";
4805  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
4806  columnIter += 1;
4807 
4808  hlpSS.str ( std::string ( ) );
4809  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
4810  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
4811  columnIter += 1;
4812 
4813  // ... Row headers
4814  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
4815  {
4816  std::stringstream hlpSS2;
4817  hlpSS2 << "Symmetry element #" << icoIt+1;
4818  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
4819  }
4820 
4821  // ... Fill in data
4822  int rowCount = 1;
4823 
4824  hlpSS.str ( std::string ( ) );
4825  hlpSS << "E";
4826  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
4827 
4828  hlpSS.str ( std::string ( ) );
4829  hlpSS << static_cast<int> ( 1 );
4830  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
4831 
4832  hlpSS.str ( std::string ( ) );
4833  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
4834  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
4835 
4836  hlpSS.str ( std::string ( ) );
4837  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4838  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
4839 
4840  hlpSS.str ( std::string ( ) );
4841  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4842  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
4843 
4844  hlpSS.str ( std::string ( ) );
4845  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
4846  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
4847 
4848  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dnSymm.at(dIt).size() ); it++ )
4849  {
4850  if ( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) % 2 == 0 )
4851  {
4852  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4853 
4854  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++ )
4855  {
4856  if ( iter == 0 ) { continue; }
4857  if ( iter == -std::ceil( static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] ) / 2.0 ) ) { continue; }
4858 
4859  std::stringstream hlpSS2;
4860  hlpSS2 << "C";
4861  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4862 
4863  hlpSS2.str ( std::string ( ) );
4864  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4865  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4866 
4867  hlpSS2.str ( std::string ( ) );
4868  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4869  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4870 
4871  hlpSS2.str ( std::string ( ) );
4872  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4873  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
4874 
4875  hlpSS2.str ( std::string ( ) );
4876  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[3], prec );
4877  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4878 
4879  hlpSS2.str ( std::string ( ) );
4880  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 );
4881  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4882  rowCount += 1;
4883  }
4884  }
4885  else
4886  {
4887  if ( this->dnSymm.at(dIt).at(it)[0] != 2 ) { continue; }
4888 
4889  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++ )
4890  {
4891  if ( iter == 0 ) { continue; }
4892 
4893  std::stringstream hlpSS2;
4894  hlpSS2 << "C";
4895  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
4896 
4897  hlpSS2.str ( std::string ( ) );
4898  hlpSS2 << static_cast<int> ( this->dnSymm.at(dIt).at(it)[0] );
4899  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
4900 
4901  hlpSS2.str ( std::string ( ) );
4902  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[1], prec );
4903  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
4904 
4905  hlpSS2.str ( std::string ( ) );
4906  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(dIt).at(it)[2], prec );
4907  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
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)[3], prec );
4911  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
4912 
4913  hlpSS2.str ( std::string ( ) );
4914  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 );
4915  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
4916  rowCount += 1;
4917  }
4918  }
4919  }
4920 
4921  rvapi_flush ( );
4922  reqFound = true;
4923  break;
4924  }
4925  }
4926  }
4927  }
4928  if ( !reqFound )
4929  {
4930  std::stringstream hlpSS;
4931  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>";
4932  rvapi_set_text ( hlpSS.str().c_str(),
4933  "ResultsSection",
4934  0,
4935  0,
4936  1,
4937  1 );
4938  rvapi_flush ( );
4939  foundRequest = false;
4940  }
4941  }
4942  else
4943  {
4944  std::stringstream hlpSS;
4945  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>";
4946  rvapi_set_text ( hlpSS.str().c_str(),
4947  "ResultsSection",
4948  0,
4949  0,
4950  1,
4951  1 );
4952  rvapi_flush ( );
4953  foundRequest = false;
4954  }
4955  }
4956 
4957  if ( symmetryType == "C" )
4958  {
4959  if ( static_cast<unsigned int> ( this->cnSymm.size() ) > 0 )
4960  {
4961  bool reqFound = false;
4962  for ( unsigned int dIt = 0; dIt < static_cast<unsigned int> ( this->cnSymm.size() ); dIt++ )
4963  {
4964  if ( this->cnSymm.at(dIt)[0] == symmetryFold )
4965  {
4966  //==================== State result
4967  std::stringstream hlpSS;
4968  hlpSS << "<b>" << "Detected <i>CYCLIC</i> symmetry as requested." << "</b>";
4969  rvapi_set_text ( hlpSS.str().c_str(),
4970  "ResultsSection",
4971  0,
4972  0,
4973  1,
4974  1 );
4975  rvapi_flush ( );
4976 
4977  //==================== Symmetry axes table
4978  rvapi_add_table ( "SymmetryTypeTable",
4979  "Detected symmetry axes",
4980  "ResultsSection",
4981  1,
4982  0,
4983  2,
4984  8,
4985  2 );
4986 
4987  // ... Column headers
4988  int columnIter = 0;
4989 
4990  hlpSS.str ( std::string ( ) );
4991  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
4992  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
4993  columnIter += 1;
4994 
4995  hlpSS.str ( std::string ( ) );
4996  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
4997  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
4998  columnIter += 1;
4999 
5000  hlpSS.str ( std::string ( ) );
5001  hlpSS << "This column states the x-axis element of the symmetry axis.";
5002  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5003  columnIter += 1;
5004 
5005  hlpSS.str ( std::string ( ) );
5006  hlpSS << "This column states the y-axis element of the symmetry axis.";
5007  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5008  columnIter += 1;
5009 
5010  hlpSS.str ( std::string ( ) );
5011  hlpSS << "This column states the z-axis element of the symmetry axis.";
5012  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5013  columnIter += 1;
5014 
5015  hlpSS.str ( std::string ( ) );
5016  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5017  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5018  columnIter += 1;
5019 
5020  hlpSS.str ( std::string ( ) );
5021  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.";
5022  rvapi_put_horz_theader( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
5023  columnIter += 1;
5024 
5025  // ... Row headers
5026  hlpSS.str ( std::string ( ) );
5027  hlpSS << "Symmetry axis #" << 1;
5028  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS.str().c_str(), "", 0 );
5029 
5030  // ... Fill in data
5031  int prec = 4;
5032  hlpSS.str ( std::string ( ) );
5033  hlpSS << "C";
5034  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 0 );
5035 
5036  hlpSS.str ( std::string ( ) );
5037  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5038  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 1 );
5039 
5040  hlpSS.str ( std::string ( ) );
5041  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5042  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 2 );
5043 
5044  hlpSS.str ( std::string ( ) );
5045  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5046  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 3 );
5047 
5048  hlpSS.str ( std::string ( ) );
5049  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5050  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 4 );
5051 
5052  hlpSS.str ( std::string ( ) );
5053  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 );
5054  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 5 );
5055 
5056  hlpSS.str ( std::string ( ) );
5057  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[4], prec );
5058  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 6 );
5059 
5060  //==================== Symmetry elements table
5061  int totRows = 0;
5062  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
5063  {
5064  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++ )
5065  {
5066  if ( iter == 0 ) { continue; }
5067  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
5068 
5069  totRows += 1;
5070  }
5071  }
5072  else
5073  {
5074  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++ )
5075  {
5076  if ( iter == 0 ) { continue; }
5077 
5078  totRows += 1;
5079  }
5080  }
5081  totRows += 1;
5082 
5083  rvapi_add_table ( "SymmetryElementsTable",
5084  "Detected symmetry elements",
5085  "ResultsSection",
5086  3,
5087  0,
5088  totRows,
5089  7,
5090  -1 );
5091  totTabRows = static_cast<unsigned int> ( totRows ) + 3;
5092 
5093  // ... Column headers
5094  columnIter = 0;
5095 
5096  hlpSS.str ( std::string ( ) );
5097  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
5098  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
5099  columnIter += 1;
5100 
5101  hlpSS.str ( std::string ( ) );
5102  hlpSS << "This column states the symmetry element fold.";
5103  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
5104  columnIter += 1;
5105 
5106  hlpSS.str ( std::string ( ) );
5107  hlpSS << "This column states the x-axis element of the symmetry element axis.";
5108  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5109  columnIter += 1;
5110 
5111  hlpSS.str ( std::string ( ) );
5112  hlpSS << "This column states the y-axis element of the symmetry element axis.";
5113  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5114  columnIter += 1;
5115 
5116  hlpSS.str ( std::string ( ) );
5117  hlpSS << "This column states the z-axis element of the symmetry element axis.";
5118  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5119  columnIter += 1;
5120 
5121  hlpSS.str ( std::string ( ) );
5122  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
5123  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5124  columnIter += 1;
5125 
5126  // ... Row headers
5127  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
5128  {
5129  std::stringstream hlpSS2;
5130  hlpSS2 << "Symmetry element #" << std::to_string ( icoIt+1 );
5131  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
5132  }
5133 
5134  // ... Fill in data
5135  int rowCount = 1;
5136 
5137  hlpSS.str ( std::string ( ) );
5138  hlpSS << "E";
5139  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
5140 
5141  hlpSS.str ( std::string ( ) );
5142  hlpSS << static_cast<int> ( 1 );
5143  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
5144 
5145  hlpSS.str ( std::string ( ) );
5146  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
5147  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
5148 
5149  hlpSS.str ( std::string ( ) );
5150  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5151  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
5152 
5153  hlpSS.str ( std::string ( ) );
5154  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5155  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
5156 
5157  hlpSS.str ( std::string ( ) );
5158  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
5159  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
5160 
5161  if ( static_cast<int> ( this->cnSymm.at(dIt)[0] ) % 2 == 0 )
5162  {
5163  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++ )
5164  {
5165  if ( iter == 0 ) { continue; }
5166  if ( iter == -std::ceil( static_cast<int> ( this->cnSymm.at(dIt)[0] ) / 2.0 ) ) { continue; }
5167 
5168  hlpSS.str ( std::string ( ) );
5169  hlpSS << "C";
5170  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
5171 
5172  hlpSS.str ( std::string ( ) );
5173  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5174  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
5175 
5176  hlpSS.str ( std::string ( ) );
5177  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5178  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
5179 
5180  hlpSS.str ( std::string ( ) );
5181  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5182  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
5183 
5184  hlpSS.str ( std::string ( ) );
5185  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5186  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
5187 
5188  hlpSS.str ( std::string ( ) );
5189  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 );
5190  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
5191  rowCount += 1;
5192  }
5193  }
5194  else
5195  {
5196  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++ )
5197  {
5198  if ( iter == 0 ) { continue; }
5199 
5200  hlpSS.str ( std::string ( ) );
5201  hlpSS << "C";
5202  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
5203 
5204  hlpSS.str ( std::string ( ) );
5205  hlpSS << static_cast<int> ( this->cnSymm.at(dIt)[0] );
5206  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
5207 
5208  hlpSS.str ( std::string ( ) );
5209  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[1], prec );
5210  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
5211 
5212  hlpSS.str ( std::string ( ) );
5213  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[2], prec );
5214  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
5215 
5216  hlpSS.str ( std::string ( ) );
5217  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(dIt)[3], prec );
5218  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
5219 
5220  hlpSS.str ( std::string ( ) );
5221  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 );
5222  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
5223  rowCount += 1;
5224  }
5225  }
5226 
5227  rvapi_flush ( );
5228  reqFound = true;
5229  break;
5230  }
5231  }
5232  if ( !reqFound )
5233  {
5234  std::stringstream hlpSS;
5235  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>";
5236  rvapi_set_text ( hlpSS.str().c_str(),
5237  "ResultsSection",
5238  0,
5239  0,
5240  1,
5241  1 );
5242  rvapi_flush ( );
5243  foundRequest = false;
5244  }
5245  }
5246  else
5247  {
5248  std::stringstream hlpSS;
5249  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>";
5250  rvapi_set_text ( hlpSS.str().c_str(),
5251  "ResultsSection",
5252  0,
5253  0,
5254  1,
5255  1 );
5256  rvapi_flush ( );
5257  foundRequest = false;
5258  }
5259  }
5260 
5261  //======================================== Print alternatives
5262  if ( foundRequest )
5263  {
5264  rvapi_add_table ( "AlternativesTable",
5265  "Alternative Symmetries Detected",
5266  "ResultsSection",
5267  totTabRows,
5268  0,
5269  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ) +
5270  static_cast<unsigned int> ( this->tetrSymm.size() ) + static_cast<unsigned int> ( this->octaSymm.size() ) +
5271  static_cast<unsigned int> ( this->icosSymm.size() ),
5272  7,
5273  -1 );
5274  }
5275  else
5276  {
5277  rvapi_add_table ( "AlternativesTable",
5278  "Alternative Symmetries Detected",
5279  "ResultsSection",
5280  totTabRows,
5281  0,
5282  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ) +
5283  static_cast<unsigned int> ( this->tetrSymm.size() ) + static_cast<unsigned int> ( this->octaSymm.size() ) +
5284  static_cast<unsigned int> ( this->icosSymm.size() ),
5285  7,
5286  1 );
5287  }
5288 
5289  // ... Column headers
5290  int columnIter = 0;
5291 
5292  std::stringstream hlpSS;
5293  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D).";
5294  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
5295  columnIter += 1;
5296 
5297  hlpSS.str ( std::string ( ) );
5298  hlpSS << "This column states the symmetry fold.";
5299  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
5300  columnIter += 1;
5301 
5302  hlpSS.str ( std::string ( ) );
5303  hlpSS << "This column states the x-axis element of the symmetry axis.";
5304  rvapi_put_horz_theader ( "AlternativesTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5305  columnIter += 1;
5306 
5307  hlpSS.str ( std::string ( ) );
5308  hlpSS << "This column states the y-axis element of the symmetry axis.";
5309  rvapi_put_horz_theader ( "AlternativesTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5310  columnIter += 1;
5311 
5312  hlpSS.str ( std::string ( ) );
5313  hlpSS << "This column states the z-axis element of the symmetry axis.";
5314  rvapi_put_horz_theader ( "AlternativesTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5315  columnIter += 1;
5316 
5317  hlpSS.str ( std::string ( ) );
5318  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5319  rvapi_put_horz_theader ( "AlternativesTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5320  columnIter += 1;
5321 
5322  hlpSS.str ( std::string ( ) );
5323  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.";
5324  rvapi_put_horz_theader ( "AlternativesTable", "Peak Height", hlpSS.str().c_str(), columnIter );
5325  columnIter += 1;
5326 
5327  // ... Row headers
5328  int maxCAlts = 0;
5329  int maxDAlts = 0;
5330  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5331  {
5332  std::stringstream hlpSS2;
5333  hlpSS2 << "Alternative Symmetry #" << gNo+1;
5334  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", gNo );
5335  maxCAlts = gNo;
5336  }
5337  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5338  {
5339  std::stringstream hlpSS2;
5340  hlpSS2 << "Alternative Symmetry #" << iter + maxCAlts + 2;
5341  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", iter + maxCAlts + 1 );
5342  maxDAlts = iter + maxCAlts;
5343  }
5344  maxDAlts += 1;
5345  if ( static_cast<int> ( this->tetrElems.size() ) > 0 )
5346  {
5347  std::stringstream hlpSS2;
5348  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5349  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5350  maxDAlts += 1;
5351  }
5352  if ( static_cast<int> ( this->octaElems.size() ) > 0 )
5353  {
5354  std::stringstream hlpSS2;
5355  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5356  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5357  maxDAlts += 1;
5358  }
5359  if ( static_cast<int> ( this->icosElems.size() ) > 0 )
5360  {
5361  std::stringstream hlpSS2;
5362  hlpSS2 << "Alternative Symmetry #" << maxDAlts + 2;
5363  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", maxDAlts + 1 );
5364  maxDAlts += 1;
5365  }
5366 
5367  int rowCount = 0;
5368  int prec = 4;
5369  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5370  {
5371  std::stringstream hlpSS2;
5372  hlpSS2 << "C";
5373  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5374 
5375  hlpSS2.str ( std::string ( ) );
5376  hlpSS2 << static_cast<int> ( static_cast<int> ( this->cnSymm.at(gNo)[0] ) );
5377  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5378 
5379  hlpSS2.str ( std::string ( ) );
5380  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[1], prec );
5381  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5382 
5383  hlpSS2.str ( std::string ( ) );
5384  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[2], prec );
5385  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5386 
5387  hlpSS2.str ( std::string ( ) );
5388  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[3], prec );
5389  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5390 
5391  hlpSS2.str ( std::string ( ) );
5392  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 );
5393  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5394 
5395  hlpSS2.str ( std::string ( ) );
5396  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->cnSymm.at(gNo)[4] ), prec );
5397  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5398  rowCount += 1;
5399  }
5400 
5401  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5402  {
5403  std::stringstream hlpSS2;
5404  hlpSS2 << "D";
5405  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5406 
5407  hlpSS2.str ( std::string ( ) );
5408  hlpSS2 << static_cast<int> ( static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ) );
5409  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5410 
5411  hlpSS2.str ( std::string ( ) );
5412  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[1], prec );
5413  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5414 
5415  hlpSS2.str ( std::string ( ) );
5416  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[2], prec );
5417  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5418 
5419  hlpSS2.str ( std::string ( ) );
5420  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[3], prec );
5421  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5422 
5423  hlpSS2.str ( std::string ( ) );
5424  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 );
5425  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5426 
5427  hlpSS2.str ( std::string ( ) );
5428  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->dnSymm.at(iter).at(0)[4] ), prec );
5429  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5430  rowCount += 1;
5431  }
5432 
5433  if ( static_cast<int> ( this->tetrElems.size() ) > 0 )
5434  {
5435  std::stringstream hlpSS2;
5436  hlpSS2 << "T";
5437  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5438 
5439  hlpSS2.str ( std::string ( ) );
5440  hlpSS2 << "N/A";
5441  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5442 
5443  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5444 
5445  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5446 
5447  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5448 
5449  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5450 
5451  hlpSS2.str ( std::string ( ) );
5452  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->tetrSymm.at(0).at(0)[4] ), prec );
5453  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5454  rowCount += 1;
5455  }
5456 
5457  if ( static_cast<int> ( this->octaElems.size() ) > 0 )
5458  {
5459  std::stringstream hlpSS2;
5460  hlpSS2 << "O";
5461  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5462 
5463  hlpSS2.str ( std::string ( ) );
5464  hlpSS2 << "N/A";
5465  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5466 
5467  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5468 
5469  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5470 
5471  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5472 
5473  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5474 
5475  hlpSS2.str ( std::string ( ) );
5476  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->octaSymm.at(0).at(0)[4] ), prec );
5477  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5478  rowCount += 1;
5479  }
5480 
5481  if ( static_cast<int> ( this->icosElems.size() ) > 0 )
5482  {
5483  std::stringstream hlpSS2;
5484  hlpSS2 << "I";
5485  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
5486 
5487  hlpSS2.str ( std::string ( ) );
5488  hlpSS2 << "N/A";
5489  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
5490 
5491  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
5492 
5493  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
5494 
5495  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
5496 
5497  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
5498 
5499  hlpSS2.str ( std::string ( ) );
5500  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->icosSymm.at(0).at(0)[4] ), prec );
5501  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
5502  rowCount += 1;
5503  }
5504 
5505  rvapi_flush ( );
5506 
5507  //======================================== Done
5508  return ;
5509 
5510 }
5511 
5523 {
5524  //======================================== Claim the symmetry to be the highest detected
5525  if ( verbose > 0 )
5526  {
5527  printf ( "-----------------------------------------------------------\n" );
5528  printf ( "| RESULTS |\n" );
5529  printf ( "-----------------------------------------------------------\n\n" );
5530  }
5531 
5532  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->icosElems.size() ) == 0 ) )
5533  {
5534  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" );
5535  }
5536 
5537  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
5538  {
5539  printf ( "Detected Icosahedral symmetry\n\n" );
5540  printf ( "Symmetry axes table:\n" );
5541  printf ( "-----------------------------------------------------------\n" );
5542  printf ( "Symmetry Fold x y z Angle Peak\n" );
5543  printf ( " Type height\n" );
5544  printf ( "-----------------------------------------------------------\n" );
5545 
5546  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5547  {
5548  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] );
5549  }
5550  printf ( "\n" );
5551 
5552  printf ( "Symmetry elements table:\n" );
5553  printf ( "-----------------------------------------------------------\n" );
5554  printf ( "Symmetry x y z Angle \n" );
5555  printf ( " Type (deg) \n" );
5556  printf ( "-----------------------------------------------------------\n" );
5557 
5558  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
5559  {
5560  if ( this->icosElems.at(icoIt)[0] != 1.0 )
5561  {
5562  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] );
5563  }
5564  else
5565  {
5566  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] );
5567  }
5568  }
5569  printf ( "\n" );
5570  }
5571  else
5572  {
5573  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
5574  {
5575  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" );
5576  }
5577 
5578  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) > 0 ) )
5579  {
5580  printf ( "Detected (Cub)octahedral symmetry\n\n" );
5581  printf ( "Symmetry axes table:\n" );
5582  printf ( "-----------------------------------------------------------\n" );
5583  printf ( "Symmetry Fold x y z Angle Peak\n" );
5584  printf ( " Type height\n" );
5585  printf ( "-----------------------------------------------------------\n" );
5586 
5587  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaAxes.size() ); octIt++ )
5588  {
5589  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] );
5590  }
5591  printf ( "\n" );
5592 
5593  printf ( "Symmetry elements table:\n" );
5594  printf ( "-----------------------------------------------------------\n" );
5595  printf ( "Symmetry x y z Angle \n" );
5596  printf ( " Type (deg) \n" );
5597  printf ( "-----------------------------------------------------------\n" );
5598 
5599  for ( unsigned int octIt = 0; octIt < static_cast<unsigned int> ( this->octaElems.size() ); octIt++ )
5600  {
5601  if ( this->octaElems.at(octIt)[0] != 1.0 )
5602  {
5603  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] );
5604  }
5605  else
5606  {
5607  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] );
5608  }
5609  }
5610  printf ( "\n" );
5611  }
5612  else
5613  {
5614  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) == 0 ) )
5615  {
5616  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
5617  {
5618  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" );
5619  }
5620  }
5621 
5622  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
5623  {
5624  printf ( "Detected Tetrahedral symmetry\n\n" );
5625  printf ( "Symmetry axes table:\n" );
5626  printf ( "-----------------------------------------------------------\n" );
5627  printf ( "Symmetry Fold x y z Angle Peak\n" );
5628  printf ( " Type height\n" );
5629  printf ( "-----------------------------------------------------------\n" );
5630 
5631  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrAxes.size() ); tetIt++ )
5632  {
5633  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] );
5634  }
5635  printf ( "\n" );
5636 
5637  printf ( "Symmetry elements table:\n" );
5638  printf ( "-----------------------------------------------------------\n" );
5639  printf ( "Symmetry x y z Angle \n" );
5640  printf ( " Type (deg) \n" );
5641  printf ( "-----------------------------------------------------------\n" );
5642 
5643  for ( unsigned int tetIt = 0; tetIt < static_cast<unsigned int> ( this->tetrElems.size() ); tetIt++ )
5644  {
5645  if ( this->tetrElems.at(tetIt)[0] != 1.0 )
5646  {
5647  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] );
5648  }
5649  else
5650  {
5651  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] );
5652  }
5653  }
5654  printf ( "\n" );
5655  }
5656  else
5657  {
5658  if ( static_cast<unsigned int> ( this->dnSymmClear.size() ) > 0 )
5659  {
5660  printf ( "Detected Dihedral symmetry\n\n" );
5661  printf ( "Symmetry axes table:\n" );
5662  printf ( "-----------------------------------------------------------\n" );
5663  printf ( "Symmetry Fold x y z Angle Peak\n" );
5664  printf ( " Type height\n" );
5665  printf ( "-----------------------------------------------------------\n" );
5666  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] );
5667  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] );
5668 
5669  printf ( "\n" );
5670 
5671  printf ( "Symmetry elements table:\n" );
5672  printf ( "-----------------------------------------------------------\n" );
5673  printf ( "Symmetry x y z Angle \n" );
5674  printf ( " Type (deg) \n" );
5675  printf ( "-----------------------------------------------------------\n" );
5676 
5677  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
5678  for ( unsigned int it = 0; it < 2; it++ )
5679  {
5680  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
5681  {
5682  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++ )
5683  {
5684  if ( iter == 0 ) { continue; }
5685  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
5686  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] ) ) );
5687  }
5688  }
5689  else
5690  {
5691  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++ )
5692  {
5693  if ( iter == 0 ) { continue; }
5694  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] ) ) );
5695  }
5696  }
5697  }
5698 
5699  printf ( "\n" );
5700  }
5701  else
5702  {
5703  if ( static_cast<unsigned int> ( this->cnSymmClear.size() ) > 0 )
5704  {
5705  printf ( "Detected Cyclic symmetry\n\n" );
5706  printf ( "Symmetry axes table:\n" );
5707  printf ( "-----------------------------------------------------------\n" );
5708  printf ( "Symmetry Fold x y z Angle Peak\n" );
5709  printf ( " Type height\n" );
5710  printf ( "-----------------------------------------------------------\n" );
5711  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] ) );
5712 
5713  printf ( "\n" );
5714 
5715  printf ( "Symmetry elements table:\n" );
5716  printf ( "-----------------------------------------------------------\n" );
5717  printf ( "Symmetry x y z Angle \n" );
5718  printf ( " Type (deg) \n" );
5719  printf ( "-----------------------------------------------------------\n" );
5720 
5721  printf ( " E %+.2f %+.2f %+.2f %+.1f \n", 1.0, 0.0, 0.0, 0.0 );
5722  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
5723  {
5724  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++ )
5725  {
5726  if ( iter == 0 ) { continue; }
5727  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
5728  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] ) ) );
5729  }
5730  }
5731  else
5732  {
5733  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++ )
5734  {
5735  if ( iter == 0 ) { continue; }
5736  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] ) ) );
5737  }
5738  }
5739  printf ( "\n" );
5740  }
5741  else
5742  {
5743  printf ( "Detected no symmetry.\n\n" );
5744  }
5745  }
5746  }
5747  }
5748  }
5749 
5750  //======================================== Print alternativs
5751  printf ( "Alternatives:\n" );
5752  printf ( "-----------------------------------------------------------\n" );
5753  printf ( "Symmetry Fold x y z Angle Peak\n" );
5754  printf ( " Type height\n" );
5755  printf ( "-----------------------------------------------------------\n" );
5756  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
5757  {
5758  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] ) );
5759  }
5760 
5761  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
5762  {
5763  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] );
5764 
5765  for ( unsigned int mem = 1; mem < static_cast<unsigned int> ( this->dnSymm.at(iter).size() ); mem++ )
5766  {
5767  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] );
5768  }
5769  }
5770 
5771  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
5772 
5773  //======================================== Done
5774  return ;
5775 
5776 }
5777 
5789 {
5790  //======================================== Claim the symmetry to be the highest detected
5791  if ( settings->htmlReport )
5792  {
5793  //==================================== Create review section
5794  rvapi_add_section ( "ReviewSection",
5795  "Review",
5796  "body",
5797  settings->htmlReportLine,
5798  0,
5799  1,
5800  1,
5801  false );
5802  settings->htmlReportLine += 1;
5803 
5804  std::stringstream hlpSS;
5805  hlpSS << "<pre>" << "Requested symmetry : " << "N/A" << "</pre>";
5806  rvapi_set_text ( hlpSS.str().c_str(),
5807  "ReviewSection",
5808  0,
5809  0,
5810  1,
5811  1 );
5812 
5813  hlpSS.str ( std::string ( ) );
5814  hlpSS << "<pre>" << "Input structure : " << this->structFiles.at(0) << "</pre>";
5815  rvapi_set_text ( hlpSS.str().c_str(),
5816  "ReviewSection",
5817  1,
5818  0,
5819  1,
5820  1 );
5821  rvapi_flush ( );
5822 
5823  //==================================== Create results section
5824  rvapi_add_section ( "ResultsSection",
5825  "Results",
5826  "body",
5827  settings->htmlReportLine,
5828  0,
5829  1,
5830  1,
5831  true );
5832  settings->htmlReportLine += 1;
5833  }
5834 
5835  int totTabRows = 0;
5836 
5837  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) == 0 ) )
5838  {
5839  //==================================== State result
5840  std::stringstream hlpSS;
5841  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>";
5842  rvapi_set_text ( hlpSS.str().c_str(),
5843  "ResultsSection",
5844  0,
5845  0,
5846  1,
5847  1 );
5848  rvapi_flush ( );
5849  }
5850 
5851  if ( ( static_cast<unsigned int> ( this->icosSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->icosElems.size() ) > 0 ) )
5852  {
5853  //==================================== State result
5854  std::stringstream hlpSS;
5855  hlpSS << "<b>" << "Detected <i>ICOSAHEDRAL</i> symmetry." << "</b>";
5856  rvapi_set_text ( hlpSS.str().c_str(),
5857  "ResultsSection",
5858  1,
5859  0,
5860  1,
5861  1 );
5862  rvapi_flush ( );
5863 
5864  //==================================== Symmetry axes table
5865  rvapi_add_table ( "SymmetryTypeTable",
5866  "Detected symmetry axes",
5867  "ResultsSection",
5868  2,
5869  0,
5870  static_cast<unsigned int> ( this->icosAxes.size() ),
5871  8,
5872  1 );
5873 
5874  // ... Column headers
5875  int columnIter = 0;
5876 
5877  hlpSS.str ( std::string ( ) );
5878  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
5879  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
5880  columnIter += 1;
5881 
5882  hlpSS.str ( std::string ( ) );
5883  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
5884  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
5885  columnIter += 1;
5886 
5887  hlpSS.str ( std::string ( ) );
5888  hlpSS << "This column states the x-axis element of the symmetry axis.";
5889  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5890  columnIter += 1;
5891 
5892  hlpSS.str ( std::string ( ) );
5893  hlpSS << "This column states the y-axis element of the symmetry axis.";
5894  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5895  columnIter += 1;
5896 
5897  hlpSS.str ( std::string ( ) );
5898  hlpSS << "This column states the z-axis element of the symmetry axis.";
5899  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5900  columnIter += 1;
5901 
5902  hlpSS.str ( std::string ( ) );
5903  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
5904  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5905  columnIter += 1;
5906 
5907  hlpSS.str ( std::string ( ) );
5908  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.";
5909  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
5910  columnIter += 1;
5911 
5912  // ... Row headers
5913  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5914  {
5915  std::stringstream hlpSS2;
5916  hlpSS2 << "Symmetry axis #" << icoIt+1;
5917  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
5918  }
5919 
5920  // ... Fill in data
5921  int prec = 4;
5922  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosAxes.size() ); icoIt++ )
5923  {
5924  std::stringstream hlpSS2;
5925  hlpSS2 << "C";
5926  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
5927 
5928  hlpSS2.str ( std::string ( ) );
5929  hlpSS2 << static_cast<int> ( this->icosAxes.at(icoIt)[0] );
5930  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
5931 
5932  hlpSS2.str ( std::string ( ) );
5933  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[1], prec );
5934  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
5935 
5936  hlpSS2.str ( std::string ( ) );
5937  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[2], prec );
5938  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
5939 
5940  hlpSS2.str ( std::string ( ) );
5941  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[3], prec );
5942  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
5943 
5944  hlpSS2.str ( std::string ( ) );
5945  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 );
5946  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
5947 
5948  hlpSS2.str ( std::string ( ) );
5949  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosAxes.at(icoIt)[4], prec );
5950  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
5951  }
5952 
5953  //==================================== Symmetry elements table
5954  rvapi_add_table ( "SymmetryElementsTable",
5955  "Detected symmetry elements",
5956  "ResultsSection",
5957  static_cast<unsigned int> ( this->icosAxes.size() ) + 2,
5958  0,
5959  static_cast<unsigned int> ( this->icosElems.size() ),
5960  7,
5961  -1 );
5962  totTabRows = static_cast<unsigned int> ( this->icosAxes.size() ) + 2 + static_cast<unsigned int> ( this->icosElems.size() );
5963 
5964  // ... Column headers
5965  columnIter = 0;
5966 
5967  hlpSS.str ( std::string ( ) );
5968  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
5969  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
5970  columnIter += 1;
5971 
5972  hlpSS.str ( std::string ( ) );
5973  hlpSS << "This column states the symmetry element fold.";
5974  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
5975  columnIter += 1;
5976 
5977  hlpSS.str ( std::string ( ) );
5978  hlpSS << "This column states the x-axis element of the symmetry element axis.";
5979  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
5980  columnIter += 1;
5981 
5982  hlpSS.str ( std::string ( ) );
5983  hlpSS << "This column states the y-axis element of the symmetry element axis.";
5984  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
5985  columnIter += 1;
5986 
5987  hlpSS.str ( std::string ( ) );
5988  hlpSS << "This column states the z-axis element of the symmetry element axis.";
5989  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
5990  columnIter += 1;
5991 
5992  hlpSS.str ( std::string ( ) );
5993  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
5994  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
5995  columnIter += 1;
5996 
5997  // ... Row headers
5998  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
5999  {
6000  std::stringstream hlpSS2;
6001  hlpSS2 << "Symmetry element #" << icoIt+1;
6002  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6003  }
6004 
6005  // ... Fill in data
6006  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->icosElems.size() ); icoIt++ )
6007  {
6008  if ( this->icosElems.at(icoIt)[0] != 1.0 )
6009  {
6010  std::stringstream hlpSS3;
6011  hlpSS3 << "C";
6012  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6013  }
6014  else
6015  {
6016  std::stringstream hlpSS3;
6017  hlpSS3 << "E";
6018  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6019  }
6020 
6021  std::stringstream hlpSS2;
6022  hlpSS2 << static_cast<int> ( this->icosElems.at(icoIt)[0] );
6023  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
6024 
6025  hlpSS2.str ( std::string ( ) );
6026  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[1], prec );
6027  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
6028 
6029  hlpSS2.str ( std::string ( ) );
6030  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[2], prec );
6031  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
6032 
6033  hlpSS2.str ( std::string ( ) );
6034  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[3], prec );
6035  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
6036 
6037  hlpSS2.str ( std::string ( ) );
6038  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->icosElems.at(icoIt)[4], prec );
6039  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
6040  }
6041 
6042  rvapi_flush ( );
6043  }
6044  else
6045  {
6046  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->octaElems.size() ) == 0 ) )
6047  {
6048  //==================================== State result
6049  std::stringstream hlpSS;
6050  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>";
6051  rvapi_set_text ( hlpSS.str().c_str(),
6052  "ResultsSection",
6053  0,
6054  0,
6055  1,
6056  1 );
6057  rvapi_flush ( );
6058  }
6059 
6060  if ( ( static_cast<unsigned int> ( this->octaSymm.size() ) > 0 ) && ( settings->htmlReport ) )
6061  {
6062  //================================ State result
6063  std::stringstream hlpSS;
6064  hlpSS << "<b>" << "Detected <i>OCTAHEDRAL</i> symmetry." << "</b>";
6065  rvapi_set_text ( hlpSS.str().c_str(),
6066  "ResultsSection",
6067  1,
6068  0,
6069  1,
6070  1 );
6071  rvapi_flush ( );
6072 
6073  //================================ Symmetry axes table
6074  rvapi_add_table ( "SymmetryTypeTable",
6075  "Detected symmetry axes",
6076  "ResultsSection",
6077  2,
6078  0,
6079  static_cast<unsigned int> ( this->octaAxes.size() ),
6080  8,
6081  1 );
6082 
6083  // ... Column headers
6084  int columnIter = 0;
6085 
6086  hlpSS.str ( std::string ( ) );
6087  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6088  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6089  columnIter += 1;
6090 
6091  hlpSS.str ( std::string ( ) );
6092  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6093  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6094  columnIter += 1;
6095 
6096  hlpSS.str ( std::string ( ) );
6097  hlpSS << "This column states the x-axis element of the symmetry axis.";
6098  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6099  columnIter += 1;
6100 
6101  hlpSS.str ( std::string ( ) );
6102  hlpSS << "This column states the y-axis element of the symmetry axis.";
6103  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6104  columnIter += 1;
6105 
6106  hlpSS.str ( std::string ( ) );
6107  hlpSS << "This column states the z-axis element of the symmetry axis.";
6108  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6109  columnIter += 1;
6110 
6111  hlpSS.str ( std::string ( ) );
6112  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6113  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6114  columnIter += 1;
6115 
6116  hlpSS.str ( std::string ( ) );
6117  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.";
6118  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6119  columnIter += 1;
6120 
6121  // ... Row headers
6122  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
6123  {
6124  std::stringstream hlpSS2;
6125  hlpSS2 << "Symmetry axis #" << icoIt+1;
6126  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
6127  }
6128 
6129  // ... Fill in data
6130  int prec = 4;
6131  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaAxes.size() ); icoIt++ )
6132  {
6133  std::stringstream hlpSS2;
6134  hlpSS2 << "C";
6135  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6136 
6137  hlpSS2.str ( std::string ( ) );
6138  hlpSS2 << static_cast<int> ( this->octaAxes.at(icoIt)[0] );
6139  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6140 
6141  hlpSS2.str ( std::string ( ) );
6142  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[1], prec );
6143  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6144 
6145  hlpSS2.str ( std::string ( ) );
6146  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[2], prec );
6147  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6148 
6149  hlpSS2.str ( std::string ( ) );
6150  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[3], prec );
6151  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6152 
6153  hlpSS2.str ( std::string ( ) );
6154  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 );
6155  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6156 
6157  hlpSS2.str ( std::string ( ) );
6158  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaAxes.at(icoIt)[4], prec );
6159  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6160  }
6161 
6162  //================================ Symmetry elements table
6163  rvapi_add_table ( "SymmetryElementsTable",
6164  "Detected symmetry elements",
6165  "ResultsSection",
6166  static_cast<unsigned int> ( this->octaAxes.size() ) + 2,
6167  0,
6168  static_cast<unsigned int> ( this->octaElems.size() ),
6169  7,
6170  -1 );
6171  totTabRows = static_cast<unsigned int> ( this->octaAxes.size() ) + 2 + static_cast<unsigned int> ( this->octaElems.size() );
6172 
6173  // ... Column headers
6174  columnIter = 0;
6175 
6176  hlpSS.str ( std::string ( ) );
6177  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6178  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6179  columnIter += 1;
6180 
6181  hlpSS.str ( std::string ( ) );
6182  hlpSS << "This column states the symmetry element fold.";
6183  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6184  columnIter += 1;
6185 
6186  hlpSS.str ( std::string ( ) );
6187  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6188  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6189  columnIter += 1;
6190 
6191  hlpSS.str ( std::string ( ) );
6192  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6193  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6194  columnIter += 1;
6195 
6196  hlpSS.str ( std::string ( ) );
6197  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6198  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6199  columnIter += 1;
6200 
6201  hlpSS.str ( std::string ( ) );
6202  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6203  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6204  columnIter += 1;
6205 
6206  // ... Row headers
6207  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
6208  {
6209  std::stringstream hlpSS2;
6210  hlpSS2 << "Symmetry element #" << icoIt+1;
6211  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6212  }
6213 
6214  // ... Fill in data
6215  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->octaElems.size() ); icoIt++ )
6216  {
6217  if ( this->octaElems.at(icoIt)[0] != 1.0 )
6218  {
6219  std::stringstream hlpSS3;
6220  hlpSS3 << "C";
6221  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6222  }
6223  else
6224  {
6225  std::stringstream hlpSS3;
6226  hlpSS3 << "E";
6227  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 0 );
6228  }
6229 
6230  std::stringstream hlpSS2;
6231  hlpSS2 << static_cast<int> ( this->octaElems.at(icoIt)[0] );
6232  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 1 );
6233 
6234  hlpSS2.str ( std::string ( ) );
6235  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[1], prec );
6236  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 2 );
6237 
6238  hlpSS2.str ( std::string ( ) );
6239  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[2], prec );
6240  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 3 );
6241 
6242  hlpSS2.str ( std::string ( ) );
6243  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[3], prec );
6244  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 4 );
6245 
6246  hlpSS2.str ( std::string ( ) );
6247  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->octaElems.at(icoIt)[4], prec );
6248  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 5 );
6249  }
6250 
6251  rvapi_flush ( );
6252  }
6253  else
6254  {
6255  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) == 0 ) )
6256  {
6257  //==================================== State result
6258  std::stringstream hlpSS;
6259  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>";
6260  rvapi_set_text ( hlpSS.str().c_str(),
6261  "ResultsSection",
6262  0,
6263  0,
6264  1,
6265  1 );
6266  rvapi_flush ( );
6267  }
6268 
6269 
6270  if ( ( static_cast<unsigned int> ( this->tetrSymm.size() ) > 0 ) && ( settings->htmlReport ) && ( static_cast<unsigned int> ( this->tetrElems.size() ) > 0 ) )
6271  {
6272  //============================ State result
6273  std::stringstream hlpSS;
6274  hlpSS << "<b>" << "Detected <i>TETRAHEDRAL</i> symmetry." << "</b>";
6275  rvapi_set_text ( hlpSS.str().c_str(),
6276  "ResultsSection",
6277  1,
6278  0,
6279  1,
6280  1 );
6281  rvapi_flush ( );
6282 
6283  //============================ Symmetry axes table
6284  rvapi_add_table ( "SymmetryTypeTable",
6285  "Detected symmetry axes",
6286  "ResultsSection",
6287  2,
6288  0,
6289  static_cast<unsigned int> ( this->tetrAxes.size() ),
6290  8,
6291  1 );
6292 
6293  // ... Column headers
6294  int columnIter = 0;
6295 
6296  hlpSS.str ( std::string ( ) );
6297  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6298  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6299  columnIter += 1;
6300 
6301  hlpSS.str ( std::string ( ) );
6302  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6303  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6304  columnIter += 1;
6305 
6306  hlpSS.str ( std::string ( ) );
6307  hlpSS << "This column states the x-axis element of the symmetry axis.";
6308  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6309  columnIter += 1;
6310 
6311  hlpSS.str ( std::string ( ) );
6312  hlpSS << "This column states the y-axis element of the symmetry axis.";
6313  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6314  columnIter += 1;
6315 
6316  hlpSS.str ( std::string ( ) );
6317  hlpSS << "This column states the z-axis element of the symmetry axis.";
6318  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6319  columnIter += 1;
6320 
6321  hlpSS.str ( std::string ( ) );
6322  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6323  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6324  columnIter += 1;
6325 
6326  hlpSS.str ( std::string ( ) );
6327  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.";
6328  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6329  columnIter += 1;
6330 
6331  // ... Row headers
6332  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
6333  {
6334  std::stringstream hlpSS2;
6335  hlpSS2 << "Symmetry axis #" << icoIt+1;
6336  rvapi_put_vert_theader ( "SymmetryTypeTable", hlpSS2.str().c_str(), "", icoIt );
6337  }
6338 
6339  // ... Fill in data
6340  int prec = 4;
6341  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrAxes.size() ); icoIt++ )
6342  {
6343  std::stringstream hlpSS2;
6344  hlpSS2 << "C";
6345  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6346 
6347  hlpSS2.str ( std::string ( ) );
6348  hlpSS2 << static_cast<int> ( this->tetrAxes.at(icoIt)[0] );
6349  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6350 
6351  hlpSS2.str ( std::string ( ) );
6352  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[1], prec );
6353  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6354 
6355  hlpSS2.str ( std::string ( ) );
6356  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[2], prec );
6357  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6358 
6359  hlpSS2.str ( std::string ( ) );
6360  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[3], prec );
6361  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6362 
6363  hlpSS2.str ( std::string ( ) );
6364  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 );
6365  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6366 
6367  hlpSS2.str ( std::string ( ) );
6368  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrAxes.at(icoIt)[4], prec );
6369  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6370  }
6371 
6372  //============================ Symmetry elements table
6373  rvapi_add_table ( "SymmetryElementsTable",
6374  "Detected symmetry elements",
6375  "ResultsSection",
6376  static_cast<unsigned int> ( this->tetrAxes.size() ) + 2,
6377  0,
6378  static_cast<unsigned int> ( this->tetrElems.size() ),
6379  7,
6380  -1 );
6381  totTabRows = static_cast<unsigned int> ( this->tetrAxes.size() ) + 2 + static_cast<unsigned int> ( this->tetrElems.size() );
6382 
6383  // ... Column headers
6384  columnIter = 0;
6385 
6386  hlpSS.str ( std::string ( ) );
6387  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6388  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6389  columnIter += 1;
6390 
6391  hlpSS.str ( std::string ( ) );
6392  hlpSS << "This column states the symmetry element fold.";
6393  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6394  columnIter += 1;
6395 
6396  hlpSS.str ( std::string ( ) );
6397  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6398  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6399  columnIter += 1;
6400 
6401  hlpSS.str ( std::string ( ) );
6402  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6403  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6404  columnIter += 1;
6405 
6406  hlpSS.str ( std::string ( ) );
6407  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6408  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6409  columnIter += 1;
6410 
6411  hlpSS.str ( std::string ( ) );
6412  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6413  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6414  columnIter += 1;
6415 
6416  // ... Row headers
6417  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
6418  {
6419  std::stringstream hlpSS2;
6420  hlpSS2 << "Symmetry element #" << icoIt+1;
6421  rvapi_put_vert_theader ( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6422  }
6423 
6424  // ... Fill in data
6425  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->tetrElems.size() ); icoIt++ )
6426  {
6427  std::stringstream hlpSS3;
6428  if ( this->tetrElems.at(icoIt)[0] != 1.0 )
6429  {
6430  std::stringstream hlpSS2;
6431  hlpSS2 << "C";
6432  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
6433  }
6434  else
6435  {
6436  std::stringstream hlpSS2;
6437  hlpSS2 << "E";
6438  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), icoIt, 0 );
6439  }
6440 
6441  hlpSS3.str ( std::string ( ) );
6442  hlpSS3 << static_cast<int> ( this->tetrElems.at(icoIt)[0] );
6443  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 1 );
6444 
6445  hlpSS3.str ( std::string ( ) );
6446  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[1], prec );
6447  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 2 );
6448 
6449  hlpSS3.str ( std::string ( ) );
6450  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[2], prec );
6451  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 3 );
6452 
6453  hlpSS3.str ( std::string ( ) );
6454  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[3], prec );
6455  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 4 );
6456 
6457  hlpSS3.str ( std::string ( ) );
6458  hlpSS3 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->tetrElems.at(icoIt)[4], prec );
6459  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS3.str().c_str(), icoIt, 5 );
6460  }
6461 
6462  rvapi_flush ( );
6463  }
6464  else
6465  {
6466  if ( ( static_cast<unsigned int> ( this->dnSymmClear.size() ) > 0 ) && ( settings->htmlReport ) )
6467  {
6468  //======================== State result
6469  std::stringstream hlpSS;
6470  hlpSS << "<b>" << "Detected <i>DIHEDRAL</i> symmetry." << "</b>";
6471  rvapi_set_text ( hlpSS.str().c_str(),
6472  "ResultsSection",
6473  1,
6474  0,
6475  1,
6476  1 );
6477  rvapi_flush ( );
6478 
6479  //======================== Symmetry axes table
6480  rvapi_add_table ( "SymmetryTypeTable",
6481  "Detected symmetry axes",
6482  "ResultsSection",
6483  2,
6484  0,
6485  3,
6486  8,
6487  1 );
6488 
6489  // ... Column headers
6490  int columnIter = 0;
6491 
6492  hlpSS.str ( std::string ( ) );
6493  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6494  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6495  columnIter += 1;
6496 
6497  hlpSS.str ( std::string ( ) );
6498  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6499  rvapi_put_horz_theader ( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6500  columnIter += 1;
6501 
6502  hlpSS.str ( std::string ( ) );
6503  hlpSS << "This column states the x-axis element of the symmetry axis.";
6504  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6505  columnIter += 1;
6506 
6507  hlpSS.str ( std::string ( ) );
6508  hlpSS << "This column states the y-axis element of the symmetry axis.";
6509  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6510  columnIter += 1;
6511 
6512  hlpSS.str ( std::string ( ) );
6513  hlpSS << "This column states the z-axis element of the symmetry axis.";
6514  rvapi_put_horz_theader ( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6515  columnIter += 1;
6516 
6517  hlpSS.str ( std::string ( ) );
6518  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6519  rvapi_put_horz_theader ( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6520  columnIter += 1;
6521 
6522  hlpSS.str ( std::string ( ) );
6523  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.";
6524  rvapi_put_horz_theader ( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6525  columnIter += 1;
6526 
6527  // ... Row headers
6528  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymmClear.at(0).size() ); icoIt++ )
6529  {
6530  hlpSS.str ( std::string ( ) );
6531  hlpSS << "Symmetry axis #" << icoIt+1;
6532  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", icoIt );
6533  }
6534 
6535  // ... Fill in data
6536  int prec = 4;
6537  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( this->dnSymmClear.at(0).size() ); icoIt++ )
6538  {
6539  std::stringstream hlpSS2;
6540  hlpSS2 << "C";
6541  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 0 );
6542 
6543  hlpSS2.str ( std::string ( ) );
6544  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(icoIt)[0] );
6545  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 1 );
6546 
6547  hlpSS2.str ( std::string ( ) );
6548  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[1], prec );
6549  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 2 );
6550 
6551  hlpSS2.str ( std::string ( ) );
6552  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[2], prec );
6553  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 3 );
6554 
6555  hlpSS2.str ( std::string ( ) );
6556  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[3], prec );
6557  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 4 );
6558 
6559  hlpSS2.str ( std::string ( ) );
6560  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 );
6561  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 5 );
6562 
6563  hlpSS2.str ( std::string ( ) );
6564  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(icoIt)[4], prec );
6565  rvapi_put_table_string( "SymmetryTypeTable", hlpSS2.str().c_str(), icoIt, 6 );
6566  }
6567 
6568  //======================== Symmetry elements table
6569  int totRows = 0;
6570  for ( unsigned int it = 0; it < 2; it++ )
6571  {
6572  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
6573  {
6574  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++ )
6575  {
6576  if ( iter == 0 ) { continue; }
6577  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
6578 
6579  totRows += 1;
6580  }
6581  }
6582  else
6583  {
6584  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++ )
6585  {
6586  if ( iter == 0 ) { continue; }
6587 
6588  totRows += 1;
6589  }
6590  }
6591  }
6592  totRows += 1;
6593  totTabRows = static_cast<unsigned int> ( totRows ) + 6;
6594 
6595  rvapi_add_table ( "SymmetryElementsTable",
6596  "Detected symmetry elements",
6597  "ResultsSection",
6598  6,
6599  0,
6600  totRows,
6601  7,
6602  -1 );
6603 
6604  // ... Column headers
6605  columnIter = 0;
6606 
6607  hlpSS.str ( std::string ( ) );
6608  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6609  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6610  columnIter += 1;
6611 
6612  hlpSS.str ( std::string ( ) );
6613  hlpSS << "This column states the symmetry element fold.";
6614  rvapi_put_horz_theader ( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6615  columnIter += 1;
6616 
6617  hlpSS.str ( std::string ( ) );
6618  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6619  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6620  columnIter += 1;
6621 
6622  hlpSS.str ( std::string ( ) );
6623  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6624  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6625  columnIter += 1;
6626 
6627  hlpSS.str ( std::string ( ) );
6628  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6629  rvapi_put_horz_theader ( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6630  columnIter += 1;
6631 
6632  hlpSS.str ( std::string ( ) );
6633  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6634  rvapi_put_horz_theader ( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6635  columnIter += 1;
6636 
6637  // ... Row headers
6638  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
6639  {
6640  std::stringstream hlpSS2;
6641  hlpSS2 << "Symmetry element #" << icoIt+1;
6642  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6643  }
6644 
6645  // ... Fill in data
6646  int rowCount = 1;
6647 
6648  hlpSS.str ( std::string ( ) );
6649  hlpSS << "E";
6650  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
6651 
6652  hlpSS.str ( std::string ( ) );
6653  hlpSS << static_cast<int> ( 1 );
6654  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
6655 
6656  hlpSS.str ( std::string ( ) );
6657  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
6658  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
6659 
6660  hlpSS.str ( std::string ( ) );
6661  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6662  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
6663 
6664  hlpSS.str ( std::string ( ) );
6665  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6666  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
6667 
6668  hlpSS.str ( std::string ( ) );
6669  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6670  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
6671 
6672  for ( unsigned int it = 0; it < 2; it++ )
6673  {
6674  if ( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) % 2 == 0 )
6675  {
6676  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++ )
6677  {
6678  if ( iter == 0 ) { continue; }
6679  if ( iter == -std::ceil( static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
6680 
6681  std::stringstream hlpSS2;
6682  hlpSS2 << "C";
6683  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
6684 
6685  hlpSS2.str ( std::string ( ) );
6686  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] );
6687  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
6688 
6689  hlpSS2.str ( std::string ( ) );
6690  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[1], prec );
6691  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
6692 
6693  hlpSS2.str ( std::string ( ) );
6694  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[2], prec );
6695  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
6696 
6697  hlpSS2.str ( std::string ( ) );
6698  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[3], prec );
6699  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
6700 
6701  hlpSS2.str ( std::string ( ) );
6702  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 );
6703  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
6704  rowCount += 1;
6705  }
6706  }
6707  else
6708  {
6709  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++ )
6710  {
6711  if ( iter == 0 ) { continue; }
6712 
6713  std::stringstream hlpSS2;
6714  hlpSS2 << "C";
6715  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 0 );
6716 
6717  hlpSS2.str ( std::string ( ) );
6718  hlpSS2 << static_cast<int> ( this->dnSymmClear.at(0).at(it)[0] );
6719  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 1 );
6720 
6721  hlpSS2.str ( std::string ( ) );
6722  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[1], prec );
6723  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 2 );
6724 
6725  hlpSS2.str ( std::string ( ) );
6726  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[2], prec );
6727  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 3 );
6728 
6729  hlpSS2.str ( std::string ( ) );
6730  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymmClear.at(0).at(it)[3], prec );
6731  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 4 );
6732 
6733  hlpSS2.str ( std::string ( ) );
6734  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 );
6735  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS2.str().c_str(), rowCount, 5 );
6736  rowCount += 1;
6737  }
6738  }
6739  }
6740 
6741  rvapi_flush ( );
6742  }
6743  else
6744  {
6745  if ( ( static_cast<unsigned int> ( this->cnSymmClear.size() ) > 0 ) && ( settings->htmlReport ) )
6746  {
6747  //==================== State result
6748  std::stringstream hlpSS;
6749  hlpSS << "<b>" << "Detected <i>CYCLIC</i> symmetry." << "</b>";
6750  rvapi_set_text ( hlpSS.str().c_str(),
6751  "ResultsSection",
6752  1,
6753  0,
6754  1,
6755  1 );
6756  rvapi_flush ( );
6757 
6758  //==================== Symmetry axes table
6759  rvapi_add_table ( "SymmetryTypeTable",
6760  "Detected symmetry axes",
6761  "ResultsSection",
6762  2,
6763  0,
6764  3,
6765  8,
6766  2 );
6767 
6768  // ... Column headers
6769  int columnIter = 0;
6770 
6771  hlpSS.str ( std::string ( ) );
6772  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D; Tetrahedral = T; Octahedral = O; Icosahedral = I).";
6773  rvapi_put_horz_theader( "SymmetryTypeTable", "Symmetry type", hlpSS.str().c_str(), columnIter );
6774  columnIter += 1;
6775 
6776  hlpSS.str ( std::string ( ) );
6777  hlpSS << "This column states the symmetry fold; this is only interesting for Cyclic and Dihedral symmetries.";
6778  rvapi_put_horz_theader( "SymmetryTypeTable", "Symmetry fold", hlpSS.str().c_str(), columnIter );
6779  columnIter += 1;
6780 
6781  hlpSS.str ( std::string ( ) );
6782  hlpSS << "This column states the x-axis element of the symmetry axis.";
6783  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6784  columnIter += 1;
6785 
6786  hlpSS.str ( std::string ( ) );
6787  hlpSS << "This column states the y-axis element of the symmetry axis.";
6788  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6789  columnIter += 1;
6790 
6791  hlpSS.str ( std::string ( ) );
6792  hlpSS << "This column states the z-axis element of the symmetry axis.";
6793  rvapi_put_horz_theader( "SymmetryTypeTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6794  columnIter += 1;
6795 
6796  hlpSS.str ( std::string ( ) );
6797  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
6798  rvapi_put_horz_theader( "SymmetryTypeTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6799  columnIter += 1;
6800 
6801  hlpSS.str ( std::string ( ) );
6802  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.";
6803  rvapi_put_horz_theader( "SymmetryTypeTable", "Peak height", hlpSS.str().c_str(), columnIter );
6804  columnIter += 1;
6805 
6806  // ... Row headers
6807  hlpSS.str ( std::string ( ) );
6808  hlpSS << "Symmetry axis #" << 1;
6809  rvapi_put_vert_theader( "SymmetryTypeTable", hlpSS.str().c_str(), "", 0 );
6810 
6811  // ... Fill in data
6812  int prec = 4;
6813  hlpSS.str ( std::string ( ) );
6814  hlpSS << "C";
6815  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 0 );
6816 
6817  hlpSS.str ( std::string ( ) );
6818  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
6819  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 1 );
6820 
6821  hlpSS.str ( std::string ( ) );
6822  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
6823  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 2 );
6824 
6825  hlpSS.str ( std::string ( ) );
6826  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
6827  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 3 );
6828 
6829  hlpSS.str ( std::string ( ) );
6830  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
6831  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 4 );
6832 
6833  hlpSS.str ( std::string ( ) );
6834  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 );
6835  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 5 );
6836 
6837  hlpSS.str ( std::string ( ) );
6838  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[4], prec );
6839  rvapi_put_table_string ( "SymmetryTypeTable", hlpSS.str().c_str(), 0, 6 );
6840 
6841  //==================== Symmetry elements table
6842  int totRows = 0;
6843  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
6844  {
6845  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++ )
6846  {
6847  if ( iter == 0 ) { continue; }
6848  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
6849 
6850  totRows += 1;
6851  }
6852  }
6853  else
6854  {
6855  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++ )
6856  {
6857  if ( iter == 0 ) { continue; }
6858 
6859  totRows += 1;
6860  }
6861  }
6862  totRows += 1;
6863  totTabRows = static_cast<unsigned int> ( totRows ) + 5;
6864 
6865  rvapi_add_table ( "SymmetryElementsTable",
6866  "Detected symmetry elements",
6867  "ResultsSection",
6868  5,
6869  0,
6870  totRows,
6871  7,
6872  -1 );
6873 
6874  // ... Column headers
6875  columnIter = 0;
6876 
6877  hlpSS.str ( std::string ( ) );
6878  hlpSS << "This column states the symmetry element type (Cyclic = C; Identity = E).";
6879  rvapi_put_horz_theader( "SymmetryElementsTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
6880  columnIter += 1;
6881 
6882  hlpSS.str ( std::string ( ) );
6883  hlpSS << "This column states the symmetry element fold.";
6884  rvapi_put_horz_theader( "SymmetryElementsTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
6885  columnIter += 1;
6886 
6887  hlpSS.str ( std::string ( ) );
6888  hlpSS << "This column states the x-axis element of the symmetry element axis.";
6889  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
6890  columnIter += 1;
6891 
6892  hlpSS.str ( std::string ( ) );
6893  hlpSS << "This column states the y-axis element of the symmetry element axis.";
6894  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
6895  columnIter += 1;
6896 
6897  hlpSS.str ( std::string ( ) );
6898  hlpSS << "This column states the z-axis element of the symmetry element axis.";
6899  rvapi_put_horz_theader( "SymmetryElementsTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
6900  columnIter += 1;
6901 
6902  hlpSS.str ( std::string ( ) );
6903  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry element axis in degrees.";
6904  rvapi_put_horz_theader( "SymmetryElementsTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
6905  columnIter += 1;
6906 
6907  // ... Row headers
6908  for ( unsigned int icoIt = 0; icoIt < static_cast<unsigned int> ( totRows ); icoIt++ )
6909  {
6910  std::stringstream hlpSS2;
6911  hlpSS2 << "Symmetry element #" << std::to_string ( icoIt+1 );
6912  rvapi_put_vert_theader( "SymmetryElementsTable", hlpSS2.str().c_str(), "", icoIt );
6913  }
6914 
6915  // ... Fill in data
6916  int rowCount = 1;
6917 
6918  hlpSS.str ( std::string ( ) );
6919  hlpSS << "E";
6920  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 0 );
6921 
6922  hlpSS.str ( std::string ( ) );
6923  hlpSS << static_cast<int> ( 1 );
6924  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 1 );
6925 
6926  hlpSS.str ( std::string ( ) );
6927  hlpSS << std::setprecision ( prec ) << std::showpos << 1;
6928  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 2 );
6929 
6930  hlpSS.str ( std::string ( ) );
6931  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6932  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 3 );
6933 
6934  hlpSS.str ( std::string ( ) );
6935  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6936  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 4 );
6937 
6938  hlpSS.str ( std::string ( ) );
6939  hlpSS << std::setprecision ( prec ) << std::showpos << 0;
6940  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), 0, 5 );
6941 
6942  if ( static_cast<int> ( this->cnSymmClear.at(0)[0] ) % 2 == 0 )
6943  {
6944  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++ )
6945  {
6946  if ( iter == 0 ) { continue; }
6947  if ( iter == -std::ceil( static_cast<int> ( this->cnSymmClear.at(0)[0] ) / 2.0 ) ) { continue; }
6948 
6949  hlpSS.str ( std::string ( ) );
6950  hlpSS << "C";
6951  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
6952 
6953  hlpSS.str ( std::string ( ) );
6954  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
6955  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
6956 
6957  hlpSS.str ( std::string ( ) );
6958  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
6959  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
6960 
6961  hlpSS.str ( std::string ( ) );
6962  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
6963  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
6964 
6965  hlpSS.str ( std::string ( ) );
6966  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
6967  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
6968 
6969  hlpSS.str ( std::string ( ) );
6970  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 );
6971  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
6972  rowCount += 1;
6973  }
6974  }
6975  else
6976  {
6977  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++ )
6978  {
6979  if ( iter == 0 ) { continue; }
6980 
6981  hlpSS.str ( std::string ( ) );
6982  hlpSS << "C";
6983  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 0 );
6984 
6985  hlpSS.str ( std::string ( ) );
6986  hlpSS << static_cast<int> ( this->cnSymmClear.at(0)[0] );
6987  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 1 );
6988 
6989  hlpSS.str ( std::string ( ) );
6990  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[1], prec );
6991  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 2 );
6992 
6993  hlpSS.str ( std::string ( ) );
6994  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[2], prec );
6995  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 3 );
6996 
6997  hlpSS.str ( std::string ( ) );
6998  hlpSS << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymmClear.at(0)[3], prec );
6999  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 4 );
7000 
7001  hlpSS.str ( std::string ( ) );
7002  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 );
7003  rvapi_put_table_string ( "SymmetryElementsTable", hlpSS.str().c_str(), rowCount, 5 );
7004  rowCount += 1;
7005  }
7006  }
7007 
7008  rvapi_flush ( );
7009  }
7010  else
7011  {
7012  printf ( "Detected no symmetry.\n\n" );
7013  }
7014  }
7015  }
7016  }
7017  }
7018 
7019  //======================================== Print alternatives
7020  rvapi_add_table ( "AlternativesTable",
7021  "Alternative Symmetries Detected",
7022  "ResultsSection",
7023  totTabRows,
7024  0,
7025  static_cast<unsigned int> ( this->cnSymm.size() ) + static_cast<unsigned int> ( this->dnSymm.size() ),
7026  7,
7027  -1 );
7028 
7029  // ... Column headers
7030  int columnIter = 0;
7031 
7032  std::stringstream hlpSS;
7033  hlpSS << "This column states the symmetry type (Cyclic = C; Dihedral = D).";
7034  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element type", hlpSS.str().c_str(), columnIter );
7035  columnIter += 1;
7036 
7037  hlpSS.str ( std::string ( ) );
7038  hlpSS << "This column states the symmetry fold.";
7039  rvapi_put_horz_theader ( "AlternativesTable", "Symmetry element fold", hlpSS.str().c_str(), columnIter );
7040  columnIter += 1;
7041 
7042  hlpSS.str ( std::string ( ) );
7043  hlpSS << "This column states the x-axis element of the symmetry axis.";
7044  rvapi_put_horz_theader ( "AlternativesTable", "<i>X</i>-axis element", hlpSS.str().c_str(), columnIter );
7045  columnIter += 1;
7046 
7047  hlpSS.str ( std::string ( ) );
7048  hlpSS << "This column states the y-axis element of the symmetry axis.";
7049  rvapi_put_horz_theader ( "AlternativesTable", "<i>Y</i>-axis element", hlpSS.str().c_str(), columnIter );
7050  columnIter += 1;
7051 
7052  hlpSS.str ( std::string ( ) );
7053  hlpSS << "This column states the z-axis element of the symmetry axis.";
7054  rvapi_put_horz_theader ( "AlternativesTable", "<i>Z</i>-axis element", hlpSS.str().c_str(), columnIter );
7055  columnIter += 1;
7056 
7057  hlpSS.str ( std::string ( ) );
7058  hlpSS << "This column states the angle (in the sense of the angle-axis representation) of the symmetry axis in degrees.";
7059  rvapi_put_horz_theader ( "AlternativesTable", "Angle (degrees)", hlpSS.str().c_str(), columnIter );
7060  columnIter += 1;
7061 
7062  hlpSS.str ( std::string ( ) );
7063  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.";
7064  rvapi_put_horz_theader ( "AlternativesTable", "Peak Height", hlpSS.str().c_str(), columnIter );
7065  columnIter += 1;
7066 
7067  // ... Row headers
7068  int maxCAlts = 0;
7069  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
7070  {
7071  std::stringstream hlpSS2;
7072  hlpSS2 << "Alternative Symmetry #" << gNo+1;
7073  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", gNo );
7074  maxCAlts = gNo;
7075  }
7076  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
7077  {
7078  std::stringstream hlpSS2;
7079  hlpSS2 << "Alternative Symmetry #" << iter + maxCAlts + 2;
7080  rvapi_put_vert_theader ( "AlternativesTable", hlpSS2.str().c_str(), "Reported symmetry alternative (i.e. also detected, but with lower reliability)", iter + maxCAlts + 1 );
7081  }
7082 
7083  int rowCount = 0;
7084  int prec = 4;
7085  for ( unsigned int gNo = 0; gNo < static_cast<unsigned int> ( this->cnSymm.size() ); gNo++ )
7086  {
7087  std::stringstream hlpSS2;
7088  hlpSS2 << "C";
7089  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
7090 
7091  hlpSS2.str ( std::string ( ) );
7092  hlpSS2 << static_cast<int> ( static_cast<int> ( this->cnSymm.at(gNo)[0] ) );
7093  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
7094 
7095  hlpSS2.str ( std::string ( ) );
7096  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[1], prec );
7097  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
7098 
7099  hlpSS2.str ( std::string ( ) );
7100  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[2], prec );
7101  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
7102 
7103  hlpSS2.str ( std::string ( ) );
7104  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->cnSymm.at(gNo)[3], prec );
7105  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
7106 
7107  hlpSS2.str ( std::string ( ) );
7108  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 );
7109  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
7110 
7111  hlpSS2.str ( std::string ( ) );
7112  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->cnSymm.at(gNo)[4] ), prec );
7113  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
7114  rowCount += 1;
7115  }
7116 
7117  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dnSymm.size() ); iter++ )
7118  {
7119  std::stringstream hlpSS2;
7120  hlpSS2 << "D";
7121  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 0 );
7122 
7123  hlpSS2.str ( std::string ( ) );
7124  hlpSS2 << static_cast<int> ( static_cast<int> ( this->dnSymm.at(iter).at(0)[0] ) );
7125  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 1 );
7126 
7127  hlpSS2.str ( std::string ( ) );
7128  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[1], prec );
7129  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 2 );
7130 
7131  hlpSS2.str ( std::string ( ) );
7132  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[2], prec );
7133  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 3 );
7134 
7135  hlpSS2.str ( std::string ( ) );
7136  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( this->dnSymm.at(iter).at(0)[3], prec );
7137  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 4 );
7138 
7139  hlpSS2.str ( std::string ( ) );
7140  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 );
7141  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 5 );
7142 
7143  hlpSS2.str ( std::string ( ) );
7144  hlpSS2 << std::setprecision ( prec ) << std::showpos << ProSHADE_internal_misc::to_string_with_precision ( static_cast<double> ( this->dnSymm.at(iter).at(0)[4] ), prec );
7145  rvapi_put_table_string ( "AlternativesTable", hlpSS2.str().c_str(), rowCount, 6 );
7146  rowCount += 1;
7147  }
7148  rvapi_flush ( );
7149 
7150  //======================================== Done
7151  return ;
7152 
7153 }
7154 
7176 std::vector< std::array<double,8> > ProSHADE_internal::ProSHADE_symmetry::getRotFnPeaks ( )
7177 {
7178  //======================================== Return
7179  return ( this->rfPeaks );
7180 
7181 }
7182 
7199 std::vector< std::array<double,5> > ProSHADE_internal::ProSHADE_symmetry::getCSymmetries ( )
7200 {
7201  //======================================== Return
7202  return ( this->cnSymm );
7203 
7204 }
7205 
7224 std::vector< std::vector< std::array<double,6> > > ProSHADE_internal::ProSHADE_symmetry::getDSymmetries ( )
7225 {
7226  //======================================== Return
7227  return ( this->dnSymm );
7228 
7229 }
7230 
7243 {
7244  //======================================== Initialise pointers
7245  this->cmpObj = nullptr;
7246 
7247  //======================================== If this is called only to save database, redirect to the proper function and quit
7248  if ( settings->taskToPerform == ProSHADE::BuildDB )
7249  {
7250  //==================================== Report progress
7251  if ( settings->verbose > 0 )
7252  {
7253  std::cout << "-----------------------------------------------------------" << std::endl;
7254  std::cout << "| MODE: BuildDB |" << std::endl;
7255  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
7256  }
7257 
7258  this->saveDatabase ( settings );
7259 
7260  if ( settings->verbose > 0 )
7261  {
7262  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
7263  std::cout << "| COMPLETED |" << std::endl;
7264  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
7265 
7266  std::cout << "Database saved to: " << settings->databaseName << std::endl << std::endl;
7267 
7268  if ( settings->htmlReport )
7269  {
7270  std::stringstream hlpSS;
7271  hlpSS << "<font color=\"green\">" << "Database saved to " << settings->databaseName << " ." << "</font>";
7272  rvapi_set_text ( hlpSS.str().c_str(),
7273  "ProgressSection",
7274  settings->htmlReportLineProgress,
7275  1,
7276  1,
7277  1 );
7278  settings->htmlReportLineProgress += 1;
7279 
7280  rvapi_flush ( );
7281  }
7282  }
7283  return ;
7284  }
7285 
7286  //======================================== If this is called to fragment and compare one structure against database, redirect to the proper function and quit
7287  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() == 1 ) && ( settings->taskToPerform == ProSHADE::DistancesFrag ) )
7288  {
7289  //==================================== Load the database and compare
7290  compareFragAgainstDatabase ( settings, &settings->structFiles );
7291 
7292  //==================================== Save the settings
7293  this->mapResolution = settings->mapResolution;
7294  this->bandwidth = settings->bandwidth;
7295  this->glIntegOrder = settings->glIntegOrder;
7296  this->theta = settings->theta;
7297  this->phi = settings->phi;
7298  this->bFactorValue = settings->bFactorValue;
7299  this->bFactorChange = settings->bFactorChange;
7300  this->noIQRsFromMap = settings->noIQRsFromMap;
7301  this->shellSpacing = settings->shellSpacing;
7302  this->manualShells = settings->manualShells;
7303  this->useCOM = settings->useCOM;
7304  this->firstLineCOM = settings->firstLineCOM;
7305  this->extraSpace = settings->extraSpace;
7306  this->alpha = settings->alpha;
7307  this->mPower = settings->mPower;
7308  this->ignoreLs = settings->ignoreLs;
7309  this->energyLevelDist = settings->energyLevelDist;
7310  this->traceSigmaDist = settings->traceSigmaDist;
7311  this->fullRotFnDist = settings->fullRotFnDist;
7312  this->usePhase = settings->usePhase;
7313  this->saveWithAndWithout = settings->saveWithAndWithout;
7314  this->enLevelsThreshold = settings->enLevelsThreshold;
7315  this->trSigmaThreshold = settings->trSigmaThreshold;
7316  this->structFiles = settings->structFiles;
7317 
7318  //==================================== Done
7319  return ;
7320  }
7321 
7322  //======================================== If this is called to compare one structure against database, redirect to the proper function and quit
7323  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() == 1 ) )
7324  {
7325  //==================================== Load the database and compare, keeping the task value unchanged by the database reading
7326  ProSHADE::Task origTask = settings->taskToPerform;
7327  compareAgainstDatabase ( settings, &settings->structFiles );
7328 
7329  settings->taskToPerform = origTask;
7330 
7331  //==================================== Save the settings
7332  this->mapResolution = settings->mapResolution;
7333  this->bandwidth = settings->bandwidth;
7334  this->glIntegOrder = settings->glIntegOrder;
7335  this->theta = settings->theta;
7336  this->phi = settings->phi;
7337  this->bFactorValue = settings->bFactorValue;
7338  this->bFactorChange = settings->bFactorChange;
7339  this->noIQRsFromMap = settings->noIQRsFromMap;
7340  this->shellSpacing = settings->shellSpacing;
7341  this->manualShells = settings->manualShells;
7342  this->useCOM = settings->useCOM;
7343  this->firstLineCOM = settings->firstLineCOM;
7344  this->extraSpace = settings->extraSpace;
7345  this->alpha = settings->alpha;
7346  this->mPower = settings->mPower;
7347  this->ignoreLs = settings->ignoreLs;
7348  this->energyLevelDist = settings->energyLevelDist;
7349  this->traceSigmaDist = settings->traceSigmaDist;
7350  this->fullRotFnDist = settings->fullRotFnDist;
7351  this->usePhase = settings->usePhase;
7352  this->saveWithAndWithout = settings->saveWithAndWithout;
7353  this->enLevelsThreshold = settings->enLevelsThreshold;
7354  this->trSigmaThreshold = settings->trSigmaThreshold;
7355  this->structFiles = settings->structFiles;
7356 
7357  //==================================== Done
7358  return ;
7359  }
7360 
7361  //======================================== Check for ambiguity
7362  if ( ( settings->databaseName != "" ) && ( settings->structFiles.size() > 1 ) )
7363  {
7364  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;
7365 
7366  if ( settings->htmlReport )
7367  {
7368  //==================================== Record progress
7369  std::stringstream hlpSS;
7370  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>";
7371  rvapi_set_text ( hlpSS.str().c_str(),
7372  "ProgressSection",
7373  settings->htmlReportLineProgress,
7374  1,
7375  1,
7376  1 );
7377  settings->htmlReportLineProgress += 1;
7378  rvapi_flush ( );
7379  }
7380 
7381  exit ( -1 );
7382  }
7383 
7384  //======================================== Save the settings
7385  this->mapResolution = settings->mapResolution;
7386  this->bandwidth = settings->bandwidth;
7387  this->glIntegOrder = settings->glIntegOrder;
7388  this->theta = settings->theta;
7389  this->phi = settings->phi;
7390  this->bFactorValue = settings->bFactorValue;
7391  this->bFactorChange = settings->bFactorChange;
7392  this->noIQRsFromMap = settings->noIQRsFromMap;
7393  this->shellSpacing = settings->shellSpacing;
7394  this->manualShells = settings->manualShells;
7395  this->useCOM = settings->useCOM;
7396  this->firstLineCOM = settings->firstLineCOM;
7397  this->extraSpace = settings->extraSpace;
7398  this->alpha = settings->alpha;
7399  this->mPower = settings->mPower;
7400  this->ignoreLs = settings->ignoreLs;
7401  this->energyLevelDist = settings->energyLevelDist;
7402  this->traceSigmaDist = settings->traceSigmaDist;
7403  this->fullRotFnDist = settings->fullRotFnDist;
7404  this->usePhase = settings->usePhase;
7405  this->saveWithAndWithout = settings->saveWithAndWithout;
7406  this->enLevelsThreshold = settings->enLevelsThreshold;
7407  this->trSigmaThreshold = settings->trSigmaThreshold;
7408  this->structFiles = settings->structFiles;
7409 
7410  //======================================== Sanity checks
7411  if ( !this->energyLevelDist && !this->traceSigmaDist && !this->fullRotFnDist )
7412  {
7413  //==================================== No distances required
7414  std::cerr << "!!! ProSHADE ERROR !!! Initialising ProSHADE_distances object with no distances required! Terminating..." << std::endl;
7415 
7416  if ( settings->htmlReport )
7417  {
7418  //==================================== Record progress
7419  std::stringstream hlpSS;
7420  hlpSS << "<font color=\"red\">" << "There are no required distances to be computed and therefore nothing to do..." << "</font>";
7421  rvapi_set_text ( hlpSS.str().c_str(),
7422  "ProgressSection",
7423  settings->htmlReportLineProgress,
7424  1,
7425  1,
7426  1 );
7427  settings->htmlReportLineProgress += 1;
7428  rvapi_flush ( );
7429  }
7430 
7431  exit ( -1 );
7432  }
7433 
7434  if ( this->structFiles.size() < 2 )
7435  {
7436  //==================================== Not enough structures
7437  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;
7438 
7439  if ( settings->htmlReport )
7440  {
7441  //==================================== Record progress
7442  std::stringstream hlpSS;
7443  hlpSS << "<font color=\"red\">" << "There are less than two structures submitted to the distance computing functionality." << "</font>";
7444  rvapi_set_text ( hlpSS.str().c_str(),
7445  "ProgressSection",
7446  settings->htmlReportLineProgress,
7447  1,
7448  1,
7449  1 );
7450  settings->htmlReportLineProgress += 1;
7451  rvapi_flush ( );
7452  }
7453 
7454  exit ( -1 );
7455  }
7456 
7457  if ( ( this->enLevelsThreshold != -999.9 ) && ( !this->energyLevelDist ) )
7458  {
7459  //==================================== Invalid settings
7460  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;
7461 
7462  if ( settings->htmlReport )
7463  {
7464  //==================================== Record progress
7465  std::stringstream hlpSS;
7466  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>";
7467  rvapi_set_text ( hlpSS.str().c_str(),
7468  "ProgressSection",
7469  settings->htmlReportLineProgress,
7470  1,
7471  1,
7472  1 );
7473  settings->htmlReportLineProgress += 1;
7474  rvapi_flush ( );
7475  }
7476 
7477  exit ( -1 );
7478  }
7479 
7480  if ( ( this->trSigmaThreshold != -999.9 ) && ( !this->traceSigmaDist ) )
7481  {
7482  //==================================== Invalid settings
7483  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;
7484 
7485  if ( settings->htmlReport )
7486  {
7487  //==================================== Record progress
7488  std::stringstream hlpSS;
7489  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>";
7490  rvapi_set_text ( hlpSS.str().c_str(),
7491  "ProgressSection",
7492  settings->htmlReportLineProgress,
7493  1,
7494  1,
7495  1 );
7496  settings->htmlReportLineProgress += 1;
7497  rvapi_flush ( );
7498  }
7499 
7500  exit ( -1 );
7501  }
7502 
7503  if ( settings->verbose > 0 )
7504  {
7505  std::cout << "Finding distances between the structure " << settings->structFiles.at(0) << " against all other structures." << std::endl;
7506  }
7507 
7508  if ( settings->verbose > 3 )
7509  {
7510  std::cout << ">>>>>>>> Sanity checks passed." << std::endl;
7511  }
7512 
7513  if ( settings->htmlReport )
7514  {
7515  //==================================== Record progress
7516  std::stringstream hlpSS;
7517  hlpSS << "<font color=\"green\">" << "Sanity checks passed" << "</font>";
7518  rvapi_set_text ( hlpSS.str().c_str(),
7519  "ProgressSection",
7520  settings->htmlReportLineProgress,
7521  1,
7522  1,
7523  1 );
7524  settings->htmlReportLineProgress += 1;
7525  rvapi_flush ( );
7526  }
7527 
7528  if ( settings->htmlReport )
7529  {
7530  //==================================== Create section
7531  rvapi_add_section ( "InputFilesSection",
7532  "List of input structures",
7533  "body",
7534  settings->htmlReportLine-1,
7535  0,
7536  1,
7537  1,
7538  false );
7539  settings->htmlReportLine += 1;
7540  rvapi_flush();
7541 
7542  // Record structure 0
7543  std::stringstream hlpSS;
7544  hlpSS << "<b>" << settings->structFiles.at(0) << "</b>";
7545  rvapi_set_text ( hlpSS.str().c_str(),
7546  "InputFilesSection",
7547  0,
7548  1,
7549  1,
7550  1 );
7551 
7552  for ( unsigned int vecIt = 1; vecIt < static_cast<unsigned int> ( this->structFiles.size() ); vecIt++ )
7553  {
7554  hlpSS.str ( std::string ( ) );
7555  hlpSS << settings->structFiles.at(vecIt);
7556  rvapi_set_text ( hlpSS.str().c_str(),
7557  "InputFilesSection",
7558  vecIt,
7559  1,
7560  1,
7561  1 );
7562  }
7563 
7564 
7565  rvapi_flush ( );
7566  }
7567 
7568  //======================================== Initialise vectors
7569  this->bandwidthVec = std::vector<unsigned int> ( this->structFiles.size(), this->bandwidth );
7570  this->thetaVec = std::vector<unsigned int> ( this->structFiles.size(), this->theta );
7571  this->phiVec = std::vector<unsigned int> ( this->structFiles.size(), this->phi );
7572  this->glIntegOrderVec = std::vector<unsigned int> ( this->structFiles.size(), this->glIntegOrder );
7573  this->extraSpaceVec = std::vector<double> ( this->structFiles.size(), this->extraSpace );
7574 
7575  //======================================== Create the one object to compare everything else against
7576  ProSHADE_data* one = new ProSHADE_data ();
7577 
7578  //======================================== Read in the structure into one
7579  unsigned int fileType = checkFileType ( structFiles.at(0) );
7580  if ( fileType == 2 )
7581  {
7582  one->getDensityMapFromMAP ( this->structFiles.at(0),
7583  &this->shellSpacing,
7584  this->mapResolution,
7585  &this->bandwidthVec.at(0),
7586  &this->thetaVec.at(0),
7587  &this->phiVec.at(0),
7588  &this->glIntegOrderVec.at(0),
7589  &this->extraSpaceVec.at(0),
7590  settings->mapResDefault,
7591  settings->rotChangeDefault,
7592  settings,
7593  settings->overlayDefaults );
7594  }
7595  else if ( fileType == 1 )
7596  {
7597  one->getDensityMapFromPDB ( this->structFiles.at(0),
7598  &this->shellSpacing,
7599  this->mapResolution,
7600  &this->bandwidthVec.at(0),
7601  &this->thetaVec.at(0),
7602  &this->phiVec.at(0),
7603  &this->glIntegOrderVec.at(0),
7604  &this->extraSpaceVec.at(0),
7605  settings->mapResDefault,
7606  settings,
7607  this->bFactorValue,
7608  this->firstLineCOM );
7609  }
7610  else
7611  {
7612  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;
7613  exit ( -1 );
7614  }
7615  if ( settings->verbose > 1 )
7616  {
7617  std::cout << ">> Structure " << this->structFiles.at(0) << " loaded." << std::endl;
7618  }
7619 
7620  if ( settings->htmlReport )
7621  {
7622  //==================================== Record progress
7623  std::stringstream hlpSS;
7624  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(0) << " loaded." << "</font>";
7625  rvapi_set_text ( hlpSS.str().c_str(),
7626  "ProgressSection",
7627  settings->htmlReportLineProgress,
7628  1,
7629  1,
7630  1 );
7631  settings->htmlReportLineProgress += 1;
7632  rvapi_flush ( );
7633  }
7634 
7635  //======================================== Deal with the centering and MAP data format, if applicable
7636  one->normaliseMap ( settings );
7637  if ( this->usePhase )
7638  {
7639  one->keepPhaseInMap ( this->alpha,
7640  this->bFactorChange,
7641  &this->bandwidthVec.at(0),
7642  &this->thetaVec.at(0),
7643  &this->phiVec.at(0),
7644  &this->glIntegOrderVec.at(0),
7645  settings,
7646  this->useCOM,
7647  settings->noIQRsFromMap,
7648  settings->verbose,
7649  settings->clearMapData,
7650  settings->rotChangeDefault,
7651  settings->overlayDefaults,
7652  settings->maskBlurFactor,
7653  settings->maskBlurFactorGiven );
7654  }
7655  else
7656  {
7657  one->removePhaseFromMap ( this->alpha,
7658  this->bFactorChange,
7659  settings );
7660  }
7661 
7662  //======================================== Map the density onto spheres
7663  one->mapPhaselessToSphere ( settings,
7664  this->thetaVec.at(0),
7665  this->phiVec.at(0),
7666  this->shellSpacing,
7667  settings->manualShells );
7668 
7669  //======================================== Compute the Spherical Harmonics (SH) coefficients
7670  one->getSphericalHarmonicsCoeffs ( this->bandwidthVec.at(0), settings );
7671 
7672  //======================================== If required, pre-compute the energy levels distance descriptor
7673  if ( this->energyLevelDist )
7674  {
7675  one->precomputeRotInvDescriptor ( settings );
7676  }
7677 
7678  if ( settings->verbose > 2 )
7679  {
7680  std::cout << ">>>>> Structure " << this->structFiles.at(0) << " spherical harmonics computed." << std::endl;
7681  }
7682 
7683  if ( settings->htmlReport )
7684  {
7685  //==================================== Record progress
7686  std::stringstream hlpSS;
7687  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(0) << " spherical harmonics computed." << "</font>";
7688  rvapi_set_text ( hlpSS.str().c_str(),
7689  "ProgressSection",
7690  settings->htmlReportLineProgress,
7691  1,
7692  1,
7693  1 );
7694  settings->htmlReportLineProgress += 1;
7695  rvapi_flush ( );
7696  }
7697 
7698  //======================================== Initialise comparison values
7699  for ( unsigned int vecIt = 1; vecIt < static_cast<unsigned int> ( this->structFiles.size() ); vecIt++ )
7700  {
7701  this->bandwidthVec.at(vecIt) = this->bandwidthVec.at(0);
7702  this->thetaVec.at(vecIt) = this->thetaVec.at(0);
7703  this->phiVec.at(vecIt) = this->phiVec.at(0);
7704  this->glIntegOrderVec.at(vecIt) = this->glIntegOrderVec.at(0);
7705  this->extraSpaceVec.at(vecIt) = this->extraSpaceVec.at(0);
7706  }
7707 
7708  //======================================== Read in the objects to compare against one and get SH Coeffs
7709  std::vector<ProSHADE_data*> objs ( this->structFiles.size() - 1 );
7710  for ( unsigned int strIt = 0; strIt < static_cast<unsigned int> ( this->structFiles.size() - 1 ); strIt++ )
7711  {
7712  //==================================== Initialise the object
7713  objs.at(strIt) = new ProSHADE_data ();
7714 
7715  //==================================== Read in the objects and determine maximum band, theta, phi, integration order and extra cell space, if not specified by user
7716  fileType = checkFileType ( structFiles.at(strIt+1) );
7717  if ( fileType == 2 )
7718  {
7719  objs.at(strIt)->getDensityMapFromMAP ( this->structFiles.at(strIt+1),
7720  &this->shellSpacing,
7721  this->mapResolution,
7722  &this->bandwidthVec.at(strIt+1),
7723  &this->thetaVec.at(strIt+1),
7724  &this->phiVec.at(strIt+1),
7725  &this->glIntegOrderVec.at(strIt+1),
7726  &this->extraSpaceVec.at(strIt+1),
7727  settings->mapResDefault,
7728  settings->rotChangeDefault,
7729  settings,
7730  settings->overlayDefaults );
7731  }
7732  else if ( fileType == 1 )
7733  {
7734  objs.at(strIt)->getDensityMapFromPDB ( this->structFiles.at(strIt+1),
7735  &this->shellSpacing,
7736  this->mapResolution,
7737  &this->bandwidthVec.at(strIt+1),
7738  &this->thetaVec.at(strIt+1),
7739  &this->phiVec.at(strIt+1),
7740  &this->glIntegOrderVec.at(strIt+1),
7741  &this->extraSpaceVec.at(strIt+1),
7742  settings->mapResDefault,
7743  settings,
7744  this->bFactorValue,
7745  this->firstLineCOM );
7746  }
7747  else
7748  {
7749  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;
7750  exit ( -1 );
7751  }
7752 
7753  if ( settings->verbose > 1 )
7754  {
7755  std::cout << ">> Structure " << this->structFiles.at(strIt+1) << " loaded." << std::endl;
7756  }
7757 
7758  if ( settings->htmlReport )
7759  {
7760  //================================ Record progress
7761  std::stringstream hlpSS;
7762  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(strIt+1) << " loaded." << "</font>";
7763  rvapi_set_text ( hlpSS.str().c_str(),
7764  "ProgressSection",
7765  settings->htmlReportLineProgress,
7766  1,
7767  1,
7768  1 );
7769  settings->htmlReportLineProgress += 1;
7770  rvapi_flush ( );
7771  }
7772 
7773  //==================================== Deal with phase and MAP format data in general
7774  objs.at(strIt)->normaliseMap ( settings );
7775  if ( this->usePhase )
7776  {
7777  objs.at(strIt)->keepPhaseInMap ( this->alpha,
7778  this->bFactorChange,
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  settings,
7784  this->useCOM,
7785  settings->noIQRsFromMap,
7786  settings->verbose,
7787  settings->clearMapData,
7788  settings->rotChangeDefault,
7789  settings->overlayDefaults,
7790  settings->maskBlurFactor,
7791  settings->maskBlurFactorGiven );
7792  }
7793  else
7794  {
7795  objs.at(strIt)->removePhaseFromMap ( this->alpha,
7796  this->bFactorChange,
7797  settings );
7798  }
7799 
7800  //==================================== Map the density onto spheres
7801  objs.at(strIt)->mapPhaselessToSphere ( settings,
7802  this->thetaVec.at(strIt+1),
7803  this->phiVec.at(strIt+1),
7804  this->shellSpacing,
7805  settings->manualShells );
7806  //==================================== Now compute the Spherical Harmonics (SH) coefficients
7807  objs.at(strIt)->getSphericalHarmonicsCoeffs( this->bandwidthVec.at(strIt+1), settings );
7808 
7809  //==================================== And if required, the energy levels distance pre-computation
7810  if ( this->energyLevelDist )
7811  {
7812  objs.at(strIt)->precomputeRotInvDescriptor ( settings );
7813  }
7814 
7815  if ( settings->verbose > 2 )
7816  {
7817  std::cout << ">>>>> Structure " << this->structFiles.at(strIt+1) << " spherical harmonics computed." << std::endl;
7818  }
7819 
7820  if ( settings->htmlReport )
7821  {
7822  //==================================== Record progress
7823  std::stringstream hlpSS;
7824  hlpSS << "<font color=\"green\">" << "Structure " << this->structFiles.at(strIt+1) << " spherical harmonics computed." << "</font>";
7825  rvapi_set_text ( hlpSS.str().c_str(),
7826  "ProgressSection",
7827  settings->htmlReportLineProgress,
7828  1,
7829  1,
7830  1 );
7831  settings->htmlReportLineProgress += 1;
7832  rvapi_flush ( );
7833  }
7834  }
7835 
7836  //======================================== Create the compare against all object
7837  this->cmpObj = new ProSHADE_compareOneAgainstAll ( one, &objs, this->ignoreLs, this->mPower, settings->verbose );
7838 
7839  //======================================== Save the decision whether to use phases or not
7840  if ( one->_keepOrRemove ) { this->cmpObj->_keepOrRemove = true; }
7841  else { this->cmpObj->_keepOrRemove = false; }
7842 
7843  //======================================== If required, compute the energy levels distances
7844  if ( this->energyLevelDist )
7845  {
7846  if ( settings->verbose > 0 )
7847  {
7848  std::cout << "Computing the cross-correlation distances." << std::endl;
7849  }
7850 
7851  if ( settings->htmlReport )
7852  {
7853  //================================ Record progress
7854  std::stringstream hlpSS;
7855  hlpSS << "<font color=\"green\">" << "Computing the cross-correlation distances." << "</font>";
7856  rvapi_set_text ( hlpSS.str().c_str(),
7857  "ProgressSection",
7858  settings->htmlReportLineProgress,
7859  1,
7860  1,
7861  1 );
7862  settings->htmlReportLineProgress += 1;
7863  rvapi_flush ( );
7864  }
7865  this->energyLevelsDistances = this->cmpObj->getEnergyLevelsDistance ( settings->verbose, settings );
7866 
7867  //==================================== ... and set which pairs not to follow further
7868  if ( this->enLevelsThreshold != -999.9 )
7869  {
7870  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7871  {
7872  if ( this->enLevelsThreshold > this->energyLevelsDistances.at(iter) )
7873  {
7874  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 1 );
7875  }
7876  else
7877  {
7878  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7879  }
7880  }
7881  }
7882  else
7883  {
7884  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7885  {
7886  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7887  }
7888  }
7889  }
7890  else
7891  {
7892  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7893  {
7894  this->cmpObj->_enLevelsDoNotFollow.emplace_back ( 0 );
7895  }
7896  }
7897 
7898  //======================================== Pre-compute the E matrices in case either the trace sigmal or full rotation distance are required
7899  if ( this->traceSigmaDist || this->fullRotFnDist )
7900  {
7901  this->cmpObj->precomputeTrSigmaDescriptor ( this->shellSpacing, &this->glIntegOrderVec, settings );
7902  }
7903 
7904  //======================================== Compute the trace sigma distances, if required
7905  if ( this->traceSigmaDist )
7906  {
7907  if ( settings->verbose > 0 )
7908  {
7909  std::cout << "Computing the trace sigma distances." << std::endl;
7910  }
7911  if ( settings->htmlReport )
7912  {
7913  //================================ Record progress
7914  std::stringstream hlpSS;
7915  hlpSS << "<font color=\"green\">" << "Computing the trace sigma distances." << "</font>";
7916  rvapi_set_text ( hlpSS.str().c_str(),
7917  "ProgressSection",
7918  settings->htmlReportLineProgress,
7919  1,
7920  1,
7921  1 );
7922  settings->htmlReportLineProgress += 1;
7923  rvapi_flush ( );
7924  }
7925 
7926  this->traceSigmaDistances = this->cmpObj->getTrSigmaDistance ( settings->verbose, settings );
7927 
7928  if ( this->trSigmaThreshold == -999.9 )
7929  {
7930  this->cmpObj->_trSigmaDoNotFollow = this->cmpObj->_enLevelsDoNotFollow;
7931  }
7932  else
7933  {
7934  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->traceSigmaDistances.size() ); iter++ )
7935  {
7936  if ( this->trSigmaThreshold > this->traceSigmaDistances.at(iter) )
7937  {
7938  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 1 );
7939  }
7940  else
7941  {
7942  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 0 );
7943  }
7944  }
7945  }
7946  }
7947  else
7948  {
7949  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cmpObj->all->size() ); iter++ )
7950  {
7951  this->cmpObj->_trSigmaDoNotFollow.emplace_back ( 0 );
7952  }
7953  }
7954 
7955  //======================================== If full rotation distance is required, pre-compute the requirements
7956  if ( this->fullRotFnDist )
7957  {
7958  if ( settings->verbose > 0 )
7959  {
7960  std::cout << "Computing the rotation function distances." << std::endl;
7961  }
7962  if ( settings->htmlReport )
7963  {
7964  //================================ Record progress
7965  std::stringstream hlpSS;
7966  hlpSS << "<font color=\"green\">" << "Computing the rotation function distances." << "</font>";
7967  rvapi_set_text ( hlpSS.str().c_str(),
7968  "ProgressSection",
7969  settings->htmlReportLineProgress,
7970  1,
7971  1,
7972  1 );
7973  settings->htmlReportLineProgress += 1;
7974  rvapi_flush ( );
7975  }
7976 
7977  this->cmpObj->getSO3InverseMap ( settings );
7978  if ( settings->verbose > 2 )
7979  {
7980  std::cout << ">>>>> Inverse SO(3) Fourier transform maps obtained." << std::endl;
7981  }
7982 
7983  this->cmpObj->getEulerAngles ( settings );
7984  if ( settings->verbose > 3 )
7985  {
7986  std::cout << ">>>>>>>> Optimal Euler angles calculated." << std::endl;
7987  }
7988 
7989  this->cmpObj->generateWignerMatrices ( settings );
7990  if ( settings->verbose > 2 )
7991  {
7992  std::cout << ">>>>> Wigner matrices computed." << std::endl;
7993  }
7994 
7995  this->fullRotationDistances = this->cmpObj->getRotCoeffDistance ( settings->verbose, settings );
7996  }
7997 
7998  //======================================== Free memory
7999  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( objs.size() ); iter++ )
8000  {
8001  if ( objs.at(iter) != nullptr )
8002  {
8003  delete objs.at(iter);
8004  }
8005  }
8006  objs.clear ( );
8007 
8008  delete cmpObj;
8009  cmpObj = nullptr;
8010 }
8011 
8020 {
8021  if ( this->cmpObj != nullptr ) { delete this->cmpObj; }
8022 }
8023 
8035 {
8036  //======================================== Sanity check
8037  if ( !this->energyLevelDist )
8038  {
8039  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;
8040  exit ( -1 );
8041  }
8042 
8043  if ( this->cmpObj != nullptr )
8044  {
8045  if ( !this->cmpObj->_energyLevelsComputed )
8046  {
8047  std::cerr << " !!! ProSHADE ERROR !!! Error in structure comparison. !!! The energy level distances were not computed before their values are required." << std::endl;
8048  exit ( -1 );
8049  }
8050  }
8051 
8052  //======================================== Return
8053  return ( this->energyLevelsDistances );
8054 
8055 }
8056 
8068 {
8069  //======================================== Sanity check
8070  if ( !this->energyLevelDist )
8071  {
8072  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;
8073  exit ( -1 );
8074  }
8075 
8076  //======================================== Return
8077  return ( this->fragEnergyLevelsDistances );
8078 
8079 }
8080 
8094 {
8095  //======================================== Sanity check
8096  if ( !this->traceSigmaDist )
8097  {
8098  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;
8099  exit ( -1 );
8100  }
8101 
8102  if ( this->cmpObj != nullptr )
8103  {
8104  if ( !this->cmpObj->_trSigmaComputed )
8105  {
8106  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The trace sigma distances were not computed before their values are required." << std::endl;
8107  exit ( -1 );
8108  }
8109  }
8110 
8111  //======================================== Return
8112  return ( this->traceSigmaDistances );
8113 
8114 }
8115 
8127 {
8128  //======================================== Sanity check
8129  if ( !this->cmpObj->_trSigmaComputed )
8130  {
8131  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The trace sigma distances were not computed before their values are required." << std::endl;
8132  exit ( -1 );
8133  }
8134 
8135  //======================================== Return
8136  return ( this->fragTraceSigmaDistances );
8137 
8138 }
8139 
8153 {
8154  //======================================== Sanity check
8155  if ( !this->fullRotFnDist )
8156  {
8157  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;
8158  exit ( -1 );
8159  }
8160 
8161  if ( this->cmpObj != nullptr )
8162  {
8163  if ( !this->cmpObj->_fullDistComputed )
8164  {
8165  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The full rotation function distances were not computed before their values are required." << std::endl;
8166  exit ( -1 );
8167  }
8168  }
8169 
8170  //======================================== Return
8171  return ( this->fullRotationDistances );
8172 
8173 }
8174 
8186 {
8187  //======================================== Sanity check
8188  if ( !this->cmpObj->_fullDistComputed )
8189  {
8190  std::cerr << "!!! ProSHADE ERROR !!! Error in structure comparison. !!! The full rotation function distances were not computed before their values are required." << std::endl;
8191  exit ( -1 );
8192  }
8193 
8194  //======================================== Return
8195  return ( this->fragfullRotationDistances );
8196 
8197 }
8198 
8209 {
8210  //======================================== Default values
8211  this->fragFilesExist = false;
8212  this->fragFiles.clear ( );
8213  this->one = nullptr;
8214 
8215  //======================================== Retain settings
8216  this->fragBoxSize = settings->mapFragBoxSize;
8217  this->mapFragName = settings->mapFragName;
8218  this->mapFragBoxFraction = settings->mapFragBoxFraction;
8219 
8220  //======================================== If half-maps processing is required, do it
8221  if ( settings->taskToPerform == ProSHADE::HalfMaps )
8222  {
8223  if ( settings->verbose != 0 )
8224  {
8225  std::cout << "-----------------------------------------------------------" << std::endl;
8226  std::cout << "| MODE: HalfMaps |" << std::endl;
8227  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8228  }
8229 
8230  //==================================== Sanity checks
8231  if ( settings->structFiles.size() != 2 )
8232  {
8233  std::cerr << "!!! ProSHADE ERROR !!! Attempted to process half-maps, but did supply ";
8234  if ( settings->structFiles.size() < 2 ) { std::cerr << "less "; }
8235  if ( settings->structFiles.size() > 2 ) { std::cerr << "more "; }
8236  std::cerr << "than 2 files. Please use the \'-f\' option to supply only the two half-maps map files. Terminating ..." << std::endl << std::endl;
8237 
8238  if ( settings->htmlReport )
8239  {
8240  std::stringstream hlpSS;
8241  hlpSS << "<font color=\"red\">" << "There are not exactly two input structures. Please supply only two files to the half-maps re-boxing functionality." << "</font>";
8242  rvapi_set_text ( hlpSS.str().c_str(),
8243  "ProgressSection",
8244  settings->htmlReportLineProgress,
8245  1,
8246  1,
8247  1 );
8248  settings->htmlReportLineProgress += 1;
8249  rvapi_flush ( );
8250  }
8251 
8252  exit ( -1 );
8253  }
8254 
8255  if ( settings->clearMapFile == "" )
8256  {
8257  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;
8258  settings->clearMapFile = "proshade_reboxed";
8259 
8260  if ( settings->htmlReport )
8261  {
8262  std::stringstream hlpSS;
8263  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>";
8264  rvapi_set_text ( hlpSS.str().c_str(),
8265  "ProgressSection",
8266  settings->htmlReportLineProgress,
8267  1,
8268  1,
8269  1 );
8270  settings->htmlReportLineProgress += 1;
8271  rvapi_flush ( );
8272  }
8273  }
8274 
8275  unsigned int fileTy1 = checkFileType ( settings->structFiles.at(0) );
8276  unsigned int fileTy2 = checkFileType ( settings->structFiles.at(1) );
8277  if ( ( fileTy1 != 2 ) || ( fileTy2 != 2 ) )
8278  {
8279  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;
8280 
8281  if ( settings->htmlReport )
8282  {
8283  std::stringstream hlpSS;
8284  hlpSS << "<font color=\"red\">" << "Cannot recognise the file format of the input file ";
8285 
8286  if ( ( fileTy1 != 2 ) && ( fileTy2 = 2 ) )
8287  {
8288  hlpSS << settings->structFiles.at(0) << "</font>";
8289  }
8290  if ( ( fileTy1 = 2 ) && ( fileTy2 != 2 ) )
8291  {
8292  hlpSS << settings->structFiles.at(1) << "</font>";
8293  }
8294  if ( ( fileTy1 != 2 ) && ( fileTy2 != 2 ) )
8295  {
8296  hlpSS << settings->structFiles.at(0) << " and " << settings->structFiles.at(1) << "</font>";
8297  }
8298 
8299  rvapi_set_text ( hlpSS.str().c_str(),
8300  "ProgressSection",
8301  settings->htmlReportLineProgress,
8302  1,
8303  1,
8304  1 );
8305  settings->htmlReportLineProgress += 1;
8306  rvapi_flush ( );
8307  }
8308 
8309  exit ( -1 );
8310  }
8311 
8312  //==================================== Deal with the maps
8313  double xTrans, yTrans, zTrans;
8314  dealWithHalfMaps ( settings, &xTrans, &yTrans, &zTrans );
8315 
8316  if ( settings->verbose > 0 )
8317  {
8318  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8319  std::cout << "| COMPLETED |" << std::endl;
8320  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8321  }
8322 
8323  if ( settings->htmlReport )
8324  {
8325  std::stringstream hlpSS;
8326  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8327  rvapi_set_text ( hlpSS.str().c_str(),
8328  "ProgressSection",
8329  settings->htmlReportLineProgress,
8330  1,
8331  1,
8332  1 );
8333  settings->htmlReportLineProgress += 1;
8334  rvapi_flush ( );
8335  }
8336 
8337  if ( settings->verbose > 0 )
8338  {
8339  std::cout << "-----------------------------------------------------------" << std::endl;
8340  std::cout << "| RESULTS |" << std::endl;
8341  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8342 
8343  std::cout << "Half maps saved into files:" << std::endl << " " << settings->clearMapFile << "_half1.map" << std::endl << " " << settings->clearMapFile << "_half2.map" << std::endl << std::endl;
8344  }
8345 
8346  //==================================== Done
8347  return ;
8348  }
8349 
8350  if ( settings->taskToPerform == ProSHADE::SimpleRebox )
8351  {
8352  unsigned int fileType = checkFileType ( settings->structFiles.at(0) );
8353  if ( fileType != 2 )
8354  {
8355  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;
8356 
8357  if ( settings->htmlReport )
8358  {
8359  std::stringstream hlpSS;
8360  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>";
8361  rvapi_set_text ( hlpSS.str().c_str(),
8362  "ProgressSection",
8363  settings->htmlReportLineProgress,
8364  1,
8365  1,
8366  1 );
8367  settings->htmlReportLineProgress += 1;
8368  rvapi_flush ( );
8369  }
8370 
8371  exit ( -1 );
8372  }
8373 
8374  if ( settings->clearMapFile == "" )
8375  {
8376  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;
8377  settings->clearMapFile = "proshade_reboxed.map";
8378 
8379  if ( settings->htmlReport )
8380  {
8381  std::stringstream hlpSS;
8382  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>";
8383  rvapi_set_text ( hlpSS.str().c_str(),
8384  "ProgressSection",
8385  settings->htmlReportLineProgress,
8386  1,
8387  1,
8388  1 );
8389  settings->htmlReportLineProgress += 1;
8390  rvapi_flush ( );
8391  }
8392  }
8393 
8394  if ( settings->verbose > 3 )
8395  {
8396  std::cout << ">>>>>>>> Sanity checks passed." << std::endl;
8397  }
8398 
8399  if ( settings->htmlReport )
8400  {
8401  std::stringstream hlpSS;
8402  hlpSS << "<font color=\"green\">" << "Sanity checks passed." << "</font>";
8403  rvapi_set_text ( hlpSS.str().c_str(),
8404  "ProgressSection",
8405  settings->htmlReportLineProgress,
8406  1,
8407  1,
8408  1 );
8409  settings->htmlReportLineProgress += 1;
8410  rvapi_flush ( );
8411  }
8412 
8413  //==================================== Create the structure object
8414  this->one = new ProSHADE_data ();
8415 
8416  //==================================== Run re-boxing
8417  if ( settings->verbose != 0 )
8418  {
8419  std::cout << "Applying the re-boxing algorithm." << std::endl;
8420  }
8421 
8422  std::array<double,6> dims = one->getDensityMapFromMAPRebox ( settings->structFiles.at(0),
8423  settings->noIQRsFromMap,
8424  settings->extraSpace,
8425  settings->verbose,
8426  settings->useCubicMaps,
8427  settings->maskBlurFactor,
8428  settings->maskBlurFactorGiven,
8429  settings );
8430 
8431  //==================================== Report progress
8432  if ( settings->verbose > 0 )
8433  {
8434  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8435  std::cout << "| COMPLETED |" << std::endl;
8436  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8437  }
8438 
8439  //======================================== Write out map
8440  one->writeMap ( settings->clearMapFile, one->_densityMapCor );
8441 
8442  if ( settings->verbose > 0 )
8443  {
8444  std::cout << "The re-boxed map has been saved to the " << settings->clearMapFile << " file." << std::endl << std::endl;
8445  }
8446 
8447  if ( settings->htmlReport )
8448  {
8449  std::stringstream hlpSS;
8450  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8451  rvapi_set_text ( hlpSS.str().c_str(),
8452  "ProgressSection",
8453  settings->htmlReportLineProgress,
8454  1,
8455  1,
8456  1 );
8457  settings->htmlReportLineProgress += 1;
8458  rvapi_flush ( );
8459  }
8460 
8461  if ( settings->htmlReport )
8462  {
8463  rvapi_add_section ( "ResultsSection",
8464  "Results",
8465  "body",
8466  settings->htmlReportLine,
8467  0,
8468  1,
8469  1,
8470  true );
8471  settings->htmlReportLine += 1;
8472 
8473  std::stringstream hlpSS;
8474  hlpSS << "<pre><b>" << "The re-boxed structure is available at: </b>" << settings->clearMapFile << "</pre>";
8475  rvapi_set_text ( hlpSS.str().c_str(),
8476  "ResultsSection",
8477  0,
8478  0,
8479  1,
8480  1 );
8481 
8482  hlpSS.str ( std::string ( ) );
8483  hlpSS << "<pre><b>" << "Original structure dims: </b>" << dims[0] << " x " << dims[1] << " x " << dims[2] << "</pre>";
8484  rvapi_set_text ( hlpSS.str().c_str(),
8485  "ResultsSection",
8486  1,
8487  0,
8488  1,
8489  1 );
8490 
8491  hlpSS.str ( std::string ( ) );
8492  hlpSS << "<pre><b>" << "Re-boxed structure dims: </b>" << dims[3] << " x " << dims[4] << " x " << dims[5] << "</pre>";
8493  rvapi_set_text ( hlpSS.str().c_str(),
8494  "ResultsSection",
8495  2,
8496  0,
8497  1,
8498  1 );
8499 
8500  hlpSS.str ( std::string ( ) );
8501  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>";
8502  rvapi_set_text ( hlpSS.str().c_str(),
8503  "ResultsSection",
8504  3,
8505  0,
8506  1,
8507  1 );
8508 
8509  hlpSS.str ( std::string ( ) );
8510  hlpSS << "<pre><b>" << "Linear processing speed-up: </b>" << ( ( dims[0] * dims[1] * dims[2] ) / ( dims[3] * dims[4] * dims[5] ) ) - 1.0 << " times</pre>";
8511  rvapi_set_text ( hlpSS.str().c_str(),
8512  "ResultsSection",
8513  4,
8514  0,
8515  1,
8516  1 );
8517  }
8518 
8519  //==================================== Done
8520  return ;
8521  }
8522 
8523  //======================================== Report progress
8524  if ( settings->verbose > -1 )
8525  {
8526  std::cout << "-----------------------------------------------------------" << std::endl;
8527  std::cout << "| MODE: Features |" << std::endl;
8528  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8529  }
8530 
8531  //======================================== Initialise valies
8532  this->maxMapU = 0.0;
8533  this->maxMapV = 0.0;
8534  this->maxMapW = 0.0;
8535  this->xRange = 0.0;
8536  this->yRange = 0.0;
8537  this->zRange = 0.0;
8538 
8539  //======================================== Create the structure object
8540  this->one = new ProSHADE_data ();
8541 
8542  //======================================== Read in the structure into one
8543  unsigned int fileType = checkFileType ( settings->structFiles.at(0) );
8544  if ( fileType == 2 )
8545  {
8546  if ( settings->verbose != 0 )
8547  {
8548  std::cout << "Computing the map features." << std::endl;
8549  }
8550  one->getDensityMapFromMAPFeatures ( settings->structFiles.at(0),
8551  &this->minDensPreNorm,
8552  &this->maxDensPreNorm,
8553  &this->minDensPostNorm,
8554  &this->maxDensPostNorm,
8555  &this->postNormMean,
8556  &this->postNormSdev,
8557  &this->maskVolume,
8558  &this->totalVolume,
8559  &this->maskMean,
8560  &this->maskSdev,
8561  &this->maskMin,
8562  &this->maskMax,
8563  &this->maskDensityRMS,
8564  &this->allDensityRMS,
8565  &this->origRanges,
8566  &this->origDims,
8567  settings->noIQRsFromMap,
8568  settings->extraSpace,
8569  settings->verbose,
8570  settings->useCubicMaps,
8571  settings->maskBlurFactor,
8572  settings->maskBlurFactorGiven,
8573  true,
8574  settings );
8575  }
8576  else if ( fileType == 1 )
8577  {
8578  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;
8579  exit ( -1 );
8580  }
8581  else
8582  {
8583  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;
8584  exit ( -1 );
8585  }
8586 
8587  if ( settings->verbose > 0 )
8588  {
8589  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
8590  std::cout << "| COMPLETED |" << std::endl;
8591  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
8592  }
8593 
8594  if ( settings->htmlReport )
8595  {
8596  std::stringstream hlpSS;
8597  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
8598  rvapi_set_text ( hlpSS.str().c_str(),
8599  "ProgressSection",
8600  settings->htmlReportLineProgress,
8601  1,
8602  1,
8603  1 );
8604  settings->htmlReportLineProgress += 1;
8605  rvapi_flush ( );
8606  }
8607 
8608  //======================================== Write out map, if needed
8609  if ( settings->clearMapFile != "" )
8610  {
8611  one->writeMap ( settings->clearMapFile, one->_densityMapCor );
8612 
8613  if ( settings->htmlReport )
8614  {
8615  //==================================== Create section
8616  rvapi_add_section ( "FilenameSection",
8617  "Saved file",
8618  "body",
8619  settings->htmlReportLine,
8620  0,
8621  1,
8622  1,
8623  false );
8624  settings->htmlReportLine += 1;
8625 
8626  std::stringstream hlpSS;
8627  hlpSS << "<pre>" << "File saved as: " << settings->clearMapFile << "</pre>";
8628  rvapi_set_text ( hlpSS.str().c_str(),
8629  "FilenameSection",
8630  0,
8631  1,
8632  1,
8633  1 );
8634 
8635  rvapi_flush ( );
8636  }
8637  }
8638 
8639  //======================================== Done
8640 
8641 }
8642 
8651 {
8652  //======================================== Free memory
8653  if ( this->one != nullptr )
8654  {
8655  delete this->one;
8656  }
8657 }
8658 
8669 {
8670  //======================================== Sanity check
8671  if ( !this->fragFilesExist )
8672  {
8673  std::cerr << "!!! ProSHADE ERROR !!! Attempted to obtain the list of fragment files without doing the fragmentation first. Terminating..." << std::endl;
8674  exit ( -1 );
8675  }
8676 
8677  //======================================== If valid, return
8678  return ( this->fragFiles );
8679 }
8680 
8681 /* \brief This function writes out a map in the CCP4 MAP format.
8682 
8683  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,
8684  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
8685  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
8686 
8687  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
8688  \param[in] map Double pointer to array of map values in the U, V, W order.
8689  \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'.
8690  \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!
8691  \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!
8692  \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!
8693  \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!
8694  \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!
8695  \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!
8696  \param[in] xRange Dimension size (x-axis) in angstroms.
8697  \param[in] yRange Dimension size (y-axis) in angstroms.
8698  \param[in] zRange Dimension size (z-axis) in angstroms.
8699 
8700  \warning This is an internal function which should not be used by the user.
8701  */
8702 void ProSHADE_internal::ProSHADE_data::writeMap ( std::string fileName,
8703  double* map,
8704  std::string axOrder,
8705  float xFrom,
8706  float yFrom,
8707  float zFrom,
8708  float xTo,
8709  float yTo,
8710  float zTo,
8711  float xRange,
8712  float yRange,
8713  float zRange )
8714 {
8715  //======================================== Open file for writing
8716  int myMapMode = 1;
8717  CMap_io::CMMFile *mapFile = nullptr;
8718  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
8719  if ( mapFile == NULL )
8720  {
8721  std::cerr << "!!! ProSHADE ERROR !!! Cannot open file " << fileName << " for writing. Terminating..." << std::endl;
8722  exit ( -1 );
8723  }
8724 
8725  //======================================== Header: Initialisation
8726  const char* title = "ProSHADE genrated map ";
8727  int grid[3];
8728  int axisOrder[3];
8729  int dims[3];
8730  int axFrom[3];
8731  float cell[6];
8732 
8733  //======================================== Header: Decide axis order
8734  for ( unsigned int iter = 0; iter < 3; iter++ )
8735  {
8736  if ( axOrder[iter] == 'x' ) { axisOrder[iter] = 1; }
8737  if ( axOrder[iter] == 'y' ) { axisOrder[iter] = 2; }
8738  if ( axOrder[iter] == 'z' ) { axisOrder[iter] = 3; }
8739  }
8740 
8741  //======================================== Header: Default or identical limits?
8742  if ( std::isinf ( xFrom ) )
8743  {
8744  xFrom = this->_xFrom;
8745  if ( std::isinf ( xFrom ) )
8746  {
8747  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;
8748  exit ( -1 );
8749  }
8750  }
8751  if ( std::isinf ( yFrom ) )
8752  {
8753  yFrom = this->_yFrom;
8754  if ( std::isinf ( yFrom ) )
8755  {
8756  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;
8757  exit ( -1 );
8758  }
8759  }
8760  if ( std::isinf ( zFrom ) )
8761  {
8762  zFrom = this->_zFrom;
8763  if ( std::isinf ( zFrom ) )
8764  {
8765  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;
8766  exit ( -1 );
8767  }
8768  }
8769  if ( std::isinf ( xTo ) )
8770  {
8771  xTo = this->_xTo;
8772  if ( std::isinf ( xTo ) )
8773  {
8774  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;
8775  exit ( -1 );
8776  }
8777  }
8778  if ( std::isinf ( yTo ) )
8779  {
8780  yTo = this->_yTo;
8781  if ( std::isinf ( yTo ) )
8782  {
8783  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;
8784  exit ( -1 );
8785  }
8786  }
8787  if ( std::isinf ( zTo ) )
8788  {
8789  zTo = this->_zTo;
8790  if ( std::isinf ( zTo ) )
8791  {
8792  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;
8793  exit ( -1 );
8794  }
8795  }
8796 
8797  //======================================== Header: Decide axis order, grid, axis limits and dimentions
8798  grid[axisOrder[0]-1] = xTo - xFrom + 1;
8799  grid[axisOrder[1]-1] = yTo - yFrom + 1;
8800  grid[axisOrder[2]-1] = zTo - zFrom + 1;
8801 
8802  axFrom[axisOrder[0]-1] = xFrom;
8803  axFrom[axisOrder[1]-1] = yFrom;
8804  axFrom[axisOrder[2]-1] = zFrom;
8805 
8806  dims[0] = this->_maxMapU + 1;
8807  dims[1] = this->_maxMapV + 1;
8808  dims[2] = this->_maxMapW + 1;
8809 
8810  //======================================== Header: Get cell parameters
8811  if ( std::isinf ( xRange ) )
8812  {
8813  xRange = this->_xRange;
8814  if ( std::isinf ( xRange ) )
8815  {
8816  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;
8817  exit ( -1 );
8818  }
8819  }
8820  if ( std::isinf ( yRange ) )
8821  {
8822  yRange = this->_yRange;
8823  if ( std::isinf ( yRange ) )
8824  {
8825  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;
8826  exit ( -1 );
8827  }
8828  }
8829  if ( std::isinf ( zRange ) )
8830  {
8831  zRange = this->_zRange;
8832  if ( std::isinf ( zRange ) )
8833  {
8834  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;
8835  exit ( -1 );
8836  }
8837  }
8838 
8839  cell[0] = xRange;
8840  cell[1] = yRange;
8841  cell[2] = zRange;
8842  cell[3] = static_cast<float> ( 90.0 );
8843  cell[4] = static_cast<float> ( 90.0 );
8844  cell[5] = static_cast<float> ( 90.0 );
8845 
8846  //======================================== Header: Write the map header
8847  CMap_io::ccp4_cmap_set_cell ( mapFile, cell );
8848  CMap_io::ccp4_cmap_set_grid ( mapFile, grid );
8849  CMap_io::ccp4_cmap_set_order ( mapFile, axisOrder );
8850  CMap_io::ccp4_cmap_set_dim ( mapFile, dims );
8851  CMap_io::ccp4_cmap_set_origin ( mapFile, axFrom );
8852 
8853  CMap_io::ccp4_cmap_set_spacegroup ( mapFile, 1 );
8854  CMap_io::ccp4_cmap_set_title ( mapFile, title );
8855  CMap_io::ccp4_cmap_set_datamode ( mapFile, 2 );
8856 
8857  //======================================== Data: Write the map data
8858  std::vector<float> section( dims[axisOrder[1]-1] * dims[axisOrder[0]-1] );
8859  int index;
8860  int iters[3];
8861  int arrPos;
8862 
8863  for ( iters[2] = 0; iters[2] < dims[axisOrder[2]-1]; iters[2]++ )
8864  {
8865  index = 0;
8866 
8867  for ( iters[1] = 0; iters[1] < dims[axisOrder[1]-1]; iters[1]++ )
8868  {
8869  for ( iters[0] = 0; iters[0] < dims[axisOrder[0]-1]; iters[0]++ )
8870  {
8871  arrPos = iters[2] + (dims[axisOrder[2]-1]) * ( iters[1] + (dims[axisOrder[1]-1]) * iters[0] );
8872 
8873  section[ index++ ] = static_cast<float> ( map[arrPos] );
8874  }
8875  }
8876 
8877  CMap_io::ccp4_cmap_write_section( mapFile, &section[0] );
8878  }
8879 
8880  CMap_io::ccp4_cmap_close ( mapFile );
8881 
8882  //======================================== Done
8883  return ;
8884 
8885 }
8886 
8887 /* \brief This function writes out a map in the CCP4 MAP format.
8888 
8889  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,
8890  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
8891  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
8892 
8893  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
8894  \param[in] map Float pointer to array of map values in the U, V, W order.
8895  \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'.
8896  \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!
8897  \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!
8898  \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!
8899  \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!
8900  \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!
8901  \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!
8902  \param[in] xRange Dimension size (x-axis) in angstroms.
8903  \param[in] yRange Dimension size (y-axis) in angstroms.
8904  \param[in] zRange Dimension size (z-axis) in angstroms.
8905 
8906  \warning This is an internal function which should not be used by the user.
8907  */
8908 void ProSHADE_internal::ProSHADE_data::writeMap ( std::string fileName,
8909  float* map,
8910  std::string axOrder,
8911  float xFrom,
8912  float yFrom,
8913  float zFrom,
8914  float xTo,
8915  float yTo,
8916  float zTo,
8917  float xRange,
8918  float yRange,
8919  float zRange )
8920 {
8921  //======================================== Open file for writing
8922  int myMapMode = 1;
8923  CMap_io::CMMFile *mapFile = nullptr;
8924  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
8925  if ( mapFile == NULL )
8926  {
8927  std::cerr << "!!! ProSHADE ERROR !!! Cannot open file " << fileName << " for writing. Terminating..." << std::endl;
8928  exit ( -1 );
8929  }
8930 
8931  //======================================== Header: Initialisation
8932  const char* title = "ProSHADE genrated map ";
8933  int grid[3];
8934  int axisOrder[3];
8935  int dims[3];
8936  int axFrom[3];
8937  float cell[6];
8938 
8939  //======================================== Header: Decide axis order
8940  for ( unsigned int iter = 0; iter < 3; iter++ )
8941  {
8942  if ( axOrder[iter] == 'x' ) { axisOrder[iter] = 1; }
8943  if ( axOrder[iter] == 'y' ) { axisOrder[iter] = 2; }
8944  if ( axOrder[iter] == 'z' ) { axisOrder[iter] = 3; }
8945  }
8946 
8947  //======================================== Header: Default or identical limits?
8948  if ( std::isinf ( xFrom ) )
8949  {
8950  xFrom = this->_xFrom;
8951  if ( std::isinf ( xFrom ) )
8952  {
8953  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;
8954  exit ( -1 );
8955  }
8956  }
8957  if ( std::isinf ( yFrom ) )
8958  {
8959  yFrom = this->_yFrom;
8960  if ( std::isinf ( yFrom ) )
8961  {
8962  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;
8963  exit ( -1 );
8964  }
8965  }
8966  if ( std::isinf ( zFrom ) )
8967  {
8968  zFrom = this->_zFrom;
8969  if ( std::isinf ( zFrom ) )
8970  {
8971  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;
8972  exit ( -1 );
8973  }
8974  }
8975  if ( std::isinf ( xTo ) )
8976  {
8977  xTo = this->_xTo;
8978  if ( std::isinf ( xTo ) )
8979  {
8980  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;
8981  exit ( -1 );
8982  }
8983  }
8984  if ( std::isinf ( yTo ) )
8985  {
8986  yTo = this->_yTo;
8987  if ( std::isinf ( yTo ) )
8988  {
8989  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;
8990  exit ( -1 );
8991  }
8992  }
8993  if ( std::isinf ( zTo ) )
8994  {
8995  zTo = this->_zTo;
8996  if ( std::isinf ( zTo ) )
8997  {
8998  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;
8999  exit ( -1 );
9000  }
9001  }
9002 
9003  //======================================== Header: Decide axis order, grid, axis limits and dimentions
9004  grid[axisOrder[0]-1] = xTo - xFrom + 1;
9005  grid[axisOrder[1]-1] = yTo - yFrom + 1;
9006  grid[axisOrder[2]-1] = zTo - zFrom + 1;
9007 
9008  axFrom[axisOrder[0]-1] = xFrom;
9009  axFrom[axisOrder[1]-1] = yFrom;
9010  axFrom[axisOrder[2]-1] = zFrom;
9011 
9012  dims[0] = this->_maxMapU + 1;
9013  dims[1] = this->_maxMapV + 1;
9014  dims[2] = this->_maxMapW + 1;
9015 
9016  //======================================== Header: Get cell parameters
9017  if ( std::isinf ( xRange ) )
9018  {
9019  xRange = this->_xRange;
9020  if ( std::isinf ( xRange ) )
9021  {
9022  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;
9023  exit ( -1 );
9024  }
9025  }
9026  if ( std::isinf ( yRange ) )
9027  {
9028  yRange = this->_yRange;
9029  if ( std::isinf ( yRange ) )
9030  {
9031  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;
9032  exit ( -1 );
9033  }
9034  }
9035  if ( std::isinf ( zRange ) )
9036  {
9037  zRange = this->_zRange;
9038  if ( std::isinf ( zRange ) )
9039  {
9040  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;
9041  exit ( -1 );
9042  }
9043  }
9044 
9045  cell[0] = xRange;
9046  cell[1] = yRange;
9047  cell[2] = zRange;
9048  cell[3] = static_cast<float> ( 90.0 );
9049  cell[4] = static_cast<float> ( 90.0 );
9050  cell[5] = static_cast<float> ( 90.0 );
9051 
9052  //======================================== Header: Write the map header
9053  CMap_io::ccp4_cmap_set_cell ( mapFile, cell );
9054  CMap_io::ccp4_cmap_set_grid ( mapFile, grid );
9055  CMap_io::ccp4_cmap_set_order ( mapFile, axisOrder );
9056  CMap_io::ccp4_cmap_set_dim ( mapFile, dims );
9057  CMap_io::ccp4_cmap_set_origin ( mapFile, axFrom );
9058 
9059  CMap_io::ccp4_cmap_set_spacegroup ( mapFile, 1 );
9060  CMap_io::ccp4_cmap_set_title ( mapFile, title );
9061  CMap_io::ccp4_cmap_set_datamode ( mapFile, 2 );
9062 
9063  //======================================== Data: Write the map data
9064  std::vector<float> section( dims[axisOrder[1]-1] * dims[axisOrder[0]-1] );
9065  int index;
9066  int iters[3];
9067  int arrPos;
9068 
9069  for ( iters[2] = 0; iters[2] < dims[axisOrder[2]-1]; iters[2]++ )
9070  {
9071  index = 0;
9072 
9073  for ( iters[1] = 0; iters[1] < dims[axisOrder[1]-1]; iters[1]++ )
9074  {
9075  for ( iters[0] = 0; iters[0] < dims[axisOrder[0]-1]; iters[0]++ )
9076  {
9077  arrPos = iters[2] + (dims[axisOrder[2]-1]) * ( iters[1] + (dims[axisOrder[1]-1]) * iters[0] );
9078 
9079  section[ index++ ] = static_cast<float> ( map[arrPos] );
9080  }
9081  }
9082 
9083  CMap_io::ccp4_cmap_write_section( mapFile, &section[0] );
9084  }
9085 
9086  CMap_io::ccp4_cmap_close ( mapFile );
9087 
9088  //======================================== Done
9089  return ;
9090 
9091 }
9092 
9093 /* \brief This function writes out a map in the CCP4 MAP format.
9094 
9095  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,
9096  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
9097  allow great control over the map output. Internally, the function uses the CCP4's CMAPLIB functionality.
9098 
9099  \param[in] fileName String file name of where the map should be saved. Will override if already exists.
9100  \param[in] map Float pointer to array of map values in the U, V, W order.
9101  \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'.
9102  \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!
9103  \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!
9104  \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!
9105  \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!
9106  \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!
9107  \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!
9108  \param[in] xRange Dimension size (x-axis) in angstroms.
9109  \param[in] yRange Dimension size (y-axis) in angstroms.
9110  \param[in] zRange Dimension size (z-axis) in angstroms.
9111 
9112  \warning This is an internal function which should not be used by the user.
9113  */
9114 
9115 void ProSHADE_internal::ProSHADE_data::writePDB ( std::string templateName,
9116  std::string outputName,
9117  double rotEulA,
9118  double rotEulB,
9119  double rotEulG,
9120  double trsX,
9121  double trsY,
9122  double trsZ )
9123 {
9124  //======================================== Read in PDB template file
9125  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
9126  if ( mfile->ReadCoorFile ( templateName.c_str() ) )
9127  {
9128  std::cerr << "!!! ProSHADE ERROR !!! Cannot read file: " << templateName.c_str() << std::endl;
9129  exit ( -1 );
9130  }
9131 
9132  //======================================== Initialise Centre location
9133  double maxX = 0.0;
9134  double minX = 0.0;
9135  double maxY = 0.0;
9136  double minY = 0.0;
9137  double maxZ = 0.0;
9138  double minZ = 0.0;
9139  bool firstAtom = true;
9140 
9141  //======================================== Initialise MMDB crawl
9142  int noChains = 0;
9143  int noResidues = 0;
9144  int noAtoms = 0;
9145 
9146  clipper::mmdb::PPCChain chain;
9147  clipper::mmdb::PPCResidue residue;
9148  clipper::mmdb::PPCAtom atom;
9149 
9150  std::vector < std::array<double,3> > atCoords;
9151  std::array<double,3> hlpArr;
9152 
9153  //======================================== Get all chains
9154  mfile->GetChainTable ( 1, chain, noChains );
9155  firstAtom = true;
9156  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9157  {
9158  if ( chain[nCh] )
9159  {
9160  //================================ Get all residues
9161  chain[nCh]->GetResidueTable ( residue, noResidues );
9162 
9163  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9164  {
9165  if ( residue[nRes] )
9166  {
9167  //======================== Get all atoms
9168  residue[nRes]->GetAtomTable ( atom, noAtoms );
9169 
9170  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9171  {
9172  if ( atom[aNo] )
9173  {
9174  //================ Check for termination 'residue'
9175  if ( atom[aNo]->Ter ) { continue; }
9176 
9177  //================ Save coords for easier manipulation
9178  hlpArr[0] = atom[aNo]->x;
9179  hlpArr[1] = atom[aNo]->y;
9180  hlpArr[2] = atom[aNo]->z;
9181  atCoords.emplace_back ( hlpArr );
9182 
9183  //================ Find axis maxs and mins
9184  if ( firstAtom )
9185  {
9186  maxX = atom[aNo]->x;
9187  minX = atom[aNo]->x;
9188  maxY = atom[aNo]->y;
9189  minY = atom[aNo]->y;
9190  maxZ = atom[aNo]->z;
9191  minZ = atom[aNo]->z;
9192  firstAtom = false;
9193  }
9194  else
9195  {
9196  if ( atom[aNo]->x > maxX ) { maxX = atom[aNo]->x; } if ( atom[aNo]->x < minX ) { minX = atom[aNo]->x; }
9197  if ( atom[aNo]->y > maxY ) { maxY = atom[aNo]->y; } if ( atom[aNo]->y < minY ) { minY = atom[aNo]->y; }
9198  if ( atom[aNo]->z > maxZ ) { maxZ = atom[aNo]->z; } if ( atom[aNo]->z < minZ ) { minZ = atom[aNo]->z; }
9199  }
9200  }
9201  }
9202  }
9203  }
9204  }
9205  }
9206 
9207  //======================================== Apply the rotation if need be
9208  if ( ( rotEulA != 0.0 ) || ( rotEulB != 0.0 ) || ( rotEulG != 0.0 ) )
9209  {
9210  // ... center on centre of cell
9211  double xRng = ( maxX - minX ) / 2.0;
9212  double yRng = ( maxY - minY ) / 2.0;
9213  double zRng = ( maxZ - minZ ) / 2.0;
9214  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9215  {
9216  atCoords.at(iter)[0] = ( atCoords.at(iter)[0] - minX ) - xRng;
9217  atCoords.at(iter)[1] = ( atCoords.at(iter)[1] - minY ) - yRng;
9218  atCoords.at(iter)[2] = ( atCoords.at(iter)[2] - minZ ) - zRng;
9219  }
9220 
9221  // ... get rotation matrix
9222  std::vector< std::vector < double > > rMat;
9223  std::vector< double > hlpVec;
9224  hlpVec.emplace_back ( cos ( rotEulA ) * cos ( rotEulB ) * cos ( rotEulG ) - sin ( rotEulA ) * sin ( rotEulG ) );
9225  hlpVec.emplace_back ( sin ( rotEulA ) * cos ( rotEulB ) * cos ( rotEulG ) + cos ( rotEulA ) * sin ( rotEulG ) );
9226  hlpVec.emplace_back ( -sin ( rotEulB ) * cos ( rotEulG ) );
9227  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9228 
9229  hlpVec.emplace_back ( -cos ( rotEulA ) * cos ( rotEulB ) * sin ( rotEulG ) - sin ( rotEulA ) * cos ( rotEulG ) );
9230  hlpVec.emplace_back ( -sin ( rotEulA ) * cos ( rotEulB ) * sin ( rotEulG ) + cos ( rotEulA ) * cos ( rotEulG ) );
9231  hlpVec.emplace_back ( sin ( rotEulB ) * sin ( rotEulG ) );
9232  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9233 
9234  hlpVec.emplace_back ( cos ( rotEulA ) * sin ( rotEulB ) );
9235  hlpVec.emplace_back ( sin ( rotEulA ) * sin ( rotEulB ) );
9236  hlpVec.emplace_back ( cos ( rotEulB ) );
9237  rMat.emplace_back ( hlpVec ); hlpVec.clear();
9238 
9239  // ... rotate coords
9240  double hlpXVal = 0.0;
9241  double hlpYVal = 0.0;
9242  double hlpZVal = 0.0;
9243  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9244  {
9245  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) );
9246  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) );
9247  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) );
9248 
9249  atCoords.at(iter)[0] = hlpXVal;
9250  atCoords.at(iter)[1] = hlpYVal;
9251  atCoords.at(iter)[2] = hlpZVal;
9252  }
9253 
9254  // ... move coords back to original positions
9255  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9256  {
9257  atCoords.at(iter)[0] = ( atCoords.at(iter)[0] + xRng ) + minX;
9258  atCoords.at(iter)[1] = ( atCoords.at(iter)[1] + yRng ) + minY;
9259  atCoords.at(iter)[2] = ( atCoords.at(iter)[2] + zRng ) + minZ;
9260  }
9261  }
9262 
9263  //======================================== Translate coordinates as required
9264  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( atCoords.size() ); iter++ )
9265  {
9266  atCoords.at(iter)[0] = atCoords.at(iter)[0] + trsX;
9267  atCoords.at(iter)[1] = atCoords.at(iter)[1] + trsY;
9268  atCoords.at(iter)[2] = atCoords.at(iter)[2] + trsZ;
9269  }
9270 
9271  //======================================== Save coords back to the PDB structure
9272  unsigned int atIt = 0;
9273  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9274  {
9275  if ( chain[nCh] )
9276  {
9277  //================================ Get all residues
9278  chain[nCh]->GetResidueTable ( residue, noResidues );
9279 
9280  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9281  {
9282  if ( residue[nRes] )
9283  {
9284  //======================== Get all atoms
9285  residue[nRes]->GetAtomTable ( atom, noAtoms );
9286 
9287  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9288  {
9289  if ( atom[aNo] )
9290  {
9291  //================ Check for termination 'residue'
9292  if ( atom[aNo]->Ter ) { continue; }
9293 
9294  //================ Save coords for easier manipulation
9295  atom[aNo]->SetCoordinates ( atCoords.at(atIt)[0],
9296  atCoords.at(atIt)[1],
9297  atCoords.at(atIt)[2],
9298  atom[aNo]->occupancy,
9299  atom[aNo]->tempFactor );
9300  atIt += 1;
9301 
9302  }
9303  }
9304  }
9305  }
9306  }
9307  }
9308 
9309  //======================================== Write the PDB file
9310  if ( mfile->WritePDBASCII ( outputName.c_str() ) )
9311  {
9312  std::cerr << "!!! ProSHADE ERROR !!! Failed to write out PDB file " << outputName.c_str() << "." << std::endl;
9313  exit ( -1 );
9314  }
9315 
9316  //======================================== Done
9317  return ;
9318 }
9319 
9320 /* \brief This function deletes a PDB model from the map densiry.
9321 
9322  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
9323  which may already have model assigned.
9324  .
9325  \param[in] modelPath The path to the PDB file containing the model.
9326 
9327  \warning This is an internal function which should not be used by the user.
9328  */
9329 
9330 void ProSHADE_internal::ProSHADE_data::deleteModel ( std::string modelPath )
9331 {
9332  //======================================== Init
9333  double vanDerWaals = 1.7;
9334  double smoothing = vanDerWaals * 2.0;
9335 
9336  //======================================== Read in file
9337  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
9338  if ( mfile->ReadCoorFile ( modelPath.c_str() ) )
9339  {
9340  std::cerr << "!!! ProSHADE ERROR !!! Cannot read model file: " << modelPath.c_str() << std::endl;
9341  exit ( -1 );
9342  }
9343 
9344  //======================================== Initialise MMDB crawl
9345  int noChains = 0;
9346  int noResidues = 0;
9347  int noAtoms = 0;
9348  std::vector<std::array<double,3>> coords;
9349  std::array<double,3> hlpArr;
9350 
9351  clipper::mmdb::PPCChain chain;
9352  clipper::mmdb::PPCResidue residue;
9353  clipper::mmdb::PPCAtom atom;
9354 
9355  //======================================== Get all chains
9356  mfile->GetChainTable ( 1, chain, noChains );
9357  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
9358  {
9359  if ( chain[nCh] )
9360  {
9361  //================================ Get all residues
9362  chain[nCh]->GetResidueTable ( residue, noResidues );
9363 
9364  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
9365  {
9366  if ( residue[nRes] )
9367  {
9368  //======================== Get all atoms
9369  residue[nRes]->GetAtomTable ( atom, noAtoms );
9370 
9371  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
9372  {
9373  if ( atom[aNo] )
9374  {
9375  //================ Check for termination 'residue'
9376  if ( atom[aNo]->Ter ) { continue; }
9377 
9378  //================ Save the coords
9379  hlpArr[0] = atom[aNo]->x;
9380  hlpArr[1] = atom[aNo]->y;
9381  hlpArr[2] = atom[aNo]->z;
9382 
9383  //================ And save to vector
9384  coords.emplace_back ( hlpArr );
9385  }
9386  }
9387  }
9388  }
9389  }
9390  }
9391 
9392  //======================================== Free memory
9393  delete mfile;
9394 
9395  //======================================== Allocate and pre-set bew mask
9396  double* remMask = new double[(this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1)];
9397  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1) ); iter++ )
9398  {
9399  remMask[iter] = 1.0;
9400  }
9401 
9402  //======================================== For each map position
9403  double xFromSM = 0.0;
9404  double xToSM = 0.0;
9405  double yFromSM = 0.0;
9406  double yToSM = 0.0;
9407  double zFromSM = 0.0;
9408  double zToSM = 0.0;
9409 
9410  double xRealStart = ( this->_xFrom / static_cast<double>( this->_maxMapU + 1 ) ) * this->_xRange;
9411  double yRealStart = ( this->_yFrom / static_cast<double>( this->_maxMapV + 1 ) ) * this->_yRange;
9412  double zRealStart = ( this->_zFrom / static_cast<double>( this->_maxMapW + 1 ) ) * this->_zRange;
9413 
9414  double xRealStep = 1.0 / static_cast<double>( this->_maxMapU + 1 ) * this->_xRange;
9415  double yRealStep = 1.0 / static_cast<double>( this->_maxMapV + 1 ) * this->_yRange;
9416  double zRealStep = 1.0 / static_cast<double>( this->_maxMapW + 1 ) * this->_zRange;
9417 
9418  double xHlp = 0.0;
9419  double yHlp = 0.0;
9420  double zHlp = 0.0;
9421 
9422  double dist = 0.0;
9423 
9424  int arrPos = 0;
9425  int uIter = 0;
9426  int vIter = 0;
9427  int wIter = 0;
9428 
9429 
9430  for ( int cIt = 0; cIt < static_cast<int> ( coords.size() ); cIt++ )
9431  {
9432  xFromSM = coords.at(cIt)[0] - smoothing;
9433  xToSM = coords.at(cIt)[0] + smoothing;
9434  yFromSM = coords.at(cIt)[1] - smoothing;
9435  yToSM = coords.at(cIt)[1] + smoothing;
9436  zFromSM = coords.at(cIt)[2] - smoothing;
9437  zToSM = coords.at(cIt)[2] + smoothing;
9438 
9439  uIter = 0;
9440  for ( double uIt = xRealStart; uIt < static_cast<double> ( ( this->_xTo / static_cast<double>( this->_maxMapU + 1 ) ) * this->_xRange ); uIt += xRealStep )
9441  {
9442  if ( ( uIt < xFromSM ) || ( uIt > xToSM ) ) { uIter += 1; continue; }
9443  xHlp = pow ( uIt - coords.at(cIt)[0], 2.0 );
9444 
9445  vIter = 0;
9446  for ( double vIt = yRealStart; vIt < static_cast<double> ( ( this->_yTo / static_cast<double>( this->_maxMapV + 1 ) ) * this->_yRange ); vIt += yRealStep )
9447  {
9448  if ( ( vIt < yFromSM ) || ( vIt > yToSM ) ) { vIter += 1; continue; }
9449  yHlp = pow ( vIt - coords.at(cIt)[1], 2.0 );
9450 
9451  wIter = 0;
9452  for ( double wIt = zRealStart; wIt < static_cast<double> ( ( this->_zTo / static_cast<double>( this->_maxMapW + 1 ) ) * this->_zRange ); wIt += zRealStep )
9453  {
9454  if ( ( wIt < zFromSM ) || ( wIt > zToSM ) ) { wIter += 1; continue; }
9455  zHlp = pow ( wIt - coords.at(cIt)[2], 2.0 );
9456 
9457  arrPos = wIter + (this->_maxMapW + 1) * ( vIter + (this->_maxMapV + 1) * uIter );
9458  dist = sqrt ( xHlp + yHlp + zHlp );
9459 
9460  if ( dist < vanDerWaals ) { remMask[arrPos] = 0.0; continue; }
9461  if ( dist < smoothing )
9462  {
9463  remMask[arrPos] = ( 1.0 - cos ( ( M_PI * ( dist - vanDerWaals ) ) / ( smoothing - vanDerWaals ) ) ) / 2.0;
9464  }
9465 
9466  wIter += 1;
9467  }
9468 
9469  vIter += 1;
9470  }
9471 
9472  uIter += 1;
9473  }
9474  }
9475 
9476  //======================================== Delete and see?
9477  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU + 1) * (this->_maxMapV + 1) * (this->_maxMapW + 1) ); iter++ )
9478  {
9479  this->_densityMapMap[iter] *= remMask[iter];
9480  }
9481 
9482  //======================================== Free memory
9483  delete[] remMask;
9484 
9485  //======================================== Done
9486  return ;
9487 
9488 }
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.
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:179
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:185
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:188
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:182
The main header file containing all declarations for the innter workings of the library.
int htmlReportLine
Iterator for current HTML line.
Definition: ProSHADE.h:186
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:187
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