ProSHADE  0.7.6.2 (DEC 2021)
Protein Shape Detection
ProSHADE_internal_mapManip Namespace Reference

This namespace contains the internal functions for manipulating maps already present in the internal structures. More...

Functions

proshade_signed myRound (proshade_double x)
 Calls the appropriate version of round function depending on compiler version. More...
 
proshade_signed myRound (proshade_single x)
 Calls the appropriate version of round function depending on compiler version. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
void changePDBBFactors (gemmi::Structure *pdbFile, proshade_double newBFactorValue, bool firstModel)
 Function for changing the PDB B-factor values to a specific single value. More...
 
void removeWaters (gemmi::Structure *pdbFile, bool firstModel)
 This function removed all waters from PDB input file. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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) and negative first (mass centered at xMax/2, yMax/2, zMax/2 instead of 0,0,0) More...
 
void removeMapPhase (fftw_complex *&mapCoeffs, proshade_unsign xDim, proshade_unsign yDim, proshade_unsign zDim)
 This function removes the phase from reciprocal (frequency) map. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
proshade_signed betterClosePrimeFactors (proshade_signed fromRange, proshade_signed toRange)
 Function for finding close numbers with better prime factors. More...
 
void distributeSpaceToBoundaries (proshade_signed &minBound, proshade_signed &maxBound, proshade_signed oldBoundRange, proshade_signed newBoundRange)
 Function for adding space to boundaries within the map confines. More...
 
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. More...
 

Detailed Description

This namespace contains the internal functions for manipulating maps already present in the internal structures.

The ProSHADE_internal_mapManip namespace contains helper functions for map manipulation and processing. However, these functions do make minimum assumptions about the map internal organisation and variables and simply perform tasks on generic variables. None of these functions should be used directly be the user.

Function Documentation

◆ addExtraBoundSpace()

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 
)

This function takes a set of bounds and adds a given number of Angstroms to them.

This function adds an extra distance to a set of bounds as given by the number of angstroms to be added. If the resulting bounds are larger than the maximum map bounds, the maxima and minima are returned instead, thus partially ignoring the requested extra space. !!! If the resulting index ranges would be odd, extra one idice is added to make them even. !!!

Parameters
[in]xDimThe number of indices along the x axis of the map.
[in]yDimThe number of indices along the y axis of the map.
[in]zDimThe number of indices along the z axis of the map.
[in]xAngsThe size of the x dimension of the map in angstroms.
[in]yAngsThe size of the y dimension of the map in angstroms.
[in]zAngsThe size of the z dimension of the map in angstroms.
[in]boundsA proshade_unsign pointer reference to array of 6 which has the current bounds (0 = minX; 1 = maxX; 2 = minY; 3 = maxY; 4 - minZ; 5 = maxZ).
[in]extraSpaceThe number of angstroms to be added to each dimension (both to start and to end).

Definition at line 1181 of file ProSHADE_mapManip.cpp.

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 }

◆ allocateResolutionFourierMemory()

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 
)

This function allocates and checks the allocatio of the memory required by the Fourier resampling.

This function allocates the memory required for the Fourier space re-sampling of density maps. It allocates the original map and original map coefficients arrays (these need to be of the fftw_complex type) as well as the re-sampled map and re-sampled map coefficients. It then also proceeds to check the memory allocation and creating the FFTW transform plans for both, the forward and re-sampled backward operations.

Parameters
[in]origMapA Reference pointer to an array where the original map data will be stored.
[in]fCoeffsA Reference pointer to an array where the original map Fourier coefficients data will be stored.
[in]newFCoeffsA Reference pointer to an array where the re-sampled map Fourier coefficients data will be stored.
[in]newMapA Reference pointer to an array where the re-sampled map data will be stored.
[in]planForwardFourierFFTW_plan which will compute the original map to Fourier coefficients transform.
[in]planBackwardRescaledFourierFFTW_plan which will compute the re-sampled Fourier coefficients to re-sampled map transform.
[in]xDimOldThe number of indices along the x-axis of the original map.
[in]yDimOldThe number of indices along the y-axis of the original map.
[in]zDimOldThe number of indices along the z-axis of the original map.
[in]xDimNewThe number of indices along the x-axis of the re-sampled map.
[in]yDimNewThe number of indices along the y-axis of the re-sampled map.
[in]zDimNewThe number of indices along the z-axis of the re-sampled map.

