ProSHADE  0.6.6 (DEC 2018)
Protein Shape Descriptors and Symmetry Detection
ProSHADE_clipper.cpp
Go to the documentation of this file.
1 
19 //============================================ Clipper
20 #include <clipper/clipper.h>
21 #include <clipper/clipper-contrib.h>
22 #include <clipper/clipper-ccp4.h>
23 #include <clipper/clipper-mmdb.h>
24 #include <clipper/clipper-minimol.h>
25 
26 //============================================ FFTW3 + SOFT
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 #include <fftw3.h>
31 #include <wrap_fftw.h>
32 #include <makeweights.h>
33 #include <s2_primitive.h>
34 #include <s2_cospmls.h>
35 #include <s2_legendreTransforms.h>
36 #include <s2_semi_fly.h>
37 #include <rotate_so3_utils.h>
38 #include <utils_so3.h>
39 #include <soft_fftw.h>
40 #include <rotate_so3_fftw.h>
41 #ifdef __cplusplus
42 }
43 #endif
44 
45 //============================================ CMAPLIB
46 #include <cmaplib.h>
47 
48 //============================================ RVAPI
49 #include <rvapi_interface.h>
50 
51 //============================================ ProSHADE
52 #include "ProSHADE.h"
53 #include "ProSHADE_internal.h"
54 #include "ProSHADE_misc.h"
55 
78  double *shellDistance,
79  double resolution,
80  unsigned int *bandwidth,
81  unsigned int *theta,
82  unsigned int *phi,
83  unsigned int *glIntegOrder,
84  double *extraSpace,
85  bool mapResDefault,
87  double Bfactor,
88  bool hpFirstLineCom,
89  bool overlayDefaults )
90 {
91  //======================================== Initialise internal values
92  this->_inputFileName = fileName;
93  this->_mapResolution = resolution;
94  this->_shellSpacing = *shellDistance;
95  this->_maxExtraCellularSpace = *extraSpace;
96  this->_firstLineCOM = hpFirstLineCom;
97 
98  //======================================== Read in file
99  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
100  if ( mfile->ReadCoorFile ( this->_inputFileName.c_str() ) )
101  {
102  std::cerr << "!!! ProSHADE ERROR !!! Cannot read file: " << this->_inputFileName.c_str() << std::endl;
103 
104  if ( settings->htmlReport )
105  {
106  std::stringstream hlpSS;
107  hlpSS << "<font color=\"red\">" << "Cannot open file: " << this->_inputFileName.c_str() << "</font>";
108  rvapi_set_text ( hlpSS.str().c_str(),
109  "ProgressSection",
110  settings->htmlReportLineProgress,
111  1,
112  1,
113  1 );
114  settings->htmlReportLineProgress += 1;
115  rvapi_flush ( );
116  }
117 
118  exit ( -1 );
119  }
120 
121  //======================================== Find axis ranges & change B-factors if required
122  double maxX = 0.0;
123  double minX = 0.0;
124  double maxY = 0.0;
125  double minY = 0.0;
126  double maxZ = 0.0;
127  double minZ = 0.0;
128  bool firstAtom = true;
129 
130  double xVal, yVal, zVal;
131 
132  //======================================== Initialise MMDB crawl
133  int noChains = 0;
134  int noResidues = 0;
135  int noAtoms = 0;
136 
137  clipper::mmdb::PPCChain chain;
138  clipper::mmdb::PPCResidue residue;
139  clipper::mmdb::PPCAtom atom;
140 
141  double pdbXCom = 0.0;
142  double pdbYCom = 0.0;
143  double pdbZCom = 0.0;
144  double bFacTot = 0.0;
145 
146  //======================================== Get all chains
147  mfile->GetChainTable ( 1, chain, noChains );
148  firstAtom = true;
149  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
150  {
151  if ( chain[nCh] )
152  {
153  //================================ Get all residues
154  chain[nCh]->GetResidueTable ( residue, noResidues );
155 
156  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
157  {
158  if ( residue[nRes] )
159  {
160  //======================== Get all atoms
161  residue[nRes]->GetAtomTable ( atom, noAtoms );
162 
163  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
164  {
165  if ( atom[aNo] )
166  {
167  //================ Check for termination 'residue'
168  if ( atom[aNo]->Ter ) { continue; }
169 
170  //================ Find axis maxs and mins
171  if ( firstAtom )
172  {
173  maxX = atom[aNo]->x;
174  minX = atom[aNo]->x;
175  maxY = atom[aNo]->y;
176  minY = atom[aNo]->y;
177  maxZ = atom[aNo]->z;
178  minZ = atom[aNo]->z;
179 
180  pdbXCom += atom[aNo]->x;
181  pdbYCom += atom[aNo]->y;
182  pdbZCom += atom[aNo]->z;
183  if ( Bfactor != 0.0 )
184  {
185  bFacTot += 1.0;
186  }
187  else
188  {
189  bFacTot += atom[aNo]->tempFactor;
190  }
191 
192 
193  firstAtom = false;
194  }
195  else
196  {
197  xVal = atom[aNo]->x;
198  yVal = atom[aNo]->y;
199  zVal = atom[aNo]->z;
200  if ( xVal > maxX ) { maxX = xVal; } if ( xVal < minX ) { minX = xVal; }
201  if ( yVal > maxY ) { maxY = yVal; } if ( yVal < minY ) { minY = yVal; }
202  if ( zVal > maxZ ) { maxZ = zVal; } if ( zVal < minZ ) { minZ = zVal; }
203 
204  if ( Bfactor != 0.0 )
205  {
206  bFacTot += 1.0;
207  pdbXCom += atom[aNo]->x;
208  pdbYCom += atom[aNo]->y;
209  pdbZCom += atom[aNo]->z;
210  }
211  else
212  {
213  bFacTot += atom[aNo]->tempFactor;
214  pdbXCom += atom[aNo]->x * atom[aNo]->tempFactor;
215  pdbYCom += atom[aNo]->y * atom[aNo]->tempFactor;
216  pdbZCom += atom[aNo]->z * atom[aNo]->tempFactor;
217  }
218  }
219  }
220  }
221  }
222  }
223  }
224  }
225 
226  //======================================== Determine original PDB COM
227  pdbXCom /= bFacTot;
228  pdbYCom /= bFacTot;
229  pdbZCom /= bFacTot;
230 
231  //======================================== Determine max dimensions
232  this->_xRange = (maxX - minX);
233  this->_yRange = (maxY - minY);
234  this->_zRange = (maxZ - minZ);
235  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
236 
237  //======================================== Save extracellular space and use internal value to avoid issues with clipper map computation
238  this->_maxExtraCellularSpace = *extraSpace;
239  double ecsHlp = std::floor ( std::max ( 20.0, ( this->_maxMapRange / 4.0 ) ) );
240 
241  //======================================== Determine max dimensions
242  this->_xRange = (maxX - minX) + ecsHlp;
243  this->_yRange = (maxY - minY) + ecsHlp;
244  this->_zRange = (maxZ - minZ) + ecsHlp;
245  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
246 
247  //======================================== Move structure to middle of map
248  double xMov = (ecsHlp/2.0) - minX;
249  double yMov = (ecsHlp/2.0) - minY;
250  double zMov = (ecsHlp/2.0) - minZ;
251 
252  //======================================== Move structure to the center of map
253  mfile->GetChainTable ( 1, chain, noChains );
254  firstAtom = true;
255  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
256  {
257  if ( chain[nCh] )
258  {
259  //================================ Get all residues
260  chain[nCh]->GetResidueTable ( residue, noResidues );
261 
262  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
263  {
264  if ( residue[nRes] )
265  {
266  //======================== Get all atoms
267  residue[nRes]->GetAtomTable ( atom, noAtoms );
268 
269  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
270  {
271  if ( atom[aNo] )
272  {
273  //================ Check for termination 'residue'
274  if ( atom[aNo]->Ter ) { continue; }
275 
276  if ( Bfactor != 0.0 )
277  {
278  atom[aNo]->SetCoordinates ( atom[aNo]->x + xMov,
279  atom[aNo]->y + yMov,
280  atom[aNo]->z + zMov,
281  atom[aNo]->occupancy,
282  Bfactor );
283  }
284  else
285  {
286  atom[aNo]->SetCoordinates ( atom[aNo]->x + xMov,
287  atom[aNo]->y + yMov,
288  atom[aNo]->z + zMov,
289  atom[aNo]->occupancy,
290  atom[aNo]->tempFactor );
291  }
292  }
293 
294  if ( firstAtom )
295  {
296  this->_xCorrErr = atom[aNo]->x;
297  this->_yCorrErr = atom[aNo]->y;
298  this->_zCorrErr = atom[aNo]->z;
299  firstAtom = false;
300  }
301  }
302  }
303  }
304  }
305  }
306 
307  //======================================== Initialise map variables
308  clipper::Spacegroup spgr ( clipper::Spacegroup::P1 );
309  clipper::Cell cell ( clipper::Cell_descr ( this->_xRange, this->_yRange, this->_zRange ) );
310  clipper::Resolution reso;
311 
312  if ( settings->taskToPerform == ProSHADE::OverlayMap )
313  {
314  reso = clipper::Resolution ( std::min ( std::max ( this->_mapResolution / 3.0, 2.0 ), this->_mapResolution ) );
315  }
316  else
317  {
318  reso = clipper::Resolution ( this->_mapResolution );
319  }
320 
321 
322  const clipper::Grid_sampling grid ( spgr, cell, reso );
323  clipper::Xmap<float> *densityMap = new clipper::Xmap<float> ( spgr, cell, grid );
324 
325  //======================================== Get Map
326  int hndl = mfile->NewSelection ( );
327  mfile->SelectAtoms ( hndl, 0, 0, ::mmdb::SKEY_NEW );
328  mfile->GetSelIndex ( hndl, atom, noAtoms );
329  clipper::MMDBAtom_list *aList = new clipper::MMDBAtom_list ( atom, noAtoms );
330  clipper::EDcalc_aniso<clipper::ftype32> edCalc;
331  edCalc ( *densityMap, *aList );
332 
333  //======================================== Free memory
334  delete mfile;
335 
336  //======================================== Find max U, V and W
337  clipper::Xmap_base::Map_reference_index LastPos = (*densityMap).first();
338  clipper::Xmap_base::Map_reference_index PrevPos = (*densityMap).first();
339  for ( LastPos = (*densityMap).first(); !LastPos.last(); LastPos.next() ) { PrevPos = LastPos; }
340  this->_maxMapU = PrevPos.coord().u();
341  this->_maxMapV = PrevPos.coord().v();
342  this->_maxMapW = PrevPos.coord().w();
343 
344  this->_preCBSU = this->_maxMapU;
345  this->_preCBSV = this->_maxMapV;
346  this->_preCBSW = this->_maxMapW;
347 
348  //======================================== Convert clipper Xmap to my map format
349  // ... Allocate map data memory
350  this->_densityMapMap = (float*) malloc ( ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ) * sizeof ( float ) );
351  if ( this->_densityMapMap == nullptr )
352  {
353  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
354 
355  if ( settings->htmlReport )
356  {
357  std::stringstream hlpSS;
358  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
359  rvapi_set_text ( hlpSS.str().c_str(),
360  "ProgressSection",
361  settings->htmlReportLineProgress,
362  1,
363  1,
364  1 );
365  settings->htmlReportLineProgress += 1;
366  rvapi_flush ( );
367  }
368 
369  exit ( -1 );
370  }
371 
372  // ... and copy
373  int arrPos = 0;
374  for ( unsigned int uIt = 0; uIt < (this->_maxMapU+1); uIt++ )
375  {
376  for ( unsigned int vIt = 0; vIt < (this->_maxMapV+1); vIt++ )
377  {
378  for ( unsigned int wIt = 0; wIt < (this->_maxMapW+1); wIt++ )
379  {
380  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
381 
382  clipper::Vec3<int> pos ( uIt, vIt, wIt );
383  clipper::Coord_grid cg ( pos );
384 
385  this->_densityMapMap[arrPos] = densityMap->get_data ( cg );
386  }
387  }
388  }
389 
390  //======================================== Free memory
391  if ( densityMap != nullptr )
392  {
393  delete densityMap;
394  densityMap = nullptr;
395  }
396 
397  //======================================== Set internal map parameters
398  this->_xFrom = 0;
399  this->_yFrom = 0;
400  this->_zFrom = 0;
401 
402  this->_xTo = this->_maxMapU;
403  this->_yTo = this->_maxMapV;
404  this->_zTo = this->_maxMapW;
405 
406  //======================================== Remove the extra space added for the map calculation
407  // ... Find new settings
408  maxX = -1.0;
409  maxY = -1.0;
410  maxZ = -1.0;
411 
412  minX = this->_maxMapU;
413  minY = this->_maxMapV;
414  minZ = this->_maxMapW;
415  for ( unsigned int uIt = 0; uIt < (this->_maxMapU+1); uIt++ )
416  {
417  for ( unsigned int vIt = 0; vIt < (this->_maxMapV+1); vIt++ )
418  {
419  for ( unsigned int wIt = 0; wIt < (this->_maxMapW+1); wIt++ )
420  {
421  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
422  if ( this->_densityMapMap[arrPos] > 0.005 )
423  {
424  if ( maxX < uIt ) { maxX = uIt; } if ( minX > uIt ) { minX = uIt; }
425  if ( maxY < vIt ) { maxY = vIt; } if ( minY > vIt ) { minY = vIt; }
426  if ( maxZ < wIt ) { maxZ = wIt; } if ( minZ > wIt ) { minZ = wIt; }
427  }
428  }
429  }
430  }
431 
432  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
433  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
434  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
435 
436  this->_xRange = this->_xRange - ( this->_maxMapU - ( maxX - minX ) ) * this->_xSamplingRate;
437  this->_yRange = this->_yRange - ( this->_maxMapV - ( maxY - minY ) ) * this->_ySamplingRate;
438  this->_zRange = this->_zRange - ( this->_maxMapW - ( maxZ - minZ ) ) * this->_zSamplingRate;
439  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
440 
441  // ... Create new map and fill it with data
442  float *hlpMap = nullptr;
443  hlpMap = (float*) malloc ( static_cast<int>( (maxX - minX + 1) * (maxY - minY + 1) * (maxZ - minZ + 1) ) * sizeof ( float ) );
444  if ( hlpMap == nullptr )
445  {
446  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
447 
448  if ( settings->htmlReport )
449  {
450  std::stringstream hlpSS;
451  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
452  rvapi_set_text ( hlpSS.str().c_str(),
453  "ProgressSection",
454  settings->htmlReportLineProgress,
455  1,
456  1,
457  1 );
458  settings->htmlReportLineProgress += 1;
459  rvapi_flush ( );
460  }
461 
462  exit ( -1 );
463  }
464 
465  unsigned int newU, newV, newW, hlpPos;
466  for ( int uIt = 0; uIt < static_cast<int> (maxX - minX + 1); uIt++ )
467  {
468  for ( int vIt = 0; vIt < static_cast<int> (maxY - minY + 1); vIt++ )
469  {
470  for ( int wIt = 0; wIt < static_cast<int> (maxZ - minZ + 1); wIt++ )
471  {
472  newU = (uIt + minX);
473  newV = (vIt + minY);
474  newW = (wIt + minZ);
475 
476  hlpPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
477  arrPos = wIt + (maxZ - minZ + 1) * ( vIt + (maxY - minY + 1) * uIt );
478 
479  hlpMap[arrPos] = this->_densityMapMap[hlpPos];
480  }
481  }
482  }
483 
484  this->_maxMapU = maxX - minX;
485  this->_maxMapV = maxY - minY;
486  this->_maxMapW = maxZ - minZ;
487 
488  this->_xTo = maxX - minX;
489  this->_yTo = maxY - minY;
490  this->_zTo = maxZ - minZ;
491 
492  // ... Copy
493  if ( this->_densityMapMap != nullptr )
494  {
495  free ( this->_densityMapMap );
496  this->_densityMapMap = nullptr;
497  }
498 
499  this->_densityMapMap = (float*) malloc ( ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ) * sizeof ( float ) );
500  if ( this->_densityMapMap == nullptr )
501  {
502  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
503 
504  if ( settings->htmlReport )
505  {
506  std::stringstream hlpSS;
507  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
508  rvapi_set_text ( hlpSS.str().c_str(),
509  "ProgressSection",
510  settings->htmlReportLineProgress,
511  1,
512  1,
513  1 );
514  settings->htmlReportLineProgress += 1;
515  rvapi_flush ( );
516  }
517 
518  exit ( -1 );
519  }
520 
521  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
522  {
523  this->_densityMapMap[iter] = hlpMap[iter];
524  }
525 
526  if ( hlpMap != nullptr )
527  {
528  free ( hlpMap );
529  hlpMap = nullptr;
530  }
531 
532  if ( this->_maxExtraCellularSpace == -777.7 )
533  {
534  this->_maxExtraCellularSpace = std::max ( 20.0, ( std::max( this->_xRange, std::max ( this->_yRange, this->_zRange ) ) - std::min( this->_xRange, std::min ( this->_yRange, this->_zRange ) ) ) );
535  *extraSpace = this->_maxExtraCellularSpace;
536  }
537 
538  if ( this->_maxExtraCellularSpace != 0.0 )
539  {
540  //==================================== Compute new stats
541  int xDiff = static_cast<int> ( std::ceil ( ( this->_xRange + this->_maxExtraCellularSpace ) / this->_xSamplingRate ) - this->_maxMapU );
542  int yDiff = static_cast<int> ( std::ceil ( ( this->_yRange + this->_maxExtraCellularSpace ) / this->_ySamplingRate ) - this->_maxMapV );
543  int zDiff = static_cast<int> ( std::ceil ( ( this->_zRange + this->_maxExtraCellularSpace ) / this->_zSamplingRate ) - this->_maxMapW );
544 
545  this->_xRange += xDiff * this->_xSamplingRate;
546  this->_yRange += yDiff * this->_ySamplingRate;
547  this->_zRange += zDiff * this->_zSamplingRate;
548 
549  if ( xDiff % 2 != 0 )
550  {
551  this->_xRange += this->_xSamplingRate;
552  xDiff = static_cast<int> ( std::ceil ( this->_xRange / this->_xSamplingRate ) - ( this->_maxMapU + 1 ) );
553  }
554  if ( yDiff % 2 != 0 )
555  {
556  this->_yRange += this->_ySamplingRate;
557  yDiff = static_cast<int> ( std::ceil ( this->_yRange / this->_ySamplingRate ) - ( this->_maxMapV + 1 ) );
558  }
559  if ( zDiff % 2 != 0 )
560  {
561  this->_zRange += this->_zSamplingRate;
562  zDiff = static_cast<int> ( std::ceil ( this->_zRange / this->_zSamplingRate ) - ( this->_maxMapW + 1 ) );
563  }
564  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
565 
566  xDiff /= 2;
567  yDiff /= 2;
568  zDiff /= 2;
569 
570  this->_exCeSpDiffX = xDiff;
571  this->_exCeSpDiffY = yDiff;
572  this->_exCeSpDiffZ = zDiff;
573 
574  this->_xFrom -= xDiff;
575  this->_yFrom -= yDiff;
576  this->_zFrom -= zDiff;
577 
578  this->_xTo += xDiff;
579  this->_yTo += yDiff;
580  this->_zTo += zDiff;
581 
582  this->_maxMapU = this->_xTo - this->_xFrom;
583  this->_maxMapV = this->_yTo - this->_yFrom;
584  this->_maxMapW = this->_zTo - this->_zFrom;
585 
586  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
587  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
588  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
589 
590  //==================================== Move the map
591  hlpMap = nullptr;
592  hlpMap = (float*) malloc ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) * sizeof ( float ) );
593  if ( hlpMap == nullptr )
594  {
595  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map moving data. Terminating... " << std::endl;
596 
597  if ( settings->htmlReport )
598  {
599  std::stringstream hlpSS;
600  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for moving the map data. Did you run out of memory?" << "</font>";
601  rvapi_set_text ( hlpSS.str().c_str(),
602  "ProgressSection",
603  settings->htmlReportLineProgress,
604  1,
605  1,
606  1 );
607  settings->htmlReportLineProgress += 1;
608  rvapi_flush ( );
609  }
610 
611  exit ( -1 );
612  }
613  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
614  {
615  hlpMap[iter] = 0.0;
616  }
617 
618  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
619  {
620  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
621  {
622  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
623  {
624  if ( ( uIt < xDiff ) || ( uIt > static_cast<int> ( this->_maxMapU - xDiff ) ) ||
625  ( vIt < yDiff ) || ( vIt > static_cast<int> ( this->_maxMapV - yDiff ) ) ||
626  ( wIt < zDiff ) || ( wIt > static_cast<int> ( this->_maxMapW - zDiff ) ) )
627  {
628  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
629  hlpMap[hlpPos] = 0.0;
630  }
631  else
632  {
633  newU = (uIt - xDiff);
634  newV = (vIt - yDiff);
635  newW = (wIt - zDiff);
636 
637  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
638  arrPos = newW + (this->_maxMapW + 1 - zDiff * 2) * ( newV + (this->_maxMapV + 1 - yDiff * 2) * newU );
639 
640  hlpMap[hlpPos] = this->_densityMapMap[arrPos];
641  }
642  }
643  }
644  }
645 
646  //==================================== Free memory
647  if ( this->_densityMapMap != nullptr )
648  {
649  free ( this->_densityMapMap );
650  this->_densityMapMap = nullptr;
651  }
652 
653  //==================================== Copy
654  this->_densityMapMap = (float*) malloc ( ((this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1)) * sizeof ( float ) );
655  if ( this->_densityMapMap == nullptr )
656  {
657  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
658 
659  if ( settings->htmlReport )
660  {
661  std::stringstream hlpSS;
662  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
663  rvapi_set_text ( hlpSS.str().c_str(),
664  "ProgressSection",
665  settings->htmlReportLineProgress,
666  1,
667  1,
668  1 );
669  settings->htmlReportLineProgress += 1;
670  rvapi_flush ( );
671  }
672 
673  exit ( -1 );
674  }
675  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
676  {
677  this->_densityMapMap[iter] = hlpMap[iter];
678  }
679 
680  //==================================== Free memory
681  if ( hlpMap != nullptr )
682  {
683  free ( hlpMap );
684  hlpMap = nullptr;
685  }
686  }
687  else
688  {
689  this->_exCeSpDiffX = 0;
690  this->_exCeSpDiffY = 0;
691  this->_exCeSpDiffZ = 0;
692  }
693 
694  //======================================== Determine sampling ranges
695  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
696  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
697  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
698 
699  //======================================== Make sure map matches original PDB in visualisation
700  double mapXCom = 0.0;
701  double mapYCom = 0.0;
702  double mapZCom = 0.0;
703  double densTot = 0.0;
704  for ( unsigned int uIt = 0; uIt < static_cast<unsigned int> ( (this->_maxMapU+1) ); uIt++ )
705  {
706  for ( unsigned int vIt = 0; vIt < static_cast<unsigned int> ( (this->_maxMapV+1) ); vIt++ )
707  {
708  for ( unsigned int wIt = 0; wIt < static_cast<unsigned int> ( (this->_maxMapW+1) ); wIt++ )
709  {
710  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
711 
712  mapXCom += uIt * this->_densityMapMap[arrPos];
713  mapYCom += vIt * this->_densityMapMap[arrPos];
714  mapZCom += wIt * this->_densityMapMap[arrPos];
715  densTot += this->_densityMapMap[arrPos];
716  }
717  }
718  }
719 
720  mapXCom /= densTot;
721  mapYCom /= densTot;
722  mapZCom /= densTot;
723 
724  mapXCom = ( mapXCom + this->_xFrom ) * this->_xSamplingRate;
725  mapYCom = ( mapYCom + this->_yFrom ) * this->_ySamplingRate;
726  mapZCom = ( mapZCom + this->_zFrom ) * this->_zSamplingRate;
727 
728  double mapXMove = ( pdbXCom - mapXCom ) / this->_xSamplingRate;
729  double mapYMove = ( pdbYCom - mapYCom ) / this->_ySamplingRate;
730  double mapZMove = ( pdbZCom - mapZCom ) / this->_zSamplingRate;
731 
732  this->_xFrom += std::round ( mapXMove );
733  this->_xTo += std::round ( mapXMove );
734  this->_yFrom += std::round ( mapYMove );
735  this->_yTo += std::round ( mapYMove );
736  this->_zFrom += std::round ( mapZMove );
737  this->_zTo += std::round ( mapZMove );
738 
739  //======================================== Check lims
740  bool xFSignChange = false;
741  if ( ( ( ( this->_xFrom - std::round ( mapXMove ) ) < 0 ) && ( this->_xFrom > 0 ) ) ||
742  ( ( ( this->_xFrom - std::round ( mapXMove ) ) > 0 ) && ( this->_xFrom < 0 ) ) ) { xFSignChange = true; }
743  bool xTSignChange = false;
744  if ( ( ( ( this->_xTo - std::round ( mapXMove ) ) < 0 ) && ( this->_xTo > 0 ) ) ||
745  ( ( ( this->_xTo - std::round ( mapXMove ) ) > 0 ) && ( this->_xTo < 0 ) ) ) { xTSignChange = true; }
746 
747  bool yFSignChange = false;
748  if ( ( ( ( this->_yFrom - std::round ( mapYMove ) ) < 0 ) && ( this->_yFrom > 0 ) ) ||
749  ( ( ( this->_yFrom - std::round ( mapYMove ) ) > 0 ) && ( this->_yFrom < 0 ) ) ) { yFSignChange = true; }
750  bool yTSignChange = false;
751  if ( ( ( ( this->_yTo - std::round ( mapYMove ) ) < 0 ) && ( this->_yTo > 0 ) ) ||
752  ( ( ( this->_yTo - std::round ( mapYMove ) ) > 0 ) && ( this->_yTo < 0 ) ) ) { yTSignChange = true; }
753 
754  bool zFSignChange = false;
755  if ( ( ( ( this->_zFrom - std::round ( mapZMove ) ) < 0 ) && ( this->_zFrom > 0 ) ) ||
756  ( ( ( this->_zFrom - std::round ( mapZMove ) ) > 0 ) && ( this->_zFrom < 0 ) ) ) { zFSignChange = true; }
757  bool zTSignChange = false;
758  if ( ( ( ( this->_zTo - std::round ( mapZMove ) ) < 0 ) && ( this->_zTo > 0 ) ) ||
759  ( ( ( this->_zTo - std::round ( mapZMove ) ) > 0 ) && ( this->_zTo < 0 ) ) ) { zTSignChange = true; }
760 
761  if ( ( xFSignChange && !xTSignChange ) || ( !xFSignChange && xTSignChange ) )
762  {
763  this->_xTo += 1;
764  }
765  if ( ( yFSignChange && !yTSignChange ) || ( !yFSignChange && yTSignChange ) )
766  {
767  this->_yTo += 1;
768  }
769  if ( ( zFSignChange && !zTSignChange ) || ( !zFSignChange && zTSignChange ) )
770  {
771  this->_zTo += 1;
772  }
773 
774  //======================================== If bandwidth is not given, determine it
775  if ( *bandwidth == 0 )
776  {
777  *bandwidth = std::ceil ( this->_maxMapRange / 4.0 );
778  }
779 
780  if ( settings->maxRotError != 0 )
781  {
782  *bandwidth = static_cast<unsigned int> ( 180 / settings->maxRotError );
783  this->_wasBandwithGiven = true;
784  }
785 
786  //======================================== Decide shell spacing, if not already decided
787  if ( *shellDistance == 0 )
788  {
789  settings->shellSpacing = static_cast<double> ( this->_maxMapRange / 2.0 ) / std::floor ( static_cast<double> ( this->_maxMapRange / 2.0 ) / static_cast<double> ( this->_mapResolution / 2.0 ) );
790  this->_shellSpacing = settings->shellSpacing;
791  *shellDistance = this->_shellSpacing;
792 
793  while ( std::floor ( this->_maxMapRange / this->_shellSpacing ) < 20 )
794  {
795  this->_shellSpacing /= 2.0;
796  settings->shellSpacing /= 2.0;
797  *shellDistance /= 2.0;
798  }
799 
800  }
801 
802  //======================================== Automatically determine maximum number of shells
803  this->_shellPlacement = std::vector<double> ( std::floor ( this->_maxMapRange / this->_shellSpacing ) );
804 
805  for ( unsigned int shellIter = 0; shellIter < static_cast<unsigned int> ( this->_shellPlacement.size() ); shellIter++ )
806  {
807  this->_shellPlacement.at(shellIter) = (shellIter+1) * this->_shellSpacing;
808  }
809 
810  //======================================== If theta and phi are not given, determine them
811  if ( *theta == 0 ) { *theta = 2 * (*bandwidth); }
812  if ( *phi == 0 ) { *phi = 2 * (*bandwidth); }
813 
814  //======================================== If Gauss-Legendre integration order is not given, decide it
815  if ( *glIntegOrder == 0 )
816  {
817  double distPerPointFraction = static_cast<double> ( this->_shellSpacing ) / ( this->_maxMapRange / 2.0 );
818 
819  for ( unsigned int iter = 2; iter < static_cast<unsigned int> ( ProSHADE_internal_misc::glIntMaxDists.size() ); iter++ )
820  {
821  if ( ProSHADE_internal_misc::glIntMaxDists.at(iter) >= distPerPointFraction )
822  {
823  *glIntegOrder = iter;
824  }
825  }
826  }
827 
828  //======================================== Done
829  this->_densityMapComputed = true;
830  this->_fromPDB = true;
831 
832 }
833 
854  double *shellDistance,
855  double resolution,
856  unsigned int *bandwidth,
857  unsigned int *theta,
858  unsigned int *phi,
859  unsigned int *glIntegOrder,
860  double *extraSpace,
861  bool mapResDefault,
862  bool rotDefaults,
863  ProSHADE::ProSHADE_settings* settings,
864  bool overlayDefaults )
865 {
866  //======================================== Initialise internal values
867  this->_inputFileName = fileName;
868  this->_shellSpacing = *shellDistance;
869  this->_mapResolution = resolution;
870  this->_maxExtraCellularSpace = *extraSpace;
871  this->_firstLineCOM = false;
872 
873  if ( *extraSpace == -777.7 )
874  {
875  this->_maxExtraCellularSpace = std::max ( 20.0, ( std::max( this->_xRange, std::max ( this->_yRange, this->_zRange ) ) - std::min( this->_xRange, std::min ( this->_yRange, this->_zRange ) ) ) );
876  *extraSpace = this->_maxExtraCellularSpace;
877  }
878 
879  //======================================== Initialise local variables
880  CMap_io::CMMFile *mapFile = nullptr;
881  float *cell = nullptr;
882  int *dim = nullptr;
883  int *grid = nullptr;
884  int *order = nullptr;
885  int *orig = nullptr;
886  int myMapMode = 0;
887  double cornerAvg = 0.0;
888  double centralAvg = 0.0;
889  double cornerCount = 0.0;
890  double centralCount = 0.0;
891 
892  //======================================== Allocate memory
893  cell = (float*) malloc ( 6 * sizeof ( float ) );
894  dim = (int* ) malloc ( 3 * sizeof ( int ) );
895  grid = (int* ) malloc ( 3 * sizeof ( int ) );
896  order = (int* ) malloc ( 3 * sizeof ( int ) );
897  orig = (int* ) malloc ( 3 * sizeof ( int ) );
898 
899  if ( ( cell == nullptr ) || ( dim == nullptr ) || ( order == nullptr ) || ( orig == nullptr ) || ( grid == nullptr ) )
900  {
901  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory. Terminating... " << std::endl;
902 
903  if ( settings->htmlReport )
904  {
905  std::stringstream hlpSS;
906  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
907  rvapi_set_text ( hlpSS.str().c_str(),
908  "ProgressSection",
909  settings->htmlReportLineProgress,
910  1,
911  1,
912  1 );
913  settings->htmlReportLineProgress += 1;
914  rvapi_flush ( );
915  }
916 
917  exit ( -1 );
918  }
919 
920  //======================================== Read in the MAP file info
921  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
922  if ( mapFile == nullptr )
923  {
924  std::cerr << "!!! ProSHADE ERROR !!! Failed to open the file " << fileName << ". Check for typos and corruption of the file. Terminating..." << std::endl;
925 
926  if ( settings->htmlReport )
927  {
928  std::stringstream hlpSS;
929  hlpSS << "<font color=\"red\">" << "Cannot open the file " << fileName << " . Could it be corrupted?" << "</font>";
930  rvapi_set_text ( hlpSS.str().c_str(),
931  "ProgressSection",
932  settings->htmlReportLineProgress,
933  1,
934  1,
935  1 );
936  settings->htmlReportLineProgress += 1;
937  rvapi_flush ( );
938  }
939 
940  exit ( -1 );
941  }
942 
943  CMap_io::ccp4_cmap_get_cell ( mapFile, cell );
944  CMap_io::ccp4_cmap_get_dim ( mapFile, dim );
945  CMap_io::ccp4_cmap_get_grid ( mapFile, grid );
946  CMap_io::ccp4_cmap_get_order ( mapFile, order );
947  CMap_io::ccp4_cmap_get_origin ( mapFile, orig );
948 
949  //======================================== If CUBIC
950  if ( ( ( cell[3] < (90.0 + 0.1) ) && ( cell[3] > (90.0 - 0.1) ) ) &&
951  ( ( cell[4] < (90.0 + 0.1) ) && ( cell[4] > (90.0 - 0.1) ) ) &&
952  ( ( cell[5] < (90.0 + 0.1) ) && ( cell[5] > (90.0 - 0.1) ) ) )
953  {
954  //==================================== Determine/Save dimmensions
955  this->_xRange = cell[0];
956  this->_yRange = cell[1];
957  this->_zRange = cell[2];
958 
959  //==================================== Maximal cell dimensions
960  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
961 
962  //==================================== Save extracellular space
963  this->_maxExtraCellularSpace = *extraSpace;
964 
965  //==================================== Find max U, V and W
966  if ( order[0] == 1 ) { this->_maxMapU = dim[0] - 1; this->_xFrom = orig[0]; }
967  if ( order[0] == 2 ) { this->_maxMapU = dim[1] - 1; this->_yFrom = orig[0]; }
968  if ( order[0] == 3 ) { this->_maxMapU = dim[2] - 1; this->_zFrom = orig[0]; }
969 
970  if ( order[1] == 1 ) { this->_maxMapV = dim[0] - 1; this->_xFrom = orig[1]; }
971  if ( order[1] == 2 ) { this->_maxMapV = dim[1] - 1; this->_yFrom = orig[1]; }
972  if ( order[1] == 3 ) { this->_maxMapV = dim[2] - 1; this->_zFrom = orig[1]; }
973 
974  if ( order[2] == 1 ) { this->_maxMapW = dim[0] - 1; this->_xFrom = orig[2]; }
975  if ( order[2] == 2 ) { this->_maxMapW = dim[1] - 1; this->_yFrom = orig[2]; }
976  if ( order[2] == 3 ) { this->_maxMapW = dim[2] - 1; this->_zFrom = orig[2]; }
977 
978 
979  this->_preCBSU = this->_maxMapU;
980  this->_preCBSV = this->_maxMapV;
981  this->_preCBSW = this->_maxMapW;
982 
983  //==================================== Get the map start and end
984  this->_xTo = this->_xFrom + this->_maxMapU;
985  this->_yTo = this->_yFrom + this->_maxMapV;
986  this->_zTo = this->_zFrom + this->_maxMapW;
987 
988  //==================================== Allocate map data memory
989  this->_densityMapMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
990  if ( this->_densityMapMap == nullptr )
991  {
992  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
993 
994  if ( settings->htmlReport )
995  {
996  std::stringstream hlpSS;
997  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
998  rvapi_set_text ( hlpSS.str().c_str(),
999  "ProgressSection",
1000  settings->htmlReportLineProgress,
1001  1,
1002  1,
1003  1 );
1004  settings->htmlReportLineProgress += 1;
1005  rvapi_flush ( );
1006  }
1007 
1008  exit ( -1 );
1009  }
1010 
1011  //==================================== Check if the mode is compatible
1012  int mapMode = CMap_io::ccp4_cmap_get_datamode ( mapFile );
1013  if ( ( mapMode != 0 ) && ( mapMode != 2 ) )
1014  {
1015  std::cerr << "!!! ProSHADE ERROR !!! Cannot read from the map file. The map file mode is not supported. Terminating..." << std::endl;
1016 
1017  if ( settings->htmlReport )
1018  {
1019  std::stringstream hlpSS;
1020  hlpSS << "<font color=\"red\">" << "Cannot read from the map file. The map mode is neither 0, nor 2; other modes are not supperted at the moment." << "</font>";
1021  rvapi_set_text ( hlpSS.str().c_str(),
1022  "ProgressSection",
1023  settings->htmlReportLineProgress,
1024  1,
1025  1,
1026  1 );
1027  settings->htmlReportLineProgress += 1;
1028  rvapi_flush ( );
1029  }
1030 
1031  exit ( -1 );
1032  }
1033 
1034  //==================================== Read in map data
1035  // ... Find the stop positions (start is in orig variables) and the axis order
1036  int maxLim[3];
1037  int XYZOrder[3];
1038  int newU, newV, newW;
1039  int arrPos;
1040 
1041  for ( int iter = 0; iter < 3; iter++ )
1042  {
1043  maxLim[iter] = orig[iter] + dim[iter] - 1;
1044  XYZOrder[order[iter]-1] = iter;
1045  }
1046 
1047  // ... Solve the dimensions and sizes
1048  int fastDimSize = ( maxLim[0] - orig[0] + 1 );
1049  int midDimSize = ( maxLim[1] - orig[1] + 1 ) * fastDimSize;
1050  std::vector<float> section( midDimSize );
1051  int index;
1052  int iters[3];
1053 
1054  // ... Read in the map data
1055  for ( iters[2] = orig[2]; iters[2] <= maxLim[2]; iters[2]++ )
1056  {
1057  index = 0;
1058  CMap_io::ccp4_cmap_read_section( mapFile, &section[0] );
1059 
1060  if ( mapMode == 0 )
1061  {
1062  for ( int iter = ( midDimSize - 1 ); iter >= 0; iter-- )
1063  {
1064  section[iter] = static_cast<float> ( ( reinterpret_cast<unsigned char*> (&section[0]) )[iter] );
1065  }
1066  }
1067 
1068  for ( iters[1] = orig[1]; iters[1] <= maxLim[1]; iters[1]++ )
1069  {
1070  for ( iters[0] = orig[0]; iters[0] <= maxLim[0]; iters[0]++ )
1071  {
1072  newU = iters[XYZOrder[0]] - orig[XYZOrder[0]];
1073  newV = iters[XYZOrder[1]] - orig[XYZOrder[1]];
1074  newW = iters[XYZOrder[2]] - orig[XYZOrder[2]];
1075  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
1076  this->_densityMapMap[arrPos] = static_cast<float> ( section[ index++ ] );
1077  }
1078  }
1079  }
1080 
1081  //==================================== Get values for normalisation
1082  std::vector<double> vals ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) );
1083  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( dim[0] * dim[1] * dim[2] ); iter++ )
1084  {
1085  vals.at(iter) = this->_densityMapMap[iter];
1086  }
1087  std::sort ( vals.begin(), vals.end() );
1088 
1089  //==================================== Find mean and standard deviation for later normalisation
1090  this->_mapMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
1091  this->_mapSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - this->_mapMean * this->_mapMean );
1092 
1093  //==================================== Check if the map is not absolutely de-centered
1094  int noPToCheckU = static_cast<unsigned int> ( this->_maxMapU / 8.0 );
1095  int noPToCheckV = static_cast<unsigned int> ( this->_maxMapV / 8.0 );
1096  int noPToCheckW = static_cast<unsigned int> ( this->_maxMapW / 8.0 );
1097 
1098  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
1099  {
1100  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
1101  {
1102  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
1103  {
1104  //======================== Initialisation
1105  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
1106 
1107  //======================== Check to which quadrant the value belongs to
1108  if ( ( ( uIt <= static_cast<int> ( this->_maxMapU/2 + noPToCheckU ) ) && ( uIt >= static_cast<int> ( this->_maxMapU/2 - noPToCheckU ) ) ) &&
1109  ( ( vIt <= static_cast<int> ( this->_maxMapV/2 + noPToCheckV ) ) && ( vIt >= static_cast<int> ( this->_maxMapV/2 - noPToCheckV ) ) ) &&
1110  ( ( wIt <= static_cast<int> ( this->_maxMapW/2 + noPToCheckW ) ) && ( wIt >= static_cast<int> ( this->_maxMapW/2 - noPToCheckW ) ) ) )
1111  {
1112  centralAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
1113  centralCount += 1.0;
1114  }
1115  if ( ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
1116  ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
1117  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
1118  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
1119  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
1120  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
1121  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
1122  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) )
1123  {
1124  cornerAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
1125  cornerCount += 1.0;
1126  }
1127  }
1128  }
1129  }
1130 
1131  cornerAvg /= cornerCount;
1132  centralAvg /= centralCount;
1133 
1134  //==================================== If density is in the corners
1135  if ( cornerAvg > centralAvg )
1136  {
1137  //================================ Initialise required variables
1138  float* hlpMap = nullptr;
1139  hlpMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
1140  if ( hlpMap == nullptr )
1141  {
1142  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
1143 
1144  if ( settings->htmlReport )
1145  {
1146  std::stringstream hlpSS;
1147  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
1148  rvapi_set_text ( hlpSS.str().c_str(),
1149  "ProgressSection",
1150  settings->htmlReportLineProgress,
1151  1,
1152  1,
1153  1 );
1154  settings->htmlReportLineProgress += 1;
1155  rvapi_flush ( );
1156  }
1157 
1158  exit ( -1 );
1159  }
1160  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( dim[0] * dim[1] * dim[2] ); iter++ )
1161  {
1162  hlpMap[iter] = this->_densityMapMap[iter];
1163  }
1164 
1165  //================================ Transform
1166  unsigned int hlpPos;
1167  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
1168  {
1169  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
1170  {
1171  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
1172  {
1173  //==================== If in lower half, add half; if in upper halp, subtract half
1174  if ( uIt < static_cast<int> (this->_maxMapU+1)/2 ) { newU = uIt + (this->_maxMapU+1)/2; } else { newU = uIt - (this->_maxMapU+1)/2; }
1175  if ( vIt < static_cast<int> (this->_maxMapV+1)/2 ) { newV = vIt + (this->_maxMapV+1)/2; } else { newV = vIt - (this->_maxMapV+1)/2; }
1176  if ( wIt < static_cast<int> (this->_maxMapW+1)/2 ) { newW = wIt + (this->_maxMapW+1)/2; } else { newW = wIt - (this->_maxMapW+1)/2; }
1177 
1178  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
1179  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
1180 
1181  //==================== Set the value into correct coords in the new map
1182  this->_densityMapMap[arrPos] = hlpMap[hlpPos];
1183  }
1184  }
1185  }
1186 
1187  //================================ Free memory
1188  free ( hlpMap );
1189  }
1190  }
1191  else
1192  {
1193  std::cerr << "!!! ProSHADE ERROR !!! Non-orthogonal maps are not yet supported." << std::endl;
1194 
1195  if ( settings->htmlReport )
1196  {
1197  std::stringstream hlpSS;
1198  hlpSS << "<font color=\"red\">" << "Non-orthogonal map detected. Only P1 maps are currently supported." << "</font>";
1199  rvapi_set_text ( hlpSS.str().c_str(),
1200  "ProgressSection",
1201  settings->htmlReportLineProgress,
1202  1,
1203  1,
1204  1 );
1205  settings->htmlReportLineProgress += 1;
1206  rvapi_flush ( );
1207  }
1208 
1209  exit ( -1 );
1210  }
1211 
1212  //======================================== Free memory
1213  if ( cell != nullptr )
1214  {
1215  free ( cell );
1216  cell = nullptr;
1217  }
1218  if ( dim != nullptr )
1219  {
1220  free ( dim );
1221  dim = nullptr;
1222  }
1223  if ( order != nullptr )
1224  {
1225  free ( order );
1226  order = nullptr;
1227  }
1228  if ( orig != nullptr )
1229  {
1230  free ( orig );
1231  orig = nullptr;
1232  }
1233 
1234  //======================================== Close the file
1235  CMap_io::ccp4_cmap_close ( mapFile );
1236 
1237  //======================================== Determine sampling ranges
1238  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
1239  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
1240  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
1241  double maxSamplingRate = std::max ( this->_xSamplingRate, std::max( this->_ySamplingRate, this->_zSamplingRate ) );
1242 
1243  //======================================== If extra cell space is given, apply
1244  this->_maxExtraCellularSpace = *extraSpace;
1245  if ( *extraSpace != 0.0 )
1246  {
1247  //==================================== Compute new stats
1248  int xDiff = static_cast<int> ( std::ceil ( ( this->_xRange + this->_maxExtraCellularSpace ) / this->_xSamplingRate ) - this->_maxMapU );
1249  int yDiff = static_cast<int> ( std::ceil ( ( this->_yRange + this->_maxExtraCellularSpace ) / this->_ySamplingRate ) - this->_maxMapV );
1250  int zDiff = static_cast<int> ( std::ceil ( ( this->_zRange + this->_maxExtraCellularSpace ) / this->_zSamplingRate ) - this->_maxMapW );
1251 
1252  this->_xRange += xDiff * this->_xSamplingRate;
1253  this->_yRange += yDiff * this->_ySamplingRate;
1254  this->_zRange += zDiff * this->_zSamplingRate;
1255 
1256  if ( xDiff % 2 != 0 )
1257  {
1258  this->_xRange += this->_xSamplingRate;
1259  xDiff = static_cast<int> ( std::ceil ( this->_xRange / this->_xSamplingRate ) - ( this->_maxMapU + 1 ) );
1260  }
1261  if ( yDiff % 2 != 0 )
1262  {
1263  this->_yRange += this->_ySamplingRate;
1264  yDiff = static_cast<int> ( std::ceil ( this->_yRange / this->_ySamplingRate ) - ( this->_maxMapV + 1 ) );
1265  }
1266  if ( zDiff % 2 != 0 )
1267  {
1268  this->_zRange += this->_zSamplingRate;
1269  zDiff = static_cast<int> ( std::ceil ( this->_zRange / this->_zSamplingRate ) - ( this->_maxMapW + 1 ) );
1270  }
1271 
1272  xDiff /= 2;
1273  yDiff /= 2;
1274  zDiff /= 2;
1275 
1276  this->_exCeSpDiffX = xDiff;
1277  this->_exCeSpDiffY = yDiff;
1278  this->_exCeSpDiffZ = zDiff;
1279 
1280  this->_xFrom -= xDiff;
1281  this->_yFrom -= yDiff;
1282  this->_zFrom -= zDiff;
1283 
1284  this->_xTo += xDiff;
1285  this->_yTo += yDiff;
1286  this->_zTo += zDiff;
1287 
1288  this->_maxMapU = this->_xTo - this->_xFrom;
1289  this->_maxMapV = this->_yTo - this->_yFrom;
1290  this->_maxMapW = this->_zTo - this->_zFrom;
1291 
1292  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
1293  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
1294  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
1295 
1296  //==================================== Move the map
1297  float *hlpMap = nullptr;
1298  hlpMap = (float*) malloc ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) * sizeof ( float ) );
1299  if ( hlpMap == nullptr )
1300  {
1301  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map moving data. Terminating... " << std::endl;
1302 
1303  if ( settings->htmlReport )
1304  {
1305  std::stringstream hlpSS;
1306  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
1307  rvapi_set_text ( hlpSS.str().c_str(),
1308  "ProgressSection",
1309  settings->htmlReportLineProgress,
1310  1,
1311  1,
1312  1 );
1313  settings->htmlReportLineProgress += 1;
1314  rvapi_flush ( );
1315  }
1316 
1317  exit ( -1 );
1318  }
1319  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
1320  {
1321  hlpMap[iter] = 0.0;
1322  }
1323 
1324  unsigned int newU, newV, newW, hlpPos, arrPos;
1325  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
1326  {
1327  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
1328  {
1329  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
1330  {
1331  if ( ( uIt < xDiff ) || ( uIt > static_cast<int> ( this->_maxMapU - xDiff ) ) ||
1332  ( vIt < yDiff ) || ( vIt > static_cast<int> ( this->_maxMapV - yDiff ) ) ||
1333  ( wIt < zDiff ) || ( wIt > static_cast<int> ( this->_maxMapW - zDiff ) ) )
1334  {
1335  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
1336  hlpMap[hlpPos] = 0.0;
1337  }
1338  else
1339  {
1340  newU = (uIt - xDiff);
1341  newV = (vIt - yDiff);
1342  newW = (wIt - zDiff);
1343 
1344  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
1345  arrPos = newW + (this->_maxMapW + 1 - zDiff * 2) * ( newV + (this->_maxMapV + 1 - yDiff * 2) * newU );
1346 
1347  hlpMap[hlpPos] = this->_densityMapMap[arrPos];
1348  }
1349  }
1350  }
1351  }
1352 
1353  //==================================== Free memory
1354  if ( this->_densityMapMap != nullptr )
1355  {
1356  free ( this->_densityMapMap );
1357  this->_densityMapMap = nullptr;
1358  }
1359 
1360  //==================================== Copy
1361  this->_densityMapMap = (float*) malloc ( ((this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1)) * sizeof ( float ) );
1362  if ( this->_densityMapMap == nullptr )
1363  {
1364  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
1365 
1366  if ( settings->htmlReport )
1367  {
1368  std::stringstream hlpSS;
1369  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Did you run out of memory?" << "</font>";
1370  rvapi_set_text ( hlpSS.str().c_str(),
1371  "ProgressSection",
1372  settings->htmlReportLineProgress,
1373  1,
1374  1,
1375  1 );
1376  settings->htmlReportLineProgress += 1;
1377  rvapi_flush ( );
1378  }
1379 
1380  exit ( -1 );
1381  }
1382  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
1383  {
1384  this->_densityMapMap[iter] = hlpMap[iter];
1385  }
1386 
1387  //==================================== Free memory
1388  if ( hlpMap != nullptr )
1389  {
1390  free ( hlpMap );
1391  hlpMap = nullptr;
1392  }
1393  }
1394  else
1395  {
1396  this->_exCeSpDiffX = 0;
1397  this->_exCeSpDiffY = 0;
1398  this->_exCeSpDiffZ = 0;
1399  }
1400 
1401  //======================================== Deal with oversampling
1402  if ( ( this->_mapResolution / 2.0 ) > maxSamplingRate )
1403  {
1404  maxSamplingRate = ( this->_mapResolution / 2.0 );
1405  }
1406  else
1407  {
1408  std::cerr << "!!! ProSHADE WARNING !!! The map sampling does not support the required resolution. This means that your map will be over-sampled and the computation will take longer than needed. Use higher resolution value to resolve." << std::endl;
1409  }
1410 
1411  //======================================== If bandwidth is not given, determine it
1412  if ( *bandwidth == 0 )
1413  {
1414  *bandwidth = std::ceil ( this->_maxMapRange / 4.0 );
1415  }
1416 
1417  if ( settings->maxRotError != 0 )
1418  {
1419  *bandwidth = static_cast<unsigned int> ( 180 / settings->maxRotError );
1420  this->_wasBandwithGiven = true;
1421  }
1422 
1423  //======================================== Decide shell spacing, if not already decided
1424  if ( *shellDistance == 0 )
1425  {
1426  settings->shellSpacing = static_cast<double> ( this->_maxMapRange / 2.0 ) / std::floor ( static_cast<double> ( this->_maxMapRange / 2.0 ) / static_cast<double> ( this->_mapResolution / 2.0 ) );
1427  this->_shellSpacing = settings->shellSpacing;
1428  *shellDistance = this->_shellSpacing;
1429 
1430  while ( std::floor ( this->_maxMapRange / this->_shellSpacing ) < 20 )
1431  {
1432  this->_shellSpacing /= 2.0;
1433  settings->shellSpacing /= 2.0;
1434  *shellDistance /= 2.0;
1435  }
1436  }
1437 
1438  //======================================== Automatically determine maximum number of shells
1439  this->_shellPlacement = std::vector<double> ( std::floor ( this->_maxMapRange / this->_shellSpacing ) );
1440 
1441  for ( unsigned int shellIter = 0; shellIter < static_cast<unsigned int> ( this->_shellPlacement.size() ); shellIter++ )
1442  {
1443  this->_shellPlacement.at(shellIter) = (shellIter+1) * this->_shellSpacing;
1444  }
1445 
1446  //======================================== If theta and phi are not given, determine them
1447  if ( *theta == 0 ) { *theta = 2 * (*bandwidth); }
1448  if ( *phi == 0 ) { *phi = 2 * (*bandwidth); }
1449 
1450  //======================================== If Gauss-Legendre integration order is not given, decide it
1451  if ( *glIntegOrder == 0 )
1452  {
1453  double distPerPointFraction = static_cast<double> ( this->_shellSpacing ) / ( this->_maxMapRange / 2.0 );
1454 
1455  for ( unsigned int iter = 2; iter < static_cast<unsigned int> ( ProSHADE_internal_misc::glIntMaxDists.size() ); iter++ )
1456  {
1457  if ( ProSHADE_internal_misc::glIntMaxDists.at(iter) >= distPerPointFraction )
1458  {
1459  *glIntegOrder = iter;
1460  }
1461  }
1462  }
1463 
1464  //======================================== Done
1465  this->_densityMapComputed = true;
1466  this->_fromPDB = false;
1467 
1468 }
1469 
1477 {
1478  //======================================== Sanity checks
1479  if ( this->_densityMapMap == nullptr )
1480  {
1481  std::cerr << "!!! ProSHADE ERROR !!! Attempted to normalise the internal map representation, but the values have already been deleted - either called the normaliseMap function too early or too late. Terminating..." << std::endl;
1482 
1483  if ( settings->htmlReport )
1484  {
1485  std::stringstream hlpSS;
1486  hlpSS << "<font color=\"red\">" << "Attempted to normalise the internal map representation, but the values have already been deleted - either called the normaliseMap function too early or too late. This seems like an internal bug, please report this case." << "</font>";
1487  rvapi_set_text ( hlpSS.str().c_str(),
1488  "ProgressSection",
1489  settings->htmlReportLineProgress,
1490  1,
1491  1,
1492  1 );
1493  settings->htmlReportLineProgress += 1;
1494  rvapi_flush ( );
1495  }
1496 
1497  exit ( -1 );
1498  }
1499 
1500  //======================================== Get values
1501  std::vector<double> vals ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) );
1502  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
1503  {
1504  vals.at(iter) = this->_densityMapMap[iter];
1505  }
1506  std::sort ( vals.begin(), vals.end() );
1507 
1508  //======================================== Find mean and standard deviation for later normalisation
1509  this->_mapMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
1510  this->_mapSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - this->_mapMean * this->_mapMean );
1511 
1512  //======================================== Apply
1513  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
1514  {
1515  this->_densityMapMap[iter] = this->_densityMapMap[iter] / this->_mapSdev;
1516  }
1517 
1518  //======================================== Done
1519  return ;
1520 }
1521 
1529 {
1530  //======================================== Sanity checks
1531  if ( this->_densityMapMap == nullptr )
1532  {
1533  std::cerr << "!!! ProSHADE ERROR !!! Attempted to get COM and distances for the internal map representation, but the values have already been deleted - either called the getCOMandDist function too early or too late. Terminating..." << std::endl;
1534 
1535  if ( settings->htmlReport )
1536  {
1537  std::stringstream hlpSS;
1538  hlpSS << "<font color=\"red\">" << "Attempted to normalise the internal map representation, but the values have already been deleted - either called the normaliseMap function too early or too late. This seems like an internal bug, please report this case." << "</font>";
1539  rvapi_set_text ( hlpSS.str().c_str(),
1540  "ProgressSection",
1541  settings->htmlReportLineProgress,
1542  1,
1543  1,
1544  1 );
1545  settings->htmlReportLineProgress += 1;
1546  rvapi_flush ( );
1547  }
1548 
1549  exit ( -1 );
1550  }
1551 
1552  //======================================== Get COM
1553  unsigned int arrPos = 0;
1554  double totDens = 0.0;
1555  std::array<double,4> meanVals;
1556  meanVals[0] = 0.0;
1557  meanVals[1] = 0.0;
1558  meanVals[2] = 0.0;
1559  meanVals[3] = 0.0;
1560  std::vector<double> vals ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) );
1561 
1562  for ( unsigned int uIt = 0; uIt < static_cast<unsigned int> ( (this->_maxMapU+1) ); uIt++ )
1563  {
1564  for ( unsigned int vIt = 0; vIt < static_cast<unsigned int> ( (this->_maxMapV+1) ); vIt++ )
1565  {
1566  for ( unsigned int wIt = 0; wIt < static_cast<unsigned int> ( (this->_maxMapW+1) ); wIt++ )
1567  {
1568  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
1569 
1570  if ( this->_densityMapMap[arrPos] > 0.0 )
1571  {
1572  meanVals[0] += this->_densityMapMap[arrPos] * uIt;
1573  meanVals[1] += this->_densityMapMap[arrPos] * vIt;
1574  meanVals[2] += this->_densityMapMap[arrPos] * wIt;
1575 
1576  totDens += this->_densityMapMap[arrPos];
1577  }
1578  }
1579  }
1580  }
1581 
1582  meanVals[0] /= totDens;
1583  meanVals[1] /= totDens;
1584  meanVals[2] /= totDens;
1585 
1586  //======================================== Find distances to borders
1587  double distX = 0.0;
1588  double distY = 0.0;
1589  double distZ = 0.0;
1590 
1591  if ( meanVals[0] <= static_cast<double> ((this->_maxMapU+1)/2) )
1592  {
1593  distX = meanVals[0] * this->_xSamplingRate;
1594  }
1595  else
1596  {
1597  distX = ( static_cast<double> ( this->_maxMapU+1 ) - meanVals[0] ) * this->_xSamplingRate;
1598  }
1599 
1600  if ( meanVals[1] <= static_cast<double> ((this->_maxMapV+1)/2) )
1601  {
1602  distY = meanVals[1] * this->_ySamplingRate;
1603  }
1604  else
1605  {
1606  distY = ( static_cast<double> ( this->_maxMapV+1 ) - meanVals[1] ) * this->_ySamplingRate;
1607  }
1608 
1609  if ( meanVals[2] <= static_cast<double> ((this->_maxMapW+1)/2) )
1610  {
1611  distZ = meanVals[2] * this->_zSamplingRate;
1612  }
1613  else
1614  {
1615  distZ = ( static_cast<double> ( this->_maxMapW+1 ) - meanVals[2] ) * this->_zSamplingRate;
1616  }
1617 
1618  //======================================== Get total distance
1619  meanVals[3] = sqrt ( pow( distX, 2.0 ) + pow ( distY, 2.0 ) + pow ( distZ, 2.0 ) );
1620 
1621  //======================================== Done
1622  return ( meanVals );
1623 }
1624 
1639  int hlpV,
1640  int hlpW,
1641  double blurBy,
1642  double maxMapIQR,
1643  double extraMaskSpace )
1644 {
1645  //================================ Initialise the data structures
1646  fftw_complex* tmpIn;
1647  fftw_complex* tmpOut;
1648  tmpIn = new fftw_complex[hlpU * hlpV * hlpW];
1649  tmpOut = new fftw_complex[hlpU * hlpV * hlpW];
1650  fftw_complex* maskData = new fftw_complex [ hlpU * hlpV * hlpW ];
1651  fftw_complex* maskDataInv = new fftw_complex [ hlpU * hlpV * hlpW ];
1652 
1653  //================================ Initialise local variables
1654  int h, k, l;
1655  int uIt, vIt, wIt;
1656  double mag, phase, S;
1657  double normFactor = (hlpU * hlpV * hlpW);
1658  double bFacChange = blurBy;
1659  double real = 0.0;
1660  double imag = 0.0;
1661  unsigned int hlpIt = 0;
1662  int arrayPos = 0;
1663  fftw_plan p;
1664 
1665  //======================================== Load map data for Fourier
1666  for ( uIt = 0; uIt < hlpU; uIt++ )
1667  {
1668  for ( vIt = 0; vIt < hlpV; vIt++ )
1669  {
1670  for ( wIt = 0; wIt < hlpW; wIt++ )
1671  {
1672  //============================ Initialisation
1673  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
1674 
1675  if ( this->_densityMapCor[arrayPos] == this->_densityMapCor[arrayPos] )
1676  {
1677  tmpIn[arrayPos][0] = ( this->_densityMapCor[arrayPos] - this->_mapMean ) / this->_mapSdev;
1678  tmpIn[arrayPos][1] = 0.0;
1679  }
1680  else
1681  {
1682  tmpIn[arrayPos][0] = 0.0;
1683  tmpIn[arrayPos][1] = 0.0;
1684  }
1685  }
1686  }
1687  }
1688 
1689  //======================================== Create plans (FFTW_MEASURE would change the arrays)
1690  p = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpIn, tmpOut, FFTW_FORWARD, FFTW_ESTIMATE );
1691  fftw_execute ( p );
1692 
1693  //================================ Prepare FFTW plan for mask FFTW
1694  fftw_plan pMaskInv = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, maskDataInv, maskData, FFTW_BACKWARD, FFTW_ESTIMATE );
1695 
1696  for ( uIt = 0; uIt < hlpU; uIt++ )
1697  {
1698  for ( vIt = 0; vIt < hlpV; vIt++ )
1699  {
1700  for ( wIt = 0; wIt < hlpW; wIt++ )
1701  {
1702  //==================== Var init
1703  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
1704  real = tmpOut[arrayPos][0];
1705  imag = tmpOut[arrayPos][1];
1706 
1707  //==================== Change the B-factors, if required
1708  if ( uIt > (hlpU / 2) ) { h = uIt - hlpU; } else { h = uIt; }
1709  if ( vIt > (hlpV / 2) ) { k = vIt - hlpV; } else { k = vIt; }
1710  if ( wIt > (hlpW / 2) ) { l = wIt - hlpW; } else { l = wIt; }
1711 
1712  //==================== Get magnitude and phase with mask parameters
1713  S = ( pow( static_cast<double> ( h ) / this->_xRange, 2.0 ) +
1714  pow( static_cast<double> ( k ) / this->_yRange, 2.0 ) +
1715  pow( static_cast<double> ( l ) / this->_zRange, 2.0 ) );
1716  mag = sqrt ( (real*real) + (imag*imag) ) * std::exp ( - ( ( bFacChange * S ) / 4.0 ) );
1717  phase = atan2 ( imag, real );
1718 
1719  //==================== Save the mask data
1720  maskDataInv[arrayPos][0] = ( mag * cos(phase) ) / normFactor;
1721  maskDataInv[arrayPos][1] = ( mag * sin(phase) ) / normFactor;
1722  }
1723  }
1724  }
1725 
1726  //======================================== Execute the inversions
1727  fftw_execute ( pMaskInv );
1728 
1729  //======================================== Get the map threshold
1730  std::vector<double> maskVals ( hlpU * hlpV * hlpW );
1731  hlpIt = 0;
1732  for ( uIt = 0; uIt < hlpU; uIt++ )
1733  {
1734  for ( vIt = 0; vIt < hlpV; vIt++ )
1735  {
1736  for ( wIt = 0; wIt < hlpW; wIt++ )
1737  {
1738  //============================ Save to vector
1739  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
1740  maskVals.at(hlpIt) = maskData[arrayPos][0];
1741  hlpIt += 1;
1742 
1743  }
1744  }
1745  }
1746 
1747  double medianPos = static_cast<unsigned int> ( maskVals.size() / 2 );
1748  std::sort ( maskVals.begin(), maskVals.end() );
1749 
1750  double interQuartileRange = maskVals.at(medianPos+(medianPos/2)) - maskVals.at(medianPos-(medianPos/2));
1751  double mapThresholdPlus = maskVals.at(medianPos+(medianPos/2)) + ( interQuartileRange * maxMapIQR );
1752  maskVals.clear();
1753 
1754  //======================================== Add extra space to mask
1755  int addPoints = static_cast<int> ( std::max ( std::ceil ( extraMaskSpace / static_cast<double> ( this->_xRange / (hlpU-1) ) ), std::max ( std::ceil ( extraMaskSpace / static_cast<double> ( this->_yRange / (hlpV-1) ) ), std::ceil ( extraMaskSpace / static_cast<double> ( this->_zRange / (hlpW-1) ) ) ) ) );
1756  int arrPosSearch = 0;
1757  int newU, newV, newW;
1758  bool breakOut = false;
1759 
1760  for ( uIt = 0; uIt < hlpU; uIt++ )
1761  {
1762  for ( vIt = 0; vIt < hlpV; vIt++ )
1763  {
1764  for ( wIt = 0; wIt < hlpW; wIt++ )
1765  {
1766  //============================ Var init
1767  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
1768 
1769  //============================ If already in mask, ignore
1770  if ( maskData[arrayPos][0] > mapThresholdPlus )
1771  {
1772  tmpIn[arrayPos][0] = 1.0;
1773  continue;
1774  }
1775 
1776  //============================ If not, find if it is close to mask
1777  tmpIn[arrayPos][0] = 0.0;
1778  breakOut = false;
1779  for ( int uCh = -addPoints; uCh <= addPoints; uCh++ )
1780  {
1781  if ( breakOut ) { break; }
1782  for ( int vCh = -addPoints; vCh <= addPoints; vCh++ )
1783  {
1784  if ( breakOut ) { break; }
1785  for ( int wCh = -addPoints; wCh <= addPoints; wCh++ )
1786  {
1787  if ( breakOut ) { break; }
1788  if ( ( uCh == 0 ) && ( vCh == 0 ) && wCh == 0 ) { continue; }
1789 
1790  newU = uIt + uCh;
1791  newV = vIt + vCh;
1792  newW = wIt + wCh;
1793 
1794  if ( newU < 0 ) { newU += hlpU; } if ( newU >= hlpU ) { newU -= hlpU; }
1795  if ( newV < 0 ) { newV += hlpV; } if ( newV >= hlpV ) { newV -= hlpV; }
1796  if ( newW < 0 ) { newW += hlpW; } if ( newW >= hlpW ) { newW -= hlpW; }
1797 
1798  arrPosSearch = newW + hlpW * ( newV + hlpV * newU );
1799 
1800  if ( maskData[arrPosSearch][0] > mapThresholdPlus )
1801  {
1802  tmpIn[arrayPos][0] = 1.0;
1803  breakOut = true;
1804  }
1805  }
1806  }
1807  }
1808  }
1809  }
1810  }
1811 
1812  //======================================== Apply the mask
1813  for ( uIt = 0; uIt < hlpU; uIt++ )
1814  {
1815  for ( vIt = 0; vIt < hlpV; vIt++ )
1816  {
1817  for ( wIt = 0; wIt < hlpW; wIt++ )
1818  {
1819  //============================ Var init
1820  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
1821 
1822  //============================ Apply mask
1823  if ( tmpIn[arrayPos][0] == 0.0 )
1824  {
1825  this->_densityMapCor[arrayPos] = 0.0;
1826  }
1827  }
1828  }
1829  }
1830 
1831  //================================ Clean up
1832  delete[] maskData;
1833  maskData = nullptr;
1834  delete[] maskDataInv;
1835  maskDataInv = nullptr;
1836  delete[] tmpIn;
1837  tmpIn = nullptr;
1838  delete[] tmpOut;
1839  tmpOut = nullptr;
1840 
1841  //================================ Delete the plans
1842  fftw_destroy_plan ( p );
1843  fftw_destroy_plan ( pMaskInv );
1844 
1845  //================================ Done
1846  return ;
1847 }
1848 
1865  int hlpV,
1866  int hlpW,
1867  int verbose,
1868  bool runAll )
1869 {
1870  //======================================== Get the list of islands
1871  std::vector< std::vector<int> > clusters = this->findMapIslands ( hlpU, hlpV, hlpW, this->_densityMapCor );
1872  if ( clusters.size() == 0 )
1873  {
1874  return ( true );
1875  }
1876 
1877  //======================================== Decide which islands to keep
1878  int maxVolume = 0;
1879  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( clusters.size() ); iter++ )
1880  {
1881  maxVolume = std::max ( maxVolume, static_cast<int> ( clusters.at(iter).size() ) );
1882  }
1883 
1884  //======================================== Are there too many islands?
1885  int fracLess10 = 0;
1886  int volTop80 = 0;
1887  int totVol = 0;
1888  int volLow20 = 0;
1889  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( clusters.size() ); iter++ )
1890  {
1891  totVol += clusters.at(iter).size();
1892  if ( static_cast<double> ( clusters.at(iter).size() ) > ( 0.8 * maxVolume ) )
1893  {
1894  volTop80 += clusters.at(iter).size();
1895  }
1896  if ( static_cast<double> ( clusters.at(iter).size() ) < ( 0.1 * maxVolume ) )
1897  {
1898  fracLess10 += 1;
1899  }
1900  if ( static_cast<double> ( clusters.at(iter).size() ) < ( 0.2 * maxVolume ) )
1901  {
1902  volLow20 += clusters.at(iter).size();
1903  }
1904  }
1905 
1906  //======================================== More computations needed?
1907  if ( ( fracLess10 != 0 ) || ( clusters.size() > 5 ) )
1908  {
1909  if ( ( ( static_cast<double> ( fracLess10 ) / static_cast<double> ( clusters.size() ) ) > 0.5 ) ||
1910  ( ( static_cast<double> ( volTop80 ) / static_cast<double> ( totVol ) ) < 0.9 ) ||
1911  ( ( static_cast<double> ( volLow20 ) / static_cast<double> ( totVol ) ) > 0.1 ) )
1912  {
1913  if ( !runAll )
1914  {
1915  return ( true );
1916  }
1917  }
1918  }
1919 
1920  //======================================== Check for corners
1921  if ( verbose > 3 )
1922  {
1923  std::cout << ">>>>>>>> Cluster check started." << std::endl;
1924  }
1925 
1926  //======================================== Apply the islands
1927  double *tmpIn = new double[hlpU * hlpV * hlpW];
1928  std::vector<int> removedClusters;
1929 
1930  for ( unsigned int i = 0; i < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); i++ )
1931  {
1932  tmpIn[i] = this->_densityMapCor[i];
1933  this->_densityMapCor[i] = 0.0;
1934  }
1935 
1936  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( clusters.size() ); iter++ )
1937  {
1938  if ( static_cast<double> ( clusters.at(iter).size() ) < ( 0.3 * static_cast<double> ( maxVolume ) ) )
1939  {
1940  continue;
1941  }
1942  else
1943  {
1944  removedClusters.emplace_back ( iter );
1945  for ( unsigned int it = 0; it < static_cast<unsigned int> ( clusters.at(iter).size() ); it++ )
1946  {
1947  this->_densityMapCor[clusters.at(iter).at(it)] = tmpIn[clusters.at(iter).at(it)];
1948  }
1949  }
1950  }
1951 
1952  //======================================== Check all values for having 3A to passing value
1953  int noPoints = std::ceil ( 3.0 / std::max ( this->_xRange / hlpU, std::max ( this->_yRange / hlpV, this->_zRange / hlpW ) ) );
1954  int arrPos = 0;
1955  int arrPos2 = 0;
1956  bool addPoint = false;
1957  int uIt, vIt, wIt;
1958  int hlpUIt, hlpVIt, hlpWIt;
1959 
1960  for ( unsigned int rIt = 0; rIt < static_cast<unsigned int> ( removedClusters.size() ); rIt++ )
1961  {
1962  for ( int rPt = 0; rPt < static_cast<int> ( clusters.at(removedClusters.at(rIt)).size() ); rPt++ )
1963  {
1964  //================================ Point was removed. Check if it is at least 3A to the closest remaining point
1965  uIt = ( clusters.at(removedClusters.at(rIt)).at(rPt) / ( hlpW * hlpV ) ) % hlpW;
1966  vIt = static_cast<int> ( std::floor ( clusters.at(removedClusters.at(rIt)).at(rPt) / hlpW ) ) % hlpV;
1967  wIt = clusters.at(removedClusters.at(rIt)).at(rPt) - ( uIt * hlpW * hlpV ) - ( vIt * hlpW );
1968 
1969  addPoint = false;
1970  for ( int newX = uIt-noPoints; newX <= uIt+noPoints; newX++ )
1971  {
1972  if ( addPoint ) { break; }
1973  for ( int newY = vIt-noPoints; newY <= vIt+noPoints; newY++ )
1974  {
1975  if ( addPoint ) { break; }
1976  for ( int newZ = wIt-noPoints; newZ <= wIt+noPoints; newZ++ )
1977  {
1978  if ( ( newX == uIt ) && ( newY == vIt ) && ( newZ == wIt ) ) { continue; }
1979 
1980  hlpUIt = newX;
1981  hlpVIt = newY;
1982  hlpWIt = newZ;
1983 
1984  if ( hlpUIt < 0 ) { hlpUIt += hlpU; } if ( hlpUIt >= hlpU ) { hlpUIt -= hlpU; }
1985  if ( hlpVIt < 0 ) { hlpVIt += hlpV; } if ( hlpVIt >= hlpV ) { hlpVIt -= hlpV; }
1986  if ( hlpWIt < 0 ) { hlpWIt += hlpW; } if ( hlpWIt >= hlpW ) { hlpWIt -= hlpW; }
1987 
1988  arrPos2 = hlpWIt + hlpW * ( hlpVIt + hlpV * hlpUIt );
1989  if ( this->_densityMapCor[arrPos2] > 0.0 ) { addPoint = true; break; }
1990  }
1991  }
1992  }
1993 
1994  if ( addPoint )
1995  {
1996  arrPos = wIt + hlpW * ( vIt + hlpV * uIt );
1997  this->_densityMapCor[arrPos] = -999.999;
1998  }
1999  }
2000  }
2001 
2002  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
2003  {
2004  if ( this->_densityMapCor[iter] == -999.999 )
2005  {
2006  this->_densityMapCor[iter] = tmpIn[iter];
2007  }
2008  }
2009 
2010  //======================================== Free memory
2011  delete[] tmpIn;
2012 
2013  //======================================== Done
2014  return ( false );
2015 }
2016 
2030  double yShift,
2031  double zShift )
2032 {
2033  //======================================== Change xFrom, xTo, yFrom, yTo, zFrom and zTo
2034  this->_xFrom += xShift;
2035  this->_xTo += xShift;
2036  this->_yFrom += yShift;
2037  this->_yTo += yShift;
2038  this->_zFrom += zShift;
2039  this->_zTo += zShift;
2040 
2041  //======================================== Done
2042 
2043 }
2044 
2057  double yShift,
2058  double zShift )
2059 {
2060  //======================================== Initialise
2061  int hlpU = this->_maxMapU + 1;
2062  int hlpV = this->_maxMapV + 1;
2063  int hlpW = this->_maxMapW + 1;
2064 
2065  int arrayPos = 0;
2066  int h, k, l;
2067  double real = 0.0;
2068  double imag = 0.0;
2069  double exponent = 0.0;
2070  double trCoeffReal = 0.0;
2071  double trCoeffImag = 0.0;
2072  double normFactor = static_cast<double> ( hlpU * hlpV * hlpW );
2073  fftw_complex *translatedMap = new fftw_complex [hlpU * hlpV * hlpW];
2074  fftw_complex *fCoeffs = new fftw_complex [hlpU * hlpV * hlpW];
2075  std::array<double,2> hlpArr;
2076  fftw_plan planForwardFourier;
2077  fftw_plan planBackwardFourier;
2078 
2079 
2080  //======================================== Create plans
2081  planForwardFourier = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, translatedMap, fCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
2082  planBackwardFourier = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, fCoeffs, translatedMap, FFTW_BACKWARD, FFTW_ESTIMATE );
2083 
2084  //======================================== Decide which map variable should be translated
2085  if ( this->_densityMapCor == nullptr )
2086  {
2087  for ( int uIt = 0; uIt < hlpU; uIt++ )
2088  {
2089  for ( int vIt = 0; vIt < hlpV; vIt++ )
2090  {
2091  for ( int wIt = 0; wIt < hlpW; wIt++ )
2092  {
2093  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
2094 
2095  translatedMap[arrayPos][0] = this->_densityMapMap[arrayPos];
2096  translatedMap[arrayPos][1] = 0.0;
2097  }
2098  }
2099  }
2100  }
2101  else
2102  {
2103  for ( int uIt = 0; uIt < hlpU; uIt++ )
2104  {
2105  for ( int vIt = 0; vIt < hlpV; vIt++ )
2106  {
2107  for ( int wIt = 0; wIt < hlpW; wIt++ )
2108  {
2109  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
2110 
2111  translatedMap[arrayPos][0] = this->_densityMapCor[arrayPos];
2112  translatedMap[arrayPos][1] = 0.0;
2113  }
2114  }
2115  }
2116  }
2117 
2118  //======================================== Compute Fourier
2119  fftw_execute ( planForwardFourier );
2120 
2121  for ( int uIt = 0; uIt < hlpU; uIt++ )
2122  {
2123  for ( int vIt = 0; vIt < hlpV; vIt++ )
2124  {
2125  for ( int wIt = 0; wIt < hlpW; wIt++ )
2126  {
2127  //============================ Var init
2128  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
2129  real = fCoeffs[arrayPos][0];
2130  imag = fCoeffs[arrayPos][1];
2131 
2132  //======================== Change the B-factors, if required
2133  if ( uIt > ((hlpU+1) / 2) ) { h = uIt - hlpU; } else { h = uIt; }
2134  if ( vIt > ((hlpV+1) / 2) ) { k = vIt - hlpV; } else { k = vIt; }
2135  if ( wIt > ((hlpW+1) / 2) ) { l = wIt - hlpW; } else { l = wIt; }
2136 
2137  //============================ Get translation coefficient change
2138  exponent = ( ( ( static_cast <double> ( h ) / this->_xRange ) * xShift ) +
2139  ( ( static_cast <double> ( k ) / this->_yRange ) * yShift ) +
2140  ( ( static_cast <double> ( l ) / this->_zRange ) * zShift ) ) * 2.0 * M_PI;
2141 
2142  trCoeffReal = cos ( exponent );
2143  trCoeffImag = sin ( exponent );
2144 
2145  hlpArr = ProSHADE_internal_misc::complexMultiplication ( &real, &imag, &trCoeffReal, &trCoeffImag );
2146 
2147  //============================ Save the mask data
2148  fCoeffs[arrayPos][0] = hlpArr[0] / normFactor;
2149  fCoeffs[arrayPos][1] = hlpArr[1] / normFactor;
2150  }
2151  }
2152  }
2153 
2154  //======================================== Compute inverse Fourier
2155  fftw_execute ( planBackwardFourier );
2156 
2157  //======================================== Decide which map variable should be translated and remove corners (sometimes have HUUUUUGE values for some reason...)
2158  if ( this->_densityMapCor == nullptr )
2159  {
2160  for ( int uIt = 0; uIt < hlpU; uIt++ )
2161  {
2162  for ( int vIt = 0; vIt < hlpV; vIt++ )
2163  {
2164  for ( int wIt = 0; wIt < hlpW; wIt++ )
2165  {
2166  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
2167  this->_densityMapMap[arrayPos] = static_cast<float> ( translatedMap[arrayPos][0] );
2168  }
2169  }
2170  }
2171  }
2172  else
2173  {
2174  for ( int uIt = 0; uIt < hlpU; uIt++ )
2175  {
2176  for ( int vIt = 0; vIt < hlpV; vIt++ )
2177  {
2178  for ( int wIt = 0; wIt < hlpW; wIt++ )
2179  {
2180  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
2181  this->_densityMapCor[arrayPos] = translatedMap[arrayPos][0];
2182  }
2183  }
2184  }
2185  }
2186 
2187  //======================================== Free memory
2188  fftw_destroy_plan ( planForwardFourier );
2189  fftw_destroy_plan ( planBackwardFourier );
2190  delete[] translatedMap;
2191  delete[] fCoeffs;
2192 
2193  //======================================== Done
2194  return ;
2195 }
2196 
2211 std::array<double,6> ProSHADE_internal::ProSHADE_data::getDensityMapFromMAPRebox ( std::string fileName,
2212  double maxMapIQR,
2213  double extraCS,
2214  int verbose,
2215  bool useCubicMaps,
2216  double maskBlurFactor,
2217  bool maskBlurFactorGiven,
2218  ProSHADE::ProSHADE_settings* settings )
2219 {
2220  //======================================== Initialise internal values
2221  this->_inputFileName = fileName;
2222  this->_maxExtraCellularSpace = extraCS;
2223 
2224  //======================================== Initialise local variables
2225  CMap_io::CMMFile *mapFile = nullptr;
2226  float *cell = nullptr;
2227  int *dim = nullptr;
2228  int *order = nullptr;
2229  int *orig = nullptr;
2230  int myMapMode = 0;
2231  double cornerAvg = 0.0;
2232  double centralAvg = 0.0;
2233  double cornerCount = 0.0;
2234  double centralCount = 0.0;
2235  int maxLim[3];
2236  int XYZOrder[3];
2237  std::array<double,6> ret;
2238 
2239  //======================================== Allocate memory
2240  cell = (float*) malloc ( 6 * sizeof ( float ) );
2241  dim = (int* ) malloc ( 3 * sizeof ( int ) );
2242  order = (int* ) malloc ( 3 * sizeof ( int ) );
2243  orig = (int* ) malloc ( 3 * sizeof ( int ) );
2244 
2245  if ( ( cell == nullptr ) || ( dim == nullptr ) || ( order == nullptr ) || ( orig == nullptr ) )
2246  {
2247  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory. Terminating... " << std::endl;
2248 
2249  if ( settings->htmlReport )
2250  {
2251  std::stringstream hlpSS;
2252  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
2253  rvapi_set_text ( hlpSS.str().c_str(),
2254  "ProgressSection",
2255  settings->htmlReportLineProgress,
2256  1,
2257  1,
2258  1 );
2259  settings->htmlReportLineProgress += 1;
2260  rvapi_flush ( );
2261  }
2262 
2263  exit ( -1 );
2264  }
2265 
2266  //======================================== Read in the MAP file info
2267  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
2268  if ( mapFile == nullptr )
2269  {
2270  std::cerr << "!!! ProSHADE ERROR !!! Failed to open the file " << fileName << ". Check for typos and curruption of the file. Terminating..." << std::endl;
2271 
2272  if ( settings->htmlReport )
2273  {
2274  std::stringstream hlpSS;
2275  hlpSS << "<font color=\"red\">" << "Cannot open file " << fileName << ".</font>";
2276  rvapi_set_text ( hlpSS.str().c_str(),
2277  "ProgressSection",
2278  settings->htmlReportLineProgress,
2279  1,
2280  1,
2281  1 );
2282  settings->htmlReportLineProgress += 1;
2283  rvapi_flush ( );
2284  }
2285 
2286  exit ( -1 );
2287  }
2288 
2289  CMap_io::ccp4_cmap_get_cell ( mapFile, cell );
2290  CMap_io::ccp4_cmap_get_dim ( mapFile, dim );
2291  CMap_io::ccp4_cmap_get_order ( mapFile, order );
2292  CMap_io::ccp4_cmap_get_origin ( mapFile, orig );
2293 
2294 
2295  if ( verbose > 2 )
2296  {
2297  std::cout << ">> Map loaded." << std::endl;
2298  }
2299 
2300  //======================================== If CUBIC
2301  if ( ( ( cell[3] < (90.0 + 0.1) ) && ( cell[3] > (90.0 - 0.1) ) ) &&
2302  ( ( cell[4] < (90.0 + 0.1) ) && ( cell[4] > (90.0 - 0.1) ) ) &&
2303  ( ( cell[5] < (90.0 + 0.1) ) && ( cell[5] > (90.0 - 0.1) ) ) )
2304  {
2305  //==================================== Determine/Save dimmensions
2306  this->_xRange = cell[0];
2307  this->_yRange = cell[1];
2308  this->_zRange = cell[2];
2309 
2310  //==================================== Maximal cell dimensions
2311  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
2312 
2313  //==================================== Find max U, V and W
2314  if ( order[0] == 1 ) { this->_maxMapU = dim[0] - 1; this->_xFrom = orig[0]; }
2315  if ( order[0] == 2 ) { this->_maxMapU = dim[1] - 1; this->_yFrom = orig[0]; }
2316  if ( order[0] == 3 ) { this->_maxMapU = dim[2] - 1; this->_zFrom = orig[0]; }
2317 
2318  if ( order[1] == 1 ) { this->_maxMapV = dim[0] - 1; this->_xFrom = orig[1]; }
2319  if ( order[1] == 2 ) { this->_maxMapV = dim[1] - 1; this->_yFrom = orig[1]; }
2320  if ( order[1] == 3 ) { this->_maxMapV = dim[2] - 1; this->_zFrom = orig[1]; }
2321 
2322  if ( order[2] == 1 ) { this->_maxMapW = dim[0] - 1; this->_xFrom = orig[2]; }
2323  if ( order[2] == 2 ) { this->_maxMapW = dim[1] - 1; this->_yFrom = orig[2]; }
2324  if ( order[2] == 3 ) { this->_maxMapW = dim[2] - 1; this->_zFrom = orig[2]; }
2325 
2326  //==================================== Get the map start and end
2327  this->_xTo = this->_xFrom + this->_maxMapU;
2328  this->_yTo = this->_yFrom + this->_maxMapV;
2329  this->_zTo = this->_zFrom + this->_maxMapW;
2330 
2331  //==================================== Allocate map data memory
2332  this->_densityMapMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
2333  if ( this->_densityMapMap == nullptr )
2334  {
2335  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
2336 
2337  if ( settings->htmlReport )
2338  {
2339  std::stringstream hlpSS;
2340  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
2341  rvapi_set_text ( hlpSS.str().c_str(),
2342  "ProgressSection",
2343  settings->htmlReportLineProgress,
2344  1,
2345  1,
2346  1 );
2347  settings->htmlReportLineProgress += 1;
2348  rvapi_flush ( );
2349  }
2350 
2351  exit ( -1 );
2352  }
2353 
2354  //==================================== Check if the mode is compatible
2355  int mapMode = CMap_io::ccp4_cmap_get_datamode ( mapFile );
2356  if ( ( mapMode != 0 ) && ( mapMode != 2 ) )
2357  {
2358  std::cerr << "!!! ProSHADE ERROR !!! Cannot read from the map file. The map file mode is not supported. Terminating..." << std::endl;
2359 
2360  if ( settings->htmlReport )
2361  {
2362  std::stringstream hlpSS;
2363  hlpSS << "<font color=\"red\">" << "Cannot read from the map file. The map file mode is neither 0, nor 2. Other map modes are not supported at the moment." << "</font>";
2364  rvapi_set_text ( hlpSS.str().c_str(),
2365  "ProgressSection",
2366  settings->htmlReportLineProgress,
2367  1,
2368  1,
2369  1 );
2370  settings->htmlReportLineProgress += 1;
2371  rvapi_flush ( );
2372  }
2373 
2374  exit ( -1 );
2375  }
2376 
2377  //==================================== Read in map data
2378  // ... Find the stop positions (start is in orig variables) and the axis order
2379  int newU, newV, newW;
2380  int arrPos;
2381 
2382  for ( int iter = 0; iter < 3; iter++ )
2383  {
2384  maxLim[iter] = orig[iter] + dim[iter] - 1;
2385  XYZOrder[order[iter]-1] = iter;
2386  }
2387 
2388  // ... Solve the dimensions and sizes
2389  int fastDimSize = ( maxLim[0] - orig[0] + 1 );
2390  int midDimSize = ( maxLim[1] - orig[1] + 1 ) * fastDimSize;
2391  std::vector<float> section( midDimSize );
2392  int index;
2393  int iters[3];
2394 
2395  // ... Read in the map data
2396  for ( iters[2] = orig[XYZOrder[2]]; iters[2] <= maxLim[XYZOrder[2]]; iters[2]++ )
2397  {
2398  index = 0;
2399  CMap_io::ccp4_cmap_read_section( mapFile, &section[0] );
2400 
2401  if ( mapMode == 0 )
2402  {
2403  for ( int iter = ( midDimSize - 1 ); iter >= 0; iter-- )
2404  {
2405  section[iter] = static_cast<float> ( ( reinterpret_cast<unsigned char*> (&section[0]) )[iter] );
2406  }
2407  }
2408 
2409  for ( iters[1] = orig[XYZOrder[1]]; iters[1] <= maxLim[XYZOrder[1]]; iters[1]++ )
2410  {
2411  for ( iters[0] = orig[XYZOrder[0]]; iters[0] <= maxLim[XYZOrder[0]]; iters[0]++ )
2412  {
2413  newU = iters[XYZOrder[0]] - orig[XYZOrder[0]];
2414  newV = iters[XYZOrder[1]] - orig[XYZOrder[1]];
2415  newW = iters[XYZOrder[2]] - orig[XYZOrder[2]];
2416  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
2417  this->_densityMapMap[arrPos] = static_cast<float> ( section[ index++ ] );
2418  }
2419  }
2420  }
2421 
2422  //==================================== Get values for normalisation
2423  std::vector<double> vals ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) );
2424  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( dim[0] * dim[1] * dim[2] ); iter++ )
2425  {
2426  vals.at(iter) = this->_densityMapMap[iter];
2427  }
2428  std::sort ( vals.begin(), vals.end() );
2429 
2430  //==================================== Find mean and standard deviation for later normalisation
2431  this->_mapMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
2432  this->_mapSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - this->_mapMean * this->_mapMean );
2433  vals.clear ( );
2434 
2435  //==================================== Check if the map is not absolutely de-centered
2436  int noPToCheckU = static_cast<unsigned int> ( this->_maxMapU / 8.0 );
2437  int noPToCheckV = static_cast<unsigned int> ( this->_maxMapV / 8.0 );
2438  int noPToCheckW = static_cast<unsigned int> ( this->_maxMapW / 8.0 );
2439 
2440  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
2441  {
2442  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
2443  {
2444  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
2445  {
2446  //======================== Initialisation
2447  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
2448 
2449  //======================== Check to which quadrant the value belongs to
2450  if ( ( ( uIt <= static_cast<int> ( this->_maxMapU/2 + noPToCheckU ) ) && ( uIt >= static_cast<int> ( this->_maxMapU/2 - noPToCheckU ) ) ) &&
2451  ( ( vIt <= static_cast<int> ( this->_maxMapV/2 + noPToCheckV ) ) && ( vIt >= static_cast<int> ( this->_maxMapV/2 - noPToCheckV ) ) ) &&
2452  ( ( wIt <= static_cast<int> ( this->_maxMapW/2 + noPToCheckW ) ) && ( wIt >= static_cast<int> ( this->_maxMapW/2 - noPToCheckW ) ) ) )
2453  {
2454  centralAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
2455  centralCount += 1.0;
2456  }
2457  if ( ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
2458  ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
2459  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
2460  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
2461  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
2462  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
2463  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
2464  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) )
2465  {
2466  cornerAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
2467  cornerCount += 1.0;
2468  }
2469  }
2470  }
2471  }
2472 
2473  cornerAvg /= cornerCount;
2474  centralAvg /= centralCount;
2475 
2476  //==================================== If density is in the corners
2477  if ( cornerAvg > centralAvg )
2478  {
2479  //================================ Initialise required variables
2480  float* hlpMap = nullptr;
2481  hlpMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
2482  if ( hlpMap == nullptr )
2483  {
2484  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
2485 
2486  if ( settings->htmlReport )
2487  {
2488  std::stringstream hlpSS;
2489  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
2490  rvapi_set_text ( hlpSS.str().c_str(),
2491  "ProgressSection",
2492  settings->htmlReportLineProgress,
2493  1,
2494  1,
2495  1 );
2496  settings->htmlReportLineProgress += 1;
2497  rvapi_flush ( );
2498  }
2499 
2500  exit ( -1 );
2501  }
2502  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( dim[0] * dim[1] * dim[2] ); iter++ )
2503  {
2504  hlpMap[iter] = this->_densityMapMap[iter];
2505  }
2506 
2507  //================================ Transform
2508  unsigned int hlpPos;
2509  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
2510  {
2511  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
2512  {
2513  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
2514  {
2515  //==================== If in lower half, add half; if in upper halp, subtract half
2516  if ( uIt < static_cast<int> (this->_maxMapU+1)/2 ) { newU = uIt + (this->_maxMapU+1)/2; } else { newU = uIt - (this->_maxMapU+1)/2; }
2517  if ( vIt < static_cast<int> (this->_maxMapV+1)/2 ) { newV = vIt + (this->_maxMapV+1)/2; } else { newV = vIt - (this->_maxMapV+1)/2; }
2518  if ( wIt < static_cast<int> (this->_maxMapW+1)/2 ) { newW = wIt + (this->_maxMapW+1)/2; } else { newW = wIt - (this->_maxMapW+1)/2; }
2519 
2520  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
2521  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
2522 
2523  //==================== Set the value into correct coords in the new map
2524  this->_densityMapMap[arrPos] = hlpMap[hlpPos];
2525  }
2526  }
2527  }
2528 
2529  //================================ Free memory
2530  free ( hlpMap );
2531  }
2532 
2533  if ( verbose > 3 )
2534  {
2535  std::cout << ">>>>> Density moved from corners to center, if applicable." << std::endl;
2536  }
2537  }
2538  else
2539  {
2540  std::cerr << "!!! ProSHADE ERROR !!! Non-orthogonal maps are not yet supported." << std::endl;
2541 
2542  if ( settings->htmlReport )
2543  {
2544  std::stringstream hlpSS;
2545  hlpSS << "<font color=\"red\">" << "Detected non-orthogonal map. Currently, only the P1 maps are supported." << "</font>";
2546  rvapi_set_text ( hlpSS.str().c_str(),
2547  "ProgressSection",
2548  settings->htmlReportLineProgress,
2549  1,
2550  1,
2551  1 );
2552  settings->htmlReportLineProgress += 1;
2553  rvapi_flush ( );
2554  }
2555 
2556  exit ( -1 );
2557  }
2558 
2559  if ( settings->htmlReport )
2560  {
2561  std::stringstream hlpSS;
2562  hlpSS << "<font color=\"green\">" << "Structure " << settings->structFiles.at(0) << " read in." << "</font>";
2563  rvapi_set_text ( hlpSS.str().c_str(),
2564  "ProgressSection",
2565  settings->htmlReportLineProgress,
2566  1,
2567  1,
2568  1 );
2569  settings->htmlReportLineProgress += 1;
2570  rvapi_flush ( );
2571  }
2572 
2573  if ( settings->htmlReport )
2574  {
2575  rvapi_add_section ( "OrigHeaderSection",
2576  "Original structure header",
2577  "body",
2578  settings->htmlReportLine,
2579  0,
2580  1,
2581  1,
2582  false );
2583  settings->htmlReportLine += 1;
2584 
2585  //==================================== Print max U, V and W
2586  std::stringstream hlpSS;
2587  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
2588  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
2589  {
2590  hlpSS << ".";
2591  }
2592 
2593  int prec = 6;
2594  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapU+1 ), prec ).length(),
2595  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapV+1 ), prec ).length(),
2596  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapW+1 ), prec ).length() ) );
2597  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xFrom, prec ).length(),
2598  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yFrom, prec ).length(),
2599  ProSHADE_internal_misc::to_string_with_precision ( this->_zFrom, prec ).length() ) );
2600  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xTo, prec ).length(),
2601  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yTo, prec ).length(),
2602  ProSHADE_internal_misc::to_string_with_precision ( this->_zTo, prec ).length() ) );
2603  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xRange, prec ).length(),
2604  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yRange, prec ).length(),
2605  ProSHADE_internal_misc::to_string_with_precision ( this->_zRange, prec ).length() ) );
2606  int CAMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( cell[3], prec ).length(),
2607  std::max ( ProSHADE_internal_misc::to_string_with_precision ( cell[4], prec ).length(),
2608  ProSHADE_internal_misc::to_string_with_precision ( cell[5], prec ).length() ) );
2609  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, std::max ( CDMAX, CAMAX ) ) ) );
2610  if ( spacer < 5 ) { spacer = 5; }
2611 
2612  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( this->_maxMapU+1 );
2613  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapU+1 ), prec ).length() ); iter++ )
2614  {
2615  hlpSS << " ";
2616  }
2617  hlpSS << " ";
2618 
2619  hlpSS << std::showpos << static_cast<int> ( this->_maxMapV+1 );
2620  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapV+1 ), prec ).length() ); iter++ )
2621  {
2622  hlpSS << " ";
2623  }
2624  hlpSS << " ";
2625 
2626  hlpSS << std::showpos << static_cast<int> ( this->_maxMapW+1 );
2627  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapW+1 ), prec ).length() ); iter++ )
2628  {
2629  hlpSS << " ";
2630  }
2631  hlpSS << "</pre>";
2632 
2633  rvapi_set_text ( hlpSS.str().c_str(),
2634  "OrigHeaderSection",
2635  0,
2636  0,
2637  1,
2638  1 );
2639 
2640  //==================================== Print from and to lims
2641  hlpSS.str ( std::string ( ) );
2642  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
2643  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
2644  {
2645  hlpSS << ".";
2646  }
2647 
2648  hlpSS << std::showpos << std::setprecision ( prec ) << " " << this->_xFrom;
2649  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xFrom, prec ).length() ); iter++ )
2650  {
2651  hlpSS << " ";
2652  }
2653  hlpSS << " ";
2654 
2655  hlpSS << std::showpos << this->_xTo;
2656  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xTo, prec ).length() ); iter++ )
2657  {
2658  hlpSS << " ";
2659  }
2660  hlpSS << " ";
2661 
2662  hlpSS << std::showpos << this->_yFrom;
2663  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yFrom, prec ).length() ); iter++ )
2664  {
2665  hlpSS << " ";
2666  }
2667  hlpSS << " ";
2668 
2669  hlpSS << std::showpos << this->_yTo;
2670  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yTo, prec ).length() ); iter++ )
2671  {
2672  hlpSS << " ";
2673  }
2674  hlpSS << " ";
2675 
2676  hlpSS << std::showpos << " " << this->_zFrom;
2677  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zFrom, prec ).length() ); iter++ )
2678  {
2679  hlpSS << " ";
2680  }
2681  hlpSS << " ";
2682 
2683  hlpSS << std::showpos << this->_zTo;
2684  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zTo, prec ).length() ); iter++ )
2685  {
2686  hlpSS << " ";
2687  }
2688  hlpSS << "</pre>";
2689 
2690  rvapi_set_text ( hlpSS.str().c_str(),
2691  "OrigHeaderSection",
2692  1,
2693  0,
2694  1,
2695  1 );
2696 
2697  //==================================== Print cell dimensions
2698  hlpSS.str ( std::string ( ) );
2699  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
2700  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
2701  {
2702  hlpSS << ".";
2703  }
2704 
2705  hlpSS << std::showpos << std::setprecision ( prec ) << " " << this->_xRange;
2706  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xRange, prec ).length() ); iter++ )
2707  {
2708  hlpSS << " ";
2709  }
2710  hlpSS << " ";
2711 
2712  hlpSS << std::showpos << this->_yRange;
2713  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yRange, prec ).length() ); iter++ )
2714  {
2715  hlpSS << " ";
2716  }
2717  hlpSS << " ";
2718 
2719  hlpSS << std::showpos << this->_zRange;
2720  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zRange, prec ).length() ); iter++ )
2721  {
2722  hlpSS << " ";
2723  }
2724  hlpSS << "</pre>";
2725 
2726  rvapi_set_text ( hlpSS.str().c_str(),
2727  "OrigHeaderSection",
2728  2,
2729  0,
2730  1,
2731  1 );
2732 
2733  //==================================== Print cell dimensions
2734  hlpSS.str ( std::string ( ) );
2735  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
2736  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
2737  {
2738  hlpSS << ".";
2739  }
2740 
2741  hlpSS << std::showpos << std::setprecision ( prec ) << " " << cell[3];
2742  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( cell[3], prec ).length() ); iter++ )
2743  {
2744  hlpSS << " ";
2745  }
2746  hlpSS << " ";
2747 
2748  hlpSS << std::showpos << cell[4];
2749  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( cell[4], prec ).length() ); iter++ )
2750  {
2751  hlpSS << " ";
2752  }
2753  hlpSS << " ";
2754 
2755  hlpSS << std::showpos << cell[5];
2756  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( cell[5], prec ).length() ); iter++ )
2757  {
2758  hlpSS << " ";
2759  }
2760  hlpSS << "</pre>";
2761 
2762  rvapi_set_text ( hlpSS.str().c_str(),
2763  "OrigHeaderSection",
2764  3,
2765  0,
2766  1,
2767  1 );
2768 
2769  //==================================== Print cell dimensions
2770  hlpSS.str ( std::string ( ) );
2771  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
2772  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
2773  {
2774  hlpSS << ".";
2775  }
2776 
2777  if ( XYZOrder[0] == 0 ) { hlpSS << " X"; }
2778  else if ( XYZOrder[0] == 1 ) { hlpSS << " Y"; }
2779  else { hlpSS << " Z"; }
2780  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
2781  {
2782  hlpSS << " ";
2783  }
2784  hlpSS << " ";
2785 
2786  if ( XYZOrder[1] == 0 ) { hlpSS << "X"; }
2787  else if ( XYZOrder[1] == 1 ) { hlpSS << "Y"; }
2788  else { hlpSS << "Z"; }
2789  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
2790  {
2791  hlpSS << " ";
2792  }
2793  hlpSS << " ";
2794 
2795  if ( XYZOrder[2] == 0 ) { hlpSS << "X"; }
2796  else if ( XYZOrder[2] == 1 ) { hlpSS << "Y"; }
2797  else { hlpSS << "Z"; }
2798  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
2799  {
2800  hlpSS << " ";
2801  }
2802  hlpSS << "</pre>";
2803 
2804  rvapi_set_text ( hlpSS.str().c_str(),
2805  "OrigHeaderSection",
2806  4,
2807  0,
2808  1,
2809  1 );
2810 
2811  rvapi_flush ( );
2812  }
2813 
2814  //======================================== Set return values
2815  ret[0] = this->_maxMapU + 1;
2816  ret[1] = this->_maxMapV + 1;
2817  ret[2] = this->_maxMapW + 1;
2818 
2819  //======================================== Free memory
2820  if ( cell != nullptr )
2821  {
2822  free ( cell );
2823  cell = nullptr;
2824  }
2825  if ( dim != nullptr )
2826  {
2827  free ( dim );
2828  dim = nullptr;
2829  }
2830  if ( order != nullptr )
2831  {
2832  free ( order );
2833  order = nullptr;
2834  }
2835  if ( orig != nullptr )
2836  {
2837  free ( orig );
2838  orig = nullptr;
2839  }
2840 
2841  //======================================== Close the file
2842  CMap_io::ccp4_cmap_close ( mapFile );
2843 
2844  //======================================== Local hlp variables
2845  int hlpU = ( this->_maxMapU + 1 );
2846  int hlpV = ( this->_maxMapV + 1 );
2847  int hlpW = ( this->_maxMapW + 1 );
2848 
2849  //======================================== Initialise local variables for Fourier and Inverse Fourier
2850  this->_densityMapCor = new double [hlpU * hlpV * hlpW];
2851 
2852  //======================================== Load map data for Fourier
2853  std::vector<double> vals ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) );
2854 
2855  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
2856  {
2857  if ( this->_densityMapMap[iter] == this->_densityMapMap[iter] )
2858  {
2859  //================================ Map value is NOT nan
2860  this->_densityMapCor[iter] = this->_densityMapMap[iter];
2861  }
2862  else
2863  {
2864  //================================ Map value is nan - this sometimes occurs for a couple of values, I have no clue as to why...
2865  this->_densityMapCor[iter] = 0.0;
2866  }
2867  }
2868  if ( verbose > 3 )
2869  {
2870  std::cout << ">>>>> Map normalised." << std::endl;
2871  }
2872 
2873  //======================================== Map masking
2874  double *tmpMp = new double[hlpU * hlpV * hlpW];
2875  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
2876  {
2877  tmpMp[iter] = this->_densityMapCor[iter];
2878  }
2879 
2880  bool notTooManyIslads = true;
2881  double blFr = 150.0;
2882 
2883  while ( notTooManyIslads )
2884  {
2885  //================================ Do not change user values
2886  blFr += 50.0;
2887  if ( maskBlurFactorGiven )
2888  {
2889  blFr = maskBlurFactor;
2890  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
2891  break;
2892  }
2893 
2894  //================================ Compute mask and apply it
2895  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
2896 
2897  //================================ Detect islands
2898  if ( verbose > 3 )
2899  {
2900  std::cout << ">>>>>>>> Island detection started." << std::endl;
2901  }
2902 
2903  notTooManyIslads = this->removeIslands ( hlpU, hlpV, hlpW, verbose, false );
2904 
2905  if ( verbose > 3 )
2906  {
2907  std::cout << ">>>>> Map masked with factor of " << blFr << " and small islands were then removed.";
2908  }
2909  if ( notTooManyIslads )
2910  {
2911  if ( verbose > 3 )
2912  {
2913  std::cout << " However, too many islands remained. Trying higher blurring factor." << std::endl;
2914  }
2915 
2916  if ( blFr <= 500.0 )
2917  {
2918  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
2919  {
2920  this->_densityMapCor[iter] = tmpMp[iter];
2921  }
2922  }
2923  }
2924  else
2925  {
2926  if ( verbose > 3 )
2927  {
2928  std::cout << std::endl;
2929  }
2930  }
2931 
2932 
2933  if ( blFr > 500.0 )
2934  {
2935  std::cout << "!!! ProSHADE WARNING !!! Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << std::endl;
2936 
2937  if ( settings->htmlReport )
2938  {
2939  std::stringstream hlpSS;
2940  hlpSS << "<font color=\"orange\">" << "Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << "</font>";
2941  rvapi_set_text ( hlpSS.str().c_str(),
2942  "ProgressSection",
2943  settings->htmlReportLineProgress,
2944  1,
2945  1,
2946  1 );
2947  settings->htmlReportLineProgress += 1;
2948  rvapi_flush ( );
2949  }
2950 
2951  break;
2952  }
2953  }
2954 
2955  //======================================== Once values are decided, run then WITHOUT the island detection
2956  if ( !maskBlurFactorGiven )
2957  {
2958  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
2959  {
2960  this->_densityMapCor[iter] = tmpMp[iter];
2961  }
2962 
2963  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
2964  }
2965 
2966  if ( verbose > 2 )
2967  {
2968  std::cout << ">> Map masked." << std::endl;
2969  }
2970 
2971  if ( settings->htmlReport )
2972  {
2973  std::stringstream hlpSS;
2974  hlpSS << "<font color=\"green\">" << "Map masked." << "</font>";
2975  rvapi_set_text ( hlpSS.str().c_str(),
2976  "ProgressSection",
2977  settings->htmlReportLineProgress,
2978  1,
2979  1,
2980  1 );
2981  settings->htmlReportLineProgress += 1;
2982  rvapi_flush ( );
2983  }
2984 
2985  //======================================== Determine the real size of the shape
2986  int coordPos = 0;
2987  int maxX = hlpU/2;
2988  int minX = hlpU/2;
2989  int maxY = hlpV/2;
2990  int minY = hlpV/2;
2991  int maxZ = hlpW/2;
2992  int minZ = hlpW/2;
2993  int maxXTot = hlpU/2;
2994  int minXTot = hlpU/2;
2995  int maxYTot = hlpV/2;
2996  int minYTot = hlpV/2;
2997  int maxZTot = hlpW/2;
2998  int minZTot = hlpW/2;
2999 
3000  for ( int uIt = 0; uIt < hlpU; uIt++ )
3001  {
3002  for ( int vIt = 0; vIt < hlpV; vIt++ )
3003  {
3004  for ( int wIt = 0; wIt < hlpW; wIt++ )
3005  {
3006  coordPos = wIt + hlpW * ( vIt + hlpV * uIt );
3007 
3008  if ( this->_densityMapCor[coordPos] > 0.0 )
3009  {
3010  maxX = std::max ( maxX, uIt );
3011  minX = std::min ( minX, uIt );
3012  maxY = std::max ( maxY, vIt );
3013  minY = std::min ( minY, vIt );
3014  maxZ = std::max ( maxZ, wIt );
3015  minZ = std::min ( minZ, wIt );
3016  }
3017  maxXTot = std::max ( maxXTot, uIt );
3018  minXTot = std::min ( minXTot, uIt );
3019  maxYTot = std::max ( maxYTot, vIt );
3020  minYTot = std::min ( minYTot, vIt );
3021  maxZTot = std::max ( maxZTot, wIt );
3022  minZTot = std::min ( minZTot, wIt );
3023  }
3024  }
3025  }
3026 
3027  //======================================== Calculate the grid for only the shape
3028  int newUStart = static_cast<int> ( this->_xFrom + ( minXTot + minX ) );
3029  int newUEnd = static_cast<int> ( this->_xTo - ( maxXTot - maxX ) );
3030  int newVStart = static_cast<int> ( this->_yFrom + ( minYTot + minY ) );
3031  int newVEnd = static_cast<int> ( this->_yTo - ( maxYTot - maxY ) );
3032  int newWStart = static_cast<int> ( this->_zFrom + ( minZTot + minZ ) );
3033  int newWEnd = static_cast<int> ( this->_zTo - ( maxZTot - maxZ ) );
3034 
3035  //======================================== Add the extra space
3036  if ( this->_maxExtraCellularSpace > 0.0 )
3037  {
3038  int extraPTs = static_cast<int> ( std::ceil ( this->_maxExtraCellularSpace / ( static_cast<double> ( this->_maxMapRange ) / static_cast<double> ( std::max ( hlpU, std::max ( hlpV, hlpW ) ) ) ) ) );
3039 
3040  if ( (newUStart - extraPTs) > static_cast<int> ( this->_xFrom ) ) { newUStart -= static_cast<int> ( extraPTs ); }
3041  if ( (newVStart - extraPTs) > static_cast<int> ( this->_yFrom ) ) { newVStart -= static_cast<int> ( extraPTs ); }
3042  if ( (newWStart - extraPTs) > static_cast<int> ( this->_zFrom ) ) { newWStart -= static_cast<int> ( extraPTs ); }
3043  if ( (newUEnd + extraPTs) < static_cast<int> ( this->_xTo ) ) { newUEnd += static_cast<int> ( extraPTs ); }
3044  if ( (newVEnd + extraPTs) < static_cast<int> ( this->_yTo ) ) { newVEnd += static_cast<int> ( extraPTs ); }
3045  if ( (newWEnd + extraPTs) < static_cast<int> ( this->_zTo ) ) { newWEnd += static_cast<int> ( extraPTs ); }
3046  }
3047 
3048  //======================================== Free unnecessary memory
3049  if ( this->_densityMapCor != nullptr )
3050  {
3051  delete[] this->_densityMapCor;
3052  this->_densityMapCor = nullptr;
3053  }
3054 
3055  //======================================== Move map
3056  int newXDim = newUEnd - newUStart + 1;
3057  int newYDim = newVEnd - newVStart + 1;
3058  int newZDim = newWEnd - newWStart + 1;
3059 
3060  if ( ( this->_xFrom < 0 ) && ( ( this->_xFrom + newUStart ) >= 0 ) ) { newXDim += 1; }
3061  if ( ( this->_yFrom < 0 ) && ( ( this->_yFrom + newVStart ) >= 0 ) ) { newYDim += 1; }
3062  if ( ( this->_zFrom < 0 ) && ( ( this->_zFrom + newWStart ) >= 0 ) ) { newZDim += 1; }
3063 
3064  this->_densityMapCor = new double [newXDim * newYDim * newZDim];
3065 
3066  int arrPos, hlpPos;
3067  int newU, newV, newW;
3068  for ( int uIt = newUStart; uIt <= newUEnd; uIt++ )
3069  {
3070  for ( int vIt = newVStart; vIt <= newVEnd; vIt++ )
3071  {
3072  for ( int wIt = newWStart; wIt <= newWEnd; wIt++ )
3073  {
3074  newU = uIt - newUStart;
3075  newV = vIt - newVStart;
3076  newW = wIt - newWStart;
3077  hlpPos = newW + newZDim * ( newV + newYDim * newU );
3078 
3079  newU = uIt - this->_xFrom;
3080  newV = vIt - this->_yFrom;
3081  newW = wIt - this->_zFrom;
3082  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
3083 
3084  this->_densityMapCor[hlpPos] = tmpMp[arrPos];
3085  }
3086  }
3087  }
3088 
3089  if ( verbose > 0 )
3090  {
3091  std::cout << "Map re-boxed." << std::endl;
3092  }
3093 
3094  if ( settings->htmlReport )
3095  {
3096  std::stringstream hlpSS;
3097  hlpSS << "<font color=\"green\">" << "Map re-boxed." << "</font>";
3098  rvapi_set_text ( hlpSS.str().c_str(),
3099  "ProgressSection",
3100  settings->htmlReportLineProgress,
3101  1,
3102  1,
3103  1 );
3104  settings->htmlReportLineProgress += 1;
3105  rvapi_flush ( );
3106  }
3107 
3108  //======================================== Clear memory
3109  delete[] tmpMp;
3110 
3111  //======================================== Change the settings
3112  this->_xFrom = newUStart;
3113  this->_yFrom = newVStart;
3114  this->_zFrom = newWStart;
3115 
3116  this->_xTo = newUEnd;
3117  this->_yTo = newVEnd;
3118  this->_zTo = newWEnd;
3119 
3120  this->_xSamplingRate = static_cast<double> ( this->_xRange ) / static_cast<double> ( hlpU );
3121  this->_ySamplingRate = static_cast<double> ( this->_yRange ) / static_cast<double> ( hlpV );
3122  this->_zSamplingRate = static_cast<double> ( this->_zRange ) / static_cast<double> ( hlpW );
3123 
3124  this->_xRange = this->_xSamplingRate * ( newXDim );
3125  this->_yRange = this->_ySamplingRate * ( newYDim );
3126  this->_zRange = this->_zSamplingRate * ( newZDim );
3127 
3128  this->_maxMapU = newXDim - 1;
3129  this->_maxMapV = newYDim - 1;
3130  this->_maxMapW = newZDim - 1;
3131 
3132  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
3133  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
3134  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
3135 
3136  //======================================== Free unnecessary memory
3137  if ( this->_densityMapMap != nullptr )
3138  {
3139  delete this->_densityMapMap;
3140  this->_densityMapMap = nullptr;
3141  }
3142 
3143  //======================================== Report the new structure header
3144  if ( settings->htmlReport )
3145  {
3146  rvapi_add_section ( "NewHeaderSection",
3147  "Re-boxed structure header",
3148  "body",
3149  settings->htmlReportLine,
3150  0,
3151  1,
3152  1,
3153  false );
3154  settings->htmlReportLine += 1;
3155 
3156  //==================================== Print max U, V and W
3157  std::stringstream hlpSS;
3158  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
3159  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
3160  {
3161  hlpSS << ".";
3162  }
3163 
3164  int prec = 6;
3165  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapU+1 ), prec ).length(),
3166  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapV+1 ), prec ).length(),
3167  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapW+1 ), prec ).length() ) );
3168  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xFrom, prec ).length(),
3169  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yFrom, prec ).length(),
3170  ProSHADE_internal_misc::to_string_with_precision ( this->_zFrom, prec ).length() ) );
3171  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xTo, prec ).length(),
3172  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yTo, prec ).length(),
3173  ProSHADE_internal_misc::to_string_with_precision ( this->_zTo, prec ).length() ) );
3174  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_xRange, prec ).length(),
3175  std::max ( ProSHADE_internal_misc::to_string_with_precision ( this->_yRange, prec ).length(),
3176  ProSHADE_internal_misc::to_string_with_precision ( this->_zRange, prec ).length() ) );
3177  int CAMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length(),
3178  std::max ( ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length(),
3179  ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length() ) );
3180  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, std::max ( CDMAX, CAMAX ) ) ) );
3181  if ( spacer < 5 ) { spacer = 5; }
3182 
3183  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( this->_maxMapU+1 );
3184  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapU+1 ), prec ).length() ); iter++ )
3185  {
3186  hlpSS << " ";
3187  }
3188  hlpSS << " ";
3189 
3190  hlpSS << std::showpos << static_cast<int> ( this->_maxMapV+1 );
3191  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapV+1 ), prec ).length() ); iter++ )
3192  {
3193  hlpSS << " ";
3194  }
3195  hlpSS << " ";
3196 
3197  hlpSS << std::showpos << static_cast<int> ( this->_maxMapW+1 );
3198  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( this->_maxMapW+1 ), prec ).length() ); iter++ )
3199  {
3200  hlpSS << " ";
3201  }
3202  hlpSS << "</pre>";
3203 
3204  rvapi_set_text ( hlpSS.str().c_str(),
3205  "NewHeaderSection",
3206  0,
3207  0,
3208  1,
3209  1 );
3210 
3211  //==================================== Print from and to lims
3212  hlpSS.str ( std::string ( ) );
3213  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
3214  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
3215  {
3216  hlpSS << ".";
3217  }
3218 
3219  hlpSS << std::showpos << std::setprecision ( prec ) << " " << this->_xFrom;
3220  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xFrom, prec ).length() ); iter++ )
3221  {
3222  hlpSS << " ";
3223  }
3224  hlpSS << " ";
3225 
3226  hlpSS << std::showpos << this->_xTo;
3227  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xTo, prec ).length() ); iter++ )
3228  {
3229  hlpSS << " ";
3230  }
3231  hlpSS << " ";
3232 
3233  hlpSS << std::showpos << this->_yFrom;
3234  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yFrom, prec ).length() ); iter++ )
3235  {
3236  hlpSS << " ";
3237  }
3238  hlpSS << " ";
3239 
3240  hlpSS << std::showpos << this->_yTo;
3241  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yTo, prec ).length() ); iter++ )
3242  {
3243  hlpSS << " ";
3244  }
3245  hlpSS << " ";
3246 
3247  hlpSS << std::showpos << " " << this->_zFrom;
3248  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zFrom, prec ).length() ); iter++ )
3249  {
3250  hlpSS << " ";
3251  }
3252  hlpSS << " ";
3253 
3254  hlpSS << std::showpos << this->_zTo;
3255  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zTo, prec ).length() ); iter++ )
3256  {
3257  hlpSS << " ";
3258  }
3259  hlpSS << "</pre>";
3260 
3261  rvapi_set_text ( hlpSS.str().c_str(),
3262  "NewHeaderSection",
3263  1,
3264  0,
3265  1,
3266  1 );
3267 
3268  //==================================== Print cell dimensions
3269  hlpSS.str ( std::string ( ) );
3270  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
3271  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
3272  {
3273  hlpSS << ".";
3274  }
3275 
3276  hlpSS << std::showpos << std::setprecision ( prec ) << " " << this->_xRange;
3277  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_xRange, prec ).length() ); iter++ )
3278  {
3279  hlpSS << " ";
3280  }
3281  hlpSS << " ";
3282 
3283  hlpSS << std::showpos << this->_yRange;
3284  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_yRange, prec ).length() ); iter++ )
3285  {
3286  hlpSS << " ";
3287  }
3288  hlpSS << " ";
3289 
3290  hlpSS << std::showpos << this->_zRange;
3291  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( this->_zRange, prec ).length() ); iter++ )
3292  {
3293  hlpSS << " ";
3294  }
3295  hlpSS << "</pre>";
3296 
3297  rvapi_set_text ( hlpSS.str().c_str(),
3298  "NewHeaderSection",
3299  2,
3300  0,
3301  1,
3302  1 );
3303 
3304  //==================================== Print cell dimensions
3305  hlpSS.str ( std::string ( ) );
3306  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
3307  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
3308  {
3309  hlpSS << ".";
3310  }
3311 
3312  hlpSS << std::showpos << std::setprecision ( prec ) << " " << 90.000;
3313  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length() ); iter++ )
3314  {
3315  hlpSS << " ";
3316  }
3317  hlpSS << " ";
3318 
3319  hlpSS << std::showpos << 90.000;
3320  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length() ); iter++ )
3321  {
3322  hlpSS << " ";
3323  }
3324  hlpSS << " ";
3325 
3326  hlpSS << std::showpos << 90.000;
3327  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.000, prec ).length() ); iter++ )
3328  {
3329  hlpSS << " ";
3330  }
3331  hlpSS << "</pre>";
3332 
3333  rvapi_set_text ( hlpSS.str().c_str(),
3334  "NewHeaderSection",
3335  3,
3336  0,
3337  1,
3338  1 );
3339 
3340  //==================================== Print cell dimensions
3341  hlpSS.str ( std::string ( ) );
3342  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
3343  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
3344  {
3345  hlpSS << ".";
3346  }
3347 
3348  if ( XYZOrder[0] == 0 ) { hlpSS << " X"; }
3349  else if ( XYZOrder[0] == 1 ) { hlpSS << " Y"; }
3350  else { hlpSS << " Z"; }
3351  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
3352  {
3353  hlpSS << " ";
3354  }
3355  hlpSS << " ";
3356 
3357  if ( XYZOrder[1] == 0 ) { hlpSS << "X"; }
3358  else if ( XYZOrder[1] == 1 ) { hlpSS << "Y"; }
3359  else { hlpSS << "Z"; }
3360  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
3361  {
3362  hlpSS << " ";
3363  }
3364  hlpSS << " ";
3365 
3366  if ( XYZOrder[2] == 0 ) { hlpSS << "X"; }
3367  else if ( XYZOrder[2] == 1 ) { hlpSS << "Y"; }
3368  else { hlpSS << "Z"; }
3369  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
3370  {
3371  hlpSS << " ";
3372  }
3373  hlpSS << "</pre>";
3374 
3375  rvapi_set_text ( hlpSS.str().c_str(),
3376  "NewHeaderSection",
3377  4,
3378  0,
3379  1,
3380  1 );
3381 
3382  rvapi_flush ( );
3383  }
3384 
3385  //======================================== Set return values
3386  ret[3] = this->_maxMapU + 1;
3387  ret[4] = this->_maxMapV + 1;
3388  ret[5] = this->_maxMapW + 1;
3389 
3390  //======================================== Done
3391  return ( ret );
3392 }
3393 
3429  double *minDensPreNorm,
3430  double *maxDensPreNorm,
3431  double *minDensPostNorm,
3432  double *maxDensPostNorm,
3433  double *postNormMean,
3434  double *postNormSdev,
3435  double *maskVolume,
3436  double* totalVolume,
3437  double *maskMean,
3438  double *maskSdev,
3439  double *maskMin,
3440  double *maskMax,
3441  double *maskDensityRMS,
3442  double *allDensityRMS,
3443  std::array<double,3> *origRanges,
3444  std::array<double,3> *origDims,
3445  double maxMapIQR,
3446  double extraCS,
3447  int verbose,
3448  bool useCubicMaps,
3449  double maskBlurFactor,
3450  bool maskBlurFactorGiven,
3451  bool reboxAtAll,
3452  ProSHADE::ProSHADE_settings* settings )
3453 {
3454  //======================================== Initialise internal values
3455  this->_inputFileName = fileName;
3456 
3457  //======================================== Initialise local variables
3458  CMap_io::CMMFile *mapFile = nullptr;
3459  float *cell = nullptr;
3460  int *dim = nullptr;
3461  int *order = nullptr;
3462  int *orig = nullptr;
3463  int myMapMode = 0;
3464  double cornerAvg = 0.0;
3465  double centralAvg = 0.0;
3466  double cornerCount = 0.0;
3467  double centralCount = 0.0;
3468 
3469  //======================================== Allocate memory
3470  cell = (float*) malloc ( 6 * sizeof ( float ) );
3471  dim = (int* ) malloc ( 3 * sizeof ( int ) );
3472  order = (int* ) malloc ( 3 * sizeof ( int ) );
3473  orig = (int* ) malloc ( 3 * sizeof ( int ) );
3474 
3475  if ( ( cell == nullptr ) || ( dim == nullptr ) || ( order == nullptr ) || ( orig == nullptr ) )
3476  {
3477  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory. Terminating... " << std::endl;
3478 
3479  if ( settings->htmlReport )
3480  {
3481  std::stringstream hlpSS;
3482  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
3483  rvapi_set_text ( hlpSS.str().c_str(),
3484  "ProgressSection",
3485  settings->htmlReportLineProgress,
3486  1,
3487  1,
3488  1 );
3489  settings->htmlReportLineProgress += 1;
3490  rvapi_flush ( );
3491  }
3492 
3493  exit ( -1 );
3494  }
3495 
3496  //======================================== Read in the MAP file info
3497  mapFile = reinterpret_cast<CMap_io::CMMFile*> ( CMap_io::ccp4_cmap_open ( fileName.c_str() , myMapMode ) );
3498  if ( mapFile == nullptr )
3499  {
3500  std::cerr << "!!! ProSHADE ERROR !!! Failed to open the file " << fileName << ". Check for typos and curruption of the file. Terminating..." << std::endl;
3501 
3502  if ( settings->htmlReport )
3503  {
3504  std::stringstream hlpSS;
3505  hlpSS << "<font color=\"red\">" << "Cannot open file " << fileName << ".</font>";
3506  rvapi_set_text ( hlpSS.str().c_str(),
3507  "ProgressSection",
3508  settings->htmlReportLineProgress,
3509  1,
3510  1,
3511  1 );
3512  settings->htmlReportLineProgress += 1;
3513  rvapi_flush ( );
3514  }
3515 
3516  exit ( -1 );
3517  }
3518 
3519  CMap_io::ccp4_cmap_get_cell ( mapFile, cell );
3520  CMap_io::ccp4_cmap_get_dim ( mapFile, dim );
3521  CMap_io::ccp4_cmap_get_order ( mapFile, order );
3522  CMap_io::ccp4_cmap_get_origin ( mapFile, orig );
3523 
3524 
3525  if ( verbose > 2 )
3526  {
3527  std::cout << ">> Map loaded." << std::endl;
3528  }
3529 
3530  //======================================== If CUBIC
3531  if ( ( ( cell[3] < (90.0 + 0.1) ) && ( cell[3] > (90.0 - 0.1) ) ) &&
3532  ( ( cell[4] < (90.0 + 0.1) ) && ( cell[4] > (90.0 - 0.1) ) ) &&
3533  ( ( cell[5] < (90.0 + 0.1) ) && ( cell[5] > (90.0 - 0.1) ) ) )
3534  {
3535  //==================================== Determine/Save dimmensions
3536  this->_xRange = cell[0];
3537  this->_yRange = cell[1];
3538  this->_zRange = cell[2];
3539 
3540  //==================================== Maximal cell dimensions
3541  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
3542 
3543  //==================================== Find max U, V and W
3544  if ( order[0] == 1 ) { this->_maxMapU = dim[0] - 1; this->_xFrom = orig[0]; }
3545  if ( order[0] == 2 ) { this->_maxMapU = dim[1] - 1; this->_yFrom = orig[0]; }
3546  if ( order[0] == 3 ) { this->_maxMapU = dim[2] - 1; this->_zFrom = orig[0]; }
3547 
3548  if ( order[1] == 1 ) { this->_maxMapV = dim[0] - 1; this->_xFrom = orig[1]; }
3549  if ( order[1] == 2 ) { this->_maxMapV = dim[1] - 1; this->_yFrom = orig[1]; }
3550  if ( order[1] == 3 ) { this->_maxMapV = dim[2] - 1; this->_zFrom = orig[1]; }
3551 
3552  if ( order[2] == 1 ) { this->_maxMapW = dim[0] - 1; this->_xFrom = orig[2]; }
3553  if ( order[2] == 2 ) { this->_maxMapW = dim[1] - 1; this->_yFrom = orig[2]; }
3554  if ( order[2] == 3 ) { this->_maxMapW = dim[2] - 1; this->_zFrom = orig[2]; }
3555 
3556  //==================================== Get the map start and end
3557  this->_xTo = this->_xFrom + this->_maxMapU;
3558  this->_yTo = this->_yFrom + this->_maxMapV;
3559  this->_zTo = this->_zFrom + this->_maxMapW;
3560 
3561  //==================================== Allocate map data memory
3562  this->_densityMapMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
3563  if ( this->_densityMapMap == nullptr )
3564  {
3565  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
3566 
3567  if ( settings->htmlReport )
3568  {
3569  std::stringstream hlpSS;
3570  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
3571  rvapi_set_text ( hlpSS.str().c_str(),
3572  "ProgressSection",
3573  settings->htmlReportLineProgress,
3574  1,
3575  1,
3576  1 );
3577  settings->htmlReportLineProgress += 1;
3578  rvapi_flush ( );
3579  }
3580 
3581  exit ( -1 );
3582  }
3583 
3584  //==================================== Check if the mode is compatible
3585  int mapMode = CMap_io::ccp4_cmap_get_datamode ( mapFile );
3586  if ( ( mapMode != 0 ) && ( mapMode != 2 ) )
3587  {
3588  std::cerr << "!!! ProSHADE ERROR !!! Cannot read from the map file. The map file mode is not supported. Terminating..." << std::endl;
3589 
3590  if ( settings->htmlReport )
3591  {
3592  std::stringstream hlpSS;
3593  hlpSS << "<font color=\"red\">" << "Cannot read from the map file. The map mode is neither 0, nor 2. Other map modes are currently not supported." << "</font>";
3594  rvapi_set_text ( hlpSS.str().c_str(),
3595  "ProgressSection",
3596  settings->htmlReportLineProgress,
3597  1,
3598  1,
3599  1 );
3600  settings->htmlReportLineProgress += 1;
3601  rvapi_flush ( );
3602  }
3603 
3604  exit ( -1 );
3605  }
3606 
3607  //==================================== Read in map data
3608  // ... Find the stop positions (start is in orig variables) and the axis order
3609  int maxLim[3];
3610  int XYZOrder[3];
3611  int newU, newV, newW;
3612  int arrPos;
3613 
3614  for ( int iter = 0; iter < 3; iter++ )
3615  {
3616  maxLim[iter] = orig[iter] + dim[iter] - 1;
3617  XYZOrder[order[iter]-1] = iter;
3618  }
3619 
3620  // ... Solve the dimensions and sizes
3621  int fastDimSize = ( maxLim[0] - orig[0] + 1 );
3622  int midDimSize = ( maxLim[1] - orig[1] + 1 ) * fastDimSize;
3623  std::vector<float> section( midDimSize );
3624  int index;
3625  int iters[3];
3626 
3627  // ... Read in the map data
3628  for ( iters[2] = orig[2]; iters[2] <= maxLim[2]; iters[2]++ )
3629  {
3630  index = 0;
3631  CMap_io::ccp4_cmap_read_section( mapFile, &section[0] );
3632 
3633  if ( mapMode == 0 )
3634  {
3635  for ( int iter = ( midDimSize - 1 ); iter >= 0; iter-- )
3636  {
3637  section[iter] = static_cast<float> ( ( reinterpret_cast<unsigned char*> (&section[0]) )[iter] );
3638  }
3639  }
3640 
3641  for ( iters[1] = orig[1]; iters[1] <= maxLim[1]; iters[1]++ )
3642  {
3643  for ( iters[0] = orig[0]; iters[0] <= maxLim[0]; iters[0]++ )
3644  {
3645  newU = iters[XYZOrder[0]] - orig[XYZOrder[0]];
3646  newV = iters[XYZOrder[1]] - orig[XYZOrder[1]];
3647  newW = iters[XYZOrder[2]] - orig[XYZOrder[2]];
3648  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
3649  this->_densityMapMap[arrPos] = static_cast<float> ( section[ index++ ] );
3650  }
3651  }
3652  }
3653 
3654  //==================================== Get values for normalisation
3655  std::vector<double> vals;
3656  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
3657  {
3658  if ( this->_densityMapMap[iter] != 0.0 )
3659  {
3660  vals.emplace_back ( this->_densityMapMap[iter] );
3661  }
3662  }
3663  std::sort ( vals.begin(), vals.end() );
3664 
3665  *minDensPreNorm = vals.at(0);
3666  *maxDensPreNorm = vals.at(vals.size()-1);
3667 
3668  //==================================== Create results section
3669  if ( settings->htmlReport )
3670  {
3671  //==================================== Create section
3672  rvapi_add_section ( "ResultsSection",
3673  "Results",
3674  "body",
3675  settings->htmlReportLine,
3676  0,
3677  1,
3678  1,
3679  true );
3680  settings->htmlReportLine += 1;
3681 
3682  std::stringstream hlpSS;
3683  hlpSS << "<pre>" << "Min / Max density pre normalisation: ";
3684  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
3685  for ( int iter = 0; iter < hlpIt; iter++ )
3686  {
3687  hlpSS << ".";
3688  }
3689 
3690  std::stringstream hlpSS2;
3691  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *minDensPreNorm * 1000.0 ) / 1000.0;
3692  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
3693  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
3694  hlpSS << " " << hlpSS2.str() << " / ";
3695 
3696  hlpSS2.str( std::string ( ) );
3697  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maxDensPreNorm * 1000.0 ) / 1000.0;
3698  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
3699  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
3700  hlpSS << hlpSS2.str() << "</pre>";
3701 
3702  rvapi_set_text ( hlpSS.str().c_str(),
3703  "ResultsSection",
3704  0,
3705  1,
3706  1,
3707  1 );
3708 
3709  rvapi_flush ( );
3710  }
3711 
3712  //==================================== Find mean and standard deviation for later normalisation
3713  this->_mapMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
3714  this->_mapSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - this->_mapMean * this->_mapMean );
3715  vals.clear ( );
3716 
3717  //==================================== Check if the map is not absolutely de-centered
3718  int noPToCheckU = static_cast<unsigned int> ( this->_maxMapU / 8.0 );
3719  int noPToCheckV = static_cast<unsigned int> ( this->_maxMapV / 8.0 );
3720  int noPToCheckW = static_cast<unsigned int> ( this->_maxMapW / 8.0 );
3721 
3722  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
3723  {
3724  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
3725  {
3726  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
3727  {
3728  //======================== Initialisation
3729  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
3730 
3731  //======================== Check to which quadrant the value belongs to
3732  if ( ( ( uIt <= static_cast<int> ( this->_maxMapU/2 + noPToCheckU ) ) && ( uIt >= static_cast<int> ( this->_maxMapU/2 - noPToCheckU ) ) ) &&
3733  ( ( vIt <= static_cast<int> ( this->_maxMapV/2 + noPToCheckV ) ) && ( vIt >= static_cast<int> ( this->_maxMapV/2 - noPToCheckV ) ) ) &&
3734  ( ( wIt <= static_cast<int> ( this->_maxMapW/2 + noPToCheckW ) ) && ( wIt >= static_cast<int> ( this->_maxMapW/2 - noPToCheckW ) ) ) )
3735  {
3736  centralAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
3737  centralCount += 1.0;
3738  }
3739  if ( ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
3740  ( ( uIt < noPToCheckU ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
3741  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
3742  ( ( uIt < noPToCheckU ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
3743  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt < noPToCheckW ) ) ||
3744  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt < noPToCheckV ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) ||
3745  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt < noPToCheckW ) ) ||
3746  ( ( uIt > static_cast<int> (this->_maxMapU-noPToCheckU) ) && ( vIt > static_cast<int> (this->_maxMapV-noPToCheckV) ) && ( wIt > static_cast<int> (this->_maxMapW-noPToCheckW) ) ) )
3747  {
3748  cornerAvg += std::max ( this->_densityMapMap[arrPos], static_cast<float>(0.0) );
3749  cornerCount += 1.0;
3750  }
3751  }
3752  }
3753  }
3754 
3755  cornerAvg /= cornerCount;
3756  centralAvg /= centralCount;
3757 
3758  //==================================== If density is in the corners
3759  if ( cornerAvg > centralAvg )
3760  {
3761  //================================ Initialise required variables
3762  float* hlpMap = nullptr;
3763  hlpMap = (float*) malloc ( (dim[0]*dim[1]*dim[2]) * sizeof ( float ) );
3764  if ( hlpMap == nullptr )
3765  {
3766  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
3767 
3768  if ( settings->htmlReport )
3769  {
3770  std::stringstream hlpSS;
3771  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
3772  rvapi_set_text ( hlpSS.str().c_str(),
3773  "ProgressSection",
3774  settings->htmlReportLineProgress,
3775  1,
3776  1,
3777  1 );
3778  settings->htmlReportLineProgress += 1;
3779  rvapi_flush ( );
3780  }
3781 
3782  exit ( -1 );
3783  }
3784  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( dim[0] * dim[1] * dim[2] ); iter++ )
3785  {
3786  hlpMap[iter] = this->_densityMapMap[iter];
3787  }
3788 
3789  //================================ Transform
3790  unsigned int hlpPos;
3791  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
3792  {
3793  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
3794  {
3795  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
3796  {
3797  //==================== If in lower half, add half; if in upper halp, subtract half
3798  if ( uIt < static_cast<int> (this->_maxMapU+1)/2 ) { newU = uIt + (this->_maxMapU+1)/2; } else { newU = uIt - (this->_maxMapU+1)/2; }
3799  if ( vIt < static_cast<int> (this->_maxMapV+1)/2 ) { newV = vIt + (this->_maxMapV+1)/2; } else { newV = vIt - (this->_maxMapV+1)/2; }
3800  if ( wIt < static_cast<int> (this->_maxMapW+1)/2 ) { newW = wIt + (this->_maxMapW+1)/2; } else { newW = wIt - (this->_maxMapW+1)/2; }
3801 
3802  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
3803  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
3804 
3805  //==================== Set the value into correct coords in the new map
3806  this->_densityMapMap[arrPos] = hlpMap[hlpPos];
3807  }
3808  }
3809  }
3810 
3811  //================================ Free memory
3812  free ( hlpMap );
3813  }
3814 
3815  if ( verbose > 3 )
3816  {
3817  std::cout << ">>>>> Density moved from corners to center, if applicable." << std::endl;
3818  }
3819  }
3820  else
3821  {
3822  std::cerr << "!!! ProSHADE ERROR !!! Non-orthogonal maps are not yet supported." << std::endl;
3823 
3824  if ( settings->htmlReport )
3825  {
3826  std::stringstream hlpSS;
3827  hlpSS << "<font color=\"red\">" << "Detected non-orthogonal map. Currently, only the P1 maps are supported." << "</font>";
3828  rvapi_set_text ( hlpSS.str().c_str(),
3829  "ProgressSection",
3830  settings->htmlReportLineProgress,
3831  1,
3832  1,
3833  1 );
3834  settings->htmlReportLineProgress += 1;
3835  rvapi_flush ( );
3836  }
3837 
3838  exit ( -1 );
3839  }
3840 
3841  if ( settings->htmlReport )
3842  {
3843  std::stringstream hlpSS;
3844  hlpSS << "<font color=\"green\">" << "Structure " << fileName << " read." << "</font>";
3845  rvapi_set_text ( hlpSS.str().c_str(),
3846  "ProgressSection",
3847  settings->htmlReportLineProgress,
3848  1,
3849  1,
3850  1 );
3851  settings->htmlReportLineProgress += 1;
3852  rvapi_flush ( );
3853  }
3854 
3855  //======================================== Free memory
3856  if ( cell != nullptr )
3857  {
3858  free ( cell );
3859  cell = nullptr;
3860  }
3861  if ( dim != nullptr )
3862  {
3863  free ( dim );
3864  dim = nullptr;
3865  }
3866  if ( order != nullptr )
3867  {
3868  free ( order );
3869  order = nullptr;
3870  }
3871  if ( orig != nullptr )
3872  {
3873  free ( orig );
3874  orig = nullptr;
3875  }
3876 
3877  //======================================== Close the file
3878  CMap_io::ccp4_cmap_close ( mapFile );
3879 
3880  //======================================== Determine sampling ranges
3881  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
3882  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
3883  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
3884 
3885  bool addXOne = false;
3886  bool addYOne = false;
3887  bool addZOne = false;
3888 
3889  //======================================== Save ranges and dims
3890  (*origRanges)[0] = this->_xRange;
3891  (*origRanges)[1] = this->_yRange;
3892  (*origRanges)[2] = this->_zRange;
3893 
3894  (*origDims)[0] = this->_maxMapU;
3895  (*origDims)[1] = this->_maxMapV;
3896  (*origDims)[2] = this->_maxMapW;
3897 
3898  //======================================== If extra cell space is given, apply
3899  this->_maxExtraCellularSpace = extraCS;
3900  if ( this->_maxExtraCellularSpace != 0.0 )
3901  {
3902  //==================================== Compute new stats
3903  int xDiff = static_cast<int> ( std::ceil ( ( this->_xRange + this->_maxExtraCellularSpace ) / this->_xSamplingRate ) - this->_maxMapU );
3904  int yDiff = static_cast<int> ( std::ceil ( ( this->_yRange + this->_maxExtraCellularSpace ) / this->_ySamplingRate ) - this->_maxMapV );
3905  int zDiff = static_cast<int> ( std::ceil ( ( this->_zRange + this->_maxExtraCellularSpace ) / this->_zSamplingRate ) - this->_maxMapW );
3906 
3907  if ( ( this->_xFrom >= 0 ) && ( ( this->_xFrom - xDiff ) < 0 ) ) { addXOne = true; }
3908  if ( ( this->_yFrom >= 0 ) && ( ( this->_yFrom - yDiff ) < 0 ) ) { addYOne = true; }
3909  if ( ( this->_zFrom >= 0 ) && ( ( this->_zFrom - zDiff ) < 0 ) ) { addZOne = true; }
3910 
3911  this->_xRange += xDiff * this->_xSamplingRate;
3912  this->_yRange += yDiff * this->_ySamplingRate;
3913  this->_zRange += zDiff * this->_zSamplingRate;
3914 
3915  if ( xDiff % 2 != 0 )
3916  {
3917  this->_xRange += this->_xSamplingRate;
3918  xDiff = static_cast<int> ( std::ceil ( this->_xRange / this->_xSamplingRate ) - ( this->_maxMapU + 1 ) );
3919  }
3920  if ( yDiff % 2 != 0 )
3921  {
3922  this->_yRange += this->_ySamplingRate;
3923  yDiff = static_cast<int> ( std::ceil ( this->_yRange / this->_ySamplingRate ) - ( this->_maxMapV + 1 ) );
3924  }
3925  if ( zDiff % 2 != 0 )
3926  {
3927  this->_zRange += this->_zSamplingRate;
3928  zDiff = static_cast<int> ( std::ceil ( this->_zRange / this->_zSamplingRate ) - ( this->_maxMapW + 1 ) );
3929  }
3930 
3931  xDiff /= 2;
3932  yDiff /= 2;
3933  zDiff /= 2;
3934 
3935  this->_xFrom -= xDiff;
3936  this->_yFrom -= yDiff;
3937  this->_zFrom -= zDiff;
3938 
3939  this->_xTo += xDiff;
3940  this->_yTo += yDiff;
3941  this->_zTo += zDiff;
3942 
3943  this->_maxMapU = this->_xTo - this->_xFrom;
3944  this->_maxMapV = this->_yTo - this->_yFrom;
3945  this->_maxMapW = this->_zTo - this->_zFrom;
3946 
3947  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
3948  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
3949  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
3950 
3951  //==================================== Move the map
3952  float *hlpMap = nullptr;
3953  hlpMap = (float*) malloc ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) * sizeof ( float ) );
3954  if ( hlpMap == nullptr )
3955  {
3956  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map moving data. Terminating... " << std::endl;
3957 
3958  if ( settings->htmlReport )
3959  {
3960  std::stringstream hlpSS;
3961  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
3962  rvapi_set_text ( hlpSS.str().c_str(),
3963  "ProgressSection",
3964  settings->htmlReportLineProgress,
3965  1,
3966  1,
3967  1 );
3968  settings->htmlReportLineProgress += 1;
3969  rvapi_flush ( );
3970  }
3971 
3972  exit ( -1 );
3973  }
3974  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
3975  {
3976  hlpMap[iter] = 0.0;
3977  }
3978 
3979  unsigned int newU, newV, newW, hlpPos, arrPos;
3980  for ( int uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
3981  {
3982  for ( int vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
3983  {
3984  for ( int wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
3985  {
3986  if ( ( uIt < xDiff ) || ( uIt > static_cast<int> ( this->_maxMapU - xDiff ) ) ||
3987  ( vIt < yDiff ) || ( vIt > static_cast<int> ( this->_maxMapV - yDiff ) ) ||
3988  ( wIt < zDiff ) || ( wIt > static_cast<int> ( this->_maxMapW - zDiff ) ) )
3989  {
3990  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
3991  hlpMap[hlpPos] = 0.0;
3992  }
3993  else
3994  {
3995  newU = (uIt - xDiff);
3996  newV = (vIt - yDiff);
3997  newW = (wIt - zDiff);
3998 
3999  hlpPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
4000  arrPos = newW + (this->_maxMapW + 1 - zDiff * 2) * ( newV + (this->_maxMapV + 1 - yDiff * 2) * newU );
4001 
4002  hlpMap[hlpPos] = this->_densityMapMap[arrPos];
4003  }
4004  }
4005  }
4006  }
4007 
4008  //==================================== Free memory
4009  if ( this->_densityMapMap != nullptr )
4010  {
4011  free ( this->_densityMapMap );
4012  this->_densityMapMap = nullptr;
4013  }
4014 
4015  //==================================== Copy
4016  this->_densityMapMap = (float*) malloc ( ((this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1)) * sizeof ( float ) );
4017  if ( this->_densityMapMap == nullptr )
4018  {
4019  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
4020 
4021  if ( settings->htmlReport )
4022  {
4023  std::stringstream hlpSS;
4024  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
4025  rvapi_set_text ( hlpSS.str().c_str(),
4026  "ProgressSection",
4027  settings->htmlReportLineProgress,
4028  1,
4029  1,
4030  1 );
4031  settings->htmlReportLineProgress += 1;
4032  rvapi_flush ( );
4033  }
4034 
4035  exit ( -1 );
4036  }
4037  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
4038  {
4039  this->_densityMapMap[iter] = hlpMap[iter];
4040  }
4041 
4042  //==================================== Free memory
4043  if ( hlpMap != nullptr )
4044  {
4045  free ( hlpMap );
4046  hlpMap = nullptr;
4047  }
4048 
4049  if ( settings->htmlReport )
4050  {
4051  std::stringstream hlpSS;
4052  hlpSS << "<font color=\"green\">" << "Extra cell space added as required." << "</font>";
4053  rvapi_set_text ( hlpSS.str().c_str(),
4054  "ProgressSection",
4055  settings->htmlReportLineProgress,
4056  1,
4057  1,
4058  1 );
4059  settings->htmlReportLineProgress += 1;
4060  rvapi_flush ( );
4061  }
4062  }
4063 
4064  //======================================== Local hlp variables
4065  int hlpU = ( this->_maxMapU + 1 );
4066  int hlpV = ( this->_maxMapV + 1 );
4067  int hlpW = ( this->_maxMapW + 1 );
4068 
4069  //======================================== Initialise local variables for Fourier and Inverse Fourier
4070  int uIt, vIt, wIt;
4071  unsigned int arrayPos = 0;
4072 
4073  this->_densityMapCor = new double [hlpU * hlpV * hlpW];
4074 
4075  //======================================== Load map data for Fourier
4076  std::vector<double> vals;
4077  std::vector<double> valsWZ;
4078 
4079  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (this->_maxMapU+1) * (this->_maxMapV+1) * (this->_maxMapW+1) ); iter++ )
4080  {
4081  if ( this->_densityMapMap[iter] == this->_densityMapMap[iter] )
4082  {
4083  //================================ Map value is NOT nan
4084  if ( this->_densityMapMap[iter] != 0.0 )
4085  {
4086  vals.emplace_back ( ( this->_densityMapMap[iter] - this->_mapMean ) / this->_mapSdev );
4087  }
4088  valsWZ.emplace_back ( ( this->_densityMapMap[iter] - this->_mapMean ) / this->_mapSdev );
4089 
4090  this->_densityMapCor[iter] = ( this->_densityMapMap[iter] - this->_mapMean ) / this->_mapSdev;
4091  }
4092  else
4093  {
4094  //================================ Map value is nan - this sometimes occurs for a couple of values, I have no clue as to why...
4095  this->_densityMapCor[iter] = 0.0;
4096  }
4097  }
4098  if ( verbose > 3 )
4099  {
4100  std::cout << ">>>>> Map normalised." << std::endl;
4101  }
4102 
4103  if ( settings->htmlReport )
4104  {
4105  std::stringstream hlpSS;
4106  hlpSS << "<font color=\"green\">" << "Map normalisation complete." << "</font>";
4107  rvapi_set_text ( hlpSS.str().c_str(),
4108  "ProgressSection",
4109  settings->htmlReportLineProgress,
4110  1,
4111  1,
4112  1 );
4113  settings->htmlReportLineProgress += 1;
4114  rvapi_flush ( );
4115  }
4116 
4117  //======================================== If not required, do not continue
4118  if ( !reboxAtAll )
4119  {
4120  vals.clear ( );
4121  return;
4122  }
4123 
4124  //======================================== Get post normalisation stats
4125  std::sort ( vals.begin(), vals.end() );
4126 
4127  *minDensPostNorm = vals.at(0);
4128  *maxDensPostNorm = vals.at(vals.size()-1);
4129 
4130  *postNormMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
4131  *postNormSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - *postNormMean * *postNormMean );
4132 
4133  *allDensityRMS = 0.0;
4134  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( valsWZ.size() ); iter++ )
4135  {
4136  *allDensityRMS += pow ( valsWZ.at(iter), 2.0 );
4137  }
4138  *allDensityRMS /= static_cast<double> ( valsWZ.size() - 1 );
4139  *allDensityRMS = sqrt ( *allDensityRMS );
4140 
4141  vals.clear ( );
4142  valsWZ.clear ( );
4143 
4144  //======================================== Print more to the results section
4145  if ( settings->htmlReport )
4146  {
4147  std::stringstream hlpSS;
4148  hlpSS << "<pre>" << "Mean (std. dev.) pre normalisation: ";
4149  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4150  for ( int iter = 0; iter < hlpIt; iter++ )
4151  {
4152  hlpSS << ".";
4153  }
4154 
4155  std::stringstream hlpSS2;
4156  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( this->_mapMean * 1000.0 ) / 1000.0;
4157  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4158  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4159  hlpSS << " " << hlpSS2.str() << " ( ";
4160 
4161  hlpSS2.str( std::string ( ) );
4162  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( this->_mapSdev * 1000.0 ) / 1000.0;
4163  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4164  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4165  hlpSS << hlpSS2.str() << " ) " << "</pre>";
4166 
4167  rvapi_set_text ( hlpSS.str().c_str(),
4168  "ResultsSection",
4169  1,
4170  1,
4171  1,
4172  1 );
4173 
4174  hlpSS.str( std::string ( "<pre>" ) );
4175  for ( int iter = 0; iter < 70; iter++ )
4176  {
4177  hlpSS << "=";
4178  }
4179  hlpSS << "</pre>";
4180  rvapi_set_text ( hlpSS.str().c_str(),
4181  "ResultsSection",
4182  2,
4183  1,
4184  1,
4185  1 );
4186 
4187  hlpSS.str( std::string ( ) );
4188  hlpSS << "<pre>" << "Min / Max density post normalisation: ";
4189  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4190  for ( int iter = 0; iter < hlpIt; iter++ )
4191  {
4192  hlpSS << ".";
4193  }
4194 
4195  hlpSS2.str( std::string ( ) );
4196  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *minDensPostNorm * 1000.0 ) / 1000.0;
4197  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4198  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4199  hlpSS << " " << hlpSS2.str() << " / ";
4200 
4201  hlpSS2.str( std::string ( ) );
4202  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maxDensPostNorm * 1000.0 ) / 1000.0;
4203  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4204  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4205  hlpSS << hlpSS2.str() << "</pre>";
4206 
4207  rvapi_set_text ( hlpSS.str().c_str(),
4208  "ResultsSection",
4209  3,
4210  1,
4211  1,
4212  1 );
4213 
4214  hlpSS.str( std::string ( ) );
4215  hlpSS << "<pre>" << "Mean (std. dev.) post normalisation: ";
4216  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4217  for ( int iter = 0; iter < hlpIt; iter++ )
4218  {
4219  hlpSS << ".";
4220  }
4221 
4222  hlpSS2.str( std::string ( ) );
4223  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *postNormMean * 1000.0 ) / 1000.0;
4224  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4225  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4226  hlpSS << " " << hlpSS2.str() << " ( ";
4227 
4228  hlpSS2.str( std::string ( ) );
4229  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *postNormSdev * 1000.0 ) / 1000.0;
4230  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4231  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4232  hlpSS << hlpSS2.str() << " ) " << "</pre>";
4233 
4234  rvapi_set_text ( hlpSS.str().c_str(),
4235  "ResultsSection",
4236  4,
4237  1,
4238  1,
4239  1 );
4240 
4241  hlpSS.str( std::string ( "<pre>" ) );
4242  for ( int iter = 0; iter < 70; iter++ )
4243  {
4244  hlpSS << "=";
4245  }
4246  hlpSS << "</pre>";
4247  rvapi_set_text ( hlpSS.str().c_str(),
4248  "ResultsSection",
4249  5,
4250  1,
4251  1,
4252  1 );
4253 
4254  rvapi_flush ( );
4255  }
4256 
4257  //======================================== Map cleaning
4258  this->_fromPDB = false;
4259  if ( !this->_fromPDB )
4260  {
4261  //==================================== Save original map to restore for each cycle
4262  double *tmpMp = new double[hlpU * hlpV * hlpW];
4263  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
4264  {
4265  tmpMp[iter] = this->_densityMapCor[iter];
4266  }
4267 
4268  bool notTooManyIslads = true;
4269  double blFr = 150.0;
4270 
4271  while ( notTooManyIslads )
4272  {
4273  //================================ Do not change user values
4274  blFr += 50.0;
4275  if ( maskBlurFactorGiven )
4276  {
4277  blFr = maskBlurFactor;
4278  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
4279  this->removeIslands ( hlpU, hlpV, hlpW, verbose, true );
4280  break;
4281  }
4282 
4283  //================================ Compute mask and apply it
4284  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
4285 
4286  //================================ Detect islands
4287  if ( verbose > 3 )
4288  {
4289  std::cout << ">>>>>>>> Island detection started." << std::endl;
4290  }
4291 
4292  notTooManyIslads = this->removeIslands ( hlpU, hlpV, hlpW, verbose, false );
4293 
4294  if ( maskBlurFactorGiven )
4295  {
4296  break;
4297  }
4298 
4299  if ( verbose > 3 )
4300  {
4301  std::cout << ">>>>> Map masked with factor of " << blFr << " and small islands were then removed.";
4302  }
4303  if ( notTooManyIslads )
4304  {
4305  if ( verbose > 3 )
4306  {
4307  std::cout << " However, too many islands remained. Trying higher blurring factor." << std::endl;
4308  }
4309 
4310  if ( blFr <= 500.0 )
4311  {
4312  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
4313  {
4314  this->_densityMapCor[iter] = tmpMp[iter];
4315  }
4316  }
4317  }
4318  else
4319  {
4320  if ( verbose > 3 )
4321  {
4322  std::cout << std::endl;
4323  }
4324  }
4325 
4326 
4327  if ( blFr > 500.0 )
4328  {
4329  std::cout << "!!! ProSHADE WARNING !!! Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << std::endl;
4330 
4331  if ( settings->htmlReport )
4332  {
4333  std::stringstream hlpSS;
4334  hlpSS << "<font color=\"orange\">" << "Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << "</font>";
4335  rvapi_set_text ( hlpSS.str().c_str(),
4336  "ProgressSection",
4337  settings->htmlReportLineProgress,
4338  1,
4339  1,
4340  1 );
4341  settings->htmlReportLineProgress += 1;
4342  rvapi_flush ( );
4343  }
4344 
4345  break;
4346  }
4347  }
4348  delete[] tmpMp;
4349  }
4350 
4351  if ( verbose > 2 )
4352  {
4353  std::cout << ">> Map masked." << std::endl;
4354  }
4355 
4356  if ( settings->htmlReport )
4357  {
4358  std::stringstream hlpSS;
4359  hlpSS << "<font color=\"green\">" << "Map masking complete." << "</font>";
4360  rvapi_set_text ( hlpSS.str().c_str(),
4361  "ProgressSection",
4362  settings->htmlReportLineProgress,
4363  1,
4364  1,
4365  1 );
4366  settings->htmlReportLineProgress += 1;
4367  rvapi_flush ( );
4368  }
4369 
4370  //======================================== Free unnecessary memory
4371  if ( this->_densityMapMap != nullptr )
4372  {
4373  delete this->_densityMapMap;
4374  this->_densityMapMap = nullptr;
4375  }
4376 
4377  //======================================== Mask stats
4378  vals.clear ( );
4379 
4380  for ( uIt = 0; uIt < hlpU; uIt++ )
4381  {
4382  for ( vIt = 0; vIt < hlpV; vIt++ )
4383  {
4384  for ( wIt = 0; wIt < hlpW; wIt++ )
4385  {
4386  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
4387  if ( this->_densityMapCor[arrayPos] != 0.0 ) { vals.emplace_back ( this->_densityMapCor[arrayPos] ); }
4388  }
4389  }
4390  }
4391 
4392  *maskVolume = static_cast<double> ( vals.size() );
4393  *totalVolume = hlpU * hlpV * hlpW;
4394 
4395  std::sort ( vals.begin(), vals.end() );
4396 
4397  *maskMin = vals.at(0);
4398  *maskMax = vals.at(vals.size()-1);
4399 
4400  //======================================== Find mean and standard deviation for later normalisation
4401  *maskMean = std::accumulate ( vals.begin(), vals.end(), 0.0 ) / static_cast<double> ( vals.size() );
4402  *maskSdev = std::sqrt ( static_cast<double> ( std::inner_product ( vals.begin(), vals.end(), vals.begin(), 0.0 ) ) / static_cast<double> ( vals.size() ) - *maskMean * *maskMean );
4403 
4404  *maskDensityRMS = 0.0;
4405  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( vals.size() ); iter++ )
4406  {
4407  *maskDensityRMS += pow ( vals.at(iter), 2.0 );
4408  }
4409  *maskDensityRMS /= static_cast<double> ( vals.size() - 1 );
4410  *maskDensityRMS = sqrt ( *maskDensityRMS );
4411 
4412  vals.clear ( );
4413 
4414  //======================================== Print after masking results
4415  if ( settings->htmlReport )
4416  {
4417  std::stringstream hlpSS;
4418  hlpSS << "<pre>" << "Min / Max density after masking: ";
4419  int hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4420  for ( int iter = 0; iter < hlpIt; iter++ )
4421  {
4422  hlpSS << ".";
4423  }
4424 
4425  std::stringstream hlpSS2;
4426  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maskMin * 1000.0 ) / 1000.0;
4427  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4428  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4429  hlpSS << " " << hlpSS2.str() << " / ";
4430 
4431  hlpSS2.str( std::string ( ) );
4432  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maskMax * 1000.0 ) / 1000.0;
4433  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4434  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4435  hlpSS << hlpSS2.str() << "</pre>";
4436 
4437  rvapi_set_text ( hlpSS.str().c_str(),
4438  "ResultsSection",
4439  6,
4440  1,
4441  1,
4442  1 );
4443 
4444  hlpSS.str( std::string ( ) );
4445  hlpSS << "<pre>" << "Mean (std. dev.) within mask: ";
4446  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4447  for ( int iter = 0; iter < hlpIt; iter++ )
4448  {
4449  hlpSS << ".";
4450  }
4451 
4452  hlpSS2.str( std::string ( ) );
4453  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maskMean * 1000.0 ) / 1000.0;
4454  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4455  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4456  hlpSS << " " << hlpSS2.str() << " ( ";
4457 
4458  hlpSS2.str( std::string ( ) );
4459  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maskSdev * 1000.0 ) / 1000.0;
4460  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4461  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4462  hlpSS << hlpSS2.str() << " ) " << "</pre>";
4463 
4464  rvapi_set_text ( hlpSS.str().c_str(),
4465  "ResultsSection",
4466  7,
4467  1,
4468  1,
4469  1 );
4470 
4471  hlpSS.str( std::string ( "<pre>" ) );
4472  for ( int iter = 0; iter < 70; iter++ )
4473  {
4474  hlpSS << "=";
4475  }
4476  hlpSS << "</pre>";
4477  rvapi_set_text ( hlpSS.str().c_str(),
4478  "ResultsSection",
4479  8,
4480  1,
4481  1,
4482  1 );
4483 
4484  hlpSS.str( std::string ( ) );
4485  hlpSS << "<pre>" << "Total structure volume: ";
4486  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4487  for ( int iter = 0; iter < hlpIt; iter++ )
4488  {
4489  hlpSS << ".";
4490  }
4491 
4492  hlpSS2.str( std::string ( ) );
4493  hlpSS2 << std::showpos << std::setprecision ( 10 ) << *totalVolume * 1000.0 / 1000.0;
4494  if ( hlpSS2.str().length() != 15 ) { int hlp = 15 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4495  if ( hlpSS2.str().length() > 15 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4496  hlpSS << " " << hlpSS2.str() << " A^3 " << "</pre>";
4497 
4498  rvapi_set_text ( hlpSS.str().c_str(),
4499  "ResultsSection",
4500  9,
4501  1,
4502  1,
4503  1 );
4504 
4505  hlpSS.str( std::string ( ) );
4506  hlpSS << "<pre>" << "Total mask volume: ";
4507  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4508  for ( int iter = 0; iter < hlpIt; iter++ )
4509  {
4510  hlpSS << ".";
4511  }
4512 
4513  hlpSS2.str( std::string ( ) );
4514  hlpSS2 << std::showpos << std::setprecision ( 10 ) << *maskVolume * 1000.0 / 1000.0;
4515  if ( hlpSS2.str().length() != 15 ) { int hlp = 15 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4516  if ( hlpSS2.str().length() > 15 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4517  hlpSS << " " << hlpSS2.str() << " A^3 " << "</pre>";
4518 
4519  rvapi_set_text ( hlpSS.str().c_str(),
4520  "ResultsSection",
4521  10,
4522  1,
4523  1,
4524  1 );
4525 
4526  hlpSS.str( std::string ( "<pre>" ) );
4527  for ( int iter = 0; iter < 70; iter++ )
4528  {
4529  hlpSS << "=";
4530  }
4531  hlpSS << "</pre>";
4532  rvapi_set_text ( hlpSS.str().c_str(),
4533  "ResultsSection",
4534  11,
4535  1,
4536  1,
4537  1 );
4538 
4539  hlpSS.str( std::string ( ) );
4540  hlpSS << "<pre>" << "RMS of complete map: ";
4541  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4542  for ( int iter = 0; iter < hlpIt; iter++ )
4543  {
4544  hlpSS << ".";
4545  }
4546 
4547  hlpSS2.str( std::string ( ) );
4548  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *allDensityRMS * 1000.0 ) / 1000.0;
4549  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4550  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4551  hlpSS << " " << hlpSS2.str() << " " << "</pre>";
4552 
4553  rvapi_set_text ( hlpSS.str().c_str(),
4554  "ResultsSection",
4555  12,
4556  1,
4557  1,
4558  1 );
4559 
4560  hlpSS.str( std::string ( ) );
4561  hlpSS << "<pre>" << "RMS of masked map: ";
4562  hlpIt = static_cast<int> ( 70 - hlpSS.str().length() );
4563  for ( int iter = 0; iter < hlpIt; iter++ )
4564  {
4565  hlpSS << ".";
4566  }
4567 
4568  hlpSS2.str( std::string ( ) );
4569  hlpSS2 << std::showpos << ProSHADE_internal_misc::roundDouble ( *maskDensityRMS * 1000.0 ) / 1000.0;
4570  if ( hlpSS2.str().length() != 6 ) { int hlp = 6 - hlpSS2.str().length(); for ( int i = 0; i < hlp; i++ ) { hlpSS2 << " "; } }
4571  if ( hlpSS2.str().length() > 6 ) { hlpSS2.str( hlpSS2.str().substr( 0, 6 ) ); }
4572  hlpSS << " " << hlpSS2.str() << " " << "</pre>";
4573 
4574  rvapi_set_text ( hlpSS.str().c_str(),
4575  "ResultsSection",
4576  13,
4577  1,
4578  1,
4579  1 );
4580 
4581  rvapi_flush ( );
4582  }
4583 
4584  //======================================== Get real dimensions, instead of unit grid
4585  double xReal = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
4586  double yReal = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
4587  double zReal = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
4588 
4589  //======================================== Find the COM
4590  std::array<double,3> meanVals;
4591  meanVals[0] = 0.0;
4592  meanVals[1] = 0.0;
4593  meanVals[2] = 0.0;
4594 
4595  double totDens = 0.0;
4596 
4597  for ( uIt = 0; uIt < hlpU; uIt++ )
4598  {
4599  for ( vIt = 0; vIt < hlpV; vIt++ )
4600  {
4601  for ( wIt = 0; wIt < hlpW; wIt++ )
4602  {
4603  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
4604 
4605  meanVals[0] += this->_densityMapCor[arrayPos] * uIt;
4606  meanVals[1] += this->_densityMapCor[arrayPos] * vIt;
4607  meanVals[2] += this->_densityMapCor[arrayPos] * wIt;
4608 
4609  totDens += this->_densityMapCor[arrayPos];
4610  }
4611  }
4612  }
4613 
4614  meanVals[0] /= totDens;
4615  meanVals[1] /= totDens;
4616  meanVals[2] /= totDens;
4617 
4618  //======================================== Re-index the map with COM in the centre
4619  this->_xCorrErr = meanVals[0] - static_cast<double> ( this->_maxMapU + 1 )/2.0;
4620  this->_yCorrErr = meanVals[1] - static_cast<double> ( this->_maxMapV + 1 )/2.0;
4621  this->_zCorrErr = meanVals[2] - static_cast<double> ( this->_maxMapW + 1 )/2.0;
4622 
4623  this->_xCorrection = std::ceil ( this->_xCorrErr );
4624  this->_yCorrection = std::ceil ( this->_yCorrErr );
4625  this->_zCorrection = std::ceil ( this->_zCorrErr );
4626 
4627  //======================================== Initialise internal values
4628  this->_densityMapCorCoords = new std::array<double,3> [hlpU * hlpV * hlpW];
4629  int newU, newV, newW, coordPos;
4630 
4631  //======================================== Save the final coords
4632  for ( uIt = 0; uIt < hlpU; uIt++ )
4633  {
4634  for ( vIt = 0; vIt < hlpV; vIt++ )
4635  {
4636  for ( wIt = 0; wIt < hlpW; wIt++ )
4637  {
4638  newU = static_cast<int> ( uIt ) - static_cast<int> ( this->_xCorrection );
4639  newV = static_cast<int> ( vIt ) - static_cast<int> ( this->_yCorrection );
4640  newW = static_cast<int> ( wIt ) - static_cast<int> ( this->_zCorrection );
4641 
4642  if ( newU < 0 ) { newU += hlpU; } if ( newU >= static_cast<int> ( hlpU ) ) { newU -= hlpU; }
4643  if ( newV < 0 ) { newV += hlpV; } if ( newV >= static_cast<int> ( hlpV ) ) { newV -= hlpV; }
4644  if ( newW < 0 ) { newW += hlpW; } if ( newW >= static_cast<int> ( hlpW ) ) { newW -= hlpW; }
4645 
4646  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
4647  coordPos = newW + hlpW * ( newV + hlpV * newU );
4648 
4649  this->_densityMapCorCoords[coordPos][0] = ( static_cast<double> ( newU ) - static_cast<double> ( hlpU ) / 2.0 ) * xReal;
4650  this->_densityMapCorCoords[coordPos][1] = ( static_cast<double> ( newV ) - static_cast<double> ( hlpV ) / 2.0 ) * yReal;
4651  this->_densityMapCorCoords[coordPos][2] = ( static_cast<double> ( newW ) - static_cast<double> ( hlpW ) / 2.0 ) * zReal;
4652  }
4653  }
4654  }
4655  if ( verbose > 2 )
4656  {
4657  std::cout << ">> Map centered." << std::endl;
4658  }
4659 
4660  if ( settings->htmlReport )
4661  {
4662  std::stringstream hlpSS;
4663  hlpSS << "<font color=\"green\">" << "Map centered." << "</font>";
4664  rvapi_set_text ( hlpSS.str().c_str(),
4665  "ProgressSection",
4666  settings->htmlReportLineProgress,
4667  1,
4668  1,
4669  1 );
4670  settings->htmlReportLineProgress += 1;
4671  rvapi_flush ( );
4672  }
4673 
4674  //======================================== Determine the real size of the shape
4675  double maxX = 0.0;
4676  double minX = 0.0;
4677  double maxY = 0.0;
4678  double minY = 0.0;
4679  double maxZ = 0.0;
4680  double minZ = 0.0;
4681  double maxXTot = 0.0;
4682  double minXTot = 0.0;
4683  double maxYTot = 0.0;
4684  double minYTot = 0.0;
4685  double maxZTot = 0.0;
4686  double minZTot = 0.0;
4687 
4688  coordPos = 0;
4689  for ( uIt = 0; uIt < hlpU; uIt++ )
4690  {
4691  for ( vIt = 0; vIt < hlpV; vIt++ )
4692  {
4693  for ( wIt = 0; wIt < hlpW; wIt++ )
4694  {
4695  coordPos = wIt + hlpW * ( vIt + hlpV * uIt );
4696 
4697  if ( this->_densityMapCor[coordPos] > 0.0 )
4698  {
4699  maxX = std::max ( maxX, this->_densityMapCorCoords[coordPos][0] );
4700  minX = std::min ( minX, this->_densityMapCorCoords[coordPos][0] );
4701  maxY = std::max ( maxY, this->_densityMapCorCoords[coordPos][1] );
4702  minY = std::min ( minY, this->_densityMapCorCoords[coordPos][1] );
4703  maxZ = std::max ( maxZ, this->_densityMapCorCoords[coordPos][2] );
4704  minZ = std::min ( minZ, this->_densityMapCorCoords[coordPos][2] );
4705  }
4706  maxXTot = std::max ( maxXTot, this->_densityMapCorCoords[coordPos][0] );
4707  minXTot = std::min ( minXTot, this->_densityMapCorCoords[coordPos][0] );
4708  maxYTot = std::max ( maxYTot, this->_densityMapCorCoords[coordPos][1] );
4709  minYTot = std::min ( minYTot, this->_densityMapCorCoords[coordPos][1] );
4710  maxZTot = std::max ( maxZTot, this->_densityMapCorCoords[coordPos][2] );
4711  minZTot = std::min ( minZTot, this->_densityMapCorCoords[coordPos][2] );
4712  }
4713  }
4714  }
4715 
4716  //======================================== Calculate the grid for only the shape
4717  int newUStart = std::floor ( ( ( minX - minXTot ) / ( maxXTot - minXTot ) ) * ( this->_maxMapU + 1 ) );
4718  int newUEnd = std::ceil ( ( ( maxX - minXTot ) / ( maxXTot - minXTot ) ) * ( this->_maxMapU + 1 ) );
4719  int newVStart = std::floor ( ( ( minY - minYTot ) / ( maxYTot - minYTot ) ) * ( this->_maxMapV + 1 ) );
4720  int newVEnd = std::ceil ( ( ( maxY - minYTot ) / ( maxYTot - minYTot ) ) * ( this->_maxMapV + 1 ) );
4721  int newWStart = std::floor ( ( ( minZ - minZTot ) / ( maxZTot - minZTot ) ) * ( this->_maxMapW + 1 ) );
4722  int newWEnd = std::ceil ( ( ( maxZ - minZTot ) / ( maxZTot - minZTot ) ) * ( this->_maxMapW + 1 ) );
4723 
4724  //======================================== Make cube. If you want rectangle (more efficient), remove the following 6 lines, but beware, the map ordering will be YXZ...
4725  if ( useCubicMaps )
4726  {
4727  newUStart = std::min( newUStart, std::min( newVStart, newWStart ) );
4728  newVStart = std::min( newUStart, std::min( newVStart, newWStart ) );
4729  newWStart = std::min( newUStart, std::min( newVStart, newWStart ) );
4730  newUEnd = std::max( newUEnd , std::max( newVEnd , newWEnd ) );
4731  newVEnd = std::max( newUEnd , std::max( newVEnd , newWEnd ) );
4732  newWEnd = std::max( newUEnd , std::max( newVEnd , newWEnd ) );
4733  }
4734 
4735  //======================================== Move map
4736  int newXDim = newUEnd - newUStart + 1;
4737  int newYDim = newVEnd - newVStart + 1;
4738  int newZDim = newWEnd - newWStart + 1;
4739 
4740  if ( ( this->_xFrom < 0 ) && ( ( this->_xFrom + newUStart ) >= 0 ) ) { newXDim += 1; }
4741  if ( ( this->_yFrom < 0 ) && ( ( this->_yFrom + newVStart ) >= 0 ) ) { newYDim += 1; }
4742  if ( ( this->_zFrom < 0 ) && ( ( this->_zFrom + newWStart ) >= 0 ) ) { newZDim += 1; }
4743 
4744  double *hlpMap = nullptr;
4745  hlpMap = (double*) malloc ( newXDim * newYDim * newZDim * sizeof ( double ) );
4746  if ( hlpMap == nullptr )
4747  {
4748  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map moving data. Terminating... " << std::endl;
4749 
4750  if ( settings->htmlReport )
4751  {
4752  std::stringstream hlpSS;
4753  hlpSS << "<font color=\"red\">" << "Cannot allocate memory for map data. Could you have run out of memory?" << "</font>";
4754  rvapi_set_text ( hlpSS.str().c_str(),
4755  "ProgressSection",
4756  settings->htmlReportLineProgress,
4757  1,
4758  1,
4759  1 );
4760  settings->htmlReportLineProgress += 1;
4761  rvapi_flush ( );
4762  }
4763 
4764  exit ( -1 );
4765  }
4766 
4767  int arrPos, hlpPos;
4768  for ( uIt = this->_xFrom; uIt <= this->_xTo; uIt++ )
4769  {
4770  for ( vIt = this->_yFrom; vIt <= this->_yTo; vIt++ )
4771  {
4772  for ( wIt = this->_zFrom; wIt <= this->_zTo; wIt++ )
4773  {
4774  if ( ( uIt < (this->_xFrom+newUStart) ) || ( uIt > (this->_xFrom+newUEnd) ) ||
4775  ( vIt < (this->_yFrom+newVStart) ) || ( vIt > (this->_yFrom+newVEnd) ) ||
4776  ( wIt < (this->_zFrom+newWStart) ) || ( wIt > (this->_zFrom+newWEnd) ) )
4777  {
4778  continue;
4779  }
4780 
4781  newU = uIt - this->_xFrom;
4782  newV = vIt - this->_yFrom;
4783  newW = wIt - this->_zFrom;
4784  arrPos = newW + (this->_maxMapW + 1) * ( newV + (this->_maxMapV + 1) * newU );
4785 
4786  newU = newU - newUStart;
4787  newV = newV - newVStart;
4788  newW = newW - newWStart;
4789  hlpPos = newW + newZDim * ( newV + newYDim * newU );
4790 
4791  hlpMap[hlpPos] = this->_densityMapCor[arrPos];
4792  }
4793  }
4794  }
4795 
4796  //======================================== Change the settings
4797  if ( addXOne ) { this->_xFrom -= 1; }
4798  if ( addYOne ) { this->_yFrom -= 1; }
4799  if ( addZOne ) { this->_zFrom -= 1; }
4800 
4801  this->_xFrom += newUStart;
4802  this->_yFrom += newVStart;
4803  this->_zFrom += newWStart;
4804 
4805  this->_xTo -= this->_maxMapU - newUEnd;
4806  this->_yTo -= this->_maxMapV - newVEnd;
4807  this->_zTo -= this->_maxMapW - newWEnd;
4808 
4809  this->_maxMapU = newXDim - 1;
4810  this->_maxMapV = newYDim - 1;
4811  this->_maxMapW = newZDim - 1;
4812 
4813  if ( ( this->_xFrom > 0 ) && ( this->_xTo > 0 ) ) { this->_xTo += 1; }
4814  if ( ( this->_yFrom > 0 ) && ( this->_yTo > 0 ) ) { this->_yTo += 1; }
4815  if ( ( this->_zFrom > 0 ) && ( this->_zTo > 0 ) ) { this->_zTo += 1; }
4816 
4817  this->_xRange = this->_xSamplingRate * ( this->_maxMapU + 1 );
4818  this->_yRange = this->_ySamplingRate * ( this->_maxMapV + 1 );
4819  this->_zRange = this->_zSamplingRate * ( this->_maxMapW + 1 );
4820 
4821  //======================================== Copy tmp to holder
4822  delete[] this->_densityMapCor;
4823  this->_densityMapCor = nullptr;
4824  this->_densityMapCor = new double [newXDim * newYDim * newZDim];
4825 
4826  for ( int iter = 0; iter < (newXDim * newYDim * newZDim); iter++ )
4827  {
4828  this->_densityMapCor[iter] = hlpMap[iter];
4829  }
4830 
4831  if ( hlpMap != nullptr )
4832  {
4833  free ( hlpMap );
4834  hlpMap = nullptr;
4835  }
4836 
4837  if ( verbose > 2 )
4838  {
4839  std::cout << ">> Map resized." << std::endl;
4840  }
4841 
4842  if ( settings->htmlReport )
4843  {
4844  std::stringstream hlpSS;
4845  hlpSS << "<font color=\"green\">" << "Map resized." << "</font>";
4846  rvapi_set_text ( hlpSS.str().c_str(),
4847  "ProgressSection",
4848  settings->htmlReportLineProgress,
4849  1,
4850  1,
4851  1 );
4852  settings->htmlReportLineProgress += 1;
4853  rvapi_flush ( );
4854  }
4855 
4856  //======================================== Done
4857 
4858 }
4859 
4872  double bFac,
4873  ProSHADE::ProSHADE_settings* settings )
4874 {
4875  //======================================== Sanity check
4876  if ( !this->_densityMapComputed )
4877  {
4878  std::cerr << "!!! ProSHADE ERROR !!! Error in file " << this->_inputFileName << " !!! Attempted to remove phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the removePhaseFromMap function." << std::endl;
4879 
4880  if ( settings->htmlReport )
4881  {
4882  std::stringstream hlpSS;
4883  hlpSS << "<font color=\"red\">" << "Attempted to remove phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the removePhaseFromMap function. This looks like an internal bug - please report this case." << "</font>";
4884  rvapi_set_text ( hlpSS.str().c_str(),
4885  "ProgressSection",
4886  settings->htmlReportLineProgress,
4887  1,
4888  1,
4889  1 );
4890  settings->htmlReportLineProgress += 1;
4891  rvapi_flush ( );
4892  }
4893 
4894  exit ( -1 );
4895  }
4896 
4897  //======================================== Initialise internal values
4898  this->_fourierCoeffPower = alpha;
4899  this->_bFactorChange = bFac;
4900 
4901  //======================================== Initialise local variables for Fourier and Inverse Fourier
4902  fftw_complex *tmpOut;
4903  fftw_complex *tmpIn;
4904  fftw_plan p;
4905  fftw_plan pInv;
4906  int uIt, vIt, wIt;
4907  double real, imag;
4908  int hlpU = ( this->_maxMapU + 1 );
4909  int hlpV = ( this->_maxMapV + 1 );
4910  int hlpW = ( this->_maxMapW + 1 );
4911 
4912  this->_densityMapCor = new double [(this->_maxMapU+2) * (this->_maxMapV+2) * (this->_maxMapW+2)];
4913  tmpIn = new fftw_complex[hlpU * hlpV * hlpW];
4914  tmpOut = new fftw_complex[hlpU * hlpV * hlpW];
4915 
4916  //======================================== Create plans (FFTW_MEASURE would change the arrays)
4917  p = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpIn, tmpOut, FFTW_FORWARD, FFTW_ESTIMATE );
4918  pInv = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpOut, tmpIn, FFTW_BACKWARD, FFTW_ESTIMATE );
4919 
4920  //======================================== Load map data for Fourier
4921  unsigned int noMapPoints = 0;
4922 
4923  for ( uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
4924  {
4925  for ( vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
4926  {
4927  for ( wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
4928  {
4929  //============================ Initialisation
4930  noMapPoints = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
4931 
4932  if ( this->_densityMapMap[noMapPoints] == this->_densityMapMap[noMapPoints] )
4933  {
4934  tmpIn[noMapPoints][0] = this->_densityMapMap[noMapPoints];
4935  tmpIn[noMapPoints][1] = 0.0;
4936  }
4937  else
4938  {
4939  tmpIn[noMapPoints][0] = 0.0;
4940  tmpIn[noMapPoints][1] = 0.0;
4941  }
4942  }
4943  }
4944  }
4945 
4946  //======================================== Calculate Fourier
4947  fftw_execute ( p );
4948 
4949  //======================================== Remove phase information
4950  unsigned int arrayPos = 0;
4951  int h, k, l;
4952  double mag, S;
4953  double normFactor = (hlpU * hlpV * hlpW);
4954  for ( uIt = 0; uIt < hlpU; uIt++ )
4955  {
4956  for ( vIt = 0; vIt < hlpV; vIt++ )
4957  {
4958  for ( wIt = 0; wIt < hlpW; wIt++ )
4959  {
4960  //============================ Var init
4961  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
4962  real = tmpOut[arrayPos][0];
4963  imag = tmpOut[arrayPos][1];
4964 
4965  //============================ Change the B-factors, if required
4966  if ( uIt > (hlpU / 2) ) { h = uIt - hlpU; } else { h = uIt; }
4967  if ( vIt > (hlpV / 2) ) { k = vIt - hlpV; } else { k = vIt; }
4968  if ( wIt > (hlpW / 2) ) { l = wIt - hlpW; } else { l = wIt; }
4969 
4970  S = pow( static_cast<double> ( h ) / this->_xRange, 2.0 ) + pow( static_cast<double> ( k ) / this->_yRange, 2.0 ) + pow( static_cast<double> ( l ) / this->_zRange, 2.0 );
4971  mag = std::exp ( - ( ( this->_bFactorChange * S ) / 4.0 ) );
4972 
4973  //============================ Get magnitude and phase
4974  mag *= sqrt ( (real*real) + (imag*imag) );
4975 
4976  //============================ Magnitude power alpha
4977  mag = pow ( mag, this->_fourierCoeffPower );
4978 
4979  //============================ Phase removal
4980  tmpOut[arrayPos][0] = mag;
4981  tmpOut[arrayPos][1] = 0.0;
4982 
4983  //============================ Normalize
4984  tmpOut[arrayPos][0] /= normFactor;
4985  }
4986  }
4987  }
4988 
4989  //======================================== Run backward Fourier
4990  fftw_execute ( pInv );
4991 
4992  //======================================== Free allocated memory
4993  fftw_destroy_plan ( p );
4994  fftw_destroy_plan ( pInv );
4995 
4996  //======================================== Initialise internal values
4997  this->_densityMapCorCoords = new std::array<double,3> [(this->_maxMapU+2) * (this->_maxMapV+2) * (this->_maxMapW+2)];
4998 
4999  //======================================== Re-order (i.e. centralise) the Patterson
5000  int newU;
5001  int newV;
5002  int newW;
5003  int cenPosU;
5004  int cenPosV;
5005  int cenPosW;
5006  int nonTranslatedIter = 0;
5007  int coordPos;
5008 
5009  for ( uIt = 0; uIt < static_cast<int> (this->_maxMapU + 2); uIt++ )
5010  {
5011  for ( vIt = 0; vIt < static_cast<int> (this->_maxMapV + 2); vIt++ )
5012  {
5013  for ( wIt = 0; wIt < static_cast<int> (this->_maxMapW + 2); wIt++ )
5014  {
5015  if ( ( uIt == hlpU ) || ( vIt == hlpV ) || ( wIt == hlpW ) ) // Deal with the -x to +x-1 unsymmetric results problem by creating +x and copying values from -x (this is only possible when phases are removed as +x and -x must then by identical by symmetry)
5016  {
5017  newU = uIt; if ( uIt == hlpU ) { newU = 0; }
5018  newV = vIt; if ( vIt == hlpV ) { newV = 0; }
5019  newW = wIt; if ( wIt == hlpW ) { newW = 0; }
5020 
5021  cenPosU = newU + (hlpU / 2); if ( cenPosU >= hlpU ) { cenPosU -= hlpU; }
5022  cenPosV = newV + (hlpV / 2); if ( cenPosV >= hlpV ) { cenPosV -= hlpV; }
5023  cenPosW = newW + (hlpW / 2); if ( cenPosW >= hlpW ) { cenPosW -= hlpW; }
5024 
5025  arrayPos = cenPosW + hlpW * ( cenPosV + hlpV * cenPosU );
5026 
5027  this->_densityMapCor[nonTranslatedIter] = tmpIn[arrayPos][0];
5028  this->_densityMapCorCoords[nonTranslatedIter][0] = uIt - hlpU / 2;
5029  this->_densityMapCorCoords[nonTranslatedIter][1] = vIt - hlpV / 2;
5030  this->_densityMapCorCoords[nonTranslatedIter][2] = wIt - hlpW / 2;
5031  }
5032  else // Proceed normally
5033  {
5034  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5035 
5036  cenPosU = uIt + (hlpU / 2); if ( cenPosU >= hlpU ) { cenPosU -= hlpU; }
5037  cenPosV = vIt + (hlpV / 2); if ( cenPosV >= hlpV ) { cenPosV -= hlpV; }
5038  cenPosW = wIt + (hlpW / 2); if ( cenPosW >= hlpW ) { cenPosW -= hlpW; }
5039  coordPos = cenPosW + (this->_maxMapW + 2) * ( cenPosV + (this->_maxMapV + 2) * cenPosU );
5040 
5041  this->_densityMapCor[coordPos] = tmpIn[arrayPos][0];
5042  this->_densityMapCorCoords[coordPos][0] = cenPosU - hlpU / 2;
5043  this->_densityMapCorCoords[coordPos][1] = cenPosV - hlpV / 2;
5044  this->_densityMapCorCoords[coordPos][2] = cenPosW - hlpW / 2;
5045  }
5046  nonTranslatedIter += 1;
5047  }
5048  }
5049  }
5050 
5051  //======================================== Free allocated memory
5052  delete[] tmpOut;
5053  delete[] tmpIn;
5054 
5055  //======================================== Free unnecessary memory
5056  if ( this->_densityMapMap != nullptr )
5057  {
5058  delete this->_densityMapMap;
5059  this->_densityMapMap = nullptr;
5060  }
5061 
5062  //======================================== Done
5063  this->_phaseRemoved = true;
5064  this->_keepOrRemove = false;
5065  this->_usePhase = false;
5066 
5067 }
5068 
5081  double bFac,
5082  ProSHADE::ProSHADE_settings* settings )
5083 {
5084  //======================================== Sanity check
5085  if ( !this->_densityMapComputed )
5086  {
5087  std::cerr << "!!! ProSHADE ERROR !!! Error in file " << this->_inputFileName << " !!! Attempted to remove phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the removePhaseFromMap function." << std::endl;
5088 
5089  if ( settings->htmlReport )
5090  {
5091  std::stringstream hlpSS;
5092  hlpSS << "<font color=\"red\">" << "Attempted to remove phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the removePhaseFromMap function. This looks like an internal bug - please report this case." << "</font>";
5093  rvapi_set_text ( hlpSS.str().c_str(),
5094  "ProgressSection",
5095  settings->htmlReportLineProgress,
5096  1,
5097  1,
5098  1 );
5099  settings->htmlReportLineProgress += 1;
5100  rvapi_flush ( );
5101  }
5102 
5103  exit ( -1 );
5104  }
5105 
5106  //======================================== Initialise internal values
5107  this->_fourierCoeffPower = alpha;
5108  this->_bFactorChange = bFac;
5109 
5110  //======================================== Initialise local variables for Fourier and Inverse Fourier
5111  fftw_complex *tmpOut;
5112  fftw_complex *tmpIn;
5113  fftw_plan p;
5114  fftw_plan pInv;
5115  int uIt, vIt, wIt;
5116  double real, imag;
5117  int hlpU = ( this->_maxMapU + 1 );
5118  int hlpV = ( this->_maxMapV + 1 );
5119  int hlpW = ( this->_maxMapW + 1 );
5120 
5121  this->_densityMapCor = new double [hlpU * hlpV * hlpW];
5122  tmpIn = new fftw_complex[hlpU * hlpV * hlpW];
5123  tmpOut = new fftw_complex[hlpU * hlpV * hlpW];
5124 
5125  //======================================== Create plans (FFTW_MEASURE would change the arrays)
5126  p = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpIn, tmpOut, FFTW_FORWARD, FFTW_ESTIMATE );
5127  pInv = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpOut, tmpIn, FFTW_BACKWARD, FFTW_ESTIMATE );
5128 
5129  //======================================== Load map data for Fourier
5130  unsigned int arrayPos = 0;
5131 
5132  for ( uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
5133  {
5134  for ( vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
5135  {
5136  for ( wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
5137  {
5138  //============================ Initialisation
5139  arrayPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
5140 
5141  if ( this->_densityMapMap[arrayPos] == this->_densityMapMap[arrayPos] )
5142  {
5143  tmpIn[arrayPos][0] = this->_densityMapMap[arrayPos];
5144  tmpIn[arrayPos][1] = 0.0;
5145  }
5146  else
5147  {
5148  tmpIn[arrayPos][0] = 0.0;
5149  tmpIn[arrayPos][1] = 0.0;
5150  }
5151  }
5152  }
5153  }
5154 
5155  //======================================== Calculate Fourier
5156  fftw_execute ( p );
5157 
5158  //======================================== Remove phase information
5159  arrayPos = 0;
5160  int h, k, l;
5161  double mag, S;
5162  double normFactor = (hlpU * hlpV * hlpW);
5163  for ( uIt = 0; uIt < hlpU; uIt++ )
5164  {
5165  for ( vIt = 0; vIt < hlpV; vIt++ )
5166  {
5167  for ( wIt = 0; wIt < hlpW; wIt++ )
5168  {
5169  //============================ Var init
5170  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5171  real = tmpOut[arrayPos][0];
5172  imag = tmpOut[arrayPos][1];
5173 
5174  //============================ Change the B-factors, if required
5175  if ( uIt > (hlpU / 2) ) { h = uIt - hlpU; } else { h = uIt; }
5176  if ( vIt > (hlpV / 2) ) { k = vIt - hlpV; } else { k = vIt; }
5177  if ( wIt > (hlpW / 2) ) { l = wIt - hlpW; } else { l = wIt; }
5178 
5179  S = pow( static_cast<double> ( h ) / this->_xRange, 2.0 ) + pow( static_cast<double> ( k ) / this->_yRange, 2.0 ) + pow( static_cast<double> ( l ) / this->_zRange, 2.0 );
5180  mag = std::exp ( - ( ( this->_bFactorChange * S ) / 4.0 ) );
5181 
5182  //============================ Get magnitude and phase
5183  mag *= sqrt ( (real*real) + (imag*imag) );
5184 
5185  //============================ Magnitude power alpha
5186  mag = pow ( mag, this->_fourierCoeffPower );
5187 
5188  //============================ Phase removal
5189  tmpOut[arrayPos][0] = mag;
5190  tmpOut[arrayPos][1] = 0.0;
5191 
5192  //============================ Normalize
5193  tmpOut[arrayPos][0] /= normFactor;
5194  }
5195  }
5196  }
5197 
5198  //======================================== Run backward Fourier
5199  fftw_execute ( pInv );
5200 
5201  //======================================== Free allocated memory
5202  fftw_destroy_plan ( p );
5203  fftw_destroy_plan ( pInv );
5204 
5205  //======================================== Re-order (i.e. centralise) the Patterson
5206  int cenPosU;
5207  int cenPosV;
5208  int cenPosW;
5209  int coordPos;
5210 
5211  for ( uIt = 0; uIt < static_cast<int> (this->_maxMapU + 1); uIt++ )
5212  {
5213  for ( vIt = 0; vIt < static_cast<int> (this->_maxMapV + 1); vIt++ )
5214  {
5215  for ( wIt = 0; wIt < static_cast<int> (this->_maxMapW + 1); wIt++ )
5216  {
5217  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5218 
5219  cenPosU = uIt + (hlpU / 2); if ( cenPosU >= hlpU ) { cenPosU -= hlpU; }
5220  cenPosV = vIt + (hlpV / 2); if ( cenPosV >= hlpV ) { cenPosV -= hlpV; }
5221  cenPosW = wIt + (hlpW / 2); if ( cenPosW >= hlpW ) { cenPosW -= hlpW; }
5222  coordPos = cenPosW + (this->_maxMapW + 1) * ( cenPosV + (this->_maxMapV + 1) * cenPosU );
5223 
5224  this->_densityMapCor[arrayPos]= tmpIn[coordPos][0];
5225  }
5226  }
5227  }
5228 
5229  //======================================== Free allocated memory
5230  delete[] tmpOut;
5231  delete[] tmpIn;
5232 
5233  //======================================== Free unnecessary memory
5234  if ( this->_densityMapMap != nullptr )
5235  {
5236  delete this->_densityMapMap;
5237  this->_densityMapMap = nullptr;
5238  }
5239 
5240  //======================================== Done
5241  this->_phaseRemoved = true;
5242  this->_usePhase = false;
5243  this->_keepOrRemove = false;
5244 
5245 }
5246 
5271  double bFac,
5272  unsigned int *bandwidth,
5273  unsigned int *theta,
5274  unsigned int *phi,
5275  unsigned int *glIntegOrder,
5276  ProSHADE::ProSHADE_settings* settings,
5277  bool useCom,
5278  double maxMapIQR,
5279  int verbose,
5280  bool clearMapData,
5281  bool rotDefaults,
5282  bool overlapDefaults,
5283  double blurFactor,
5284  bool maskBlurFactorGiven )
5285 {
5286  //======================================== Sanity check
5287  if ( !this->_densityMapComputed )
5288  {
5289  std::cerr << "!!! ProSHADE ERROR !!! Error in file " << this->_inputFileName << " !!! Attempted to keep phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the keepPhaseInMap function." << std::endl;
5290 
5291  if ( settings->htmlReport )
5292  {
5293  std::stringstream hlpSS;
5294  hlpSS << "<font color=\"red\">" << "Attempted to remove phase information from map before computing the map. Call the getDensityMapFromPDB function BEFORE the keepPhaseInMap function. This looks like an internal bug - please report this case." << "</font>";
5295  rvapi_set_text ( hlpSS.str().c_str(),
5296  "ProgressSection",
5297  settings->htmlReportLineProgress,
5298  1,
5299  1,
5300  1 );
5301  settings->htmlReportLineProgress += 1;
5302  rvapi_flush ( );
5303  }
5304 
5305  exit ( -1 );
5306  }
5307 
5308  //======================================== Initialise internal values
5309  this->_fourierCoeffPower = alpha;
5310  this->_bFactorChange = bFac;
5311 
5312  //======================================== Local hlp variables
5313  int hlpU = ( this->_maxMapU + 1 );
5314  int hlpV = ( this->_maxMapV + 1 );
5315  int hlpW = ( this->_maxMapW + 1 );
5316 
5317  //======================================== Initialise local variables for Fourier and Inverse Fourier
5318  fftw_complex *tmpOut;
5319  fftw_complex *tmpIn;
5320  fftw_plan p;
5321  fftw_plan pInv;
5322  int uIt, vIt, wIt;
5323  double real, imag;
5324  unsigned int arrayPos = 0;
5325  int arrPos = 0;
5326 
5327  this->_densityMapCor = new double [hlpU * hlpV * hlpW];
5328  tmpIn = new fftw_complex[hlpU * hlpV * hlpW];
5329  tmpOut = new fftw_complex[hlpU * hlpV * hlpW];
5330 
5331  //======================================== Create plans (FFTW_MEASURE would change the arrays)
5332  p = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpIn, tmpOut, FFTW_FORWARD, FFTW_ESTIMATE );
5333  pInv = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpOut, tmpIn, FFTW_BACKWARD, FFTW_ESTIMATE );
5334 
5335  //======================================== Load map data for Fourier
5336  for ( uIt = 0; uIt < static_cast<int> (this->_maxMapU+1); uIt++ )
5337  {
5338  for ( vIt = 0; vIt < static_cast<int> (this->_maxMapV+1); vIt++ )
5339  {
5340  for ( wIt = 0; wIt < static_cast<int> (this->_maxMapW+1); wIt++ )
5341  {
5342  //============================ Initialisation
5343  arrPos = wIt + (this->_maxMapW + 1) * ( vIt + (this->_maxMapV + 1) * uIt );
5344 
5345  if ( this->_densityMapMap[arrPos] == this->_densityMapMap[arrPos] )
5346  {
5347  tmpIn[arrPos][0] = this->_densityMapMap[arrPos];
5348  tmpIn[arrPos][1] = 0.0;
5349  }
5350  else
5351  {
5352  tmpIn[arrPos][0] = 0.0;
5353  tmpIn[arrPos][1] = 0.0;
5354  }
5355  }
5356  }
5357  }
5358 
5359  //======================================== Check if alpha or B-factor change is required
5360  if ( ( this->_fourierCoeffPower != 1.0 ) || ( this->_bFactorChange != 0.0 ) )
5361  {
5362  //==================================== Calculate Fourier
5363  fftw_execute ( p );
5364 
5365  //==================================== Manipulate the B-factors and such
5366  int h, k, l;
5367  double mag, phase, S;
5368  double normFactor = (hlpU * hlpV * hlpW);
5369  for ( uIt = 0; uIt < hlpU; uIt++ )
5370  {
5371  for ( vIt = 0; vIt < hlpV; vIt++ )
5372  {
5373  for ( wIt = 0; wIt < hlpW; wIt++ )
5374  {
5375  //======================== Var init
5376  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5377  real = tmpOut[arrayPos][0];
5378  imag = tmpOut[arrayPos][1];
5379 
5380  //======================== Change the B-factors, if required
5381  if ( uIt > (hlpU / 2) ) { h = uIt - hlpU; } else { h = uIt; }
5382  if ( vIt > (hlpV / 2) ) { k = vIt - hlpV; } else { k = vIt; }
5383  if ( wIt > (hlpW / 2) ) { l = wIt - hlpW; } else { l = wIt; }
5384 
5385  S = pow ( static_cast<double> ( h ) / this->_xRange, 2.0 ) +
5386  pow ( static_cast<double> ( k ) / this->_yRange, 2.0 ) +
5387  pow ( static_cast<double> ( l ) / this->_zRange, 2.0 );
5388  mag = std::exp ( - ( ( this->_bFactorChange * S ) / 4.0 ) );
5389 
5390  //======================== Get magnitude and phase
5391  mag *= sqrt ( (real*real) + (imag*imag) );
5392  phase = atan2 ( imag, real );
5393 
5394  //======================== Magnitude power alpha
5395  mag = pow ( mag, this->_fourierCoeffPower );
5396 
5397  //======================== Phase kept
5398  tmpOut[arrayPos][0] = mag * cos(phase);
5399  tmpOut[arrayPos][1] = mag * sin(phase);
5400 
5401  //======================== Normalize
5402  tmpOut[arrayPos][0] /= normFactor;
5403  tmpOut[arrayPos][1] /= normFactor;
5404  }
5405  }
5406  }
5407 
5408  //==================================== Run backward Fourier
5409  fftw_execute ( pInv );
5410  }
5411 
5412  //======================================== Free allocated memory
5413  fftw_destroy_plan ( p );
5414  fftw_destroy_plan ( pInv );
5415 
5416  //======================================== Copy map to new holder
5417  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
5418  {
5419  this->_densityMapCor[iter] = this->_densityMapMap[iter];
5420  }
5421 
5422  //======================================== Free unnecessary memory
5423  if ( this->_densityMapMap != nullptr )
5424  {
5425  free ( this->_densityMapMap );
5426  this->_densityMapMap = nullptr;
5427  }
5428 
5429  //======================================== Map cleaning
5430  if ( !this->_fromPDB )
5431  {
5432  if ( clearMapData )
5433  {
5434  //================================ Save original map to restore for each cycle
5435  double *tmpMp = new double[hlpU * hlpV * hlpW];
5436  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
5437  {
5438  tmpMp[iter] = this->_densityMapCor[iter];
5439  }
5440 
5441  bool notTooManyIslads = true;
5442  double blFr = 150.0;
5443 
5444  while ( notTooManyIslads )
5445  {
5446  //============================ Do not change user values
5447  blFr += 50.0;
5448  if ( maskBlurFactorGiven )
5449  {
5450  blFr = blurFactor;
5451  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
5452  this->removeIslands ( hlpU, hlpV, hlpW, verbose, true );
5453  break;
5454  }
5455 
5456  //============================ Compute mask and apply it
5457  this->maskMap ( hlpU, hlpV, hlpW, blFr, maxMapIQR, 3.0 );
5458 
5459  //============================ Detect islands
5460  if ( verbose > 3 )
5461  {
5462  std::cout << ">>>>>>>> Island detection started." << std::endl;
5463  }
5464 
5465  notTooManyIslads = this->removeIslands ( hlpU, hlpV, hlpW, verbose, false );
5466 
5467  if ( maskBlurFactorGiven )
5468  {
5469  break;
5470  }
5471 
5472  if ( verbose > 3 )
5473  {
5474  std::cout << ">>>>> Map masked with factor of " << blFr << " and small islands were then removed.";
5475  }
5476  if ( notTooManyIslads )
5477  {
5478  if ( verbose > 3 )
5479  {
5480  std::cout << " However, too many islands remained. Trying higher blurring factor." << std::endl;
5481  }
5482 
5483  if ( blFr <= 500.0 )
5484  {
5485  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
5486  {
5487  this->_densityMapCor[iter] = tmpMp[iter];
5488  }
5489  }
5490  }
5491  else
5492  {
5493  if ( verbose > 3 )
5494  {
5495  std::cout << std::endl;
5496  }
5497  }
5498 
5499  if ( blFr > 500.0 )
5500  {
5501  std::cout << "!!! ProSHADE WARNING !!! Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << std::endl;
5502 
5503  if ( settings->htmlReport )
5504  {
5505  std::stringstream hlpSS;
5506  hlpSS << "<font color=\"orange\">" << "Even blurring factor of 500 did not remove islands. Will not proceed with what we have, but be warned that either the masking is bugged or yout map has high levels of noise. You can consider using the -y ( or --no_clear ) options to avoid this message and the extra time for testing different blurring factors for this map." << "</font>";
5507  rvapi_set_text ( hlpSS.str().c_str(),
5508  "ProgressSection",
5509  settings->htmlReportLineProgress,
5510  1,
5511  1,
5512  1 );
5513  settings->htmlReportLineProgress += 1;
5514  rvapi_flush ( );
5515  }
5516 
5517  break;
5518  }
5519  }
5520  delete[] tmpMp;
5521  }
5522  }
5523 
5524  //======================================== Get real dimensions, instead of unit grid
5525  double xReal = this->_xRange / static_cast<double> ( this->_maxMapU + 1 );
5526  double yReal = this->_yRange / static_cast<double> ( this->_maxMapV + 1 );
5527  double zReal = this->_zRange / static_cast<double> ( this->_maxMapW + 1 );
5528 
5529  //======================================== Find the COM
5530  std::array<double,3> meanVals;
5531  meanVals[0] = 0.0;
5532  meanVals[1] = 0.0;
5533  meanVals[2] = 0.0;
5534 
5535  if ( !this->_firstLineCOM )
5536  {
5537  if ( useCom )
5538  {
5539  double totDens = 0.0;
5540 
5541  for ( uIt = 0; uIt < hlpU; uIt++ )
5542  {
5543  for ( vIt = 0; vIt < hlpV; vIt++ )
5544  {
5545  for ( wIt = 0; wIt < hlpW; wIt++ )
5546  {
5547  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5548 
5549  if ( !this->_fromPDB )
5550  {
5551  if ( this->_densityMapCor[arrayPos] > 0.0 )
5552  {
5553  meanVals[0] += this->_densityMapCor[arrayPos] * uIt;
5554  meanVals[1] += this->_densityMapCor[arrayPos] * vIt;
5555  meanVals[2] += this->_densityMapCor[arrayPos] * wIt;
5556 
5557  totDens += this->_densityMapCor[arrayPos];
5558  }
5559  }
5560  else
5561  {
5562  if ( tmpIn[arrayPos][0] > 0.0 )
5563  {
5564  meanVals[0] += tmpIn[arrayPos][0] * uIt;
5565  meanVals[1] += tmpIn[arrayPos][0] * vIt;
5566  meanVals[2] += tmpIn[arrayPos][0] * wIt;
5567 
5568  totDens += tmpIn[arrayPos][0];
5569  }
5570  }
5571  }
5572  }
5573  }
5574 
5575  meanVals[0] /= totDens;
5576  meanVals[1] /= totDens;
5577  meanVals[2] /= totDens;
5578  }
5579  else
5580  {
5581  meanVals[0] = static_cast<double> ( this->_maxMapU + 1 )/2.0;
5582  meanVals[1] = static_cast<double> ( this->_maxMapV + 1 )/2.0;
5583  meanVals[2] = static_cast<double> ( this->_maxMapW + 1 )/2.0;
5584  }
5585  }
5586  else
5587  {
5588  meanVals[0] = this->_xCorrErr / xReal;
5589  meanVals[1] = this->_yCorrErr / yReal;
5590  meanVals[2] = this->_zCorrErr / zReal;
5591  }
5592 
5593  //======================================== Re-index the map with COM in the centre
5594  this->_xCorrErr = meanVals[0] - static_cast<double> ( this->_maxMapU + 1 )/2.0;
5595  this->_yCorrErr = meanVals[1] - static_cast<double> ( this->_maxMapV + 1 )/2.0;
5596  this->_zCorrErr = meanVals[2] - static_cast<double> ( this->_maxMapW + 1 )/2.0;
5597 
5598  this->_xCorrection = std::ceil ( this->_xCorrErr );
5599  this->_yCorrection = std::ceil ( this->_yCorrErr );
5600  this->_zCorrection = std::ceil ( this->_zCorrErr );
5601 
5602  //======================================== Initialise internal values
5603  this->_densityMapCorCoords = new std::array<double,3> [hlpU * hlpV * hlpW];
5604  int newU, newV, newW, coordPos;
5605 
5606  if ( this->_fromPDB )
5607  {
5608  if ( useCom )
5609  {
5610  for ( uIt = 0; uIt < hlpU; uIt++ )
5611  {
5612  for ( vIt = 0; vIt < hlpV; vIt++ )
5613  {
5614  for ( wIt = 0; wIt < hlpW; wIt++ )
5615  {
5616  newU = static_cast<int> ( uIt ) - static_cast<int> ( this->_xCorrection );
5617  newV = static_cast<int> ( vIt ) - static_cast<int> ( this->_yCorrection );
5618  newW = static_cast<int> ( wIt ) - static_cast<int> ( this->_zCorrection );
5619 
5620  if ( newU < 0 ) { newU += hlpU; } if ( newU >= static_cast<int> ( hlpU ) ) { newU -= hlpU; }
5621  if ( newV < 0 ) { newV += hlpV; } if ( newV >= static_cast<int> ( hlpV ) ) { newV -= hlpV; }
5622  if ( newW < 0 ) { newW += hlpW; } if ( newW >= static_cast<int> ( hlpW ) ) { newW -= hlpW; }
5623 
5624  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5625  coordPos = newW + hlpW * ( newV + hlpV * newU );
5626 
5627  this->_densityMapCor[coordPos] = tmpIn[arrayPos][0];
5628 
5629  //======================== Save results
5630  this->_densityMapCorCoords[coordPos][0] = ( static_cast<double> ( newU ) - static_cast<double> ( hlpU ) / 2.0 ) * xReal;
5631  this->_densityMapCorCoords[coordPos][1] = ( static_cast<double> ( newV ) - static_cast<double> ( hlpV ) / 2.0 ) * yReal;
5632  this->_densityMapCorCoords[coordPos][2] = ( static_cast<double> ( newW ) - static_cast<double> ( hlpW ) / 2.0 ) * zReal;
5633  }
5634  }
5635  }
5636  }
5637  else
5638  {
5639  for ( uIt = 0; uIt < hlpU; uIt++ )
5640  {
5641  for ( vIt = 0; vIt < hlpV; vIt++ )
5642  {
5643  for ( wIt = 0; wIt < hlpW; wIt++ )
5644  {
5645  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5646 
5647  this->_densityMapCor[arrayPos] = tmpIn[arrayPos][0];
5648  this->_densityMapCorCoords[arrayPos][0] = ( static_cast<double> ( uIt ) - ( static_cast<double> ( hlpU ) / 2.0 ) ) * xReal;
5649  this->_densityMapCorCoords[arrayPos][1] = ( static_cast<double> ( vIt ) - ( static_cast<double> ( hlpV ) / 2.0 ) ) * yReal;
5650  this->_densityMapCorCoords[arrayPos][2] = ( static_cast<double> ( wIt ) - ( static_cast<double> ( hlpW ) / 2.0 ) ) * zReal;
5651  }
5652  }
5653  }
5654  }
5655  }
5656  //======================================== Speedup for maps
5657  else
5658  {
5659  if ( !clearMapData )
5660  {
5661  this->_xCorrection = 0.0;
5662  this->_yCorrection = 0.0;
5663  this->_zCorrection = 0.0;
5664  }
5665 
5666  //==================================== Save the final coords
5667  for ( uIt = 0; uIt < hlpU; uIt++ )
5668  {
5669  for ( vIt = 0; vIt < hlpV; vIt++ )
5670  {
5671  for ( wIt = 0; wIt < hlpW; wIt++ )
5672  {
5673  newU = static_cast<int> ( uIt ) - static_cast<int> ( this->_xCorrection );
5674  newV = static_cast<int> ( vIt ) - static_cast<int> ( this->_yCorrection );
5675  newW = static_cast<int> ( wIt ) - static_cast<int> ( this->_zCorrection );
5676 
5677  if ( newU < 0 ) { newU += hlpU; } if ( newU >= static_cast<int> ( hlpU ) ) { newU -= hlpU; }
5678  if ( newV < 0 ) { newV += hlpV; } if ( newV >= static_cast<int> ( hlpV ) ) { newV -= hlpV; }
5679  if ( newW < 0 ) { newW += hlpW; } if ( newW >= static_cast<int> ( hlpW ) ) { newW -= hlpW; }
5680 
5681  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
5682  coordPos = newW + hlpW * ( newV + hlpV * newU );
5683 
5684  this->_densityMapCorCoords[coordPos][0] = ( static_cast<double> ( newU ) - static_cast<double> ( hlpU ) / 2.0 ) * xReal;
5685  this->_densityMapCorCoords[coordPos][1] = ( static_cast<double> ( newV ) - static_cast<double> ( hlpV ) / 2.0 ) * yReal;
5686  this->_densityMapCorCoords[coordPos][2] = ( static_cast<double> ( newW ) - static_cast<double> ( hlpW ) / 2.0 ) * zReal;
5687  }
5688  }
5689  }
5690 
5691  //==================================== Determine the real size of the shape
5692  double maxX = 0.0;
5693  double minX = 0.0;
5694  double maxY = 0.0;
5695  double minY = 0.0;
5696  double maxZ = 0.0;
5697  double minZ = 0.0;
5698  double maxXTot = 0.0;
5699  double minXTot = 0.0;
5700  double maxYTot = 0.0;
5701  double minYTot = 0.0;
5702  double maxZTot = 0.0;
5703  double minZTot = 0.0;
5704 
5705  for ( uIt = 0; uIt < hlpU; uIt++ )
5706  {
5707  for ( vIt = 0; vIt < hlpV; vIt++ )
5708  {
5709  for ( wIt = 0; wIt < hlpW; wIt++ )
5710  {
5711  coordPos = wIt + hlpW * ( vIt + hlpV * uIt );
5712 
5713  if ( this->_densityMapCor[coordPos] > 0.0 )
5714  {
5715  maxX = std::max ( maxX, this->_densityMapCorCoords[coordPos][0] );
5716  minX = std::min ( minX, this->_densityMapCorCoords[coordPos][0] );
5717  maxY = std::max ( maxY, this->_densityMapCorCoords[coordPos][1] );
5718  minY = std::min ( minY, this->_densityMapCorCoords[coordPos][1] );
5719  maxZ = std::max ( maxZ, this->_densityMapCorCoords[coordPos][2] );
5720  minZ = std::min ( minZ, this->_densityMapCorCoords[coordPos][2] );
5721  }
5722  maxXTot = std::max ( maxXTot, this->_densityMapCorCoords[coordPos][0] );
5723  minXTot = std::min ( minXTot, this->_densityMapCorCoords[coordPos][0] );
5724  maxYTot = std::max ( maxYTot, this->_densityMapCorCoords[coordPos][1] );
5725  minYTot = std::min ( minYTot, this->_densityMapCorCoords[coordPos][1] );
5726  maxZTot = std::max ( maxZTot, this->_densityMapCorCoords[coordPos][2] );
5727  minZTot = std::min ( minZTot, this->_densityMapCorCoords[coordPos][2] );
5728  }
5729  }
5730  }
5731 
5732  //==================================== If masking did nothing, submit full map
5733  if ( ( ( maxX == maxXTot ) && ( minX == minXTot ) ) &&
5734  ( ( maxY == maxYTot ) && ( minY == minYTot ) ) &&
5735  ( ( maxZ == maxZTot ) && ( minZ == minZTot ) ) )
5736  {
5737  //================================ Done
5738  this->_phaseRemoved = true;
5739  this->_keepOrRemove = true;
5740  this->_usePhase = true;
5741 
5742  return ;
5743  }
5744 
5745  //==================================== If rotating map, do not change it!
5746  if ( rotDefaults || overlapDefaults )
5747  {
5748  //================================ Done
5749  this->_phaseRemoved = true;
5750  this->_keepOrRemove = true;
5751  this->_usePhase = true;
5752 
5753  return ;
5754  }
5755 
5756  //==================================== Calculate the grid for only the shape
5757  int newUStart = std::floor ( ( ( minX - minXTot ) / ( maxXTot - minXTot ) ) * ( this->_maxMapU + 1 ) );
5758  int newUEnd = std::ceil ( ( ( maxX - minXTot ) / ( maxXTot - minXTot ) ) * ( this->_maxMapU + 1 ) );
5759  int newVStart = std::floor ( ( ( minY - minYTot ) / ( maxYTot - minYTot ) ) * ( this->_maxMapV + 1 ) );
5760  int newVEnd = std::ceil ( ( ( maxY - minYTot ) / ( maxYTot - minYTot ) ) * ( this->_maxMapV + 1 ) );
5761  int newWStart = std::floor ( ( ( minZ - minZTot ) / ( maxZTot - minZTot ) ) * ( this->_maxMapW + 1 ) );
5762  int newWEnd = std::ceil ( ( ( maxZ - minZTot ) / ( maxZTot - minZTot ) ) * ( this->_maxMapW + 1 ) );
5763 
5764  int newURange = std::max ( std::abs ( newUStart - static_cast<int>( this->_maxMapU + 1 )/2 ), std::abs ( newUEnd - static_cast<int>( this->_maxMapU + 1 )/2 ) );
5765  int newVRange = std::max ( std::abs ( newVStart - static_cast<int>( this->_maxMapV + 1 )/2 ), std::abs ( newVEnd - static_cast<int>( this->_maxMapV + 1 )/2 ) );
5766  int newWRange = std::max ( std::abs ( newWStart - static_cast<int>( this->_maxMapW + 1 )/2 ), std::abs ( newWEnd - static_cast<int>( this->_maxMapW + 1 )/2 ) );
5767 
5768  newUStart = ( this->_maxMapU + 1 )/2 - newURange;
5769  newUEnd = ( this->_maxMapU + 1 )/2 + newURange;
5770  newVStart = ( this->_maxMapV + 1 )/2 - newVRange;
5771  newVEnd = ( this->_maxMapV + 1 )/2 + newVRange;
5772  newWStart = ( this->_maxMapW + 1 )/2 - newWRange;
5773  newWEnd = ( this->_maxMapW + 1 )/2 + newWRange;
5774 
5775  newURange = newURange * 2 + 1;
5776  newVRange = newVRange * 2 + 1;
5777  newWRange = newWRange * 2 + 1;
5778 
5779  //==================================== Create new map and coords structures
5780  double* newMapHlp = new double [newURange * newVRange * newWRange];
5781  std::array<double,3>* newMapCoords = new std::array<double,3> [newURange * newVRange * newWRange];
5782 
5783  //==================================== Copy map portion to new structures
5784  unsigned int newUIt, newVIt, newWIt;
5785 
5786  newUIt = 0;
5787  for ( uIt = 0; uIt < hlpU; uIt++ )
5788  {
5789  if ( ( uIt < newUStart ) || ( uIt > newUEnd ) ) { continue; }
5790 
5791  newVIt = 0;
5792  for ( vIt = 0; vIt < hlpV; vIt++ )
5793  {
5794  if ( ( vIt < newVStart ) || ( vIt > newVEnd ) ) { continue; }
5795 
5796  newWIt = 0;
5797  for ( wIt = 0; wIt < hlpW; wIt++ )
5798  {
5799  if ( ( wIt < newWStart ) || ( wIt > newWEnd ) ) { continue; }
5800 
5801  coordPos = wIt + hlpW * ( vIt + hlpV * uIt );
5802  arrayPos = newWIt + newWRange * ( newVIt + newVRange * newUIt );
5803 
5804  newMapHlp[arrayPos] = this->_densityMapCor[coordPos];
5805  newMapCoords[arrayPos][0] = this->_densityMapCorCoords[coordPos][0];
5806  newMapCoords[arrayPos][1] = this->_densityMapCorCoords[coordPos][1];
5807  newMapCoords[arrayPos][2] = this->_densityMapCorCoords[coordPos][2];
5808 
5809  newWIt += 1;
5810  }
5811 
5812  newVIt += 1;
5813  }
5814 
5815  newUIt += 1;
5816  }
5817 
5818  //==================================== Delete old structures
5819  delete this->_densityMapCor;
5820  delete this->_densityMapCorCoords;
5821  this->_densityMapCor = nullptr;
5822  this->_densityMapCorCoords = nullptr;
5823 
5824  //==================================== Copy
5825  this->_densityMapCor = newMapHlp;
5826  newMapHlp = nullptr;
5827  this->_densityMapCorCoords = newMapCoords;
5828  newMapCoords = nullptr;
5829 
5830  //==================================== Re-set internal variables
5831  this->_xRange = ( static_cast<double> (newURange - 1) / static_cast<double> ( this->_maxMapU ) ) * this->_xRange;
5832  this->_yRange = ( static_cast<double> (newVRange - 1) / static_cast<double> ( this->_maxMapV ) ) * this->_yRange;
5833  this->_zRange = ( static_cast<double> (newWRange - 1) / static_cast<double> ( this->_maxMapW ) ) * this->_zRange;
5834  this->_maxMapRange = std::max ( this->_xRange, std::max( this->_yRange, this->_zRange ) );
5835 
5836  this->_maxMapU = newURange - 1;
5837  this->_maxMapV = newVRange - 1;
5838  this->_maxMapW = newWRange - 1;
5839 
5840  //==================================== Automatically determine maximum number of shells
5841  this->_shellPlacement = std::vector<double> ( std::floor ( this->_maxMapRange / this->_shellSpacing ) );
5842 
5843  for ( unsigned int shellIter = 0; shellIter < static_cast<unsigned int> ( this->_shellPlacement.size() ); shellIter++ )
5844  {
5845  this->_shellPlacement.at(shellIter) = (shellIter+1) * this->_shellSpacing;
5846  }
5847 
5848  //==================================== Determine sampling ranges
5849  this->_xSamplingRate = this->_xRange / static_cast<double> ( this->_maxMapU );
5850  this->_ySamplingRate = this->_yRange / static_cast<double> ( this->_maxMapV );
5851  this->_zSamplingRate = this->_zRange / static_cast<double> ( this->_maxMapW );
5852  double maxSamplingRate = std::max ( this->_xSamplingRate, std::max( this->_ySamplingRate, this->_zSamplingRate ) );
5853 
5854  //==================================== Set sampling according to user set resolution and not the real map sampling
5855  if ( ( this->_mapResolution / 2.0 ) > maxSamplingRate )
5856  {
5857  maxSamplingRate = ( this->_mapResolution / 2.0 );
5858  }
5859 
5860  //==================================== If bandwidth is not given, determine it
5861  if ( !this->_wasBandwithGiven )
5862  {
5863  *bandwidth = std::ceil ( std::ceil ( ( ( std::ceil ( this->_maxMapRange / this->_shellSpacing ) * this->_shellSpacing ) / maxSamplingRate ) * 2.0 ) / 2.0 );
5864  }
5865  if ( settings->maxRotError != 0 )
5866  {
5867  *bandwidth = static_cast<unsigned int> ( 180 / settings->maxRotError );
5868  this->_wasBandwithGiven = true;
5869  }
5870 
5871  //==================================== If theta and phi are not given, determine them
5872  if ( !this->_wasThetaGiven ) { *theta = 2 * (*bandwidth); this->_thetaAngle = *theta; }
5873  if ( !this->_wasPhiGiven ) { *phi = 2 * (*bandwidth); this->_phiAngle = *phi; }
5874 
5875  //==================================== If Gauss-Legendre integration order is not given, decide it
5876  double distPerPointFraction;
5877  if ( !this->_wasGlInterGiven )
5878  {
5879  distPerPointFraction = static_cast<double> ( this->_shellSpacing ) / ( this->_maxMapRange / 2.0 );
5880 
5881  for ( unsigned int iter = 2; iter < static_cast<unsigned int> ( ProSHADE_internal_misc::glIntMaxDists.size() ); iter++ )
5882  {
5883  if ( ProSHADE_internal_misc::glIntMaxDists.at(iter) >= distPerPointFraction )
5884  {
5885  *glIntegOrder = iter;
5886  }
5887  }
5888  }
5889  }
5890 
5891  //======================================== Set internal values
5892  this->_bandwidthLimit = *bandwidth;
5893  this->_thetaAngle = static_cast<double> ( *theta );
5894  this->_phiAngle = static_cast<double> ( *phi );
5895 
5896  //======================================== Free allocated memory
5897  delete[] tmpOut;
5898  delete[] tmpIn;
5899 
5900  //======================================== Done
5901  this->_phaseRemoved = true;
5902  this->_usePhase = true;
5903  this->_keepOrRemove = true;
5904 
5905 }
5906 
5917 {
5918  if ( verbose > 0 )
5919  {
5920  std::cout << "-----------------------------------------------------------" << std::endl;
5921  std::cout << "| RESULTS |" << std::endl;
5922  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
5923  }
5924 
5925  if ( verbose > -1 )
5926  {
5927  printf ( "File name: %s\n", this->one->_inputFileName.c_str() );
5928  printf ( "\n" );
5929  printf ( "Cell dimmensions (A): %+.1f x %+.1f x %+.1f\n", this->origRanges[0], this->origRanges[1], this->origRanges[2] );
5930  printf ( "Cell U, V and W: %+.1f x %+.1f x %+.1f\n", this->origDims[0]+1, this->origDims[1]+1, this->origDims[2]+1 );
5931  printf ( "\n" );
5932  printf ( "Min/Max density: %+.3f / %+.3f\n", this->minDensPreNorm, this->maxDensPreNorm );
5933  printf ( "Density mean: %+.3f\n", this->one->_mapMean );
5934  printf ( "Density std. dev: %+.3f\n", this->one->_mapSdev );
5935  printf ( "\n" );
5936  printf ( "Min/Max norm density: %+.3f / %+.3f\n", this->minDensPostNorm, this->maxDensPostNorm );
5937  printf ( "Norm. density mean: %+.3f\n", this->postNormMean );
5938  printf ( "Norm. density std. dev: %+.3f\n", this->postNormSdev );
5939  printf ( "\n" );
5940  printf ( "Total volume (A^3): %+.1f\n", this->totalVolume );
5941  printf ( "Mask volume (A^3): %+.1f\n", this->maskVolume );
5942  printf ( "\n" );
5943  printf ( "Min/Max mask density: %+.3f / %+.3f\n", this->maskMin, this->maskMax );
5944  printf ( "Mask density mean: %+.3f\n", this->maskMean );
5945  printf ( "Mask density std. dev: %+.3f\n", this->maskSdev );
5946  printf ( "\n" );
5947  printf ( "All density RMS: %+.3f\n", this->allDensityRMS );
5948  printf ( "Mask density RMS: %+.3f\n", this->maskDensityRMS );
5949  printf ( "\n\n" );
5950  }
5951 
5952 }
5953 
5970 std::vector< std::vector<int> > ProSHADE_internal::ProSHADE_data::findMapIslands ( int hlpU,
5971  int hlpV,
5972  int hlpW,
5973  double *map,
5974  double threshold )
5975 {
5976  //======================================== Initialise local variables
5977  int newU, newV, newW, coordPos, arrayPos;
5978  int uIt, vIt, wIt;
5979 
5980  //======================================== Island detection:
5981  std::vector< std::array<int,5> > clMap ( hlpU * hlpV * hlpW );
5982  std::array<int,5> hlpArr;
5983  for ( uIt = 0; uIt < hlpU; uIt++ )
5984  {
5985  for ( vIt = 0; vIt < hlpV; vIt++ )
5986  {
5987  for ( wIt = 0; wIt < hlpW; wIt++ )
5988  {
5989  hlpArr[0] = uIt;
5990  hlpArr[1] = vIt;
5991  hlpArr[2] = wIt;
5992  hlpArr[3] = wIt + hlpW * ( vIt + hlpV * uIt );
5993 
5994  if ( map[hlpArr[3]] <= threshold )
5995  {
5996  hlpArr[4] = -999;
5997  }
5998  else
5999  {
6000  hlpArr[4] = -1;
6001  }
6002  clMap.at(hlpArr[3]) = hlpArr;
6003  }
6004  }
6005  }
6006 
6007  //======================================== Island detection algorithm
6008  std::vector< std::vector<int> > clusters;
6009  std::vector<int> unclNeigh;
6010  std::vector<int> clNeigh;
6011  std::vector<int> hlpVec;
6012  std::vector<int> XXXVec;
6013  int clusterNo = 0;
6014  bool allSame = false;
6015  int hlpVal = 0;
6016  int minCl = 0;
6017 
6018  for ( uIt = 0; uIt < hlpU; uIt++ )
6019  {
6020  for ( vIt = 0; vIt < hlpV; vIt++ )
6021  {
6022  for ( wIt = 0; wIt < hlpW; wIt++ )
6023  {
6024  //============================ Find current array pos
6025  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
6026 
6027  //============================ If zero, ignore
6028  if ( clMap.at(arrayPos)[4] == -999 ) { continue; }
6029 
6030  //============================ Check neighbours
6031  unclNeigh.clear ( );
6032  clNeigh.clear ( );
6033  for ( int uCh = -1; uCh < 2; uCh++ )
6034  {
6035  for ( int vCh = -1; vCh < 2; vCh++ )
6036  {
6037  for ( int wCh = -1; wCh < 2; wCh++ )
6038  {
6039  if ( ( uCh == 0 ) && ( vCh == 0 ) && ( wCh == 0 ) ) { continue; }
6040 
6041  newU = static_cast<int> ( uIt ) + uCh;
6042  newV = static_cast<int> ( vIt ) + vCh;
6043  newW = static_cast<int> ( wIt ) + wCh;
6044 
6045  if ( newU < 0 ) { newU += hlpU; } if ( newU >= static_cast<int> ( hlpU ) ) { newU -= hlpU; }
6046  if ( newV < 0 ) { newV += hlpV; } if ( newV >= static_cast<int> ( hlpV ) ) { newV -= hlpV; }
6047  if ( newW < 0 ) { newW += hlpW; } if ( newW >= static_cast<int> ( hlpW ) ) { newW -= hlpW; }
6048 
6049  coordPos = newW + hlpW * ( newV + hlpV * newU );
6050 
6051  //================ If zero, ignore
6052  if ( clMap.at(coordPos)[4] == -999 ) { continue; }
6053 
6054  //================ If not clustered to anyone
6055  if ( clMap.at(coordPos)[4] == -1 )
6056  {
6057  unclNeigh.emplace_back ( coordPos );
6058  continue;
6059  }
6060 
6061  clNeigh.emplace_back ( coordPos );
6062  }
6063  }
6064  }
6065 
6066  //============================ If single point
6067  if ( ( unclNeigh.size() == 0 ) && ( clNeigh.size() == 0 ) )
6068  {
6069  //======================== Assign into new cluster
6070  clMap.at(arrayPos)[4] = clusterNo;
6071 
6072  unclNeigh.emplace_back ( arrayPos );
6073  clusters.emplace_back ( unclNeigh );
6074  unclNeigh.clear ( );
6075 
6076  clusterNo += 1;
6077  continue;
6078  }
6079 
6080  //============================ If only unclustered neighbours
6081  if ( ( unclNeigh.size() > 0 ) && ( clNeigh.size() == 0 ) )
6082  {
6083  //======================== Assign all new cluster
6084  clMap.at(arrayPos)[4] = clusterNo;
6085 
6086  clNeigh.emplace_back ( arrayPos );
6087  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( unclNeigh.size() ); iter++ )
6088  {
6089  clNeigh.emplace_back ( clMap.at(unclNeigh.at(iter))[3] );
6090  clMap.at(unclNeigh.at(iter))[4] = clusterNo;
6091  }
6092 
6093  clusters.emplace_back ( clNeigh );
6094  clNeigh.clear ( );
6095 
6096  clusterNo += 1;
6097  continue;
6098  }
6099 
6100  //============================ If some clustered neighbours
6101  if ( clNeigh.size() > 0 )
6102  {
6103  allSame = true;
6104  hlpVal = clMap.at(clNeigh.at(0))[4];
6105  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( clNeigh.size() ); iter++ )
6106  {
6107  if ( clMap.at(clNeigh.at(iter))[4] != hlpVal )
6108  {
6109  allSame = false;
6110  }
6111  }
6112 
6113  if ( allSame )
6114  {
6115  //==================== Assign this point to the same cluster as neighbours
6116  if ( clMap.at(arrayPos)[4] == -1 )
6117  {
6118  clMap.at(arrayPos)[4] = clMap.at(clNeigh.at(0))[4];
6119  clusters.at(clMap.at(clNeigh.at(0))[4]).emplace_back ( arrayPos );
6120  }
6121 
6122  //==================== Assign all yet unclustered neighbours also
6123  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( unclNeigh.size() ); iter++ )
6124  {
6125  clusters.at(clMap.at(clNeigh.at(0))[4]).emplace_back ( clMap.at(unclNeigh.at(iter))[3] );
6126  clMap.at(unclNeigh.at(iter))[4] = clMap.at(clNeigh.at(0))[4];
6127  }
6128  continue;
6129  }
6130  else
6131  {
6132  //==================== This is where two clusters meet. Start by finding the smalles cluster (smallest ID)
6133  hlpVec.clear ( );
6134  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( clNeigh.size() ); iter++ )
6135  {
6136  hlpVec.emplace_back ( clMap.at(clNeigh.at(iter))[4] );
6137  }
6138 
6139  std::sort ( hlpVec.begin(), hlpVec.end() );
6140  hlpVec.erase ( std::unique( hlpVec.begin(), hlpVec.end() ), hlpVec.end() );
6141 
6142  minCl = hlpVec.at(0);
6143 
6144  //==================== Now, enter this point to the cluster
6145  if ( clMap.at(arrayPos)[4] == -1 )
6146  {
6147  clMap.at(arrayPos)[4] = minCl;
6148  clusters.at(minCl).emplace_back ( arrayPos );
6149  }
6150 
6151  //==================== Then, copy all unclustered points to the smallest ID cluster
6152  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( unclNeigh.size() ); iter++ )
6153  {
6154  clMap.at(unclNeigh.at(iter))[4] = minCl;
6155  clusters.at(minCl).emplace_back ( unclNeigh.at(iter) );
6156  }
6157 
6158  //==================== And copy all other clusters to the one with smallest ID
6159  for ( unsigned int iter = 1; iter < static_cast<unsigned int> ( hlpVec.size() ); iter++ )
6160  {
6161  for ( unsigned int it = 0; it < static_cast<unsigned int> ( clusters.at(hlpVec.at(iter)).size() ); it++ )
6162  {
6163  clMap.at(clusters.at(hlpVec.at(iter)).at(it))[4] = minCl;
6164  clusters.at(minCl).emplace_back ( clusters.at(hlpVec.at(iter)).at(it) );
6165  }
6166  clusters.at(hlpVec.at(iter)).clear();
6167  }
6168  }
6169  }
6170  }
6171  }
6172  }
6173 
6174  //======================================== Find best clusters
6175  std::vector< std::array<double,3> > clVec;
6176  std::array<double,3> hArr;
6177  for ( unsigned int clIt = 0; clIt < static_cast<unsigned int> ( clusters.size() ); clIt++ )
6178  {
6179  if ( clusters.at(clIt).size() > 1 )
6180  {
6181  unsigned int minU = clMap.at(clusters.at(clIt).at(0))[0];
6182  unsigned int maxU = clMap.at(clusters.at(clIt).at(0))[0];
6183  unsigned int minV = clMap.at(clusters.at(clIt).at(0))[1];
6184  unsigned int maxV = clMap.at(clusters.at(clIt).at(0))[1];
6185  unsigned int minW = clMap.at(clusters.at(clIt).at(0))[2];
6186  unsigned int maxW = clMap.at(clusters.at(clIt).at(0))[2];
6187  for ( unsigned int el = 0; el < static_cast<unsigned int> ( clusters.at(clIt).size() ); el++ )
6188  {
6189  minU = std::min ( minU, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[0] ) );
6190  maxU = std::max ( maxU, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[0] ) );
6191  minV = std::min ( minV, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[1] ) );
6192  maxV = std::max ( maxV, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[1] ) );
6193  minW = std::min ( minW, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[2] ) );
6194  maxW = std::max ( maxW, static_cast<unsigned int> ( clMap.at(clusters.at(clIt).at(el))[2] ) );
6195  }
6196  double encVol = ( maxU - minU + 1 ) * ( maxV - minV + 1 ) * ( maxW - minW + 1 );
6197  hArr[0] = encVol / static_cast<double> ( clusters.at(clIt).size() );
6198  hArr[1] = static_cast<double> ( clusters.at(clIt).size() );
6199  hArr[2] = clIt;
6200  clVec.emplace_back ( hArr );
6201  }
6202  }
6203  std::sort ( clVec.begin(), clVec.end(), [](const std::array<double,3>& a, const std::array<double,3>& b) { return a[1] > b[1]; });
6204 
6205  std::vector<double> hlpVals;
6206  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( clVec.size() ); iter++ )
6207  {
6208  hlpVals.emplace_back ( clVec.at(iter)[1] );
6209  }
6210 
6211  double mean = std::accumulate ( hlpVals.begin(), hlpVals.end(), 0.0 ) / static_cast<double> ( hlpVals.size() );
6212  double sd = sqrt ( std::inner_product( hlpVals.begin(), hlpVals.end(), hlpVals.begin(), 0.0 ) / static_cast<double> ( hlpVals.size() ) - mean * mean );
6213  double thres = 0.0;
6214 
6215  std::vector< std::array<double,3> > hVec;
6216  for ( double iter = 5.0; iter >= 0.0; iter = iter - 0.5 )
6217  {
6218  thres = mean + ( iter * sd );
6219  hVec.clear ( );
6220 
6221  for ( unsigned int it = 0; it < static_cast<unsigned int> ( clVec.size() ); it++ )
6222  {
6223  if ( clVec.at(it)[1] >= thres )
6224  {
6225  hArr[0] = clVec.at(it)[0];
6226  hArr[1] = clVec.at(it)[2];
6227  hVec.emplace_back ( hArr );
6228  }
6229  }
6230 
6231  if ( ( hVec.size() > std::max ( std::floor ( clVec.size() * 0.05 ), 10.0 ) ) && ( hVec.size() < clVec.size() ) )
6232  {
6233  break;
6234  }
6235  }
6236 
6237  std::sort ( hVec.begin(), hVec.end(), [](const std::array<double,3>& a, const std::array<double,3>& b) { return a[0] < b[0]; });
6238  std::vector< std::vector<int> > clusts;
6239 
6240  hlpVals.clear ( );
6241  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hVec.size() ); iter++ )
6242  {
6243  hlpVals.emplace_back ( hVec.at(iter)[0] );
6244  }
6245 
6246  if ( hVec.size() == 0 )
6247  {
6248  return ( clusts );
6249  }
6250  if ( hVec.size() < 5 )
6251  {
6252  mean = hVec.at(hVec.size()-1)[0] + 0.0001;
6253  sd = mean / 12.0;
6254  }
6255  else
6256  {
6257  mean = std::accumulate ( hlpVals.begin(), hlpVals.end(), 0.0 ) / static_cast<double> ( hlpVals.size() );
6258  sd = sqrt ( std::inner_product( hlpVals.begin(), hlpVals.end(), hlpVals.begin(), 0.0 ) / static_cast<double> ( hlpVals.size() ) - mean * mean );
6259  }
6260 
6261  for ( double it = 3.0; it >= 0.0; it = it - 0.25 )
6262  {
6263  thres = mean - ( it * sd );
6264  clusts.clear ( );
6265 
6266  if ( it == 0.0 )
6267  {
6268  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hVec.size() ); iter++ )
6269  {
6270  thres = std::max ( hVec.at(iter)[0], thres );
6271  }
6272  }
6273 
6274  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hVec.size() ); iter++ )
6275  {
6276  if ( hVec.at(iter)[0] <= thres )
6277  {
6278  clusts.emplace_back ( clusters.at(hVec.at(iter)[1]) );
6279  }
6280  }
6281 
6282  if ( ( clusts.size() > 0 ) && ( clusts.size() < 5 ) )
6283  {
6284  if ( ( clusts.size() ) < hVec.size() )
6285  {
6286  if ( ( hVec.at(clusts.size()-1)[0] > 3.0 ) && ( ( 2.0 * hVec.at(clusts.size()-1)[0] ) < hVec.at(clusts.size())[0] ) )
6287  {
6288  break;
6289  }
6290  }
6291  }
6292 
6293  if ( ( clusts.size() > std::max ( std::floor ( hVec.size() * 0.1 ), 5.0 ) ) && ( clusts.size() < hVec.size() ) ) { break; }
6294  }
6295 
6296  //======================================== Done
6297  return ( clusts );
6298 
6299 }
6300 
6313  int verbose,
6314  ProSHADE::ProSHADE_settings* settings )
6315 {
6316  //======================================== Sanity check
6317  if ( this->fragBoxSize <= 0.0 )
6318  {
6319  std::cerr << "!!! ProSHADE ERROR !!! Tried to fragment the map to boxes of size " << this->fragBoxSize << " . Terminating..." << std::endl;
6320 
6321  if ( settings->htmlReport )
6322  {
6323  std::stringstream hlpSS;
6324  hlpSS << "<font color=\"red\">" << "The box size to which the map should be fragmented in not in the allowed range ( " << this->fragBoxSize << " )" << "</font>";
6325  rvapi_set_text ( hlpSS.str().c_str(),
6326  "ProgressSection",
6327  settings->htmlReportLineProgress,
6328  1,
6329  1,
6330  1 );
6331  settings->htmlReportLineProgress += 1;
6332  rvapi_flush ( );
6333  }
6334 
6335  exit ( -1 );
6336  }
6337 
6338  if ( verbose > 0 )
6339  {
6340  std::cout << "-----------------------------------------------------------" << std::endl;
6341  std::cout << "| MAP FRAGMENTATION |" << std::endl;
6342  std::cout << "-----------------------------------------------------------" << std::endl << std::endl;
6343  }
6344 
6345  //======================================== Find X, Y and Z starts and ends of the required boxes
6346  std::vector< std::array<unsigned int,2> > XDim;
6347  std::vector< std::array<unsigned int,2> > YDim;
6348  std::vector< std::array<unsigned int,2> > ZDim;
6349  std::array<unsigned int,2> hlpArrX;
6350  std::array<unsigned int,2> hlpArrY;
6351  std::array<unsigned int,2> hlpArrZ;
6352  double maxMapAngPerIndex = std::max ( this->one->_xRange / static_cast<double> ( this->one->_maxMapU ),
6353  std::max ( this->one->_yRange / static_cast<double> ( this->one->_maxMapV ),
6354  this->one->_zRange / static_cast<double> ( this->one->_maxMapW ) ) );
6355  unsigned int boxDimInIndices = static_cast<unsigned int> ( std::round ( this->fragBoxSize / maxMapAngPerIndex ) );
6356  if ( ( boxDimInIndices % 2 ) == 1 )
6357  {
6358  //==================================== If odd, change to even
6359  boxDimInIndices += 1;
6360  }
6361 
6362  //======================================== Problem! The box is too small
6363  if ( boxDimInIndices < 2 )
6364  {
6365  std::cerr << "!!! ProSHADE ERROR !!! The box size for fragmentation is too small, please increase the box size or submit more detailed map. (Increasing the number of points by interpolation could work without changing the map here...)" << std::endl;
6366 
6367  if ( settings->htmlReport )
6368  {
6369  std::stringstream hlpSS;
6370  hlpSS << "<font color=\"red\">" << "The box size for fragmentation is too small, please increase the box size or submit more detailed map. (Increasing the number of points by interpolation could work without changing the map here...)." << "</font>";
6371  rvapi_set_text ( hlpSS.str().c_str(),
6372  "ProgressSection",
6373  settings->htmlReportLineProgress,
6374  1,
6375  1,
6376  1 );
6377  settings->htmlReportLineProgress += 1;
6378  rvapi_flush ( );
6379  }
6380 
6381  exit ( -1 );
6382  }
6383  if ( ( boxDimInIndices >= this->one->_maxMapU ) || ( boxDimInIndices >= this->one->_maxMapV ) || ( boxDimInIndices >= this->one->_maxMapW ) )
6384  {
6385  std::cerr << "!!! ProSHADE ERROR !!! The box size for fragmentation is too large, please decrease the box size so that it is smaller than the map dimmensions." << std::endl;
6386 
6387  if ( settings->htmlReport )
6388  {
6389  std::stringstream hlpSS;
6390  hlpSS << "<font color=\"red\">" << "The box size for fragmentation is too large, please decrease the box size so that it is smaller than the map dimmensions." << "</font>";
6391  rvapi_set_text ( hlpSS.str().c_str(),
6392  "ProgressSection",
6393  settings->htmlReportLineProgress,
6394  1,
6395  1,
6396  1 );
6397  settings->htmlReportLineProgress += 1;
6398  rvapi_flush ( );
6399  }
6400 
6401  exit ( -1 );
6402  }
6403 
6404  //======================================== Generate box starts and ends
6405  for ( unsigned int xStart = 0; xStart <= ( this->one->_maxMapU - boxDimInIndices ); xStart += ( boxDimInIndices / 2 ) )
6406  {
6407  hlpArrX[0] = xStart;
6408  hlpArrX[1] = xStart + boxDimInIndices;
6409 
6410  //==================================== Check for terminal boxes, they may need to have larger size
6411  if ( ( xStart + ( boxDimInIndices / 2 ) ) > ( this->one->_maxMapU - boxDimInIndices ) )
6412  {
6413  //================================ This is the last X
6414  hlpArrX[1] = this->one->_maxMapU;
6415  }
6416 
6417  for ( unsigned int yStart = 0; yStart <= ( this->one->_maxMapV - boxDimInIndices ); yStart += ( boxDimInIndices / 2 ) )
6418  {
6419  hlpArrY[0] = yStart;
6420  hlpArrY[1] = yStart + boxDimInIndices;
6421 
6422  //================================ Check for terminal boxes, they may need to have larger size
6423  if ( ( yStart + ( boxDimInIndices / 2 ) ) > ( this->one->_maxMapV - boxDimInIndices ) )
6424  {
6425  //============================ This is the last Y
6426  hlpArrY[1] = this->one->_maxMapV;
6427  }
6428 
6429  for ( unsigned int zStart = 0; zStart <= ( this->one->_maxMapW - boxDimInIndices ); zStart += ( boxDimInIndices / 2 ) )
6430  {
6431  hlpArrZ[0] = zStart;
6432  hlpArrZ[1] = zStart + boxDimInIndices;
6433 
6434  //============================ Check for terminal boxes, they may need to have larger size
6435  if ( ( zStart + ( boxDimInIndices / 2 ) ) > ( this->one->_maxMapW - boxDimInIndices ) )
6436  {
6437  //======================== This is the last Z
6438  hlpArrZ[1] = this->one->_maxMapW;
6439  }
6440 
6441  XDim.emplace_back ( hlpArrX );
6442  YDim.emplace_back ( hlpArrY );
6443  ZDim.emplace_back ( hlpArrZ );
6444  }
6445  }
6446  }
6447 
6448  if ( verbose > 2 )
6449  {
6450  std::cout << ">> Box borders generated." << std::endl;
6451  }
6452 
6453  //======================================== If the box has enough density, write it out!
6454  unsigned int noDensityPoints = 0;
6455  unsigned int arrayPos = 0;
6456  unsigned int hlpPos = 0;
6457  int fileIter = 0;
6458  double boxVolume = 0.0;
6459  int newU, newV, newW;
6460  std::string fileName;
6461 
6462  for ( unsigned int boxIt = 0; boxIt < static_cast<unsigned int> ( XDim.size() ); boxIt++ )
6463  {
6464  //==================================== Check the box density fraction
6465  noDensityPoints = 0;
6466  for ( unsigned int x = XDim.at(boxIt)[0]; x <= XDim.at(boxIt)[1]; x++ )
6467  {
6468  for ( unsigned int y = YDim.at(boxIt)[0]; y <= YDim.at(boxIt)[1]; y++ )
6469  {
6470  for ( unsigned int z = ZDim.at(boxIt)[0]; z <= ZDim.at(boxIt)[1]; z++ )
6471  {
6472  arrayPos = z + (this->one->_maxMapW+1) * ( y + (this->one->_maxMapV+1) * x );
6473 
6474  if ( this->one->_densityMapCor[arrayPos] > 0.0 )
6475  {
6476  noDensityPoints += 1;
6477  }
6478  }
6479  }
6480  }
6481 
6482  //==================================== If passing, write out the box
6483  boxVolume = ( ( XDim.at(boxIt)[1] - XDim.at(boxIt)[0] ) + 1 ) * ( ( YDim.at(boxIt)[1] - YDim.at(boxIt)[0] ) + 1 ) * ( ( ZDim.at(boxIt)[1] - ZDim.at(boxIt)[0] ) + 1 );
6484 
6485  if ( ( static_cast<double> ( noDensityPoints ) / boxVolume ) > this->mapFragBoxFraction )
6486  {
6487  //================================ Solve file names
6488  fileName = this->mapFragName + std::to_string ( fileIter ) + ".map";
6489  this->fragFiles.emplace_back ( fileName );
6490  fileIter += 1;
6491  if ( verbose > 3 )
6492  {
6493  std::cout << ">>>>> Writing out box " << fileIter-1 << std::endl;
6494  }
6495 
6496  //================================ Create map fragment
6497  float *boxMap = nullptr;
6498  boxMap = (float*) malloc ( (XDim.at(boxIt)[1]-XDim.at(boxIt)[0]+1) * (YDim.at(boxIt)[1]-YDim.at(boxIt)[0]+1) * (ZDim.at(boxIt)[1]-ZDim.at(boxIt)[0]+1) * sizeof ( float ) );
6499  if ( boxMap == nullptr )
6500  {
6501  std::cerr << "!!! ProSHADE ERROR !!! Cannot allocate memory for map data. Terminating... " << std::endl;
6502 
6503  if ( settings->htmlReport )
6504  {
6505  std::stringstream hlpSS;
6506  hlpSS << "<font color=\"red\">" << "Cannot allocate memory. Could you have run out of memory?" << "</font>";
6507  rvapi_set_text ( hlpSS.str().c_str(),
6508  "ProgressSection",
6509  settings->htmlReportLineProgress,
6510  1,
6511  1,
6512  1 );
6513  settings->htmlReportLineProgress += 1;
6514  rvapi_flush ( );
6515  }
6516 
6517  exit ( -1 );
6518  }
6519 
6520  for ( unsigned int x = XDim.at(boxIt)[0]; x <= XDim.at(boxIt)[1]; x++ )
6521  {
6522  for ( unsigned int y = YDim.at(boxIt)[0]; y <= YDim.at(boxIt)[1]; y++ )
6523  {
6524  for ( unsigned int z = ZDim.at(boxIt)[0]; z <= ZDim.at(boxIt)[1]; z++ )
6525  {
6526  arrayPos = z + (this->one->_maxMapW+1) * ( y + (this->one->_maxMapV+1) * x );
6527 
6528  newU = x - XDim.at(boxIt)[0];
6529  newV = y - YDim.at(boxIt)[0];
6530  newW = z - ZDim.at(boxIt)[0];
6531  hlpPos = newW + (ZDim.at(boxIt)[1]-ZDim.at(boxIt)[0]) * ( newV + (YDim.at(boxIt)[1]-YDim.at(boxIt)[0]) * newU );
6532 
6533  boxMap[hlpPos] = this->one->_densityMapCor[arrayPos];
6534  }
6535  }
6536  }
6537 
6538  float xFrom = XDim.at(boxIt)[0] + this->one->_xFrom;
6539  float xTo = XDim.at(boxIt)[1] + this->one->_xFrom - 1;
6540  float yFrom = YDim.at(boxIt)[0] + this->one->_yFrom;
6541  float yTo = YDim.at(boxIt)[1] + this->one->_yFrom - 1;
6542  float zFrom = ZDim.at(boxIt)[0] + this->one->_zFrom;
6543  float zTo = ZDim.at(boxIt)[1] + this->one->_zFrom - 1;
6544 
6545  this->one->writeMap ( fileName.c_str(),
6546  boxMap,
6547  axOrder,
6548  xFrom,
6549  yFrom,
6550  zFrom,
6551  xTo,
6552  yTo,
6553  zTo,
6554  ( this->one->_xSamplingRate * ( XDim.at(boxIt)[1] - XDim.at(boxIt)[0] ) ),
6555  ( this->one->_ySamplingRate * ( YDim.at(boxIt)[1] - YDim.at(boxIt)[0] ) ),
6556  ( this->one->_zSamplingRate * ( ZDim.at(boxIt)[1] - ZDim.at(boxIt)[0] ) ) );
6557 
6558  free ( boxMap );
6559  boxMap = nullptr;
6560  }
6561  }
6562 
6563  if ( verbose > 0 )
6564  {
6565  if ( fileIter > 0 )
6566  {
6567  std::cout << ">> " << fileIter << " boxes written in " << this->mapFragName << "xx ." << std::endl << std::endl;
6568  }
6569  else
6570  {
6571  std::cout << ">> No boxes conform to your criteria. NO BOXES WRITTEN." << std::endl << std::endl;
6572  }
6573  }
6574  if ( fileIter == 0 )
6575  {
6576  std::cout << "!!! ProSHADE WARNING !!! No map fragments produced - no box passed the required criteria." << std::endl << std::endl;
6577 
6578  if ( settings->htmlReport )
6579  {
6580  std::stringstream hlpSS;
6581  hlpSS << "<font color=\"orange\">" << "No map fragments produced - no box passed the required criteria.." << "</font>";
6582  rvapi_set_text ( hlpSS.str().c_str(),
6583  "ProgressSection",
6584  settings->htmlReportLineProgress,
6585  1,
6586  1,
6587  1 );
6588  settings->htmlReportLineProgress += 1;
6589  rvapi_flush ( );
6590  }
6591  }
6592 
6593  //======================================== Note that fragmentation was attempted
6594  this->fragFilesExist = true;
6595 
6596  //======================================== Done
6597  return ;
6598 
6599 }
6600 
6615  double *xTranslate,
6616  double *yTranslate,
6617  double *zTranslate )
6618 {
6619  //======================================== Initialise local variables
6620  ProSHADE_data* halfMap1 = new ProSHADE_data ();
6621  ProSHADE_data* halfMap2 = new ProSHADE_data ();
6622 
6623  double shSpacing1 = settings->shellSpacing;
6624  double shSpacing2 = settings->shellSpacing;
6625  unsigned int bandwidth1 = settings->bandwidth;
6626  unsigned int bandwidth2 = settings->bandwidth;
6627  unsigned int theta1 = settings->theta;
6628  unsigned int theta2 = settings->theta;
6629  unsigned int phi1 = settings->phi;
6630  unsigned int phi2 = settings->phi;
6631  unsigned int glInteg1 = settings->glIntegOrder;
6632  unsigned int glInteg2 = settings->glIntegOrder;
6633 
6634  //======================================== Read in the first half map
6635  halfMap1->getDensityMapFromMAP ( settings->structFiles.at(0),
6636  &shSpacing1,
6637  settings->mapResolution,
6638  &bandwidth1,
6639  &theta1,
6640  &phi1,
6641  &glInteg1,
6642  &settings->extraSpace,
6643  settings->mapResDefault,
6644  settings->rotChangeDefault,
6645  settings,
6646  settings->overlayDefaults );
6647 
6648  if ( settings->verbose > 0 )
6649  {
6650  std::cout << "Read in the first half map." << std::endl;
6651  }
6652 
6653  if ( settings->htmlReport )
6654  {
6655  std::stringstream hlpSS;
6656  hlpSS << "<font color=\"green\">" << "Read in the first half map." << "</font>";
6657  rvapi_set_text ( hlpSS.str().c_str(),
6658  "ProgressSection",
6659  settings->htmlReportLineProgress,
6660  1,
6661  1,
6662  1 );
6663  settings->htmlReportLineProgress += 1;
6664  rvapi_flush ( );
6665  }
6666 
6667  //======================================== Read in the second half map
6668  halfMap2->getDensityMapFromMAP ( settings->structFiles.at(1),
6669  &shSpacing2,
6670  settings->mapResolution,
6671  &bandwidth2,
6672  &theta2,
6673  &phi2,
6674  &glInteg2,
6675  &settings->extraSpace,
6676  settings->mapResDefault,
6677  settings->rotChangeDefault,
6678  settings,
6679  settings->overlayDefaults );
6680 
6681  if ( settings->verbose > 0 )
6682  {
6683  std::cout << "Read in the second half map." << std::endl;
6684  }
6685 
6686  if ( settings->htmlReport )
6687  {
6688  std::stringstream hlpSS;
6689  hlpSS << "<font color=\"green\">" << "Read in the second half map." << "</font>";
6690  rvapi_set_text ( hlpSS.str().c_str(),
6691  "ProgressSection",
6692  settings->htmlReportLineProgress,
6693  1,
6694  1,
6695  1 );
6696  settings->htmlReportLineProgress += 1;
6697  rvapi_flush ( );
6698  }
6699 
6700  //======================================== Size and sampling checks
6701  bool sizeAndSampleIdentical = true;
6702  if ( ( halfMap1->_xRange != halfMap2->_xRange ) || ( halfMap1->_yRange != halfMap2->_yRange ) || ( halfMap1->_zRange != halfMap2->_zRange ) )
6703  {
6704  std::cout << "!!! ProSHADE WARNING !!! The cell ranges differ between the two half maps - this is not allowed for half maps. Will attempt to re-size and re-sample the maps, but beware this may not be what you wanted. Please check the output manually." << std::endl;
6705 
6706  if ( settings->htmlReport )
6707  {
6708  std::stringstream hlpSS;
6709  hlpSS << "<font color=\"orange\">" << "The cell ranges differ between the two half maps - this is not allowed for half maps. Will attempt to re-size and re-sample the maps, but beware this may not be what you wanted. Please check the output manually." << "</font>";
6710  rvapi_set_text ( hlpSS.str().c_str(),
6711  "ProgressSection",
6712  settings->htmlReportLineProgress,
6713  1,
6714  1,
6715  1 );
6716  settings->htmlReportLineProgress += 1;
6717  rvapi_flush ( );
6718  }
6719 
6720  sizeAndSampleIdentical = false;
6721  }
6722 
6723  if ( ( halfMap1->_maxMapU != halfMap2->_maxMapU ) || ( halfMap1->_maxMapV != halfMap2->_maxMapV ) || ( halfMap1->_maxMapW != halfMap2->_maxMapW ) )
6724  {
6725  std::cout << "!!! ProSHADE WARNING !!! The cell dimensions differ between the two half maps - this is not allowed for half maps. Will attempt to re-size and re-sample the maps, but beware this may not be what you wanted. Please check the output manually." << std::endl;
6726 
6727  if ( settings->htmlReport )
6728  {
6729  std::stringstream hlpSS;
6730  hlpSS << "<font color=\"orange\">" << "The cell dimensions differ between the two half maps - this is not allowed for half maps. Will attempt to re-size and re-sample the maps, but beware this may not be what you wanted. Please check the output manually." << "</font>";
6731  rvapi_set_text ( hlpSS.str().c_str(),
6732  "ProgressSection",
6733  settings->htmlReportLineProgress,
6734  1,
6735  1,
6736  1 );
6737  settings->htmlReportLineProgress += 1;
6738  rvapi_flush ( );
6739  }
6740 
6741  sizeAndSampleIdentical = false;
6742  }
6743 
6744  if ( !sizeAndSampleIdentical )
6745  {
6746  if ( settings->verbose > 0 )
6747  {
6748  std::cout << "Starting the re-sampling and re-sizing procedure. This may take some time." << std::endl;
6749  }
6750 
6751  if ( settings->htmlReport )
6752  {
6753  std::stringstream hlpSS;
6754  hlpSS << "<font color=\"green\">" << "Starting the re-sampling and re-sizing procedure. This may take some time." << "</font>";
6755  rvapi_set_text ( hlpSS.str().c_str(),
6756  "ProgressSection",
6757  settings->htmlReportLineProgress,
6758  1,
6759  1,
6760  1 );
6761  settings->htmlReportLineProgress += 1;
6762  rvapi_flush ( );
6763  }
6764 
6765  //==================================== Copy from initial hoder to full holder
6766  halfMap1->_densityMapCor = new double[(halfMap1->_maxMapU+1)*(halfMap1->_maxMapV+1)*(halfMap1->_maxMapW+1)];
6767  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (halfMap1->_maxMapU+1)*(halfMap1->_maxMapV+1)*(halfMap1->_maxMapW+1) ); iter++ )
6768  {
6769  halfMap1->_densityMapCor[iter] = halfMap1->_densityMapMap[iter];
6770  }
6771  delete[] halfMap1->_densityMapMap;
6772  halfMap1->_densityMapMap = nullptr;
6773 
6774  halfMap2->_densityMapCor = new double[(halfMap2->_maxMapU+1)*(halfMap2->_maxMapV+1)*(halfMap2->_maxMapW+1)];
6775  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( (halfMap2->_maxMapU+1)*(halfMap2->_maxMapV+1)*(halfMap2->_maxMapW+1) ); iter++ )
6776  {
6777  halfMap2->_densityMapCor[iter] = halfMap2->_densityMapMap[iter];
6778  }
6779  delete[] halfMap2->_densityMapMap;
6780  halfMap2->_densityMapMap = nullptr;
6781 
6782  //==================================== Match sampling and sizes
6783  ProSHADE_comparePairwise* cmpObj = new ProSHADE_comparePairwise ( halfMap2,
6784  halfMap2,
6785  settings->mPower,
6786  settings->ignoreLs,
6787  std::max ( glInteg1, glInteg2 ),
6788  settings );
6789  std::array<double,4> translationVec;
6790  double xMapMov, yMapMov, zMapMov;
6791  ProSHADE_data str1Copy = ProSHADE_data ( halfMap1 );
6792  translationVec = cmpObj->getTranslationFunctionMap ( &str1Copy, halfMap2, &xMapMov, &yMapMov, &zMapMov );
6793 
6794  delete cmpObj;
6795  }
6796 
6797  //======================================== Print headers of the input files
6798  if ( settings->htmlReport )
6799  {
6800  if ( sizeAndSampleIdentical )
6801  {
6802  rvapi_add_section ( "h1Header",
6803  "Half Map 1 Header",
6804  "body",
6805  settings->htmlReportLine,
6806  0,
6807  1,
6808  1,
6809  false );
6810  }
6811  else
6812  {
6813  rvapi_add_section ( "h1Header",
6814  "Half Map 1 Header (after re-sampling)",
6815  "body",
6816  settings->htmlReportLine,
6817  0,
6818  1,
6819  1,
6820  false );
6821  }
6822  settings->htmlReportLine += 1;
6823 
6824  //==================================== Print max U, V and W
6825  std::stringstream hlpSS;
6826  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
6827  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
6828  {
6829  hlpSS << ".";
6830  }
6831 
6832  int prec = 6;
6833  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapU+1 ), prec ).length(),
6834  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapV+1 ), prec ).length(),
6835  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapW+1 ), prec ).length() ) );
6836  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xFrom, prec ).length(),
6837  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yFrom, prec ).length(),
6838  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zFrom, prec ).length() ) );
6839  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xTo, prec ).length(),
6840  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yTo, prec ).length(),
6841  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zTo, prec ).length() ) );
6842  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xRange, prec ).length(),
6843  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yRange, prec ).length(),
6844  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zRange, prec ).length() ) );
6845  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, CDMAX ) ) );
6846  if ( spacer < 5 ) { spacer = 5; }
6847 
6848  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( halfMap1->_maxMapU+1 );
6849  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapU+1 ), prec ).length() ); iter++ )
6850  {
6851  hlpSS << " ";
6852  }
6853  hlpSS << " ";
6854 
6855  hlpSS << std::showpos << static_cast<int> ( halfMap1->_maxMapV+1 );
6856  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapV+1 ), prec ).length() ); iter++ )
6857  {
6858  hlpSS << " ";
6859  }
6860  hlpSS << " ";
6861 
6862  hlpSS << std::showpos << static_cast<int> ( halfMap1->_maxMapW+1 );
6863  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapW+1 ), prec ).length() ); iter++ )
6864  {
6865  hlpSS << " ";
6866  }
6867  hlpSS << "</pre>";
6868 
6869  rvapi_set_text ( hlpSS.str().c_str(),
6870  "h1Header",
6871  0,
6872  0,
6873  1,
6874  1 );
6875 
6876  //==================================== Print from and to lims
6877  hlpSS.str ( std::string ( ) );
6878  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
6879  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
6880  {
6881  hlpSS << ".";
6882  }
6883 
6884  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap1->_xFrom;
6885  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xFrom, prec ).length() ); iter++ )
6886  {
6887  hlpSS << " ";
6888  }
6889  hlpSS << " ";
6890 
6891  hlpSS << std::showpos << halfMap1->_xTo;
6892  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xTo, prec ).length() ); iter++ )
6893  {
6894  hlpSS << " ";
6895  }
6896  hlpSS << " ";
6897 
6898  hlpSS << std::showpos << halfMap1->_yFrom;
6899  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yFrom, prec ).length() ); iter++ )
6900  {
6901  hlpSS << " ";
6902  }
6903  hlpSS << " ";
6904 
6905  hlpSS << std::showpos << halfMap1->_yTo;
6906  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yTo, prec ).length() ); iter++ )
6907  {
6908  hlpSS << " ";
6909  }
6910  hlpSS << " ";
6911 
6912  hlpSS << std::showpos << " " << halfMap1->_zFrom;
6913  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zFrom, prec ).length() ); iter++ )
6914  {
6915  hlpSS << " ";
6916  }
6917  hlpSS << " ";
6918 
6919  hlpSS << std::showpos << halfMap1->_zTo;
6920  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zTo, prec ).length() ); iter++ )
6921  {
6922  hlpSS << " ";
6923  }
6924  hlpSS << "</pre>";
6925 
6926  rvapi_set_text ( hlpSS.str().c_str(),
6927  "h1Header",
6928  1,
6929  0,
6930  1,
6931  1 );
6932 
6933  //==================================== Print cell dimensions
6934  hlpSS.str ( std::string ( ) );
6935  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
6936  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
6937  {
6938  hlpSS << ".";
6939  }
6940 
6941  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap1->_xRange;
6942  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xRange, prec ).length() ); iter++ )
6943  {
6944  hlpSS << " ";
6945  }
6946  hlpSS << " ";
6947 
6948  hlpSS << std::showpos << halfMap1->_yRange;
6949  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yRange, prec ).length() ); iter++ )
6950  {
6951  hlpSS << " ";
6952  }
6953  hlpSS << " ";
6954 
6955  hlpSS << std::showpos << halfMap1->_zRange;
6956  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zRange, prec ).length() ); iter++ )
6957  {
6958  hlpSS << " ";
6959  }
6960  hlpSS << "</pre>";
6961 
6962  rvapi_set_text ( hlpSS.str().c_str(),
6963  "h1Header",
6964  2,
6965  0,
6966  1,
6967  1 );
6968 
6969  //==================================== Print cell dimensions
6970  hlpSS.str ( std::string ( ) );
6971  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
6972  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
6973  {
6974  hlpSS << ".";
6975  }
6976 
6977  hlpSS << std::showpos << std::setprecision ( prec ) << " " << 90.0;
6978  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
6979  {
6980  hlpSS << " ";
6981  }
6982  hlpSS << " ";
6983 
6984  hlpSS << std::showpos << 90.0;
6985  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
6986  {
6987  hlpSS << " ";
6988  }
6989  hlpSS << " ";
6990 
6991  hlpSS << std::showpos << 90.0;
6992  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
6993  {
6994  hlpSS << " ";
6995  }
6996  hlpSS << "</pre>";
6997 
6998  rvapi_set_text ( hlpSS.str().c_str(),
6999  "h1Header",
7000  3,
7001  0,
7002  1,
7003  1 );
7004 
7005  //==================================== Print cell dimensions
7006  hlpSS.str ( std::string ( ) );
7007  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
7008  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7009  {
7010  hlpSS << ".";
7011  }
7012 
7013  std::string hlpAO = settings->axisOrder;
7014  std::transform ( hlpAO.begin(), hlpAO.end(), hlpAO.begin(), ::toupper);
7015  hlpSS << " " << hlpAO;
7016  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
7017  {
7018  hlpSS << " ";
7019  }
7020  hlpSS << "</pre>";
7021 
7022  rvapi_set_text ( hlpSS.str().c_str(),
7023  "h1Header",
7024  4,
7025  0,
7026  1,
7027  1 );
7028 
7029  rvapi_flush ( );
7030  }
7031 
7032  if ( settings->htmlReport )
7033  {
7034  if ( sizeAndSampleIdentical )
7035  {
7036  rvapi_add_section ( "h2Header",
7037  "Half Map 2 Header",
7038  "body",
7039  settings->htmlReportLine,
7040  0,
7041  1,
7042  1,
7043  false );
7044  }
7045  else
7046  {
7047  rvapi_add_section ( "h2Header",
7048  "Half Map 2 Header (after re-sampling)",
7049  "body",
7050  settings->htmlReportLine,
7051  0,
7052  1,
7053  1,
7054  false );
7055  }
7056  settings->htmlReportLine += 1;
7057 
7058  //==================================== Print max U, V and W
7059  std::stringstream hlpSS;
7060  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
7061  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7062  {
7063  hlpSS << ".";
7064  }
7065 
7066  int prec = 6;
7067  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapU+1 ), prec ).length(),
7068  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapV+1 ), prec ).length(),
7069  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapW+1 ), prec ).length() ) );
7070  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xFrom, prec ).length(),
7071  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yFrom, prec ).length(),
7072  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zFrom, prec ).length() ) );
7073  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xTo, prec ).length(),
7074  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yTo, prec ).length(),
7075  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zTo, prec ).length() ) );
7076  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xRange, prec ).length(),
7077  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yRange, prec ).length(),
7078  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zRange, prec ).length() ) );
7079  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, CDMAX ) ) );
7080  if ( spacer < 5 ) { spacer = 5; }
7081 
7082  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( halfMap2->_maxMapU+1 );
7083  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapU+1 ), prec ).length() ); iter++ )
7084  {
7085  hlpSS << " ";
7086  }
7087  hlpSS << " ";
7088 
7089  hlpSS << std::showpos << static_cast<int> ( halfMap2->_maxMapV+1 );
7090  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapV+1 ), prec ).length() ); iter++ )
7091  {
7092  hlpSS << " ";
7093  }
7094  hlpSS << " ";
7095 
7096  hlpSS << std::showpos << static_cast<int> ( halfMap2->_maxMapW+1 );
7097  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapW+1 ), prec ).length() ); iter++ )
7098  {
7099  hlpSS << " ";
7100  }
7101  hlpSS << "</pre>";
7102 
7103  rvapi_set_text ( hlpSS.str().c_str(),
7104  "h2Header",
7105  0,
7106  0,
7107  1,
7108  1 );
7109 
7110  //==================================== Print from and to lims
7111  hlpSS.str ( std::string ( ) );
7112  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
7113  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7114  {
7115  hlpSS << ".";
7116  }
7117 
7118  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap2->_xFrom;
7119  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xFrom, prec ).length() ); iter++ )
7120  {
7121  hlpSS << " ";
7122  }
7123  hlpSS << " ";
7124 
7125  hlpSS << std::showpos << halfMap2->_xTo;
7126  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xTo, prec ).length() ); iter++ )
7127  {
7128  hlpSS << " ";
7129  }
7130  hlpSS << " ";
7131 
7132  hlpSS << std::showpos << halfMap2->_yFrom;
7133  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yFrom, prec ).length() ); iter++ )
7134  {
7135  hlpSS << " ";
7136  }
7137  hlpSS << " ";
7138 
7139  hlpSS << std::showpos << halfMap2->_yTo;
7140  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yTo, prec ).length() ); iter++ )
7141  {
7142  hlpSS << " ";
7143  }
7144  hlpSS << " ";
7145 
7146  hlpSS << std::showpos << " " << halfMap2->_zFrom;
7147  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zFrom, prec ).length() ); iter++ )
7148  {
7149  hlpSS << " ";
7150  }
7151  hlpSS << " ";
7152 
7153  hlpSS << std::showpos << halfMap2->_zTo;
7154  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zTo, prec ).length() ); iter++ )
7155  {
7156  hlpSS << " ";
7157  }
7158  hlpSS << "</pre>";
7159 
7160  rvapi_set_text ( hlpSS.str().c_str(),
7161  "h2Header",
7162  1,
7163  0,
7164  1,
7165  1 );
7166 
7167  //==================================== Print cell dimensions
7168  hlpSS.str ( std::string ( ) );
7169  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
7170  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7171  {
7172  hlpSS << ".";
7173  }
7174 
7175  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap2->_xRange;
7176  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xRange, prec ).length() ); iter++ )
7177  {
7178  hlpSS << " ";
7179  }
7180  hlpSS << " ";
7181 
7182  hlpSS << std::showpos << halfMap2->_yRange;
7183  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yRange, prec ).length() ); iter++ )
7184  {
7185  hlpSS << " ";
7186  }
7187  hlpSS << " ";
7188 
7189  hlpSS << std::showpos << halfMap2->_zRange;
7190  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zRange, prec ).length() ); iter++ )
7191  {
7192  hlpSS << " ";
7193  }
7194  hlpSS << "</pre>";
7195 
7196  rvapi_set_text ( hlpSS.str().c_str(),
7197  "h2Header",
7198  2,
7199  0,
7200  1,
7201  1 );
7202 
7203  //==================================== Print cell dimensions
7204  hlpSS.str ( std::string ( ) );
7205  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
7206  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7207  {
7208  hlpSS << ".";
7209  }
7210 
7211  hlpSS << std::showpos << std::setprecision ( prec ) << " " << 90.0;
7212  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7213  {
7214  hlpSS << " ";
7215  }
7216  hlpSS << " ";
7217 
7218  hlpSS << std::showpos << 90.0;
7219  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7220  {
7221  hlpSS << " ";
7222  }
7223  hlpSS << " ";
7224 
7225  hlpSS << std::showpos << 90.0;
7226  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7227  {
7228  hlpSS << " ";
7229  }
7230  hlpSS << "</pre>";
7231 
7232  rvapi_set_text ( hlpSS.str().c_str(),
7233  "h2Header",
7234  3,
7235  0,
7236  1,
7237  1 );
7238 
7239  //==================================== Print cell dimensions
7240  hlpSS.str ( std::string ( ) );
7241  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
7242  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7243  {
7244  hlpSS << ".";
7245  }
7246 
7247  std::string hlpAO = settings->axisOrder;
7248  std::transform ( hlpAO.begin(), hlpAO.end(), hlpAO.begin(), ::toupper);
7249  hlpSS << " " << hlpAO;
7250  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
7251  {
7252  hlpSS << " ";
7253  }
7254  hlpSS << "</pre>";
7255 
7256  rvapi_set_text ( hlpSS.str().c_str(),
7257  "h2Header",
7258  4,
7259  0,
7260  1,
7261  1 );
7262 
7263  rvapi_flush ( );
7264  }
7265 
7266  //======================================== Initialise local variables for Fourier and Inverse Fourier
7267  fftw_complex *tmpOutA;
7268  fftw_complex *tmpInA;
7269  fftw_complex *tmpOutB;
7270  fftw_complex *tmpInB;
7271  fftw_plan pA;
7272  fftw_plan pB;
7273 
7274  int hlpU = halfMap1->_maxMapU + 1;
7275  int hlpV = halfMap1->_maxMapV + 1;
7276  int hlpW = halfMap1->_maxMapW + 1;
7277 
7278  //======================================== Allocate the memory
7279  tmpInA = new fftw_complex[hlpU * hlpV * hlpW];
7280  tmpOutA = new fftw_complex[hlpU * hlpV * hlpW];
7281  tmpInB = new fftw_complex[hlpU * hlpV * hlpW];
7282  tmpOutB = new fftw_complex[hlpU * hlpV * hlpW];
7283 
7284  //======================================== Create plans (FFTW_MEASURE would change the arrays)
7285  pA = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpInA, tmpOutA, FFTW_FORWARD, FFTW_ESTIMATE );
7286  pB = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, tmpInB, tmpOutB, FFTW_FORWARD, FFTW_ESTIMATE );
7287 
7288  //======================================== Load map data for Fourier
7289  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
7290  {
7291  if ( halfMap1->_densityMapCor[iter] == halfMap1->_densityMapCor[iter] )
7292  {
7293  //================================ Map value is NOT nan
7294  tmpInA[iter][0] = halfMap1->_densityMapCor[iter];
7295  tmpInA[iter][1] = 0.0;
7296  }
7297  else
7298  {
7299  //================================ Map value is nan - this sometimes occurs for a couple of values, I have no clue as to why...
7300  tmpInA[iter][0] = 0.0;
7301  tmpInA[iter][1] = 0.0;
7302  }
7303 
7304  if ( halfMap2->_densityMapCor[iter] == halfMap2->_densityMapCor[iter] )
7305  {
7306  //================================ Map value is NOT nan
7307  tmpInB[iter][0] = halfMap2->_densityMapCor[iter];
7308  tmpInB[iter][1] = 0.0;
7309  }
7310  else
7311  {
7312  //================================ Map value is nan - this sometimes occurs for a couple of values, I have no clue as to why...
7313  tmpInB[iter][0] = 0.0;
7314  tmpInB[iter][1] = 0.0;
7315  }
7316  }
7317 
7318  //======================================== Execute FFTs
7319  fftw_execute ( pA );
7320  fftw_execute ( pB );
7321  fftw_destroy_plan ( pA );
7322  fftw_destroy_plan ( pB );
7323 
7324  //======================================== Initialise the mask data structure
7325  fftw_complex* maskDataA = new fftw_complex [ hlpU * hlpV * hlpW ];
7326  fftw_complex* maskDataInvA = new fftw_complex [ hlpU * hlpV * hlpW ];
7327  fftw_complex* maskDataB = new fftw_complex [ hlpU * hlpV * hlpW ];
7328  fftw_complex* maskDataInvB = new fftw_complex [ hlpU * hlpV * hlpW ];
7329 
7330  //======================================== Initialise local variables
7331  int uIt, vIt, wIt;
7332  double real, imag;
7333  unsigned int arrayPos = 0;
7334  double normFactor = (hlpU * hlpV * hlpW);
7335  double bFacChange = settings->maskBlurFactor;
7336  int h, k, l;
7337  double mag, phase, S;
7338 
7339  //======================================== Prepare FFTW plan for mask FFTW
7340  fftw_plan pMaskInvA = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, maskDataInvA, maskDataA, FFTW_BACKWARD, FFTW_ESTIMATE );
7341  fftw_plan pMaskInvB = fftw_plan_dft_3d ( hlpU, hlpV, hlpW, maskDataInvB, maskDataB, FFTW_BACKWARD, FFTW_ESTIMATE );
7342 
7343  for ( uIt = 0; uIt < hlpU; uIt++ )
7344  {
7345  for ( vIt = 0; vIt < hlpV; vIt++ )
7346  {
7347  for ( wIt = 0; wIt < hlpW; wIt++ )
7348  {
7349  //============================ FOR MAP A
7350  // ... Var init
7351  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
7352  real = tmpOutA[arrayPos][0];
7353  imag = tmpOutA[arrayPos][1];
7354 
7355  // ... Change the B-factors, if required
7356  if ( uIt > (hlpU / 2) ) { h = uIt - hlpU; } else { h = uIt; }
7357  if ( vIt > (hlpV / 2) ) { k = vIt - hlpV; } else { k = vIt; }
7358  if ( wIt > (hlpW / 2) ) { l = wIt - hlpW; } else { l = wIt; }
7359 
7360  // ... Get magnitude and phase with mask parameters
7361  S = ( pow( static_cast<double> ( h ) / halfMap1->_xRange, 2.0 ) +
7362  pow( static_cast<double> ( k ) / halfMap1->_yRange, 2.0 ) +
7363  pow( static_cast<double> ( l ) / halfMap1->_zRange, 2.0 ) );
7364  mag = sqrt ( (real*real) + (imag*imag) ) * std::exp ( - ( ( bFacChange * S ) / 4.0 ) );
7365  phase = atan2 ( imag, real );
7366 
7367  // ... Save the mask data
7368  maskDataInvA[arrayPos][0] = ( mag * cos(phase) ) / normFactor;
7369  maskDataInvA[arrayPos][1] = ( mag * sin(phase) ) / normFactor;
7370 
7371  //============================ FOR MAP B
7372  // ... Var init
7373  real = tmpOutB[arrayPos][0];
7374  imag = tmpOutB[arrayPos][1];
7375 
7376  // ... Get magnitude and phase with mask parameters
7377  S = ( pow( static_cast<double> ( h ) / halfMap2->_xRange, 2.0 ) +
7378  pow( static_cast<double> ( k ) / halfMap2->_yRange, 2.0 ) +
7379  pow( static_cast<double> ( l ) / halfMap2->_zRange, 2.0 ) );
7380  mag = sqrt ( (real*real) + (imag*imag) ) * std::exp ( - ( ( bFacChange * S ) / 4.0 ) );
7381  phase = atan2 ( imag, real );
7382 
7383  // ... Save the mask data
7384  maskDataInvB[arrayPos][0] = ( mag * cos(phase) ) / normFactor;
7385  maskDataInvB[arrayPos][1] = ( mag * sin(phase) ) / normFactor;
7386  }
7387  }
7388  }
7389 
7390  //======================================== Execute the inversions
7391  fftw_execute ( pMaskInvA );
7392  fftw_execute ( pMaskInvB );
7393  fftw_destroy_plan ( pMaskInvA );
7394  fftw_destroy_plan ( pMaskInvB );
7395  delete[] maskDataInvA;
7396  delete[] maskDataInvB;
7397  delete[] tmpOutA;
7398  delete[] tmpOutB;
7399 
7400  if ( settings->verbose > 2 )
7401  {
7402  std::cout << ">>>>> Map blurring complete." << std::endl;
7403  }
7404 
7405  if ( settings->htmlReport )
7406  {
7407  std::stringstream hlpSS;
7408  hlpSS << "<font color=\"green\">" << "Map blurring complete." << "</font>";
7409  rvapi_set_text ( hlpSS.str().c_str(),
7410  "ProgressSection",
7411  settings->htmlReportLineProgress,
7412  1,
7413  1,
7414  1 );
7415  settings->htmlReportLineProgress += 1;
7416  rvapi_flush ( );
7417  }
7418 
7419  //======================================== Find mask threshold
7420  double mapThresholdPlusA = 0.0;
7421  double mapThresholdPlusB = 0.0;
7422  unsigned int hlpIt = 0;
7423  std::vector<double> maskValsA ( hlpU * hlpV * hlpW );
7424  std::vector<double> maskValsB ( hlpU * hlpV * hlpW );
7425 
7426  for ( uIt = 0; uIt < hlpU; uIt++ ) { for ( vIt = 0; vIt < hlpV; vIt++ ) { for ( wIt = 0; wIt < hlpW; wIt++ ) { arrayPos = wIt + hlpW * ( vIt + hlpV * uIt ); maskValsA.at(hlpIt) = maskDataA[arrayPos][0]; maskValsB.at(hlpIt) = maskDataB[arrayPos][0]; hlpIt += 1; } } }
7427 
7428  unsigned int medianPos = static_cast<unsigned int> ( maskValsA.size() / 2 );
7429  std::sort ( maskValsA.begin(), maskValsA.end() );
7430  std::sort ( maskValsB.begin(), maskValsB.end() );
7431 
7432  double interQuartileRangeA = maskValsA.at(medianPos+(medianPos/2)) - maskValsA.at(medianPos-(medianPos/2));
7433  mapThresholdPlusA = maskValsA.at(medianPos+(medianPos/2)) + ( interQuartileRangeA * settings->noIQRsFromMap );
7434 
7435  double interQuartileRangeB = maskValsB.at(medianPos+(medianPos/2)) - maskValsB.at(medianPos-(medianPos/2));
7436  mapThresholdPlusB = maskValsB.at(medianPos+(medianPos/2)) + ( interQuartileRangeB * settings->noIQRsFromMap );
7437 
7438  maskValsA.clear ( );
7439  maskValsB.clear ( );
7440 
7441  //======================================== Apply the mask
7442  for ( uIt = 0; uIt < hlpU; uIt++ )
7443  {
7444  for ( vIt = 0; vIt < hlpV; vIt++ )
7445  {
7446  for ( wIt = 0; wIt < hlpW; wIt++ )
7447  {
7448  //============================ Var init
7449  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
7450 
7451  //============================ Apply mask
7452  if ( mapThresholdPlusA >= maskDataA[arrayPos][0] )
7453  {
7454  tmpInA[arrayPos][0] = 0.0;
7455  }
7456  if ( mapThresholdPlusB >= maskDataB[arrayPos][0] )
7457  {
7458  tmpInB[arrayPos][0] = 0.0;
7459  }
7460  }
7461  }
7462  }
7463 
7464  //======================================== Free unnecessary memory
7465  delete[] maskDataA;
7466  delete[] maskDataB;
7467 
7468  if ( settings->htmlReport )
7469  {
7470  std::stringstream hlpSS;
7471  hlpSS << "<font color=\"green\">" << "Map masking complete." << "</font>";
7472  rvapi_set_text ( hlpSS.str().c_str(),
7473  "ProgressSection",
7474  settings->htmlReportLineProgress,
7475  1,
7476  1,
7477  1 );
7478  settings->htmlReportLineProgress += 1;
7479  rvapi_flush ( );
7480  }
7481 
7482 
7483  //======================================== Check for obvious errors
7484  bool atLeastSingleValueA = false;
7485  bool atLeastSingleValueB = false;
7486  for ( uIt = 0; uIt < hlpU; uIt++ )
7487  {
7488  for ( vIt = 0; vIt < hlpV; vIt++ )
7489  {
7490  for ( wIt = 0; wIt < hlpW; wIt++ )
7491  {
7492  //============================ Find current array pos
7493  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
7494 
7495  if ( !atLeastSingleValueA ) { if ( tmpInA[arrayPos][0] > 0.0 ) { atLeastSingleValueA = true; } }
7496  if ( !atLeastSingleValueB ) { if ( tmpInB[arrayPos][0] > 0.0 ) { atLeastSingleValueB = true; } }
7497  }
7498  }
7499  }
7500 
7501  if ( !atLeastSingleValueA || !atLeastSingleValueB )
7502  {
7503  printf ( "!!! ProSHADE ERROR !!! The masking procedure failed to detect any significant density in the map!\n" );
7504 
7505  if ( settings->htmlReport )
7506  {
7507  std::stringstream hlpSS;
7508  hlpSS << "<font color=\"red\">" << "The masking procedure failed to detect any significant density in the map. Please consider changing the blurring coefficient value." << "</font>";
7509  rvapi_set_text ( hlpSS.str().c_str(),
7510  "ProgressSection",
7511  settings->htmlReportLineProgress,
7512  1,
7513  1,
7514  1 );
7515  settings->htmlReportLineProgress += 1;
7516  rvapi_flush ( );
7517  }
7518 
7519  exit ( -1 );
7520  }
7521 
7522  //======================================== Determine the real size of the shape
7523  int maxX = 0;
7524  int minX = hlpU;
7525  int maxY = 0;
7526  int minY = hlpV;
7527  int maxZ = 0;
7528  int minZ = hlpW;
7529  int arrPos = 0;
7530 
7531  for ( uIt = 0; uIt < hlpU; uIt++ )
7532  {
7533  for ( vIt = 0; vIt < hlpV; vIt++ )
7534  {
7535  for ( wIt = 0; wIt < hlpW; wIt++ )
7536  {
7537  arrPos = wIt + hlpW * ( vIt + hlpV * uIt );
7538 
7539  if ( tmpInA[arrPos][0] > 0.0 )
7540  {
7541  maxX = std::max ( maxX, uIt );
7542  minX = std::min ( minX, uIt );
7543  maxY = std::max ( maxY, vIt );
7544  minY = std::min ( minY, vIt );
7545  maxZ = std::max ( maxZ, wIt );
7546  minZ = std::min ( minZ, wIt );
7547  }
7548  if ( tmpInB[arrPos][0] > 0.0 )
7549  {
7550  maxX = std::max ( maxX, uIt );
7551  minX = std::min ( minX, uIt );
7552  maxY = std::max ( maxY, vIt );
7553  minY = std::min ( minY, vIt );
7554  maxZ = std::max ( maxZ, wIt );
7555  minZ = std::min ( minZ, wIt );
7556  }
7557  }
7558  }
7559  }
7560 
7561  delete[] tmpInA;
7562  delete[] tmpInB;
7563 
7564  //======================================== Add 7.5+ angstroms to make sure inter-cell interactions do not occur
7565  maxX += std::ceil ( 7.5 / halfMap1->_xSamplingRate );
7566  maxY += std::ceil ( 7.5 / halfMap1->_ySamplingRate );
7567  maxZ += std::ceil ( 7.5 / halfMap1->_zSamplingRate );
7568  minX -= std::ceil ( 7.5 / halfMap1->_xSamplingRate );
7569  minY -= std::ceil ( 7.5 / halfMap1->_ySamplingRate );
7570  minZ -= std::ceil ( 7.5 / halfMap1->_zSamplingRate );
7571 
7572  if ( maxX > static_cast<int> ( halfMap1->_maxMapU ) ) { maxX = halfMap1->_maxMapU; }
7573  if ( maxY > static_cast<int> ( halfMap1->_maxMapV ) ) { maxY = halfMap1->_maxMapV; }
7574  if ( maxZ > static_cast<int> ( halfMap1->_maxMapW ) ) { maxZ = halfMap1->_maxMapW; }
7575  if ( minX < 0 ) { minX = 0; }
7576  if ( minY < 0 ) { minY = 0; }
7577  if ( minZ < 0 ) { minZ = 0; }
7578 
7579  //======================================== Make cube
7580  if ( settings->useCubicMaps )
7581  {
7582  minX = std::max ( 0, std::min ( minX, std::min ( minY, minZ ) ) );
7583  minY = std::max ( 0, std::min ( minX, std::min ( minY, minZ ) ) );
7584  minZ = std::max ( 0, std::min ( minX, std::min ( minY, minZ ) ) );
7585  maxX = std::min ( hlpU, std::max ( maxX , std::max ( maxY , maxZ ) ) );
7586  maxY = std::min ( hlpV, std::max ( maxX , std::max ( maxY , maxZ ) ) );
7587  maxZ = std::min ( hlpW, std::max ( maxX , std::max ( maxY , maxZ ) ) );
7588 
7589  if ( ( maxX != maxY ) || ( maxX != maxZ ) || ( maxY != maxZ ) )
7590  {
7591  std::cout << "!!! ProSHADE Warning !!! Although cubic map was requested, this cannot be done as the input is not cubic and cutting it to cubic would result in density being removed. Maps will not be cubic." << std::endl;
7592 
7593  if ( settings->htmlReport )
7594  {
7595  std::stringstream hlpSS;
7596  hlpSS << "<font color=\"orange\">" << "Although cubic map was requested, this cannot be done as the input is not cubic and cutting it to cubic would result in density being removed. Maps will not be cubic." << "</font>";
7597  rvapi_set_text ( hlpSS.str().c_str(),
7598  "ProgressSection",
7599  settings->htmlReportLineProgress,
7600  1,
7601  1,
7602  1 );
7603  settings->htmlReportLineProgress += 1;
7604  rvapi_flush ( );
7605  }
7606  }
7607  }
7608 
7609  //======================================== Create new maps
7610  int xDim = 1 + maxX - minX;
7611  int yDim = 1 + maxY - minY;
7612  int zDim = 1 + maxZ - minZ;
7613  int hlpPos = 0;
7614 
7615  double* newHalf1Map = new double[xDim * yDim * zDim];
7616  double* newHalf2Map = new double[xDim * yDim * zDim];
7617 
7618  for ( int xIt = 0; xIt < hlpU; xIt++ )
7619  {
7620  for ( int yIt = 0; yIt < hlpV; yIt++ )
7621  {
7622  for ( int zIt = 0; zIt < hlpW; zIt++ )
7623  {
7624  if ( ( xIt < minX ) || ( xIt > maxX ) ) { continue; }
7625  if ( ( yIt < minY ) || ( yIt > maxY ) ) { continue; }
7626  if ( ( zIt < minZ ) || ( zIt > maxZ ) ) { continue; }
7627 
7628  arrPos = zIt + hlpW * ( yIt + hlpV * xIt );
7629  hlpPos = (zIt - minZ) + zDim * ( (yIt - minY) + yDim * (xIt - minX) );
7630 
7631  newHalf1Map[hlpPos] = halfMap1->_densityMapCor[arrPos];
7632  newHalf2Map[hlpPos] = halfMap2->_densityMapCor[arrPos];
7633  }
7634  }
7635  }
7636 
7637  //======================================== Copy
7638  delete[] halfMap1->_densityMapCor;
7639  delete[] halfMap2->_densityMapCor;
7640  halfMap1->_densityMapCor = new double[xDim * yDim * zDim];
7641  halfMap2->_densityMapCor = new double[xDim * yDim * zDim];
7642  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( xDim * yDim * zDim ); iter++ )
7643  {
7644  halfMap1->_densityMapCor[iter] = newHalf1Map[iter];
7645  halfMap2->_densityMapCor[iter] = newHalf2Map[iter];
7646  }
7647  delete[] newHalf1Map;
7648  delete[] newHalf2Map;
7649 
7650  if ( settings->htmlReport )
7651  {
7652  std::stringstream hlpSS;
7653  hlpSS << "<font color=\"green\">" << "Half maps re-boxed." << "</font>";
7654  rvapi_set_text ( hlpSS.str().c_str(),
7655  "ProgressSection",
7656  settings->htmlReportLineProgress,
7657  1,
7658  1,
7659  1 );
7660  settings->htmlReportLineProgress += 1;
7661  rvapi_flush ( );
7662  }
7663 
7664  //======================================== Set object headers
7665  int oDimX1 = halfMap1->_maxMapU;
7666  int oDimY1 = halfMap1->_maxMapV;
7667  int oDimZ1 = halfMap1->_maxMapW;
7668 
7669  int oDimX2 = halfMap2->_maxMapU;
7670  int oDimY2 = halfMap2->_maxMapV;
7671  int oDimZ2 = halfMap2->_maxMapW;
7672 
7673  halfMap1->_maxMapU = xDim;
7674  halfMap1->_maxMapV = yDim;
7675  halfMap1->_maxMapW = zDim;
7676 
7677  halfMap1->_xTo = maxX + halfMap1->_xFrom;
7678  halfMap1->_yTo = maxY + halfMap1->_yFrom;
7679  halfMap1->_zTo = maxZ + halfMap1->_zFrom;
7680 
7681  halfMap1->_xFrom = minX + halfMap1->_xFrom;
7682  halfMap1->_yFrom = minY + halfMap1->_yFrom;
7683  halfMap1->_zFrom = minZ + halfMap1->_zFrom;
7684 
7685  halfMap1->_xRange = xDim * halfMap1->_xSamplingRate;
7686  halfMap1->_yRange = yDim * halfMap1->_ySamplingRate;
7687  halfMap1->_zRange = zDim * halfMap1->_zSamplingRate;
7688 
7689  halfMap2->_maxMapU = xDim;
7690  halfMap2->_maxMapV = yDim;
7691  halfMap2->_maxMapW = zDim;
7692 
7693  halfMap2->_xTo = maxX + halfMap2->_xFrom;
7694  halfMap2->_yTo = maxY + halfMap2->_yFrom;
7695  halfMap2->_zTo = maxZ + halfMap2->_zFrom;
7696 
7697  halfMap2->_xFrom = minX + halfMap2->_xFrom;
7698  halfMap2->_yFrom = minY + halfMap2->_yFrom;
7699  halfMap2->_zFrom = minZ + halfMap2->_zFrom;
7700 
7701  halfMap2->_xRange = xDim * halfMap2->_xSamplingRate;
7702  halfMap2->_yRange = yDim * halfMap2->_ySamplingRate;
7703  halfMap2->_zRange = zDim * halfMap2->_zSamplingRate;
7704 
7705  //======================================== Print headers of the output files
7706  if ( settings->htmlReport )
7707  {
7708  rvapi_add_section ( "h1OutHeader",
7709  "Half Map 1 Re-boxed Header",
7710  "body",
7711  settings->htmlReportLine,
7712  0,
7713  1,
7714  1,
7715  false );
7716  settings->htmlReportLine += 1;
7717 
7718  //==================================== Print max U, V and W
7719  std::stringstream hlpSS;
7720  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
7721  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7722  {
7723  hlpSS << ".";
7724  }
7725 
7726  int prec = 6;
7727  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapU+1 ), prec ).length(),
7728  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapV+1 ), prec ).length(),
7729  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapW+1 ), prec ).length() ) );
7730  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xFrom, prec ).length(),
7731  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yFrom, prec ).length(),
7732  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zFrom, prec ).length() ) );
7733  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xTo, prec ).length(),
7734  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yTo, prec ).length(),
7735  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zTo, prec ).length() ) );
7736  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xRange, prec ).length(),
7737  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yRange, prec ).length(),
7738  ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zRange, prec ).length() ) );
7739  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, CDMAX ) ) );
7740  if ( spacer < 5 ) { spacer = 5; }
7741 
7742  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( halfMap1->_maxMapU+1 );
7743  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapU+1 ), prec ).length() ); iter++ )
7744  {
7745  hlpSS << " ";
7746  }
7747  hlpSS << " ";
7748 
7749  hlpSS << std::showpos << static_cast<int> ( halfMap1->_maxMapV+1 );
7750  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapV+1 ), prec ).length() ); iter++ )
7751  {
7752  hlpSS << " ";
7753  }
7754  hlpSS << " ";
7755 
7756  hlpSS << std::showpos << static_cast<int> ( halfMap1->_maxMapW+1 );
7757  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap1->_maxMapW+1 ), prec ).length() ); iter++ )
7758  {
7759  hlpSS << " ";
7760  }
7761  hlpSS << "</pre>";
7762 
7763  rvapi_set_text ( hlpSS.str().c_str(),
7764  "h1OutHeader",
7765  0,
7766  0,
7767  1,
7768  1 );
7769 
7770  //==================================== Print from and to lims
7771  hlpSS.str ( std::string ( ) );
7772  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
7773  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7774  {
7775  hlpSS << ".";
7776  }
7777 
7778  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap1->_xFrom;
7779  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xFrom, prec ).length() ); iter++ )
7780  {
7781  hlpSS << " ";
7782  }
7783  hlpSS << " ";
7784 
7785  hlpSS << std::showpos << halfMap1->_xTo;
7786  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xTo, prec ).length() ); iter++ )
7787  {
7788  hlpSS << " ";
7789  }
7790  hlpSS << " ";
7791 
7792  hlpSS << std::showpos << halfMap1->_yFrom;
7793  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yFrom, prec ).length() ); iter++ )
7794  {
7795  hlpSS << " ";
7796  }
7797  hlpSS << " ";
7798 
7799  hlpSS << std::showpos << halfMap1->_yTo;
7800  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yTo, prec ).length() ); iter++ )
7801  {
7802  hlpSS << " ";
7803  }
7804  hlpSS << " ";
7805 
7806  hlpSS << std::showpos << " " << halfMap1->_zFrom;
7807  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zFrom, prec ).length() ); iter++ )
7808  {
7809  hlpSS << " ";
7810  }
7811  hlpSS << " ";
7812 
7813  hlpSS << std::showpos << halfMap1->_zTo;
7814  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zTo, prec ).length() ); iter++ )
7815  {
7816  hlpSS << " ";
7817  }
7818  hlpSS << "</pre>";
7819 
7820  rvapi_set_text ( hlpSS.str().c_str(),
7821  "h1OutHeader",
7822  1,
7823  0,
7824  1,
7825  1 );
7826 
7827  //==================================== Print cell dimensions
7828  hlpSS.str ( std::string ( ) );
7829  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
7830  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7831  {
7832  hlpSS << ".";
7833  }
7834 
7835  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap1->_xRange;
7836  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_xRange, prec ).length() ); iter++ )
7837  {
7838  hlpSS << " ";
7839  }
7840  hlpSS << " ";
7841 
7842  hlpSS << std::showpos << halfMap1->_yRange;
7843  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_yRange, prec ).length() ); iter++ )
7844  {
7845  hlpSS << " ";
7846  }
7847  hlpSS << " ";
7848 
7849  hlpSS << std::showpos << halfMap1->_zRange;
7850  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap1->_zRange, prec ).length() ); iter++ )
7851  {
7852  hlpSS << " ";
7853  }
7854  hlpSS << "</pre>";
7855 
7856  rvapi_set_text ( hlpSS.str().c_str(),
7857  "h1OutHeader",
7858  2,
7859  0,
7860  1,
7861  1 );
7862 
7863  //==================================== Print cell dimensions
7864  hlpSS.str ( std::string ( ) );
7865  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
7866  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7867  {
7868  hlpSS << ".";
7869  }
7870 
7871  hlpSS << std::showpos << std::setprecision ( prec ) << " " << 90.0;
7872  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7873  {
7874  hlpSS << " ";
7875  }
7876  hlpSS << " ";
7877 
7878  hlpSS << std::showpos << 90.0;
7879  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7880  {
7881  hlpSS << " ";
7882  }
7883  hlpSS << " ";
7884 
7885  hlpSS << std::showpos << 90.0;
7886  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
7887  {
7888  hlpSS << " ";
7889  }
7890  hlpSS << "</pre>";
7891 
7892  rvapi_set_text ( hlpSS.str().c_str(),
7893  "h1OutHeader",
7894  3,
7895  0,
7896  1,
7897  1 );
7898 
7899  //==================================== Print cell dimensions
7900  hlpSS.str ( std::string ( ) );
7901  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
7902  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7903  {
7904  hlpSS << ".";
7905  }
7906 
7907  std::string hlpAO = settings->axisOrder;
7908  std::transform ( hlpAO.begin(), hlpAO.end(), hlpAO.begin(), ::toupper);
7909  hlpSS << " " << hlpAO;
7910  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
7911  {
7912  hlpSS << " ";
7913  }
7914  hlpSS << "</pre>";
7915 
7916  rvapi_set_text ( hlpSS.str().c_str(),
7917  "h1OutHeader",
7918  4,
7919  0,
7920  1,
7921  1 );
7922 
7923  rvapi_flush ( );
7924  }
7925 
7926  if ( settings->htmlReport )
7927  {
7928  rvapi_add_section ( "h2OutHeader",
7929  "Half Map 2 Re-boxed Header",
7930  "body",
7931  settings->htmlReportLine,
7932  0,
7933  1,
7934  1,
7935  false );
7936  settings->htmlReportLine += 1;
7937 
7938  //==================================== Print max U, V and W
7939  std::stringstream hlpSS;
7940  hlpSS << "<pre><b>" << "Rows, Columns and Sections sizes: " << "</b>";
7941  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7942  {
7943  hlpSS << ".";
7944  }
7945 
7946  int prec = 6;
7947  int UVWMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapU+1 ), prec ).length(),
7948  std::max ( ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapV+1 ), prec ).length(),
7949  ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapW+1 ), prec ).length() ) );
7950  int FMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xFrom, prec ).length(),
7951  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yFrom, prec ).length(),
7952  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zFrom, prec ).length() ) );
7953  int TMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xTo, prec ).length(),
7954  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yTo, prec ).length(),
7955  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zTo, prec ).length() ) );
7956  int CDMAX = std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xRange, prec ).length(),
7957  std::max ( ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yRange, prec ).length(),
7958  ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zRange, prec ).length() ) );
7959  int spacer = std::max ( UVWMAX, std::max ( FMAX, std::max ( TMAX, CDMAX ) ) );
7960  if ( spacer < 5 ) { spacer = 5; }
7961 
7962  hlpSS << std::showpos << std::setprecision ( prec ) << " " << static_cast<int> ( halfMap2->_maxMapU+1 );
7963  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapU+1 ), prec ).length() ); iter++ )
7964  {
7965  hlpSS << " ";
7966  }
7967  hlpSS << " ";
7968 
7969  hlpSS << std::showpos << static_cast<int> ( halfMap2->_maxMapV+1 );
7970  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapV+1 ), prec ).length() ); iter++ )
7971  {
7972  hlpSS << " ";
7973  }
7974  hlpSS << " ";
7975 
7976  hlpSS << std::showpos << static_cast<int> ( halfMap2->_maxMapW+1 );
7977  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( static_cast<int> ( halfMap2->_maxMapW+1 ), prec ).length() ); iter++ )
7978  {
7979  hlpSS << " ";
7980  }
7981  hlpSS << "</pre>";
7982 
7983  rvapi_set_text ( hlpSS.str().c_str(),
7984  "h2OutHeader",
7985  0,
7986  0,
7987  1,
7988  1 );
7989 
7990  //==================================== Print from and to lims
7991  hlpSS.str ( std::string ( ) );
7992  hlpSS << "<pre><b>" << "Start and stop points on columns, rows, sections: " << "</b>";
7993  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
7994  {
7995  hlpSS << ".";
7996  }
7997 
7998  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap2->_xFrom;
7999  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xFrom, prec ).length() ); iter++ )
8000  {
8001  hlpSS << " ";
8002  }
8003  hlpSS << " ";
8004 
8005  hlpSS << std::showpos << halfMap2->_xTo;
8006  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xTo, prec ).length() ); iter++ )
8007  {
8008  hlpSS << " ";
8009  }
8010  hlpSS << " ";
8011 
8012  hlpSS << std::showpos << halfMap2->_yFrom;
8013  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yFrom, prec ).length() ); iter++ )
8014  {
8015  hlpSS << " ";
8016  }
8017  hlpSS << " ";
8018 
8019  hlpSS << std::showpos << halfMap2->_yTo;
8020  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yTo, prec ).length() ); iter++ )
8021  {
8022  hlpSS << " ";
8023  }
8024  hlpSS << " ";
8025 
8026  hlpSS << std::showpos << " " << halfMap2->_zFrom;
8027  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zFrom, prec ).length() ); iter++ )
8028  {
8029  hlpSS << " ";
8030  }
8031  hlpSS << " ";
8032 
8033  hlpSS << std::showpos << halfMap2->_zTo;
8034  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zTo, prec ).length() ); iter++ )
8035  {
8036  hlpSS << " ";
8037  }
8038  hlpSS << "</pre>";
8039 
8040  rvapi_set_text ( hlpSS.str().c_str(),
8041  "h2OutHeader",
8042  1,
8043  0,
8044  1,
8045  1 );
8046 
8047  //==================================== Print cell dimensions
8048  hlpSS.str ( std::string ( ) );
8049  hlpSS << "<pre><b>" << "Cell dimensions (Angstrom): " << "</b>";
8050  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
8051  {
8052  hlpSS << ".";
8053  }
8054 
8055  hlpSS << std::showpos << std::setprecision ( prec ) << " " << halfMap2->_xRange;
8056  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_xRange, prec ).length() ); iter++ )
8057  {
8058  hlpSS << " ";
8059  }
8060  hlpSS << " ";
8061 
8062  hlpSS << std::showpos << halfMap2->_yRange;
8063  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_yRange, prec ).length() ); iter++ )
8064  {
8065  hlpSS << " ";
8066  }
8067  hlpSS << " ";
8068 
8069  hlpSS << std::showpos << halfMap2->_zRange;
8070  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( halfMap2->_zRange, prec ).length() ); iter++ )
8071  {
8072  hlpSS << " ";
8073  }
8074  hlpSS << "</pre>";
8075 
8076  rvapi_set_text ( hlpSS.str().c_str(),
8077  "h2OutHeader",
8078  2,
8079  0,
8080  1,
8081  1 );
8082 
8083  //==================================== Print cell dimensions
8084  hlpSS.str ( std::string ( ) );
8085  hlpSS << "<pre><b>" << "Cell angles (Degrees): " << "</b>";
8086  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
8087  {
8088  hlpSS << ".";
8089  }
8090 
8091  hlpSS << std::showpos << std::setprecision ( prec ) << " " << 90.0;
8092  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
8093  {
8094  hlpSS << " ";
8095  }
8096  hlpSS << " ";
8097 
8098  hlpSS << std::showpos << 90.0;
8099  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
8100  {
8101  hlpSS << " ";
8102  }
8103  hlpSS << " ";
8104 
8105  hlpSS << std::showpos << 90.0;
8106  for ( int iter = 0; iter < static_cast<int> ( spacer - ProSHADE_internal_misc::to_string_with_precision ( 90.0, prec ).length() ); iter++ )
8107  {
8108  hlpSS << " ";
8109  }
8110  hlpSS << "</pre>";
8111 
8112  rvapi_set_text ( hlpSS.str().c_str(),
8113  "h2OutHeader",
8114  3,
8115  0,
8116  1,
8117  1 );
8118 
8119  //==================================== Print cell dimensions
8120  hlpSS.str ( std::string ( ) );
8121  hlpSS << "<pre><b>" << "Fast, medium, slow axes: " << "</b>";
8122  for ( int iter = static_cast<int> ( hlpSS.str().length() ); iter < 70; iter++ )
8123  {
8124  hlpSS << ".";
8125  }
8126 
8127  std::string hlpAO = settings->axisOrder;
8128  std::transform ( hlpAO.begin(), hlpAO.end(), hlpAO.begin(), ::toupper);
8129  hlpSS << " " << hlpAO;
8130  for ( int iter = 0; iter < static_cast<int> ( spacer - 1 ); iter++ )
8131  {
8132  hlpSS << " ";
8133  }
8134  hlpSS << "</pre>";
8135 
8136  rvapi_set_text ( hlpSS.str().c_str(),
8137  "h2OutHeader",
8138  4,
8139  0,
8140  1,
8141  1 );
8142 
8143  rvapi_flush ( );
8144  }
8145 
8146  //======================================== Write out the re-boxed half maps
8147  std::stringstream ss;
8148  ss << settings->clearMapFile << "_half1.map";
8149  halfMap1->writeMap ( ss.str(), halfMap1->_densityMapCor );
8150 
8151  ss.str( std::string ( ) );
8152  ss << settings->clearMapFile << "_half2.map";
8153  halfMap2->writeMap ( ss.str(), halfMap2->_densityMapCor );
8154 
8155  if ( settings->htmlReport )
8156  {
8157  std::stringstream hlpSS;
8158  hlpSS << "<font color=\"green\">" << "Half maps saved." << "</font>";
8159  rvapi_set_text ( hlpSS.str().c_str(),
8160  "ProgressSection",
8161  settings->htmlReportLineProgress,
8162  1,
8163  1,
8164  1 );
8165  settings->htmlReportLineProgress += 1;
8166  rvapi_flush ( );
8167  }
8168 
8169  if ( settings->htmlReport )
8170  {
8171  rvapi_add_section ( "ResultsSection",
8172  "Results",
8173  "body",
8174  settings->htmlReportLine,
8175  0,
8176  1,
8177  1,
8178  true );
8179  settings->htmlReportLine += 1;
8180 
8181  std::stringstream hlpSS;
8182  hlpSS << "<pre><b>" << "The re-boxed structures are available at: </b>" << settings->clearMapFile << "_half1.map" << "</pre>";
8183  rvapi_set_text ( hlpSS.str().c_str(),
8184  "ResultsSection",
8185  0,
8186  0,
8187  1,
8188  1 );
8189 
8190  hlpSS.str ( std::string ( ) );
8191  hlpSS << "<pre><b>" << " ... and : </b>" << settings->clearMapFile << "_half2.map" << "</pre>";
8192  rvapi_set_text ( hlpSS.str().c_str(),
8193  "ResultsSection",
8194  1,
8195  0,
8196  1,
8197  1 );
8198 
8199  hlpSS.str ( std::string ( ) );
8200  hlpSS << "<pre><b>" << "Original structure dims: </b>" << oDimX1+1 << " x " << oDimY1+1 << " x " << oDimZ1+1 << "</pre>";
8201  rvapi_set_text ( hlpSS.str().c_str(),
8202  "ResultsSection",
8203  2,
8204  0,
8205  1,
8206  1 );
8207 
8208  hlpSS.str ( std::string ( ) );
8209  hlpSS << "<pre><b>" << " ... and : </b>" << oDimX2+1 << " x " << oDimY2+1 << " x " << oDimZ2+1 << "</pre>";
8210  rvapi_set_text ( hlpSS.str().c_str(),
8211  "ResultsSection",
8212  3,
8213  0,
8214  1,
8215  1 );
8216 
8217  hlpSS.str ( std::string ( ) );
8218  hlpSS << "<pre><b>" << "Re-boxed structure dims: </b>" << halfMap1->_maxMapU << " x " << halfMap1->_maxMapV << " x " << halfMap1->_maxMapW << "</pre>";
8219  rvapi_set_text ( hlpSS.str().c_str(),
8220  "ResultsSection",
8221  4,
8222  0,
8223  1,
8224  1 );
8225 
8226  hlpSS.str ( std::string ( ) );
8227  hlpSS << "<pre><b>" << " ... and : </b>" << halfMap2->_maxMapU << " x " << halfMap2->_maxMapV << " x " << halfMap2->_maxMapW << "</pre>";
8228  rvapi_set_text ( hlpSS.str().c_str(),
8229  "ResultsSection",
8230  5,
8231  0,
8232  1,
8233  1 );
8234 
8235  hlpSS.str ( std::string ( ) );
8236  hlpSS << "<pre><b>" << "New volume as percentage of old volume: </b>" << ProSHADE_internal_misc::to_string_with_precision ( ( static_cast<double> ( (halfMap1->_maxMapU+1) * (halfMap1->_maxMapV+1) * (halfMap1->_maxMapW+1) ) / static_cast<double> ( (oDimX1+1) * (oDimY1+1) * (oDimZ1+1) ) ) * 100 ) << " %</pre>";
8237  rvapi_set_text ( hlpSS.str().c_str(),
8238  "ResultsSection",
8239  6,
8240  0,
8241  1,
8242  1 );
8243 
8244  hlpSS.str ( std::string ( ) );
8245  hlpSS << "<pre><b>" << "Linear processing speed-up: </b>" << ProSHADE_internal_misc::to_string_with_precision ( ( ( (oDimX1+1) * (oDimY1+1) * (oDimZ1+1) ) / ( (halfMap1->_maxMapU+1) * (halfMap1->_maxMapV+1) * (halfMap1->_maxMapW+1) ) ) - 1.0 ) << " times</pre>";
8246  rvapi_set_text ( hlpSS.str().c_str(),
8247  "ResultsSection",
8248  7,
8249  0,
8250  1,
8251  1 );
8252 
8253  rvapi_flush ( );
8254  }
8255 
8256  //======================================== Release memory
8257  delete halfMap1;
8258  delete halfMap2;
8259 
8260  //======================================== Done
8261  return ;
8262 
8263 }
8264 
8279 std::vector<ProSHADE_internal::ProSHADE_data*> ProSHADE_internal::ProSHADE_data::fragmentMap ( ProSHADE::ProSHADE_settings* settings,
8280  bool userCOM )
8281 {
8282  //======================================== Sanity check
8283  if ( !this->_densityMapComputed )
8284  {
8285  std::cerr << "!!! ProSHADE ERROR !!! Tried to fragment map without first computing it. Terminating..." << std::endl;
8286 
8287  if ( settings->htmlReport )
8288  {
8289  std::stringstream hlpSS;
8290  hlpSS << "<font color=\"red\">" << "Tried to fragment map without first computing it. This looks like an internal bug - please report this case." << "</font>";
8291  rvapi_set_text ( hlpSS.str().c_str(),
8292  "ProgressSection",
8293  settings->htmlReportLineProgress,
8294  1,
8295  1,
8296  1 );
8297  settings->htmlReportLineProgress += 1;
8298  rvapi_flush ( );
8299  }
8300 
8301  exit ( -1 );
8302  }
8303 
8304  if ( settings->verbose > 1 )
8305  {
8306  std::cout << ">> Fragmenting map." << std::endl;
8307  }
8308 
8309  //======================================== Initialise local variables
8310  std::vector<ProSHADE_data*> ret;
8311  std::vector< std::array<unsigned int,2> > XDim;
8312  std::vector< std::array<unsigned int,2> > YDim;
8313  std::vector< std::array<unsigned int,2> > ZDim;
8314  std::array<unsigned int,2> hlpArrX;
8315  std::array<unsigned int,2> hlpArrY;
8316  std::array<unsigned int,2> hlpArrZ;
8317  double maxMapAngPerIndex = std::max ( this->_xRange / static_cast<double> ( this->_maxMapU ),
8318  std::max ( this->_yRange / static_cast<double> ( this->_maxMapV ),
8319  this->_zRange / static_cast<double> ( this->_maxMapW ) ) );
8320 
8321  unsigned int boxDimInIndices = static_cast<unsigned int> ( std::round ( settings->mapFragBoxSize / maxMapAngPerIndex ) );
8322  if ( ( boxDimInIndices % 2 ) == 1 )
8323  {
8324  //==================================== If odd, change to even
8325  boxDimInIndices += 1;
8326  }
8327 
8328  //======================================== Problem! The box is too small
8329  if ( boxDimInIndices < 2 )
8330  {
8331  std::cerr << "!!! ProSHADE ERROR !!! The box size for fragmentation is too small, please increase the box size or submit more detailed map. (Increasing the number of points by interpolation could work without changing the map here...)" << std::endl;
8332 
8333  if ( settings->htmlReport )
8334  {
8335  std::stringstream hlpSS;
8336  hlpSS << "<font color=\"red\">" << "The box size for fragmentation is too small, please increase the box size or submit more detailed map. (Increasing the number of points by interpolation could work without changing the map here...)." << "</font>";
8337  rvapi_set_text ( hlpSS.str().c_str(),
8338  "ProgressSection",
8339  settings->htmlReportLineProgress,
8340  1,
8341  1,
8342  1 );
8343  settings->htmlReportLineProgress += 1;
8344  rvapi_flush ( );
8345  }
8346 
8347  exit ( -1 );
8348  }
8349  if ( ( boxDimInIndices >= this->_maxMapU ) || ( boxDimInIndices >= this->_maxMapV ) || ( boxDimInIndices >= this->_maxMapW ) )
8350  {
8351  std::cerr << "!!! ProSHADE ERROR !!! The box size for fragmentation is too large, please decrease the box size so that it is smaller than the clearmap dimmensions." << std::endl;
8352 
8353  if ( settings->htmlReport )
8354  {
8355  std::stringstream hlpSS;
8356  hlpSS << "<font color=\"red\">" << "The box size for fragmentation is too large, please decrease the box size so that it is smaller than the map dimmensions." << "</font>";
8357  rvapi_set_text ( hlpSS.str().c_str(),
8358  "ProgressSection",
8359  settings->htmlReportLineProgress,
8360  1,
8361  1,
8362  1 );
8363  settings->htmlReportLineProgress += 1;
8364  rvapi_flush ( );
8365  }
8366 
8367  exit ( -1 );
8368  }
8369  if ( settings->verbose > 3 )
8370  {
8371  std::cout << ">>>>>>>> Sanity checks passed." << std::endl;
8372  }
8373 
8374  //======================================== Generate box starts and ends
8375  for ( unsigned int xStart = 0; xStart <= ( this->_maxMapU - boxDimInIndices ); xStart += ( boxDimInIndices / 2 ) )
8376  {
8377  hlpArrX[0] = xStart;
8378  hlpArrX[1] = xStart + boxDimInIndices;
8379 
8380  //==================================== Check for terminal boxes, they may need to have larger size
8381  if ( ( xStart + ( boxDimInIndices / 2 ) ) > ( this->_maxMapU - boxDimInIndices ) )
8382  {
8383  //================================ This is the last X
8384  hlpArrX[1] = this->_maxMapU;
8385  }
8386 
8387  for ( unsigned int yStart = 0; yStart <= ( this->_maxMapV - boxDimInIndices ); yStart += ( boxDimInIndices / 2 ) )
8388  {
8389  hlpArrY[0] = yStart;
8390  hlpArrY[1] = yStart + boxDimInIndices;
8391 
8392  //================================ Check for terminal boxes, they may need to have larger size
8393  if ( ( yStart + ( boxDimInIndices / 2 ) ) > ( this->_maxMapV - boxDimInIndices ) )
8394  {
8395  //============================ This is the last Y
8396  hlpArrY[1] = this->_maxMapV;
8397  }
8398 
8399  for ( unsigned int zStart = 0; zStart <= ( this->_maxMapW - boxDimInIndices ); zStart += ( boxDimInIndices / 2 ) )
8400  {
8401  hlpArrZ[0] = zStart;
8402  hlpArrZ[1] = zStart + boxDimInIndices;
8403 
8404  //============================ Check for terminal boxes, they may need to have larger size
8405  if ( ( zStart + ( boxDimInIndices / 2 ) ) > ( this->_maxMapW - boxDimInIndices ) )
8406  {
8407  //======================== This is the last Z
8408  hlpArrZ[1] = this->_maxMapW;
8409  }
8410 
8411  XDim.emplace_back ( hlpArrX );
8412  YDim.emplace_back ( hlpArrY );
8413  ZDim.emplace_back ( hlpArrZ );
8414  }
8415  }
8416  }
8417  if ( settings->verbose > 2 )
8418  {
8419  std::cout << ">>>>> Box sizes computed." << std::endl;
8420  }
8421 
8422  //======================================== If the box has enough density, create a new object!
8423  unsigned int noDensityPoints = 0;
8424  unsigned int strCounter = 0;
8425  unsigned int arrayPos = 0;
8426  int coordPos = 0;
8427  double boxVolume = 0.0;
8428  double xCOM = 0.0;
8429  double yCOM = 0.0;
8430  double zCOM = 0.0;
8431  double densTot = 0.0;
8432  int newU, newV, newW;
8433  int hlpU, hlpV, hlpW;
8434  std::vector<double> mapVals;
8435  std::string fileName;
8436 
8437  for ( unsigned int boxIt = 0; boxIt < static_cast<unsigned int> ( XDim.size() ); boxIt++ )
8438  {
8439  if ( settings->verbose > 2 )
8440  {
8441  std::cout << ">>>>> Trying box " << boxIt << " ." << std::endl;
8442  }
8443 
8444  //==================================== Check the box density fraction
8445  noDensityPoints = 0;
8446  for ( unsigned int x = XDim.at(boxIt)[0]; x <= XDim.at(boxIt)[1]; x++ )
8447  {
8448  for ( unsigned int y = YDim.at(boxIt)[0]; y <= YDim.at(boxIt)[1]; y++ )
8449  {
8450  for ( unsigned int z = ZDim.at(boxIt)[0]; z <= ZDim.at(boxIt)[1]; z++ )
8451  {
8452  arrayPos = z + (this->_maxMapW+1) * ( y + (this->_maxMapV+1) * x );
8453 
8454  if ( this->_densityMapCor[arrayPos] > 0.0 )
8455  {
8456  noDensityPoints += 1;
8457  }
8458  }
8459  }
8460  }
8461 
8462  //==================================== If passing, write out the box
8463  boxVolume = ( ( XDim.at(boxIt)[1] - XDim.at(boxIt)[0] ) + 1 ) * ( ( YDim.at(boxIt)[1] - YDim.at(boxIt)[0] ) + 1 ) * ( ( ZDim.at(boxIt)[1] - ZDim.at(boxIt)[0] ) + 1 );
8464  if ( ( static_cast<double> ( noDensityPoints ) / boxVolume ) > settings->mapFragBoxFraction )
8465  {
8466  //================================ Create new structure
8467  ret.emplace_back ( new ProSHADE_data () );
8468 
8469  //================================ Fill in the obvious parameters
8470  ret.at(strCounter)->_fromPDB = false;
8471  ret.at(strCounter)->_shellSpacing = settings->shellSpacing;
8472  ret.at(strCounter)->_maxExtraCellularSpace = settings->extraSpace;
8473  ret.at(strCounter)->_xRange = ( XDim.at(boxIt)[1] - XDim.at(boxIt)[0] ) * ( this->_xRange / static_cast<double> ( this->_maxMapU ) );
8474  ret.at(strCounter)->_yRange = ( YDim.at(boxIt)[1] - YDim.at(boxIt)[0] ) * ( this->_yRange / static_cast<double> ( this->_maxMapV ) );
8475  ret.at(strCounter)->_zRange = ( ZDim.at(boxIt)[1] - ZDim.at(boxIt)[0] ) * ( this->_zRange / static_cast<double> ( this->_maxMapW ) );
8476 
8477  //================================ Set xyzFrom and xyzTo
8478  ret.at(strCounter)->_xFrom = XDim.at(boxIt)[0] + this->_xFrom;
8479  ret.at(strCounter)->_yFrom = YDim.at(boxIt)[0] + this->_yFrom;;
8480  ret.at(strCounter)->_zFrom = ZDim.at(boxIt)[0] + this->_zFrom;;
8481 
8482  ret.at(strCounter)->_xTo = XDim.at(boxIt)[1] + this->_xFrom;;
8483  ret.at(strCounter)->_yTo = YDim.at(boxIt)[1] + this->_yFrom;;
8484  ret.at(strCounter)->_zTo = ZDim.at(boxIt)[1] + this->_zFrom;;
8485 
8486  //================================ Automatically determine maximum number of shells
8487  ret.at(strCounter)->_shellPlacement = std::vector<double> ( std::floor ( std::max ( ret.at(strCounter)->_xRange, std::max ( ret.at(strCounter)->_yRange, ret.at(strCounter)->_zRange ) ) / ret.at(strCounter)->_shellSpacing ) );
8488 
8489  for ( unsigned int shellIter = 0; shellIter < static_cast<unsigned int> ( ret.at(strCounter)->_shellPlacement.size() ); shellIter++ )
8490  {
8491  ret.at(strCounter)->_shellPlacement.at(shellIter) = (shellIter+1) * ret.at(strCounter)->_shellSpacing;
8492  }
8493 
8494  //================================ Determine other basic parameters
8495  ret.at(strCounter)->_mapResolution= settings->mapResolution;
8496  ret.at(strCounter)->_maxMapU = ( XDim.at(boxIt)[1] - XDim.at(boxIt)[0] );
8497  ret.at(strCounter)->_maxMapV = ( YDim.at(boxIt)[1] - YDim.at(boxIt)[0] );
8498  ret.at(strCounter)->_maxMapW = ( ZDim.at(boxIt)[1] - ZDim.at(boxIt)[0] );
8499  ret.at(strCounter)->_densityMapComputed = true;
8500 
8501  hlpU = ( ret.at(strCounter)->_maxMapU + 1 );
8502  hlpV = ( ret.at(strCounter)->_maxMapV + 1 );
8503  hlpW = ( ret.at(strCounter)->_maxMapW + 1 );
8504 
8505  //================================ Fill the density map
8506  mapVals.clear ( );
8507  ret.at(strCounter)->_densityMapCor= new double [(ret.at(strCounter)->_maxMapU+1) * (ret.at(strCounter)->_maxMapV+1) * (ret.at(strCounter)->_maxMapW + 1)];
8508  xCOM = 0.0;
8509  yCOM = 0.0;
8510  zCOM = 0.0;
8511  densTot = 0.0;
8512  for ( unsigned int x = XDim.at(boxIt)[0]; x <= XDim.at(boxIt)[1]; x++ )
8513  {
8514  for ( unsigned int y = YDim.at(boxIt)[0]; y <= YDim.at(boxIt)[1]; y++ )
8515  {
8516  for ( unsigned int z = ZDim.at(boxIt)[0]; z <= ZDim.at(boxIt)[1]; z++ )
8517  {
8518  arrayPos = z + (this->_maxMapW+1) * ( y + (this->_maxMapV+1) * x );
8519  coordPos = (z-ZDim.at(boxIt)[0]) + (ret.at(strCounter)->_maxMapW+1) * ( (y-YDim.at(boxIt)[0]) + (ret.at(strCounter)->_maxMapV+1) * (x-XDim.at(boxIt)[0]) );
8520 
8521  ret.at(strCounter)->_densityMapCor[coordPos] = this->_densityMapCor[arrayPos];
8522 
8523  if ( this->_densityMapCor[arrayPos] > 0.0 )
8524  {
8525  mapVals.emplace_back ( this->_densityMapCor[arrayPos] );
8526  xCOM += ( x - XDim.at(boxIt)[0] ) * this->_densityMapCor[arrayPos];
8527  yCOM += ( y - YDim.at(boxIt)[0] ) * this->_densityMapCor[arrayPos];
8528  zCOM += ( z - ZDim.at(boxIt)[0] ) * this->_densityMapCor[arrayPos];
8529  densTot += this->_densityMapCor[arrayPos];
8530  }
8531  }
8532  }
8533  }
8534 
8535  //================================ Determine other parameters
8536  ret.at(strCounter)->_mapMean = std::accumulate ( mapVals.begin(), mapVals.end(), 0.0 ) / static_cast<double> ( mapVals.size() );
8537  ret.at(strCounter)->_mapSdev = std::sqrt ( static_cast<double> ( std::inner_product ( mapVals.begin(), mapVals.end(), mapVals.begin(), 0.0 ) ) /
8538  static_cast<double> ( mapVals.size() ) - ret.at(strCounter)->_mapMean * ret.at(strCounter)->_mapMean );
8539  mapVals.clear ( );
8540 
8541  //====== Determine COM
8542  std::array<double,3> meanVals;
8543  if ( userCOM )
8544  {
8545  meanVals[0] = xCOM / densTot;
8546  meanVals[1] = yCOM / densTot;
8547  meanVals[2] = zCOM / densTot;
8548  }
8549  else
8550  {
8551  meanVals[0] = static_cast<double> ( hlpU ) / 2.0;
8552  meanVals[1] = static_cast<double> ( hlpV ) / 2.0;
8553  meanVals[2] = static_cast<double> ( hlpW ) / 2.0;
8554  }
8555 
8556  //================================ Re-index the map with COM in the centre
8557  ret.at(strCounter)->_xCorrErr = meanVals[0] - static_cast<double> ( hlpU ) / 2.0;
8558  ret.at(strCounter)->_yCorrErr = meanVals[1] - static_cast<double> ( hlpV ) / 2.0;
8559  ret.at(strCounter)->_zCorrErr = meanVals[2] - static_cast<double> ( hlpW ) / 2.0;
8560 
8561  ret.at(strCounter)->_xCorrection = std::ceil ( ret.at(strCounter)->_xCorrErr );
8562  ret.at(strCounter)->_yCorrection = std::ceil ( ret.at(strCounter)->_yCorrErr );
8563  ret.at(strCounter)->_zCorrection = std::ceil ( ret.at(strCounter)->_zCorrErr );
8564 
8565  ret.at(strCounter)->_densityMapCorCoords = new std::array<double,3> [hlpU * hlpV * hlpW];
8566  double *tmpIn = new double [hlpU * hlpV * hlpW];
8567  for ( unsigned int iter = 0; iter < static_cast<unsigned int> ( hlpU * hlpV * hlpW ); iter++ )
8568  {
8569  tmpIn[iter] = ret.at(strCounter)->_densityMapCor[iter];
8570  }
8571 
8572  for ( int uIt = 0; uIt < hlpU; uIt++ )
8573  {
8574  for ( int vIt = 0; vIt < hlpV; vIt++ )
8575  {
8576  for ( int wIt = 0; wIt < hlpW; wIt++ )
8577  {
8578  newU = static_cast<int> ( uIt ) - static_cast<int> ( ret.at(strCounter)->_xCorrection );
8579  newV = static_cast<int> ( vIt ) - static_cast<int> ( ret.at(strCounter)->_yCorrection );
8580  newW = static_cast<int> ( wIt ) - static_cast<int> ( ret.at(strCounter)->_zCorrection );
8581 
8582  if ( newU < 0 ) { newU += hlpU; } if ( newU >= static_cast<int> ( hlpU ) ) { newU -= hlpU; }
8583  if ( newV < 0 ) { newV += hlpV; } if ( newV >= static_cast<int> ( hlpV ) ) { newV -= hlpV; }
8584  if ( newW < 0 ) { newW += hlpW; } if ( newW >= static_cast<int> ( hlpW ) ) { newW -= hlpW; }
8585 
8586  arrayPos = wIt + hlpW * ( vIt + hlpV * uIt );
8587  coordPos = newW + hlpW * ( newV + hlpV * newU );
8588 
8589  ret.at(strCounter)->_densityMapCor[coordPos] = tmpIn[arrayPos];
8590 
8591  //==================== Save results
8592  ret.at(strCounter)->_densityMapCorCoords[coordPos][0] = ( static_cast<double> ( newU ) - static_cast<double> ( hlpU ) /2.0 ) * ( ret.at(strCounter)->_xRange / static_cast<double> ( hlpU ) );
8593  ret.at(strCounter)->_densityMapCorCoords[coordPos][1] = ( static_cast<double> ( newV ) - static_cast<double> ( hlpV ) /2.0 ) * ( ret.at(strCounter)->_yRange / static_cast<double> ( hlpV ) );;
8594  ret.at(strCounter)->_densityMapCorCoords[coordPos][2] = ( static_cast<double> ( newW ) - static_cast<double> ( hlpW ) /2.0 ) * ( ret.at(strCounter)->_zRange / static_cast<double> ( hlpW ) );;
8595  }
8596  }
8597  }
8598  delete[] tmpIn;
8599 
8600  //================================ Set final batch of parameters
8601  ret.at(strCounter)->_fourierCoeffPower = this->_fourierCoeffPower;
8602  ret.at(strCounter)->_bFactorChange= this->_bFactorChange;
8603  ret.at(strCounter)->_maxMapRange = std::max ( ret.at(strCounter)->_xRange, std::max ( ret.at(strCounter)->_yRange, ret.at(strCounter)->_zRange ) );
8604  ret.at(strCounter)->_phaseRemoved = this->_phaseRemoved;
8605  ret.at(strCounter)->_keepOrRemove = this->_keepOrRemove;
8606  ret.at(strCounter)->_thetaAngle = this->_thetaAngle;
8607  ret.at(strCounter)->_phiAngle = this->_phiAngle;
8608  ret.at(strCounter)->_noShellsWithData = 0;
8609  ret.at(strCounter)->_sphereMapped = false;
8610  ret.at(strCounter)->_firstLineCOM = false;
8611  ret.at(strCounter)->_bandwidthLimit = this->_bandwidthLimit;
8612  ret.at(strCounter)->_oneDimmension= ret.at(strCounter)->_bandwidthLimit * 2;
8613  ret.at(strCounter)->_sphericalCoefficientsComputed = false;
8614  ret.at(strCounter)->_rrpMatricesPrecomputed = false;
8615  ret.at(strCounter)->_shellMappedData = nullptr;
8616  ret.at(strCounter)->_realSHCoeffs = nullptr;
8617  ret.at(strCounter)->_imagSHCoeffs = nullptr;
8618  ret.at(strCounter)->_sphericalHarmonicsWeights= nullptr;
8619  ret.at(strCounter)->_semiNaiveTable = nullptr;
8620  ret.at(strCounter)->_semiNaiveTableSpace = nullptr;
8621  ret.at(strCounter)->_shWorkspace = nullptr;
8622  ret.at(strCounter)->_invRealData = nullptr;
8623  ret.at(strCounter)->_invImagData = nullptr;
8624  ret.at(strCounter)->_rrpMatrices = nullptr;
8625 
8626  //================================ Object initialised!
8627  strCounter += 1;
8628  }
8629  else
8630  {
8631  if ( settings->verbose > 3 )
8632  {
8633  std::cout << ">>>>>>>> Density check NOT passed." << std::endl;
8634  }
8635  }
8636 
8637  if ( settings->verbose > 3 )
8638  {
8639  std::cout << ">>>>>>>> Box " << boxIt << " processed." << std::endl;
8640  }
8641  }
8642 
8643  //======================================== Done
8644  return ( ret );
8645 
8646 }
8647 
8657 double ProSHADE_internal_misc::modelRadiusCalc ( std::string modelPath )
8658 {
8659  //======================================== Read in the PDB
8660  clipper::mmdb::CMMDBManager *mfile = new clipper::mmdb::CMMDBManager ( );
8661  if ( mfile->ReadCoorFile ( modelPath.c_str() ) )
8662  {
8663  std::cerr << "!!! ProSHADE ERROR !!! Cannot read model file: " << modelPath.c_str() << std::endl;
8664  exit ( -1 );
8665  }
8666 
8667  //======================================== Initialise MMDB crawl
8668  int noChains = 0;
8669  int noResidues = 0;
8670  int noAtoms = 0;
8671  std::vector<std::array<double,3>> coords;
8672  std::array<double,3> hlpArr;
8673 
8674  clipper::mmdb::PPCChain chain;
8675  clipper::mmdb::PPCResidue residue;
8676  clipper::mmdb::PPCAtom atom;
8677 
8678  //======================================== Get all chains
8679  mfile->GetChainTable ( 1, chain, noChains );
8680  for ( unsigned int nCh = 0; nCh < static_cast<unsigned int> ( noChains ); nCh++ )
8681  {
8682  if ( chain[nCh] )
8683  {
8684  //================================ Get all residues
8685  chain[nCh]->GetResidueTable ( residue, noResidues );
8686 
8687  for ( unsigned int nRes = 0; nRes < static_cast<unsigned int> ( noResidues ); nRes++ )
8688  {
8689  if ( residue[nRes] )
8690  {
8691  //======================== Get all atoms
8692  residue[nRes]->GetAtomTable ( atom, noAtoms );
8693 
8694  for ( unsigned int aNo = 0; aNo < static_cast<unsigned int> ( noAtoms ); aNo++ )
8695  {
8696  if ( atom[aNo] )
8697  {
8698  //================ Check for termination 'residue'
8699  if ( atom[aNo]->Ter ) { continue; }
8700 
8701  //================ Save the coords
8702  hlpArr[0] = atom[aNo]->x;
8703  hlpArr[1] = atom[aNo]->y;
8704  hlpArr[2] = atom[aNo]->z;
8705 
8706  //================ And save to vector
8707  coords.emplace_back ( hlpArr );
8708  }
8709  }
8710  }
8711  }
8712  }
8713  }
8714 
8715  //======================================== Free memory
8716  delete mfile;
8717 
8718  //======================================== Full distance check
8719 // double maxQuadDist = 0.0;
8720 // double distHlp = 0.0;
8721 // for ( unsigned int at1 = 0; at1 < static_cast<unsigned int> ( coords.size() ); at1++ )
8722 // {
8723 // for ( unsigned int at2 = 1; at2 < static_cast<unsigned int> ( coords.size() ); at2++ )
8724 // {
8725 // if ( at1 >= at2 ) { continue; }
8726 //
8727 // distHlp = sqrt ( pow ( std::abs( coords.at(at1)[0] - coords.at(at2)[0] ), 2.0 ) +
8728 // pow ( std::abs( coords.at(at1)[1] - coords.at(at2)[1] ), 2.0 ) +
8729 // pow ( std::abs( coords.at(at1)[2] - coords.at(at2)[2] ), 2.0 ) );
8730 // if ( maxQuadDist < distHlp )
8731 // {
8732 // maxQuadDist = distHlp;
8733 // }
8734 // }
8735 // }
8736 
8737  //======================================== Firt approximation
8738  double fullDist = 0.0;
8739  double firstApprox = 0.0;
8740  double hlpDist = 0.0;
8741  double xMean = 0.0;
8742  double yMean = 0.0;
8743  double zMean = 0.0;
8744  unsigned int furthestAtom = 0;
8745  for ( unsigned int at1 = 0; at1 < static_cast<unsigned int> ( coords.size() ); at1++ )
8746  {
8747  xMean += coords.at(at1)[0];
8748  yMean += coords.at(at1)[1];
8749  zMean += coords.at(at1)[2];
8750  }
8751  xMean /= static_cast<double> ( coords.size() );
8752  yMean /= static_cast<double> ( coords.size() );
8753  zMean /= static_cast<double> ( coords.size() );
8754 
8755  std::vector<double> dists ( coords.size(), 0.0 );
8756  for ( unsigned int at1 = 0; at1 < static_cast<unsigned int> ( coords.size() ); at1++ )
8757  {
8758  hlpDist = sqrt ( pow ( std::abs ( xMean - coords.at(at1)[0] ), 2.0 ) +
8759  pow ( std::abs ( yMean - coords.at(at1)[1] ), 2.0 ) +
8760  pow ( std::abs ( zMean - coords.at(at1)[2] ), 2.0 ) );
8761  dists.at(at1) = hlpDist;
8762 
8763  if ( firstApprox < hlpDist )
8764  {
8765  firstApprox = hlpDist;
8766  furthestAtom = at1;
8767  }
8768  }
8769 
8770  for ( unsigned int at1 = 0; at1 < static_cast<unsigned int> ( dists.size() ); at1++ )
8771  {
8772  if ( at1 == furthestAtom ) { continue; }
8773 
8774  hlpDist = sqrt ( pow ( std::abs ( coords.at(furthestAtom)[0] - coords.at(at1)[0] ), 2.0 ) +
8775  pow ( std::abs ( coords.at(furthestAtom)[1] - coords.at(at1)[1] ), 2.0 ) +
8776  pow ( std::abs ( coords.at(furthestAtom)[2] - coords.at(at1)[2] ), 2.0 ) );
8777 
8778  if ( fullDist < hlpDist )
8779  {
8780  fullDist = hlpDist;
8781  }
8782  }
8783 
8784  //======================================== Done
8785  return ( fullDist );
8786 
8787 }
This class deals with reading in the data and computing structure specific information including the ...
double mapResolution
This is the internal resolution at which the calculations are done, not necessarily the resolution of...
Definition: ProSHADE.h:78
double noIQRsFromMap
This is the number of interquartile distances from mean that is used to threshold the map masking...
Definition: ProSHADE.h:93
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::string clearMapFile
If map features are to be extracted, should the clear map be saved (then give file name here)...
Definition: ProSHADE.h:144
void normaliseMap(ProSHADE::ProSHADE_settings *settings)
This function does normalises the map data.
void translateMap(double xShift, double yShift, double zShift)
This function translates the data along the three coordinate axis by the amount given by the three pa...
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
double mapFragBoxFraction
Fraction of box that needs to have density in order to be passed on.
Definition: ProSHADE.h:153
unsigned int bandwidth
This parameter determines the angular resolution of the spherical harmonics decomposition.
Definition: ProSHADE.h:80
void keepPhaseInMap(double alpha, double bFac, unsigned int *bandwidth, unsigned int *theta, unsigned int *phi, unsigned int *glIntegOrder, ProSHADE::ProSHADE_settings *settings, bool useCom=true, double maxMapIQR=10.0, int verbose=0, bool clearMapData=true, bool rotDefaults=false, bool overlapDefaults=false, double blurFactor=500.0, bool maskBlurFactorGiven=false)
This function keeps the phase information from the density map and prepares the data for SH coefficie...
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
The main header file containing all declarations the user of the library needs.
void getDensityMapFromMAPFeatures(std::string fileName, double *minDensPreNorm, double *maxDensPreNorm, double *minDensPostNorm, double *maxDensPostNorm, double *postNormMean, double *postNormSdev, double *maskVolume, double *totalVolume, double *maskMean, double *maskSdev, double *maskMin, double *maskMax, double *maskDensityRMS, double *allDensityRMS, std::array< double, 3 > *origRanges, std::array< double, 3 > *origDims, double maxMapIQR, double extraCS, int verbose, bool useCubicMaps, double maskBlurFactor, bool maskBlurFactorGiven, bool reboxAtAll, ProSHADE::ProSHADE_settings *settings)
This function reads in the CCP4&#39; MAP formatted file and computes its features.
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...
std::vector< std::vector< int > > findMapIslands(int hlpU, int hlpV, int hlpW, double *map, double threshold=0.0)
This function takes a map and a threshold on it and proceeds to detect islands (continuous fragments ...
bool useCubicMaps
When saving clear maps, should the rectangular or cubic (older versions of refmac need this) maps be ...
Definition: ProSHADE.h:145
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
double modelRadiusCalc(std::string modelPath)
This function takes model and finds the maximum distance between any two atoms.
void shiftMap(double xShift, double yShift, double zShift)
This function shifts (changing header) the data along the three coordinate axis by the amount given b...
void getDensityMapFromPDB(std::string fileName, double *shellDistance, double resolution, unsigned int *bandwidth, unsigned int *theta, unsigned int *phi, unsigned int *glIntegOrder, double *extraSpace, bool mapResDefault, ProSHADE::ProSHADE_settings *settings, double Bfactor=80.0, bool hpFirstLineCom=false, bool overlayDefaults=false)
Function to read in the PDB file and compute the theoretical density map.
double shellSpacing
This parameter determines how far the radial shells should be from each other.
Definition: ProSHADE.h:96
std::array< double, 6 > getDensityMapFromMAPRebox(std::string fileName, double maxMapIQR, double extraCS, int verbose, bool useCubicMaps, double maskBlurFactor, bool maskBlurFactorGiven, ProSHADE::ProSHADE_settings *settings)
This function reads in the CCP4&#39; MAP formatted file and re-boxes its contents using the masking proce...
bool mapResDefault
This variable states if default resolution should be used, or whether the user has supplied a differe...
Definition: ProSHADE.h:85
This is the executive class responsible for comparing strictly two structures.
std::vector< ProSHADE_data * > fragmentMap(ProSHADE::ProSHADE_settings *settings, bool userCOM)
This function takes the map and fragments it into boxes of given size, returning vector of data objec...
void printInfo(int verbose)
This is the main information output for the ProSHADE_mapFeatures class.
bool rotChangeDefault
If map rotation is selected, the default automatic parameter decision is changed. This variable state...
Definition: ProSHADE.h:170
void removePhaseFromMapOverlay(double alpha, double bFac, ProSHADE::ProSHADE_settings *settings)
This function removes the phase information from the density map for the overlay purposes.
unsigned int phi
This parameter is the latitudd of the spherical grid mapping. It should be 2 * bandwidth unless there...
Definition: ProSHADE.h:84
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::string axisOrder
A string specifying the order of the axis. Must have three characters and any permutation of &#39;x&#39;...
Definition: ProSHADE.h:182
The main header file containing all declarations for the innter workings of the library.
int htmlReportLine
Iterator for current HTML line.
Definition: ProSHADE.h:186
int htmlReportLineProgress
Iterator for current HTML line in the progress bar.
Definition: ProSHADE.h:187
void getDensityMapFromMAP(std::string fileName, double *shellDistance, double resolution, unsigned int *bandwidth, unsigned int *theta, unsigned int *phi, unsigned int *glIntegOrder, double *extraSpace, bool mapResDefault, bool rotDefaults, ProSHADE::ProSHADE_settings *settings, bool overlayDefaults=false)
Function to read in the MAP file and provide the basic processing.
void dealWithHalfMaps(ProSHADE::ProSHADE_settings *settings, double *xTranslate, double *yTranslate, double *zTranslate)
This function takes the clear map produced already and fragments it into overlapping boxes of given s...
double mapFragBoxSize
Should the clear map be fragmented into boxes? If so, put box size here, otherwise leave 0...
Definition: ProSHADE.h:151
ProSHADE_data()
Contructor for the ProSHADE_data class.
std::array< double, 4 > getCOMandDist(ProSHADE::ProSHADE_settings *settings)
This function gets COM and its distance to closes border.
This class stores all the settings and is passed to the executive classes instead of multitude of par...
Definition: ProSHADE.h:74
double mPower
This parameter determines the scaling for trace sigma descriptor.
Definition: ProSHADE.h:114
bool removeIslands(int hlpU, int hlpV, int hlpW, int verbose=0, bool runAll=false)
This function does the island detection support and decides whether different masking should be appli...
void maskMap(int hlpU, int hlpV, int hlpW, double blurBy=250.0, double maxMapIQR=3.0, double extraMaskSpace=3.0)
This function does the map masking for cleaning and re-boxing maps.
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
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
void removePhaseFromMap(double alpha, double bFac, ProSHADE::ProSHADE_settings *settings)
This function removes the phase information from the density map.
std::array< double, 4 > getTranslationFunctionMap(ProSHADE_data *obj1, ProSHADE_data *obj2, double *ob2XMov=nullptr, double *ob2YMov=nullptr, double *ob2ZMov=nullptr)
Computes the translation function for the two objects and returns the position of the highest peak...
This file contains the ProSHADE_internal_misc namespace and its miscellaneous functions.
double extraSpace
What should be the distance added on both sides to the structure, so that the next cell density would...
Definition: ProSHADE.h:109
unsigned int glIntegOrder
This parameter controls the Gauss-Legendre integration order and so the radial resolution.
Definition: ProSHADE.h:82