Xmipp  v3.23.11-Nereus
Classes | Macros | Functions | Variables
pdb.cpp File Reference
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include "cif++.hpp"
#include "pdb.h"
#include "core/matrix2d.h"
#include "core/multidim_array.h"
#include "core/transformations.h"
#include "core/xmipp_fftw.h"
#include "core/xmipp_strings.h"
#include "data/fourier_projection.h"
#include "data/integration.h"
#include "data/mask.h"
#include "data/numerical_tools.h"
Include dependency graph for pdb.cpp:

Go to the source code of this file.

Classes

class  AtomValueFunc
 

Macros

#define IOTBX_PDB_HYBRID_36_C_H
 
#define HY36_WIDTH_4_MIN   -999
 
#define HY36_WIDTH_4_MAX   2436111 /* 10000 + 2*26*36*36*36 - 1 */
 
#define HY36_WIDTH_5_MIN   -9999
 
#define HY36_WIDTH_5_MAX   87440031 /* 100000 + 2*26*36*36*36*36 - 1 */
 
#define INTEGRATION   2
 

Functions

void analyzePDBAtoms (const FileName &fn_pdb, const std::string &typeOfAtom, int &numberOfAtoms, pdbInfo &at_pos)
 
int atomCharge (const std::string &atom)
 
double atomRadius (const std::string &atom)
 
double atomCovalentRadius (const std::string &atom)
 
void computePDBgeometry (const std::string &fnPDB, Matrix1D< double > &centerOfMass, Matrix1D< double > &limit0, Matrix1D< double > &limitF, const std::string &intensityColumn)
 
void applyGeometryToPDBFile (const std::string &fn_in, const std::string &fn_out, const Matrix2D< double > &A, bool centerPDB, const std::string &intensityColumn)
 
bool checkExtension (const std::filesystem::path &filePath, const std::list< std::string > &acceptedExtensions, const std::list< std::string > &acceptedCompressions)
 Checks if the file uses a supported extension type. More...
 
template<typename callable >
void readPDB (const FileName &fnPDB, const callable &addAtom)
 Read phantom from PDB. More...
 
template<typename callable >
void readCIF (const std::string &fnCIF, const callable &addAtom, cif::datablock &dataBlock)
 Read phantom from CIF. More...
 
template<typename callable >
void readRichPDB (const FileName &fnPDB, const callable &addAtom, std::vector< double > &intensities, std::vector< std::string > &remarks, const bool pseudoatoms, const double threshold)
 Read rich phantom from either a PDB of CIF file. More...
 
template<typename callable >
void readRichCIF (const std::string &fnCIF, const callable &addAtom, std::vector< double > &intensities, const bool pseudoatoms, const double threshold, cif::datablock &dataBlock)
 Read rich phantom from CIF. More...
 
template<typename callable >
void writePDB (const FileName &fnPDB, bool renumber, const std::vector< std::string > &remarks, const callable &atomList)
 Write rich phantom to PDB file. More...
 
template<typename callable >
void writeCIF (const std::string &fnCIF, const callable &atomList, cif::datablock &dataBlock)
 Write rich phantom to CIF file. More...
 
void atomDescriptors (const std::string &atom, Matrix1D< double > &descriptors)
 
double electronFormFactorFourier (double f, const Matrix1D< double > &descriptors)
 
double electronFormFactorRealSpace (double r, const Matrix1D< double > &descriptors)
 
void hlpf (MultidimArray< double > &f, int M, const std::string &filterType, MultidimArray< double > &filter, double reductionFactor=0.8, double ripple=0.01, double deltaw=1.0/8.0)
 
void fhlpf (const MultidimArray< double > &f, const MultidimArray< double > &filter, int M, MultidimArray< double > &convolution)
 
double Hlpf_fitness (double *p, void *prm)
 
void optimizeHlpf (MultidimArray< double > &f, int M, double T, const std::string &atom, MultidimArray< double > &filter, Matrix1D< double > &bestPrm)
 
void atomRadialProfile (int M, double T, const std::string &atom, MultidimArray< double > &profile)
 
void atomProjectionRadialProfile (int M, const MultidimArray< double > &profileCoefficients, MultidimArray< double > &projectionProfile)
 
void projectAtom (const Atom &atom, Projection &P, const Matrix2D< double > &VP, const Matrix2D< double > &PV, const AtomInterpolator &interpolator)
 
void projectPDB (const PDBPhantom &phantomPDB, const AtomInterpolator &interpolator, Projection &proj, int Ydim, int Xdim, double rot, double tilt, double psi)
 
void distanceHistogramPDB (const PDBPhantom &phantomPDB, size_t Nnearest, double maxDistance, int Nbins, Histogram1D &hist)
 
const char * hy36encode (unsigned width, int value, char *result)
 
const char * hy36decode (unsigned width, const char *s, unsigned s_size, int *result)
 
void hy36decodeSafe (unsigned width, const char *s, unsigned s_size, int *result)
 
void hy36encodeSafe (unsigned width, int value, char *result)
 

Variables

Matrix1D< double > globalHlpfPrm (3)
 
MultidimArray< double > globalf
 
int globalM
 
double globalT
 
std::string globalAtom
 

Macro Definition Documentation

◆ HY36_WIDTH_4_MAX

#define HY36_WIDTH_4_MAX   2436111 /* 10000 + 2*26*36*36*36 - 1 */

Definition at line 55 of file pdb.cpp.

◆ HY36_WIDTH_4_MIN

#define HY36_WIDTH_4_MIN   -999

Definition at line 54 of file pdb.cpp.

◆ HY36_WIDTH_5_MAX

#define HY36_WIDTH_5_MAX   87440031 /* 100000 + 2*26*36*36*36*36 - 1 */

Definition at line 57 of file pdb.cpp.

◆ HY36_WIDTH_5_MIN

#define HY36_WIDTH_5_MIN   -9999

Definition at line 56 of file pdb.cpp.

◆ INTEGRATION

#define INTEGRATION   2

Definition at line 1362 of file pdb.cpp.

◆ IOTBX_PDB_HYBRID_36_C_H

#define IOTBX_PDB_HYBRID_36_C_H

Definition at line 48 of file pdb.cpp.

Function Documentation

◆ atomProjectionRadialProfile()

void atomProjectionRadialProfile ( int  M,
const MultidimArray< double > &  profileCoefficients,
MultidimArray< double > &  projectionProfile 
)

Definition at line 1363 of file pdb.cpp.

1366 {
1367  AtomValueFunc atomValue;
1368  atomValue.profileCoefficients=&profileCoefficients;
1369  atomValue.M=M;
1370  double radius=(double)FINISHINGX(profileCoefficients)/M;
1371  double r2=radius*radius;
1372 
1373  projectionProfile.initZeros(profileCoefficients);
1374  FOR_ALL_ELEMENTS_IN_ARRAY1D(projectionProfile)
1375  {
1376  double r0=(double)i/M;
1377  atomValue.r0_2=r0*r0;
1378  if (atomValue.r0_2>r2)
1379  continue; // Because of numerical instabilities
1380 
1381  double maxZ=sqrt(r2-atomValue.r0_2);
1382 
1383 #if INTEGRATION==1
1384 
1385  double dz=1/24.0;
1386  double integral=0;
1387  for (atomValue.z=-maxZ; atomValue.z<=maxZ; atomValue.z+=dz)
1388  {
1389  projectionProfile(i)+=atomValue();
1390  }
1391  projectionProfile(i)*=dz;
1392 #else
1393 
1394  Romberg Rom(atomValue, atomValue.z,-maxZ,maxZ);
1395  projectionProfile(i) = Rom();
1396 #endif
1397 
1398  }
1399 }
#define FINISHINGX(v)
double z
Definition: pdb.cpp:1351
void sqrt(Image< double > &op)
#define i
double r0_2
Definition: pdb.cpp:1350
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
const MultidimArray< double > * profileCoefficients
Definition: pdb.cpp:1352
float r2
void initZeros(const MultidimArray< T1 > &op)
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115