Definition at line 1546 of file ProSHADE_mapManip.cpp.

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 }

◆ beautifyBoundaries()

void ProSHADE_internal_mapManip::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.

This function does two things. Firstly, it attempts to find even boundaries which have a small sum of the prime factors - i.e. this is good for further processing. Secondly, it attempts to make boundaries with sizes within some threshold the same. This is purely human thing :-).

Parameters
[in]boundsA proshade_signed pointer to array of 6 in which the current bounds are (0 = minX; 1 = maxX; 2 = minY; 3 = maxY; 4 - minZ; 5 = maxZ).
[in]xDimThe number of indices along the x axis of the map.
[in]yDimThe number of indices along the y axis of the map.
[in]zDimThe number of indices along the z axis of the map.
[in]boundsDiffThresNumber of indices by which boudaries in different dimensions can differ and still be made the same.

Definition at line 1966 of file ProSHADE_mapManip.cpp.

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 }

◆ betterClosePrimeFactors()

proshade_signed ProSHADE_internal_mapManip::betterClosePrimeFactors ( proshade_signed  fromRange,
proshade_signed  toRange 
)

Function for finding close numbers with better prime factors.

This function takes a range of integer numbers and proceeds to find if a close number in the range to the range start does not have better (smaller sum of) prime factors, taking into account the distance of this better number to the starting position. This is useful for finding boundaries with nice prime number sizes.

Parameters
[in]fromRangeWhich number the search will be from and possibilities compared to.
[in]toRangeThe maximum number to which the posibilities should be searched.
[out]XThe value in the range which has better prime factors, or the first value if none other has.

Definition at line 2036 of file ProSHADE_mapManip.cpp.

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 }

◆ blurSharpenMap()

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 
)

Function for blurring/sharpening maps.

This function takes the internal map representation information from the parameters as well as the internal map itself and proceeds to compute blue/sharpen the map by changing its overall B-factors by adding a specific value. If this value is negative, then the map is sharpened, while if the value is positive, the map is blurred.

Parameters
[in]mapA Reference Pointer to the map which should be blurred/sharpened.
[in]blurredMapA Reference Pointer to the variable which will store the modified map.
[in]xDimSThe number of indices along the x axis of the map.
[in]yDimSThe number of indices along the y axis of the map.
[in]zDimSThe number of indices along the z axis of the map.
[in]xAngsThe size of the x dimension of the map in angstroms.
[in]yAngsThe size of the y dimension of the map in angstroms.
[in]zAngsThe size of the z dimension of the map in angstroms.
[in]blurringFactorThe amount of B-factor change that should be applied to the map. (I.e. increasing the map overall B-factors by 20 will be done by supplying 20 as a value for this parameter).

Definition at line 974 of file ProSHADE_mapManip.cpp.

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 }

◆ changeFourierOrder()

void ProSHADE_internal_mapManip::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) and negative first (mass centered at xMax/2, yMax/2, zMax/2 instead of 0,0,0)

This function firstly determines the start and end of the positive and negative Fourier coefficients for all three axes (it assumes 3D array); this works for both odd and even axis sizes. To do this properly, in the case of odd axis sizes, the function needs to know whether we are changing the order from FFTW defaul positive first, or if we are changing the other way around - the last parameter serves the purpose of passing this information. Finally, the function then switches the order of the Fourier coefficients as requested using a temporary array that it allocates and deletes within itself.

