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