SSAGES  0.1
A MetaDynamics Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
ParallelBetaRMSDCV.h
1 
21 #pragma once
22 
23 #include "CollectiveVariable.h"
24 #include "Validator/ObjectRequirement.h"
25 #include "Drivers/DriverException.h"
26 #include "Snapshot.h"
27 #include "schema.h"
28 #include "Utility/ReadBackbone.h"
29 #include <stdexcept>
30 
31 namespace SSAGES
32 {
34 
44  {
45  private:
46 
48  std::vector<int> resids_;
49 
51  //std::vector<int> atomids_;
52  std::vector< std::vector<std::string> > atomids_;
53 
55  std::string refpdb_;
56 
58  std::vector<Vector3> refalpha_;
59 
61  double unitconv_;
62 
64  int mode_;
65 
66  public:
68 
79  ParallelBetaRMSDCV(std::vector<int> resids, std::string refpdb, double unitconv, int mode) :
80  resids_(resids), refpdb_(refpdb), unitconv_(unitconv), mode_(mode)
81  {
82  if(resids_.size() != 2 ){
83  throw std::invalid_argument("ParallelBetaRMSDCV: Input must designate range of residues with 2 residue numbers.");
84  }
85 
86  resids_.clear();
87 
88  if(resids[0] >= resids[1]){
89  throw std::invalid_argument("ParallelBetaRMSDCV: Input must list lower residue index first: please reverse residue range.");
90  } else if(resids[1] - resids[0] < 5) {
91  throw std::invalid_argument("ParallelBetaRMSDCV: Residue range must span at least 6 residues for secondary structure calculation.");
92  }
93 
94  std::cout << "ParallelBetaRMSDCV: Calculating parallel beta sheet character from residue " << resids[0] << " to " << resids[1] << "." << std::endl;
95 
96  for(unsigned int i = resids[0]; i <= resids[1]; i++){
97  resids_.push_back(i);
98  }
99  }
100 
102 
105  void Initialize(const Snapshot& snapshot) override
106  {
108 
109  // reference structure for parallel beta sheet, values in nanometers
110  // Reference structure taken from values used in Plumed 2.2.0
111  refalpha_.push_back(unitconv_ * Vector3{-.1439, -.5122, -.1144}); // N residue i
112  refalpha_.push_back(unitconv_ * Vector3{-.0816, -.3803, -.1013}); // CA
113  refalpha_.push_back(unitconv_ * Vector3{ .0099, -.3509, -.2206}); // CB
114  refalpha_.push_back(unitconv_ * Vector3{-.1928, -.2770, -.0952}); // C
115  refalpha_.push_back(unitconv_ * Vector3{-.2991, -.2970, -.1551}); // O
116  refalpha_.push_back(unitconv_ * Vector3{-.1698, -.1687, -.0215}); // N residue i+1
117  refalpha_.push_back(unitconv_ * Vector3{-.2681, -.0613, -.0143}); // CA
118  refalpha_.push_back(unitconv_ * Vector3{-.3323, -.0477, .1267}); // CB
119  refalpha_.push_back(unitconv_ * Vector3{-.1984, .0681, -.0574}); // C
120  refalpha_.push_back(unitconv_ * Vector3{-.0807, .0921, -.0273}); // O
121  refalpha_.push_back(unitconv_ * Vector3{-.2716, .1492, -.1329}); // N residue i+2
122  refalpha_.push_back(unitconv_ * Vector3{-.2196, .2731, -.1883}); // CA
123  refalpha_.push_back(unitconv_ * Vector3{-.2263, .2692, -.3418}); // CB
124  refalpha_.push_back(unitconv_ * Vector3{-.2989, .3949, -.1433}); // C
125  refalpha_.push_back(unitconv_ * Vector3{-.4214, .3989, -.1583}); // O
126  refalpha_.push_back(unitconv_ * Vector3{ .2464, -.4352, .2149}); // N residue h
127  refalpha_.push_back(unitconv_ * Vector3{ .3078, -.3170, .1541}); // CA
128  refalpha_.push_back(unitconv_ * Vector3{ .3398, -.3415, .0060}); // CB
129  refalpha_.push_back(unitconv_ * Vector3{ .2080, -.2021, .1639}); // C
130  refalpha_.push_back(unitconv_ * Vector3{ .0938, -.2178, .1225}); // O
131  refalpha_.push_back(unitconv_ * Vector3{ .2525, -.0886, .2183}); // N residue h+1
132  refalpha_.push_back(unitconv_ * Vector3{ .1692, .0303, .2346}); // CA
133  refalpha_.push_back(unitconv_ * Vector3{ .1541, .0665, .3842}); // CB
134  refalpha_.push_back(unitconv_ * Vector3{ .2420, .1410, .1608}); // C
135  refalpha_.push_back(unitconv_ * Vector3{ .3567, .1733, .1937}); // O
136  refalpha_.push_back(unitconv_ * Vector3{ .1758, .1976, .0600}); // N residue h+2
137  refalpha_.push_back(unitconv_ * Vector3{ .2373, .2987, -.0238}); // CA
138  refalpha_.push_back(unitconv_ * Vector3{ .2367, .2527, -.1720}); // CB
139  refalpha_.push_back(unitconv_ * Vector3{ .1684, .4331, -.0148}); // C
140  refalpha_.push_back(unitconv_ * Vector3{ .0486, .4430, -.0415}); // O
141  }
142 
144 
147  void Evaluate(const Snapshot& snapshot) override
148  {
149  // need atom positions for all atoms in atomids_
150  const auto& pos = snapshot.GetPositions();
151  std::vector<int> groupidx;
152  std::vector<int> double_atomids(atomids_[0].size());
153  std::transform(atomids_[0].begin(), atomids_[0].end(), double_atomids.begin(), [](std::string val) {return std::stod(val);});
154  snapshot.GetLocalIndices(double_atomids, &groupidx);
155 
156  unsigned int resgroups = resids_.size() - 2;
157  double rmsd, dist_norm, dxgrouprmsd;
158  Vector3 dist_xyz, dist_ref;
159  std::vector<Vector3> refxyz;
160  std::vector< std::vector< Vector3 > > deriv(30, std::vector<Vector3>(30, Vector3{0,0,0}));
161 
162  std::fill(grad_.begin(), grad_.end(), Vector3{0,0,0});
163  grad_.resize(snapshot.GetNumAtoms(), Vector3{0,0,0});
164  val_ = 0.0;
165 
166  for(size_t i = 0; i < resgroups - 3; i++){
167  for(size_t j = i + 3; j < resgroups; j++){
168  // mode: 0 for all, 1 for inter, 2 for intra
169  if((mode_ == 0) || (mode_ == 1 && atomids_[1][5 * j] != atomids_[1][5 * i]) || (mode_ == 2 && atomids_[1][5 * j] == atomids_[1][5 * i])){
170  rmsd = 0.0;
171  std::fill(refxyz.begin(), refxyz.end(), Vector3{0,0,0});
172  refxyz.resize(30, Vector3{0,0,0});
173  for(size_t k = 0; k < 15; k++){
174  refxyz[k] = pos[groupidx[5 * i + k]];
175  }
176  for(size_t k = 0; k < 15; k++){
177  refxyz[k + 15] = pos[groupidx[5 * j + k]];
178  }
179 
180  // sum over all pairs to calculate CV
181  for(size_t k = 0; k < 29; k++){
182  for(size_t h = k + 1; h < 30; h++){
183  dist_xyz = refxyz[k] - refxyz[h];
184  dist_ref = refalpha_[k] - refalpha_[h];
185  dist_norm = dist_xyz.norm() - dist_ref.norm();
186  rmsd += dist_norm * dist_norm;
187  deriv[k][h] = dist_xyz * dist_norm / dist_xyz.norm();
188  }
189  }
190 
191  rmsd = pow(rmsd / 435, 0.5) / 0.1;
192  val_ += (1 - pow(rmsd, 8.0)) / (1 - pow(rmsd, 12.0));
193 
194  dxgrouprmsd = pow(rmsd, 11.0) + pow(rmsd, 7.0);
195  dxgrouprmsd /= pow(rmsd, 8.0) + pow(rmsd, 4.0) + 1;
196  dxgrouprmsd /= pow(rmsd, 8.0) + pow(rmsd, 4.0) + 1;
197  dxgrouprmsd *= -40. / 435;
198 
199  for(size_t k = 0; k < 15; k++){
200  for(size_t h = k + 1; h < 15; h++){
201  grad_[groupidx[5 * i + k]] += dxgrouprmsd * deriv[k][h];
202  grad_[groupidx[5 * i + h]] -= dxgrouprmsd * deriv[k][h];
203  }
204  for(size_t h = 0; h < 15; h++){
205  grad_[groupidx[5 * i + k]] += dxgrouprmsd * deriv[k][h+15];
206  grad_[groupidx[5 * j + h]] -= dxgrouprmsd * deriv[k][h+15];
207  }
208  }
209  for(size_t k = 0; k < 14; k++){
210  for(size_t h = k + 1; h < 15; h++){
211  grad_[groupidx[5 * j + k]] += dxgrouprmsd * deriv[k+15][h+15];
212  grad_[groupidx[5 * j + h]] -= dxgrouprmsd * deriv[k+15][h+15];
213  }
214  }
215  }
216  }
217  }
218  }
219 
221  static ParallelBetaRMSDCV* Build(const Json::Value& json, const std::string& path)
222  {
223  Json::ObjectRequirement validator;
224  Json::Value schema;
225  Json::Reader reader;
226 
227  reader.parse(JsonSchema::ParallelBetaRMSDCV, schema);
228  validator.Parse(schema, path);
229 
230  //Validate inputs
231  validator.Validate(json, path);
232  if(validator.HasErrors())
233  throw BuildException(validator.GetErrors());
234 
235  std::vector<int> resids;
236  for(auto& s : json["residue_ids"])
237  resids.push_back(s.asInt());
238  auto reference = json["reference"].asString();
239 
240  double unitconv = json.get("length_unit", 1).asDouble();
241 
242  int mode = json.get("mode", 0).asInt();
243 
244  return new ParallelBetaRMSDCV(resids, reference, unitconv, mode);
245  }
246  };
247 }
double unitconv_
Length unit conversion: convert 1 nm to your internal MD units (ex. if using angstroms use 10) ...
void Evaluate(const Snapshot &snapshot) override
Evaluate the CV.
bool HasErrors()
Check if errors have occured.
Definition: Requirement.h:86
unsigned GetNumAtoms() const
Get number of atoms in this snapshot.
Definition: Snapshot.h:200
std::string refpdb_
Name of pdb reference for system.
Class containing a snapshot of the current simulation in time.
Definition: Snapshot.h:43
std::vector< int > resids_
Residue IDs for secondary structure calculation.
virtual void Parse(Value json, const std::string &path) override
Parse JSON value to generate Requirement(s).
std::vector< Vector3 > grad_
Gradient vector dCv/dxi.
void GetLocalIndices(const Label &ids, Label *indices) const
Definition: Snapshot.h:573
Exception to be thrown when building the Driver fails.
Collective variable to measure parallel beta sheet secondary structure.
std::vector< std::string > GetErrors()
Get list of error messages.
Definition: Requirement.h:92
ParallelBetaRMSDCV(std::vector< int > resids, std::string refpdb, double unitconv, int mode)
Constructor.
Requirements on an object.
int mode_
Specify whether to calculate beta sheet character in intra or inter mode: 0 for either, 1 for inter, 2 for intra.
std::vector< Vector3 > refalpha_
Coordinates for reference structure.
std::vector< std::vector< std::string > > atomids_
Atom IDs for secondary structure calculation: backbone of resids_.
Eigen::Vector3d Vector3
Three-dimensional vector.
Definition: types.h:33
double val_
Current value of CV.
Abstract class for a collective variable.
static std::vector< std::vector< std::string > > GetPdbBackbone(std::string refpdb, std::vector< int > resids)
Read protein backbone atoms from reference PDB file.
Definition: ReadBackbone.h:57
void Initialize(const Snapshot &snapshot) override
Initialize necessary variables.
const std::vector< Vector3 > & GetPositions() const
Access the particle positions.
Definition: Snapshot.h:323
static ParallelBetaRMSDCV * Build(const Json::Value &json, const std::string &path)
Set up collective variable.
virtual void Validate(const Value &json, const std::string &path) override
Validate JSON value.