Parameters
[in]fCoeffsA Reference pointer to an array where the Fourier coefficients for re-ordering are stored.
[in]xDimThe size of the x-axis dimension of the fCoeffs array.
[in]yDimThe size of the x-axis dimension of the fCoeffs array.
[in]zDimThe size of the x-axis dimension of the fCoeffs array.
[in]negativeFirstShould the coefficients be stored negarive first (TRUE), or are we reversing already re-ordered array (FALSE)?

Definition at line 1609 of file ProSHADE_mapManip.cpp.

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 }

◆ changePDBBFactors()

void ProSHADE_internal_mapManip::changePDBBFactors ( gemmi::Structure *  pdbFile,
proshade_double  newBFactorValue,
bool  firstModel 
)

Function for changing the PDB B-factor values to a specific single value.

This function does a quick read-through the PDB file and changes all the atom B-factor values to a single, pre-set value. This is important for PDB files which have all atoms with B-factor value 0, as these then produce bad maps, which fail further processing by ProSHADE.

Parameters
[in]pdbFileA pointer to gemmi::Structure object read in from the input file.
[in]newBFactorValueThe value with which all atom B-factor values should be replaced.
[in]firstModelShould only the first, or all models be used?

Definition at line 446 of file ProSHADE_mapManip.cpp.

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 }

◆ connectMaskBlobs()

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 
)

This function connects blobs in mask.

Parameters
[in]maskA pointer reference to mask map in which blobs should be connected.
[in]xDimThe number of map indices along the x-axis.
[in]yDimThe number of map indices along the y-axis.
[in]zDimThe number of map indices along the z-axis.
[in]xAngsThe map size in Angstroms along the x-axis.
[in]yAngsThe map size in Angstroms along the y-axis.
[in]zAngsThe map size in Angstroms along the z-axis.
[in]maskThresThe threshold which will be used for applying mask.

Definition at line 1889 of file ProSHADE_mapManip.cpp.

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 }

◆ copyMapByBounds()

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 
)

This function copies an old map to a new map with different boundaries.

This function takes old and new structure details and the original structure map. It then proceed to iterate through the new structure map, checking if this particular point is inside the original structure's map and if it is, it will copy the value of this point from the original to the new map. Otherwise, it will set the new map's point value to 0.0. This is used when creating a new structure from an old structure given new bounds, which can be larger or smaller than the originals.

Parameters
[in]xFromThe starting x-axis index of the new map.
[in]xToThe last x-axis index of the new map.
[in]yFromThe starting y-axis index of the new map.
[in]yToThe last y-axis index of the new map.
[in]zFromThe starting z-axis index of the new map.
[in]zToThe last z-axis index of the new map.
[in]origXFromThe starting x-axis index of the original (copied) map.
[in]origYFromThe starting y-axis index of the original (copied) map.
[in]origZFromThe starting z-axis index of the original (copied) map.
[in]yDimIndicesThe size of the y-axis dimension in the new map.
[in]zDimIndicesThe size of the z-axis dimension in the new map.
[in]origXDimIndicesThe size of the x-axis dimension in the old map.
[in]origYDimIndicesThe size of the y-axis dimension in the old map.
[in]origZDimIndicesThe size of the z-axis dimension in the old map.
[in]newMapPointer reference to the array where new map will be saved to.
[in]origMapPointer to the array where the original map can be accessed.

Definition at line 2132 of file ProSHADE_mapManip.cpp.

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 }

◆ determinePDBRanges()

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 
)

Function for finding the PDB file ranges.

This function does a quick read-through the PDB file and reports the x, y and z to and from values. This is used to determine if these need to be changed for proper theoretical map computation operation.

Parameters
[in]pdbFileA gemmi::Structure object read in from the input file.
[in]xFromAddress to a variable to save the x axis minimal atom position.
[in]xToAddress to a variable to save the x axis maximum atom position.
[in]yFromAddress to a variable to save the y axis minimal atom position.
[in]yToAddress to a variable to save the y axis maximum atom position.
[in]zFromAddress to a variable to save the z axis minimal atom position.
[in]zToAddress to a variable to save the z axis maximum atom position.
[in]firstModelShould only the first, or all models be used?
Warning
This function ignores hydrogen atoms, as they will not be used in map computation by Gemmi and their inclusion causes mismatches between the map and the co-ordinates as they now contain different contents.

