ProSHADE  0.7.6.0 (JUL 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  //============================================ Supress MSVC C4101 Unferenced variable warning / clang and gcc -Wunused-exception-parameter
42  (void)e;
43 
44  //============================================ Read failed. Done
45  return ( false );
46  }
47 
48  //================================================ Read successfull. Done
49  return ( true );
50 
51 }
52 
60 bool ProSHADE_internal_io::isFileMAP ( std::string fName )
61 {
62  gemmi::Ccp4<float> map;
63  try
64  {
65  map.read_ccp4 ( gemmi::MaybeGzipped (fName.c_str() ) );
66  }
67  catch ( std::runtime_error& e )
68  {
69  //============================================ Supress MSVC C4101 Unferenced variable warning / clang and gcc -Wunused-exception-parameter
70  (void)e;
71 
72  //============================================ Failed to read the map
73  return ( false );
74  }
75 
76  //================================================ Done
77  return ( true );
78 
79 }
80 
109 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 )
110 {
111  //================================================ Read in the map file header
112  *xDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 1 ) );
113  *yDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 2 ) );
114  *zDimInds = static_cast<proshade_unsign> ( map->header_i32 ( 3 ) );
115 
116  *xFrom = static_cast<proshade_signed> ( map->header_i32 ( 5 ) );
117  *yFrom = static_cast<proshade_signed> ( map->header_i32 ( 6 ) );
118  *zFrom = static_cast<proshade_signed> ( map->header_i32 ( 7 ) );
119 
120  *xDim = static_cast<proshade_single> ( map->header_float ( 11 ) );
121  *yDim = static_cast<proshade_single> ( map->header_float ( 12 ) );
122  *zDim = static_cast<proshade_single> ( map->header_float ( 13 ) );
123 
124  *aAng = static_cast<proshade_single> ( map->header_float ( 14 ) );
125  *bAng = static_cast<proshade_single> ( map->header_float ( 15 ) );
126  *cAng = static_cast<proshade_single> ( map->header_float ( 16 ) );
127 
128  *xAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 50 ) ) + (*xFrom);
129  *yAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 51 ) ) + (*yFrom);
130  *zAxOrigin = static_cast<proshade_signed> ( map->header_i32 ( 52 ) ) + (*zFrom);
131 
132  *xAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 17 ) );
133  *yAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 18 ) );
134  *zAxOrder = static_cast<proshade_unsign> ( map->header_i32 ( 19 ) );
135 
136  *xGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 8 ) );
137  *yGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 9 ) );
138  *zGridInds = static_cast<proshade_unsign> ( map->header_i32 ( 10 ) );
139 
140  //================================================ Deal with sampling being different from cell size
141  if ( *xGridInds != *xDimInds )
142  {
143  *xDim = *xDim * ( static_cast<proshade_single> ( *xDimInds ) / static_cast<proshade_single> ( *xGridInds ) );
144  *xGridInds = *xDimInds;
145  }
146 
147  if ( *yGridInds != *yDimInds )
148  {
149  *yDim = *yDim * ( static_cast<proshade_single> ( *yDimInds ) / static_cast<proshade_single> ( *yGridInds ) );
150  *yGridInds = *yDimInds;
151  }
152 
153  if ( *zGridInds != *zDimInds )
154  {
155  *zDim = *zDim * ( static_cast<proshade_single> ( *zDimInds ) / static_cast<proshade_single> ( *zGridInds ) );
156  *zGridInds = *zDimInds;
157  }
158 
159  //================================================ Done
160  return ;
161 
162 }
163 
178 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 )
179 {
180  //================================================ Allocate internal variables
181  proshade_unsign *axOrdArr = new proshade_unsign[3];
182  proshade_unsign *axDimArr = new proshade_unsign[3];
183  proshade_unsign arrPos = 0;
184 
185  //================================================ Check memory allocation and fill in values
186  ProSHADE_internal_misc::checkMemoryAllocation ( axOrdArr, __FILE__, __LINE__, __func__ );
187  ProSHADE_internal_misc::checkMemoryAllocation ( axDimArr, __FILE__, __LINE__, __func__ );
188  axDimArr[0] = xDimInds;
189  axDimArr[1] = yDimInds;
190  axDimArr[2] = zDimInds;
191 
192  //================================================ Allocate the ProSHADE internal map variable memory
193  map = new proshade_double [xDimInds * yDimInds * zDimInds];
194  ProSHADE_internal_misc::checkMemoryAllocation ( map, __FILE__, __LINE__, __func__ );
195 
196  //================================================ Copy read in data to internal map variable
197  for ( axOrdArr[0] = 0; axOrdArr[0] < axDimArr[xAxOrder-1]; axOrdArr[0]++ )
198  {
199  for ( axOrdArr[1] = 0; axOrdArr[1] < axDimArr[yAxOrder-1]; axOrdArr[1]++ )
200  {
201  for ( axOrdArr[2] = 0; axOrdArr[2] < axDimArr[zAxOrder-1]; axOrdArr[2]++ )
202  {
203  arrPos = axOrdArr[2] + axDimArr[zAxOrder-1] * ( axOrdArr[1] + axDimArr[yAxOrder-1] * axOrdArr[0] );
204  map[arrPos] = static_cast< proshade_double > ( gemmiMap->grid.get_value_q( static_cast< int > ( axOrdArr[xAxOrder-1] ),
205  static_cast< int > ( axOrdArr[yAxOrder-1] ),
206  static_cast< int > ( axOrdArr[zAxOrder-1] ) ) );
207  }
208  }
209  }
210 
211  //================================================ Release internal variables memory
212  delete[] axDimArr;
213  delete[] axOrdArr;
214 
215  //================================================ Done
216  return ;
217 
218 }
219 
234 void ProSHADE_internal_io::readInMapData ( gemmi::Ccp4<int8_t> *gemmiMap, proshade_double*& map, proshade_unsign xDimInds, proshade_unsign yDimInds, proshade_unsign zDimInds, proshade_unsign xAxOrder, proshade_unsign yAxOrder, proshade_unsign zAxOrder )
235 {
236  //================================================ Allocate internal variables
237  proshade_unsign *axOrdArr = new proshade_unsign[3];
238  proshade_unsign *axDimArr = new proshade_unsign[3];
239  proshade_unsign arrPos = 0;
240 
241  //================================================ Check memory allocation and fill in values
242  ProSHADE_internal_misc::checkMemoryAllocation ( axOrdArr, __FILE__, __LINE__, __func__ );
243  ProSHADE_internal_misc::checkMemoryAllocation ( axDimArr, __FILE__, __LINE__, __func__ );
244  axDimArr[0] = xDimInds;
245  axDimArr[1] = yDimInds;
246  axDimArr[2] = zDimInds;
247 
248  //================================================ Allocate the ProSHADE internal map variable memory
249  map = new proshade_double [xDimInds * yDimInds * zDimInds];
250  ProSHADE_internal_misc::checkMemoryAllocation ( map, __FILE__, __LINE__, __func__ );
251 
252  //================================================ Copy read in data to internal map variable
253  for ( axOrdArr[0] = 0; axOrdArr[0] < axDimArr[xAxOrder-1]; axOrdArr[0]++ )
254  {
255  for ( axOrdArr[1] = 0; axOrdArr[1] < axDimArr[yAxOrder-1]; axOrdArr[1]++ )
256  {
257  for ( axOrdArr[2] = 0; axOrdArr[2] < axDimArr[zAxOrder-1]; axOrdArr[2]++ )
258  {
259  arrPos = axOrdArr[2] + axDimArr[zAxOrder-1] * ( axOrdArr[1] + axDimArr[yAxOrder-1] * axOrdArr[0] );
260  map[arrPos] = static_cast< proshade_double > ( gemmiMap->grid.get_value_q( static_cast< int > ( axOrdArr[xAxOrder-1] ),
261  static_cast< int > ( axOrdArr[yAxOrder-1] ),
262  static_cast< int > ( axOrdArr[zAxOrder-1] ) ) );
263  }
264  }
265  }
266 
267  //================================================ Release internal variables memory
268  delete[] axDimArr;
269  delete[] axOrdArr;
270 
271  //================================================ Done
272  return ;
273 
274 }
275 
306 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 )
307 {
308  //================================================ Fill in the map file header
309  map->set_header_i32 ( 1 , static_cast<int32_t> ( xDimInds ) ); // Number of columns in 3D data array (fast axis)
310  map->set_header_i32 ( 2 , static_cast<int32_t> ( yDimInds ) ); // Number of columns in 3D data array (medium axis)
311  map->set_header_i32 ( 3 , static_cast<int32_t> ( zDimInds ) ); // Number of columns in 3D data array (slow axis)
312  map->set_header_i32 ( 4 , static_cast<int32_t> ( mode ) ); // Map mode
313  map->set_header_i32 ( 5 , static_cast<int32_t> ( xFrom ) ); // Starting index (fast axis)
314  map->set_header_i32 ( 6 , static_cast<int32_t> ( yFrom ) ); // Starting index (medium axis)
315  map->set_header_i32 ( 7 , static_cast<int32_t> ( zFrom ) ); // Starting index (slow axis)
316  map->set_header_i32 ( 8 , static_cast<int32_t> ( xGridInds ) ); // Grid sampling (fast axis)
317  map->set_header_i32 ( 9 , static_cast<int32_t> ( yGridInds ) ); // Grid sampling (medium axis)
318  map->set_header_i32 ( 10, static_cast<int32_t> ( zGridInds ) ); // Grid sampling (slow axis)
319  map->set_header_float ( 11, static_cast<float> ( xDim ) ); // Grid dimension in Angstrom (fast axis)
320  map->set_header_float ( 12, static_cast<float> ( yDim ) ); // Grid dimension in Angstrom (medium axis)
321  map->set_header_float ( 13, static_cast<float> ( zDim ) ); // Grid dimension in Angstrom (slow axis)
322  map->set_header_float ( 14, static_cast<float> ( aAng ) ); // Alpha angle in degrees
323  map->set_header_float ( 15, static_cast<float> ( bAng ) ); // Beta angle in degrees
324  map->set_header_float ( 16, static_cast<float> ( cAng ) ); // Gamma angle in degrees
325  map->set_header_i32 ( 17, static_cast<int32_t> ( xAxOrder ) ); // MAPC
326  map->set_header_i32 ( 18, static_cast<int32_t> ( yAxOrder ) ); // MAPR
327  map->set_header_i32 ( 19, static_cast<int32_t> ( zAxOrder ) ); // MAPS
328  if ( map->grid.spacegroup ) { map->set_header_i32 ( 23, static_cast<int32_t> ( map->grid.spacegroup->ccp4 ) ); } // Space group
329  else { map->set_header_i32 ( 23, static_cast<int32_t> ( 1 ) ); }
330  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
331  map->set_header_str ( 27, "CCP4" ); // Code for the type of extended header
332  map->set_header_i32 ( 28, static_cast<int32_t> ( 20140 ) ); // Version
333  map->set_header_i32 ( 50, static_cast<int32_t> ( xAxOrigin ) ); // Origin of the map (fast axis)
334  map->set_header_i32 ( 51, static_cast<int32_t> ( yAxOrigin ) ); // Origin of the map (medium axis)
335  map->set_header_i32 ( 52, static_cast<int32_t> ( zAxOrigin ) ); // Origin of the map (slow axis)
336  map->set_header_str ( 53, "MAP" ); // File format
337  if ( gemmi::is_little_endian() ) { map->set_header_i32 ( 54, static_cast<int32_t> ( 0x00004144 ) ); } // Machine stamp encoding byte ordering of data
338  else { map->set_header_i32 ( 54, static_cast<int32_t> ( 0x11110000 ) ); }
339  map->set_header_i32 ( 56, static_cast<int32_t> ( 1 ) ); // Number of labels used
340  std::memset ( reinterpret_cast<void*> ( &(map->ccp4_header.at( 56 )) ), ' ', static_cast< size_t > ( 800 + map->grid.spacegroup->operations().order() * 80 ) ); // 56 is used because the vector is indexed from 0
341  map->set_header_str ( 57, title ); // Title
342 
343  //================================================ Done
344  return ;
345 
346 }
347 
356 ProSHADE_internal_io::InputType ProSHADE_internal_io::figureDataType ( std::string fName )
357 {
358  //================================================ Try readin as PDB
359  if ( isFilePDB ( fName ) )
360  {
361  return ( PDB );
362  }
363 
364  //================================================ If not, try readin as MAP
365  if ( isFileMAP ( fName ) )
366  {
367  return ( MAP );
368  }
369 
370  //================================================ No luck? UNKNOWN it is ...
371  return ( UNKNOWN );
372 
373  //================================================ Done
374 
375 }
376 
398 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 )
399 {
400  //================================================ Open file for writing
401  std::ofstream jsonFile;
402  jsonFile.open ( fileName );
403 
404  //================================================ Check file opening success
405  if ( !jsonFile.is_open( ) )
406  {
407  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." );
408  }
409 
410  //================================================ Get rotation matrix from Euler angles
411  proshade_double* rotMat = new proshade_double[9];
412  ProSHADE_internal_misc::checkMemoryAllocation ( rotMat, __FILE__, __LINE__, __func__ );
414 
415  //================================================ Write the info
416  jsonFile << "{\n";
417  jsonFile << " \"translationToOrigin\" : [ " << trsX1 << ", " << trsY1 << ", " << trsZ1 << " ], \n";
418 
419  jsonFile << " \"rotationMatrix:\" : [ " << rotMat[0] << ", " << rotMat[1] << ", " << rotMat[2] << ", \n";
420  jsonFile << " " << rotMat[3] << ", " << rotMat[4] << ", " << rotMat[5] << ", \n";
421  jsonFile << " " << rotMat[6] << ", " << rotMat[7] << ", " << rotMat[8] << "], \n";
422 
423  jsonFile << " \"translationFromRotCenToOverlay\" : [ " << trsX2 << ", " << trsY2 << ", " << trsZ2 << " ] \n";
424  jsonFile << "}\n";
425 
426  //================================================ Close file
427  jsonFile.close ( );
428 
429  //================================================ Release memory
430  delete[] rotMat;
431 
432  //================================================ Done
433  return ;
434 
435 }
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:1011
ProSHADE_internal_io::isFileMAP
bool isFileMAP(std::string fName)
Function determining if the input data type is MAP.
Definition: ProSHADE_io.cpp:60
ProSHADE_internal_io::figureDataType
InputType figureDataType(std::string fName)
Function determining input data type.
Definition: ProSHADE_io.cpp:356
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:178
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:398
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:306
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:67
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:109