File: Trajectory.cpp

package info (click to toggle)
rdkit 201809.1%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 123,688 kB
  • sloc: cpp: 230,509; python: 70,501; java: 6,329; ansic: 5,427; sql: 1,899; yacc: 1,739; lex: 1,243; makefile: 445; xml: 229; fortran: 183; sh: 123; cs: 93
file content (206 lines) | stat: -rw-r--r-- 7,676 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//
// Copyright (C) 2003-2016 Sereina Riniker, Paolo Tosco
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#include <RDGeneral/Invariant.h>
#include <RDGeneral/BadFileException.h>
#include <GraphMol/ROMol.h>
#include <GraphMol/Conformer.h>
#include <fstream>
#include <sstream>
#include <set>
#include "Trajectory.h"

namespace RDKit {

RDGeom::Point2D Snapshot::getPoint2D(unsigned int pointNum) const {
  PRECONDITION(d_pos, "d_pos must not be NULL");
  PRECONDITION(d_trajectory, "d_trajectory must not be NULL");
  PRECONDITION(d_trajectory->dimension() == 2, "d_dimension must be == 2");
  PRECONDITION(d_trajectory->numPoints(), "d_numPoints must be > 0");
  URANGE_CHECK(pointNum, d_trajectory->numPoints());
  unsigned int i = pointNum * d_trajectory->dimension();
  return RDGeom::Point2D(d_pos[i], d_pos[i + 1]);
}

RDGeom::Point3D Snapshot::getPoint3D(unsigned int pointNum) const {
  PRECONDITION(d_pos, "d_pos must not be NULL");
  PRECONDITION(d_trajectory, "d_trajectory must not be NULL");
  PRECONDITION(d_trajectory->dimension() >= 2, "d_dimension must be >= 2");
  PRECONDITION(d_trajectory->numPoints(), "d_numPoints must be > 0");
  URANGE_CHECK(pointNum, d_trajectory->numPoints());
  unsigned int i = pointNum * d_trajectory->dimension();
  return (
      RDGeom::Point3D(d_pos[i], d_pos[i + 1],
                      (d_trajectory->dimension() == 3) ? d_pos[i + 2] : 0.0));
}

Trajectory::Trajectory(unsigned int dimension, unsigned int numPoints,
                       SnapshotVect *snapshotVect)
    : d_dimension(dimension), d_numPoints(numPoints) {
  if (!snapshotVect) snapshotVect = new SnapshotVect;
  d_snapshotVect.reset(snapshotVect);
  for (auto &vectIt : *d_snapshotVect) vectIt.d_trajectory = this;
}

Trajectory::Trajectory(const Trajectory &other)
    : d_dimension(other.d_dimension),
      d_numPoints(other.d_numPoints),
      d_snapshotVect(new SnapshotVect) {
  for (SnapshotVect::const_iterator vectIt = other.d_snapshotVect->begin();
       vectIt != other.d_snapshotVect->end(); ++vectIt)
    addSnapshot(*vectIt);
}

unsigned int Trajectory::addSnapshot(const Snapshot &s) {
  return insertSnapshot(d_snapshotVect->size(), s);
}

const Snapshot &Trajectory::getSnapshot(unsigned int snapshotNum) const {
  URANGE_CHECK(snapshotNum, d_snapshotVect->size());
  return (*d_snapshotVect)[snapshotNum];
}

unsigned int Trajectory::insertSnapshot(unsigned int snapshotNum, Snapshot s) {
  URANGE_CHECK(snapshotNum, d_snapshotVect->size() + 1);
  s.d_trajectory = this;
  return (d_snapshotVect->insert(d_snapshotVect->begin() + snapshotNum, s) -
          d_snapshotVect->begin());
}

unsigned int Trajectory::removeSnapshot(unsigned int snapshotNum) {
  URANGE_CHECK(snapshotNum, d_snapshotVect->size());
  return (d_snapshotVect->erase(d_snapshotVect->begin() + snapshotNum) -
          d_snapshotVect->begin());
}

unsigned int Trajectory::addConformersToMol(ROMol &mol, int from, int to) {
  PRECONDITION(d_numPoints == mol.getNumAtoms(),
               "Number of atom mismatch between ROMol and Trajectory");
  PRECONDITION(from < static_cast<int>(size()), "from must be < size()");
  PRECONDITION(to < static_cast<int>(size()), "to must be < size()");
  if (from < 0) from = 0;
  if (to < 0) to = size() - 1;
  PRECONDITION(!size() || (from <= to), "from must be <= to");
  int n;
  unsigned int nConf;
  for (n = from, nConf = 0; size() && (n <= to); ++n, ++nConf) {
    auto *conf = new Conformer(mol.getNumAtoms());
    for (unsigned int i = 0; i < mol.getNumAtoms(); ++i)
      conf->setAtomPos(i, getSnapshot(n).getPoint3D(i));
    mol.addConformer(conf, true);
  }
  return nConf;
}

unsigned int readAmberTrajectory(const std::string &fName, Trajectory &traj) {
  PRECONDITION(traj.dimension() == 3,
               "The trajectory must have dimension == 3");
  std::ifstream inStream(fName.c_str());
  if (!inStream || inStream.bad()) {
    std::stringstream ss;
    ss << "Bad input file: " << fName;
    throw RDKit::BadFileException(ss.str());
  }
  std::string tempStr;
  // title
  std::getline(inStream, tempStr);
  // read coordinates
  unsigned int nCoords = traj.numPoints() * 3;
  unsigned int nSnapshots = 0;
  while (inStream.good() && !inStream.eof()) {
    boost::shared_array<double> c(new double[nCoords]());
    unsigned int i = 0;
    while (i < nCoords) {
      if (!(inStream >> c[i])) {
        if (!inStream.eof()) {
          std::stringstream ss;
          ss << "Error while reading file: " << fName;
          throw ValueErrorException(ss.str());
        } else if (i && (i < (nCoords - 1))) {
          std::stringstream ss;
          ss << "Premature end of file: " << fName;
          throw ValueErrorException(ss.str());
        }
        break;
      }
      ++i;
    }
    if (!inStream.eof()) {
      traj.addSnapshot(Snapshot(c));
      ++nSnapshots;
    }
  }
  return nSnapshots;
}

unsigned int readGromosTrajectory(const std::string &fName, Trajectory &traj) {
  PRECONDITION(traj.dimension() == 3,
               "The trajectory must have dimension == 3");
  std::ifstream inStream(fName.c_str());
  if (!inStream || inStream.bad()) {
    std::stringstream ss;
    ss << "Bad input file: " << fName;
    throw RDKit::BadFileException(ss.str());
  }
  std::string tempStr;
  unsigned int nCoords = traj.numPoints() * 3;
  unsigned int nSnapshots = 0;
  const static char *ignoredKeywordArray[] = {
      "TITLE", "TIMESTEP", "VELOCITYRED", "VELOCITY", "GENBOX", "BOX"};
  std::set<std::string> ignoredKeywordSet;
  for (auto &kw : ignoredKeywordArray)
    ignoredKeywordSet.insert(std::string(kw));
  while (inStream.good() && !inStream.eof()) {
    std::getline(inStream, tempStr);
    if (inStream.bad() || inStream.eof()) continue;
    if (ignoredKeywordSet.find(tempStr) != ignoredKeywordSet.end()) {
      // ignored block
      while (inStream.good() && !inStream.eof() && (tempStr != "END"))
        std::getline(inStream, tempStr);
    } else if ((tempStr == "POSITIONRED") || (tempStr == "POSITION")) {
      // these are the positions
      boost::shared_array<double> c(new double[nCoords]());
      unsigned int j = 0;
      for (unsigned int i = 0; i < traj.numPoints();) {
        std::getline(inStream, tempStr);
        if (inStream.bad() || inStream.eof() || (tempStr == "END"))
          throw ValueErrorException("Wrong number of coordinates");
        // ignore comments
        if (tempStr.find("#") != std::string::npos) continue;
        std::stringstream ls(tempStr);
        double x, y, z;
        if (!(ls >> x >> y >> z))
          throw ValueErrorException("Error while reading file");
        // store the coordinates (convert to Angstrom!)
        c[j++] = x * 10.0;
        c[j++] = y * 10.0;
        c[j++] = z * 10.0;
        ++i;
      }
      std::getline(inStream, tempStr);  // the END line
      if (inStream.bad() || inStream.eof() || (tempStr != "END"))
        throw ValueErrorException("Wrong number of coordinates");
      traj.addSnapshot(Snapshot(c));
      ++nSnapshots;
    } else {
      std::string supportedBlocks("POSITIONRED, POSITION");
      for (const auto &it : ignoredKeywordSet) supportedBlocks += ", " + it;
      throw ValueErrorException("Unsupported block: " + tempStr +
                                ". Supported blocks are " + supportedBlocks);
    }
  }  // read file
  if (inStream.bad()) {
    std::stringstream ss;
    ss << "Bad input file: " << fName;
    throw RDKit::BadFileException(ss.str());
  }
  return nSnapshots;
}
}