Definition at line 72 of file ProSHADE_mapManip.cpp.

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 }

◆ distributeSpaceToBoundaries()

void ProSHADE_internal_mapManip::distributeSpaceToBoundaries ( proshade_signed &  minBound,
proshade_signed &  maxBound,
proshade_signed  oldBoundRange,
proshade_signed  newBoundRange 
)

Function for adding space to boundaries within the map confines.

This function takes the current boudaries and attempts to add the extra space specified by the parameters 3 and 4 equally to both the top and bottom boundaries, making sure the bottom boundary does not go belowe 0 and the top boundary does not exceed the final parameter.

Parameters
[in]minBoundReference to where the lower boundary value is held.
[in]maxBoundReference to where the upper boundary value is held.
[in]oldBoundRangeThe range between the original boundaries.
[in]newBoundRangeThe range which should be between the new boundaries.

Definition at line 2082 of file ProSHADE_mapManip.cpp.

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 }

◆ findMAPCOMValues()

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 
)

This function finds the Centre of Mass for a map.

This function takes the proshade map object and procceds to compute the Centre of Mass of this object in Angstroms in real space.

Parameters
[in]mapA pointer to prshade density map.
[in]xComA pointer to proshade_double variable where the MAP file COM along the X-axis will be saved.
[in]yComA pointer to proshade_double variable where the MAP file COM along the Y-axis will be saved.
[in]zComA pointer to proshade_double variable where the MAP file COM along the Z-axis will be saved.
[in]xAngsThe map size in Angstroms along the X axis.
[in]yAngsThe map size in Angstroms along the Y axis.
[in]zAngsThe map size in Angstroms along the Z axis.
[in]xFromThe initial index of the x dimension of the map.
[in]xToThe terminal index of the x dimension of the map.
[in]yFromThe initial index of the y dimension of the map.
[in]yToThe terminal index of the y dimension of the map.
[in]zFromThe initial index of the z dimension of the map.
[in]zToThe terminal index of the z dimension of the map.

Definition at line 240 of file ProSHADE_mapManip.cpp.

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 }

◆ findPDBCOMValues()

void ProSHADE_internal_mapManip::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.

This function takes the gemmi::Structure object read from a co-odinate file and procceds to compute the Centre of Mass of this object.

Parameters
[in]pdbFileA gemmi::Structure object read in from input file.
[in]xComA pointer to proshade_double variable where the PDB file COM along the X-axis will be saved.
[in]yComA pointer to proshade_double variable where the PDB file COM along the Y-axis will be saved.
[in]zComA pointer to proshade_double variable where the PDB file COM along the Z-axis will be saved.
[in]firstModelShould only the first, or all models be used?

Definition at line 157 of file ProSHADE_mapManip.cpp.

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 }

◆ generateMapFromPDB()

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 
)

This function generates a theoretical map from co-ordinate input files.

This function makes use of the Gemmi internal functionality to firstly create a properly sized cell object, then to check the input co-ordinate file for containing known elements as well as elements for which Gemmi knows the form factors. Then, this function proceeds to compute the F's using Cromer & Libermann method (from Gemmi) to finally compute the theoretical map using these. This map is then copied to the variable supplied in the second argument, presumably the ProSHADE internal map variable.

Parameters
[in]pdbFileA gemmi::Structure object read in from the input file.
[in]mapPointer reference to a variable to save the map data.
[in]requestedResolutionMap resolution to which the map should be computed.
[in]xCellThe size of the map cell to be created.
[in]yCellThe size of the map cell to be created.
[in]zCellThe size of the map cell to be created.
[in]xToPointer to variable where the map size along the x-axis in indices will be saved.
[in]yToPointer to variable where the map size along the y-axis in indices will be saved.
[in]zToPointer to variable where the map size along the z-axis in indices will be saved.
[in]forceP1Should the P1 spacegroup be forced?
[in]firstModelShould only the first, or all models be used?
Warning
By default, this function will force the P1 spacegroup!

