ProSHADE  0.7.6.2 (DEC 2021)
Protein Shape Detection
ProSHADE_mapManip.cpp
Go to the documentation of this file.
1 
22 //==================================================== ProSHADE
23 #include "ProSHADE_mapManip.hpp"
24 
25 //==================================================== Define round for C++98
31 proshade_signed ProSHADE_internal_mapManip::myRound ( proshade_double x )
32 {
33 #if __cplusplus >= 201103L
34  return ( static_cast< proshade_signed > ( std::round ( x ) ) );
35 #else
36  return ( static_cast< proshade_signed > ( round ( x ) ) );
37 #endif
38 }
39 
40 //==================================================== Define round for C++98
46 proshade_signed ProSHADE_internal_mapManip::myRound ( proshade_single x )
47 {
48 #if __cplusplus >= 201103L
49  return ( static_cast< proshade_signed > ( std::round ( x ) ) );
50 #else
51  return ( static_cast< proshade_signed > ( round ( x ) ) );
52 #endif
53 }
54 
72 void ProSHADE_internal_mapManip::determinePDBRanges ( gemmi::Structure pdbFile, proshade_single* xFrom, proshade_single* xTo, proshade_single* yFrom, proshade_single* yTo, proshade_single* zFrom, proshade_single* zTo, bool firstModel )
73 {
74  //================================================ Initialise structure crawl
75  bool firstAtom = true;
76 
77  //================================================ Use the first model, if it exists
78  if ( pdbFile.models.size() > 0 )
79  {
80  //============================================ For each model
81  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile.models.size() ); sIt++ )
82  {
83  //======================================== Check if multiple models are allowed
84  if ( firstModel && ( sIt != 0 ) ) { break; }
85 
86  //======================================== Get model
87  gemmi::Model model = pdbFile.models.at(sIt);
88 
89  //======================================== For each chain
90  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model.chains.size() ); mIt++ )
91  {
92  //==================================== Get chain
93  gemmi::Chain chain = model.chains.at(mIt);
94 
95  //==================================== For each residue
96  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain.residues.size() ); rIt++ )
97  {
98  //================================ Get residue
99  gemmi::Residue residue = chain.residues.at(rIt);
100 
101  //================================ For each atom
102  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue.atoms.size() ); aIt++ )
103  {
104  //============================ Get atom
105  gemmi::Atom atom = residue.atoms.at(aIt);
106 
107  //============================ Ignore hydrogens, map computations ignore them anyway and inclusion here causes map - co-ordinate mismatches.
108  if ( atom.is_hydrogen() ) { continue; }
109 
110  //============================ Find the coordinate ranges
111  if ( firstAtom )
112  {
113  *xTo = static_cast<proshade_single> ( atom.pos.x );
114  *xFrom = static_cast<proshade_single> ( atom.pos.x );
115  *yTo = static_cast<proshade_single> ( atom.pos.y );
116  *yFrom = static_cast<proshade_single> ( atom.pos.y );
117  *zTo = static_cast<proshade_single> ( atom.pos.z );
118  *zFrom = static_cast<proshade_single> ( atom.pos.z );
119  firstAtom = false;
120  }
121  else
122  {
123  if ( static_cast<proshade_single> ( atom.pos.x ) > *xTo ) { *xTo = static_cast<proshade_single> ( atom.pos.x ); }
124  if ( static_cast<proshade_single> ( atom.pos.x ) < *xFrom ) { *xFrom = static_cast<proshade_single> ( atom.pos.x ); }
125  if ( static_cast<proshade_single> ( atom.pos.y ) > *yTo ) { *yTo = static_cast<proshade_single> ( atom.pos.y ); }
126  if ( static_cast<proshade_single> ( atom.pos.y ) < *yFrom ) { *yFrom = static_cast<proshade_single> ( atom.pos.y ); }
127  if ( static_cast<proshade_single> ( atom.pos.z ) > *zTo ) { *zTo = static_cast<proshade_single> ( atom.pos.z ); }
128  if ( static_cast<proshade_single> ( atom.pos.z ) < *zFrom ) { *zFrom = static_cast<proshade_single> ( atom.pos.z ); }
129  }
130  }
131  }
132  }
133  }
134  }
135  else
136  {
137  std::stringstream hlpSS;
138  hlpSS << "Found 0 models in input file " << pdbFile.name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
139  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
140  }
141 
142  //================================================ Done
143  return ;
144 
145 }
146 
157 void ProSHADE_internal_mapManip::findPDBCOMValues ( gemmi::Structure pdbFile, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, bool firstModel )
158 {
159  //================================================ Initialise structure crawl
160  proshade_double totAtoms = 0.0;
161  *xCom = 0.0;
162  *yCom = 0.0;
163  *zCom = 0.0;
164 
165  //================================================ Use the first model, if it exists
166  if ( pdbFile.models.size() > 0 )
167  {
168  //============================================ For each model
169  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile.models.size() ); sIt++ )
170  {
171  //======================================== Get model
172  gemmi::Model model = pdbFile.models.at(sIt);
173 
174  //======================================== Check if multiple models are allowed
175  if ( firstModel && ( sIt != 0 ) ) { break; }
176 
177  //======================================== For each chain
178  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model.chains.size() ); mIt++ )
179  {
180  //==================================== Get chain
181  gemmi::Chain chain = model.chains.at(mIt);
182 
183  //==================================== For each residue
184  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain.residues.size() ); rIt++ )
185  {
186  //================================ Get residue
187  gemmi::Residue residue = chain.residues.at(rIt);
188 
189  //================================ For each atom
190  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue.atoms.size() ); aIt++ )
191  {
192  //============================ Get atom
193  gemmi::Atom atom = residue.atoms.at(aIt);
194 
195  //============================ Save the COM sums
196  *xCom += atom.pos.x * atom.element.weight();
197  *yCom += atom.pos.y * atom.element.weight();
198  *zCom += atom.pos.z * atom.element.weight();
199  totAtoms += atom.element.weight();
200  }
201  }
202  }
203  }
204  }
205  else
206  {
207  std::stringstream hlpSS;
208  hlpSS << "Found 0 models in input file " << pdbFile.name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
209  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
210  }
211 
212  //================================================ Normalise sums to COM
213  *xCom /= totAtoms;
214  *yCom /= totAtoms;
215  *zCom /= totAtoms;
216 
217  //================================================ Done
218  return ;
219 
220 }
221 
240 void ProSHADE_internal_mapManip::findMAPCOMValues ( proshade_double* map, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo )
241 {
242  //================================================ Initialise computation
243  proshade_double totDensity = 0.0;
244  *xCom = 0.0;
245  *yCom = 0.0;
246  *zCom = 0.0;
247  proshade_signed arrPos = 0;
248  proshade_single xSampRate = xAngs / static_cast< proshade_single > ( xTo - xFrom );
249  proshade_single ySampRate = yAngs / static_cast< proshade_single > ( yTo - yFrom );
250  proshade_single zSampRate = zAngs / static_cast< proshade_single > ( zTo - zFrom );
251 
252  //================================================ For each map point
253  for ( proshade_signed xIt = xFrom; xIt <= xTo; xIt++ )
254  {
255  for ( proshade_signed yIt = yFrom; yIt <= yTo; yIt++ )
256  {
257  for ( proshade_signed zIt = zFrom; zIt <= zTo; zIt++ )
258  {
259  arrPos = (zIt-zFrom) + ( zTo - zFrom + 1 ) * ( ( yIt - yFrom ) + ( yTo - yFrom + 1 ) * ( xIt - xFrom ) );
260  const FloatingPoint< proshade_double > lhs ( map[arrPos] );
261  if ( !lhs.AlmostEquals ( lhs ) ) { map[arrPos] = 0.0; continue; }
262 
263  if ( map[arrPos] > 0.0 )
264  {
265  totDensity += map[arrPos];
266  *xCom += static_cast<proshade_double> ( static_cast< proshade_single > ( xIt ) * xSampRate ) * map[arrPos];
267  *yCom += static_cast<proshade_double> ( static_cast< proshade_single > ( yIt ) * ySampRate ) * map[arrPos];
268  *zCom += static_cast<proshade_double> ( static_cast< proshade_single > ( zIt ) * zSampRate ) * map[arrPos];
269  }
270  }
271  }
272  }
273 
274  //================================================ Normalise sums to COM
275  *xCom /= totDensity;
276  *yCom /= totDensity;
277  *zCom /= totDensity;
278 
279  //================================================ Done
280  return ;
281 
282 }
283 
298 void ProSHADE_internal_mapManip::rotatePDBCoordinates ( gemmi::Structure *pdbFile, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double xCom,
299 proshade_double yCom, proshade_double zCom, bool firstModel )
300 {
301  //================================================ Convert Euler angles to rotation matrix
302  proshade_double *rotMat = new proshade_double[9];
303  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
305 
306  //================================================ Initialise internal variables
307  proshade_double xTmp, yTmp, zTmp;
308 
309  //================================================ Use the first model, if it exists
310  if ( pdbFile->models.size() > 0 )
311  {
312  //============================================ For each model
313  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile->models.size() ); sIt++ )
314  {
315  //======================================== Get model
316  gemmi::Model *model = &pdbFile->models.at(sIt);
317 
318  //======================================== Check if multiple models are allowed
319  if ( firstModel && ( sIt != 0 ) ) { break; }
320 
321  //======================================== For each chain
322  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model->chains.size() ); mIt++ )
323  {
324  //==================================== Get chain
325  gemmi::Chain *chain = &model->chains.at(mIt);
326 
327  //==================================== For each residue
328  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain->residues.size() ); rIt++ )
329  {
330  //================================ Get residue
331  gemmi::Residue *residue = &chain->residues.at(rIt);
332 
333  //================================ For each atom
334  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue->atoms.size() ); aIt++ )
335  {
336  //============================ Get atom
337  gemmi::Atom *atom = &residue->atoms.at(aIt);
338 
339  //============================ Move to mid-point
340  xTmp = static_cast< proshade_double > ( atom->pos.x - xCom );
341  yTmp = static_cast< proshade_double > ( atom->pos.y - yCom );
342  zTmp = static_cast< proshade_double > ( atom->pos.z - zCom );
343 
344  //============================ Rotate the atom position
345  atom->pos.x = ( xTmp * rotMat[0] ) + ( yTmp * rotMat[1] ) + ( zTmp * rotMat[2] );
346  atom->pos.y = ( xTmp * rotMat[3] ) + ( yTmp * rotMat[4] ) + ( zTmp * rotMat[5] );
347  atom->pos.z = ( xTmp * rotMat[6] ) + ( yTmp * rotMat[7] ) + ( zTmp * rotMat[8] );
348 
349  //============================ Move back
350  atom->pos.x = atom->pos.x + xCom;
351  atom->pos.y = atom->pos.y + yCom;
352  atom->pos.z = atom->pos.z + zCom;
353  }
354  }
355  }
356  }
357  }
358  else
359  {
360  std::stringstream hlpSS;
361  hlpSS << "Found 0 models in input file " << pdbFile->name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
362  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
363  }
364 
365  //================================================ Release memory
366  delete[] rotMat;
367 
368  //================================================ Done
369  return ;
370 
371 }
372 
383 void ProSHADE_internal_mapManip::translatePDBCoordinates ( gemmi::Structure *pdbFile, proshade_double transX, proshade_double transY, proshade_double transZ, bool firstModel )
384 {
385  //================================================ Use the first model, if it exists
386  if ( pdbFile->models.size() > 0 )
387  {
388  //============================================ For each model
389  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile->models.size() ); sIt++ )
390  {
391  //======================================== Check if multiple models are allowed
392  if ( firstModel && ( sIt != 0 ) ) { break; }
393 
394  //======================================== Get model
395  gemmi::Model *model = &pdbFile->models.at(sIt);
396 
397  //======================================== For each chain
398  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model->chains.size() ); mIt++ )
399  {
400  //==================================== Get chain
401  gemmi::Chain *chain = &model->chains.at(mIt);
402 
403  //==================================== For each residue
404  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain->residues.size() ); rIt++ )
405  {
406  //================================ Get residue
407  gemmi::Residue *residue = &chain->residues.at(rIt);
408 
409  //================================ For each atom
410  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue->atoms.size() ); aIt++ )
411  {
412  //============================ Get atom
413  gemmi::Atom *atom = &residue->atoms.at(aIt);
414 
415  //============================ Translate
416  atom->pos.x += transX;
417  atom->pos.y += transY;
418  atom->pos.z += transZ;
419  }
420  }
421  }
422  }
423  }
424  else
425  {
426  std::stringstream hlpSS;
427  hlpSS << "Found 0 models in input file " << pdbFile->name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
428  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
429  }
430 
431  //================================================ Done
432  return ;
433 
434 }
435 
446 void ProSHADE_internal_mapManip::changePDBBFactors ( gemmi::Structure *pdbFile, proshade_double newBFactorValue, bool firstModel )
447 {
448  //================================================ Use the first model, if it exists
449  if ( pdbFile->models.size() > 0 )
450  {
451  //============================================ For each model
452  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile->models.size() ); sIt++ )
453  {
454  //======================================== Check if multiple models are allowed
455  if ( firstModel && ( sIt != 0 ) ) { break; }
456 
457  //======================================== Get model
458  gemmi::Model *model = &pdbFile->models.at(sIt);
459 
460  //======================================== For each chain
461  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model->chains.size() ); mIt++ )
462  {
463  //==================================== Get chain
464  gemmi::Chain *chain = &model->chains.at(mIt);
465 
466  //==================================== For each residue
467  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain->residues.size() ); rIt++ )
468  {
469  //================================ Get residue
470  gemmi::Residue *residue = &chain->residues.at(rIt);
471 
472  //================================ For each atom
473  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue->atoms.size() ); aIt++ )
474  {
475  //============================ Get atom
476  gemmi::Atom *atom = &residue->atoms.at(aIt);
477 
478  //============================ Change the B-factors
479  atom->b_iso = static_cast< float > ( newBFactorValue );
480  }
481  }
482  }
483  }
484  }
485  else
486  {
487  std::stringstream hlpSS;
488  hlpSS << "Found 0 models in input file " << pdbFile->name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
489  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
490  }
491 
492  //================================================ Done
493  return ;
494 
495 }
496 
506 void ProSHADE_internal_mapManip::removeWaters ( gemmi::Structure *pdbFile, bool firstModel )
507 {
508  //================================================ Use the first model, if it exists
509  if ( pdbFile->models.size() > 0 )
510  {
511  //============================================ For each model
512  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile->models.size() ); sIt++ )
513  {
514  //======================================== Check if multiple models are allowed
515  if ( firstModel && ( sIt != 0 ) ) { break; }
516 
517  //======================================== Get model
518  gemmi::Model *model = &pdbFile->models.at(sIt);
519 
520  //======================================== For each chain
521  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model->chains.size() ); mIt++ )
522  {
523  //==================================== Get chain
524  gemmi::Chain *chain = &model->chains.at(mIt);
525 
526  //==================================== Initialise del vector
527  std::vector< proshade_unsign > delVec;
528 
529  //==================================== For each residue
530  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain->residues.size() ); rIt++ )
531  {
532  //================================ Get residue
533  gemmi::Residue *residue = &chain->residues.at(rIt);
534 
535  //================================ If residue is water
536  if ( residue->is_water() )
537  {
539  }
540  }
541 
542  //==================================== Delete from end to avoid indexing issues
543  std::sort ( delVec.begin(), delVec.end(), std::greater<int>() );
544  for ( proshade_unsign vecIt = 0; vecIt < static_cast<proshade_unsign> ( delVec.size() ); vecIt++ )
545  {
546  chain->residues.erase ( chain->residues.begin() + static_cast< long int > ( delVec.at(vecIt) ) );
547  }
548  }
549  }
550  }
551  else
552  {
553  std::stringstream hlpSS;
554  hlpSS << "Found 0 models in input file " << pdbFile->name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
555  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
556  }
557 
558  //================================================ Done
559  return ;
560 
561 }
562 
575 void ProSHADE_internal_mapManip::movePDBForMapCalc ( gemmi::Structure *pdbFile, proshade_single xMov, proshade_single yMov, proshade_single zMov, bool firstModel )
576 {
577  //================================================ Use the first model, if it exists
578  if ( pdbFile->models.size() > 0 )
579  {
580  //============================================ For each model
581  for ( proshade_unsign sIt = 0; sIt < static_cast<proshade_unsign> ( pdbFile->models.size() ); sIt++ )
582  {
583  //======================================== Check if multiple models are allowed
584  if ( firstModel && ( sIt != 0 ) ) { break; }
585 
586  //======================================== Get model
587  gemmi::Model *model = &pdbFile->models.at(sIt);
588 
589  //======================================== For each chain
590  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( model->chains.size() ); mIt++ )
591  {
592  //==================================== Get chain
593  gemmi::Chain *chain = &model->chains.at(mIt);
594 
595  //==================================== For each residue
596  for ( proshade_unsign rIt = 0; rIt < static_cast<proshade_unsign> ( chain->residues.size() ); rIt++ )
597  {
598  //================================ Get residue
599  gemmi::Residue *residue = &chain->residues.at(rIt);
600 
601  //================================ For each atom
602  for ( proshade_unsign aIt = 0; aIt < static_cast<proshade_unsign> ( residue->atoms.size() ); aIt++ )
603  {
604  //============================ Get atom
605  gemmi::Atom *atom = &residue->atoms.at(aIt);
606 
607  //============================ Move the atoms
608  atom->pos = gemmi::Position ( atom->pos.x + static_cast< proshade_double > ( xMov ), atom->pos.y + static_cast< proshade_double > ( yMov ), atom->pos.z + static_cast< proshade_double > ( zMov ) );
609  }
610  }
611  }
612 
613  }
614  }
615  else
616  {
617  std::stringstream hlpSS;
618  hlpSS << "Found 0 models in input file " << pdbFile->name << ".\n : This suggests that the input co-ordinate file is\n : corrupted or mis-formatted.";
619  throw ProSHADE_exception ( "Found no model in co-ordinate file.", "EP00050", __FILE__, __LINE__, __func__, hlpSS.str() );
620  }
621 
622  //================================================ Done
623  return ;
624 }
625 
646 void ProSHADE_internal_mapManip::generateMapFromPDB ( gemmi::Structure pdbFile, proshade_double*& map, proshade_single requestedResolution, proshade_single xCell, proshade_single yCell, proshade_single zCell, proshade_signed* xTo, proshade_signed* yTo, proshade_signed* zTo, bool forceP1, bool firstModel )
647 {
648  //================================================ Set cell dimensions from the increased ranges (we need to add some space) and re-calculate cell properties
649  if ( forceP1 ) { pdbFile.cell = gemmi::UnitCell(); }
650  pdbFile.cell.a = static_cast< proshade_double > ( xCell );
651  pdbFile.cell.b = static_cast< proshade_double > ( yCell );
652  pdbFile.cell.c = static_cast< proshade_double > ( zCell );
653  pdbFile.cell.calculate_properties ( );
654 
655  //================================================ Get elements in Gemmi format
656  std::string totElString;
657  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( pdbFile.models.size() ); mIt++ )
658  {
659  //============================================ Check if multiple models are allowed
660  if ( firstModel && ( mIt != 0 ) )
661  {
662  std::stringstream hlpSS;
663  hlpSS << "!!! ProSHADE WARNING !!! Found multiple models (" << pdbFile.models.size() << ") in input file " << pdbFile.name << ", while the settings state that only the first PDB file model should be used. If all models should be used, please supply ProSHADE with the \"-x\" option.";
664  ProSHADE_internal_messages::printWarningMessage ( 0, hlpSS.str(), "WP00055" );
665  break;
666  }
667 
668  std::string hlpStr = pdbFile.models[mIt].present_elements ( ).to_string<char,std::char_traits<char>,std::allocator<char> >();
669  totElString = totElString + hlpStr;
670  }
671  std::bitset< static_cast< size_t > ( gemmi::El::END )> present_elems ( totElString );
672 
673  //================================================ Sanity checks
674  if ( present_elems[static_cast<int> ( gemmi::El::X )] )
675  {
676  throw ProSHADE_exception ( "Found unknown element in input file.", "EP00051", __FILE__, __LINE__, __func__, "Gemmi library does not recognise some of the elements in\n : the co-ordinate file. Please check the file for not being\n : corrupted and containing standard elements." );
677  }
678 
679  for ( proshade_unsign elIt = 0; elIt < static_cast<proshade_unsign> ( present_elems.size() ); elIt++ )
680  {
681  if ( present_elems[elIt] && !gemmi::IT92<double>::has ( static_cast<gemmi::El> ( elIt ) ) )
682  {
683  std::stringstream hlpSS;
684  hlpSS << "Missing form factor for element " << element_name ( static_cast<gemmi::El> ( elIt ) );
685  throw ProSHADE_exception ( hlpSS.str().c_str(), "EP00052", __FILE__, __LINE__, __func__, "Gemmi library does not have a form factor value for this\n : reported element. Please report this to the author." );
686  }
687  }
688 
689  //================================================ Compute the f's
690  double wavelength = 10.0;
691  double energy = gemmi::hc() / wavelength;
692 
693  //================================================ Create the density calculator object and fill it in
694  gemmi::DensityCalculator<gemmi::IT92<double>, float> dencalc;
695 
696  dencalc.d_min = static_cast< double > ( requestedResolution );
697  for ( size_t elIt = 0; elIt < present_elems.size(); elIt++ ) { if ( present_elems[elIt] ) { dencalc.addends.set ( static_cast< gemmi::El > ( elIt ), static_cast< float > ( gemmi::cromer_liberman ( static_cast< int > ( elIt ), energy, nullptr ) ) ); } }
698  dencalc.set_grid_cell_and_spacegroup ( pdbFile );
699 
700  //================================================ Force P1 spacegroup
701  if ( forceP1 ) { dencalc.grid.spacegroup = &gemmi::get_spacegroup_p1(); }
702 
703  //================================================ Compute the theoretical map for each model
704  dencalc.grid.data.clear ( );
705  dencalc.grid.set_size_from_spacing ( dencalc.d_min / ( 2.0 * dencalc.rate), true );
706  for ( proshade_unsign mIt = 0; mIt < static_cast<proshade_unsign> ( pdbFile.models.size() ); mIt++ )
707  {
708  if ( firstModel && ( mIt != 0 ) ) { break; }
709  dencalc.add_model_density_to_grid ( pdbFile.models[mIt] );
710  dencalc.grid.symmetrize ( [](float a, float b) { return a + b; } );
711  }
712 
713  //================================================ Get the map
714  const gemmi::Grid<float>& grid = dencalc.grid;
715 
716  //================================================ Save the map dimensions
717  *xTo = grid.nu;
718  *yTo = grid.nv;
719  *zTo = grid.nw;
720 
721  //================================================ Copy the gemmi::Grid to my map format
722  map = new proshade_double [(*xTo) * (*yTo) * (*zTo)];
723  ProSHADE_internal_misc::checkMemoryAllocation ( map, __FILE__, __LINE__, __func__ );
724 
725  proshade_signed arrPos = 0;
726  for ( proshade_signed uIt = 0; uIt < (*xTo); uIt++ )
727  {
728  for ( proshade_signed vIt = 0; vIt < (*yTo); vIt++ )
729  {
730  for ( proshade_signed wIt = 0; wIt < (*zTo); wIt++ )
731  {
732  arrPos = wIt + (*zTo) * ( vIt + (*yTo) * uIt );
733  map[arrPos] = static_cast< proshade_double > ( grid.get_value_q( static_cast< int > ( uIt ), static_cast< int > ( vIt ), static_cast< int > ( wIt ) ) );
734  }
735  }
736  }
737 
738  //================================================ Done
739  return ;
740 
741 }
742 
765 void ProSHADE_internal_mapManip::moveMapByIndices ( proshade_single* xMov, proshade_single* yMov, proshade_single* zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed* xFrom, proshade_signed* xTo, proshade_signed* yFrom, proshade_signed* yTo, proshade_signed* zFrom, proshade_signed* zTo, proshade_signed* xOrigin, proshade_signed* yOrigin, proshade_signed* zOrigin )
766 {
767  //================================================ Compute movement in indices
768  proshade_single xIndMove = std::floor ( -(*xMov) / ( xAngs / ( static_cast< proshade_single > ( *xTo ) - static_cast< proshade_single > ( *xFrom ) + 1.0f ) ) );
769  proshade_single yIndMove = std::floor ( -(*yMov) / ( yAngs / ( static_cast< proshade_single > ( *yTo ) - static_cast< proshade_single > ( *yFrom ) + 1.0f ) ) );
770  proshade_single zIndMove = std::floor ( -(*zMov) / ( zAngs / ( static_cast< proshade_single > ( *zTo ) - static_cast< proshade_single > ( *zFrom ) + 1.0f ) ) );
771 
772  //================================================ Set the movs to the remainder
773  *xMov = -( *xMov ) - ( xIndMove * ( xAngs / ( static_cast< proshade_single > ( *xTo ) - static_cast< proshade_single > ( *xFrom ) + 1.0f ) ) );
774  *yMov = -( *yMov ) - ( yIndMove * ( yAngs / ( static_cast< proshade_single > ( *yTo ) - static_cast< proshade_single > ( *yFrom ) + 1.0f ) ) );
775  *zMov = -( *zMov ) - ( zIndMove * ( zAngs / ( static_cast< proshade_single > ( *zTo ) - static_cast< proshade_single > ( *zFrom ) + 1.0f ) ) );
776 
777  //================================================ Move indices by as much
778  *xFrom += static_cast< proshade_signed > ( xIndMove );
779  *xTo += static_cast< proshade_signed > ( xIndMove );
780  *yFrom += static_cast< proshade_signed > ( yIndMove );
781  *yTo += static_cast< proshade_signed > ( yIndMove );
782  *zFrom += static_cast< proshade_signed > ( zIndMove );
783  *zTo += static_cast< proshade_signed > ( zIndMove );
784 
785  //================================================ And set origin to reflect the changes
786  *xOrigin = *xFrom;
787  *yOrigin = *yFrom;
788  *zOrigin = *zFrom;
789 
790  //================================================ Done
791  return ;
792 
793 }
794 
813 void ProSHADE_internal_mapManip::moveMapByFourier ( proshade_double*& map, proshade_single xMov, proshade_single yMov, proshade_single zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
814 {
815  //================================================ Local variables initialisation
816  proshade_unsign arrayPos = 0;
817 
818  //================================================ Create Fourier map variable
819  fftw_complex *fCoeffs = new fftw_complex [xDim * yDim * zDim];
820  fftw_complex *translatedMap = new fftw_complex [xDim * yDim * zDim];
821 
822  //================================================ Check memory allocation
823  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffs, __FILE__, __LINE__, __func__ );
824  ProSHADE_internal_misc::checkMemoryAllocation ( translatedMap, __FILE__, __LINE__, __func__ );
825 
826  //================================================ Create plans
827  fftw_plan planForwardFourier = fftw_plan_dft_3d ( static_cast< int > ( xDim ), static_cast< int > ( yDim ), static_cast< int > ( zDim ), translatedMap, fCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
828  fftw_plan planBackwardFourier = fftw_plan_dft_3d ( static_cast< int > ( xDim ), static_cast< int > ( yDim ), static_cast< int > ( zDim ), fCoeffs, translatedMap, FFTW_BACKWARD, FFTW_ESTIMATE );
829 
830  //================================================ Copy map to complex format
831  for ( proshade_unsign uIt = 0; uIt < static_cast< proshade_unsign > ( xDim ); uIt++ )
832  {
833  for ( proshade_unsign vIt = 0; vIt < static_cast< proshade_unsign > ( yDim ); vIt++ )
834  {
835  for ( proshade_unsign wIt = 0; wIt < static_cast< proshade_unsign > ( zDim ); wIt++ )
836  {
837  arrayPos = wIt + static_cast< proshade_unsign > ( zDim ) * ( vIt + static_cast< proshade_unsign > ( yDim ) * uIt );
838 
839  const FloatingPoint< proshade_double > lhs ( map[arrayPos] ), rhs ( map[arrayPos] );
840  if ( lhs.AlmostEquals ( rhs ) ) { translatedMap[arrayPos][0] = map[arrayPos]; }
841  else { translatedMap[arrayPos][0] = 0.0; }
842  translatedMap[arrayPos][1] = 0.0;
843  }
844  }
845  }
846 
847  //================================================ Compute Forward Fourier
848  fftw_execute ( planForwardFourier );
849 
850  //================================================ Shift the Fourier coefficients
851  proshade_double *weight = nullptr;
852  moveMapByFourierInReci ( fCoeffs, weight, xMov, yMov, zMov, xAngs, yAngs, zAngs, xDim, yDim, zDim );
853 
854  //================================================ Compute inverse Fourier
855  fftw_execute ( planBackwardFourier );
856 
857  //================================================ Copy back to map
858  for ( proshade_unsign uIt = 0; uIt < static_cast< proshade_unsign > ( xDim ); uIt++ )
859  {
860  for ( proshade_unsign vIt = 0; vIt < static_cast< proshade_unsign > ( yDim ); vIt++ )
861  {
862  for ( proshade_unsign wIt = 0; wIt < static_cast< proshade_unsign > ( zDim ); wIt++ )
863  {
864  arrayPos = wIt + static_cast< proshade_unsign > ( zDim ) * ( vIt + static_cast< proshade_unsign > ( yDim ) * uIt );
865  map[arrayPos] = translatedMap[arrayPos][0];
866  }
867  }
868  }
869 
870  //================================================ Release memory
871  fftw_destroy_plan ( planForwardFourier );
872  fftw_destroy_plan ( planBackwardFourier );
873  delete[] fCoeffs;
874  delete[] translatedMap;
875 
876  //================================================ Done
877  return ;
878 
879 }
880 
898 void ProSHADE_internal_mapManip::moveMapByFourierInReci ( proshade_complex*& coeffs, proshade_double*& weights, proshade_single xMov, proshade_single yMov, proshade_single zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim )
899 {
900  //================================================ Local variables initialisation
901  proshade_unsign arrayPos = 0;
902  proshade_signed h, k, l;
903  proshade_double real = 0.0;
904  proshade_double imag = 0.0;
905  proshade_double trCoeffReal, trCoeffImag;
906  proshade_double normFactor = static_cast< proshade_double > ( xDim * yDim * zDim );
907  proshade_double exponent = 0.0;
908  proshade_double hlpArrReal;
909  proshade_double hlpArrImag;
910 
911  //================================================ If no weights are given, set them to 1.0, otherwise use supplied
912  proshade_double* wght = new proshade_double[xDim * yDim * zDim];
913  ProSHADE_internal_misc::checkMemoryAllocation ( wght, __FILE__, __LINE__, __func__ );
914  if ( weights == nullptr ) { for ( size_t iter = 0; iter < static_cast< size_t > ( xDim * yDim * zDim ); iter++ ) { wght[iter] = 1.0; } }
915  else { for ( size_t iter = 0; iter < static_cast< size_t > ( xDim * yDim * zDim ); iter++ ) { wght[iter] = weights[iter]; } }
916 
917  //================================================ Add the required shift
918  for ( proshade_unsign uIt = 0; uIt < static_cast<proshade_unsign> ( xDim ); uIt++ )
919  {
920  for ( proshade_unsign vIt = 0; vIt < static_cast<proshade_unsign> ( yDim ); vIt++ )
921  {
922  for ( proshade_unsign wIt = 0; wIt < static_cast<proshade_unsign> ( zDim ); wIt++ )
923  {
924  //==================================== Var init
925  arrayPos = wIt + static_cast< proshade_unsign > ( zDim ) * ( vIt + static_cast< proshade_unsign > ( yDim ) * uIt );
926  real = coeffs[arrayPos][0];
927  imag = coeffs[arrayPos][1];
928 
929  //==================================== Convert 0-max indices to HKL
930  if ( uIt > static_cast< proshade_unsign > ( (xDim+1) / 2) ) { h = static_cast < proshade_signed > ( uIt ) - xDim; } else { h = static_cast < proshade_signed > ( uIt ); }
931  if ( vIt > static_cast< proshade_unsign > ( (yDim+1) / 2) ) { k = static_cast < proshade_signed > ( vIt ) - yDim; } else { k = static_cast < proshade_signed > ( vIt ); }
932  if ( wIt > static_cast< proshade_unsign > ( (zDim+1) / 2) ) { l = static_cast < proshade_signed > ( wIt ) - zDim; } else { l = static_cast < proshade_signed > ( wIt ); }
933 
934  //==================================== Get translation coefficient change
935  exponent = ( ( ( static_cast <proshade_double> ( h ) / static_cast <proshade_double> ( xAngs ) ) * static_cast< proshade_double > ( -xMov ) ) +
936  ( ( static_cast <proshade_double> ( k ) / static_cast <proshade_double> ( yAngs ) ) * static_cast< proshade_double > ( -yMov ) ) +
937  ( ( static_cast <proshade_double> ( l ) / static_cast <proshade_double> ( zAngs ) ) * static_cast< proshade_double > ( -zMov ) ) ) * 2.0 * M_PI;
938 
939  trCoeffReal = cos ( exponent );
940  trCoeffImag = sin ( exponent );
941  ProSHADE_internal_maths::complexMultiplication ( &real, &imag, &trCoeffReal, &trCoeffImag, &hlpArrReal, &hlpArrImag );
942 
943  //==================================== Save the translated coefficient value and apply weights
944  coeffs[arrayPos][0] = ( hlpArrReal / normFactor ) * wght[arrayPos];
945  coeffs[arrayPos][1] = ( hlpArrImag / normFactor ) * wght[arrayPos];
946  }
947  }
948  }
949 
950  //================================================ Release weights
951  delete[] wght;
952 
953  //================================================ Done
954  return ;
955 
956 }
957 
974 void ProSHADE_internal_mapManip::blurSharpenMap ( proshade_double*& map, proshade_double*& blurredMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single blurringFactor )
975 {
976  //================================================ Set local variables
977  proshade_signed xDim = static_cast< proshade_signed > ( xDimS );
978  proshade_signed yDim = static_cast< proshade_signed > ( yDimS );
979  proshade_signed zDim = static_cast< proshade_signed > ( zDimS );
980  proshade_double real, imag, S, mag, phase;
981  proshade_signed h, k, l;
982  proshade_unsign arrayPos = 0;
983  proshade_double normFactor = static_cast<proshade_double> ( xDim * yDim * zDim );
984 
985  //================================================ Copy map for processing
986  fftw_complex* mapCoeffs = new fftw_complex[xDim * yDim * zDim];
987  fftw_complex* mapMask = new fftw_complex[xDim * yDim * zDim];
988 
989  //================================================ Check memory allocation
990  ProSHADE_internal_misc::checkMemoryAllocation ( mapCoeffs, __FILE__, __LINE__, __func__ );
991  ProSHADE_internal_misc::checkMemoryAllocation ( mapMask, __FILE__, __LINE__, __func__ );
992 
993  //================================================ Copy data to mask
994  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> (xDim * yDim * zDim); iter++ )
995  {
996  mapMask[iter][0] = map[iter];
997  mapMask[iter][1] = 0.0;
998  }
999 
1000  //================================================ Prepare FFTW plans
1001  fftw_plan forward = fftw_plan_dft_3d ( static_cast< int > ( xDim ), static_cast< int > ( yDim ), static_cast< int > ( zDim ), mapMask, mapCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
1002  fftw_plan inverse = fftw_plan_dft_3d ( static_cast< int > ( xDim ), static_cast< int > ( yDim ), static_cast< int > ( zDim ), mapCoeffs, mapMask, FFTW_BACKWARD, FFTW_ESTIMATE );
1003 
1004  //================================================ Run forward Fourier
1005  fftw_execute ( forward );
1006 
1007  //================================================ Blur the coeffs
1008  for ( proshade_unsign uIt = 0; uIt < static_cast<proshade_unsign> ( xDim ); uIt++ )
1009  {
1010  for ( proshade_unsign vIt = 0; vIt < static_cast<proshade_unsign> ( yDim ); vIt++ )
1011  {
1012  for ( proshade_unsign wIt = 0; wIt < static_cast<proshade_unsign> ( zDim ); wIt++ )
1013  {
1014  //==================================== Var init
1015  arrayPos = wIt + static_cast< proshade_unsign > ( zDim ) * ( vIt + static_cast< proshade_unsign > ( yDim ) * uIt );
1016  real = mapCoeffs[arrayPos][0];
1017  imag = mapCoeffs[arrayPos][1];
1018 
1019  //==================================== Convert to HKL
1020  if ( uIt > static_cast< proshade_unsign > ( (xDim+1) / 2) ) { h = static_cast < proshade_signed > ( uIt ) - xDim; } else { h = static_cast < proshade_signed > ( uIt ); }
1021  if ( vIt > static_cast< proshade_unsign > ( (yDim+1) / 2) ) { k = static_cast < proshade_signed > ( vIt ) - yDim; } else { k = static_cast < proshade_signed > ( vIt ); }
1022  if ( wIt > static_cast< proshade_unsign > ( (zDim+1) / 2) ) { l = static_cast < proshade_signed > ( wIt ) - zDim; } else { l = static_cast < proshade_signed > ( wIt ); }
1023 
1024  //====================================Get magnitude and phase with mask parameters
1025  S = ( pow( static_cast< proshade_double > ( h ) / static_cast< proshade_double > ( xAngs ), 2.0 ) +
1026  pow( static_cast< proshade_double > ( k ) / static_cast< proshade_double > ( yAngs ), 2.0 ) +
1027  pow( static_cast< proshade_double > ( l ) / static_cast< proshade_double > ( zAngs ), 2.0 ) );
1028  mag = std::sqrt ( (real*real) + (imag*imag) ) * std::exp ( - ( ( static_cast< proshade_double > ( blurringFactor ) * S ) / 4.0 ) );
1029  phase = std::atan2 ( imag, real );
1030 
1031  //==================================== Save the mask data
1032  mapCoeffs[arrayPos][0] = ( mag * cos(phase) ) / normFactor;
1033  mapCoeffs[arrayPos][1] = ( mag * sin(phase) ) / normFactor;
1034  }
1035  }
1036  }
1037 
1038  //================================================ Run inverse Fourier
1039  fftw_execute ( inverse );
1040 
1041  //================================================ Save the results
1042  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> (xDim * yDim * zDim); iter++ )
1043  {
1044  blurredMap[iter] = mapMask[iter][0];
1045  }
1046 
1047  //================================================ Release memory
1048  delete[] mapMask;
1049  delete[] mapCoeffs;
1050 
1051  //================================================ Delete FFTW plans
1052  fftw_destroy_plan ( forward );
1053  fftw_destroy_plan ( inverse );
1054 
1055  //================================================ Done
1056  return ;
1057 
1058 }
1059 
1074 void ProSHADE_internal_mapManip::getMaskFromBlurr ( proshade_double*& blurMap, proshade_double*& outMap, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single noIQRs )
1075 {
1076  //================================================ Initialise vector for map data
1077  std::vector<proshade_double> mapVals ( xDim * yDim * zDim, 0.0 );
1078 
1079  //================================================ Save map values in vector
1080  for ( proshade_unsign iter = 0; iter < ( xDim * yDim * zDim ); iter++ )
1081  {
1082  mapVals.at(iter) = blurMap[iter];
1083  }
1084 
1085  //================================================ Find median and IQRs
1086  proshade_double* medAndIQR = new proshade_double[2];
1087  ProSHADE_internal_maths::vectorMedianAndIQR ( &mapVals, medAndIQR );
1088 
1089  //================================================ Find the threshold
1090  proshade_double maskThreshold = medAndIQR[0] + ( medAndIQR[1] * static_cast<proshade_double> ( noIQRs ) );
1091 
1092  //================================================ Apply threshold
1093  for ( proshade_unsign iter = 0; iter < ( xDim * yDim * zDim ); iter++ )
1094  {
1095  if ( blurMap[iter] < maskThreshold )
1096  {
1097  outMap[iter] = 0.0;
1098  blurMap[iter] = 0.0;
1099  }
1100  }
1101 
1102  //================================================ Release vector values
1103  mapVals.clear ( );
1104 
1105  //================================================ Release memory
1106  delete[] medAndIQR;
1107 
1108  //================================================ Done
1109  return ;
1110 
1111 }
1112 
1124 void ProSHADE_internal_mapManip::getNonZeroBounds ( proshade_double* map, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_signed*& ret )
1125 {
1126  //================================================ Initialise local variables
1127  proshade_signed arrayPos = 0;
1128 
1129  //================================================ Initialise result variable
1130  ret[0] = xDim;
1131  ret[1] = 0;
1132  ret[2] = yDim;
1133  ret[3] = 0;
1134  ret[4] = zDim;
1135  ret[5] = 0;
1136 
1137  //================================================ Iterate through map and check bounds
1138  for ( proshade_signed xIt = 0; xIt < xDim; xIt++ )
1139  {
1140  for ( proshade_signed yIt = 0; yIt < yDim; yIt++ )
1141  {
1142  for ( proshade_signed zIt = 0; zIt < zDim; zIt++ )
1143  {
1144  //==================================== Var init
1145  arrayPos = zIt + zDim * ( yIt + yDim * xIt );
1146 
1147  //==================================== Check bounds
1148  if ( map[arrayPos] > 0.001 )
1149  {
1150  if ( xIt < ret[0] ) { ret[0] = xIt; }
1151  if ( xIt > ret[1] ) { ret[1] = xIt; }
1152  if ( yIt < ret[2] ) { ret[2] = yIt; }
1153  if ( yIt > ret[3] ) { ret[3] = yIt; }
1154  if ( zIt < ret[4] ) { ret[4] = zIt; }
1155  if ( zIt > ret[5] ) { ret[5] = zIt; }
1156  }
1157  }
1158  }
1159  }
1160 
1161  //================================================ Done
1162  return ;
1163 
1164 }
1165 
1181 void ProSHADE_internal_mapManip::addExtraBoundSpace ( proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed*& bounds, proshade_single extraSpace )
1182 {
1183  //================================================ Convert angstrom distance to indices
1184  proshade_signed xExtraInds = ProSHADE_internal_mapManip::myRound ( extraSpace / ( xAngs / static_cast<proshade_single> ( xDim ) ) );
1185  proshade_signed yExtraInds = ProSHADE_internal_mapManip::myRound ( extraSpace / ( yAngs / static_cast<proshade_single> ( yDim ) ) );
1186  proshade_signed zExtraInds = ProSHADE_internal_mapManip::myRound ( extraSpace / ( zAngs / static_cast<proshade_single> ( zDim ) ) );
1187 
1188  //=============================================== Changed bounds even if exceeding physical map - this will be deal with in the map creation part
1189  bounds[0] = bounds[0] - xExtraInds;
1190  bounds[1] = bounds[1] + xExtraInds;
1191  bounds[2] = bounds[2] - yExtraInds;
1192  bounds[3] = bounds[3] + yExtraInds;
1193  bounds[4] = bounds[4] - zExtraInds;
1194  bounds[5] = bounds[5] + zExtraInds;
1195 
1196  //================================================ Done
1197  return ;
1198 
1199 }
1200 
1217 void ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear ( proshade_double*& map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single*& corrs )
1218 {
1219  //================================================ Sanity check - the resolution needs to be set
1220  if ( resolution <= 0.0f )
1221  {
1222  throw ProSHADE_exception ( "Requested resolution not set for map re-sampling.", "EM00015", __FILE__, __LINE__, __func__, "There is no resolution value set, but map re-sampling to\n : this unset resolution value is required. This error\n : occurs when a task with no resolution requirement is\n : requested on a map data and the map resolution change is\n : set to \'on\'. Either supply a resolution value, or do not\n : re-sample the map." );
1223  }
1224 
1225  //================================================ Initialise local variables
1226  proshade_signed xDim = static_cast<proshade_signed> ( xDimS );
1227  proshade_signed yDim = static_cast<proshade_signed> ( yDimS );
1228  proshade_signed zDim = static_cast<proshade_signed> ( zDimS );
1229  proshade_single oldXSample = ( xAngs / static_cast<proshade_single> ( xDim ) );
1230  proshade_single oldYSample = ( yAngs / static_cast<proshade_single> ( yDim ) );
1231  proshade_single oldZSample = ( zAngs / static_cast<proshade_single> ( zDim ) );
1232  proshade_single newXSample = static_cast< proshade_single > ( resolution / 2.0f );
1233  proshade_single newYSample = static_cast< proshade_single > ( resolution / 2.0f );
1234  proshade_single newZSample = static_cast< proshade_single > ( resolution / 2.0f );
1235 
1236  //================================================ Compute required grid size
1237  proshade_signed newXDim = static_cast<proshade_signed> ( std::ceil ( xAngs / newXSample ) );
1238  proshade_signed newYDim = static_cast<proshade_signed> ( std::ceil ( yAngs / newYSample ) );
1239  proshade_signed newZDim = static_cast<proshade_signed> ( std::ceil ( zAngs / newZSample ) );
1240 
1241  //================================================ Create a new map variable
1242  proshade_double* newMap = new proshade_double [newXDim * newYDim * newZDim];
1243 
1244  //================================================ For each new map point
1245  proshade_signed xBottom = 0, xTop, yBottom = 0, yTop, zBottom = 0, zTop, oldMapIndex, newMapIndex;
1246  std::vector<proshade_double> c000 = std::vector<proshade_double> ( 4, 0.0 );
1247  std::vector<proshade_double> c001 = std::vector<proshade_double> ( 4, 0.0 );
1248  std::vector<proshade_double> c010 = std::vector<proshade_double> ( 4, 0.0 );
1249  std::vector<proshade_double> c011 = std::vector<proshade_double> ( 4, 0.0 );
1250  std::vector<proshade_double> c100 = std::vector<proshade_double> ( 4, 0.0 );
1251  std::vector<proshade_double> c101 = std::vector<proshade_double> ( 4, 0.0 );
1252  std::vector<proshade_double> c110 = std::vector<proshade_double> ( 4, 0.0 );
1253  std::vector<proshade_double> c111 = std::vector<proshade_double> ( 4, 0.0 );
1254  std::vector<proshade_double> c00 = std::vector<proshade_double> ( 4, 0.0 );
1255  std::vector<proshade_double> c01 = std::vector<proshade_double> ( 4, 0.0 );
1256  std::vector<proshade_double> c10 = std::vector<proshade_double> ( 4, 0.0 );
1257  std::vector<proshade_double> c11 = std::vector<proshade_double> ( 4, 0.0 );
1258  std::vector<proshade_double> c0 = std::vector<proshade_double> ( 4, 0.0 );
1259  std::vector<proshade_double> c1 = std::vector<proshade_double> ( 4, 0.0 );
1260  proshade_double xRelative, yRelative, zRelative;
1261 
1262  for ( proshade_signed xIt = 0; xIt < newXDim; xIt++ )
1263  {
1264  for ( proshade_signed yIt = 0; yIt < newYDim; yIt++ )
1265  {
1266  for ( proshade_signed zIt = 0; zIt < newZDim; zIt++ )
1267  {
1268  //==================================== Get this point's index
1269  newMapIndex = zIt + newZDim * ( yIt + newYDim * xIt );
1270 
1271  //==================================== Find this points bottom and top positions in the old map (including periodicity)
1272  for ( proshade_signed ox = 0; ox < ( static_cast< proshade_signed > ( xDimS ) - 1 ); ox++ ) { if ( ( ( static_cast< proshade_single > ( xIt ) * newXSample ) >= ( static_cast< proshade_single > ( ox ) * oldXSample ) ) && ( ( static_cast< proshade_single > ( xIt ) * newXSample ) <= ( ( static_cast< proshade_single > ( ox ) + 1 ) * oldXSample ) ) ) { xBottom = ox; break; } }
1273  for ( proshade_signed oy = 0; oy < ( static_cast< proshade_signed > ( yDimS ) - 1 ); oy++ ) { if ( ( ( static_cast< proshade_single > ( yIt ) * newYSample ) >= ( static_cast< proshade_single > ( oy ) * oldYSample ) ) && ( ( static_cast< proshade_single > ( yIt ) * newYSample ) <= ( ( static_cast< proshade_single > ( oy ) + 1 ) * oldYSample ) ) ) { yBottom = oy; break; } }
1274  for ( proshade_signed oz = 0; oz < ( static_cast< proshade_signed > ( zDimS ) - 1 ); oz++ ) { if ( ( ( static_cast< proshade_single > ( zIt ) * newZSample ) >= ( static_cast< proshade_single > ( oz ) * oldZSample ) ) && ( ( static_cast< proshade_single > ( zIt ) * newZSample ) <= ( ( static_cast< proshade_single > ( oz ) + 1 ) * oldZSample ) ) ) { zBottom = oz; break; } }
1275  xTop = xBottom + 1;
1276  yTop = yBottom + 1;
1277  zTop = zBottom + 1;
1278 
1279  //==================================== Find the surrounding point's values from the original map
1280  oldMapIndex = zBottom + static_cast< proshade_signed > ( zDimS ) * ( yBottom + static_cast< proshade_signed > ( yDimS ) * xBottom );
1281  c000.at(0) = static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample );
1282  c000.at(1) = static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample );
1283  c000.at(2) = static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample );
1284  c000.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1285 
1286  oldMapIndex = zTop + static_cast< proshade_signed > ( zDimS ) * ( yBottom + static_cast< proshade_signed > ( yDimS ) * xBottom );
1287  c001.at(0) = static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample );
1288  c001.at(1) = static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample );
1289  c001.at(2) = static_cast<proshade_double> ( zTop ) * static_cast<proshade_double> ( oldZSample );
1290  c001.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1291 
1292  oldMapIndex = zBottom + static_cast< proshade_signed > ( zDimS ) * ( yTop + static_cast< proshade_signed > ( yDimS ) * xBottom );
1293  c010.at(0) = static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample );
1294  c010.at(1) = static_cast<proshade_double> ( yTop ) * static_cast<proshade_double> ( oldYSample );
1295  c010.at(2) = static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample );
1296  c010.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1297 
1298  oldMapIndex = zTop + static_cast< proshade_signed > ( zDimS ) * ( yTop + static_cast< proshade_signed > ( yDimS ) * xBottom );
1299  c011.at(0) = static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample );
1300  c011.at(1) = static_cast<proshade_double> ( yTop ) * static_cast<proshade_double> ( oldYSample );
1301  c011.at(2) = static_cast<proshade_double> ( zTop ) * static_cast<proshade_double> ( oldZSample );
1302  c011.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1303 
1304  oldMapIndex = zBottom + static_cast< proshade_signed > ( zDimS ) * ( yBottom + static_cast< proshade_signed > ( yDimS ) * xTop );
1305  c100.at(0) = static_cast<proshade_double> ( xTop ) * static_cast<proshade_double> ( oldXSample );
1306  c100.at(1) = static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample );
1307  c100.at(2) = static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample );
1308  c100.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1309 
1310  oldMapIndex = zTop + static_cast< proshade_signed > ( zDimS ) * ( yBottom + static_cast< proshade_signed > ( yDimS ) * xTop );
1311  c101.at(0) = static_cast<proshade_double> ( xTop ) * static_cast<proshade_double> ( oldXSample );
1312  c101.at(1) = static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample );
1313  c101.at(2) = static_cast<proshade_double> ( zTop ) * static_cast<proshade_double> ( oldZSample );
1314  c101.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1315 
1316  oldMapIndex = zBottom + static_cast< proshade_signed > ( zDimS ) * ( yTop + static_cast< proshade_signed > ( yDimS ) * xTop );
1317  c110.at(0) = static_cast<proshade_double> ( xTop ) * static_cast<proshade_double> ( oldXSample );
1318  c110.at(1) = static_cast<proshade_double> ( yTop ) * static_cast<proshade_double> ( oldYSample );
1319  c110.at(2) = static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample );
1320  c110.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1321 
1322  oldMapIndex = zTop + static_cast< proshade_signed > ( zDimS ) * ( yTop + static_cast< proshade_signed > ( yDimS ) * xTop );
1323  c111.at(0) = static_cast<proshade_double> ( xTop ) * static_cast<proshade_double> ( oldXSample );
1324  c111.at(1) = static_cast<proshade_double> ( yTop ) * static_cast<proshade_double> ( oldYSample );
1325  c111.at(2) = static_cast<proshade_double> ( zTop ) * static_cast<proshade_double> ( oldZSample );
1326  c111.at(3) = static_cast<proshade_double> ( map[oldMapIndex] );
1327 
1328  //==================================== Interpolate to the new grid along X
1329  xRelative = ( ( static_cast<proshade_double> ( xIt ) * static_cast<proshade_double> ( newXSample ) ) - ( static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample ) ) ) / ( ( static_cast<proshade_double> ( xTop ) * static_cast<proshade_double> ( oldXSample ) ) - ( static_cast<proshade_double> ( xBottom ) * static_cast<proshade_double> ( oldXSample ) ) );
1330 
1331  //==================================== Interpolate for the less less point
1332  c00.at(0) = ( static_cast< proshade_double > ( newXSample ) * xRelative ) + c000.at(0);
1333  c00.at(1) = c000.at(1);
1334  c00.at(2) = c000.at(2);
1335  c00.at(3) = ( c000.at(3) * ( 1.0 - xRelative ) ) + ( c100.at(3) * xRelative );
1336 
1337  //==================================== Interpolate for the less more point
1338  c01.at(0) = ( static_cast< proshade_double > ( newXSample ) * xRelative ) + c001.at(0);
1339  c01.at(1) = c001.at(1);
1340  c01.at(2) = c001.at(2);
1341  c01.at(3) = ( c001.at(3) * ( 1.0 - xRelative ) ) + ( c101.at(3) * xRelative );
1342 
1343  //==================================== Interpolate for the more less point
1344  c10.at(0) = ( static_cast< proshade_double > ( newXSample ) * xRelative ) + c010.at(0);
1345  c10.at(1) = c010.at(1);
1346  c10.at(2) = c010.at(2);
1347  c10.at(3) = ( c010.at(3) * ( 1.0 - xRelative ) ) + ( c110.at(3) * xRelative );
1348 
1349  //==================================== Interpolate for the more more point
1350  c11.at(0) = ( static_cast< proshade_double > ( newXSample ) * xRelative ) + c011.at(0);
1351  c11.at(1) = c011.at(1);
1352  c11.at(2) = c011.at(2);
1353  c11.at(3) = ( c011.at(3) * ( 1.0 - xRelative ) ) + ( c111.at(3) * xRelative );
1354 
1355  //==================================== Interpolate to the new grid along Y
1356  yRelative = ( ( static_cast<proshade_double> ( yIt ) * static_cast<proshade_double> ( newYSample ) ) - ( static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample ) ) ) / ( ( static_cast<proshade_double> ( yTop ) * static_cast<proshade_double> ( oldYSample ) ) - ( static_cast<proshade_double> ( yBottom ) * static_cast<proshade_double> ( oldYSample ) ) );
1357 
1358  //==================================== Interpolate for the less point
1359  c0.at(0) = c00.at(0);
1360  c0.at(1) = ( static_cast< proshade_double > ( newYSample ) * yRelative ) + c00.at(1);
1361  c0.at(2) = c00.at(2);
1362  c0.at(3) = ( c00.at(3) * ( 1.0 - yRelative ) ) + ( c10.at(3) * yRelative );
1363 
1364  //==================================== Interpolate for the more point
1365  c1.at(0) = c01.at(0);
1366  c1.at(1) = ( static_cast< proshade_double > ( newYSample ) * yRelative ) + c01.at(1);
1367  c1.at(2) = c01.at(2);
1368  c1.at(3) = ( c01.at(3) * ( 1.0 - yRelative ) ) + ( c11.at(3) * yRelative );
1369 
1370  //==================================== Interpolate to the new grid along Z
1371  zRelative = ( ( static_cast<proshade_double> ( zIt ) * static_cast< proshade_double > ( newZSample ) ) - ( static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample ) ) ) / static_cast< proshade_double > ( ( static_cast<proshade_double> ( zTop ) * static_cast<proshade_double> ( oldZSample ) ) - ( static_cast<proshade_double> ( zBottom ) * static_cast<proshade_double> ( oldZSample ) ) );
1372  newMap[newMapIndex] = ( c0.at(3) * ( 1.0 - zRelative ) ) + ( c1.at(3) * zRelative );
1373  }
1374  }
1375  }
1376 
1377  //================================================ Delete old map and allocate new memory
1378  delete[] map;
1379  map = new proshade_double [newXDim * newYDim * newZDim];
1380 
1381  //================================================ Copy map
1382  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( newXDim * newYDim * newZDim ); iter++ )
1383  {
1384  map[iter] = newMap[iter];
1385  }
1386 
1387  //================================================ Release memory
1388  delete[] newMap;
1389 
1390  //================================================ Define change in indices and return it
1391  corrs[0] = static_cast< proshade_single > ( newXDim - xDim );
1392  corrs[1] = static_cast< proshade_single > ( newYDim - yDim );
1393  corrs[2] = static_cast< proshade_single > ( newZDim - zDim );
1394  corrs[3] = static_cast< proshade_single > ( newXDim ) * static_cast< proshade_single > ( newXSample );
1395  corrs[4] = static_cast< proshade_single > ( newYDim ) * static_cast< proshade_single > ( newYSample );
1396  corrs[5] = static_cast< proshade_single > ( newZDim ) * static_cast< proshade_single > ( newZSample );
1397 
1398  //======================================== Done
1399  return ;
1400 
1401 }
1402 
1427 void ProSHADE_internal_mapManip::reSampleMapToResolutionFourier ( proshade_double*& map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single*& corrs )
1428 {
1429  //================================================ Sanity check - the resolution needs to be set
1430  if ( resolution <= 0.0f )
1431  {
1432  throw ProSHADE_exception ( "Requested resolution not set for map re-sampling.", "EM00015", __FILE__, __LINE__, __func__, "There is no resolution value set, but map re-sampling to\n : this unset resolution value is required. This error\n : occurs when a task with no resolution requirement is\n : requested on a map data and the map resolution change is\n : set to \'on\'. Either supply a resolution value, or do not\n : re-sample the map." );
1433  }
1434 
1435  //================================================ Initialise variables
1436  proshade_unsign newXDim = static_cast<proshade_unsign> ( ProSHADE_internal_mapManip::myRound ( xAngs / ( resolution / 2.0f ) ) );
1437  proshade_unsign newYDim = static_cast<proshade_unsign> ( ProSHADE_internal_mapManip::myRound ( yAngs / ( resolution / 2.0f ) ) );
1438  proshade_unsign newZDim = static_cast<proshade_unsign> ( ProSHADE_internal_mapManip::myRound ( zAngs / ( resolution / 2.0f ) ) );
1439 
1440  if ( newXDim % 2 != 0 ) { newXDim += 1; }
1441  if ( newYDim % 2 != 0 ) { newYDim += 1; }
1442  if ( newZDim % 2 != 0 ) { newZDim += 1; }
1443 
1444  proshade_signed preXChange, preYChange, preZChange;
1445  if ( ( xDimS % 2 ) == 0 ) { preXChange = static_cast< proshade_signed > ( std::ceil ( ( static_cast<proshade_signed> ( xDimS ) - static_cast<proshade_signed> ( newXDim ) ) / 2 ) ); }
1446  else { preXChange = static_cast< proshade_signed > ( std::floor ( ( static_cast<proshade_signed> ( xDimS ) - static_cast<proshade_signed> ( newXDim ) ) / 2 ) ); }
1447  if ( ( yDimS % 2 ) == 0 ) { preYChange = static_cast< proshade_signed > ( std::ceil ( ( static_cast<proshade_signed> ( yDimS ) - static_cast<proshade_signed> ( newYDim ) ) / 2 ) ); }
1448  else { preYChange = static_cast< proshade_signed > ( std::floor ( ( static_cast<proshade_signed> ( yDimS ) - static_cast<proshade_signed> ( newYDim ) ) / 2 ) ); }
1449  if ( ( zDimS % 2 ) == 0 ) { preZChange = static_cast< proshade_signed > ( std::ceil ( ( static_cast<proshade_signed> ( zDimS ) - static_cast<proshade_signed> ( newZDim ) ) / 2 ) ); }
1450  else { preZChange = static_cast< proshade_signed > ( std::floor ( ( static_cast<proshade_signed> ( zDimS ) - static_cast<proshade_signed> ( newZDim ) ) / 2 ) ); }
1451 
1452  proshade_signed postXChange = static_cast<proshade_signed> ( xDimS ) - ( preXChange + static_cast<proshade_signed> ( newXDim ) );
1453  proshade_signed postYChange = static_cast<proshade_signed> ( yDimS ) - ( preYChange + static_cast<proshade_signed> ( newYDim ) );
1454  proshade_signed postZChange = static_cast<proshade_signed> ( zDimS ) - ( preZChange + static_cast<proshade_signed> ( newZDim ) );
1455 
1456  proshade_unsign origSizeArr = 0, newSizeArr = 0;
1457  proshade_double normFactor = static_cast<proshade_double> ( xDimS * yDimS * zDimS );
1458 
1459  //================================================ Manage memory
1460  fftw_complex *origMap, *fCoeffs, *newFCoeffs, *newMap;
1461  fftw_plan planForwardFourier, planBackwardRescaledFourier;
1462  allocateResolutionFourierMemory ( origMap, fCoeffs, newFCoeffs, newMap, planForwardFourier, planBackwardRescaledFourier,
1463  xDimS, yDimS, zDimS, newXDim, newYDim, newZDim );
1464 
1465  //================================================ Fill maps with data and zeroes
1466  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( xDimS * yDimS * zDimS ); iter++ ) { origMap[iter][0] = map[iter]; origMap[iter][1] = 0.0; }
1467  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( newXDim * newYDim * newZDim ); iter++ ) { newFCoeffs[iter][0] = 0.0; newFCoeffs[iter][1] = 0.0; }
1468 
1469  //================================================ Get the Fourier coeffs
1470  fftw_execute ( planForwardFourier );
1471 
1472  //================================================ Change the order of Fourier coefficients
1473  changeFourierOrder ( fCoeffs, static_cast< proshade_signed > ( xDimS ), static_cast< proshade_signed > ( yDimS ), static_cast< proshade_signed > ( zDimS ), true );
1474 
1475  //================================================ Re-sample the coefficients by removing high frequencies or adding these with 0 values
1476  for ( proshade_unsign xIt = 0; xIt < newXDim; xIt++ )
1477  {
1478  for ( proshade_unsign yIt = 0; yIt < newYDim; yIt++ )
1479  {
1480  for ( proshade_unsign zIt = 0; zIt < newZDim; zIt++ )
1481  {
1482  //==================================== Find the array positions
1483  origSizeArr = ( ( zIt + static_cast< proshade_unsign > ( preZChange ) ) + zDimS *
1484  ( ( yIt + static_cast< proshade_unsign > ( preYChange ) ) + yDimS *
1485  ( xIt + static_cast< proshade_unsign > ( preXChange ) ) ) );
1486  newSizeArr = zIt + newZDim * ( yIt + newYDim * xIt );
1487 
1488  //==================================== If original coefficient for this new coefficient position exists, copy
1489  if ( ( ( -1 < static_cast< proshade_signed > ( xIt ) + preXChange ) && ( -1 < static_cast<proshade_signed> ( yIt ) + preYChange ) && ( -1 < static_cast<proshade_signed> ( zIt ) + preZChange ) ) &&
1490  ( ( xIt < newXDim + static_cast<proshade_unsign> ( postXChange ) ) && ( yIt < newYDim + static_cast<proshade_unsign> ( postYChange ) ) && ( zIt < newZDim + static_cast<proshade_unsign> ( postZChange ) ) ) )
1491  {
1492  //================================ Copy the Fourier coeff
1493  newFCoeffs[newSizeArr][0] = fCoeffs[origSizeArr][0] / normFactor;
1494  newFCoeffs[newSizeArr][1] = fCoeffs[origSizeArr][1] / normFactor;
1495  }
1496  }
1497  }
1498  }
1499 
1500  //================================================ Change the order of the re-sampled Fourier coefficients
1501  changeFourierOrder ( newFCoeffs, static_cast< proshade_signed > ( newXDim ), static_cast< proshade_signed > ( newYDim ), static_cast< proshade_signed > ( newZDim ), false );
1502 
1503  //================================================ Get the new map from the re-sized Fourier coefficients
1504  fftw_execute ( planBackwardRescaledFourier );
1505 
1506  //================================================ Delete the old map and create a new, re-sized one. Then copy the new map values into this new map memory.
1507  delete map;
1508  map = new proshade_double [newXDim * newYDim * newZDim];
1509  ProSHADE_internal_misc::checkMemoryAllocation ( map, __FILE__, __LINE__, __func__ );
1510  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( newXDim * newYDim * newZDim ); iter++ ) { map[iter] = newMap[iter][0]; }
1511 
1512  //================================================ Release memory
1513  releaseResolutionFourierMemory ( origMap, fCoeffs, newFCoeffs, newMap, planForwardFourier, planBackwardRescaledFourier );
1514 
1515  //================================================ Define change in indices and return it
1516  corrs[0] = static_cast< proshade_single > ( newXDim ) - static_cast< proshade_single > ( xDimS );
1517  corrs[1] = static_cast< proshade_single > ( newYDim ) - static_cast< proshade_single > ( yDimS );
1518  corrs[2] = static_cast< proshade_single > ( newZDim ) - static_cast< proshade_single > ( zDimS );
1519  corrs[3] = static_cast< proshade_single > ( newXDim ) * static_cast< proshade_single > ( resolution / 2.0f );
1520  corrs[4] = static_cast< proshade_single > ( newYDim ) * static_cast< proshade_single > ( resolution / 2.0f );
1521  corrs[5] = static_cast< proshade_single > ( newZDim ) * static_cast< proshade_single > ( resolution / 2.0f );
1522 
1523  //======================================== Done
1524  return ;
1525 
1526 }
1527 
1546 void ProSHADE_internal_mapManip::allocateResolutionFourierMemory ( fftw_complex*& origMap, fftw_complex*& fCoeffs, fftw_complex*& newFCoeffs, fftw_complex*& newMap, fftw_plan& planForwardFourier, fftw_plan& planBackwardRescaledFourier, proshade_unsign xDimOld, proshade_unsign yDimOld, proshade_unsign zDimOld, proshade_unsign xDimNew, proshade_unsign yDimNew, proshade_unsign zDimNew )
1547 {
1548  //================================================ Initialise memory
1549  origMap = new fftw_complex [xDimOld * yDimOld * zDimOld];
1550  fCoeffs = new fftw_complex [xDimOld * yDimOld * zDimOld];
1551  newFCoeffs = new fftw_complex [xDimNew * yDimNew * zDimNew];
1552  newMap = new fftw_complex [xDimNew * yDimNew * zDimNew];
1553 
1554  //================================================ Check memory allocation
1555  ProSHADE_internal_misc::checkMemoryAllocation ( origMap, __FILE__, __LINE__, __func__ );
1556  ProSHADE_internal_misc::checkMemoryAllocation ( fCoeffs, __FILE__, __LINE__, __func__ );
1557  ProSHADE_internal_misc::checkMemoryAllocation ( newFCoeffs, __FILE__, __LINE__, __func__ );
1558  ProSHADE_internal_misc::checkMemoryAllocation ( newMap, __FILE__, __LINE__, __func__ );
1559 
1560  //================================================ Create plans
1561  planForwardFourier = fftw_plan_dft_3d ( static_cast< int > ( xDimOld ), static_cast< int > ( yDimOld ), static_cast< int > ( zDimOld ), origMap, fCoeffs, FFTW_FORWARD, FFTW_ESTIMATE );
1562  planBackwardRescaledFourier = fftw_plan_dft_3d ( static_cast< int > ( xDimNew ), static_cast< int > ( yDimNew ), static_cast< int > ( zDimNew ), newFCoeffs, newMap, FFTW_BACKWARD, FFTW_ESTIMATE );
1563 
1564  //================================================ Done
1565  return ;
1566 
1567 }
1568 
1580 void ProSHADE_internal_mapManip::releaseResolutionFourierMemory ( fftw_complex*& origMap, fftw_complex*& fCoeffs, fftw_complex*& newFCoeffs, fftw_complex*& newMap, fftw_plan& planForwardFourier, fftw_plan& planBackwardRescaledFourier )
1581 {
1582  //================================================ Delete the FFTW plans
1583  fftw_destroy_plan ( planForwardFourier );
1584  fftw_destroy_plan ( planBackwardRescaledFourier );
1585 
1586  //================================================ Delete the complex arrays
1587  delete[] origMap;
1588  delete[] fCoeffs;
1589  delete[] newFCoeffs;
1590  delete[] newMap;
1591 
1592  //================================================ Done
1593  return ;
1594 
1595 }
1596 
1609 void ProSHADE_internal_mapManip::changeFourierOrder ( fftw_complex*& fCoeffs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, bool negativeFirst )
1610 {
1611  //================================================ Initialise local variables
1612  proshade_signed h = 0, k = 0, l = 0, origSizeArr = 0, newSizeArr = 0;
1613  proshade_signed xSeq1FreqStart, ySeq1FreqStart, zSeq1FreqStart, xSeq2FreqStart, ySeq2FreqStart, zSeq2FreqStart;
1614 
1615  //================================================ Find the positive and negative indices cot-offs
1616  if ( negativeFirst )
1617  {
1618  if ( ( xDim % 2 ) == 0 ) { xSeq1FreqStart = xDim / 2; xSeq2FreqStart = xDim / 2; } else { xSeq1FreqStart = (xDim / 2) + 1; xSeq2FreqStart = xDim / 2; }
1619  if ( ( yDim % 2 ) == 0 ) { ySeq1FreqStart = yDim / 2; ySeq2FreqStart = yDim / 2; } else { ySeq1FreqStart = (yDim / 2) + 1; ySeq2FreqStart = yDim / 2; }
1620  if ( ( zDim % 2 ) == 0 ) { zSeq1FreqStart = zDim / 2; zSeq2FreqStart = zDim / 2; } else { zSeq1FreqStart = (zDim / 2) + 1; zSeq2FreqStart = zDim / 2; }
1621  }
1622  else
1623  {
1624  if ( ( xDim % 2 ) == 0 ) { xSeq1FreqStart = xDim / 2; xSeq2FreqStart = xDim / 2; } else { xSeq1FreqStart = (xDim / 2); xSeq2FreqStart = xDim / 2 + 1; }
1625  if ( ( yDim % 2 ) == 0 ) { ySeq1FreqStart = yDim / 2; ySeq2FreqStart = yDim / 2; } else { ySeq1FreqStart = (yDim / 2); ySeq2FreqStart = yDim / 2 + 1; }
1626  if ( ( zDim % 2 ) == 0 ) { zSeq1FreqStart = zDim / 2; zSeq2FreqStart = zDim / 2; } else { zSeq1FreqStart = (zDim / 2); zSeq2FreqStart = zDim / 2 + 1; }
1627  }
1628 
1629  //================================================ Allocate helper array memory
1630  fftw_complex *hlpFCoeffs = new fftw_complex [xDim * yDim * zDim];
1631  ProSHADE_internal_misc::checkMemoryAllocation ( hlpFCoeffs, __FILE__, __LINE__, __func__ );
1632 
1633  //================================================ Change the coefficients order
1634  for ( proshade_signed xIt = 0; xIt < xDim; xIt++ )
1635  {
1636  //============================================ Find x frequency
1637  if ( xIt < xSeq1FreqStart ) { h = xIt + xSeq2FreqStart; } else { h = xIt - xSeq1FreqStart; }
1638  for ( proshade_signed yIt = 0; yIt < yDim; yIt++ )
1639  {
1640  //======================================== Find y frequency
1641  if ( yIt < ySeq1FreqStart ) { k = yIt + ySeq2FreqStart; } else { k = yIt - ySeq1FreqStart; }
1642 
1643  for ( proshade_signed zIt = 0; zIt < zDim; zIt++ )
1644  {
1645  //==================================== Find z frequency
1646  if ( zIt < zSeq1FreqStart ) { l = zIt + zSeq2FreqStart; } else { l = zIt - zSeq1FreqStart; }
1647 
1648  //==================================== Find array positions
1649  newSizeArr = l + zDim * ( k + yDim * h );
1650  origSizeArr = zIt + zDim * ( yIt + yDim * xIt );
1651 
1652  //==================================== Copy vals
1653  hlpFCoeffs[newSizeArr][0] = fCoeffs[origSizeArr][0];
1654  hlpFCoeffs[newSizeArr][1] = fCoeffs[origSizeArr][1];
1655  }
1656  }
1657  }
1658 
1659  //================================================ Copy the helper array to the input Fourier coefficients array
1660  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( xDim * yDim * zDim ); iter++ ) { fCoeffs[iter][0] = hlpFCoeffs[iter][0]; fCoeffs[iter][1] = hlpFCoeffs[iter][1]; }
1661 
1662  //================================================ Release helper array memory
1663  delete[] hlpFCoeffs;
1664 
1665  //================================================ Done
1666  return ;
1667 
1668 }
1669 
1681 void ProSHADE_internal_mapManip::removeMapPhase ( fftw_complex*& mapCoeffs, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim )
1682 {
1683  //================================================ Set local variables
1684  proshade_double real, imag, mag, phase;
1685  proshade_unsign arrayPos = 0;
1686  proshade_double normFactor = static_cast<proshade_double> ( xDim * yDim * zDim );
1687 
1688  //================================================ Iterate through the map
1689  for ( proshade_unsign uIt = 0; uIt < xDim; uIt++ )
1690  {
1691  for ( proshade_unsign vIt = 0; vIt < yDim; vIt++ )
1692  {
1693  for ( proshade_unsign wIt = 0; wIt < zDim; wIt++ )
1694  {
1695  //==================================== Var init
1696  arrayPos = wIt + zDim * ( vIt + yDim * uIt );
1697  real = mapCoeffs[arrayPos][0];
1698  imag = mapCoeffs[arrayPos][1];
1699 
1700  //==================================== Get magnitude and phase with mask parameters
1701  mag = std::sqrt ( (real*real) + (imag*imag) );;
1702  phase = 0.0; // This would be std::atan2 ( imag, real ); - but here we remove the phase.
1703 
1704  //==================================== Save the phaseless data
1705  mapCoeffs[arrayPos][0] = ( mag * cos(phase) ) / normFactor;
1706  mapCoeffs[arrayPos][1] = ( mag * sin(phase) ) / normFactor;
1707  }
1708  }
1709  }
1710 
1711  //================================================ Done
1712  return ;
1713 
1714 }
1715 
1730 void ProSHADE_internal_mapManip::getFakeHalfMap ( proshade_double*& map, proshade_double*& fakeHalfMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_signed fakeMapKernel )
1731 {
1732  //================================================ Set local variables
1733  proshade_signed xDim = static_cast< proshade_signed > ( xDimS );
1734  proshade_signed yDim = static_cast< proshade_signed > ( yDimS );
1735  proshade_signed zDim = static_cast< proshade_signed > ( zDimS );
1736  proshade_signed currentPos, neighArrPos, neighXPos, neighYPos, neighZPos;
1737  proshade_double neighSum;
1738  proshade_double neighCount = pow ( ( ( fakeMapKernel * 2 ) + 1 ), 3.0 ) - 1.0;
1739 
1740  //================================================ Blur the coeffs
1741  for ( proshade_signed uIt = 0; uIt < xDim; uIt++ )
1742  {
1743  for ( proshade_signed vIt = 0; vIt < yDim; vIt++ )
1744  {
1745  for ( proshade_signed wIt = 0; wIt < zDim; wIt++ )
1746  {
1747  //==================================== Var init
1748  currentPos = wIt + zDim * ( vIt + yDim * uIt );
1749  neighSum = 0.0;
1750 
1751  //==================================== Average neighbours
1752  for ( proshade_signed xCh = -fakeMapKernel; xCh <= +fakeMapKernel; xCh++ )
1753  {
1754  for ( proshade_signed yCh = -fakeMapKernel; yCh <= +fakeMapKernel; yCh++ )
1755  {
1756  for ( proshade_signed zCh = -fakeMapKernel; zCh <= +fakeMapKernel; zCh++ )
1757  {
1758  if ( ( xCh == 0 ) && ( yCh == 0 ) && ( zCh == 0 ) ) { continue; }
1759 
1760  //======================== Find the nieghbour peak indices (with periodicity)
1761  neighXPos = uIt + xCh; if ( neighXPos >= xDim ) { neighXPos -= xDim; }; if ( neighXPos < 0 ) { neighXPos += xDim; }
1762  neighYPos = vIt + yCh; if ( neighYPos >= yDim ) { neighYPos -= yDim; }; if ( neighYPos < 0 ) { neighYPos += yDim; }
1763  neighZPos = wIt + zCh; if ( neighZPos >= zDim ) { neighZPos -= zDim; }; if ( neighZPos < 0 ) { neighZPos += zDim; }
1764  neighArrPos = neighZPos + zDim * ( neighYPos + yDim * neighXPos );
1765 
1766  //======================== Add to average
1767  neighSum += map[neighArrPos];
1768  }
1769  }
1770  }
1771 
1772  //==================================== Save the average to "fake" half-map
1773  fakeHalfMap[currentPos] = neighSum / neighCount;
1774  }
1775  }
1776  }
1777 
1778  //================================================ Done
1779  return ;
1780 
1781 }
1782 
1795 void ProSHADE_internal_mapManip::getCorrelationMapMask ( proshade_double*& map, proshade_double*& fakeHalfMap, proshade_double*& correlationMask, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_signed corrMaskKernel )
1796 {
1797  //================================================ Set local variables
1798  proshade_signed xDim = static_cast< proshade_signed > ( xDimS ), yDim = static_cast< proshade_signed > ( yDimS ), zDim = static_cast< proshade_signed > ( zDimS ), currentPos, neighArrPos, neighXPos, neighYPos, neighZPos, corrIter;
1799  proshade_unsign noCorrVals = static_cast<proshade_unsign> ( pow ( ( ( corrMaskKernel * 2 ) + 1 ), 3 ) );
1800 
1801  //================================================ Alocate memory
1802  proshade_double *origMap = new proshade_double [noCorrVals];
1803  proshade_double *fakeHM = new proshade_double [noCorrVals];
1804 
1805  //================================================ Check memory allocation
1806  ProSHADE_internal_misc::checkMemoryAllocation ( origMap, __FILE__, __LINE__, __func__ );
1807  ProSHADE_internal_misc::checkMemoryAllocation ( fakeHM, __FILE__, __LINE__, __func__ );
1808 
1809  //================================================ Blur the coeffs
1810  for ( proshade_signed uIt = 0; uIt < xDim; uIt++ )
1811  {
1812  for ( proshade_signed vIt = 0; vIt < yDim; vIt++ )
1813  {
1814  for ( proshade_signed wIt = 0; wIt < zDim; wIt++ )
1815  {
1816  //==================================== Var init
1817  currentPos = wIt + zDim * ( vIt + yDim * uIt );
1818  corrIter = 0;
1819 
1820  //==================================== Average neighbours
1821  for ( proshade_signed xCh = -corrMaskKernel; xCh <= +corrMaskKernel; xCh++ )
1822  {
1823  for ( proshade_signed yCh = -corrMaskKernel; yCh <= +corrMaskKernel; yCh++ )
1824  {
1825  for ( proshade_signed zCh = -corrMaskKernel; zCh <= +corrMaskKernel; zCh++ )
1826  {
1827  //======================== Find the nieghbour peak indices (with periodicity)
1828  neighXPos = uIt + xCh; if ( neighXPos >= xDim ) { neighXPos -= xDim; }; if ( neighXPos < 0 ) { neighXPos += xDim; }
1829  neighYPos = vIt + yCh; if ( neighYPos >= yDim ) { neighYPos -= yDim; }; if ( neighYPos < 0 ) { neighYPos += yDim; }
1830  neighZPos = wIt + zCh; if ( neighZPos >= zDim ) { neighZPos -= zDim; }; if ( neighZPos < 0 ) { neighZPos += zDim; }
1831  neighArrPos = neighZPos + zDim * ( neighYPos + yDim * neighXPos );
1832 
1833  //======================== Add to correct arrays
1834  origMap[corrIter] = map[neighArrPos];
1835  fakeHM[corrIter] = fakeHalfMap[neighArrPos];
1836  corrIter += 1;
1837  }
1838  }
1839  }
1840 
1841  //==================================== Save the correlation comparison result
1842  correlationMask[currentPos] = ProSHADE_internal_maths::pearsonCorrCoeff ( origMap, fakeHM, noCorrVals );
1843  }
1844  }
1845  }
1846 
1847  //================================================ Done
1848  return ;
1849 
1850 }
1851 
1866 proshade_single ProSHADE_internal_mapManip::getIndicesFromAngstroms ( proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single dist )
1867 {
1868  //================================================ Compute
1869  proshade_single ret = static_cast< proshade_single > ( ProSHADE_internal_mapManip::myRound ( std::max ( dist / ( xAngs / static_cast<proshade_single> ( xDim ) ),
1870  std::max ( dist / ( yAngs / static_cast<proshade_single> ( yDim ) ),
1871  dist / ( zAngs / static_cast<proshade_single> ( zDim ) ) ) ) ) );
1872 
1873  //================================================ Done
1874  return ( ret );
1875 
1876 }
1877 
1889 void ProSHADE_internal_mapManip::connectMaskBlobs ( proshade_double*& mask, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single maskThres )
1890 {
1891  //================================================ Initialise variables
1892  proshade_double* hlpMap = new proshade_double[xDim * yDim * zDim];
1893  proshade_signed addSurroundingPoints = static_cast< proshade_signed > ( std::max ( 3L, static_cast<proshade_signed> ( std::ceil ( getIndicesFromAngstroms( static_cast< proshade_unsign > ( xDim ), static_cast< proshade_unsign > ( yDim ), static_cast< proshade_unsign > ( zDim ), xAngs, yAngs, zAngs, static_cast< proshade_single > ( std::max( xAngs, std::max( yAngs, zAngs ) ) * 0.1f ) ) ) ) ) );
1894  proshade_signed currPos, neighXPos, neighYPos, neighZPos, neighArrPos;
1895 
1896  //================================================ Check memory allocation
1897  ProSHADE_internal_misc::checkMemoryAllocation ( hlpMap, __FILE__, __LINE__, __func__ );
1898 
1899  //================================================ Copy the mask map
1900  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( xDim * yDim * zDim ); iter++ ) { hlpMap[iter] = mask[iter]; }
1901 
1902  //================================================ Repeat as many times as needed
1903  for ( proshade_signed it = 0; it < addSurroundingPoints; it++ )
1904  {
1905  //============================================ For each x, y and z
1906  for ( proshade_signed xIt = 0; xIt < xDim; xIt++ )
1907  {
1908  for ( proshade_signed yIt = 0; yIt < yDim; yIt++ )
1909  {
1910  for ( proshade_signed zIt = 0; zIt < zDim; zIt++ )
1911  {
1912  //================================ Current position
1913  currPos = zIt + zDim * ( yIt + yDim * xIt );
1914 
1915  //================================ If zero, ignore
1916  if ( hlpMap[currPos] < static_cast< proshade_double > ( maskThres ) ) { continue; }
1917 
1918  //================================ Check neighbours
1919  for ( proshade_signed xCh = -1; xCh <= +1; xCh++ )
1920  {
1921  for ( proshade_signed yCh = -1; yCh <= +1; yCh++ )
1922  {
1923  for ( proshade_signed zCh = -1; zCh <= +1; zCh++ )
1924  {
1925  if ( ( xCh == 0 ) && ( yCh == 0 ) && ( zCh == 0 ) ) { continue; }
1926 
1927  //==================== Find the nieghbour indices (without periodicity)
1928  neighXPos = xIt + xCh; if ( neighXPos < 0 ) { continue; } if ( neighXPos >= xDim ) { continue; }
1929  neighYPos = yIt + yCh; if ( neighYPos < 0 ) { continue; } if ( neighYPos >= yDim ) { continue; }
1930  neighZPos = zIt + zCh; if ( neighZPos < 0 ) { continue; } if ( neighZPos >= zDim ) { continue; }
1931  neighArrPos = neighZPos + zDim * ( neighYPos + yDim * neighXPos );
1932 
1933  //==================== Add to mask if this point is below it (as it is a neighbour to a point which is part of the mask)
1934  if ( hlpMap[neighArrPos] < static_cast< proshade_double > ( maskThres ) ) { mask[neighArrPos] = static_cast< proshade_double > ( maskThres ); }
1935  }
1936  }
1937  }
1938  }
1939  }
1940  }
1941 
1942  //============================================ Now copy the updated mask to the temporary helper, unless last iteration
1943  for ( proshade_unsign iter = 0; iter < static_cast<proshade_unsign> ( xDim * yDim * zDim ); iter++ ) { hlpMap[iter] = mask[iter]; }
1944  }
1945 
1946  //================================================ Release memory
1947  delete[] hlpMap;
1948 
1949  //================================================ Done
1950  return ;
1951 
1952 }
1953 
1966 void ProSHADE_internal_mapManip::beautifyBoundaries ( proshade_signed*& bounds, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_signed boundsDiffThres )
1967 {
1968  //================================================ If extra bounds space pushed the bounds over the physical map, freely add up to 10 indices over the current value
1969  while ( bounds[1] >= static_cast<proshade_signed> ( xDim ) ) { xDim += 10; }
1970  while ( bounds[3] >= static_cast<proshade_signed> ( yDim ) ) { yDim += 10; }
1971  while ( bounds[5] >= static_cast<proshade_signed> ( zDim ) ) { zDim += 10; }
1972 
1973  //================================================ Find if better bouds exist in terms of prime numbers
1974  proshade_signed addToX = betterClosePrimeFactors ( bounds[1] - bounds[0] + 1, static_cast< proshade_signed > ( xDim ) );
1975  proshade_signed addToY = betterClosePrimeFactors ( bounds[3] - bounds[2] + 1, static_cast< proshade_signed > ( yDim ) );
1976  proshade_signed addToZ = betterClosePrimeFactors ( bounds[5] - bounds[4] + 1, static_cast< proshade_signed > ( zDim ) );
1977 
1978  //================================================ Figure if similar sizes should not be forced to be the same
1979  proshade_signed XtoY = std::abs ( addToX - addToY );
1980  proshade_signed XtoZ = std::abs ( addToX - addToZ );
1981  proshade_signed YtoZ = std::abs ( addToY - addToZ );
1982 
1983  if ( ( ( XtoY < boundsDiffThres ) && ( XtoZ < boundsDiffThres ) ) ||
1984  ( ( XtoY < boundsDiffThres ) && ( YtoZ < boundsDiffThres ) ) ||
1985  ( ( XtoZ < boundsDiffThres ) && ( YtoZ < boundsDiffThres ) ) )
1986  {
1987  //============================================ Dealing with chain ( a <= b <= c type ) where at least two dista are smaller than threshold
1988  proshade_signed maxSize = std::max ( addToX, std::max ( addToY, addToZ ) );
1989  addToX = maxSize;
1990  addToY = maxSize;
1991  addToZ = maxSize;
1992  }
1993  else
1994  {
1995  //============================================ Only two may be similar enough
1996  if ( XtoY <= boundsDiffThres )
1997  {
1998  proshade_signed maxSize = std::max ( addToX, addToY );
1999  addToX = maxSize;
2000  addToY = maxSize;
2001  }
2002  if ( XtoZ <= boundsDiffThres )
2003  {
2004  proshade_signed maxSize = std::max ( addToX, addToZ );
2005  addToX = maxSize;
2006  addToZ = maxSize;
2007  }
2008  if ( YtoZ <= boundsDiffThres )
2009  {
2010  proshade_signed maxSize = std::max ( addToY, addToZ );
2011  addToY = maxSize;
2012  addToZ = maxSize;
2013  }
2014  }
2015 
2016  //================================================ Add the extra space appropriately
2017  distributeSpaceToBoundaries ( bounds[0], bounds[1], ( bounds[1] - bounds[0] + 1 ), addToX );
2018  distributeSpaceToBoundaries ( bounds[2], bounds[3], ( bounds[3] - bounds[2] + 1 ), addToY );
2019  distributeSpaceToBoundaries ( bounds[4], bounds[5], ( bounds[5] - bounds[4] + 1 ), addToZ );
2020 
2021  //================================================ Done
2022  return ;
2023 
2024 }
2025 
2036 proshade_signed ProSHADE_internal_mapManip::betterClosePrimeFactors ( proshade_signed fromRange, proshade_signed toRange )
2037 {
2038  //================================================ Initialise variables
2039  proshade_signed ret = fromRange;
2040  std::vector < proshade_signed > posibles, hlp;
2041  proshade_signed sum;
2042 
2043  //================================================ Find the sums of prime factors for each number in the whole range
2044  for ( proshade_signed iter = fromRange; iter < toRange; iter++ )
2045  {
2046  sum = 0;
2048  for ( proshade_unsign i = 0; i < static_cast<proshade_unsign> ( hlp.size() ); i++ ) { sum += hlp.at(i); }
2049  hlp.clear ( );
2050  ProSHADE_internal_misc::addToSignedVector ( &posibles, sum );
2051  }
2052 
2053  //================================================ Find a better number
2054  for ( proshade_signed iter = fromRange; iter < toRange; iter++ )
2055  {
2056  //============================================ Ignore odd numbers
2057  if ( iter %2 != 0 ) { continue; }
2058 
2059  //============================================ Better number needs to have lower prime factor sum, but also needs not to be too far
2060  if ( posibles.at( static_cast< size_t > ( iter - fromRange ) ) < ( posibles.at( static_cast< size_t > ( ret - fromRange ) ) - ( iter - ret ) ) ) { ret = iter; }
2061  }
2062 
2063  //================================================ In the case of large prime number, just add one for even number
2064  if ( ( ret % 2 != 0 ) && ( ret < ( toRange - 1 ) ) ) { ret += 1; }
2065 
2066  //================================================ Done
2067  return ( ret );
2068 
2069 }
2070 
2082 void ProSHADE_internal_mapManip::distributeSpaceToBoundaries ( proshade_signed& minBound, proshade_signed& maxBound, proshade_signed oldBoundRange, proshade_signed newBoundRange )
2083 {
2084  //================================================ Only bother when sometings is to be added
2085  if ( newBoundRange > oldBoundRange )
2086  {
2087  //============================================ How much are we adding?
2088  proshade_signed distributeThis = newBoundRange - oldBoundRange;
2089 
2090  while ( distributeThis != 0 )
2091  {
2092  minBound -= 1;
2093  distributeThis -= 1;
2094 
2095  if ( distributeThis != 0 )
2096  {
2097  maxBound += 1;
2098  distributeThis -= 1;
2099  }
2100  }
2101  }
2102 
2103  //================================================ Done
2104  return ;
2105 
2106 }
2107 
2132 void ProSHADE_internal_mapManip::copyMapByBounds ( proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo, proshade_signed origXFrom, proshade_signed origYFrom, proshade_signed origZFrom, proshade_unsign yDimIndices, proshade_unsign zDimIndices, proshade_unsign origXDimIndices, proshade_unsign origYDimIndices, proshade_unsign origZDimIndices, proshade_double*& newMap, proshade_double* origMap )
2133 {
2134  //================================================ Initialise variables
2135  proshade_signed newMapIndex, oldMapIndex, oldX, oldY, oldZ, newX, newY, newZ;
2136 
2137  //=============================================== For all values in the new map
2138  for ( proshade_signed xIt = xFrom; xIt <= xTo; xIt++ )
2139  {
2140  //============================================ Index position init
2141  newX = ( xIt - xFrom );
2142  oldX = ( newX + ( xFrom - origXFrom ) );
2143 
2144  for ( proshade_signed yIt = yFrom; yIt <= yTo; yIt++ )
2145  {
2146  //======================================== Index position init
2147  newY = ( yIt - yFrom );
2148  oldY = ( newY + ( yFrom - origYFrom ) );
2149 
2150  for ( proshade_signed zIt = zFrom; zIt <= zTo; zIt++ )
2151  {
2152  //==================================== Index position init
2153  newZ = ( zIt - zFrom );
2154  oldZ = ( newZ + ( zFrom - origZFrom ) );
2155 
2156  //==================================== Index arrays
2157  newMapIndex = newZ + static_cast< proshade_signed > ( zDimIndices ) * ( newY + static_cast< proshade_signed > ( yDimIndices ) * newX );
2158  oldMapIndex = oldZ + static_cast< proshade_signed > ( origZDimIndices ) * ( oldY + static_cast< proshade_signed > ( origYDimIndices ) * oldX );
2159 
2160  //============================ Check if we are adding new point
2161  if ( ( ( oldX < 0 ) || ( oldX >= static_cast< proshade_signed > ( origXDimIndices ) ) ) ||
2162  ( ( oldY < 0 ) || ( oldY >= static_cast< proshade_signed > ( origYDimIndices ) ) ) ||
2163  ( ( oldZ < 0 ) || ( oldZ >= static_cast< proshade_signed > ( origZDimIndices ) ) ) )
2164  {
2165  //================================ Yes, this is a new point, no known value for it
2166  newMap[newMapIndex] = 0.0;
2167  continue;
2168  }
2169 
2170  //==================================== If we got here, this should be within the old map, so just copy value
2171  newMap[newMapIndex] = origMap[oldMapIndex];
2172  }
2173  }
2174  }
2175 
2176  //================================================ Done
2177  return ;
2178 
2179 }
ProSHADE_internal_mapManip::addExtraBoundSpace
void addExtraBoundSpace(proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed *&bounds, proshade_single extraSpace)
This function takes a set of bounds and adds a given number of Angstroms to them.
Definition: ProSHADE_mapManip.cpp:1181
ProSHADE_internal_mapManip::determinePDBRanges
void determinePDBRanges(gemmi::Structure pdbFile, proshade_single *xFrom, proshade_single *xTo, proshade_single *yFrom, proshade_single *yTo, proshade_single *zFrom, proshade_single *zTo, bool firstModel)
Function for finding the PDB file ranges.
Definition: ProSHADE_mapManip.cpp:72
ProSHADE_internal_mapManip::changePDBBFactors
void changePDBBFactors(gemmi::Structure *pdbFile, proshade_double newBFactorValue, bool firstModel)
Function for changing the PDB B-factor values to a specific single value.
Definition: ProSHADE_mapManip.cpp:446
ProSHADE_exception
This class is the representation of ProSHADE exception.
Definition: ProSHADE_exceptions.hpp:37
ProSHADE_internal_mapManip::distributeSpaceToBoundaries
void distributeSpaceToBoundaries(proshade_signed &minBound, proshade_signed &maxBound, proshade_signed oldBoundRange, proshade_signed newBoundRange)
Function for adding space to boundaries within the map confines.
Definition: ProSHADE_mapManip.cpp:2082
ProSHADE_internal_mapManip::getMaskFromBlurr
void getMaskFromBlurr(proshade_double *&blurMap, proshade_double *&outMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single noIQRs)
Function for computing mask from blurred map.
Definition: ProSHADE_mapManip.cpp:1074
ProSHADE_mapManip.hpp
This header file declares the ProSHADE_internal_mapManip namespace, which groups functions for intern...
ProSHADE_internal_mapManip::findMAPCOMValues
void findMAPCOMValues(proshade_double *map, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo)
This function finds the Centre of Mass for a map.
Definition: ProSHADE_mapManip.cpp:240
ProSHADE_internal_mapManip::blurSharpenMap
void blurSharpenMap(proshade_double *&map, proshade_double *&maskedMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single blurringFactor)
Function for blurring/sharpening maps.
Definition: ProSHADE_mapManip.cpp:974
ProSHADE_internal_mapManip::moveMapByFourier
void moveMapByFourier(proshade_double *&map, proshade_single xMov, proshade_single yMov, proshade_single zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim)
Function for moving map back to original PDB location by using Fourier transformation.
Definition: ProSHADE_mapManip.cpp:813
ProSHADE_internal_mapManip::movePDBForMapCalc
void movePDBForMapCalc(gemmi::Structure *pdbFile, proshade_single xMov, proshade_single yMov, proshade_single zMov, bool firstModel)
Function for moving co-ordinate atoms to better suit theoretical map computation.
Definition: ProSHADE_mapManip.cpp:575
ProSHADE_internal_maths::getRotationMatrixFromEulerZXZAngles
void getRotationMatrixFromEulerZXZAngles(proshade_double eulerAlpha, proshade_double eulerBeta, proshade_double eulerGamma, proshade_double *matrix)
Function to find the rotation matrix from Euler angles (ZXZ convention).
Definition: ProSHADE_maths.cpp:1020
ProSHADE_internal_maths::complexMultiplication
void complexMultiplication(proshade_double *r1, proshade_double *i1, proshade_double *r2, proshade_double *i2, proshade_double *retReal, proshade_double *retImag)
Function to multiply two complex numbers.
Definition: ProSHADE_maths.cpp:38
ProSHADE_internal_messages::printWarningMessage
void printWarningMessage(proshade_signed verbose, std::string message, std::string warnCode)
General stderr message printing (used for warnings).
Definition: ProSHADE_messages.cpp:102
ProSHADE_internal_mapManip::reSampleMapToResolutionTrilinear
void reSampleMapToResolutionTrilinear(proshade_double *&map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single *&corrs)
This function re-samples a map to conform to given resolution using tri-linear interpolation.
Definition: ProSHADE_mapManip.cpp:1217
ProSHADE_internal_mapManip::getCorrelationMapMask
void getCorrelationMapMask(proshade_double *&map, proshade_double *&fakeHalfMap, proshade_double *&correlationMask, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_signed corrMaskKernel)
Function for creating the correlation mask.
Definition: ProSHADE_mapManip.cpp:1795
ProSHADE_internal_mapManip::changeFourierOrder
void changeFourierOrder(fftw_complex *&fCoeffs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, bool negativeFirst)
This function changes the order of Fourier coefficients in a 3D array between positive first (default...
Definition: ProSHADE_mapManip.cpp:1609
ProSHADE_internal_mapManip::releaseResolutionFourierMemory
void releaseResolutionFourierMemory(fftw_complex *&origMap, fftw_complex *&fCoeffs, fftw_complex *&newFCoeffs, fftw_complex *&newMap, fftw_plan &planForwardFourier, fftw_plan &planBackwardRescaledFourier)
This function releases the memory required by the Fourier resampling.
Definition: ProSHADE_mapManip.cpp:1580
ProSHADE_internal_mapManip::removeWaters
void removeWaters(gemmi::Structure *pdbFile, bool firstModel)
This function removed all waters from PDB input file.
Definition: ProSHADE_mapManip.cpp:506
ProSHADE_internal_maths::pearsonCorrCoeff
proshade_double pearsonCorrCoeff(proshade_double *valSet1, proshade_double *valSet2, proshade_unsign length)
Function for computing the Pearson's correlation coefficient.
Definition: ProSHADE_maths.cpp:246
ProSHADE_internal_mapManip::findPDBCOMValues
void findPDBCOMValues(gemmi::Structure pdbFile, proshade_double *xCom, proshade_double *yCom, proshade_double *zCom, bool firstModel)
This function finds the Centre of Mass for the co-ordinate file.
Definition: ProSHADE_mapManip.cpp:157
ProSHADE_internal_misc::addToSignedVector
void addToSignedVector(std::vector< proshade_signed > *vecToAddTo, proshade_signed elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:121
ProSHADE_internal_mapManip::getIndicesFromAngstroms
proshade_single getIndicesFromAngstroms(proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single dist)
This function converts distance in Angstroms to distance in map indices.
Definition: ProSHADE_mapManip.cpp:1866
ProSHADE_internal_mapManip::getNonZeroBounds
void getNonZeroBounds(proshade_double *map, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_signed *&ret)
Function for finding the map boundaries enclosing positive only values.
Definition: ProSHADE_mapManip.cpp:1124
ProSHADE_internal_mapManip::removeMapPhase
void removeMapPhase(fftw_complex *&mapCoeffs, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim)
This function removes the phase from reciprocal (frequency) map.
Definition: ProSHADE_mapManip.cpp:1681
ProSHADE_internal_mapManip::allocateResolutionFourierMemory
void allocateResolutionFourierMemory(fftw_complex *&origMap, fftw_complex *&fCoeffs, fftw_complex *&newFCoeffs, fftw_complex *&newMap, fftw_plan &planForwardFourier, fftw_plan &planBackwardRescaledFourier, proshade_unsign xDimOld, proshade_unsign yDimOld, proshade_unsign zDimOld, proshade_unsign xDimNew, proshade_unsign yDimNew, proshade_unsign zDimNew)
This function allocates and checks the allocatio of the memory required by the Fourier resampling.
Definition: ProSHADE_mapManip.cpp:1546
ProSHADE_internal_maths::primeFactorsDecomp
std::vector< proshade_signed > primeFactorsDecomp(proshade_signed number)
Function to find prime factors of an integer.
Definition: ProSHADE_maths.cpp:1722
ProSHADE_internal_mapManip::betterClosePrimeFactors
proshade_signed betterClosePrimeFactors(proshade_signed fromRange, proshade_signed toRange)
Function for finding close numbers with better prime factors.
Definition: ProSHADE_mapManip.cpp:2036
ProSHADE_internal_mapManip::myRound
proshade_signed myRound(proshade_double x)
Calls the appropriate version of round function depending on compiler version.
Definition: ProSHADE_mapManip.cpp:31
ProSHADE_internal_mapManip::beautifyBoundaries
void beautifyBoundaries(proshade_signed *&bounds, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim, proshade_signed boundsDiffThres)
Function for modifying boundaries to a mathematically more pleasant values.
Definition: ProSHADE_mapManip.cpp:1966
ProSHADE_internal_mapManip::rotatePDBCoordinates
void rotatePDBCoordinates(gemmi::Structure *pdbFile, proshade_double euA, proshade_double euB, proshade_double euG, proshade_double xCom, proshade_double yCom, proshade_double zCom, bool firstModel)
Function for rotating the PDB file co-ordinates by Euler angles.
Definition: ProSHADE_mapManip.cpp:298
ProSHADE_internal_mapManip::generateMapFromPDB
void generateMapFromPDB(gemmi::Structure pdbFile, proshade_double *&map, proshade_single requestedResolution, proshade_single xCell, proshade_single yCell, proshade_single zCell, proshade_signed *xTo, proshade_signed *yTo, proshade_signed *zTo, bool forceP1, bool firstModel)
This function generates a theoretical map from co-ordinate input files.
Definition: ProSHADE_mapManip.cpp:646
ProSHADE_internal_misc::checkMemoryAllocation
void checkMemoryAllocation(chVar checkVar, std::string fileP, unsigned int lineP, std::string funcP, std::string infoP="This error may occurs when ProSHADE requests memory to be\n : allocated to it and this operation fails. This could\n : happen when not enough memory is available, either due to\n : other processes using a lot of memory, or when the machine\n : does not have sufficient memory available. Re-run to see\n : if this problem persists.")
Checks if memory was allocated properly.
Definition: ProSHADE_misc.hpp:68
ProSHADE_internal_mapManip::translatePDBCoordinates
void translatePDBCoordinates(gemmi::Structure *pdbFile, proshade_double transX, proshade_double transY, proshade_double transZ, bool firstModel)
Function for translating the PDB file co-ordinates by given distances in Angstroms.
Definition: ProSHADE_mapManip.cpp:383
ProSHADE_internal_maths::vectorMedianAndIQR
void vectorMedianAndIQR(std::vector< proshade_double > *vec, proshade_double *&ret)
Function to get vector median and inter-quartile range.
Definition: ProSHADE_maths.cpp:149
ProSHADE_internal_mapManip::getFakeHalfMap
void getFakeHalfMap(proshade_double *&map, proshade_double *&fakeHalfMap, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_signed fakeMapKernel)
Function for creating "fake" half-maps.
Definition: ProSHADE_mapManip.cpp:1730
ProSHADE_internal_misc::addToUnsignVector
void addToUnsignVector(std::vector< proshade_unsign > *vecToAddTo, proshade_unsign elementToAdd)
Adds the element to the vector.
Definition: ProSHADE_misc.cpp:99
ProSHADE_internal_mapManip::reSampleMapToResolutionFourier
void reSampleMapToResolutionFourier(proshade_double *&map, proshade_single resolution, proshade_unsign xDimS, proshade_unsign yDimS, proshade_unsign zDimS, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single *&corrs)
This function re-samples a map to conform to given resolution using Fourier.
Definition: ProSHADE_mapManip.cpp:1427
ProSHADE_internal_mapManip::copyMapByBounds
void copyMapByBounds(proshade_signed xFrom, proshade_signed xTo, proshade_signed yFrom, proshade_signed yTo, proshade_signed zFrom, proshade_signed zTo, proshade_signed origXFrom, proshade_signed origYFrom, proshade_signed origZFrom, proshade_unsign yDimIndices, proshade_unsign zDimIndices, proshade_unsign origXDimIndices, proshade_unsign origYDimIndices, proshade_unsign origZDimIndices, proshade_double *&newMap, proshade_double *origMap)
This function copies an old map to a new map with different boundaries.
Definition: ProSHADE_mapManip.cpp:2132
ProSHADE_internal_mapManip::connectMaskBlobs
void connectMaskBlobs(proshade_double *&mask, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_single maskThres)
This function connects blobs in mask.
Definition: ProSHADE_mapManip.cpp:1889
ProSHADE_internal_mapManip::moveMapByFourierInReci
void moveMapByFourierInReci(proshade_complex *&coeffs, proshade_double *&weights, proshade_single xMov, proshade_single yMov, proshade_single zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed xDim, proshade_signed yDim, proshade_signed zDim)
Function for moving map using Fourier coefficients in the reciprocal space only.
Definition: ProSHADE_mapManip.cpp:898
ProSHADE_internal_mapManip::moveMapByIndices
void moveMapByIndices(proshade_single *xMov, proshade_single *yMov, proshade_single *zMov, proshade_single xAngs, proshade_single yAngs, proshade_single zAngs, proshade_signed *xFrom, proshade_signed *xTo, proshade_signed *yFrom, proshade_signed *yTo, proshade_signed *zFrom, proshade_signed *zTo, proshade_signed *xOrigin, proshade_signed *yOrigin, proshade_signed *zOrigin)
Function for moving map back to original PDB location by changing the indices.
Definition: ProSHADE_mapManip.cpp:765