ProSHADE  0.6.5 (NOV 2018)
Protein Shape Descriptors and Symmetry Detection
ProSHADE.cpp
Go to the documentation of this file.
1 
21 //============================================ Clipper
22 #include <clipper/clipper.h>
23 #include <clipper/clipper-contrib.h>
24 #include <clipper/clipper-ccp4.h>
25 #include <clipper/clipper-mmdb.h>
26 #include <clipper/clipper-minimol.h>
27 
28 //============================================ FFTW3 + SOFT
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 #include <fftw3.h>
33 #include <wrap_fftw.h>
34 #include <makeweights.h>
35 #include <s2_primitive.h>
36 #include <s2_cospmls.h>
37 #include <s2_legendreTransforms.h>
38 #include <s2_semi_fly.h>
39 #include <rotate_so3_utils.h>
40 #include <utils_so3.h>
41 #include <soft_fftw.h>
42 #include <rotate_so3_fftw.h>
43 #ifdef __cplusplus
44 }
45 #endif
46 
47 //============================================ CMAPLIB
48 #include <cmaplib.h>
49 
50 //============================================ RVAPI
51 #include <rvapi_interface.h>
52 
53 //============================================ ProSHADE
54 #include "ProSHADE.h"
55 #include "ProSHADE_internal.h"
56 #include "ProSHADE_files.h"
57 #include "ProSHADE_misc.h"
58 #include "ProSHADE_legendre.h"
59 #include "ProSHADE_rvapi.h"
60 
70 {
71  //======================================== Settings regarding resolutions
72  this->mapResolution = 8.0;
73  this->wasResolutionGiven = false;
74  this->bandwidth = 0;
75  this->wasBandGiven = false;
76  this->glIntegOrder = 0;
77  this->theta = 0;
78  this->phi = 0;
79  this->mapResDefault = true;
80 
81  //======================================== Settings regarding B factors
82  this->bFactorValue = 80.0;
83  this->bFactorChange = 0.0;
84  this->wasBChangeGiven = false;
85 
86  //======================================== Settings regarding phase
87  this->usePhase = true;
88  this->saveWithAndWithout = false;
89 
90  //======================================== Settings regarding concentric shells
91  this->shellSpacing = 0.0;
92  this->wasShellSpacingGiven = false;
93  this->manualShells = 0;
94 
95  //======================================== Settings regarding map with phases
96  this->useCOM = true;
97  this->firstLineCOM = false;
98 
99  //======================================== Settings regarding space around the structure in lattice
100  this->extraSpace = 8.0;
101  this->wasExtraSpaceGiven = false;
102 
103  //======================================== Settings regarding weighting the distances
104  this->alpha = 1.0;
105  this->mPower = 1.0;
106 
107  //======================================== Settings regarding the map masking threshold
108  this->noIQRsFromMap = 4.0;
109 
110  //======================================== Settings regarding peak finding
111  this->peakHeightNoIQRs = 3.0;
112  this->peakDistanceForReal = 0.2;
113  this->peakSurroundingPoints = 1;
114 
115  //======================================== Settings regarding which distances to compute
116  this->energyLevelDist = true;
117  this->traceSigmaDist = true;
118  this->fullRotFnDist = true;
119 
120  //======================================== Settings regarding symmetry detection
121  this->aaErrorTolerance = 0.1;
122  this->symGapTolerance = 0.2;
123 
124  //======================================== Settings regarding hierarchical distances computation
125  this->enLevelsThreshold = -999.9;
126  this->trSigmaThreshold = -999.9;
127 
128  //======================================== Settings regarding bands to ignore
129  this->ignoreLs.emplace_back ( 0 );
130 
131  //======================================== Settings regarding the task to perform
132  this->taskToPerform = NA;
133 
134  //======================================== Settings regarding where and if to save the clear map
135  this->clearMapFile = "";
136  this->useCubicMaps = false;
137  this->clearMapData = false;
138  this->maskBlurFactor = 500.0;
139  this->maskBlurFactorGiven = false;
140 
141  //======================================== Settings regarding map fragmentation
142  this->mapFragBoxSize = 0.0;
143  this->mapFragName = "./mapFrag";
144  this->mapFragBoxFraction = 0.5;
145 
146  //======================================== Settings regarding the database
147  this->databaseName = "";
148  this->databaseMaxVolume = 0.0;
149  this->databaseMinVolume = 0.0;
150  this->volumeTolerance = 0.2;
151 
152  //======================================== Settings regarding the symmetry type required
153  this->symmetryFold = 0;
154  this->symmetryType = "";
155 
156  //======================================== Settings regarding the map rotation mode
157  this->rotAngle = 0.0;
158  this->rotXAxis = 0.0;
159  this->rotYAxis = 0.0;
160  this->rotZAxis = 0.0;
161  this->rotChangeDefault = false;
162  this->xTranslation = 0.0;
163  this->yTranslation = 0.0;
164  this->zTranslation = 0.0;
165 
166  //======================================== Settings regarding the map overlay mode
167  this->overlayDefaults = false;
168  this->dbDistOverlay = false;
169  this->resizeMovingStructure = false;
170  this->maxRotError = 0;
171  this->deleteModels = std::vector<std::string> ( );
172 
173  //======================================== Settings regarding the map saving mode
174  this->axisOrder = "xyz";
175 
176  //======================================== Settings regarding the verbosity of the program
177  this->htmlReport = true;
178  this->htmlReportLine = 0;
179  this->htmlReportLineProgress = 0;
180  this->verbose = 1;
181 
182 }
183 
191 {
192  if ( this->verbose > 3 )
193  {
194  std::cout << "-----------------------------------------------------------" << std::endl;
195  std::cout << "| SETTINGS: |" << std::endl;
196  std::cout << "-----------------------------------------------------------" << std::endl;
197  std::stringstream strstr2;
198  strstr2 << this->mapResolution;
199  printf ( "Resolution : %37s\n", strstr2.str().c_str() );
200 
201  std::stringstream strstr3;
202  strstr3 << this->bandwidth;
203  printf ( "Bandwidth : %37s\n", strstr3.str().c_str() );
204 
205  strstr3.str(std::string());
206  strstr3 << this->glIntegOrder;
207  printf ( "Integration order : %37s\n", strstr3.str().c_str() );
208 
209  strstr3.str(std::string());
210  strstr3 << this->theta;
211  printf ( "Theta angle : %37s\n", strstr3.str().c_str() );
212 
213  strstr3.str(std::string());
214  strstr3 << this->phi;
215  printf ( "Phi angle : %37s\n", strstr3.str().c_str() );
216 
217  strstr3.str(std::string());
218  strstr3 << this->bFactorValue;
219  printf ( "B-factor value : %37s\n", strstr3.str().c_str() );
220 
221  strstr3.str(std::string());
222  strstr3 << this->bFactorChange;
223  printf ( "B-factor change : %37s\n", strstr3.str().c_str() );
224 
225  strstr3.str(std::string());
226  if ( this->usePhase ) { strstr3 << "TRUE"; }
227  else { strstr3 << "FALSE"; }
228  printf ( "Use phase : %37s\n", strstr3.str().c_str() );
229 
230  strstr3.str(std::string());
231  if ( this->useCOM ) { strstr3 << "TRUE"; }
232  else { strstr3 << "FALSE"; }
233  printf ( "Use COM to center : %37s\n", strstr3.str().c_str() );
234 
235  strstr3.str(std::string());
236  if ( this->firstLineCOM ) { strstr3 << "TRUE"; }
237  else { strstr3 << "FALSE"; }
238  printf ( "Use first line COM : %37s\n", strstr3.str().c_str() );
239 
240  strstr3.str(std::string());
241  strstr3 << this->shellSpacing;
242  printf ( "Shell distances in A: %37s\n", strstr3.str().c_str() );
243 
244  strstr3.str(std::string());
245  strstr3 << this->manualShells;
246  printf ( "Manual no shells : %37s\n", strstr3.str().c_str() );
247 
248  strstr3.str(std::string());
249  strstr3 << this->extraSpace;
250  printf ( "Extra cell space : %37s\n", strstr3.str().c_str() );
251 
252  strstr3.str(std::string());
253  strstr3 << this->alpha;
254  printf ( "Raise |F| to power : %37s\n", strstr3.str().c_str() );
255 
256  strstr3.str(std::string());
257  strstr3 << this->mPower;
258  printf ( "Cross-cor weighting : %37s\n", strstr3.str().c_str() );
259 
260  strstr3.str(std::string());
261  strstr3 << this->noIQRsFromMap;
262  printf ( "IQRs masking thres : %37s\n", strstr3.str().c_str() );
263 
264  strstr3.str(std::string());
265  strstr3 << this->peakHeightNoIQRs;
266  printf ( "IQRs peak thres : %37s\n", strstr3.str().c_str() );
267 
268  strstr3.str(std::string());
269  strstr3 << this->peakDistanceForReal;
270  printf ( "Peak similarity thr : %37s\n", strstr3.str().c_str() );
271 
272  strstr3.str(std::string());
273  strstr3 << this->peakSurroundingPoints;
274  printf ( "Peak width : %37s\n", strstr3.str().c_str() );
275 
276  strstr3.str(std::string());
277  if ( this->energyLevelDist ) { strstr3 << "TRUE"; }
278  else { strstr3 << "FALSE"; }
279  printf ( "Get cross-cor dists : %37s\n", strstr3.str().c_str() );
280 
281  strstr3.str(std::string());
282  if ( this->traceSigmaDist ) { strstr3 << "TRUE"; }
283  else { strstr3 << "FALSE"; }
284  printf ( "Get tr sigma dists : %37s\n", strstr3.str().c_str() );
285 
286  strstr3.str(std::string());
287  if ( this->fullRotFnDist ) { strstr3 << "TRUE"; }
288  else { strstr3 << "FALSE"; }
289  printf ( "Get rot func dists : %37s\n", strstr3.str().c_str() );
290 
291  strstr3.str(std::string());
292  strstr3 << this->aaErrorTolerance;
293  printf ( "Symmetry axis toler : %37s\n", strstr3.str().c_str() );
294 
295  strstr3.str(std::string());
296  strstr3 << this->symGapTolerance;
297  printf ( "Symmetry gap toler : %37s\n", strstr3.str().c_str() );
298 
299  strstr3.str(std::string());
300  strstr3 << this->enLevelsThreshold;
301  printf ( "Cross-cor hierar thr: %37s\n", strstr3.str().c_str() );
302 
303  strstr3.str(std::string());
304  strstr3 << this->trSigmaThreshold;
305  printf ( "Tr sigma hierar thr : %37s\n", strstr3.str().c_str() );
306 
307  strstr3.str(std::string());
308  strstr3 << 0;
309  for ( int i = 0; i < static_cast<int> ( this->ignoreLs.size() ); i++ )
310  {
311  if ( this->ignoreLs.at(i) != 0 )
312  {
313  strstr3 << ", " << this->ignoreLs.at(i);
314  }
315  }
316  printf ( "Bands to ignore : %37s\n", strstr3.str().c_str() );
317 
318  strstr3.str(std::string());
319  strstr3 << "\"" << this->clearMapFile << "\"";
320  printf ( "Map saving location : %37s\n", strstr3.str().c_str() );
321 
322  strstr3.str(std::string());
323  if ( this->useCubicMaps ) { strstr3 << "TRUE"; }
324  else { strstr3 << "FALSE"; }
325  printf ( "Use cubic maps : %37s\n", strstr3.str().c_str() );
326 
327  strstr3.str(std::string());
328  if ( this->clearMapData ) { strstr3 << "TRUE"; }
329  else { strstr3 << "FALSE"; }
330  printf ( "Map noice removal : %37s\n", strstr3.str().c_str() );
331 
332  strstr3.str(std::string());
333  strstr3 << this->maskBlurFactor;
334  printf ( "Map mask blurring : %37s\n", strstr3.str().c_str() );
335 
336  strstr3.str(std::string());
337  if ( this->maskBlurFactorGiven ) { strstr3 << "TRUE"; }
338  else { strstr3 << "FALSE"; }
339  printf ( "Blur. factor given : %37s\n", strstr3.str().c_str() );
340 
341  strstr3.str(std::string());
342  strstr3 << this->maxRotError;
343  printf ( "Max Rotation Error : %37s\n", strstr3.str().c_str() );
344 
345  strstr3.str(std::string());
346  strstr3 << this->mapFragBoxSize;
347  printf ( "Map fragm box size : %37s\n", strstr3.str().c_str() );
348 
349  strstr3.str(std::string());
350  strstr3 << this->mapFragName;
351  printf ( "Map fragm save name : %37s\n", strstr3.str().c_str() );
352 
353  strstr3.str(std::string());
354  strstr3 << this->mapFragBoxFraction;
355  printf ( "Map frag min density: %37s\n", strstr3.str().c_str() );
356 
357  strstr3.str(std::string());
358  strstr3 << "\"" << this->databaseName << "\"";
359  printf ( "Database name : %37s\n", strstr3.str().c_str() );
360 
361  strstr3.str(std::string());
362  strstr3 << this->volumeTolerance;
363  printf ( "Database volume tol : %37s\n", strstr3.str().c_str() );
364 
365  strstr3.str(std::string());
366  strstr3 << this->symmetryFold;
367  printf ( "Required sym fold : %37s\n", strstr3.str().c_str() );
368 
369  strstr3.str(std::string());
370  strstr3 << "\'" << this->symmetryType << "\'";
371  printf ( "Required sym type : %37s\n", strstr3.str().c_str() );
372 
373  strstr3.str(std::string());
374  strstr3 << this->rotAngle;
375  printf ( "Map rotation angle : %37s\n", strstr3.str().c_str() );
376 
377  strstr3.str(std::string());
378  strstr3 << this->rotXAxis;
379  printf ( "Map rotation X-axis : %37s\n", strstr3.str().c_str() );
380 
381  strstr3.str(std::string());
382  strstr3 << this->rotYAxis;
383  printf ( "Map rotation Y-axis : %37s\n", strstr3.str().c_str() );
384 
385  strstr3.str(std::string());
386  strstr3 << this->rotZAxis;
387  printf ( "Map rotation Z-axis : %37s\n", strstr3.str().c_str() );
388 
389  strstr3.str(std::string());
390  strstr3 << this->xTranslation;
391  printf ( "Map transl. X-axis : %37s\n", strstr3.str().c_str() );
392 
393  strstr3.str(std::string());
394  strstr3 << this->yTranslation;
395  printf ( "Map transl. Y-axis : %37s\n", strstr3.str().c_str() );
396 
397  strstr3.str(std::string());
398  strstr3 << this->zTranslation;
399  printf ( "Map transl. Z-axis : %37s\n", strstr3.str().c_str() );
400 
401  strstr3.str(std::string());
402  strstr3 << this->axisOrder;
403  printf ( "Out map axis order : %37s\n", strstr3.str().c_str() );
404 
405  strstr3.str(std::string());
406  strstr3 << this->verbose;
407  printf ( "Verbose : %37s\n\n", strstr3.str().c_str() );
408 
409  strstr3.str(std::string());
410  if ( this->taskToPerform == Symmetry ) { strstr3 << "SYMMETRY DETECTION"; }
411  if ( this->taskToPerform == Distances ) { strstr3 << "DISTANCES COMPUTATION"; }
412  if ( this->taskToPerform == Features ) { strstr3 << "MAP FEATURES EXTRACTION"; }
413  if ( this->taskToPerform == BuildDB ) { strstr3 << "BUILD STRUCTURE DATABASE"; }
414  if ( this->taskToPerform == DistancesFrag ) { strstr3 << "FRAGMENT DISTANCES"; }
415  if ( this->taskToPerform == HalfMaps ) { strstr3 << "HALF MAPS RE-BOXING"; }
416  if ( this->taskToPerform == RotateMap ) { strstr3 << "MAP ROTATION"; }
417  if ( this->taskToPerform == OverlayMap ) { { strstr3 << "MAP OVERLAY"; } }
418  if ( this->taskToPerform == SimpleRebox ) { { strstr3 << "MAP RE-BOXING"; } }
419  printf ( "Task to perform : %37s\n", strstr3.str().c_str() );
420 
421  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
422  }
423 
424 }
425 
434  char** argv )
435 {
436  //======================================== If no command line arguments, print help
437  if ( argc == 1 ) { ProSHADE_internal_misc::printHelp ( ); }
438 
439  //======================================== Long options struct
440  const struct option longopts[] =
441  {
442  { "version", no_argument, nullptr, 'v' },
443  { "help", no_argument, nullptr, 'h' },
444  { "distances", no_argument, nullptr, 'D' },
445  { "buildDB", no_argument, nullptr, 'B' },
446  { "features", no_argument, nullptr, 'F' },
447  { "symmetry", no_argument, nullptr, 'S' },
448  { "distancesFrag", no_argument, nullptr, 'M' },
449  { "halpMaps", no_argument, nullptr, 'H' },
450  { "strOverlay", no_argument, nullptr, 'O' },
451  { "reBox", no_argument, nullptr, 'E' },
452  { "rotate", no_argument, nullptr, 'R' },
453  { "no_phase", no_argument, nullptr, 'p' },
454  { "no_COM", no_argument, nullptr, 'c' },
455  { "fl_Cen", no_argument, nullptr, 'l' },
456  { "no_crCorr", no_argument, nullptr, 'e' },
457  { "no_trSig", no_argument, nullptr, 't' },
458  { "no_rotFn", no_argument, nullptr, 'r' },
459  { "clear", no_argument, nullptr, 'y' },
460  { "cubic", no_argument, nullptr, 'U' },
461  { "no_report", no_argument, nullptr, 'A' },
462  { "resizeOverlay", no_argument, nullptr, 'C' },
463  { "f", required_argument, nullptr, 'f' },
464  { "fileList", required_argument, nullptr, 'i' },
465  { "delModel", required_argument, nullptr, 'P' },
466  { "bandList", required_argument, nullptr, 'b' },
467  { "resolution", required_argument, nullptr, 's' },
468  { "bandWidth", required_argument, nullptr, 'a' },
469  { "integration", required_argument, nullptr, 'n' },
470  { "maxRotErr", required_argument, nullptr, 'L' },
471  { "sym", required_argument, nullptr, 'u' },
472  { "clearMap", required_argument, nullptr, 'm' },
473  { "axisOrder", required_argument, nullptr, 'g' },
474  { "dbFile", required_argument, nullptr, 'x' },
475  { "bValues", required_argument, nullptr, '{' },
476  { "bChange", required_argument, nullptr, '}' },
477  { "sphDistance", required_argument, nullptr, '[' },
478  { "sphNumber", required_argument, nullptr, ']' },
479  { "mapMaskThres", required_argument, nullptr, '(' },
480  { "mapMaskBlur", required_argument, nullptr, 'K' },
481  { "cellBorderSpace", required_argument, nullptr, ')' },
482  { "fPower", required_argument, nullptr, '@' },
483  { "mPower", required_argument, nullptr, '%' },
484  { "peakSize", required_argument, nullptr, '^' },
485  { "peakThres", required_argument, nullptr, '&' },
486  { "peakMinSim", required_argument, nullptr, '*' },
487  { "axisTolerance", required_argument, nullptr, 'Q' },
488  { "symGap", required_argument, nullptr, 'q' },
489  { "CCThres", required_argument, nullptr, 'W' },
490  { "TSThres", required_argument, nullptr, 'w' },
491  { "mFrag", required_argument, nullptr, 'o' },
492  { "mBoxFrac", required_argument, nullptr, 'G' },
493  { "mBoxPath", required_argument, nullptr, 'T' },
494  { "dbSizeLim", required_argument, nullptr, 'Y' },
495  { "rotAng", required_argument, nullptr, '<' },
496  { "rotX", required_argument, nullptr, '>' },
497  { "rotY", required_argument, nullptr, '~' },
498  { "rotZ", required_argument, nullptr, '|' },
499  { "trsX", required_argument, nullptr, 'N' },
500  { "trsY", required_argument, nullptr, 'J' },
501  { "trsZ", required_argument, nullptr, 'I' },
502  { "verbose", optional_argument, nullptr, 'V' },
503  { nullptr, 0, nullptr, 0 },
504  };
505 
506  //======================================== Change the defaults for Patterson data, unless user supplied their own values
507  bool userRes = false;
508  bool userBVal = false;
509 
510  //======================================== Short options string
511  const char* const shortopts = "vhDBFSMHOERpcletryUACf:i:P:b:s:a:n:L:u:m:g:x:{:}:[:]:(:K:):@:^:&:*:Q:q:W:w:o:G:T:Y:<:>:~:|:N:J:I:V::?";
512 
513  //======================================== Parsing the options
514  while ( true )
515  {
516  //==================================== Read the next option
517  const auto opt = getopt_long ( argc, argv, shortopts, longopts, nullptr );
518 
519  //==================================== Done parsing
520  if ( opt == -1 )
521  {
522  break;
523  }
524 
525  //==================================== For each option, set the internal values appropriately
526  const char *tmp_optarg = optarg;
527  switch (opt)
528  {
529  //================================ Patterson should be used instead of phased maps
530  case 'D':
531  {
532  this->taskToPerform = Distances;
533  continue;
534  }
535 
536  //================================ Build the database from the input files
537  case 'B':
538  {
539  this->taskToPerform = BuildDB;
540  continue;
541  }
542 
543  //================================ Find the features of a MAP file
544  case 'F':
545  {
546  this->taskToPerform = Features;
547  continue;
548  }
549 
550  //================================Detect symmetry
551  case 'S':
552  {
553  this->taskToPerform = Symmetry;
554  this->useCOM = false;
555  this->extraSpace = 0.0;
556  this->mapResolution = 6.0;
557  continue;
558  }
559 
560  //================================ Fragment distances to database required
561  case 'M':
562  {
563  this->taskToPerform = DistancesFrag;
564  continue;
565  }
566 
567  //================================ Half maps will need to be cleared
568  case 'H':
569  {
570  this->taskToPerform = HalfMaps;
571  continue;
572  }
573 
574  //================================ Overlay mode selected
575  case 'O':
576  {
577  this->taskToPerform = OverlayMap;
578  this->clearMapData = false;
579  this->useCOM = false;
580  this->mapResolution = 2.0;
581  this->rotChangeDefault = true;
582  this->extraSpace = -777.7;
583  this->overlayDefaults = true;
584  continue;
585  }
586 
587  //================================ Simple reboxing selected
588  case 'E':
589  {
590  this->taskToPerform = SimpleRebox;
591  this->clearMapData = false;
592  this->useCOM = false;
593  this->mapResolution = 2.0;
594  this->rotChangeDefault = true;
595  this->extraSpace = 3.0;
596  this->overlayDefaults = true;
597  continue;
598  }
599 
600  //================================ Rotate map
601  case 'R':
602  {
603  this->taskToPerform = RotateMap;
604  this->clearMapData = false;
605  this->useCOM = false;
606  this->mapResolution = 1.0;
607  this->ignoreLs = std::vector<int> ();
608  this->rotChangeDefault = true;
609  this->extraSpace = 0.0;
610  continue;
611  }
612 
613  //================================ Patterson should be used instead of phased maps
614  case 'p':
615  {
616  this->usePhase = false;
617  if ( !userBVal )
618  {
619  this->bFactorValue = 120;
620  }
621  if ( !userRes )
622  {
623  this->mapResolution = 9.0;
624  }
625  continue;
626  }
627 
628  //================================ Centreing has already been done
629  case 'c':
630  {
631  this->useCOM = false;
632  continue;
633  }
634 
635  //================================ Centre on the first line coordinates
636  case 'l':
637  {
638  this->firstLineCOM = true;
639  continue;
640  }
641 
642  //================================ No interest in cross-correlation distance
643  case 'e':
644  {
645  this->energyLevelDist = false;
646  continue;
647  }
648 
649  //================================ No interest in trace sigma distance
650  case 't':
651  {
652  this->traceSigmaDist = false;
653  continue;
654  }
655 
656  //================================ No interest in rotation function distance
657  case 'r':
658  {
659  this->fullRotFnDist = false;
660  continue;
661  }
662 
663  //================================ No interest in rotation function distance
664  case 'y':
665  {
666  this->clearMapData = true;
667  continue;
668  }
669 
670  //================================ Do use the cubic clear maps instead of rectangular
671  case 'U':
672  {
673  this->useCubicMaps = true;
674  continue;
675  }
676 
677  //================================ Do not produce the HTML report
678  case 'A':
679  {
680  this->htmlReport = false;
681  continue;
682  }
683 
684  //================================ Do not resize the moving molecule to have same dimensions as the static molecule
685  case 'C':
686  {
687  this->resizeMovingStructure = true;
688  continue;
689  }
690 
691  //================================ File name of input file
692  case 'f':
693  {
694  this->structFiles.emplace_back ( std::string ( optarg ) );
695  continue;
696  }
697 
698  //================================ File list of input files
699  case 'i':
700  {
701  //============================ Open the file
702  std::ifstream textFile ( std::string ( optarg ), std::ios::in );
703 
704  //============================ Check
705  if ( textFile.fail() )
706  {
707  std::cout << "!!! ProSHADE ERROR !!! The filename supplied with the \'-i\' parameter cannot be opened. Terminating..." << std::endl;
708  exit ( -1 );
709  }
710 
711  //============================ Read
712  std::string hlpStr;
713  while ( std::getline ( textFile, hlpStr ) )
714  {
715  this->structFiles.emplace_back ( hlpStr );
716  }
717 
718  //============================ Close
719  textFile.close ();
720  continue;
721  }
722 
723  //================================ File name of model to be deleted
724  case 'P':
725  {
726  this->deleteModels.emplace_back ( std::string ( optarg ) );
727  continue;
728  }
729 
730  //================================ List of bands to ignore
731  case 'b':
732  {
733  this->ignoreLs.emplace_back ( stoi ( std::string ( optarg ) ) );
734  continue;
735  }
736 
737  //================================ List of bands to ignore
738  case 's':
739  {
740  this->mapResolution = stof ( std::string ( optarg ) );
741  userRes = true;
742  this->mapResDefault = false;
743  this->wasResolutionGiven = true;
744  continue;
745  }
746 
747  //================================ Maximum bandwidth
748  case 'a':
749  {
750  this->bandwidth = stof ( std::string ( optarg ) );
751  this->wasBandGiven = true;
752  continue;
753  }
754 
755  //================================ Maximum integration order
756  case 'n':
757  {
758  this->glIntegOrder = stoi ( std::string ( optarg ) );
759  continue;
760  }
761 
762  //================================ Maximum rotation error
763  case 'L':
764  {
765  this->maxRotError = static_cast<unsigned int> ( stoi ( std::string ( optarg ) ) );
766  continue;
767  }
768 
769  //================================ Symmetry required
770  case 'u':
771  {
772  std::string hlpStr = std::string ( optarg );
773  if ( hlpStr.at(0) == 'C' )
774  {
775  this->symmetryType = "C";
776  }
777  else
778  {
779  if ( hlpStr.at(0) == 'D' )
780  {
781  this->symmetryType = "D";
782  }
783  else
784  {
785  if ( hlpStr.at(0) == 'T' )
786  {
787  this->symmetryType = "T";
788  }
789  else
790  {
791  if ( hlpStr.at(0) == 'O' )
792  {
793  this->symmetryType = "O";
794  }
795  else
796  {
797  if ( hlpStr.at(0) == 'I' )
798  {
799  this->symmetryType = "I";
800  }
801  else
802  {
803  ProSHADE_internal_misc::printHelp ( );
804  exit ( -1 );
805  }
806  }
807  }
808  }
809  }
810 
811  if ( ( this->symmetryType == "C" ) || ( this->symmetryType == "D" ) )
812  {
813  std::string numHlp ( hlpStr.begin()+1, hlpStr.end() );
814  if ( numHlp.length() > 0 )
815  {
816  this->symmetryFold = stoi ( numHlp );
817  }
818  else
819  {
820  std::cerr << "!!! ProSHADE ERROR !!! The input argument requests search for Cyclic/Dihedral symmetry, but does not specify the requested fold." << std::endl;
821  exit ( -1 );
822  }
823  }
824  else
825  {
826  this->symmetryFold = 0;
827  std::string numHlp ( hlpStr.begin()+1, hlpStr.end() );
828  if ( numHlp != "" )
829  {
830  ProSHADE_internal_misc::printHelp ( );
831  exit ( -1 );
832  }
833  }
834 
835  continue;
836  }
837 
838  //================================ Clear map location
839  case 'm':
840  {
841  this->clearMapFile = std::string ( optarg );
842  continue;
843  }
844 
845  //================================ Map axes order
846  case 'g':
847  {
848  this->axisOrder = std::string ( optarg );
849  std::transform ( this->axisOrder.begin(),
850  this->axisOrder.end(),
851  this->axisOrder.begin(),
852  ::tolower);
853  if ( this->axisOrder.length() != 3 )
854  {
855  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string of three characters only." << std::endl;
856  exit ( -1 );
857  }
858  if ( ( this->axisOrder[0] != 'x' ) && ( this->axisOrder[0] != 'y' ) && ( this->axisOrder[0] != 'z' ) )
859  {
860  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string consisting of only \'x\', \'y\' and \'z\' characters." << std::endl;
861  exit ( -1 );
862  }
863  if ( ( this->axisOrder[1] != 'x' ) && ( this->axisOrder[1] != 'y' ) && ( this->axisOrder[1] != 'z' ) )
864  {
865  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string consisting of only \'x\', \'y\' and \'z\' characters." << std::endl;
866  exit ( -1 );
867  }
868  if ( ( this->axisOrder[2] != 'x' ) && ( this->axisOrder[2] != 'y' ) && ( this->axisOrder[2] != 'z' ) )
869  {
870  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string consisting of only \'x\', \'y\' and \'z\' characters." << std::endl;
871  exit ( -1 );
872  }
873  if ( ( this->axisOrder[0] != 'x' ) && ( this->axisOrder[1] != 'x' ) && ( this->axisOrder[2] != 'x' ) )
874  {
875  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string with at least one \'x\' character." << std::endl;
876  exit ( -1 );
877  }
878  if ( ( this->axisOrder[0] != 'y' ) && ( this->axisOrder[1] != 'y' ) && ( this->axisOrder[2] != 'y' ) )
879  {
880  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string with at least one \'y\' character." << std::endl;
881  exit ( -1 );
882  }
883  if ( ( this->axisOrder[0] != 'z' ) && ( this->axisOrder[1] != 'z' ) && ( this->axisOrder[2] != 'z' ) )
884  {
885  std::cerr << "!!! ProSHADE ERROR !!! Input parameter error !!! The axisOrder parameter requires a string with at least one \'z\' character." << std::endl;
886  exit ( -1 );
887  }
888  continue;
889  }
890 
891  //================================ Database file location
892  case 'x':
893  {
894  this->databaseName = std::string ( optarg );
895  continue;
896  }
897 
898  //================================ B factor value to which all atoms are changed to
899  case '{':
900  {
901  this->bFactorValue = stof ( std::string ( optarg ) );
902  userBVal = true;
903  continue;
904  }
905 
906  //================================ B factor value change for maps (sharpening/blurring)
907  case '}':
908  {
909  this->bFactorChange = stof ( std::string ( optarg ) );
910  this->wasBChangeGiven = true;
911  continue;
912  }
913 
914  //================================ Distance between concentric spheres
915  case '[':
916  {
917  this->shellSpacing = stof ( std::string ( optarg ) );
918  this->wasShellSpacingGiven = true;
919  continue;
920  }
921 
922  //================================ Maximum number of concentric spheres
923  case ']':
924  {
925  this->manualShells = stoi ( std::string ( optarg ) );
926  continue;
927  }
928 
929  //================================ Number of inter-qusrtile ranges from the third quartile to use as threshold for masking
930  case '(':
931  {
932  this->noIQRsFromMap = stof ( std::string ( optarg ) );
933  continue;
934  }
935 
936  //================================ Amount of blurring to apply to create a mask
937  case 'K':
938  {
939  this->maskBlurFactor = stof ( std::string ( optarg ) );
940  this->maskBlurFactorGiven = true;
941  continue;
942  }
943 
944  //================================ Extra cellular space
945  case ')':
946  {
947  this->extraSpace = stof ( std::string ( optarg ) );
948  this->wasExtraSpaceGiven = true;
949  continue;
950  }
951 
952  //================================ Fourier coefficient power
953  case '@':
954  {
955  this->alpha = stof ( std::string ( optarg ) );
956  continue;
957  }
958 
959  //================================ Cross-correlation descriptor weight
960  case '%':
961  {
962  this->mPower = stof ( std::string ( optarg ) );
963  continue;
964  }
965 
966  //================================ Peak size
967  case '^':
968  {
969  this->peakSurroundingPoints = stoi ( std::string ( optarg ) );
970  continue;
971  }
972 
973  //================================ Peak threshold IQRs
974  case '&':
975  {
976  this->peakHeightNoIQRs = stof ( std::string ( optarg ) );
977  continue;
978  }
979 
980  //================================ Minimum missing peak similarity to become real
981  case '*':
982  {
983  this->peakDistanceForReal = stof ( std::string ( optarg ) );
984  continue;
985  }
986 
987  //================================ Axis tolerance
988  case 'Q':
989  {
990  this->aaErrorTolerance = stof ( std::string ( optarg ) );
991  continue;
992  }
993 
994  //================================ Symmetry gap
995  case 'q':
996  {
997  this->symGapTolerance = stof ( std::string ( optarg ) );
998  continue;
999  }
1000 
1001  //================================ Cross-correlation hierarchical threshold
1002  case 'W':
1003  {
1004  this->enLevelsThreshold = stof ( std::string ( optarg ) );
1005  continue;
1006  }
1007 
1008  //================================ Trace sigma hierarchical threshold
1009  case 'w':
1010  {
1011  this->trSigmaThreshold = stof ( std::string ( optarg ) );
1012  continue;
1013  }
1014 
1015  //================================ Map fragmentation box size
1016  case 'o':
1017  {
1018  this->mapFragBoxSize = stof ( std::string ( optarg ) );
1019  continue;
1020  }
1021 
1022  //================================ Map box fraction full
1023  case 'G':
1024  {
1025  this->mapFragBoxFraction = stof ( std::string ( optarg ) );
1026  continue;
1027  }
1028 
1029  //================================ Map box save path
1030  case 'T':
1031  {
1032  this->mapFragName = std::string ( optarg );
1033  continue;
1034  }
1035 
1036  //================================ Tolerance on volume for struct against db
1037  case 'Y':
1038  {
1039  this->volumeTolerance = stof ( std::string ( optarg ) );
1040  continue;
1041  }
1042 
1043  //================================ The angle by which to rotate the structure
1044  case '<':
1045  {
1046  this->rotAngle = stof ( std::string ( optarg ) );
1047  continue;
1048  }
1049 
1050  //================================ The X-axis of the rotation axis vector
1051  case '>':
1052  {
1053  this->rotXAxis = stof ( std::string ( optarg ) );
1054  continue;
1055  }
1056 
1057  //================================The Y-axis of the rotation axis vector
1058  case '~':
1059  {
1060  this->rotYAxis = stof ( std::string ( optarg ) );
1061  continue;
1062  }
1063 
1064  //================================ The Z-axis of the rotation axis vector
1065  case '|':
1066  {
1067  this->rotZAxis = stof ( std::string ( optarg ) );
1068  continue;
1069  }
1070 
1071  //================================ The X-axis of the translation vector
1072  case 'N':
1073  {
1074  this->xTranslation = stof ( std::string ( optarg ) );
1075  continue;
1076  }
1077 
1078  //================================ The Y-axis of the translation vector
1079  case 'J':
1080  {
1081  this->yTranslation = stof ( std::string ( optarg ) );
1082  continue;
1083  }
1084 
1085  //================================ The Z-axis of the translation vector
1086  case 'I':
1087  {
1088  this->zTranslation = stof ( std::string ( optarg ) );
1089  continue;
1090  }
1091 
1092  //================================ Print version info
1093  case 'V':
1094  {
1095  if ( !optarg && argv[optind] != NULL && argv[optind][0] != '-' )
1096  {
1097  tmp_optarg = argv[optind++];
1098  }
1099 
1100  if ( tmp_optarg )
1101  {
1102  this->verbose = stoi ( std::string ( tmp_optarg ) );
1103  }
1104  else
1105  {
1106  this->verbose = 3;
1107  }
1108 
1109  if ( ( this->verbose < -1 ) || ( this->verbose > 4 ) )
1110  {
1111  printf ( "!!! ProSHADE ERROR !!! The \'--verbose\' option takes only values in range 0 to 4, including. Terminating...\n" );
1112  exit ( -1 );
1113  }
1114 
1115  continue;
1116  }
1117 
1118  //================================ Print version info
1119  case 'v':
1120  {
1121  std::cout << "ProSHADE " << __PROSHADE_VERSION__ << std::endl << std::endl;
1122  exit ( 0 );
1123  }
1124 
1125  //================================ User needs help
1126  case 'h':
1127  {
1128  ProSHADE_internal_misc::printHelp ( );
1129  exit ( 0 );
1130  }
1131 
1132  //================================ Unknown option
1133  case '?':
1134  {
1135  //============================ This case is handled by getopt_long, nothing more needed.
1136  exit ( 0 );
1137  }
1138 
1139  //================================ Fallback option
1140  default:
1141  {
1142  ProSHADE_internal_misc::printHelp ( );
1143  exit ( 0 );
1144  }
1145  }
1146  }
1147 
1148  //======================================== Done
1149  return;
1150 
1151 }
1152 
1153 void ProSHADE::ProSHADE_settings::ignoreLsAddValuePy ( const int val )
1154 {
1155  //======================================== Add the value
1156  this->ignoreLs.emplace_back ( val );
1157 
1158  //======================================== Done
1159  return;
1160 }
1161 
1169 {
1170  //======================================== Initialise variables
1171  this->settings = setUp;
1172 
1173  this->distancesAvailable = false;
1174  this->symmetriesAvailable = false;
1175  this->fragmentsAvailable = false;
1176 
1177  //======================================== Report progress
1178  if ( setUp->verbose > 0 )
1179  {
1180  std::cout << "ProSHADE " << __PROSHADE_VERSION__ << " :" << std::endl;
1181  std::cout << "==========================" << std::endl << std::endl;
1182 
1183  setUp->printSettings ();
1184  }
1185 
1186  //======================================== If no task, report error
1187  if ( setUp->taskToPerform == NA )
1188  {
1189  std::cerr << "!!! ProSHADE ERROR !!! There is no task (functionality) selected for this run." << std::endl << std::endl;
1190  std::cerr << "Please select a functionality and supply it to the settings object (or using command line). Your options are:" << std::endl;
1191  std::cerr << " " << std::endl;
1192  std::cerr << " -D or --distances " << std::endl;
1193  std::cerr << " The shape distances will be computed between the first supplied " << std::endl;
1194  std::cerr << " structure and all other structures. Requires at least two " << std::endl;
1195  std::cerr << " structures. " << std::endl;
1196  std::cerr << " " << std::endl;
1197  std::cerr << " -B or --buildDB " << std::endl;
1198  std::cerr << " Pre-compute the spherical harmonics coefficients for all " << std::endl;
1199  std::cerr << " supplied structures for the given options. Save the results in " << std::endl;
1200  std::cerr << " a binary database file given by the \'x\' option. " << std::endl;
1201  std::cerr << " " << std::endl;
1202  std::cerr << " -F or --features " << std::endl;
1203  std::cerr << " Return a table of statistics for input map. To save a clean and " << std::endl;
1204  std::cerr << " resized map, use the \'m\' option to specify the file to save to. " << std::endl;
1205  std::cerr << " " << std::endl;
1206  std::cerr << " -S or --symmetry " << std::endl;
1207  std::cerr << " Detect if any C, D, T or I symmetries are present in the first " << std::endl;
1208  std::cerr << " structure supplied. Also prints all symmetry elements for C and " << std::endl;
1209  std::cerr << " D symmetries, but only two elements for T and I. " << std::endl;
1210  std::cerr << " " << std::endl;
1211  std::cerr << " -M or --distancesFrag " << std::endl;
1212  std::cerr << " Fragment the supplied map file and search each resulting frag- " << std::endl;
1213  std::cerr << " ment against the whole database supplied by the \'x\' option. Per " << std::endl;
1214  std::cerr << " fragment distances are reported. " << std::endl;
1215  std::cerr << " " << std::endl;
1216  std::cerr << " -R or --rotate " << std::endl;
1217  std::cerr << " Take a single density map and apply the rotation defined by the " << std::endl;
1218  std::cerr << " \'--rotAng\', \'--rotAlp\', \'--rotBet\' and \'--rotGam\' options. The " << std::endl;
1219  std::cerr << " resulting rotated map is saved to location given by the " << std::endl;
1220  std::cerr << " \'--clearMap\' option. Many of the default settings are over- " << std::endl;
1221  std::cerr << " written and while can be modified using the command line " << std::endl;
1222  std::cerr << " options, this is not recommended. " << std::endl;
1223  std::cerr << " " << std::endl;
1224  std::cerr << " -O or --strOverlay " << std::endl;
1225  std::cerr << " Given two structures, find the optimal overlay using the " << std::endl;
1226  std::cerr << " rotation and translation functions. The first structure is " << std::endl;
1227  std::cerr << " always unchanged, while a rotated and translated version of the " << std::endl;
1228  std::cerr << " second structure will be written to the \'--clearMap\' option " << std::endl;
1229  std::cerr << " path or \'./rotStr\' file. " << std::endl;
1230  std::cerr << " " << std::endl;
1231  std::cerr << " -E or --reBox " << std::endl;
1232  std::cerr << " Takes a single map structure and computes the mask. Then, finds " << std::endl;
1233  std::cerr << " the box around the mask, adds extra \'--cellBorderSpace\' angs. " << std::endl;
1234  std::cerr << " of space and outputs the re-sized map to \'--clearMap\'. " << std::endl;
1235  std::cerr << " " << std::endl;
1236  }
1237 
1238  if ( setUp->htmlReport )
1239  {
1240  //==================================== Create report directory
1241  mkdir ( "proshade_report", 0777 );
1242 
1243  //==================================== Initialise empty HTML document
1244  std::stringstream hlpSS;
1245  hlpSS << __PROSHADE_RVAPI__ << "/jsrview";
1246  rvapi_init_document ( "ProSHADE Results Report",
1247  "./proshade_report",
1248  "ProSHADE Results Report",
1249  RVAPI_MODE_Html,
1250  RVAPI_LAYOUT_Plain,
1251  hlpSS.str().c_str(),
1252  NULL,
1253  "index.html",
1254  NULL,
1255  NULL );
1256  rvapi_flush ( );
1257  }
1258 
1259  //======================================== If overlaying two maps, proceed
1260  if ( setUp->taskToPerform == OverlayMap )
1261  {
1262  if ( setUp->verbose > 0 )
1263  {
1264  std::cout << "-----------------------------------------------------------" << std::endl;
1265  std::cout << "| MODE: Structure Overlay |" << std::endl;
1266  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
1267  }
1268 
1269  if ( setUp->htmlReport )
1270  {
1271  //================================ Report title
1272  rvapi_set_text ( "<h1>ProSHADE Results: Structure Overlay</h1>",
1273  "body",
1274  setUp->htmlReportLine,
1275  0,
1276  1,
1277  1 );
1278  setUp->htmlReportLine += 1;
1279 
1280  //==================================== Create section
1281  rvapi_add_section ( "ProgressSection",
1282  "Progress",
1283  "body",
1284  setUp->htmlReportLine,
1285  0,
1286  1,
1287  1,
1288  true );
1289  setUp->htmlReportLine += 1;
1290 
1291  rvapi_flush ( );
1292  }
1293 
1294  if ( setUp->htmlReport )
1295  {
1296  std::stringstream hlpSS;
1297  hlpSS << "<font color=\"green\">" << "Overlay of structures started." << "</font>";
1298  rvapi_set_text ( hlpSS.str().c_str(),
1299  "ProgressSection",
1300  setUp->htmlReportLineProgress,
1301  1,
1302  1,
1303  1 );
1304  setUp->htmlReportLineProgress += 1;
1305  rvapi_flush ( );
1306  }
1307 
1308  ProSHADE_internal::ProSHADE_symmetry symmetry ( setUp );
1309 
1310  //==================================== Done
1311 
1312  }
1313 
1314  //======================================== If rotating map, do so
1315  if ( setUp->taskToPerform == RotateMap )
1316  {
1317  if ( setUp->verbose > 0 )
1318  {
1319  std::cout << "-----------------------------------------------------------" << std::endl;
1320  std::cout << "| MODE: Map Rotation |" << std::endl;
1321  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
1322  }
1323 
1324  ProSHADE_internal::ProSHADE_symmetry symmetry ( setUp );
1325  }
1326 
1327  //======================================== If creating database, do so
1328  if ( setUp->taskToPerform == BuildDB )
1329  {
1330  if ( setUp->htmlReport )
1331  {
1332  //================================ Report title
1333  rvapi_set_text ( "<h1>ProSHADE Results: Building a database of structures</h1>",
1334  "body",
1335  setUp->htmlReportLine,
1336  0,
1337  1,
1338  1 );
1339  setUp->htmlReportLine += 1;
1340 
1341  //==================================== Create section
1342  rvapi_add_section ( "ProgressSection",
1343  "Progress",
1344  "body",
1345  setUp->htmlReportLine,
1346  0,
1347  1,
1348  1,
1349  true );
1350  setUp->htmlReportLine += 1;
1351 
1352  std::stringstream hlpSS;
1353  hlpSS << "<font color=\"green\">" << "Database building procedure started." << "</font>";
1354  rvapi_set_text ( hlpSS.str().c_str(),
1355  "ProgressSection",
1356  setUp->htmlReportLineProgress,
1357  1,
1358  1,
1359  1 );
1360  setUp->htmlReportLineProgress += 1;
1361 
1362  rvapi_flush ( );
1363  }
1364 
1366  delete db;
1367 
1368  if ( setUp->htmlReport )
1369  {
1370  std::stringstream hlpSS;
1371  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
1372  rvapi_set_text ( hlpSS.str().c_str(),
1373  "ProgressSection",
1374  setUp->htmlReportLineProgress,
1375  1,
1376  1,
1377  1 );
1378  setUp->htmlReportLineProgress += 1;
1379 
1380  rvapi_flush ( );
1381  }
1382  }
1383 
1384  //======================================== If computing features, do so
1385  if ( setUp->taskToPerform == Features )
1386  {
1387  if ( setUp->htmlReport )
1388  {
1389  //================================ Report title
1390  rvapi_set_text ( "<h1>ProSHADE Results: Density map features</h1>",
1391  "body",
1392  setUp->htmlReportLine,
1393  0,
1394  1,
1395  1 );
1396  setUp->htmlReportLine += 1;
1397 
1398  //==================================== Create section
1399  rvapi_add_section ( "ProgressSection",
1400  "Progress",
1401  "body",
1402  setUp->htmlReportLine,
1403  0,
1404  1,
1405  1,
1406  true );
1407  setUp->htmlReportLine += 1;
1408 
1409  std::stringstream hlpSS;
1410  hlpSS << "<font color=\"green\">" << "Density map features detection procedure started." << "</font>";
1411  rvapi_set_text ( hlpSS.str().c_str(),
1412  "ProgressSection",
1413  setUp->htmlReportLineProgress,
1414  1,
1415  1,
1416  1 );
1417  setUp->htmlReportLineProgress += 1;
1418 
1419  rvapi_flush ( );
1420  }
1421 
1422  ProSHADE_internal::ProSHADE_mapFeatures features ( setUp );
1423 
1424  features.printInfo ( setUp->verbose );
1425 
1426  if ( setUp->clearMapFile != "" )
1427  {
1428  if ( setUp->verbose > 0 )
1429  {
1430  std::cout << "-----------------------------------------------------------" << std::endl;
1431  std::cout << "| SAVING CLEAN MAP |" << std::endl;
1432  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
1433  }
1434 
1435  if ( setUp->verbose > 0 )
1436  {
1437  std::cout << "Clean map saved to file: " << setUp->clearMapFile << std::endl << std::endl;
1438  }
1439  }
1440 
1441  if ( setUp->mapFragBoxSize > 0.0 )
1442  {
1443  features.fragmentMap ( setUp->axisOrder,
1444  setUp->verbose,
1445  setUp );
1446  this->fragmentList = features.getFragmentsList ( );
1447  this->fragmentsAvailable = true;
1448  }
1449  else
1450  {
1451  if ( setUp->verbose > 0 )
1452  {
1453  std::cout << "-----------------------------------------------------------" << std::endl;
1454  std::cout << "| MAP FRAGMENTATION |" << std::endl;
1455  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
1456 
1457  std::cout << "Map fragmentation was not required." << std::endl << std::endl;
1458  }
1459  }
1460  }
1461 
1462  //======================================== If computing symmetry, do so
1463  if ( setUp->taskToPerform == Symmetry )
1464  {
1465  ProSHADE_internal::ProSHADE_symmetry symmetry ( setUp );
1466  this->cyclicSymmetries = symmetry.cnSymm;
1467  this->cyclicSymmetriesClear = symmetry.cnSymmClear;
1468  this->dihedralSymmetries = symmetry.dnSymm;
1469  this->dihedralSymmetriesClear = symmetry.dnSymmClear;
1470  this->tetrahedralSymmetry = symmetry.tetrAxes;
1471  this->octahedralSymmetry = symmetry.octaAxes;
1472  this->icosahedralSymmetry = symmetry.icosAxes;
1473  this->symmetriesAvailable = true;
1474 
1475  //==================================== Print results to standard output, if need be
1476  if ( setUp->symmetryType == "" )
1477  {
1478  if ( setUp->verbose > -1 )
1479  {
1480  symmetry.printResultsClear ( setUp->verbose );
1481  }
1482  if ( setUp->htmlReport )
1483  {
1484  symmetry.printResultsClearHTML( setUp );
1485  }
1486  }
1487  else
1488  {
1489  if ( setUp->verbose > -1 )
1490  {
1491  symmetry.printResultsRequest ( setUp->symmetryType,
1492  setUp->symmetryFold,
1493  setUp->verbose );
1494  }
1495  if ( setUp->htmlReport )
1496  {
1497  symmetry.printResultsRequestHTML ( setUp->symmetryType,
1498  setUp->symmetryFold,
1499  setUp );
1500  }
1501  }
1502 
1503  //==================================== Align symmetry axes to coordinate axes, if required
1504  if ( setUp->clearMapFile != "" )
1505  {
1506  if ( symmetry.inputStructureDataType )
1507  {
1508  std::cerr << "!!! ProSHADE ERROR !!! The symmetry output map can only be used for map input, the functionality to align PDB symmetry axes (which are detected) to the system axes is not yet implemented. Please report this if you are interested in a swift solution." << std::endl;
1509  exit ( -1 );
1510  }
1511 
1512  if ( setUp->verbose != -1 )
1513  {
1514  std::cout << "-----------------------------------------------------------" << std::endl;
1515  std::cout << "| Structure Axis Alignment |" << std::endl;
1516  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
1517  }
1518 
1519  if ( setUp->htmlReport )
1520  {
1521  std::stringstream hlpSS;
1522  hlpSS << "<font color=\"green\">" << "Symmetry axes alignment started." << "</font>";
1523  rvapi_set_text ( hlpSS.str().c_str(),
1524  "ProgressSection",
1525  setUp->htmlReportLineProgress,
1526  1,
1527  1,
1528  1 );
1529  setUp->htmlReportLineProgress+= 1;
1530  rvapi_flush ( );
1531  }
1532 
1533  if ( static_cast<unsigned int> ( this->icosahedralSymmetry.size() ) > 0 )
1534  {
1535  if ( setUp->verbose > -1 )
1536  {
1537  std::cout << "Applying the ICOSAHEDRAL axis alignment convention of Heymann, Chagoyen and Belnap (2005) I1 (2-fold axes on X, Y and Z)." << std::endl;
1538  }
1539 
1540  if ( setUp->htmlReport )
1541  {
1542  std::stringstream hlpSS;
1543  hlpSS << "<font color=\"green\">" << "Applying axes alignment using the convention of Heymann, Chagoyen and Belnap (2005) <b>I1</b> (2-fold axes on X, Y and Z)." << "</font>";
1544  rvapi_set_text ( hlpSS.str().c_str(),
1545  "ProgressSection",
1546  setUp->htmlReportLineProgress,
1547  1,
1548  1,
1549  1 );
1550  setUp->htmlReportLineProgress += 1;
1551  rvapi_flush ( );
1552  }
1553 
1554  //============================ Take the highest symmetry and consequently highest peak axes
1555  std::sort ( this->icosahedralSymmetry.begin(), this->icosahedralSymmetry.end(), [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[0] > b[0]; });
1556 
1557  double maxFold = this->icosahedralSymmetry.at(0)[0];
1558  int noMaxFold = 0;
1559  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->icosahedralSymmetry.size() ); iter++ )
1560  {
1561  if ( this->icosahedralSymmetry.at(iter)[0] == maxFold )
1562  {
1563  noMaxFold += 1;
1564  }
1565  }
1566  std::sort ( this->icosahedralSymmetry.begin(), this->icosahedralSymmetry.begin() + noMaxFold, [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1567 
1568  maxFold = this->icosahedralSymmetry.at(noMaxFold)[0];
1569  int noMaxFold2 = 0;
1570  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->icosahedralSymmetry.size() ); iter++ )
1571  {
1572  if ( this->icosahedralSymmetry.at(iter)[0] == maxFold )
1573  {
1574  noMaxFold2 += 1;
1575  }
1576  }
1577 
1578  std::sort ( this->icosahedralSymmetry.begin() + noMaxFold, this->icosahedralSymmetry.begin() + noMaxFold + noMaxFold2, [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1579 
1580  //============================ Initialise axes
1581  std::vector<std::vector<double>> origAxis;
1582  std::vector<std::vector<double>> basisAxis;
1583  std::vector<double> hlpVec;
1584  hlpVec.emplace_back ( 0.0 ); hlpVec.emplace_back ( 0.0 );
1585  origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec );
1586 
1587  //============================ Find the three (two) perpendicular C2 axes
1588  int c2It = 0;
1589  while ( static_cast<int> ( noMaxFold + noMaxFold2 + c2It ) < static_cast<int> ( this->icosahedralSymmetry.size() ) )
1590  {
1591  bool firstAxis = true;
1592  for ( unsigned int iter = noMaxFold + noMaxFold2 + c2It; iter < static_cast<unsigned int> ( this->icosahedralSymmetry.size() ); iter++ )
1593  {
1594  if ( firstAxis )
1595  {
1596  firstAxis = false;
1597  origAxis.at(0).at(0) = this->icosahedralSymmetry.at(iter)[1];
1598  origAxis.at(1).at(0) = this->icosahedralSymmetry.at(iter)[2];
1599  origAxis.at(2).at(0) = this->icosahedralSymmetry.at(iter)[3];
1600  }
1601  else
1602  {
1603  double dotProd = origAxis.at(0).at(0) * this->icosahedralSymmetry.at(iter)[1] +
1604  origAxis.at(1).at(0) * this->icosahedralSymmetry.at(iter)[2] +
1605  origAxis.at(2).at(0) * this->icosahedralSymmetry.at(iter)[3];
1606 
1607  if ( ( dotProd < 0.05 ) && ( dotProd > -0.05 ) )
1608  {
1609  origAxis.at(0).at(1) = this->icosahedralSymmetry.at(iter)[1];
1610  origAxis.at(1).at(1) = this->icosahedralSymmetry.at(iter)[2];
1611  origAxis.at(2).at(1) = this->icosahedralSymmetry.at(iter)[3];
1612 
1613  break;
1614  }
1615  }
1616  }
1617 
1618  if ( ( std::abs( origAxis.at(0).at(1) ) < 0.05 ) && ( std::abs( origAxis.at(1).at(1) ) < 0.05 ) && ( std::abs( origAxis.at(2).at(1) ) < 0.05 ) )
1619  {
1620  c2It += 1;
1621  }
1622  else
1623  {
1624  break;
1625  }
1626  }
1627 
1628  if ( ( std::abs( origAxis.at(0).at(1) ) < 0.05 ) && ( std::abs( origAxis.at(1).at(1) ) < 0.05 ) && ( std::abs( origAxis.at(2).at(1) ) < 0.05 ) )
1629  {
1630  std::cerr << "!!! ProSHADE ERROR !!! Cannot find three perpendicular C2 axes in the Icosahedral symmetry. This looks like a bug, please report this case. Also, you can try increasing the resolution to overcome this problem." << std::endl;
1631  if ( setUp->htmlReport )
1632  {
1633  std::stringstream hlpSS;
1634  hlpSS << "<font color=\"red\">" << "Cannot find three perpendicular C2 axes in the Icosahedral symmetry. This looks like a bug, please report this case. Also, you can try increasing the resolution to overcome this problem." << "</font>";
1635  rvapi_set_text ( hlpSS.str().c_str(),
1636  "ProgressSection",
1637  setUp->htmlReportLineProgress,
1638  1,
1639  1,
1640  1 );
1641  setUp->htmlReportLineProgress += 1;
1642  rvapi_flush ( );
1643  }
1644  exit ( -1 );
1645  }
1646 
1647  //============================ Basis vectors for alignment
1648  hlpVec.emplace_back ( 0.0 );
1649  basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec );
1650 
1651  basisAxis.at(0).at(0) = 1.0;
1652  basisAxis.at(1).at(0) = 0.0;
1653  basisAxis.at(2).at(0) = 0.0;
1654 
1655  basisAxis.at(0).at(1) = 0.0;
1656  basisAxis.at(1).at(1) = 1.0;
1657  basisAxis.at(2).at(1) = 0.0;
1658 
1659  basisAxis.at(0).at(2) = 0.0;
1660  basisAxis.at(1).at(2) = 0.0;
1661  basisAxis.at(2).at(2) = 1.0;
1662 
1663  //============================ Get angle axis representation of the matrix
1664  std::array<double,5> joinAA = ProSHADE_internal_misc::getAxisAngleFromSymmetryAxes ( origAxis, basisAxis, 0, 1 );
1665 
1666  //============================ Set up rotation ProSHADE run
1667  ProSHADE_settings* rotSet = new ProSHADE_settings ( );
1668 
1669  // ... Settings regarding resolutions
1670  rotSet->mapResolution = setUp->mapResolution;
1671 
1672  // ... Settings regarding space around the structure in lattice
1673  rotSet->extraSpace = setUp->extraSpace;
1674 
1675  // ... Settings regarding rotation module, these should to be set this way!
1676  rotSet->clearMapData = false;
1677  rotSet->useCOM = false;
1678  rotSet->rotChangeDefault = true;
1679  rotSet->ignoreLs = std::vector<int> ();
1680  rotSet->maskBlurFactor = 500.0;
1681  rotSet->maskBlurFactorGiven = false;
1682 
1683  // ... Settings regarding the task
1684  rotSet->taskToPerform = RotateMap;
1685 
1686  // ... Settings regarding where and if to save the clear map
1687  rotSet->clearMapFile = setUp->clearMapFile;
1688 
1689  // ... Settings regarding the map rotation mode
1690  rotSet->rotXAxis = joinAA[1];
1691  rotSet->rotYAxis = joinAA[2];
1692  rotSet->rotZAxis = joinAA[3];
1693  rotSet->rotAngle = joinAA[0];
1694 
1695  // ... Settings regarding the map saving mode
1696  rotSet->axisOrder = setUp->axisOrder;
1697 
1698  // ... Settings regarding the standard output amount
1699  rotSet->verbose = -1;
1700 
1701  // ... Settings regarding the file to rotate
1702  rotSet->structFiles.emplace_back ( setUp->structFiles.at(0) );
1703 
1704  //============================ Rotate the structure as required
1705  if ( setUp->verbose > 0 )
1706  {
1707  std::cout << ">> Structure rotation initiated." << std::endl;
1708  }
1709 
1710  ProSHADE *run = new ProSHADE ( rotSet );
1711  delete run;
1712 
1713  if ( setUp->verbose > -1 )
1714  {
1715  std::cout << "Structure with symmetry axis to box axes alignment writted in " << setUp->clearMapFile << std::endl;
1716  }
1717  }
1718 
1719  else if ( static_cast<unsigned int> ( this->octahedralSymmetry.size() ) > 0 )
1720  {
1721  if ( setUp->verbose > -1 )
1722  {
1723  std::cout << "Applying the OCTAHEDRAL axis alignment convention of Heymann, Chagoyen and Belnap (2005) (4-fold axes on X, Y and Z)." << std::endl;
1724  }
1725 
1726  if ( setUp->htmlReport )
1727  {
1728  std::stringstream hlpSS;
1729  hlpSS << "<font color=\"green\">" << "Applying axes alignment using the convention of Heymann, Chagoyen and Belnap (2005) (4-fold axes on X, Y and Z)." << "</font>";
1730  rvapi_set_text ( hlpSS.str().c_str(),
1731  "ProgressSection",
1732  setUp->htmlReportLineProgress,
1733  1,
1734  1,
1735  1 );
1736  setUp->htmlReportLineProgress += 1;
1737  rvapi_flush ( );
1738  }
1739 
1740  //============================ Take the highest symmetry and consequently highest peak axes
1741  std::sort ( this->octahedralSymmetry.begin(), this->octahedralSymmetry.end(), [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[0] > b[0]; });
1742 
1743  double maxFold = this->octahedralSymmetry.at(0)[0];
1744  int noMaxFold = 0;
1745  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->octahedralSymmetry.size() ); iter++ )
1746  {
1747  if ( this->octahedralSymmetry.at(iter)[0] == maxFold )
1748  {
1749  noMaxFold += 1;
1750  }
1751  }
1752  std::sort ( this->octahedralSymmetry.begin(), this->octahedralSymmetry.begin() + noMaxFold, [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1753 
1754  maxFold = this->octahedralSymmetry.at(noMaxFold)[0];
1755  int noMaxFold2 = 0;
1756  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->octahedralSymmetry.size() ); iter++ )
1757  {
1758  if ( this->octahedralSymmetry.at(iter)[0] == maxFold )
1759  {
1760  noMaxFold2 += 1;
1761  }
1762  }
1763  std::sort ( this->octahedralSymmetry.begin() + noMaxFold, this->octahedralSymmetry.begin() + noMaxFold2 + noMaxFold, [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1764 
1765  //============================ Original symmetry axes for Z-alignment
1766  std::vector<std::vector<double>> origAxis;
1767  std::vector<std::vector<double>> basisAxis;
1768  std::vector<double> hlpVec;
1769  hlpVec.emplace_back ( 0.0 ); hlpVec.emplace_back ( 0.0 );
1770  origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec );
1771 
1772  origAxis.at(0).at(0) = this->octahedralSymmetry.at(0)[1];
1773  origAxis.at(1).at(0) = this->octahedralSymmetry.at(0)[2];
1774  origAxis.at(2).at(0) = this->octahedralSymmetry.at(0)[3];
1775 
1776  origAxis.at(0).at(1) = this->octahedralSymmetry.at(1)[1];
1777  origAxis.at(1).at(1) = this->octahedralSymmetry.at(1)[2];
1778  origAxis.at(2).at(1) = this->octahedralSymmetry.at(1)[3];
1779 
1780  //============================ Basis vectors for alignment
1781  hlpVec.emplace_back ( 0.0 );
1782  basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec );
1783 
1784  basisAxis.at(0).at(0) = 1.0;
1785  basisAxis.at(1).at(0) = 0.0;
1786  basisAxis.at(2).at(0) = 0.0;
1787 
1788  basisAxis.at(0).at(1) = 0.0;
1789  basisAxis.at(1).at(1) = 1.0;
1790  basisAxis.at(2).at(1) = 0.0;
1791 
1792  basisAxis.at(0).at(2) = 0.0;
1793  basisAxis.at(1).at(2) = 0.0;
1794  basisAxis.at(2).at(2) = 1.0;
1795 
1796  //============================ Get angle axis representation of the matrix
1797  std::array<double,5> joinAA = ProSHADE_internal_misc::getAxisAngleFromSymmetryAxes ( origAxis, basisAxis, 1, 2 );
1798 
1799  //============================ Set up rotation ProSHADE run
1800  ProSHADE_settings* rotSet = new ProSHADE_settings ( );
1801 
1802  // ... Settings regarding resolutions
1803  rotSet->mapResolution = setUp->mapResolution;
1804 
1805  // ... Settings regarding space around the structure in lattice
1806  rotSet->extraSpace = setUp->extraSpace;
1807 
1808  // ... Settings regarding rotation module, these should to be set this way!
1809  rotSet->clearMapData = false;
1810  rotSet->useCOM = false;
1811  rotSet->rotChangeDefault = true;
1812  rotSet->ignoreLs = std::vector<int> ();
1813  rotSet->maskBlurFactor = 500.0;
1814  rotSet->maskBlurFactorGiven = false;
1815 
1816  // ... Settings regarding the task
1817  rotSet->taskToPerform = RotateMap;
1818 
1819  // ... Settings regarding where and if to save the clear map
1820  rotSet->clearMapFile = setUp->clearMapFile;
1821 
1822  // ... Settings regarding the map rotation mode
1823  rotSet->rotXAxis = joinAA[1];
1824  rotSet->rotYAxis = joinAA[2];
1825  rotSet->rotZAxis = joinAA[3];
1826  rotSet->rotAngle = joinAA[0];
1827 
1828  // ... Settings regarding the map saving mode
1829  rotSet->axisOrder = setUp->axisOrder;
1830 
1831  // ... Settings regarding the standard output amount
1832  rotSet->verbose = -1;
1833 
1834  // ... Settings regarding the file to rotate
1835  rotSet->structFiles.emplace_back ( setUp->structFiles.at(0) );
1836 
1837  //============================ Rotate the structure as required
1838  if ( setUp->verbose > 0 )
1839  {
1840  std::cout << ">> Structure rotation initiated." << std::endl;
1841  }
1842 
1843  ProSHADE *run = new ProSHADE ( rotSet );
1844  delete run;
1845 
1846  if ( setUp->verbose > -1 )
1847  {
1848  std::cout << "Structure with symmetry axis to box axes alignment writted in " << setUp->clearMapFile << std::endl;
1849  }
1850  }
1851 
1852  else if ( static_cast<unsigned int> ( this->tetrahedralSymmetry.size() ) > 0 )
1853  {
1854  if ( setUp->verbose > -1 )
1855  {
1856  std::cout << "Applying the TETRAHEDRAL axis alignment convention from RELION (3-fold axis on Z)." << std::endl;
1857  }
1858 
1859  if ( setUp->htmlReport )
1860  {
1861  std::stringstream hlpSS;
1862  hlpSS << "<font color=\"green\">" << "Applying axis alignment using the RELION convention (3-fold axis on Z)." << "</font>";
1863  rvapi_set_text ( hlpSS.str().c_str(),
1864  "ProgressSection",
1865  setUp->htmlReportLineProgress,
1866  1,
1867  1,
1868  1 );
1869  setUp->htmlReportLineProgress += 1;
1870  rvapi_flush ( );
1871  }
1872 
1873  //============================ Take the highest symmetry and consequently highest peak axes
1874  std::sort ( this->tetrahedralSymmetry.begin(), this->tetrahedralSymmetry.end(), [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[0] > b[0]; });
1875 
1876  double maxFold = this->tetrahedralSymmetry.at(0)[0];
1877  int noMaxFold = 0;
1878  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->tetrahedralSymmetry.size() ); iter++ )
1879  {
1880  if ( this->tetrahedralSymmetry.at(iter)[0] == maxFold )
1881  {
1882  noMaxFold += 1;
1883  }
1884  }
1885  std::sort ( this->tetrahedralSymmetry.begin(), this->tetrahedralSymmetry.begin() + noMaxFold, [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1886  std::sort ( this->tetrahedralSymmetry.begin() + noMaxFold, this->tetrahedralSymmetry.end(), [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[4] > b[4]; });
1887 
1888  //============================ Original symmetry axes for Z-alignment
1889  std::vector<std::vector<double>> origAxis;
1890  std::vector<std::vector<double>> basisAxis;
1891  std::vector<double> hlpVec;
1892  hlpVec.emplace_back ( 0.0 ); hlpVec.emplace_back ( 0.0 );
1893  origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec );
1894 
1895  origAxis.at(0).at(0) = this->tetrahedralSymmetry.at(0)[1];
1896  origAxis.at(1).at(0) = this->tetrahedralSymmetry.at(0)[2];
1897  origAxis.at(2).at(0) = this->tetrahedralSymmetry.at(0)[3];
1898 
1899  origAxis.at(0).at(1) = this->tetrahedralSymmetry.at(3)[1];
1900  origAxis.at(1).at(1) = this->tetrahedralSymmetry.at(3)[2];
1901  origAxis.at(2).at(1) = this->tetrahedralSymmetry.at(3)[3];
1902 
1903  //============================ Basis vectors for alignment
1904  hlpVec.emplace_back ( 0.0 );
1905  basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec );
1906 
1907  basisAxis.at(0).at(0) = 1.0;
1908  basisAxis.at(1).at(0) = 0.0;
1909  basisAxis.at(2).at(0) = 0.0;
1910 
1911  basisAxis.at(0).at(1) = 0.0;
1912  basisAxis.at(1).at(1) = 1.0;
1913  basisAxis.at(2).at(1) = 0.0;
1914 
1915  basisAxis.at(0).at(2) = 0.0;
1916  basisAxis.at(1).at(2) = 0.0;
1917  basisAxis.at(2).at(2) = 1.0;
1918 
1919  //============================ Get angle axis representation of the matrix
1920  std::array<double,5> joinAA = ProSHADE_internal_misc::getAxisAngleFromSymmetryAxes ( origAxis, basisAxis, 1, 2 );
1921 
1922  //============================ Set up rotation ProSHADE run
1923  ProSHADE_settings* rotSet = new ProSHADE_settings ( );
1924 
1925  // ... Settings regarding resolutions
1926  rotSet->mapResolution = setUp->mapResolution;
1927 
1928  // ... Settings regarding space around the structure in lattice
1929  rotSet->extraSpace = setUp->extraSpace;
1930 
1931  // ... Settings regarding rotation module, these should to be set this way!
1932  rotSet->clearMapData = false;
1933  rotSet->useCOM = false;
1934  rotSet->rotChangeDefault = true;
1935  rotSet->ignoreLs = std::vector<int> ();
1936  rotSet->maskBlurFactor = 500.0;
1937  rotSet->maskBlurFactorGiven = false;
1938 
1939  // ... Settings regarding the task
1940  rotSet->taskToPerform = RotateMap;
1941 
1942  // ... Settings regarding where and if to save the clear map
1943  rotSet->clearMapFile = setUp->clearMapFile;
1944 
1945  // ... Settings regarding the map rotation mode
1946  rotSet->rotXAxis = joinAA[1];
1947  rotSet->rotYAxis = joinAA[2];
1948  rotSet->rotZAxis = joinAA[3];
1949  rotSet->rotAngle = joinAA[0];
1950 
1951  // ... Settings regarding the map saving mode
1952  rotSet->axisOrder = setUp->axisOrder;
1953 
1954  // ... Settings regarding the standard output amount
1955  rotSet->verbose = -1;
1956 
1957  // ... Settings regarding the file to rotate
1958  rotSet->structFiles.emplace_back ( setUp->structFiles.at(0) );
1959 
1960  //============================ Rotate the structure as required
1961  if ( setUp->verbose > 0 )
1962  {
1963  std::cout << ">> Structure rotation initiated." << std::endl;
1964  }
1965 
1966  ProSHADE *run = new ProSHADE ( rotSet );
1967  delete run;
1968 
1969  if ( setUp->verbose > -1 )
1970  {
1971  std::cout << "Structure with symmetry axis to box axes alignment writted in " << setUp->clearMapFile << std::endl;
1972  }
1973  }
1974 
1975  //================================ Dihedral symmetry
1976  else if ( static_cast<unsigned int> ( this->dihedralSymmetries.size() ) > 0 )
1977  {
1978  if ( setUp->verbose > -1 )
1979  {
1980  std::cout << "Applying the DIHEDRAL axis alignment convention of Heymann, Chagoyen and Belnap (2005) (principle symm axis on Z, 2-fold on X)." << std::endl;
1981  }
1982 
1983  if ( setUp->htmlReport )
1984  {
1985  std::stringstream hlpSS;
1986  hlpSS << "<font color=\"green\">" << "Applying axes alignment using the convention of Heymann, Chagoyen and Belnap (2005) (principle symm axis on Z, 2-fold on X)." << "</font>";
1987  rvapi_set_text ( hlpSS.str().c_str(),
1988  "ProgressSection",
1989  setUp->htmlReportLineProgress,
1990  1,
1991  1,
1992  1 );
1993  setUp->htmlReportLineProgress += 1;
1994  rvapi_flush ( );
1995  }
1996 
1997  //============================ Take the highest symmetry and consequently highest peak axes
1998  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dihedralSymmetries.size() ); iter++ )
1999  {
2000  std::sort ( this->dihedralSymmetries.at(iter).begin(), this->dihedralSymmetries.at(iter).end(), [](const std::array<double,6>& a, const std::array<double,6>& b) { return a[0] > b[0]; });
2001  }
2002  std::sort ( this->dihedralSymmetries.begin(), this->dihedralSymmetries.end(), [](const std::vector< std::array<double,6> >& a, const std::vector< std::array<double,6> >& b) { return a.at(0)[0] > b.at(0)[0]; });
2003 
2004  double maxFold = this->dihedralSymmetries.at(0).at(0)[0];
2005  int noMaxFold = 0;
2006  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dihedralSymmetries.size() ); iter++ )
2007  {
2008  if ( this->dihedralSymmetries.at(iter).at(0)[0] == maxFold )
2009  {
2010  noMaxFold += 1;
2011  }
2012  }
2013  std::sort ( this->dihedralSymmetries.begin(), this->dihedralSymmetries.begin() + noMaxFold, [](const std::vector< std::array<double,6> >& a, const std::vector< std::array<double,6> >& b) { return a.at(0)[5] > b.at(0)[5]; });
2014 
2015  //============================ Original symmetry axes for Z-alignment
2016  std::vector<std::vector<double>> origAxis;
2017  std::vector<std::vector<double>> basisAxis;
2018  std::vector<double> hlpVec;
2019  hlpVec.emplace_back ( 0.0 ); hlpVec.emplace_back ( 0.0 );
2020  origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec );
2021 
2022  origAxis.at(0).at(0) = this->dihedralSymmetries.at(0).at(0)[1];
2023  origAxis.at(1).at(0) = this->dihedralSymmetries.at(0).at(0)[2];
2024  origAxis.at(2).at(0) = this->dihedralSymmetries.at(0).at(0)[3];
2025 
2026  origAxis.at(0).at(1) = this->dihedralSymmetries.at(0).at(1)[1];
2027  origAxis.at(1).at(1) = this->dihedralSymmetries.at(0).at(1)[2];
2028  origAxis.at(2).at(1) = this->dihedralSymmetries.at(0).at(1)[3];
2029 
2030  //============================ Basis vectors for alignment
2031  hlpVec.emplace_back ( 0.0 );
2032  basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec );
2033 
2034  basisAxis.at(0).at(0) = 1.0;
2035  basisAxis.at(1).at(0) = 0.0;
2036  basisAxis.at(2).at(0) = 0.0;
2037 
2038  basisAxis.at(0).at(1) = 0.0;
2039  basisAxis.at(1).at(1) = 1.0;
2040  basisAxis.at(2).at(1) = 0.0;
2041 
2042  basisAxis.at(0).at(2) = 0.0;
2043  basisAxis.at(1).at(2) = 0.0;
2044  basisAxis.at(2).at(2) = 1.0;
2045 
2046  //============================ Get angle axis representation of the matrix
2047  std::array<double,5> joinAA = ProSHADE_internal_misc::getAxisAngleFromSymmetryAxes ( origAxis, basisAxis, 1, 2 );
2048 
2049  //============================ Set up rotation ProSHADE run
2050  ProSHADE_settings* rotSet = new ProSHADE_settings ( );
2051 
2052  // ... Settings regarding resolutions
2053  rotSet->mapResolution = setUp->mapResolution;
2054 
2055  // ... Settings regarding space around the structure in lattice
2056  rotSet->extraSpace = setUp->extraSpace;
2057 
2058  // ... Settings regarding rotation module, these should to be set this way!
2059  rotSet->clearMapData = false;
2060  rotSet->useCOM = false;
2061  rotSet->rotChangeDefault = true;
2062  rotSet->ignoreLs = std::vector<int> ();
2063  rotSet->maskBlurFactor = 500.0;
2064  rotSet->maskBlurFactorGiven = false;
2065 
2066  // ... Settings regarding the task
2067  rotSet->taskToPerform = RotateMap;
2068 
2069  // ... Settings regarding where and if to save the clear map
2070  rotSet->clearMapFile = setUp->clearMapFile;
2071 
2072  // ... Settings regarding the map rotation mode
2073  rotSet->rotXAxis = joinAA[1];
2074  rotSet->rotYAxis = joinAA[2];
2075  rotSet->rotZAxis = joinAA[3];
2076  rotSet->rotAngle = joinAA[0];
2077 
2078  // ... Settings regarding the map saving mode
2079  rotSet->axisOrder = setUp->axisOrder;
2080 
2081  // ... Settings regarding the standard output amount
2082  rotSet->verbose = -1;
2083 
2084  // ... Settings regarding the file to rotate
2085  rotSet->structFiles.emplace_back ( setUp->structFiles.at(0) );
2086 
2087  //============================ Rotate the structure as required
2088  if ( setUp->verbose > 0 )
2089  {
2090  std::cout << ">> Structure rotation initiated." << std::endl;
2091  }
2092 
2093  ProSHADE *run = new ProSHADE ( rotSet );
2094  delete run;
2095 
2096  if ( setUp->verbose > -1 )
2097  {
2098  std::cout << "Structure with symmetry axis to box axes alignment writted in " << setUp->clearMapFile << std::endl;
2099  }
2100  }
2101 
2102  //================================ Cyclic symmetry
2103  else if ( static_cast<unsigned int> ( this->cyclicSymmetries.size() ) > 0 )
2104  {
2105  if ( setUp->verbose > -1 )
2106  {
2107  std::cout << "Applying the CYCLIC axis alignment convention of Heymann, Chagoyen and Belnap (2005) (symm axis on Z)." << std::endl;
2108  }
2109 
2110  if ( setUp->htmlReport )
2111  {
2112  std::stringstream hlpSS;
2113  hlpSS << "<font color=\"green\">" << "Applying axis alignment using the convention of Heymann, Chagoyen and Belnap (2005) (symm axis on Z)." << "</font>";
2114  rvapi_set_text ( hlpSS.str().c_str(),
2115  "ProgressSection",
2116  setUp->htmlReportLineProgress,
2117  1,
2118  1,
2119  1 );
2120  setUp->htmlReportLineProgress += 1;
2121  rvapi_flush ( );
2122  }
2123 
2124  //============================ Take the highest symmetry axis
2125  std::sort ( this->cyclicSymmetries.begin(), this->cyclicSymmetries.end(), [](const std::array<double,5>& a, const std::array<double,5>& b) { return a[0] > b[0]; });
2126 
2127  //============================ Original symmetry axes for Z-alignment
2128  std::vector<std::vector<double>> origAxis;
2129  std::vector<std::vector<double>> basisAxis;
2130  std::vector<double> hlpVec;
2131  hlpVec.emplace_back ( 0.0 );
2132  origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec ); origAxis.emplace_back( hlpVec );
2133 
2134  origAxis.at(0).at(0) = this->cyclicSymmetries.at(0)[1];
2135  origAxis.at(1).at(0) = this->cyclicSymmetries.at(0)[2];
2136  origAxis.at(2).at(0) = this->cyclicSymmetries.at(0)[3];
2137 
2138  //============================ Basis vectors for alignment
2139  hlpVec.emplace_back ( 0.0 ); hlpVec.emplace_back ( 0.0 );
2140  basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec ); basisAxis.emplace_back( hlpVec );
2141 
2142  basisAxis.at(0).at(0) = 1.0;
2143  basisAxis.at(1).at(0) = 0.0;
2144  basisAxis.at(2).at(0) = 0.0;
2145 
2146  basisAxis.at(0).at(1) = 0.0;
2147  basisAxis.at(1).at(1) = 1.0;
2148  basisAxis.at(2).at(1) = 0.0;
2149 
2150  basisAxis.at(0).at(2) = 0.0;
2151  basisAxis.at(1).at(2) = 0.0;
2152  basisAxis.at(2).at(2) = 1.0;
2153 
2154  //============================ Get angle axis representation of the matrix
2155  std::array<double,5> joinAA = ProSHADE_internal_misc::getAxisAngleFromSymmetryAxes ( origAxis, basisAxis, 1, 2 );
2156 
2157  //============================ Set up rotation ProSHADE run
2158  ProSHADE_settings* rotSet = new ProSHADE_settings ( );
2159 
2160  // ... Settings regarding resolutions
2161  rotSet->mapResolution = setUp->mapResolution;
2162 
2163  // ... Settings regarding space around the structure in lattice
2164  rotSet->extraSpace = setUp->extraSpace;
2165 
2166  // ... Settings regarding rotation module, these should to be set this way!
2167  rotSet->clearMapData = false;
2168  rotSet->useCOM = false;
2169  rotSet->rotChangeDefault = true;
2170  rotSet->ignoreLs = std::vector<int> ();
2171  rotSet->maskBlurFactor = 500.0;
2172  rotSet->maskBlurFactorGiven = false;
2173 
2174  // ... Settings regarding the task
2175  rotSet->taskToPerform = RotateMap;
2176 
2177  // ... Settings regarding where and if to save the clear map
2178  rotSet->clearMapFile = setUp->clearMapFile;
2179 
2180  // ... Settings regarding the map rotation mode
2181  rotSet->rotXAxis = joinAA[1];
2182  rotSet->rotYAxis = joinAA[2];
2183  rotSet->rotZAxis = joinAA[3];
2184  rotSet->rotAngle = -joinAA[0];
2185 
2186  // ... Settings regarding the map saving mode
2187  rotSet->axisOrder = setUp->axisOrder;
2188 
2189  // ... Settings regarding the standard output amount
2190  rotSet->verbose = -1;
2191 
2192  // ... Settings regarding the file to rotate
2193  rotSet->structFiles.emplace_back ( setUp->structFiles.at(0) );
2194 
2195  //============================ Rotate the structure as required
2196  if ( setUp->verbose > 0 )
2197  {
2198  std::cout << ">> Structure rotation initiated." << std::endl;
2199  }
2200 
2201  ProSHADE *run = new ProSHADE ( rotSet );
2202  delete run;
2203 
2204  if ( setUp->verbose > -1 )
2205  {
2206  std::cout << "Structure with symmetry axis to box axes alignment writted in " << setUp->clearMapFile << std::endl;
2207  }
2208  }
2209  }
2210 
2211  if ( setUp->htmlReport )
2212  {
2213  std::stringstream hlpSS;
2214  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
2215  rvapi_set_text ( hlpSS.str().c_str(),
2216  "ProgressSection",
2217  setUp->htmlReportLineProgress,
2218  1,
2219  1,
2220  1 );
2221  setUp->htmlReportLineProgress += 1;
2222  rvapi_flush ( );
2223  }
2224  }
2225 
2226  //======================================== If computing half maps, do so
2227  if ( setUp->taskToPerform == HalfMaps )
2228  {
2229  if ( setUp->htmlReport )
2230  {
2231  //================================ Report title
2232  rvapi_set_text ( "<h1>ProSHADE Results: Half-maps re-boxing</h1>",
2233  "body",
2234  setUp->htmlReportLine,
2235  0,
2236  1,
2237  1 );
2238  setUp->htmlReportLine += 1;
2239 
2240  //==================================== Create section
2241  rvapi_add_section ( "ProgressSection",
2242  "Progress",
2243  "body",
2244  setUp->htmlReportLine,
2245  0,
2246  1,
2247  1,
2248  true );
2249  setUp->htmlReportLine += 1;
2250 
2251  std::stringstream hlpSS;
2252  hlpSS << "<font color=\"green\">" << "Starting the re-boxing of half-maps." << "</font>";
2253  rvapi_set_text ( hlpSS.str().c_str(),
2254  "ProgressSection",
2255  setUp->htmlReportLineProgress,
2256  1,
2257  1,
2258  1 );
2259  setUp->htmlReportLineProgress += 1;
2260  rvapi_flush ( );
2261  }
2262 
2263  ProSHADE_internal::ProSHADE_mapFeatures features ( setUp );
2264 
2265  }
2266 
2267  //======================================== If simple re-boxing is to be done, do it
2268  if ( setUp->taskToPerform == SimpleRebox )
2269  {
2270  //==================================== Report progress
2271  if ( setUp->verbose > 0 )
2272  {
2273  std::cout << "-----------------------------------------------------------" << std::endl;
2274  std::cout << "| MODE: Re-boxing map |" << std::endl;
2275  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2276  }
2277 
2278  if ( setUp->htmlReport )
2279  {
2280  //================================ Report title
2281  rvapi_set_text ( "<h1>ProSHADE Results: Map Re-boxing</h1>",
2282  "body",
2283  setUp->htmlReportLine,
2284  0,
2285  1,
2286  1 );
2287  setUp->htmlReportLine += 1;
2288 
2289  //==================================== Create section
2290  rvapi_add_section ( "ProgressSection",
2291  "Progress",
2292  "body",
2293  setUp->htmlReportLine,
2294  0,
2295  1,
2296  1,
2297  true );
2298  setUp->htmlReportLine += 1;
2299 
2300  //================================ Sanity check
2301  if ( setUp->structFiles.size() != 1 )
2302  {
2303  std::cerr << "!!! ProSHADE ERROR !!! Attampted to re-box a map, but supplied ";
2304  if ( setUp->structFiles.size() < 1 ) { std::cerr << "less "; }
2305  if ( setUp->structFiles.size() > 1 ) { std::cerr << "more "; }
2306  std::cerr << "than exactly one file. Please use the \'-f\' option to supply a single map file. Terminating ..." << std::endl << std::endl;
2307 
2308  if ( setUp->htmlReport )
2309  {
2310  std::stringstream hlpSS;
2311  hlpSS << "<font color=\"red\">" << "Supplied incorrect number (" << setUp->structFiles.size() << ") of structures - a single one expected." << "</font>";
2312  rvapi_set_text ( hlpSS.str().c_str(),
2313  "ProgressSection",
2314  settings->htmlReportLineProgress,
2315  1,
2316  1,
2317  1 );
2318  setUp->htmlReportLineProgress += 1;
2319  rvapi_flush ( );
2320  }
2321 
2322  exit ( -1 );
2323  }
2324 
2325  std::stringstream hlpSS;
2326  hlpSS << "<font color=\"green\">" << "Starting computation of map re-boxing for the input structure " << setUp->structFiles.at(0) << " ." << "</font>";
2327  rvapi_set_text ( hlpSS.str().c_str(),
2328  "ProgressSection",
2329  setUp->htmlReportLineProgress,
2330  1,
2331  1,
2332  1 );
2333  setUp->htmlReportLineProgress += 1;
2334  rvapi_flush ( );
2335  }
2336 
2337  //==================================== Run
2338  ProSHADE_internal::ProSHADE_mapFeatures features ( setUp );
2339  }
2340 
2341  //======================================== If computing distances, do so
2342  if ( setUp->taskToPerform == Distances )
2343  {
2344  //==================================== Report progress
2345  if ( setUp->verbose > 0 )
2346  {
2347  std::cout << "-----------------------------------------------------------" << std::endl;
2348  std::cout << "| MODE: Distances |" << std::endl;
2349  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2350  }
2351 
2352  if ( setUp->htmlReport )
2353  {
2354  //================================ Report title
2355  rvapi_set_text ( "<h1>ProSHADE Results: Distances</h1>",
2356  "body",
2357  setUp->htmlReportLine,
2358  0,
2359  1,
2360  1 );
2361  setUp->htmlReportLine += 1;
2362 
2363  //==================================== Create section
2364  rvapi_add_section ( "ProgressSection",
2365  "Progress",
2366  "body",
2367  setUp->htmlReportLine,
2368  0,
2369  1,
2370  1,
2371  true );
2372  setUp->htmlReportLine += 1;
2373 
2374  std::stringstream hlpSS;
2375  hlpSS << "<font color=\"green\">" << "Starting computation of distances between input structures." << "</font>";
2376  rvapi_set_text ( hlpSS.str().c_str(),
2377  "ProgressSection",
2378  setUp->htmlReportLineProgress,
2379  1,
2380  1,
2381  1 );
2382  setUp->htmlReportLineProgress += 1;
2383  rvapi_flush ( );
2384  }
2385 
2386  //==================================== Compute the distances
2388 
2389  //==================================== Save the distances to this object
2390  if ( setUp->energyLevelDist ) { this->crossCorrDists = distObj->getEnergyLevelsDistances ( ); }
2391  if ( setUp->traceSigmaDist ) { this->traceSigmaDists = distObj->getTraceSigmaDistances ( ); }
2392  if ( setUp->fullRotFnDist ) { this->rotFunctionDists = distObj->getFullRotationDistances ( ); }
2393 
2394  //==================================== Free memory
2395  delete distObj;
2396 
2397  if ( setUp->verbose > 0 )
2398  {
2399  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2400  std::cout << "| COMPLETED |" << std::endl;
2401  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2402  }
2403 
2404  if ( setUp->htmlReport )
2405  {
2406  //================================ Record progress
2407  std::stringstream hlpSS;
2408  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
2409  rvapi_set_text ( hlpSS.str().c_str(),
2410  "ProgressSection",
2411  setUp->htmlReportLineProgress,
2412  1,
2413  1,
2414  1 );
2415  setUp->htmlReportLineProgress += 1;
2416  rvapi_flush ( );
2417  }
2418 
2419  if ( setUp->verbose > 0 )
2420  {
2421  std::cout << "-----------------------------------------------------------" << std::endl;
2422  std::cout << "| RESULTS |" << std::endl;
2423  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2424  }
2425 
2426  if ( setUp->htmlReport )
2427  {
2428  //================================ Record progress
2429  rvapi_add_section ( "ResultsSection",
2430  "Distances",
2431  "body",
2432  setUp->htmlReportLine,
2433  0,
2434  1,
2435  1,
2436  true );
2437  setUp->htmlReportLine += 1;
2438 
2439  rvapi_add_grid ( "distGrid",
2440  true,
2441  "ResultsSection",
2442  2,
2443  0,
2444  1,
2445  1 );
2446 
2447  rvapi_add_table ( "DistancesTable",
2448  "Distances between structures",
2449  "distGrid",
2450  0,
2451  0,
2452  1,
2453  1,
2454  1 );
2455 
2456  // ... Column headers
2457  std::stringstream hlpSS;
2458  int columnIter = 0;
2459 
2460  if ( setUp->energyLevelDist )
2461  {
2462  hlpSS.str ( std::string ( ) );
2463  hlpSS << "This column contains the distances obtained by computing correlations between the spherical harmonics on different shells and then comparing these correlation tables between the two structures. These distances are all from structure " << setUp->structFiles.at(0) << " and the structure named in the row name.";
2464  rvapi_put_horz_theader ( "DistancesTable", "Energy Levels Distances", hlpSS.str().c_str(), columnIter );
2465  columnIter += 1;
2466  }
2467 
2468  if ( setUp->energyLevelDist )
2469  {
2470  hlpSS.str ( std::string ( ) );
2471  hlpSS << "This column contains the distances obtained by calculating the distances in spherical harmonics coefficients integrated over all the shells, using Singular Value Decomposition to approximate the rotation difference. These distances are all from structure " << setUp->structFiles.at(0) << " and the structure named in the row name.";
2472  rvapi_put_horz_theader ( "DistancesTable", "Trace Sigma Distances", hlpSS.str().c_str(), columnIter );
2473  columnIter += 1;
2474  }
2475 
2476  if ( setUp->energyLevelDist )
2477  {
2478  hlpSS.str ( std::string ( ) );
2479  hlpSS << "This column contains the distances obtained by calculating the distances in spherical harmonics coefficients integrated over all the shells, using the Rotation Function to find the optimal overlay rotation between the structures. These distances are all from structure " << setUp->structFiles.at(0) << " and the structure named in the row name.";
2480  rvapi_put_horz_theader ( "DistancesTable", "Rotation Function Distances", hlpSS.str().c_str(), columnIter );
2481  columnIter += 1;
2482  }
2483 
2484  // ... Row headers
2485  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( setUp->structFiles.size() ); iter++ )
2486  {
2487  hlpSS.str ( std::string ( ) );
2488  hlpSS << setUp->structFiles.at(iter);
2489  rvapi_put_vert_theader ( "DistancesTable", hlpSS.str().c_str(), "", iter-1 );
2490  }
2491 
2492  rvapi_flush ( );
2493  }
2494 
2495  if ( setUp->energyLevelDist )
2496  {
2497  if ( setUp->verbose != -1 )
2498  {
2499  printf ( "Energy Level Descriptor distances : %+.4f", this->crossCorrDists.at(0) );
2500  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( this->crossCorrDists.size() ); iter++ )
2501  {
2502  printf ( " %+.4f", this->crossCorrDists.at(iter) );
2503  }
2504  std::cout << std::endl;
2505  }
2506 
2507  }
2508 
2509  if ( setUp->traceSigmaDist )
2510  {
2511  if ( setUp->verbose != -1 )
2512  {
2513  printf ( "Trace Sigma Descriptor distances : %+.4f", this->traceSigmaDists.at(0) );
2514  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( this->traceSigmaDists.size() ); iter++ )
2515  {
2516  printf ( " %+.4f", this->traceSigmaDists.at(iter) );
2517  }
2518  std::cout << std::endl;
2519  }
2520  }
2521 
2522  if ( setUp->fullRotFnDist )
2523  {
2524  if ( setUp->verbose != -1 )
2525  {
2526  printf ( "Rotation Function Descriptor distances : %+.4f", this->rotFunctionDists.at(0) );
2527  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( this->rotFunctionDists.size() ); iter++ )
2528  {
2529  printf ( " %+.4f", this->rotFunctionDists.at(iter) );
2530  }
2531  std::cout << std::endl;
2532  }
2533  }
2534 
2535  if ( setUp->verbose != -1 )
2536  {
2537  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( setUp->structFiles.size() ); iter++ )
2538  {
2539  std::cout << "Matching structure names : " << setUp->structFiles.at(iter) << std::endl;
2540  }
2541  std::cout << std::endl;
2542  }
2543 
2544  if ( setUp->htmlReport )
2545  {
2546  int colIter = 0;
2547  std::stringstream hlpSS;
2548 
2549  if ( setUp->energyLevelDist )
2550  {
2551  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( this->crossCorrDists.size() ); rIter++ )
2552  {
2553  hlpSS.str ( std::string ( ) );
2554  hlpSS << this->crossCorrDists.at(rIter);
2555  rvapi_put_table_string ( "DistancesTable", hlpSS.str().c_str(), rIter, colIter );
2556  }
2557  colIter += 1;
2558  }
2559 
2560  if ( setUp->traceSigmaDist )
2561  {
2562  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( this->traceSigmaDists.size() ); rIter++ )
2563  {
2564  hlpSS.str ( std::string ( ) );
2565  hlpSS << this->traceSigmaDists.at(rIter);
2566  rvapi_put_table_string ( "DistancesTable", hlpSS.str().c_str(), rIter, colIter );
2567  }
2568  colIter += 1;
2569  }
2570 
2571  if ( setUp->fullRotFnDist )
2572  {
2573  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( this->rotFunctionDists.size() ); rIter++ )
2574  {
2575  hlpSS.str ( std::string ( ) );
2576  hlpSS << this->rotFunctionDists.at(rIter);
2577  rvapi_put_table_string ( "DistancesTable", hlpSS.str().c_str(), rIter, colIter );
2578  }
2579  colIter += 1;
2580  }
2581  rvapi_flush ( );
2582  }
2583 
2584  if ( ( setUp->verbose > 0 ) && ( setUp->databaseName != "" ) )
2585  {
2586  std::cout << "NOTE: If you do not see a structure you were expecting and know to be in the database, it may be caused by the querry structure and the one you were expecting having too different dimmensions - see the help dialogue for parameter \'--dbSizeLim\'." << std::endl << std::endl;
2587  }
2588 
2589  this->distancesAvailable = true;
2590 
2591  }
2592 
2593  //======================================== If computing fragments distances, do so
2594  if ( setUp->taskToPerform == DistancesFrag )
2595  {
2596  //==================================== Report progress
2597  if ( setUp->verbose != 0 )
2598  {
2599  std::cout << "-----------------------------------------------------------" << std::endl;
2600  std::cout << "| MODE: DistancesFrag |" << std::endl;
2601  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2602  }
2603 
2604  if ( setUp->htmlReport )
2605  {
2606  //================================ Report title
2607  rvapi_set_text ( "<h1>ProSHADE Results: Searching fragments in database</h1>",
2608  "body",
2609  setUp->htmlReportLine,
2610  0,
2611  1,
2612  1 );
2613  setUp->htmlReportLine += 1;
2614 
2615  //==================================== Create section
2616  rvapi_add_section ( "ProgressSection",
2617  "Progress",
2618  "body",
2619  setUp->htmlReportLine,
2620  0,
2621  1,
2622  1,
2623  true );
2624  setUp->htmlReportLine += 1;
2625 
2626  std::stringstream hlpSS;
2627  hlpSS << "<font color=\"green\">" << "Starting fragment search of file " << setUp->structFiles.at(0) << " against the database." << "</font>";
2628  rvapi_set_text ( hlpSS.str().c_str(),
2629  "ProgressSection",
2630  setUp->htmlReportLineProgress,
2631  1,
2632  1,
2633  1 );
2634  setUp->htmlReportLineProgress += 1;
2635  rvapi_flush ( );
2636  }
2637 
2639 
2640  if ( setUp->verbose > 0 )
2641  {
2642  std::cout << std::endl << "-----------------------------------------------------------" << std::endl;
2643  std::cout << "| COMPLETED |" << std::endl;
2644  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2645  }
2646 
2647  if ( setUp->htmlReport )
2648  {
2649  std::stringstream hlpSS;
2650  hlpSS << "<font color=\"green\">" << "COMPLETED." << "</font>";
2651  rvapi_set_text ( hlpSS.str().c_str(),
2652  "ProgressSection",
2653  setUp->htmlReportLineProgress,
2654  1,
2655  1,
2656  1 );
2657  setUp->htmlReportLineProgress += 1;
2658 
2659  rvapi_flush ( );
2660  }
2661 
2662  if ( setUp->verbose > 0 )
2663  {
2664  std::cout << "-----------------------------------------------------------" << std::endl;
2665  std::cout << "| RESULTS |" << std::endl;
2666  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
2667  }
2668 
2669  std::vector< std::vector<double> > enLevDists;
2670  std::vector< std::vector<double> > trSigmaDists;
2671  std::vector< std::vector<double> > fullRotFnDists;
2672  if ( setUp->energyLevelDist )
2673  {
2674  enLevDists = distObj->getFragEnergyLevelsDistances ( );
2675  }
2676 
2677  if ( setUp->traceSigmaDist )
2678  {
2679  trSigmaDists = distObj->getFragTraceSigmaDistances ( );
2680  }
2681 
2682  if ( setUp->fullRotFnDist )
2683  {
2684  fullRotFnDists = distObj->getFragFullRotationDistances ( );
2685  }
2686 
2687  if ( setUp->verbose > -1 )
2688  {
2689  double maxFrag = std::max ( enLevDists.size(), std::max ( trSigmaDists.size(), fullRotFnDists.size() ) );
2690  for ( unsigned int frag = 0; frag < static_cast<unsigned int> ( maxFrag ); frag++ )
2691  {
2692  printf ( "Fragment %d Results:\n", frag );
2693  printf ( "--------------------\n" );
2694  if ( setUp->energyLevelDist )
2695  {
2696  printf ( "Energy levels descriptor distances : %+.4f", enLevDists.at(frag).at(0) );
2697  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( enLevDists.at(frag).size() ); iter++ )
2698  {
2699  printf ( " %+.4f", enLevDists.at(frag).at(iter) );
2700  }
2701  std::cout << std::endl;
2702  }
2703  if ( setUp->traceSigmaDist )
2704  {
2705  printf ( "Trace sigma descriptor distances : %+.4f", trSigmaDists.at(frag).at(0) );
2706  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( trSigmaDists.at(frag).size() ); iter++ )
2707  {
2708  printf ( " %+.4f", trSigmaDists.at(frag).at(iter) );
2709  }
2710  std::cout << std::endl;
2711  }
2712  if ( setUp->fullRotFnDist )
2713  {
2714  printf ( "Full RF descriptor distances : %+.4f", fullRotFnDists.at(frag).at(0) );
2715  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( fullRotFnDists.at(frag).size() ); iter++ )
2716  {
2717  printf ( " %+.4f", fullRotFnDists.at(frag).at(iter) );
2718  }
2719  std::cout << std::endl;
2720  }
2721  std::cout << std::endl;
2722  }
2723 
2724  std::cout << std::endl;
2725  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( setUp->structFiles.size() ); iter++ )
2726  {
2727  std::cout << "Matching structure names : " << setUp->structFiles.at(iter) << std::endl;
2728  }
2729  }
2730 
2731  if ( setUp->htmlReport )
2732  {
2733  int maxFrag = std::max ( enLevDists.size(), std::max ( trSigmaDists.size(), fullRotFnDists.size() ) );
2734 
2735  //================================ Create section
2736  rvapi_add_section ( "ResultsSection",
2737  "Fragment Distances",
2738  "body",
2739  settings->htmlReportLine,
2740  0,
2741  1,
2742  1,
2743  true );
2744  settings->htmlReportLine += 1;
2745 
2746  //================================ Fragment distances table for Enetry Levels
2747  rvapi_add_table ( "FragmentDistancesELTable",
2748  "Fragment Energy Level distances to database entries",
2749  "ResultsSection",
2750  0,
2751  0,
2752  enLevDists.size(),
2753  enLevDists.at(0).size(),
2754  1 );
2755 
2756  // ... Column headers
2757  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( enLevDists.at(0).size() ); iter++ )
2758  {
2759  std::stringstream hlpSS;
2760  hlpSS << "Database entry " << setUp->structFiles.at(iter);
2761  std::stringstream hlpSS2;
2762  hlpSS2 << "This is the Energy Levels distance for the fragment in the row to the database entry listed here (" << setUp->structFiles.at(iter) << ")";
2763  rvapi_put_horz_theader ( "FragmentDistancesELTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2764  }
2765 
2766  // ... Row headers
2767  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( maxFrag ); iter++ )
2768  {
2769  std::stringstream hlpSS;
2770  hlpSS << "Fragment Number " << iter;
2771  std::stringstream hlpSS2;
2772  hlpSS2 << "This is the Energy Levels distance for the fragment number " << iter << " to the database entry in the column header.";
2773  rvapi_put_vert_theader ( "FragmentDistancesELTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2774  }
2775 
2776  // ... Fill in data
2777  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( enLevDists.size() ); rIter++ )
2778  {
2779  for ( unsigned int cIter = 0; cIter < static_cast<unsigned int> ( enLevDists.at(rIter).size() ); cIter++ )
2780  {
2781  std::stringstream hlpSS;
2782  hlpSS << std::showpos << ProSHADE_internal_misc::roundDouble ( enLevDists.at(rIter).at(cIter) * 1000.0 ) / 1000.0;
2783  if ( hlpSS.str().length() != 6 ) { int hlp = 6 - hlpSS.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS << " "; } }
2784  if ( hlpSS.str().length() > 6 ) { hlpSS.str( hlpSS.str().substr( 0, 6 ) ); }
2785  rvapi_put_table_string ( "FragmentDistancesELTable", hlpSS.str().c_str(), rIter, cIter );
2786  }
2787  }
2788 
2789  //================================ Fragment distances table for Trace Sigma
2790  rvapi_add_table ( "FragmentDistancesTSTable",
2791  "Fragment Trace Sigma distances to database entries",
2792  "ResultsSection",
2793  enLevDists.size() + 1,
2794  0,
2795  trSigmaDists.size(),
2796  trSigmaDists.at(0).size(),
2797  1 );
2798 
2799  // ... Column headers
2800  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( enLevDists.at(0).size() ); iter++ )
2801  {
2802  std::stringstream hlpSS;
2803  hlpSS << "Database entry " << setUp->structFiles.at(iter);
2804  std::stringstream hlpSS2;
2805  hlpSS2 << "This is the Trace Sigma distance for the fragment in the row to the database entry listed here (" << setUp->structFiles.at(iter) << ")";
2806  rvapi_put_horz_theader ( "FragmentDistancesTSTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2807  }
2808 
2809  // ... Row headers
2810  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( maxFrag ); iter++ )
2811  {
2812  std::stringstream hlpSS;
2813  hlpSS << "Fragment Number " << iter;
2814  std::stringstream hlpSS2;
2815  hlpSS2 << "This is the Trace Sigma distance for the fragment number " << iter << " to the database entry in the column header.";
2816  rvapi_put_vert_theader ( "FragmentDistancesTSTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2817  }
2818 
2819  // ... Fill in data
2820  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( trSigmaDists.size() ); rIter++ )
2821  {
2822  for ( unsigned int cIter = 0; cIter < static_cast<unsigned int> ( trSigmaDists.at(rIter).size() ); cIter++ )
2823  {
2824  std::stringstream hlpSS;
2825  hlpSS << std::showpos << ProSHADE_internal_misc::roundDouble ( trSigmaDists.at(rIter).at(cIter) * 1000.0 ) / 1000.0;
2826  if ( hlpSS.str().length() != 6 ) { int hlp = 6 - hlpSS.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS << " "; } }
2827  if ( hlpSS.str().length() > 6 ) { hlpSS.str( hlpSS.str().substr( 0, 6 ) ); }
2828  rvapi_put_table_string ( "FragmentDistancesTSTable", hlpSS.str().c_str(), rIter, cIter );
2829  }
2830  }
2831 
2832  //================================ Fragment distances table for Rotation Function
2833  rvapi_add_table ( "FragmentDistancesRFTable",
2834  "Fragment Rotation Function distances to database entries",
2835  "ResultsSection",
2836  enLevDists.size() + trSigmaDists.size() + 1,
2837  0,
2838  fullRotFnDists.size(),
2839  fullRotFnDists.at(0).size(),
2840  1 );
2841 
2842  // ... Column headers
2843  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( fullRotFnDists.at(0).size() ); iter++ )
2844  {
2845  std::stringstream hlpSS;
2846  hlpSS << "Database entry " << setUp->structFiles.at(iter);
2847  std::stringstream hlpSS2;
2848  hlpSS2 << "This is the Rotation Function distance for the fragment in the row to the database entry listed here (" << setUp->structFiles.at(iter) << ")";
2849  rvapi_put_horz_theader ( "FragmentDistancesRFTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2850  }
2851 
2852  // ... Row headers
2853  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( maxFrag ); iter++ )
2854  {
2855  std::stringstream hlpSS;
2856  hlpSS << "Fragment Number " << iter;
2857  std::stringstream hlpSS2;
2858  hlpSS2 << "This is the Rotation Function distance for the fragment number " << iter << " to the database entry in the column header.";
2859  rvapi_put_vert_theader ( "FragmentDistancesRFTable", hlpSS.str().c_str(), hlpSS2.str().c_str(), iter );
2860  }
2861 
2862  // ... Fill in data
2863  for ( unsigned int rIter = 0; rIter < static_cast<unsigned int> ( fullRotFnDists.size() ); rIter++ )
2864  {
2865  for ( unsigned int cIter = 0; cIter < static_cast<unsigned int> ( fullRotFnDists.at(rIter).size() ); cIter++ )
2866  {
2867  std::stringstream hlpSS;
2868  hlpSS << std::showpos << ProSHADE_internal_misc::roundDouble ( fullRotFnDists.at(rIter).at(cIter) * 1000.0 ) / 1000.0;
2869  if ( hlpSS.str().length() != 6 ) { int hlp = 6 - hlpSS.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS << " "; } }
2870  if ( hlpSS.str().length() > 6 ) { hlpSS.str( hlpSS.str().substr( 0, 6 ) ); }
2871  rvapi_put_table_string ( "FragmentDistancesRFTable", hlpSS.str().c_str(), rIter, cIter );
2872  }
2873  }
2874 
2875  rvapi_flush ( );
2876  }
2877 
2878  delete distObj;
2879  }
2880 
2881  //======================================== Done
2882 
2883 }
2884 
2888 {
2889  //======================================== Clear vectors
2890  this->crossCorrDists.clear ( );
2891  this->traceSigmaDists.clear ( );
2892  this->rotFunctionDists.clear ( );
2893  this->cyclicSymmetries.clear ( );
2894  this->cyclicSymmetriesClear.clear ( );
2895  this->dihedralSymmetries.clear ( );
2896  this->tetrahedralSymmetry.clear ( );
2897  this->octahedralSymmetry.clear ( );
2898  this->icosahedralSymmetry.clear ( );
2899  this->fragmentList.clear ( );
2900 
2901  //======================================== Done
2902 
2903 }
2904 
2911 {
2912  //======================================== Check for sanity
2913  return ( std::string ( __PROSHADE_VERSION__ ) );
2914 
2915  //======================================== Done
2916 
2917 }
2918 
2925 {
2926  //======================================== Check for sanity
2927  this->structFiles.emplace_back ( str );
2928 
2929  //======================================== Done
2930 
2931 }
2932 
2938 std::vector<std::string> ProSHADE::ProSHADE::getMapFragments ( )
2939 {
2940  //======================================== Check for sanity
2941  if ( !this->fragmentsAvailable )
2942  {
2943  std::cerr << "!!! ProSHADE ERROR !!! Attempted to obtain list of map fragments, but did not compute the fragmentation beforehand. This is an undefined behaviour - terminating..." << std::endl;
2944  exit ( -1 );
2945  }
2946 
2947  //======================================== Done
2948  return ( this->fragmentList );
2949 }
2950 
2960 {
2961  //======================================== Check for sanity
2962  if ( this->distancesAvailable )
2963  {
2964  return ( this->crossCorrDists );
2965  }
2966  else
2967  {
2968  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the cross-correlation distances without requesting their computation first. Returning empty vector." << std::endl;
2969  return ( std::vector<double> () );
2970  }
2971 
2972  //======================================== Done
2973 
2974 }
2975 
2986 {
2987  //======================================== Check for sanity
2988  if ( this->distancesAvailable )
2989  {
2990  return ( this->traceSigmaDists );
2991  }
2992  else
2993  {
2994  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the trace sigma distances without requesting their computation first. Returning empty vector." << std::endl;
2995  return ( std::vector<double> () );
2996  }
2997 
2998  //======================================== Done
2999 
3000 }
3001 
3012 {
3013  //======================================== Check for sanity
3014  if ( this->distancesAvailable )
3015  {
3016  return ( this->rotFunctionDists );
3017  }
3018  else
3019  {
3020  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the rotation function based distances without requesting their computation first. Returning empty vector." << std::endl;
3021  return ( std::vector<double> () );
3022  }
3023 
3024  //======================================== Done
3025 
3026 }
3027 
3037 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getCyclicSymmetries ( )
3038 {
3039  //======================================== Check for sanity
3040  if ( this->symmetriesAvailable )
3041  {
3042  return ( this->cyclicSymmetries );
3043  }
3044  else
3045  {
3046  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the cyclic symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3047  return ( std::vector< std::array<double,5> > () );
3048  }
3049 
3050  //======================================== Done
3051 
3052 }
3053 
3063 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getClearCyclicSymmetries ( )
3064 {
3065  //======================================== Check for sanity
3066  if ( this->symmetriesAvailable )
3067  {
3068  return ( this->cyclicSymmetriesClear );
3069  }
3070  else
3071  {
3072  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the clear cyclic symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3073  return ( std::vector< std::array<double,5> > () );
3074  }
3075 
3076  //======================================== Done
3077 
3078 }
3079 
3092 {
3093  //======================================== Check for sanity
3094  if ( this->symmetriesAvailable )
3095  {
3096  std::vector< double > ret;
3097 
3098  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->cyclicSymmetries.size() ); iter++ )
3099  {
3100  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->cyclicSymmetries.at(iter).size() ); it++ )
3101  {
3102  ret.emplace_back ( this->cyclicSymmetries.at(iter).at(it) );
3103  }
3104  ret.emplace_back ( -999.999 );
3105  }
3106 
3107  return ( ret );
3108  }
3109  else
3110  {
3111  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the cyclic symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3112  return ( std::vector< double > () );
3113  }
3114 
3115  //======================================== Done
3116 
3117 }
3118 
3132 {
3133  //======================================== Check for sanity
3134  if ( this->symmetriesAvailable )
3135  {
3136  std::vector< double > ret;
3137 
3138  for ( unsigned int i = 0; i < static_cast<unsigned int> ( this->dihedralSymmetries.size() ); i++ )
3139  {
3140  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->dihedralSymmetries.at(i).size() ); iter++ )
3141  {
3142  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->dihedralSymmetries.at(i).at(iter).size() ); it++ )
3143  {
3144  ret.emplace_back ( this->dihedralSymmetries.at(i).at(iter).at(it) );
3145  }
3146  ret.emplace_back ( -999.999 );
3147  }
3148  ret.emplace_back ( -777.777 );
3149  }
3150 
3151  return ( ret );
3152  }
3153  else
3154  {
3155  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the dihedral symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3156  return ( std::vector< double > () );
3157  }
3158 
3159  //======================================== Done
3160 
3161 }
3162 
3173 std::vector< std::vector<std::array<double,6> > > ProSHADE::ProSHADE::getDihedralSymmetries ( )
3174 {
3175  //======================================== Check for sanity
3176  if ( this->symmetriesAvailable )
3177  {
3178  return ( this->dihedralSymmetries );
3179  }
3180  else
3181  {
3182  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the dihedral symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3183  return ( std::vector< std::vector< std::array<double,6> > > () );
3184  }
3185 
3186  //======================================== Done
3187 
3188 }
3189 
3200 std::vector< std::vector<std::array<double,6> > > ProSHADE::ProSHADE::getClearDihedralSymmetries ( )
3201 {
3202  //======================================== Check for sanity
3203  if ( this->symmetriesAvailable )
3204  {
3205  return ( this->dihedralSymmetriesClear );
3206  }
3207  else
3208  {
3209  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the clear dihedral symmetries list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3210  return ( std::vector< std::vector< std::array<double,6> > > () );
3211  }
3212 
3213  //======================================== Done
3214 
3215 }
3216 
3226 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getTetrahedralSymmetries ( )
3227 {
3228  //======================================== Check for sanity
3229  if ( this->symmetriesAvailable )
3230  {
3231  return ( this->tetrahedralSymmetry );
3232  }
3233  else
3234  {
3235  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the tetrahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3236  return ( std::vector< std::array<double,5> > () );
3237  }
3238 
3239  //======================================== Done
3240 
3241 }
3242 
3254 {
3255  //======================================== Check for sanity
3256  if ( this->symmetriesAvailable )
3257  {
3258  std::vector< double > ret;
3259 
3260  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->tetrahedralSymmetry.size() ); iter++ )
3261  {
3262  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->tetrahedralSymmetry.at(iter).size() ); it++ )
3263  {
3264  ret.emplace_back ( this->tetrahedralSymmetry.at(iter).at(it) );
3265  }
3266  ret.emplace_back ( -999.999 );
3267  }
3268 
3269  return ( ret );
3270  }
3271  else
3272  {
3273  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the tetrahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3274  return ( std::vector< double > () );
3275  }
3276 
3277  //======================================== Done
3278 
3279 }
3280 
3290 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getOctahedralSymmetries ( )
3291 {
3292  //======================================== Check for sanity
3293  if ( this->symmetriesAvailable )
3294  {
3295  return ( this->octahedralSymmetry );
3296  }
3297  else
3298  {
3299  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the octahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3300  return ( std::vector< std::array<double,5> > () );
3301  }
3302 
3303  //======================================== Done
3304 
3305 }
3306 
3318 {
3319  //======================================== Check for sanity
3320  if ( this->symmetriesAvailable )
3321  {
3322  std::vector< double > ret;
3323 
3324  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->octahedralSymmetry.size() ); iter++ )
3325  {
3326  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->octahedralSymmetry.at(iter).size() ); it++ )
3327  {
3328  ret.emplace_back ( this->octahedralSymmetry.at(iter).at(it) );
3329  }
3330  ret.emplace_back ( -999.999 );
3331  }
3332 
3333  return ( ret );
3334  }
3335  else
3336  {
3337  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the octahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3338  return ( std::vector< double > () );
3339  }
3340 
3341  //======================================== Done
3342 
3343 }
3344 
3354 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getIcosahedralSymmetries ( )
3355 {
3356  //======================================== Check for sanity
3357  if ( this->symmetriesAvailable )
3358  {
3359  return ( this->icosahedralSymmetry );
3360  }
3361  else
3362  {
3363  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the icosahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3364  return ( std::vector< std::array<double,5> > () );
3365  }
3366 
3367  //======================================== Done
3368 
3369 }
3370 
3382 {
3383  //======================================== Check for sanity
3384  if ( this->symmetriesAvailable )
3385  {
3386  std::vector< double > ret;
3387 
3388  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( this->icosahedralSymmetry.size() ); iter++ )
3389  {
3390  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->icosahedralSymmetry.at(iter).size() ); it++ )
3391  {
3392  ret.emplace_back ( this->icosahedralSymmetry.at(iter).at(it) );
3393  }
3394  ret.emplace_back ( -999.999 );
3395  }
3396 
3397  return ( ret );
3398  }
3399  else
3400  {
3401  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the icosahedral symmetry list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3402  return ( std::vector< double > () );
3403  }
3404 
3405  //======================================== Done
3406 
3407 }
3408 
3419 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getRecommendedSymmetry ( )
3420 {
3421  //======================================== Check for sanity
3422  if ( this->symmetriesAvailable )
3423  {
3424  //==================================== Initialise
3426  std::vector< std::array<double,5> > ret;
3427  std::array<double,5> hlpArr;
3428 
3429  //==================================== Identity element
3430  hlpArr[0] = 1.0;
3431  hlpArr[1] = 1.0;
3432  hlpArr[2] = 0.0;
3433  hlpArr[3] = 0.0;
3434  hlpArr[4] = 0.0;
3435  ret.emplace_back ( hlpArr );
3436 
3437  //==================================== If icosahedral exist, return that
3438  if ( this->icosahedralSymmetry.size() < 1 )
3439  {
3440  this->icosahedralSymmetry = getIcosahedralSymmetries ( );
3441  }
3442 
3443  if ( static_cast<unsigned int> ( this->icosahedralSymmetry.size() ) > 0 )
3444  {
3445  std::vector< std::array<double,5> > hlp = symObj.generateIcosElements ( this->icosahedralSymmetry, this->settings, -1 );
3446  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3447  {
3448  ret.emplace_back ( hlp.at(iter) );
3449  }
3450  return ( ret );
3451  }
3452 
3453  //==================================== If octahedral exist, return that
3454  if ( this->octahedralSymmetry.size() < 1 )
3455  {
3456  this->octahedralSymmetry = getOctahedralSymmetries ( );
3457  }
3458 
3459  if ( static_cast<unsigned int> ( this->octahedralSymmetry.size() ) > 0 )
3460  {
3461  std::vector< std::array<double,5> > hlp = symObj.generateOctaElements ( this->octahedralSymmetry, this->settings, -1 );
3462  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3463  {
3464  ret.emplace_back ( hlp.at(iter) );
3465  }
3466  return ( ret );
3467  }
3468 
3469  //==================================== If tetrahedral exist, return that
3470  if ( this->tetrahedralSymmetry.size() < 1 )
3471  {
3472  this->tetrahedralSymmetry = getTetrahedralSymmetries ( );
3473  }
3474 
3475  if ( static_cast<unsigned int> ( this->tetrahedralSymmetry.size() ) > 0 )
3476  {
3477  std::vector< std::array<double,5> > hlp = symObj.generateTetrElements ( this->tetrahedralSymmetry, this->settings, -1 );
3478  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3479  {
3480  ret.emplace_back ( hlp.at(iter) );
3481  }
3482  return ( ret );
3483  }
3484 
3485  //==================================== If dihedral exist, return that
3486  if ( this->dihedralSymmetries.size() < 1 )
3487  {
3488  this->dihedralSymmetries = getDihedralSymmetries ( );
3489  }
3490  this->dihedralSymmetriesClear = getClearDihedralSymmetries ( );
3491 
3492  if ( static_cast<unsigned int> ( this->dihedralSymmetriesClear.size() ) > 0 )
3493  {
3494  for ( unsigned int it = 0; it < 2; it++ )
3495  {
3496  if ( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) % 2 == 0 )
3497  {
3498  for ( int iter = -std::ceil( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
3499  {
3500  if ( iter == 0 ) { continue; }
3501  if ( iter == -std::ceil( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) / 2.0 ) ) { continue; }
3502  hlpArr[0] = this->dihedralSymmetriesClear.at(0).at(it)[0];
3503  hlpArr[1] = this->dihedralSymmetriesClear.at(0).at(it)[1];
3504  hlpArr[2] = this->dihedralSymmetriesClear.at(0).at(it)[2];
3505  hlpArr[3] = this->dihedralSymmetriesClear.at(0).at(it)[3];
3506  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) );
3507  ret.emplace_back ( hlpArr );
3508  }
3509  }
3510  else
3511  {
3512  for ( int iter = -std::floor( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) / 2.0 ); iter++ )
3513  {
3514  if ( iter == 0 ) { continue; }
3515  hlpArr[0] = this->dihedralSymmetriesClear.at(0).at(it)[0];
3516  hlpArr[1] = this->dihedralSymmetriesClear.at(0).at(it)[1];
3517  hlpArr[2] = this->dihedralSymmetriesClear.at(0).at(it)[2];
3518  hlpArr[3] = this->dihedralSymmetriesClear.at(0).at(it)[3];
3519  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->dihedralSymmetriesClear.at(0).at(it)[0] ) );
3520  ret.emplace_back ( hlpArr );
3521  }
3522  }
3523  }
3524 
3525  return ( ret );
3526  }
3527 
3528  //==================================== If cyclic exist, return that
3529  if ( this->cyclicSymmetries.size() < 1 )
3530  {
3531  this->cyclicSymmetries = getCyclicSymmetries ( );
3532  }
3533  this->cyclicSymmetriesClear = getClearCyclicSymmetries ( );
3534 
3535  if ( static_cast<unsigned int> ( this->cyclicSymmetriesClear.size() ) > 0 )
3536  {
3537  if ( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) % 2 == 0 )
3538  {
3539  for ( int iter = -std::ceil( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) / 2.0 ); iter++ )
3540  {
3541  if ( iter == 0 ) { continue; }
3542  if ( iter == -std::ceil( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) / 2.0 ) ) { continue; }
3543  hlpArr[0] = this->cyclicSymmetriesClear.at(0)[0];
3544  hlpArr[1] = this->cyclicSymmetriesClear.at(0)[1];
3545  hlpArr[2] = this->cyclicSymmetriesClear.at(0)[2];
3546  hlpArr[3] = this->cyclicSymmetriesClear.at(0)[3];
3547  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->cyclicSymmetriesClear.at(0)[0] ) );
3548  ret.emplace_back ( hlpArr );
3549  }
3550  }
3551  else
3552  {
3553  for ( int iter = -std::floor( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cyclicSymmetriesClear.at(0)[0] ) / 2.0 ); iter++ )
3554  {
3555  if ( iter == 0 ) { continue; }
3556  hlpArr[0] = this->cyclicSymmetriesClear.at(0)[0];
3557  hlpArr[1] = this->cyclicSymmetriesClear.at(0)[1];
3558  hlpArr[2] = this->cyclicSymmetriesClear.at(0)[2];
3559  hlpArr[3] = this->cyclicSymmetriesClear.at(0)[3];
3560  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->cyclicSymmetriesClear.at(0)[0] ) );
3561  ret.emplace_back ( hlpArr );
3562  }
3563  }
3564 
3565  return ( ret );
3566  }
3567 
3568  std::cout << "!!! ProSHADE WARNING !!! Did not find any symmetries to report. Returning empty vector..." << std::endl;
3569  return ( std::vector< std::array<double,5> > () );
3570  }
3571  else
3572  {
3573  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the symmetry elements list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3574  return ( std::vector< std::array<double,5> > () );
3575  }
3576 
3577  //======================================== Done
3578  std::cerr << "!!! ProSHADE ERROR !!! Something went wery wrong... Please report this. Returning empty vector..." << std::endl;
3579  return ( std::vector< std::array<double,5> > () );
3580 }
3581 
3595 {
3596  //======================================== Check for sanity
3597  if ( this->symmetriesAvailable )
3598  {
3599  std::vector< std::array< double, 5 > > hlp = this->getRecommendedSymmetry ( );
3600  std::vector< double > ret;
3601 
3602  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3603  {
3604  for ( unsigned int it = 0; it < static_cast<unsigned int> ( hlp.at(iter).size() ); it++ )
3605  {
3606  ret.emplace_back ( hlp.at(iter).at(it) );
3607  }
3608  ret.emplace_back ( -999.999 );
3609  }
3610 
3611  return ( ret );
3612  }
3613  else
3614  {
3615  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the symmetry elements list without requesting their computation first. Returning empty vector." << std::endl;
3616  return ( std::vector< double > () );
3617  }
3618 
3619  //======================================== Done
3620 
3621 }
3622 
3635 std::vector< std::array<double,5> > ProSHADE::ProSHADE::getSpecificSymmetryElements ( std::string symType,
3636  int symFold )
3637 {
3638  //======================================== Check for sanity
3639  if ( this->symmetriesAvailable )
3640  {
3641  //==================================== Initialise
3643  std::vector< std::array<double,5> > ret;
3644  std::array<double,5> hlpArr;
3645 
3646  //==================================== Identity element
3647  hlpArr[0] = 1.0;
3648  hlpArr[1] = 1.0;
3649  hlpArr[2] = 0.0;
3650  hlpArr[3] = 0.0;
3651  hlpArr[4] = 0.0;
3652  ret.emplace_back ( hlpArr );
3653 
3654  //==================================== If no fold is given, use the highest scoring one
3655  if ( symFold == 0 )
3656  {
3657  if ( symType == "D" )
3658  {
3659  //============================ If not yet loaded, get them
3660  if ( this->dihedralSymmetries.size() < 1 )
3661  {
3662  this->dihedralSymmetries = getDihedralSymmetries ( );
3663  }
3664 
3665  //============================ Take highest peak
3666  symFold = this->dihedralSymmetries.at(0).at(0)[0];
3667  }
3668  else
3669  {
3670  //============================ If not yet loaded, get them
3671  if ( this->cyclicSymmetries.size() < 1 )
3672  {
3673  this->cyclicSymmetries = getCyclicSymmetries ( );
3674  }
3675 
3676  //============================ Take highest peak
3677  symFold = this->cyclicSymmetries.at(0)[0];
3678  }
3679  }
3680 
3681  //==================================== Cyclic symmetry
3682  if ( symType == "C" )
3683  {
3684  //================================ If not yet loaded, get them
3685  if ( this->cyclicSymmetries.size() < 1 )
3686  {
3687  this->cyclicSymmetries = getCyclicSymmetries ( );
3688  }
3689 
3690  //================================ Locate the highest cyclic symmetry with required fold
3691  bool foundSym = false;
3692  for ( unsigned int it = 0; it < static_cast<unsigned int> ( this->cyclicSymmetries.size() ); it++ )
3693  {
3694  if ( this->cyclicSymmetries.at(it)[0] == symFold )
3695  {
3696  //======================== Init
3697  foundSym = true;
3698 
3699  //======================== Find elements
3700  if ( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) % 2 == 0 )
3701  {
3702  for ( int iter = -std::ceil( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) / 2.0 ); iter++ )
3703  {
3704  if ( iter == 0 ) { continue; }
3705  if ( iter == -std::ceil( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) / 2.0 ) ) { continue; }
3706  hlpArr[0] = this->cyclicSymmetries.at(it)[0];
3707  hlpArr[1] = this->cyclicSymmetries.at(it)[1];
3708  hlpArr[2] = this->cyclicSymmetries.at(it)[2];
3709  hlpArr[3] = this->cyclicSymmetries.at(it)[3];
3710  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->cyclicSymmetries.at(it)[0] ) );
3711  ret.emplace_back ( hlpArr );
3712  }
3713  }
3714  else
3715  {
3716  for ( int iter = -std::floor( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->cyclicSymmetries.at(it)[0] ) / 2.0 ); iter++ )
3717  {
3718  if ( iter == 0 ) { continue; }
3719  hlpArr[0] = this->cyclicSymmetries.at(it)[0];
3720  hlpArr[1] = this->cyclicSymmetries.at(it)[1];
3721  hlpArr[2] = this->cyclicSymmetries.at(it)[2];
3722  hlpArr[3] = this->cyclicSymmetries.at(it)[3];
3723  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->cyclicSymmetries.at(it)[0] ) );
3724  ret.emplace_back ( hlpArr );
3725  }
3726  }
3727 
3728  //======================== Done
3729  break;
3730  }
3731  }
3732 
3733  //================================ Report if required fold was not found
3734  if ( !foundSym )
3735  {
3736  std::cout << "!!! ProSHADE WARNING !!! Requested symmetry elements for " << symType << "-" << symFold << " symmetry, but this symmetry was not found. Returning empty vector." << std::endl;
3737  return ( std::vector< std::array<double,5> > () );
3738  }
3739  }
3740 
3741  //==================================== Dihedral symmetry
3742  if ( symType == "D" )
3743  {
3744  //================================ If not yet loaded, get them
3745  if ( this->dihedralSymmetries.size() < 1 )
3746  {
3747  this->dihedralSymmetries = getDihedralSymmetries ( );
3748  }
3749 
3750  //================================ Locate the highest cyclic symmetry with required fold
3751  bool foundSym = false;
3752  for ( unsigned int i = 0; i < static_cast<unsigned int> ( this->dihedralSymmetries.size() ); i++ )
3753  {
3754  if ( this->dihedralSymmetries.at(i).at(0)[0] == symFold )
3755  {
3756  //======================== Init
3757  foundSym = true;
3758 
3759  //======================== Find elements
3760  for ( unsigned int it = 0; it < 2; it++ )
3761  {
3762  if ( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) % 2 == 0 )
3763  {
3764  for ( int iter = -std::ceil( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) / 2.0 ); iter <= std::ceil( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) / 2.0 ); iter++ )
3765  {
3766  if ( iter == 0 ) { continue; }
3767  if ( iter == -std::ceil( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) / 2.0 ) ) { continue; }
3768  hlpArr[0] = this->dihedralSymmetries.at(i).at(it)[0];
3769  hlpArr[1] = this->dihedralSymmetries.at(i).at(it)[1];
3770  hlpArr[2] = this->dihedralSymmetries.at(i).at(it)[2];
3771  hlpArr[3] = this->dihedralSymmetries.at(i).at(it)[3];
3772  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->dihedralSymmetries.at(i).at(it)[0] ) );
3773  ret.emplace_back ( hlpArr );
3774  }
3775  }
3776  else
3777  {
3778  for ( int iter = -std::floor( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) / 2.0 ); iter <= std::floor( static_cast<int> ( this->dihedralSymmetries.at(i).at(it)[0] ) / 2.0 ); iter++ )
3779  {
3780  if ( iter == 0 ) { continue; }
3781  hlpArr[0] = this->dihedralSymmetries.at(i).at(it)[0];
3782  hlpArr[1] = this->dihedralSymmetries.at(i).at(it)[1];
3783  hlpArr[2] = this->dihedralSymmetries.at(i).at(it)[2];
3784  hlpArr[3] = this->dihedralSymmetries.at(i).at(it)[3];
3785  hlpArr[4] = iter * ( ( 2.0 * M_PI ) / static_cast<double> ( this->dihedralSymmetries.at(i).at(it)[0] ) );
3786  ret.emplace_back ( hlpArr );
3787  }
3788  }
3789  }
3790 
3791  //======================== Done
3792  break;
3793  }
3794  }
3795 
3796  //================================ Report if required fold was not found
3797  if ( !foundSym )
3798  {
3799  std::cout << "!!! ProSHADE WARNING !!! Requested symmetry elements for " << symType << "-" << symFold << " symmetry, but this symmetry was not found. Returning empty vector." << std::endl;
3800  return ( std::vector< std::array<double,5> > () );
3801  }
3802  }
3803 
3804  //==================================== Tetrahedral symmetry
3805  if ( symType == "T" )
3806  {
3807  //================================ If not yet loaded, get them
3808  if ( this->tetrahedralSymmetry.size() < 1 )
3809  {
3810  this->tetrahedralSymmetry = getTetrahedralSymmetries ( );
3811  }
3812 
3813  //================================ Generate
3814  if ( this->tetrahedralSymmetry.size() > 1 )
3815  {
3816  std::vector< std::array<double,5 >> hlp = symObj.generateTetrElements ( this->tetrahedralSymmetry, settings, -1 );
3817  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3818  {
3819  ret.emplace_back ( hlp.at(iter) );
3820  }
3821  }
3822 
3823  //================================ Report if required fold was not found
3824  if ( this->tetrahedralSymmetry.size() < 1 )
3825  {
3826  std::cout << "!!! ProSHADE WARNING !!! Requested symmetry elements for tetrahedral symmetry, but this symmetry was not found. Returning empty vector." << std::endl;
3827  return ( std::vector< std::array<double,5> > () );
3828  }
3829  }
3830 
3831  //==================================== Octahedral symmetry
3832  if ( symType == "O" )
3833  {
3834  //================================ If not yet loaded, get them
3835  if ( this->octahedralSymmetry.size() < 1 )
3836  {
3837  this->octahedralSymmetry = getOctahedralSymmetries ( );
3838  }
3839 
3840  //================================ Generate
3841  if ( this->octahedralSymmetry.size() > 1 )
3842  {
3843  std::vector< std::array<double,5> > hlp = symObj.generateOctaElements ( this->octahedralSymmetry, settings, -1 );
3844  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3845  {
3846  ret.emplace_back ( hlp.at(iter) );
3847  }
3848  }
3849 
3850  //================================ Report if required fold was not found
3851  if ( this->octahedralSymmetry.size() < 1 )
3852  {
3853  std::cout << "!!! ProSHADE WARNING !!! Requested symmetry elements for octahedral symmetry, but this symmetry was not found. Returning empty vector." << std::endl;
3854  return ( std::vector< std::array<double,5> > () );
3855  }
3856  }
3857 
3858  //==================================== Icosahedral symmetry
3859  if ( symType == "I" )
3860  {
3861  //================================ If not yet loaded, get them
3862  if ( this->icosahedralSymmetry.size() < 1 )
3863  {
3864  this->icosahedralSymmetry = getIcosahedralSymmetries ( );
3865  }
3866 
3867  //================================ Generate
3868  if ( this->icosahedralSymmetry.size() > 1 )
3869  {
3870  std::vector< std::array<double,5> > hlp = symObj.generateIcosElements ( this->icosahedralSymmetry, settings, -1 );
3871  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3872  {
3873  ret.emplace_back ( hlp.at(iter) );
3874  }
3875  }
3876 
3877  //================================ Report if required fold was not found
3878  if ( this->icosahedralSymmetry.size() < 1 )
3879  {
3880  std::cout << "!!! ProSHADE WARNING !!! Requested symmetry elements for icosahedral symmetry, but this symmetry was not found. Returning empty vector." << std::endl;
3881  return ( std::vector< std::array<double,5> > () );
3882  }
3883  }
3884 
3885  if ( ( symType != "I" ) && ( symType != "O" ) && ( symType != "T" ) && ( symType != "D" ) && ( symType != "C" ) )
3886  {
3887  std::cerr << "!!! ProSHADE ERROR !!! Unknown symmetry type supplied to the \"getSpecificSymmetryElements\" function. Allowed values are \"C\", \"D\", \"T\", \"O\" and \"I\". Terminating..." << std::endl;
3888  exit ( -1 );
3889  }
3890 
3891  //==================================== Symmetry element found, now returning
3892  return ( ret );
3893  }
3894  else
3895  {
3896  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the symmetry elements list without requesting their computation first. Returning empty vector of arrays." << std::endl;
3897  return ( std::vector< std::array<double,5> > () );
3898  }
3899 
3900  //======================================== Done
3901  std::cerr << "!!! ProSHADE ERROR !!! Something went wery wrong... Please report this. Returning empty vector..." << std::endl;
3902  return ( std::vector< std::array<double,5> > () );
3903 
3904 }
3905 
3920 std::vector< double > ProSHADE::ProSHADE::getSpecificSymmetryElementsPy ( std::string symType,
3921  int symFold )
3922 {
3923  //======================================== Check for sanity
3924  if ( this->symmetriesAvailable )
3925  {
3926  std::vector< std::array< double, 5 > > hlp = this->getSpecificSymmetryElements ( symType, symFold );
3927  std::vector< double > ret;
3928 
3929  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlp.size() ); iter++ )
3930  {
3931  for ( unsigned int it = 0; it < static_cast<unsigned int> ( hlp.at(iter).size() ); it++ )
3932  {
3933  ret.emplace_back ( hlp.at(iter).at(it) );
3934  }
3935  ret.emplace_back ( -999.999 );
3936  }
3937 
3938  return ( ret );
3939  }
3940  else
3941  {
3942  std::cout << "!!! ProSHADE WARNING !!! Attempted to access the symmetry elements list without requesting their computation first. Returning empty vector." << std::endl;
3943  return ( std::vector< double > () );
3944  }
3945 
3946  //======================================== Done
3947 
3948 }
double aaErrorTolerance
The tolerance parameter on matching axes for the angle-axis representation of rotations.
Definition: ProSHADE.h:128
bool wasBandGiven
Variable stating whether the bandwidth value was given by the user, or decided automatically.
Definition: ProSHADE.h:81
std::vector< double > getIcosahedralSymmetriesPy(void)
Accessor function for the icosahedral symmetries list for python.
Definition: ProSHADE.cpp:3381
std::vector< std::array< double, 5 > > getRecommendedSymmetry(void)
Accessor function for the recommended symmetry elements list.
Definition: ProSHADE.cpp:3419
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
std::vector< double > getRotFunctionDists(void)
Accessor function for the rotation function based distances vector.
Definition: ProSHADE.cpp:3011
double noIQRsFromMap
This is the number of interquartile distances from mean that is used to threshold the map masking...
Definition: ProSHADE.h:93
This class is responsible for reading in map and computing all its features and other possible map ma...
std::vector< std::vector< std::array< double, 6 > > > getClearDihedralSymmetries(void)
Accessor function for the dihedral symmetries list. These will be sorted using the fold and peak heig...
Definition: ProSHADE.cpp:3200
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, 6 > > > dnSymmClear
This variable holds the gap corrected Dihedral symmetry results.
bool dbDistOverlay
This value is false in all conditions, unless programatically changed. If changed, distance computations will use the phaseless database to compute overlay before distances computation. This is computationally expensive and requires phaseless as well as phased database.
Definition: ProSHADE.h:177
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
std::vector< double > getTetrahedralSymmetriesPy(void)
Accessor function for the tetrahedral symmetries list for python.
Definition: ProSHADE.cpp:3253
double databaseMinVolume
The smallest volume of a structure in the database.
Definition: ProSHADE.h:157
std::vector< std::array< double, 5 > > cnSymm
This variable holds the complete Cyclic symmetry results.
void printSettings()
Function for outputting the current settings recorded in the ProSHADE_settings class instance...
Definition: ProSHADE.cpp:190
std::string databaseName
The name of the bin file to which the database should be saved.
Definition: ProSHADE.h:156
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
bool wasExtraSpaceGiven
Variable stating whether the extra cell space value was given by the user, or decided automatically...
Definition: ProSHADE.h:110
double mapFragBoxFraction
Fraction of box that needs to have density in order to be passed on.
Definition: ProSHADE.h:153
std::vector< std::string > deleteModels
The filenames listed here consist of models which should have their density deleted from the map befo...
Definition: ProSHADE.h:180
std::vector< std::array< double, 5 > > getIcosahedralSymmetries(void)
Accessor function for the icosahedral symmetries list.
Definition: ProSHADE.cpp:3354
unsigned int bandwidth
This parameter determines the angular resolution of the spherical harmonics decomposition.
Definition: ProSHADE.h:80
std::vector< std::vector< double > > getFragTraceSigmaDistances()
This function returns a vector of vectors of trace sigma distances between each fragment and the whol...
bool wasShellSpacingGiven
Variable stating whether the distance between shells value was given by the user, or decided automati...
Definition: ProSHADE.h:97
bool htmlReport
Should HTML report for the run be created?
Definition: ProSHADE.h:186
int verbose
Should the software report on the progress, or just be quiet? Value between 0 (quiet) and 4 (loud) ...
Definition: ProSHADE.h:189
double rotAngle
The angle of the rotation to be done to the map structure in the map rotation mode.
Definition: ProSHADE.h:166
void printResultsClear(int verbose)
This function prints the cleared results to the screen.
bool saveWithAndWithout
This option decides whether both with and without phase spherical harmonics should be saved...
Definition: ProSHADE.h:102
std::string getProSHADEVersion(void)
Miscellanous function allowing the user to get the ProSHADE version.
Definition: ProSHADE.cpp:2910
std::vector< std::array< double, 5 > > generateTetrElements(std::vector< std::array< double, 5 > > symmAxes, ProSHADE::ProSHADE_settings *settings, int verbose=0)
This function generates the 12 unique tetrahedral symmetry group elements from the already detected a...
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
std::vector< std::array< double, 5 > > getCyclicSymmetries(void)
Accessor function for the cyclic symmetries list.
Definition: ProSHADE.cpp:3037
bool firstLineCOM
This is a special option for metal detection, please leave false.
Definition: ProSHADE.h:106
void fragmentMap(std::string axOrder, int verbose, ProSHADE::ProSHADE_settings *settings)
This function takes the clear map produced already and fragments it into overlapping boxes of given s...
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< double > getFullRotationDistances()
This function returns a vector of full rotation function distances between the first and all other st...
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...
std::vector< std::array< double, 5 > > icosAxes
This variable holds the 31 unique axes of the octahedral symmetry, if they are found.
std::vector< std::array< double, 5 > > generateOctaElements(std::vector< std::array< double, 5 > > symmAxes, ProSHADE::ProSHADE_settings *settings, int verbose=0)
This function generates the 24 octahedral symmetry group elements from the axes generated by generate...
double databaseMaxVolume
The largest volume allowed to exist in the database.
Definition: ProSHADE.h:158
std::vector< double > getDihedralSymmetriesPy(void)
Accessor function for the dihedral symmetries list for python.
Definition: ProSHADE.cpp:3131
ProSHADE(ProSHADE_settings *settings)
Contructor for the ProSHADE class.
Definition: ProSHADE.cpp:1168
double volumeTolerance
The percentage tolerance on each dimmension when comparing one structure to entire database...
Definition: ProSHADE.h:159
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
std::vector< std::array< double, 5 > > getSpecificSymmetryElements(std::string symType, int symFold=0)
Accessor function for the given symmetry elements list.
Definition: ProSHADE.cpp:3635
std::vector< std::string > getMapFragments(void)
Accessor function returning the list of fragment files produced by map fragmentation.
Definition: ProSHADE.cpp:2938
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
std::vector< double > getTraceSigmaDists(void)
Accessor function for the trace sigma distances vector.
Definition: ProSHADE.cpp:2985
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...
void appendStructure(std::string str)
Miscellanous function allowing adding a single string to the structures vector.
Definition: ProSHADE.cpp:2924
void printInfo(int verbose)
This is the main information output for the ProSHADE_mapFeatures class.
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
void getCommandLineParams(int argc, char *argv[])
This function parses the command line arguments and saves the user values into the settings class...
Definition: ProSHADE.cpp:433
std::vector< double > getOctahedralSymmetriesPy(void)
Accessor function for the octahedral symmetries list for python.
Definition: ProSHADE.cpp:3317
unsigned int phi
This parameter is the latitudd of the spherical grid mapping. It should be 2 * bandwidth unless there...
Definition: ProSHADE.h:84
std::vector< std::array< double, 5 > > cnSymmClear
This variable holds the gap corrected Cyclic symmetry results.
unsigned int maxRotError
This is the maximum allowed error in degrees for the rotation computation. This can be used to speed ...
Definition: ProSHADE.h:179
std::vector< std::array< double, 5 > > generateIcosElements(std::vector< std::array< double, 5 > > symmAxes, ProSHADE::ProSHADE_settings *settings, int verbose=0)
This function generates the 60 icosahedral symmetry group elements from the axes generated by generat...
void printResultsClearHTML(ProSHADE::ProSHADE_settings *settings)
This function prints the cleared results to the HTML file.
unsigned int symmetryFold
The required fold of the sought symmetry. Applicable to C and D symmetries, otherwise leave 0...
Definition: ProSHADE.h:162
std::string axisOrder
A string specifying the order of the axis. Must have three characters and any permutation of &#39;x&#39;...
Definition: ProSHADE.h:183
The main header file containing all declarations for the innter workings of the library.
std::vector< std::array< double, 5 > > getClearCyclicSymmetries(void)
Accessor function for the clear cyclic symmetries list.
Definition: ProSHADE.cpp:3063
std::vector< std::array< double, 5 > > getTetrahedralSymmetries(void)
Accessor function for the tetrahedral symmetries list.
Definition: ProSHADE.cpp:3226
This namespace contains all the external objects and their forward declarations.
int htmlReportLine
Iterator for current HTML line.
Definition: ProSHADE.h:187
bool inputStructureDataType
This variable tells whether input data type is PDB or not.
bool energyLevelDist
Should the energy level distances descriptor be computed.
Definition: ProSHADE.h:132
double xTranslation
The number of angstroms by which the structure should be translated along the X axis.
Definition: ProSHADE.h:171
int htmlReportLineProgress
Iterator for current HTML line in the progress bar.
Definition: ProSHADE.h:188
This header file contains function and globals required for platform-independent file detection...
double bFactorChange
This value will be used to change the B-factors if required by the user.
Definition: ProSHADE.h:89
std::vector< double > getRecommendedSymmetryElementsPy(void)
Accessor function for the list of symmetry element for python.
Definition: ProSHADE.cpp:3594
bool wasResolutionGiven
Variable stating whether the resolution value was given by the user, or decided automatically.
Definition: ProSHADE.h:79
ProSHADE_settings()
Contructor for the ProSHADE_settings class.
Definition: ProSHADE.cpp:69
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...
void printResultsRequestHTML(std::string symmetryType, unsigned int symmetryFold, ProSHADE::ProSHADE_settings *settings)
This function prints the cleared results to the HTML report file.
This is the class which computes the symmetry in a single structure.
std::vector< std::array< double, 5 > > getOctahedralSymmetries(void)
Accessor function for the octahedral symmetries list.
Definition: ProSHADE.cpp:3290
bool wasBChangeGiven
Variable stating whether the B factor change (sharpening/blurring) value was given by the user...
Definition: ProSHADE.h:90
double yTranslation
The number of angstroms by which the structure should be translated along the Y axis.
Definition: ProSHADE.h:172
std::vector< double > getSpecificSymmetryElementsPy(std::string symType, int symFold=0)
Accessor function for the list of symmetry element for python.
Definition: ProSHADE.cpp:3920
std::vector< std::array< double, 5 > > tetrAxes
This variable holds the 7 unique axes of the tetrahedral symmetry, if they are found.
This is the executive class for computing distances between two or more structures.
double mapFragBoxSize
Should the clear map be fragmented into boxes? If so, put box size here, otherwise leave 0...
Definition: ProSHADE.h:151
This class stores all the settings and is passed to the executive classes instead of multitude of par...
Definition: ProSHADE.h:74
double symGapTolerance
For C-symmetries - if there are many, only those with average peak height - parameter * top symmetry ...
Definition: ProSHADE.h:129
std::vector< std::array< double, 5 > > octaAxes
This variable holds the 13 unique axes of the octahedral symmetry, if they are found.
std::vector< double > getCyclicSymmetriesPy(void)
Accessor function for the cyclic symmetries list for python.
Definition: ProSHADE.cpp:3091
double mPower
This parameter determines the scaling for trace sigma descriptor.
Definition: ProSHADE.h:114
~ProSHADE(void)
Destructor for the ProSHADE class.
Definition: ProSHADE.cpp:2887
unsigned int manualShells
Should the user require so, the maximum number of radial shells can be set.
Definition: ProSHADE.h:98
std::vector< double > getCrossCorrDists(void)
Accessor function for the cross-correlation distances vector.
Definition: ProSHADE.cpp:2959
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
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
This file contains the ProSHADE_internal_misc namespace and its miscellaneous functions.
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
std::vector< std::vector< std::array< double, 6 > > > getDihedralSymmetries(void)
Accessor function for the dihedral symmetries list. These will be sorted using the fold and peak heig...
Definition: ProSHADE.cpp:3173
std::vector< std::vector< std::array< double, 6 > > > dnSymm
This variable holds the complete Dihedral symmetry results.
unsigned int glIntegOrder
This parameter controls the Gauss-Legendre integration order and so the radial resolution.
Definition: ProSHADE.h:82