Definition at line 646 of file ProSHADE_mapManip.cpp.

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 }

◆ getCorrelationMapMask()

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 
)

Function for creating the correlation mask.

This function is currently not used and should probably be deleted. The proper implementation of this masking approach should be available in the EMDA software.

Parameters
[in]mapA Reference Pointer to the map which should be blurred/sharpened.
[in]blurredMapA Reference Pointer to the variable which stores the fake half-map.
[in]correlationMaskA Reference Pointer to empty map where the mask will be saved.
[in]xDimSThe number of indices along the x axis of the map.
[in]yDimSThe number of indices along the y axis of the map.
[in]zDimSThe number of indices along the z axis of the map.
[in]corrMaskKernelThe amount of neighbours in any direction whose correlation is to be used to get the current points correlation.

Definition at line 1795 of file ProSHADE_mapManip.cpp.

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 }

◆ getFakeHalfMap()

void ProSHADE_internal_mapManip::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.

This function takes the internal map and an empty map array and proceeds to find all neighbours within the kernel distance to each map points. It then computes the average of these neighbours and saves this average as the value of the "fake" half-map. These are then useul for map masking, as the correlation between the "fake" half-maps and the original maps give nice masks according to Rangana

  • see him about how well these work.
Parameters
[in]mapA Reference Pointer to the map which should be blurred/sharpened.
[in]blurredMapA Reference Pointer to the variable which will store the modified map.
[in]xDimSThe number of indices along the x axis of the map.
[in]yDimSThe number of indices along the y axis of the map.
[in]zDimSThe number of indices along the z axis of the map.
[in]fakeMapKernelThe amount of neighbours in any direction whose average is to be used to get the current point.

Definition at line 1730 of file ProSHADE_mapManip.cpp.

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 }

◆ getIndicesFromAngstroms()

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 
)

This function converts distance in Angstroms to distance in map indices.

This function finds out how many indices are required to cover a space of size "dist" in Angstroms. If you need this rounded in any way (ceil, floor, ...), just apply appropriate function to the output of this function.

Parameters
[in]xDimThe number of map indices along the x-axis.
[in]yDimThe number of map indices along the y-axis.
[in]zDimThe number of map indices along the z-axis.
[in]xAngsThe map size in Angstroms along the x-axis.
[in]yAngsThe map size in Angstroms along the y-axis.
[in]zAngsThe map size in Angstroms along the z-axis.
[in]distThe distance in Angstroms to be converted

Definition at line 1866 of file ProSHADE_mapManip.cpp.

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 }

◆ getMaskFromBlurr()

void ProSHADE_internal_mapManip::getMaskFromBlurr ( proshade_double *&  blurMap,
proshade_double *&  outMap,
proshade_unsign  xDim,
proshade_unsign  yDim,
proshade_unsign  zDim,
proshade_single  noIQRs 
)

Function for computing mask from blurred map.

This function takes a blurred map and proceeds to compute the cut-off threshold for masking. It then applies this mask to the blurred map and applies the masking to the second input map. The assumption is that this second map is the map before blurring, as non-zero mask points will not be changed. Careful about this!!! It, however, does not output the mask.

Parameters
[in]blurMapA Reference Pointer to the map which has been blurred for mask computation.
[in]outMapA Reference Pointer to the map which will be masked - this map should be the map before blurring.
[in]xDimThe number of indices along the x axis of the map.
[in]yDimThe number of indices along the y axis of the map.
[in]zDimThe number of indices along the z axis of the map.
[in]noIQRsThe number of inter-quartile ranges from the median which should be used to compute the threshold for masking.

Definition at line 1074 of file ProSHADE_mapManip.cpp.

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 }

◆ getNonZeroBounds()

void ProSHADE_internal_mapManip::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.

This function takes a map and searches for minimum and maximum map indices in all three dimensions, which enclose all the non-zero map values.