◆ atomRadialProfile()

void atomRadialProfile ( int  M,
double  T,
const std::string &  atom,
MultidimArray< double > &  profile 
)

Definition at line 1306 of file pdb.cpp.

1308 {
1309  // Compute the electron form factor in real space
1310  double largestb1=76.7309/(4*PI*PI);
1311  double Rmax=4*sqrt(2*largestb1);
1312  auto imax=(int)CEIL(Rmax/T);
1313  Matrix1D<double> descriptors;
1314  atomDescriptors(atom, descriptors);
1315  MultidimArray<double> f(2*imax+1);
1316  f.setXmippOrigin();
1317  for (int i=-imax; i<=imax; i++)
1318  {
1319  double r=i*T;
1320  f(i)=electronFormFactorRealSpace(r,descriptors);
1321  }
1322 
1323  // Compute the optimal filter
1324  MultidimArray<double> filter;
1325  Matrix1D<double> bestPrm;
1326  optimizeHlpf(f, M, T, atom, filter, bestPrm);
1327 
1328  // Perform the convolution
1329  fhlpf(f, filter, M, profile);
1330 
1331  // Remove zero values
1332  int ileft=STARTINGX(profile);
1333  if (fabs(profile(ileft))<1e-3)
1334  for (ileft=STARTINGX(profile)+1; ileft<=0; ileft++)
1335  if (fabs(profile(ileft))>1e-3)
1336  break;
1337  int iright=FINISHINGX(profile);
1338  if (fabs(profile(iright))<1e-3)
1339  for (iright=FINISHINGX(profile)-1; iright>=0; iright--)
1340  if (fabs(profile(iright))>1e-3)
1341  break;
1342  profile.selfWindow(ileft,iright);
1343 }
void selfWindow(int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T init_value=0)
double electronFormFactorRealSpace(double r, const Matrix1D< double > &descriptors)
Definition: pdb.cpp:1087
#define FINISHINGX(v)
void sqrt(Image< double > &op)
#define STARTINGX(v)
#define i
#define CEIL(x)
Definition: xmipp_macros.h:225
double * f
void atomDescriptors(const std::string &atom, Matrix1D< double > &descriptors)
Definition: pdb.cpp:883
void optimizeHlpf(MultidimArray< double > &f, int M, double T, const std::string &atom, MultidimArray< double > &filter, Matrix1D< double > &bestPrm)
Definition: pdb.cpp:1285
void fhlpf(const MultidimArray< double > &f, const MultidimArray< double > &filter, int M, MultidimArray< double > &convolution)
Definition: pdb.cpp:1134
#define PI
Definition: tools.h:43

◆ checkExtension()

bool checkExtension ( const std::filesystem::path &  filePath,
const std::list< std::string > &  acceptedExtensions,
const std::list< std::string > &  acceptedCompressions 
)

Checks if the file uses a supported extension type.

This function checks if the given file path has one of the given supported extensions, with or without compression in any of the accepted compressions.

Parameters
filePathFile including path.
acceptedExtensionsList of accepted extensions.
acceptedCompressionsList of accepted compressions.
Returns
true if the extension is valid, false otherwise.

Definition at line 384 of file pdb.cpp.

384  {
385  // File extension is invalid by default
386  bool validExtension = false;
387 
388  // Checking if file extension is in accepted extensions with or without an accepted compression
389  if (find(acceptedExtensions.begin(), acceptedExtensions.end(), filePath.extension()) != acceptedExtensions.end()) {
390  // Accepted extension without compression
391  validExtension = true;
392  } else {
393  if (find(acceptedCompressions.begin(), acceptedCompressions.end(), filePath.extension()) != acceptedCompressions.end()) {
394  // Accepted compression detected
395  // Checking if next extension is valid
396  const std::filesystem::path shortedPath = filePath.parent_path().u8string() + "/" + filePath.stem().u8string();
397  if (find(acceptedExtensions.begin(), acceptedExtensions.end(), shortedPath.extension()) != acceptedExtensions.end()) {
398  // Accepted extension with compression
399  validExtension = true;
400  }
401  }
402  }
403 
404  // Returning calculated validity
405  return validExtension;
406 }
std::vector< SelLine >::iterator find(std::vector< SelLine > &text, const std::string &img_name)
Definition: selfile.cpp:553

◆ fhlpf()

void fhlpf ( const MultidimArray< double > &  f,
const MultidimArray< double > &  filter,
int  M,
MultidimArray< double > &  convolution 
)

Definition at line 1134 of file pdb.cpp.

1136 {
1137  // Expand the two input signals
1138  int Nmax=FINISHINGX(filter);
1139  MultidimArray<double> auxF;
1140  MultidimArray<double> auxFilter;
1141  auxF=f;
1142  auxFilter=filter;
1143  auxF.selfWindow(STARTINGX(f)-Nmax,FINISHINGX(f)+Nmax);
1144  auxFilter.selfWindow(STARTINGX(filter)-Nmax,FINISHINGX(filter)+Nmax);
1145 
1146  // Convolve in Fourier
1149  FourierTransform(auxF,F);
1150  FourierTransform(auxFilter,Filter);
1151  F*=Filter;
1152 
1153  // Correction for the double phase factor and the double
1154  // amplitude factor
1155  const double K1=2*PI*(STARTINGX(auxFilter)-1);
1156  const double K2=XSIZE(auxFilter);
1157  std::complex<double> aux;
1158  auto * ptrAux=(double*)&aux;
1160  {
1161  double w;
1162  FFT_IDX2DIGFREQ(i,XSIZE(F),w);
1163  double arg=w*K1;
1164  sincos(arg,ptrAux+1,ptrAux);
1165  *ptrAux*=K2;
1166  *(ptrAux+1)*=K2;
1167  A1D_ELEM(F,i)*=aux;
1168  }
1169  InverseFourierTransform(F,convolution);
1170  convolution.setXmippOrigin();
1171 }
void selfWindow(int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T init_value=0)
#define FINISHINGX(v)
#define A1D_ELEM(v, i)
doublereal * w
void InverseFourierTransform(const MultidimArray< std::complex< double > > &in, MultidimArray< double > &out)
Definition: xmipp_fft.cpp:155
#define STARTINGX(v)
#define i
double * f
#define XSIZE(v)
void sincos(const MultidimArray< double > &x, MultidimArray< double > &s, MultidimArray< double > &c)
void FourierTransform(const MultidimArray< double > &in, MultidimArray< std::complex< double > > &out)
Definition: xmipp_fft.cpp:124
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
#define PI
Definition: tools.h:43

◆ hlpf()

void hlpf ( MultidimArray< double > &  f,
int  M,
const std::string &  filterType,
MultidimArray< double > &  filter,
double  reductionFactor = 0.8,
double  ripple = 0.01,
double  deltaw = 1.0/8.0 
)

Definition at line 1104 of file pdb.cpp.

1107 {
1108  filter.initZeros(XSIZE(f));
1109  filter.setXmippOrigin();
1110 
1111  auto Nmax=(int)CEIL(M/2.0);
1112  if (filterType=="SimpleAveraging")
1113  {
1115  if (ABS(i)<=Nmax)
1116  filter(i)=1.0/(2*Nmax+1);
1117  }
1118  else if (filterType=="SincKaiser")
1119  {
1120  int lastIdx=FINISHINGX(filter);
1121  SincKaiserMask(filter,reductionFactor*PI/M,ripple,deltaw);
1122  int newLastIdx=FINISHINGX(filter);
1123  if (newLastIdx>3*lastIdx)
1124  filter.selfWindow(-lastIdx,lastIdx);
1125  filter/=filter.sum();
1126  if (FINISHINGX(f)>FINISHINGX(filter))
1127  filter.selfWindow(STARTINGX(f),FINISHINGX(f));
1128  else
1129  f.selfWindow(STARTINGX(filter),FINISHINGX(filter));
1130  }
1131 }
void selfWindow(int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T init_value=0)
#define FINISHINGX(v)
#define STARTINGX(v)
#define i
#define CEIL(x)
Definition: xmipp_macros.h:225
#define XSIZE(v)
#define ABS(x)
Definition: xmipp_macros.h:142
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
void initZeros(const MultidimArray< T1 > &op)
#define PI
Definition: tools.h:43
double sum() const
void SincKaiserMask(MultidimArray< double > &mask, double omega, double delta, double Deltaw)
Definition: mask.cpp:139

