ProSHADE  0.7.5.3 (FEB 2021)
Protein Shape Detection
ProSHADE_io.cpp
Go to the documentation of this file.
1 
22 //==================================================== ProSHADE
23 #include "ProSHADE_io.hpp"
24 
32 bool ProSHADE_internal_io::isFilePDB ( std::string fName )
33 {
34  //================================================ Try reading the file using Gemmi
35  try
36  {
37  gemmi::Structure structure = gemmi::read_structure ( gemmi::MaybeGzipped ( fName ) );
38  }
39  catch ( std::runtime_error& e )
40  {
41  //============================================ Read failed. Done
42  return ( false );
43  }
44 
45  //================================================ Read successfull. Done
46  return ( true );
47 
48 }
49 
57 bool ProSHADE_internal_io::isFileMAP ( std::string fName )
58 {
59  gemmi::Ccp4<float> map;
60  try
61  {
62  map.read_ccp4 ( gemmi::MaybeGzipped (fName.c_str() ) );
63  }
64  catch ( std::runtime_error& e )
65  {
66  //============================================ Failed to read the map
67  return ( false );
68  }
69 
70  //================================================ Done
71  return ( true );
72 
73 }
74 
103 void ProSHADE_internal_io::readInMapHeader ( gemmi::Ccp4<float> *map, proshade_unsign *xDimInds, proshade_unsign *yDimInds, proshade_unsign *zDimInds, proshade_single *xDim, proshade_single *yDim, proshade_single *zDim, proshade_single *aAng, proshade_single *bAng, proshade_single *cAng, proshade_signed *xFrom, proshade_signed *yFrom, proshade_signed *zFrom, proshade_signed *xAxOrigin, proshade_signed *yAxOrigin, proshade_signed *zAxOrigin, proshade_unsign *xAxOrder, proshade_unsign *yAxOrder, proshade_unsign *zAxOrder, proshade_unsign *xGridInds, proshade_unsign *yGridInds, proshade_unsign *zGridInds )
104 {
105  //================================================ Read in the map file header
106  *xDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 1 ) );
107  *yDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 2 ) );
108  *zDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 3 ) );
109 
110  *xFrom = static_cast<proshade_signed> ( map->header_i32 ( 5 ) );
111  *yFrom = static_cast<proshade_signed> ( map->header_i32 ( 6 ) );
112  *zFrom = static_cast<proshade_signed> ( map->header_i32 ( 7 ) );
113 
114  *xDim = static_cast<proshade_single> ( map->header_float ( 11 ) );
115  *yDim = static_cast<proshade_single> ( map->header_float ( 12 ) );
116  *zDim = static_cast<proshade_single> ( map->header_float ( 13 ) );
117 
118  *aAng = static_cast<proshade_single> ( map->header_float ( 14 ) );
119  *bAng = static_cast<proshade_single> ( map->header_float ( 15 ) );
120  *cAng = static_cast<proshade_single> ( map->header_float ( 16 ) );
121 
122  *xAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 50 ) ) + (*xFrom);
123  *yAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 51 ) ) + (*yFrom);
124  *zAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 52 ) ) + (*zFrom);
125 
126  *xAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 17 ) );
127  *yAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 18 ) );
128  *zAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 19 ) );
129 
130  *xGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 8 ) );
131  *yGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 9 ) );
132  *zGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 10 ) );
133 
134  //================================================ Deal with sampling being different from cell size
135  if ( *xGridInds != *xDimInds )
136  {
137  *xDim = *xDim * ( static_cast<proshade_single> ( *xDimInds ) / static_cast<proshade_single> ( *xGridInds ) );
138  *xGridInds = *xDimInds;
139  }
140 
141  if ( *yGridInds != *yDimInds )
142  {
143  *yDim = *yDim * ( static_cast<proshade_single> ( *yDimInds ) / static_cast<proshade_single> ( *yGridInds ) );
144  *yGridInds = *yDimInds;
145  }
146 
147  if ( *zGridInds != *zDimInds )
148  {
149  *zDim = *zDim * ( static_cast<proshade_single> ( *zDimInds ) / static_cast<proshade_single> ( *zGridInds ) );
150  *zGridInds = *zDimInds;
151  }
152 
153  //================================================ Done
154  return ;
155 
156 }
157 
172 void ProSHADE_internal_io::readInMapData ( gemmi::Ccp4<float> *gemmiMap, proshade_double*& map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder )
173 {
174  //================================================ Allocate internal variables
175  proshade_unsign *axOrdArr = new proshade_unsign[3];
176  proshade_unsign *axDimArr = new proshade_unsign[3];
177  proshade_unsign arrPos = 0;
178 
179  //================================================ Check memory allocation and fill in values
180  ProSHADE_internal_misc::checkMemoryAllocation ( axOrdArr, __FILE__, __LINE__, __func__ );
181  ProSHADE_internal_misc::checkMemoryAllocation ( axDimArr, __FILE__, __LINE__, __func__ );
182  axDimArr[0] = xDimInds;
183  axDimArr[1] = yDimInds;
184  axDimArr[2] = zDimInds;
185 
186  //================================================ Allocate the ProSHADE internal map variable memory
187  map = new proshade_double [xDimInds * yDimInds * zDimInds];
188  ProSHADE_internal_misc::checkMemoryAllocation ( map, __FILE__, __LINE__, __func__ );
189 
190  //================================================ Copy read in data to internal map variable
191  for ( axOrdArr[0] = 0; axOrdArr[0] < axDimArr[xAxOrder-1]; axOrdArr[0]++ )
192  {
193  for ( axOrdArr[1] = 0; axOrdArr[1] < axDimArr[yAxOrder-1]; axOrdArr[1]++ )
194  {
195  for ( axOrdArr[2] = 0; axOrdArr[2] < axDimArr[zAxOrder-1]; axOrdArr[2]++ )
196  {
197  arrPos = axOrdArr[2] + axDimArr[zAxOrder-1] * ( axOrdArr[1] + axDimArr[yAxOrder-1] * axOrdArr[0] );
198  map[arrPos] = gemmiMap->grid.get_value_q( axOrdArr[xAxOrder-1], axOrdArr[yAxOrder-1], axOrdArr[zAxOrder-1] );
199  }
200  }
201  }
202 
203  //================================================ Release internal variables memory
204  delete[] axDimArr;
205  delete[] axOrdArr;
206 
207  //================================================ Done
208  return ;
209 
210 }
211 
242 void ProSHADE_internal_io::writeOutMapHeader ( gemmi::Ccp4<float> *map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_single xDim, proshade_single yDim, proshade_single zDim, proshade_single aAng, proshade_single bAng, proshade_single cAng, proshade_signed xFrom, proshade_signed yFrom, proshade_signed zFrom, proshade_signed xAxOrigin, proshade_signed yAxOrigin, proshade_signed zAxOrigin, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder, proshade_unsign xGridInds, proshade_unsign yGridInds, proshade_unsign zGridInds, std::string title, int mode )
243 {
244  //================================================ Fill in the map file header
245  map->set_header_i32 ( 1 , static_cast<int32_t> ( xDimInds ) ); // Number of columns in 3D data array (fast axis)
246  map->set_header_i32 ( 2 , static_cast<int32_t> ( yDimInds ) ); // Number of columns in 3D data array (medium axis)
247  map->set_header_i32 ( 3 , static_cast<int32_t> ( zDimInds ) ); // Number of columns in 3D data array (slow axis)
248  map->set_header_i32 ( 4 , static_cast<int32_t> ( mode ) ); // Map mode
249  map->set_header_i32 ( 5 , static_cast<int32_t> ( xFrom ) ); // Starting index (fast axis)
250  map->set_header_i32 ( 6 , static_cast<int32_t> ( yFrom ) ); // Starting index (medium axis)
251  map->set_header_i32 ( 7 , static_cast<int32_t> ( zFrom ) ); // Starting index (slow axis)
252  map->set_header_i32 ( 8 , static_cast<int32_t> ( xGridInds ) ); // Grid sampling (fast axis)
253  map->set_header_i32 ( 9 , static_cast<int32_t> ( yGridInds ) ); // Grid sampling (medium axis)
254  map->set_header_i32 ( 10, static_cast<int32_t> ( zGridInds ) ); // Grid sampling (slow axis)
255  map->set_header_float ( 11, static_cast<float> ( xDim ) ); // Grid dimension in Angstrom (fast axis)
256  map->set_header_float ( 12, static_cast<float> ( yDim ) ); // Grid dimension in Angstrom (medium axis)
257  map->set_header_float ( 13, static_cast<float> ( zDim ) ); // Grid dimension in Angstrom (slow axis)
258  map->set_header_float ( 14, static_cast<float> ( aAng ) ); // Alpha angle in degrees
259  map->set_header_float ( 15, static_cast<float> ( bAng ) ); // Beta angle in degrees
260  map->set_header_float ( 16, static_cast<float> ( cAng ) ); // Gamma angle in degrees
261  map->set_header_i32 ( 17, static_cast<int32_t> ( xAxOrder ) ); // MAPC
262  map->set_header_i32 ( 18, static_cast<int32_t> ( yAxOrder ) ); // MAPR
263  map->set_header_i32 ( 19, static_cast<int32_t> ( zAxOrder ) ); // MAPS
264  if ( map->grid.spacegroup ) { map->set_header_i32 ( 23, static_cast<int32_t> ( map->grid.spacegroup->ccp4 ) ); } // Space group
265  else { map->set_header_i32 ( 23, static_cast<int32_t> ( 1 ) ); }
266  map->set_header_i32 ( 24, static_cast<int32_t> ( map->grid.spacegroup->operations().order() * 80 ) ); // NSYMBT - size of extended header (which follows main header) in bytes
267  map->set_header_str ( 27, "CCP4" ); // Code for the type of extended header
268  map->set_header_i32 ( 28, static_cast<int32_t> ( 20140 ) ); // Version
269  map->set_header_i32 ( 50, static_cast<int32_t> ( xAxOrigin ) ); // Origin of the map (fast axis)
270  map->set_header_i32 ( 51, static_cast<int32_t> ( yAxOrigin ) ); // Origin of the map (medium axis)
271  map->set_header_i32 ( 52, static_cast<int32_t> ( zAxOrigin ) ); // Origin of the map (slow axis)
272  map->set_header_str ( 53, "MAP" ); // File format
273  if ( gemmi::is_little_endian() ) { map->set_header_i32 ( 54, static_cast<int32_t> ( 0x00004144 ) ); } // Machine stamp encoding byte ordering of data
274  else { map->set_header_i32 ( 54, static_cast<int32_t> ( 0x11110000 ) ); }
275  map->set_header_i32 ( 56, static_cast<int32_t> ( 1 ) ); // Number of labels used
276  std::memset ( reinterpret_cast<void*> ( &(map->ccp4_header.at( 56 )) ), ' ', 800 + map->grid.spacegroup->operations().order() * 80); // 56 is used because the vector is indexed from 0
277  map->set_header_str ( 57, title ); // Title
278 
279  //================================================ Done
280  return ;
281 
282 }
283 
292 ProSHADE_internal_io::InputType ProSHADE_internal_io::figureDataType ( std::string fName )
293 {
294  //================================================ Try readin as PDB
295  if ( isFilePDB ( fName ) )
296  {
297  return ( PDB );
298  }
299 
300  //================================================ If not, try readin as MAP
301  if ( isFileMAP ( fName ) )
302  {
303  return ( MAP );
304  }
305 
306  //================================================ No luck? UNKNOWN it is ...
307  return ( UNKNOWN );
308 
309  //================================================ Done
310 
311 }
312 
334 void ProSHADE_internal_io::writeRotationTranslationJSON ( proshade_double trsX1, proshade_double trsY1, proshade_double trsZ1, proshade_double eulA, proshade_double eulB, proshade_double eulG, proshade_double trsX2, proshade_double trsY2, proshade_double trsZ2, std::string fileName )
335 {
336  //================================================ Open file for writing
337  std::ofstream jsonFile;
338  jsonFile.open ( fileName );
339 
340  //================================================ Check file opening success
341  if ( !jsonFile.is_open( ) )
342  {
343  throw ProSHADE_exception ( "Failed to open JSON output file.", "E000056", __FILE__, __LINE__, __func__, "Failed to open json file to which the rotation and\n : translation would be written into. Most likely cause is\n : lack of rights to write in the current folder." );
344  }
345 
346  //================================================ Get rotation matrix from Euler angles
347  proshade_double* rotMat = new proshade_double[9];
348  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
350 
351  //================================================ Write the info
352  jsonFile << "{\n";
353  jsonFile << " \"translationToOrigin\" : [ " << trsX1 << ", " << trsY1 << ", " << trsZ1 << " ], \n";
354 
355  jsonFile << " \"rotationMatrix:\" : [ " << rotMat[0] << ", " << rotMat[1] << ", " << rotMat[2] << ", \n";
356  jsonFile << " " << rotMat[3] << ", " << rotMat[4] << ", " << rotMat[5] << ", \n";
357  jsonFile << " " << rotMat[6] << ", " << rotMat[7] << ", " << rotMat[8] << "], \n";
358 
359  jsonFile << " \"translationFromRotCenToOverlay\" : [ " << trsX2 << ", " << trsY2 << ", " << trsZ2 << " ] \n";
360  jsonFile << "}\n";
361 
362  //================================================ Close file
363  jsonFile.close ( );
364 
365  //================================================ Release memory
366  delete[] rotMat;
367 
368  //================================================ Done
369  return ;
370 
371 }
ProSHADE_internal_io::isFilePDB
bool isFilePDB(std::string fName)
Function determining if the input data type is PDB.
Definition: ProSHADE_io.cpp:32
ProSHADE_exception
This class is the representation of ProSHADE exception.
Definition: ProSHADE_exceptions.hpp:37
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:1005
ProSHADE_internal_io::isFileMAP
bool isFileMAP(std::string fName)
Function determining if the input data type is MAP.
Definition: ProSHADE_io.cpp:57
ProSHADE_internal_io::figureDataType
InputType figureDataType(std::string fName)
Function determining input data type.
Definition: ProSHADE_io.cpp:292
ProSHADE_io.hpp
This header file declares all the functions required for low level file format access.
ProSHADE_internal_io::readInMapData
void readInMapData(gemmi::Ccp4< float > *gemmiMap, proshade_double *&map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder)
This function converts the gemmi Ccp4 object data to ProSHADE internal map representation.
Definition: ProSHADE_io.cpp:172
ProSHADE_internal_io::writeRotationTranslationJSON
void writeRotationTranslationJSON(proshade_double trsX1, proshade_double trsY1, proshade_double trsZ1, proshade_double eulA, proshade_double eulB, proshade_double eulG, proshade_double trsX2, proshade_double trsY2, proshade_double trsZ2, std::string fileName)
Function for writing out the optimal rotation and translation into a JSON file.
Definition: ProSHADE_io.cpp:334
ProSHADE_internal_io::writeOutMapHeader
void writeOutMapHeader(gemmi::Ccp4< float > *map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_single xDim, proshade_single yDim, proshade_single zDim, proshade_single aAng, proshade_single bAng, proshade_single cAng, proshade_signed xFrom, proshade_signed yFrom, proshade_signed zFrom, proshade_signed xAxOrigin, proshade_signed yAxOrigin, proshade_signed zAxOrigin, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder, proshade_unsign xGridInds, proshade_unsign yGridInds, proshade_unsign zGridInds, std::string title, int mode)
This function parses the CCP4 MAP file header as read in by gemmi.
Definition: ProSHADE_io.cpp:242
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:65
ProSHADE_internal_io::readInMapHeader
void readInMapHeader(gemmi::Ccp4< float > *map, proshade_unsign *xDimInds, proshade_unsign *yDimInds, proshade_unsign *zDimInds, proshade_single *xDim, proshade_single *yDim, proshade_single *zDim, proshade_single *aAng, proshade_single *bAng, proshade_single *cAng, proshade_signed *xFrom, proshade_signed *yFrom, proshade_signed *zFrom, proshade_signed *xAxOrigin, proshade_signed *yAxOrigin, proshade_signed *zAxOrigin, proshade_unsign *xAxOrder, proshade_unsign *yAxOrder, proshade_unsign *zAxOrder, proshade_unsign *xGridInds, proshade_unsign *yGridInds, proshade_unsign *zGridInds)
This function parses the CCP4 MAP file header as read in by gemmi.
Definition: ProSHADE_io.cpp:103