Parameters
[in]mapA pointer to the map for which the bounds are to be found.
[in]xDimThe number of indices along the x axis of the map.
[in]yDimThe number of indices along the y axis of the map.
[in]zDimThe number of indices along the z axis of the map.
[in]retA proshade_unsign pointer to array of 6 to which the results will be saved (0 = minX; 1 = maxX; 2 = minY; 3 = maxY; 4 - minZ; 5 = maxZ).

Definition at line 1124 of file ProSHADE_mapManip.cpp.

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 }

◆ moveMapByFourier()

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 
)

Function for moving map back to original PDB location by using Fourier transformation.

This function translates the map by changing the phase information of the map Fourier transform and then doing the inverse Fourier. This allows for movement smaller than one index distance, but should not be used over long distances (could move out of boundaries and meet pariodicity problem such as map from different cell now being moved into this cell).

Parameters
[in]mapA Reference Pointer to the map which should be shifted.
[in]xMovThe NEGATIVE value by how many angstroms should the x axis be moved.
[in]yMovThe NEGATIVE value by how many angstroms should the y axis be moved.
[in]zMovThe NEGATIVE value by how many angstroms should the z axis be moved.
[in]xAngsHow many angstroms are there along the x dimension.
[in]yAngsHow many angstroms are there along the y dimensionzAngs
[in]zAngsHow many angstroms are there along the z dimension.
[in]xDimHow many indices are there along the x dimension.
[in]yDimHow many indices are there along the y dimension.
[in]zDimHow many indices are there along the z dimension.

Definition at line 813 of file ProSHADE_mapManip.cpp.

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 }

◆ moveMapByFourierInReci()

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 
)

Function for moving map using Fourier coefficients in the reciprocal space only.

This function translates the map by changing the phase information of the map Fourier transform. Contrary to the moveMapByFourier() function, it does not compute the inverse Fourier transform

Parameters
[in]coeffsA Reference Pointer to the Fourier decomposition coefficients of the map to be moved.
[in]weightsAn array of weights to be applied to the shifted coefficients.
[in]xMovThe NEGATIVE value by how many angstroms should the x axis be moved.
[in]yMovThe NEGATIVE value by how many angstroms should the y axis be moved.
[in]zMovThe NEGATIVE value by how many angstroms should the z axis be moved.
[in]xAngsHow many angstroms are there along the x dimension.
[in]yAngsHow many angstroms are there along the y dimensionzAngs
[in]zAngsHow many angstroms are there along the z dimension.
[in]xDimHow many indices are there along the x dimension.
[in]yDimHow many indices are there along the y dimension.
[in]zDimHow many indices are there along the z dimension.

Definition at line 898 of file ProSHADE_mapManip.cpp.

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 }

◆ moveMapByIndices()

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 
)

Function for moving map back to original PDB location by changing the indices.

This function translates the map by changing the to and from index values so that the location of the map will be the same as the location of the original PDB file. This most likely cannot be done exactly as it allows only movement by increments of the sampling rate, but it is a decent start.

Parameters
[in]xMovPointer to the NEGATIVE value by how many angstroms should the x axis be moved.
[in]yMovPointer to the NEGATIVE value by how many angstroms should the y axis be moved.
[in]zMovPointer to the NEGATIVE value by how many angstroms should the z axis be moved.
[in]xAngsHow many angstroms are there along the x dimension.
[in]yAngsHow many angstroms are there along the y dimension.
[in]zAngsHow many angstroms are there along the z dimension.
[in]xFromThe initial index of the x dimension of the map.
[in]xToThe terminal index of the x dimension of the map.
[in]yFromThe initial index of the y dimension of the map.
[in]yToThe terminal index of the y dimension of the map.
[in]zFromThe initial index of the z dimension of the map.
[in]zToThe terminal index of the z dimension of the map.
[in]xOriginThe first value of the x axis index.
[in]yOriginThe first value of the y axis index.
[in]zOriginThe first value of the z axis index.

Definition at line 765 of file ProSHADE_mapManip.cpp.

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 }