◆ Hlpf_fitness()

double Hlpf_fitness ( double *  p,
void *  prm 
)

Definition at line 1181 of file pdb.cpp.

1182 {
1183  double reductionFactor=p[1];
1184  double ripple=p[2];
1185  double deltaw=p[3];
1186 
1187  if (reductionFactor<0.7 || reductionFactor>1.3)
1188  return 1e38;
1189  if (ripple<0 || ripple>0.2)
1190  return 1e38;
1191  if (deltaw<1e-3 || deltaw>0.2)
1192  return 1e38;
1193 
1194  // Construct the filter with the current parameters
1195  MultidimArray<double> filter;
1196  MultidimArray<double> auxf;
1197  auxf=globalf;
1198  hlpf(auxf, globalM, "SincKaiser", filter, reductionFactor,
1199  ripple, deltaw);
1200 
1201  // Convolve the filter with the atomic profile
1202  MultidimArray<double> fhlpfFinelySampled;
1203  fhlpf(auxf, filter, globalM, fhlpfFinelySampled);
1204 
1205  // Coarsely sample
1206  double Rmax=FINISHINGX(fhlpfFinelySampled)*globalT;
1207  int imax=CEIL(Rmax/(globalM*globalT));
1208  MultidimArray<double> fhlpfCoarselySampled(2*imax+1);
1209  MultidimArray<double> splineCoeffsfhlpfFinelySampled;
1210  produceSplineCoefficients(xmipp_transformation::BSPLINE3,splineCoeffsfhlpfFinelySampled,fhlpfFinelySampled);
1211  fhlpfCoarselySampled.setXmippOrigin();
1212  FOR_ALL_ELEMENTS_IN_ARRAY1D(fhlpfCoarselySampled)
1213  {
1214  double r=i*(globalM*globalT)/globalT;
1215  fhlpfCoarselySampled(i)=
1216  splineCoeffsfhlpfFinelySampled.interpolatedElementBSpline1D(r,3);
1217  }
1218 
1219  // Build the frequency response of the convolved and coarsely sampled
1220  // atom
1222  MultidimArray<double> FfilterMag;
1223  MultidimArray<double> freq;
1225  aux=fhlpfCoarselySampled;
1226  aux.selfWindow(-10*FINISHINGX(aux),10*FINISHINGX(aux));
1227  FourierTransform(aux,Ffilter);
1228  FFT_magnitude(Ffilter,FfilterMag);
1229  freq.initZeros(XSIZE(Ffilter));
1230 
1231  FOR_ALL_ELEMENTS_IN_ARRAY1D(FfilterMag)
1232  FFT_IDX2DIGFREQ(i,XSIZE(FfilterMag),freq(i));
1233  freq/=globalM*globalT;
1234  double amplitudeFactor=fhlpfFinelySampled.sum()/
1235  fhlpfCoarselySampled.sum();
1236 
1237  // Compute the error in representation
1238  double error=0;
1239  Matrix1D<double> descriptors;
1240  atomDescriptors(globalAtom, descriptors);
1241  double iglobalT=1.0/globalT;
1242 #ifdef DEBUG
1243  MultidimArray<double> f1array, f2array;
1244  f1array.initZeros(FfilterMag);
1245  f2array.initZeros(FfilterMag);
1246 #endif
1247  double Npoints=0;
1248  FOR_ALL_ELEMENTS_IN_ARRAY1D(FfilterMag)
1249  if (A1D_ELEM(freq,i)>=0)
1250  {
1251  double f1=log10(A1D_ELEM(FfilterMag,i)*XSIZE(FfilterMag)*amplitudeFactor);
1252  double f2=log10(iglobalT*
1253  electronFormFactorFourier(A1D_ELEM(freq,i),descriptors));
1254  Npoints++;
1255  double diff=(f1-f2);
1256  error+=diff*diff;
1257 #ifdef DEBUG
1258  f1array(i)=f1;
1259  f2array(i)=f2;
1260  std::cout << "i=" << i << " wi=" << A1D_ELEM(freq,i) << " f1=" << f1 << " f2=" << f2 << " diff=" << diff << " err2=" << diff*diff << std::endl;
1261 #endif
1262  }
1263 #ifdef DEBUG
1264  f1array.write("PPPf1.txt");
1265  f2array.write("PPPf2.txt");
1266  std::cout << "Error " << error/Npoints << " " << Npoints << " M=" << globalM << " T=" << globalT << std::endl;
1267 #endif
1268 
1269  return error/Npoints;
1270 }
void selfWindow(int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T init_value=0)
T interpolatedElementBSpline1D(double x, int SplineDegree=3) const
#define FINISHINGX(v)
void hlpf(MultidimArray< double > &f, int M, const std::string &filterType, MultidimArray< double > &filter, double reductionFactor=0.8, double ripple=0.01, double deltaw=1.0/8.0)
Definition: pdb.cpp:1104
MultidimArray< double > globalf
Definition: pdb.cpp:1175
#define A1D_ELEM(v, i)
#define i
int globalM
Definition: pdb.cpp:1176
#define CEIL(x)
Definition: xmipp_macros.h:225
void produceSplineCoefficients(int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
#define XSIZE(v)
void write(const FileName &fn) const
double globalT
Definition: pdb.cpp:1177
void log10(Image< double > &op)
void FourierTransform(const MultidimArray< double > &in, MultidimArray< std::complex< double > > &out)
Definition: xmipp_fft.cpp:124
double electronFormFactorFourier(double f, const Matrix1D< double > &descriptors)
Definition: pdb.cpp:1059
void atomDescriptors(const std::string &atom, Matrix1D< double > &descriptors)
Definition: pdb.cpp:883
__device__ float FFT_IDX2DIGFREQ(int idx, int size)
void fhlpf(const MultidimArray< double > &f, const MultidimArray< double > &filter, int M, MultidimArray< double > &convolution)
Definition: pdb.cpp:1134
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
void initZeros(const MultidimArray< T1 > &op)
void FFT_magnitude(const MultidimArray< std::complex< double > > &v, MultidimArray< double > &mag)
Definition: xmipp_fftw.cpp:393
double sum() const
std::string globalAtom
Definition: pdb.cpp:1178

◆ hy36decode()

const char* hy36decode ( unsigned  width,
const char *  s,
unsigned  s_size,
int *  result 
)

hybrid-36 decoder: converts string s to integer result width: must be 4 (e.g. for residue sequence numbers) or 5 (e.g. for atom serial numbers) s: string to be converted does not have to be null-terminated s_size: size of s must be equal to width, or an error message is returned otherwise result: integer holding the conversion result return value: pointer to error message, if any, or 0 on success Example usage (from C++): int result; const char* errmsg = hy36decode(width, "A1T5", 4, &result); if (errmsg) throw std::runtime_error(errmsg);

Definition at line 1892 of file pdb.cpp.

1893 {
1894  static int first_call = 1;
1895  static int digits_values_upper[128U];
1896  static int digits_values_lower[128U];
1897  static const char*
1898  ie_range = "internal error hy36decode: integer value out of range.";
1899  unsigned i;
1900  int di;
1901  const char* errmsg;
1902  if (first_call) {
1903  first_call = 0;
1904  for(i=0;i<128U;i++) digits_values_upper[i] = -1;
1905  for(i=0;i<128U;i++) digits_values_lower[i] = -1;
1906  for(i=0;i<36U;i++) {
1907  di = digits_upper()[i];
1908  if (di < 0 || di > 127) {
1909  *result = 0;
1910  return ie_range;
1911  }
1912  digits_values_upper[di] = i;
1913  }
1914  for(i=0;i<36U;i++) {
1915  di = digits_lower()[i];
1916  if (di < 0 || di > 127) {
1917  *result = 0;
1918  return ie_range;
1919  }
1920  digits_values_lower[di] = i;
1921  }
1922  }
1923  if (s_size == width) {
1924  di = s[0];
1925  if (di >= 0 && di <= 127) {
1926  if (digits_values_upper[di] >= 10) {
1927  errmsg = decode_pure(digits_values_upper, 36U, s, s_size, result);
1928  if (errmsg == 0) {
1929  /* result - 10*36**(width-1) + 10**width */
1930  if (width == 4U) (*result) -= 456560;
1931  else if (width == 5U) (*result) -= 16696160;
1932  else {
1933  *result = 0;
1934  return unsupported_width();
1935  }
1936  return 0;
1937  }
1938  }
1939  else if (digits_values_lower[di] >= 10) {
1940  errmsg = decode_pure(digits_values_lower, 36U, s, s_size, result);
1941  if (errmsg == 0) {
1942  /* result + 16*36**(width-1) + 10**width */
1943  if (width == 4U) (*result) += 756496;
1944  else if (width == 5U) (*result) += 26973856;
1945  else {
1946  *result = 0;
1947  return unsupported_width();
1948  }
1949  return 0;
1950  }
1951  }
1952  else {
1953  errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
1954  if (errmsg) return errmsg;
1955  if (!(width == 4U || width == 5U)) {
1956  *result = 0;
1957  return unsupported_width();
1958  }
1959  return 0;
1960  }
1961  }
1962  }
1963  *result = 0;
1964  return invalid_number_literal();
1965 }
double * di
#define i

◆ hy36decodeSafe()

void hy36decodeSafe ( unsigned  width,
const char *  s,
unsigned  s_size,
int *  result 
)

Definition at line 1968 of file pdb.cpp.

1969 {
1970  auto* errmsg = hy36decode(width, s, s_size, result);
1971  if (errmsg) {
1973  }
1974 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
const char * hy36decode(unsigned width, const char *s, unsigned s_size, int *result)
Definition: pdb.cpp:1892
Incorrect value received.
Definition: xmipp_error.h:195

◆ hy36encode()

const char* hy36encode ( unsigned  width,
int  value,
char *  result 
)

hybrid-36 encoder: converts integer value to string result width: must be 4 (e.g. for residue sequence numbers) or 5 (e.g. for atom serial numbers) value: integer value to be converted result: pointer to char array of size width+1 or greater on return result is null-terminated return value: pointer to error message, if any, or 0 on success Example usage (from C++): char result[4+1]; const char* errmsg = hy36encode(4, 12345, result); if (errmsg) throw std::runtime_error(errmsg);

Definition at line 1824 of file pdb.cpp.

1825 {
1826  int i = value;
1827  if (width == 4U) {
1828  if (i >= -999) {
1829  if (i < 10000) {
1830  encode_pure(digits_upper(), 10U, 4U, i, result);
1831  return 0;
1832  }
1833  i -= 10000;
1834  if (i < 1213056 /* 26*36**3 */) {
1835  i += 466560 /* 10*36**3 */;
1836  encode_pure(digits_upper(), 36U, 0U, i, result);
1837  return 0;
1838  }
1839  i -= 1213056;
1840  if (i < 1213056) {
1841  i += 466560;
1842  encode_pure(digits_lower(), 36U, 0U, i, result);
1843  return 0;
1844  }
1845  }
1846  }
1847  else if (width == 5U) {
1848  if (i >= -9999) {
1849  if (i < 100000) {
1850  encode_pure(digits_upper(), 10U, 5U, i, result);
1851  return 0;
1852  }
1853  i -= 100000;
1854  if (i < 43670016 /* 26*36**4 */) {
1855  i += 16796160 /* 10*36**4 */;
1856  encode_pure(digits_upper(), 36U, 0U, i, result);
1857  return 0;
1858  }
1859  i -= 43670016;
1860  if (i < 43670016) {
1861  i += 16796160;
1862  encode_pure(digits_lower(), 36U, 0U, i, result);
1863  return 0;
1864  }
1865  }
1866  }
1867  else {
1868  fill_with_stars(width, result);
1869  return unsupported_width();
1870  }
1871  fill_with_stars(width, result);
1872  return value_out_of_range();
1873 }
#define i

◆ hy36encodeSafe()

void hy36encodeSafe ( unsigned  width,
int  value,
char *  result 
)

Definition at line 1977 of file pdb.cpp.

1978 {
1979  const char* errmsg = hy36encode(width, value, result);
1980  if (errmsg) {
1982  }
1983 }
const char * hy36encode(unsigned width, int value, char *result)
Definition: pdb.cpp:1824
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
Incorrect value received.
Definition: xmipp_error.h:195

◆ optimizeHlpf()

void optimizeHlpf ( MultidimArray< double > &  f,
int  M,
double  T,
const std::string &  atom,
MultidimArray< double > &  filter,
Matrix1D< double > &  bestPrm 
)

Optimize the low pass filter. The optimization is so that the Fourier response of the coarsely downsampled and convolved atom profile resembles as much as possible the ideal atomic response up to the maximum frequency provided by the Nyquist frequency associated to M*T.

f is the electron scattering factor in real space sampled at a sampling rate T. M is the downsampling factor. atom is the name of the atom being optimized. filter is an output parameter with the optimal impulse response sampled at a sampling rate T. bestPrm(0)=reduction function of the cutoff frequency, bestPrm(1)=ripple of the Kaiser selfWindow, bestPrm(2)=deltaw of the Kaiser selfWindow.

Definition at line 1285 of file pdb.cpp.

1287 {
1288  globalHlpfPrm(0)=1.0; // reduction factor
1289  globalHlpfPrm(1)=0.01; // ripple
1290  globalHlpfPrm(2)=1.0/8.0; // deltaw
1291  globalf=f;
1292  globalM=M;
1293  globalT=T;
1294  globalAtom=atom;
1295  double fitness;
1296  int iter;
1298  steps.initConstant(1);
1300  &Hlpf_fitness, nullptr, 0.05, fitness, iter, steps, false);
1301  bestPrm=globalHlpfPrm;
1302  hlpf(f, M, "SincKaiser", filter, bestPrm(0), bestPrm(1), bestPrm(2));
1303 }
void hlpf(MultidimArray< double > &f, int M, const std::string &filterType, MultidimArray< double > &filter, double reductionFactor=0.8, double ripple=0.01, double deltaw=1.0/8.0)
Definition: pdb.cpp:1104
MultidimArray< double > globalf
Definition: pdb.cpp:1175
void powellOptimizer(Matrix1D< double > &p, int i0, int n, double(*f)(double *x, void *), void *prm, double ftol, double &fret, int &iter, const Matrix1D< double > &steps, bool show)
glob_prnt iter
double Hlpf_fitness(double *p, void *prm)
Definition: pdb.cpp:1181
int globalM
Definition: pdb.cpp:1176
double * f
double globalT
Definition: pdb.cpp:1177
double steps
Matrix1D< double > globalHlpfPrm(3)
double fitness(double *p)
std::string globalAtom
Definition: pdb.cpp:1178

◆ projectAtom()

void projectAtom ( const Atom atom,
Projection P,
const Matrix2D< double > &  VP,
const Matrix2D< double > &  PV,
const AtomInterpolator interpolator 
)

PDB projection ------------------------------------------------------—

Definition at line 1446 of file pdb.cpp.

1449 {
1450 constexpr float SUBSAMPLING = 2; // for every measure 2x2 line
1451  // integrals will be taken to
1452  // avoid numerical errors
1453 constexpr float SUBSTEP = 1/(SUBSAMPLING*2.0);
1454 
1455  Matrix1D<double> origin(3);
1457  VP.getRow(2, direction);
1458  direction.selfTranspose();
1459  Matrix1D<double> corner1(3);
1460  Matrix1D<double> corner2(3);
1461  Matrix1D<double> act(3);
1463 
1464  // Find center of the feature in the projection plane ...................
1465  // Step 1). Project the center to the plane, the result is in the
1466  // universal coord system
1467  Matrix1D<double> Center(3);
1468  VECTOR_R3(Center, atom.x, atom.y, atom.z);
1469  double max_distance=interpolator.atomRadius(atom.atomType);
1470  M3x3_BY_V3x1(origin, VP, Center);
1471 
1472  //#define DEBUG_LITTLE
1473 #ifdef DEBUG_LITTLE
1474 
1475  std::cout << "Actual atom\n" << atom.atomType << " ("
1476  << atom.x << "," << atom.y << "," << atom.z << ")\n";
1477  std::cout << "Center " << Center.transpose() << std::endl;
1478  std::cout << "VP matrix\n" << VP << std::endl;
1479  std::cout << "P.direction " << P.direction.transpose() << std::endl;
1480  std::cout << "direction " << direction.transpose() << std::endl;
1481  std::cout << "P.euler matrix " << P.euler << std::endl;
1482  std::cout << "max_distance " << max_distance << std::endl;
1483  std::cout << "origin " << origin.transpose() << std::endl;
1484 #endif
1485 
1486  // Find limits for projection ...........................................
1487  // Choose corners for the projection of this feature. It is supposed
1488  // to have at the worst case a projection of size max_distance
1489  VECTOR_R3(corner1, max_distance, max_distance, max_distance);
1490  VECTOR_R3(corner2, -max_distance, -max_distance, -max_distance);
1491 #ifdef DEBUG_LITTLE
1492 
1493  std::cout << "Corner1 : " << corner1.transpose() << std::endl
1494  << "Corner2 : " << corner2.transpose() << std::endl;
1495 #endif
1496 
1497  box_enclosing(corner1, corner2, VP, corner1, corner2);
1498 #ifdef DEBUG_LITTLE
1499 
1500  std::cout << "Corner1 moves to : " << corner1.transpose() << std::endl
1501  << "Corner2 moves to : " << corner2.transpose() << std::endl;
1502 #endif
1503 
1504  V3_PLUS_V3(corner1, origin, corner1);
1505  V3_PLUS_V3(corner2, origin, corner2);
1506 #ifdef DEBUG_LITTLE
1507 
1508  std::cout << "Corner1 finally is : " << corner1.transpose() << std::endl
1509  << "Corner2 finally is : " << corner2.transpose() << std::endl;
1510 #endif
1511  // Discard not necessary components
1512  corner1.resize(2);
1513  corner2.resize(2);
1514 
1515  // Clip to image size
1516  sortTwoVectors(corner1, corner2);
1517  XX(corner1) = CLIP(ROUND(XX(corner1)), STARTINGX(P()), FINISHINGX(P()));
1518  YY(corner1) = CLIP(ROUND(YY(corner1)), STARTINGY(P()), FINISHINGY(P()));
1519  XX(corner2) = CLIP(ROUND(XX(corner2)), STARTINGX(P()), FINISHINGX(P()));
1520  YY(corner2) = CLIP(ROUND(YY(corner2)), STARTINGY(P()), FINISHINGY(P()));
1521 
1522 #ifdef DEBUG_LITTLE
1523 
1524  std::cout << "corner1 " << corner1.transpose() << std::endl;
1525  std::cout << "corner2 " << corner2.transpose() << std::endl;
1526  std::cout.flush();
1527 #endif
1528 
1529  // Check if there is something to project
1530  if (XX(corner1) == XX(corner2))
1531  return;
1532  if (YY(corner1) == YY(corner2))
1533  return;
1534 
1535  // Study the projection for each point in the projection plane ..........
1536  // (u,v) are in the deformed projection plane (if any deformation)
1537  for (auto v = (int)YY(corner1); v <= (int)YY(corner2); v++)
1538  for (auto u = (int)XX(corner1); u <= (int)XX(corner2); u++)
1539  {
1540  double length = 0;
1541  //#define DEBUG_EVEN_MORE
1542 #ifdef DEBUG_EVEN_MORE
1543 
1544  std::cout << "Studying point (" << u << "," << v << ")\n";
1545  std::cout.flush();
1546 #endif
1547 
1548  // Perform subsampling ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1549  double u0 = u - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1550  double v0 = v - (int)(SUBSAMPLING / 2.0) * SUBSTEP;
1551  double actv = v0;
1552  for (int subv = 0; subv < SUBSAMPLING; subv++)
1553  {
1554  double actu = u0;
1555  for (int subu = 0; subu < SUBSAMPLING; subu++)
1556  {
1557  // Compute the coordinates of point (subu,subv) which is
1558  // within the plane in the universal coordinate system
1559  XX(act) = actu;
1560  YY(act) = actv;
1561  ZZ(act) = 0;
1562  M3x3_BY_V3x1(act, PV, act);
1563 
1564  // Compute the intersection of a ray which passes through
1565  // this point and its direction is perpendicular to the
1566  // projection plane
1567  double r=point_line_distance_3D(Center, act, direction);
1568  double possible_length=interpolator.
1569  projectionAtDistance(atom.atomType,r);
1570  if (possible_length > 0)
1571  length += possible_length;
1572 
1573 #ifdef DEBUG_EVEN_MORE
1574 
1575  std::cout << "Averaging at (" << actu << "," << actv << ")\n";
1576  std::cout << " which in univ. coords is " << act.transpose() << std::endl;
1577  std::cout << " r=" << r << std::endl;
1578  std::cout << " intersection there " << possible_length << std::endl;
1579  std::cout.flush();
1580 #endif
1581  // Prepare for next iteration
1582  actu += SUBSTEP * 2.0;
1583  }
1584  actv += SUBSTEP * 2.0;
1585  }
1586  length /= (SUBSAMPLING * SUBSAMPLING);
1587  //#define DEBUG
1588 #ifdef DEBUG
1589 
1590  std::cout << "Final value added at position (" << u << "," << v << ")="
1591  << length << std::endl;
1592  std::cout.flush();
1593 #endif
1594 
1595  // Add at the correspondent pixel the found intersection ,,,,,,,,,,
1596  IMGPIXEL(P, v, u) += length;
1597  }
1598 }
double z
Position Z.
Definition: pdb.h:123
double point_line_distance_3D(const Matrix1D< double > &p, const Matrix1D< double > &a, const Matrix1D< double > &v)
Definition: geometry.cpp:85
void sortTwoVectors(Matrix1D< T > &v1, Matrix1D< T > &v2)
Definition: matrix1d.h:1206
#define FINISHINGX(v)
Matrix2D< double > euler
double x
Position X.
Definition: pdb.h:117
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
char atomType
Type.
Definition: pdb.h:114
void selfTranspose()
Definition: matrix1d.h:944
#define STARTINGX(v)
Matrix1D< T > transpose() const
Definition: matrix1d.cpp:644
#define STARTINGY(v)
#define CLIP(x, x0, xF)
Definition: xmipp_macros.h:260
void box_enclosing(const Matrix1D< double > &v0, const Matrix1D< double > &vF, const Matrix2D< double > &V, Matrix1D< double > &corner1, Matrix1D< double > &corner2)
Definition: geometry.cpp:366
#define XX(v)
Definition: matrix1d.h:85
__host__ __device__ float length(float2 v)
#define ROUND(x)
Definition: xmipp_macros.h:210
void direction(const MultidimArray< double > &orMap, MultidimArray< double > &qualityMap, double lambda, int size, MultidimArray< double > &dirMap, int x, int y)
Matrix1D< double > direction
#define M3x3_BY_V3x1(a, M, b)
Definition: matrix2d.h:170
#define YY(v)
Definition: matrix1d.h:93
#define FINISHINGY(v)
double y
Position Y.
Definition: pdb.h:120
#define VECTOR_R3(v, x, y, z)
Definition: matrix1d.h:124
doublereal * u
double atomRadius(char atom) const
Definition: pdb.h:414
double v0
void getRow(size_t i, Matrix1D< T > &v) const
Definition: matrix2d.cpp:871
#define ZZ(v)
Definition: matrix1d.h:101
#define V3_PLUS_V3(a, b, c)
Definition: matrix1d.h:190
#define IMGPIXEL(I, i, j)
#define SPEED_UP_temps012
Definition: xmipp_macros.h:403

◆ readCIF()

template<typename callable >
void readCIF ( const std::string &  fnCIF,
const callable &  addAtom,
cif::datablock &  dataBlock 
)

Read phantom from CIF.

This function reads the given CIF file and inserts the found atoms inside in the class's atom list.

Parameters
fnPDBCIF file path.
addAtomFunction to add atoms to class's atom list.
dataBlockData block used to store all of CIF file's fields.

Definition at line 463 of file pdb.cpp.

464 {
465  // Parsing mmCIF file
466  cif::file cifFile;
467  cifFile.load(fnCIF);
468 
469  // Extrayendo datos del archivo en un DataBlock
470  cif::datablock& db = cifFile.front();
471 
472  // Reading Atom section
473  // Typical line:
474  // ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
475  cif::category& atom_site = db["atom_site"];
476 
477  // Iterating through atoms and heteroatoms getting atom id and x,y,z positions
478  Atom atom;
479  for (const auto& [atom_id, x_pos, y_pos, z_pos]: atom_site.find
480  <std::string,float,float,float>
481  (
482  cif::key("group_PDB") == "ATOM" || cif::key("group_PDB") == "HETATM",
483  "label_atom_id",
484  "Cartn_x",
485  "Cartn_y",
486  "Cartn_z"
487  ))
488  {
489  // Obtaining:
490  // ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
491  // * ****** ******* ******
492  atom.atomType = atom_id[0];
493  atom.x = x_pos;
494  atom.y = y_pos;
495  atom.z = z_pos;
496  addAtom(atom);
497  }
498 
499  // Storing whole datablock
500  dataBlock = db;
501 }
double z
Position Z.
Definition: pdb.h:123
double x
Position X.
Definition: pdb.h:117
char atomType
Type.
Definition: pdb.h:114
Definition: pdb.h:110
double y
Position Y.
Definition: pdb.h:120

◆ readPDB()

template<typename callable >
void readPDB ( const FileName fnPDB,
const callable &  addAtom 
)

Read phantom from PDB.

This function reads the given PDB file and inserts the found atoms inside in the class's atom list.

Parameters
fnPDBPDB file.
addAtomFunction to add atoms to class's atom list.

Definition at line 417 of file pdb.cpp.

418 {
419  // Open file
420  std::ifstream fh_in;
421  fh_in.open(fnPDB.c_str());
422  if (!fh_in)
424 
425  // Process all lines of the file
426  std::string line;
427  std::string kind;
428  Atom atom;
429  while (!fh_in.eof())
430  {
431  // Read an ATOM line
432  getline(fh_in, line);
433  if (line == "")
434  continue;
435  kind = line.substr(0, 4);
436  if (kind != "ATOM" && kind != "HETA")
437  continue;
438 
439  // Extract atom type and position
440  // Typical line:
441  // ATOM 909 CA ALA A 161 58.775 31.984 111.803 1.00 34.78
442  atom.atomType = line[13];
443  atom.x = textToFloat(line.substr(30, 8));
444  atom.y = textToFloat(line.substr(38, 8));
445  atom.z = textToFloat(line.substr(46, 8));
446  addAtom(atom);
447  }
448 
449  // Close files
450  fh_in.close();
451 }
double z
Position Z.
Definition: pdb.h:123
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double x
Position X.
Definition: pdb.h:117
char atomType
Type.
Definition: pdb.h:114
float textToFloat(const char *str)
File or directory does not exist.
Definition: xmipp_error.h:136
Definition: pdb.h:110
double y
Position Y.
Definition: pdb.h:120

◆ readRichCIF()

template<typename callable >
void readRichCIF ( const std::string &  fnCIF,
const callable &  addAtom,
std::vector< double > &  intensities,
const bool  pseudoatoms,
const double  threshold,
cif::datablock &  dataBlock 
)

Read rich phantom from CIF.

This function reads the given CIF file and stores the found atoms, remarks, and intensities. Note: CIF files do not contain segment name, so that data won't be read.

Parameters
fnPDBCIF file path.
addAtomFunction to add atoms to class's atom list.
intensitiesList of atom intensities.
pseudoatomsFlag for returning intensities (stored in B-factors) instead of atoms. false (default) is used when there are no pseudoatoms or when using a threshold.
thresholdB factor threshold for filtering out for pdb_reduce_pseudoatoms.
dataBlockData block used to store all of CIF file's fields.

Definition at line 622 of file pdb.cpp.

624 {
625  // Parsing mmCIF file
626  cif::file cifFile;
627  cifFile.load(fnCIF);
628 
629  // Extrayendo datos del archivo en un DataBlock
630  cif::datablock& db = cifFile.front();
631 
632  // Reading Atom section
633  cif::category& atom_site = db["atom_site"];
634 
635  // Iterating through atoms and heteroatoms getting atom id and x,y,z positions
636  RichAtom atom;
637  for (const auto& [record, serialNumber, atomId, altId, resName, chain, resSeq, seqId, iCode, xPos, yPos, zPos,
638  occupancy, bFactor, charge, authSeqId, authCompId, authAsymId, authAtomId, pdbNum]:
639  atom_site.find<std::string,int,std::string,std::string,std::string,std::string,int,int,std::string,float,
640  float,float,float,float,std::string,int,std::string,std::string,std::string,int>
641  (
642  // Note: search by key is needed to iterate list of atoms. Workaround: use every possible record type for the search
643  cif::key("group_PDB") == "ATOM" || cif::key("group_PDB") == "HETATM",
644  "group_PDB", // Record: -->ATOM<-- 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
645  "id", // Serial number: ATOM -->8<-- C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
646  "label_atom_id", // Id: ATOM 8 C -->CD1<-- . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
647  "label_alt_id", // Alt id: ATOM 8 C CD1 -->.<-- ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
648  "label_comp_id", // Chain name: ATOM 8 C CD1 . -->ILE<-- A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
649  "label_asym_id", // Chain location: ATOM 8 C CD1 . ILE -->A<-- 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
650  "label_entity_id", // Residue sequence:ATOM 8 C CD1 . ILE A -->1<-- 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
651  "label_seq_id", // Sequence id: ATOM 8 C CD1 . ILE A 1 -->3<-- ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
652  "pdbx_PDB_ins_code", // Ins code: ATOM 8 C CD1 . ILE A 1 3 -->?<-- 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
653  "Cartn_x", // X position: ATOM 8 C CD1 . ILE A 1 3 ? -->48.271<-- 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 1
654  "Cartn_y", // Y position: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 -->183.605<-- 19.253 1.00 35.73 ? 3 ILE A CD1 1
655  "Cartn_z", // Z position: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 -->19.253<-- 1.00 35.73 ? 3 ILE A CD1 1
656  "occupancy", // Occupancy: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 -->1.00<-- 35.73 ? 3 ILE A CD1 1
657  "B_iso_or_equiv", // B factor: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 -->35.73<-- ? 3 ILE A CD1 1
658  "pdbx_formal_charge", // Author charge: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 -->?<-- 3 ILE A CD1 1
659  "auth_seq_id", // Author seq id: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? -->3<-- ILE A CD1 1
660  "auth_comp_id", // Author chainname:ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 -->ILE<-- A CD1 1
661  "auth_asym_id", // Author chain loc:ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE -->A<-- CD1 1
662  "auth_atom_id", // Author id: ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A -->CD1<-- 1
663  "pdbx_PDB_model_num" // PDB model number:ATOM 8 C CD1 . ILE A 1 3 ? 48.271 183.605 19.253 1.00 35.73 ? 3 ILE A CD1 -->1<--
664  ))
665  {
666  // Storing values in atom list
667  atom.record = record;
668  atom.serial = serialNumber;
669  atom.name = atomId;
670  atom.atomType = atomId;
671  atom.altId = altId;
672  atom.resname = resName;
673  atom.altloc = chain;
674  atom.chainid = chain[0];
675  atom.resseq = resSeq;
676  atom.seqId = seqId;
677  atom.icode = iCode;
678  atom.x = xPos;
679  atom.y = yPos;
680  atom.z = zPos;
681  atom.occupancy = occupancy;
682  atom.bfactor = bFactor;
683  atom.charge = charge;
684  atom.authSeqId = authSeqId;
685  atom.authCompId = authCompId;
686  atom.authAsymId = authAsymId;
687  atom.authAtomId = authAtomId;
688  atom.pdbNum = pdbNum;
689 
690  // If it is a pseudoatom, insert B factor into intensities
691  if(pseudoatoms) {
692  intensities.push_back(bFactor);
693  } else {
694  // Adding atom if is not pseudoatom and B factor is not greater than set threshold
695  if (bFactor >= threshold)
696  addAtom(atom);
697  }
698  }
699 
700  // Storing whole datablock
701  dataBlock = db;
702 }
int seqId
Definition: pdb.h:231
std::string charge
2-char charge with sign 2nd (e.g. 1- or 2+)
Definition: pdb.h:220
std::string record
Record Type ("ATOM " or "HETATM")
Definition: pdb.h:178
char chainid
ChainId.
Definition: pdb.h:202
int serial
atom serial number
Definition: pdb.h:181
Definition: pdb.h:174
std::string resname
Residue name.
Definition: pdb.h:199
std::string authCompId
Definition: pdb.h:237
std::string atomType
atom element type
Definition: pdb.h:217
void threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
int resseq
Residue sequence.
Definition: pdb.h:205
double y
Position Y.
Definition: pdb.h:187
double occupancy
Occupancy.
Definition: pdb.h:211
std::string altId
Definition: pdb.h:228
int pdbNum
Definition: pdb.h:246
double bfactor
Bfactor.
Definition: pdb.h:214
double x
Position X.
Definition: pdb.h:184
std::string authAsymId
Definition: pdb.h:240
int authSeqId
Definition: pdb.h:234
std::string name
Name.
Definition: pdb.h:193
std::string icode
Icode.
Definition: pdb.h:208
std::string authAtomId
Definition: pdb.h:243
double z
Position Z.
Definition: pdb.h:190
std::string altloc
Alternate location.
Definition: pdb.h:196

◆ readRichPDB()

template<typename callable >
void readRichPDB ( const FileName fnPDB,
const callable &  addAtom,
std::vector< double > &  intensities,
std::vector< std::string > &  remarks,
const bool  pseudoatoms,
const double  threshold 
)

Read rich phantom from either a PDB of CIF file.

This function reads the given PDB or CIF file and stores the found atoms, remarks, and intensities.

Parameters
fnPDBPDB/CIF file.
addAtomFunction to add atoms to class's atom list.
intensitiesList of atom intensities.
remarksList of file remarks.
pseudoatomsFlag for returning intensities (stored in B-factors) instead of atoms. false (default) is used when there are no pseudoatoms or when using a threshold.
thresholdB factor threshold for filtering out for pdb_reduce_pseudoatoms.

Definition at line 538 of file pdb.cpp.

540 {
541  // Open file
542  std::ifstream fh_in;
543  fh_in.open(fnPDB.c_str());
544  if (!fh_in)
546 
547  // Process all lines of the file
548  auto line = std::string(80, ' ');
549  std::string kind;
550 
551  RichAtom atom;
552  while (!fh_in.eof())
553  {
554  // Read an ATOM line
555  getline(fh_in, line);
556  if (line == "")
557  {
558  continue;
559  }
560 
561  // Reading and storing type of atom
562  kind = simplify(line.substr(0, 6)); // Removing extra spaces if there are any
563 
564  if (kind == "ATOM" || kind == "HETATM")
565  {
566  line.resize (80,' ');
567 
568  // Extract atom type and position
569  // Typical line:
570  // ATOM 909 CA ALA A 161 58.775 31.984 111.803 1.00 34.78
571  // ATOM 2 CA ALA A 1 73.796 56.531 56.644 0.50 84.78 C
572  atom.record = kind;
573  hy36decodeSafe(5, line.substr(6, 5).c_str(), 5, &atom.serial);
574  atom.name = simplify(line.substr(12, 4)); // Removing extra spaces if there are any
575  atom.altloc = line[16];
576  atom.resname = line.substr(17, 3);
577  atom.chainid = line[21];
578  hy36decodeSafe(4, line.substr(22, 4).c_str(), 4, &atom.resseq);
579  atom.icode = line[26];
580  atom.x = textToFloat(line.substr(30, 8));
581  atom.y = textToFloat(line.substr(38, 8));
582  atom.z = textToFloat(line.substr(46, 8));
583  atom.occupancy = textToFloat(line.substr(54, 6));
584  atom.bfactor = textToFloat(line.substr(60, 6));
585  if (line.length() >= 76 && simplify(line.substr(72, 4)) != "")
586  atom.segment = line.substr(72, 4);
587  if (line.length() >= 78 && simplify(line.substr(77, 1)) != "")
588  atom.atomType = line.substr(77, 1);
589  else
590  atom.atomType = atom.name[0];
591  if (line.length() >= 80 && simplify(line.substr(79, 1)) != "")
592  atom.charge = simplify(line.substr(79, 1)); // Converting into empty string if it is a space
593 
594  if(pseudoatoms)
595  intensities.push_back(atom.bfactor);
596 
597  if(!pseudoatoms && atom.bfactor >= threshold)
598  addAtom(atom);
599 
600  } else if (kind == "REMARK")
601  remarks.push_back(line);
602  }
603 
604  // Close files
605  fh_in.close();
606 }
std::string segment
segment name
Definition: pdb.h:224
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
std::string charge
2-char charge with sign 2nd (e.g. 1- or 2+)
Definition: pdb.h:220
std::string record
Record Type ("ATOM " or "HETATM")
Definition: pdb.h:178
char chainid
ChainId.
Definition: pdb.h:202
int serial
atom serial number
Definition: pdb.h:181
Definition: pdb.h:174
std::string resname
Residue name.
Definition: pdb.h:199
std::string atomType
atom element type
Definition: pdb.h:217
void threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
int resseq
Residue sequence.
Definition: pdb.h:205
double y
Position Y.
Definition: pdb.h:187
float textToFloat(const char *str)
double occupancy
Occupancy.
Definition: pdb.h:211
String simplify(const String &str)
File or directory does not exist.
Definition: xmipp_error.h:136
double bfactor
Bfactor.
Definition: pdb.h:214
double x
Position X.
Definition: pdb.h:184
void hy36decodeSafe(unsigned width, const char *s, unsigned s_size, int *result)
Definition: pdb.cpp:1968
std::string name
Name.
Definition: pdb.h:193
std::string icode
Icode.
Definition: pdb.h:208
double z
Position Z.
Definition: pdb.h:190
std::string altloc
Alternate location.
Definition: pdb.h:196

◆ writeCIF()

template<typename callable >
void writeCIF ( const std::string &  fnCIF,
const callable &  atomList,
cif::datablock &  dataBlock 
)

Write rich phantom to CIF file.

This function stores all the data of the rich phantom into a CIF file.

Parameters
fnPDBPDB file path to write to.
atomListList of atoms to be stored.
dataBlockData block containing the full CIF file.

Definition at line 773 of file pdb.cpp.

774 {
775  // Opening CIF file
776  std::ofstream cifFile(fnCIF);
777 
778  // Creating atom_site category
779  cif::category atomSite("atom_site");
780  cif::row_initializer atomSiteInserter;
781 
782  // Declaring temporary variables for occupancy, coords, and Bfactor
783  std::stringstream tempStream;
784  std::string occupancy;
785  std::string xPos;
786  std::string yPos;
787  std::string zPos;
788  std::string bFactor;
789 
790  // Inserting data from atom list
791  for (RichAtom atom : atomList) {
792  // Converting occupancy to string with 2 fixed decimals
793  tempStream << std::fixed << std::setprecision(2) << atom.occupancy;
794  occupancy = tempStream.str();
795  tempStream.clear();
796  tempStream.str("");
797 
798  // Converting xPos to string with 3 fixed decimals
799  tempStream << std::fixed << std::setprecision(3) << atom.x;
800  xPos = tempStream.str();
801  tempStream.clear();
802  tempStream.str("");
803 
804  // Converting yPos to string with 3 fixed decimals
805  tempStream << std::fixed << std::setprecision(3) << atom.y;
806  yPos = tempStream.str();
807  tempStream.clear();
808  tempStream.str("");
809 
810  // Converting zPos to string with 3 fixed decimals
811  tempStream << std::fixed << std::setprecision(3) << atom.z;
812  zPos = tempStream.str();
813  tempStream.clear();
814  tempStream.str("");
815 
816  // Converting bFactor to string with 2 fixed decimals
817  tempStream << std::fixed << std::setprecision(2) << atom.bfactor;
818  bFactor = tempStream.str();
819  tempStream.clear();
820  tempStream.str("");
821 
822  // Defining row
823  // Empty string or char values are substitued with "." or '.' (no value)
824  // No "?" are inserted since it is not allowed by spec
825  atomSiteInserter = {
826  {"group_PDB", atom.record.empty() ? "." : atom.record},
827  {"id", atom.serial},
828  {"type_symbol", atom.name.empty() ? '.' : atom.name[0]},
829  {"label_atom_id", atom.name.empty() ? "." : atom.name},
830  {"label_alt_id", atom.altId.empty() ? "." : atom.altId},
831  {"label_comp_id", atom.resname.empty() ? "." : atom.resname},
832  {"label_asym_id", atom.altloc.empty() ? "." : atom.altloc},
833  {"label_entity_id", atom.resseq},
834  {"label_seq_id", atom.seqId},
835  {"pdbx_PDB_ins_code", atom.icode.empty() ? "." : atom.icode},
836  {"Cartn_x", xPos},
837  {"Cartn_y", yPos},
838  {"Cartn_z", zPos},
839  {"occupancy", occupancy},
840  {"B_iso_or_equiv", bFactor},
841  {"pdbx_formal_charge", atom.charge.empty() ? "." : atom.charge},
842  {"auth_seq_id", atom.authSeqId},
843  {"auth_comp_id", atom.authCompId.empty() ? "." : atom.authCompId},
844  {"auth_asym_id", atom.authAsymId.empty() ? "." : atom.authAsymId},
845  {"auth_atom_id", atom.authAtomId.empty() ? "." : atom.authAtomId},
846  {"pdbx_PDB_model_num", atom.pdbNum}
847  };
848 
849  // Inserting row
850  atomSite.emplace(std::move(atomSiteInserter));
851  }
852 
853  // Updating atom list in stored data block
854  auto categoryInsertPosition = std::find_if(
855  dataBlock.cbegin(), dataBlock.cend(),
856  [](const cif::category& cat) {
857  return cat.name() == "atom_site";
858  }
859  );
860  if (categoryInsertPosition != dataBlock.cend()) {
861  categoryInsertPosition = dataBlock.erase(categoryInsertPosition);
862  }
863  dataBlock.insert(categoryInsertPosition, atomSite);
864 
865  // Writing datablock to file
866  dataBlock.write(cifFile);
867 
868  // Closing file
869  cifFile.close();
870 }
Definition: pdb.h:174

◆ writePDB()

template<typename callable >
void writePDB ( const FileName fnPDB,
bool  renumber,
const std::vector< std::string > &  remarks,
const callable &  atomList 
)

Write rich phantom to PDB file.

This function stores all the data of the rich phantom into a PDB file.

Parameters
fnPDBPDB file to write to.
renumberFlag for determining if atom's serial numbers must be renumbered or not.
remarksList of remarks.
atomListList of atoms to be stored.

Definition at line 725 of file pdb.cpp.

726 {
727  FILE* fh_out=fopen(fnPDB.c_str(),"w");
728  if (!fh_out)
730  size_t imax=remarks.size();
731  for (size_t i=0; i<imax; ++i)
732  fprintf(fh_out,"%s\n",remarks[i].c_str());
733 
734  imax=atomList.size();
735  for (size_t i=0; i<imax; ++i)
736  {
737  const RichAtom &atom=atomList[i];
738  char serial[5+1];
739  if (!renumber) {
740  auto* errmsg3 = hy36encode(5, atom.serial, serial);
741  if (errmsg3) {
742  reportWarning("Failed to use atom.serial. Using i+1 instead.");
743  renumber=true;
744  hy36encodeSafe(5, (int)i + 1, serial);
745  }
746  }
747  else {
748  // use i+1 instead
749  hy36encodeSafe(5, (int)i + 1, serial);
750  }
751  char resseq[4+1];
752  hy36encodeSafe(4, atom.resseq, resseq);
753  fprintf (fh_out,"%-6s%5s %-4s%s%-4s%c%4s%s %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s%-2s\n",
754  atom.record.c_str(),serial,atom.name.c_str(),
755  atom.altloc.c_str(),atom.resname.c_str(),atom.chainid,
756  resseq,atom.icode.c_str(),
757  atom.x,atom.y,atom.z,atom.occupancy,atom.bfactor,
758  atom.segment.c_str(),atom.atomType.c_str(),atom.charge.c_str());
759  }
760  fclose(fh_out);
761 }
const char * hy36encode(unsigned width, int value, char *result)
Definition: pdb.cpp:1824
void reportWarning(const String &what)
std::string segment
segment name
Definition: pdb.h:224
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
std::string charge
2-char charge with sign 2nd (e.g. 1- or 2+)
Definition: pdb.h:220
Couldn&#39;t write to file.
Definition: xmipp_error.h:140
std::string record
Record Type ("ATOM " or "HETATM")
Definition: pdb.h:178
char chainid
ChainId.
Definition: pdb.h:202
int serial
atom serial number
Definition: pdb.h:181
Definition: pdb.h:174
std::string resname
Residue name.
Definition: pdb.h:199
std::string atomType
atom element type
Definition: pdb.h:217
void hy36encodeSafe(unsigned width, int value, char *result)
Definition: pdb.cpp:1977
#define i
int resseq
Residue sequence.
Definition: pdb.h:205
double y
Position Y.
Definition: pdb.h:187
double occupancy
Occupancy.
Definition: pdb.h:211
double bfactor
Bfactor.
Definition: pdb.h:214
double x
Position X.
Definition: pdb.h:184
std::string name
Name.
Definition: pdb.h:193
fprintf(glob_prnt.io, "\)
std::string icode
Icode.
Definition: pdb.h:208
double z
Position Z.
Definition: pdb.h:190
std::string altloc
Alternate location.
Definition: pdb.h:196

Variable Documentation

◆ globalAtom

std::string globalAtom

Definition at line 1178 of file pdb.cpp.

◆ globalf

MultidimArray<double> globalf

Definition at line 1175 of file pdb.cpp.

◆ globalHlpfPrm

Matrix1D<double> globalHlpfPrm(3)

◆ globalM

int globalM

Definition at line 1176 of file pdb.cpp.

◆ globalT

double globalT

Definition at line 1177 of file pdb.cpp.