◆ movePDBForMapCalc()

void ProSHADE_internal_mapManip::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.

This function translates all atoms by a given x, y and z distances. This is required as theoretical map computation can only output map cells starting from 0, 0, 0 and therefore to avoid density being in corners for PDB atoms not located in posivite axes, the atoms need to be moved. This effect should be reversed later.

Parameters
[in]pdbFileA pointer to the gemmi::Structure object as read in from the input file.
[in]xMovHow many angstroms should the atoms be moved along the x axis.
[in]yMovHow many angstroms should the atoms be moved along the y axis.
[in]zMovHow many angstroms should the atoms be moved along the z axis.
[in]firstModelShould only the first, or all models be used?

Definition at line 575 of file ProSHADE_mapManip.cpp.

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 }

◆ myRound() [1/2]

proshade_signed ProSHADE_internal_mapManip::myRound ( proshade_double  x)

Calls the appropriate version of round function depending on compiler version.

Parameters
[in]xA decimal point number to be rounded.
[out]XThe rounded number.

Definition at line 31 of file ProSHADE_mapManip.cpp.

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 }

◆ myRound() [2/2]

proshade_signed ProSHADE_internal_mapManip::myRound ( proshade_single  x)

Calls the appropriate version of round function depending on compiler version.

Parameters
[in]xA decimal point number to be rounded.
[out]XThe rounded number.

Definition at line 46 of file ProSHADE_mapManip.cpp.

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 }

◆ releaseResolutionFourierMemory()

void ProSHADE_internal_mapManip::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.

This function simply deletes all the memory allocated by the allocateResolutionFourierMemory() function.

Parameters
[in]origMapA Reference pointer to an array where the original map data were stored.
[in]fCoeffsA Reference pointer to an array where the original map Fourier coefficients data were stored.
[in]newFCoeffsA Reference pointer to an array where the re-sampled map Fourier coefficients data were stored.
[in]newMapA Reference pointer to an array where the re-sampled map data were stored.
[in]planForwardFourierFFTW_plan which computed the original map to Fourier coefficients transform.
[in]planBackwardRescaledFourierFFTW_plan which computed the re-sampled Fourier coefficients to re-sampled map transform.

Definition at line 1580 of file ProSHADE_mapManip.cpp.

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 }

◆ removeMapPhase()

void ProSHADE_internal_mapManip::removeMapPhase ( fftw_complex *&  mapCoeffs,
proshade_unsign  xDim,
proshade_unsign  yDim,
proshade_unsign  zDim 
)

This function removes the phase from reciprocal (frequency) map.

This function takes an already FFTW-ed map and its dimensions as the input and proceeds to remove the phase from the map. It writes over the map and does not release any memory - it is the role of the calling function to deal with both these features.

Parameters
[in]mapCoeffsA Reference Pointer to the frequency map, from which phase is to be removed.
[in]xDimThe number of indices along the x-axis of the input map.
[in]yDimThe number of indices along the y-axis of the input map.
[in]zDimThe number of indices along the z-axis of the input map.

Definition at line 1681 of file ProSHADE_mapManip.cpp.

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 }

◆ removeWaters()

void ProSHADE_internal_mapManip::removeWaters ( gemmi::Structure *  pdbFile,
bool  firstModel 
)

This function removed all waters from PDB input file.

This function does a quick read-through the PDB file and deletes all water molecules from the PDB file. This is important as comparing two similar structures, one with hundreds of waters (with high occupancy in some cases) and one without will lead to the structures being different in ProSHADE's eyes.

Parameters
[in]pdbFileA pointer to gemmi::Structure object read in from the input file.
[in]firstModelShould only the first, or all models be used?

Definition at line 506 of file ProSHADE_mapManip.cpp.

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 }

◆ reSampleMapToResolutionFourier()

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 
)

This function re-samples a map to conform to given resolution using Fourier.

This function re-samples the internal map to a given resolutution by removing or zero-padding the Fourier (reciprocal space) coefficients and computing the inverse Fourier transform. This is the default option for map re-sampling, should it be required by the user.

Parameters
[in]mapA Reference Pointer to the map for which the bounds are to be found.
[in]resolutionThe required resolution value.
[in]xDimSThe number of indices along the x axis of the map.
[in]yDimSThe number of indices along the y axis of the map.
[in]zDimSThe number of indices along the z axis of the map.
[in]xAngsThe size of the x dimension of the map in angstroms.
[in]yAngsThe size of the y dimension of the map in angstroms.
[in]zAngsThe size of the z dimension of the map in angstroms.
[in]corrsPointer reference to proshade_single array of 6 values with the following meaning: 0 = xAdd; 1 = yAdd; 2 = zAdd; 3 = newXAng; 4 = newYAng; 5 = newZAng
[in]xFromThe initial index of the x dimension of the map.
[in]xToThe terminal index of the x dimension of the map.
[in]yFromThe initial index of the y dimension of the map.
[in]yToThe terminal index of the y dimension of the map.
[in]zFromThe initial index of the z dimension of the map.
[in]zToThe terminal index of the z dimension of the map.
[in]xOriginThe first value of the x axis index.
[in]yOriginThe first value of the y axis index.
[in]zOriginThe first value of the z axis index.

Definition at line 1427 of file ProSHADE_mapManip.cpp.

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 }

◆ reSampleMapToResolutionTrilinear()

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 
)

This function re-samples a map to conform to given resolution using tri-linear interpolation.

This function takes a map and resolution value and it proceeds to create a new map, which has sampling resolution/2 and is large enough to contain the original map. It then proceeds to interpolate the new map values from the old map values, re-writing the old map once interpolation is done.

Parameters
[in]mapA Reference Pointer to the map for which the bounds are to be found.
[in]resolutionThe required resolution value.
[in]xDimSThe number of indices along the x axis of the map.
[in]yDimSThe number of indices along the y axis of the map.
[in]zDimSThe number of indices along the z axis of the map.
[in]xAngsThe size of the x dimension of the map in angstroms.
[in]yAngsThe size of the y dimension of the map in angstroms.
[in]zAngsThe size of the z dimension of the map in angstroms.
[in]corrsPointer reference to proshade_single array of 6 values with the following meaning: 0 = xAdd; 1 = yAdd; 2 = zAdd; 3 = newXAng; 4 = newYAng; 5 = newZAng

Definition at line 1217 of file ProSHADE_mapManip.cpp.

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 }

◆ rotatePDBCoordinates()

void ProSHADE_internal_mapManip::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.

This function takes the three Euler angles and a pointer to a gemmi::Structure and it then proceeds to compute the rotation matrix from the Euler angles. This matrix is then applied to the co-ordinates in the gemmi::Structure in a way so that the rotation is done over the centre of the co-ordinates, but the co-ordinate positions stay unchanged.

Parameters
[in]pdbFilePointer to a gemmi::Structure object which will have its co-ordinates rotated.
[in]euAThe Euler angle alpha by which the co-ordinates should be rotated.
[in]euBThe Euler angle beta by which the co-ordinates should be rotated.
[in]euGThe Euler angle gamma by which the co-ordinates should be rotated.
[in]xComThe x-axis position around which the rotation should be applied.
[in]yComThe y-axis position around which the rotation should be applied.
[in]zComThe z-axis position around which the rotation should be applied.
[in]firstModelShould only the first, or all models be used?

Definition at line 298 of file ProSHADE_mapManip.cpp.

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 }

◆ translatePDBCoordinates()

void ProSHADE_internal_mapManip::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.

This function simply iterates through the given structure object and adds the required shift to all atoms in the first model along the three axes.

Parameters
[in]pdbFilePointer to a gemmi::Structure object whose co-ordinates are to be translated.
[in]transXThe
[in]transYThe
[in]transZThe
[in]firstModelShould only the first, or all models be used?

Definition at line 383 of file ProSHADE_mapManip.cpp.

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 }
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_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::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_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_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::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_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_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_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::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