votca 2024.1-dev
Loading...
Searching...
No Matches
md2qmengine.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2021 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18// Local VOTCA includes
20
21namespace votca {
22namespace xtp {
23
25 std::string molkey = "topology.molecules.molecule";
26 std::vector<tools::Property*> molecules = topology_map.Select(molkey);
27 if (SameValueForMultipleEntries<std::string>(molecules, "mdname")) {
28 throw std::runtime_error("Multiple molecules have same mdname");
29 }
30 std::string segkey = "segments.segment";
31 std::vector<tools::Property*> segments_all;
32 for (tools::Property* mol : molecules) {
33 std::vector<tools::Property*> segments = mol->Select(segkey);
34 if (SameValueForMultipleEntries<std::string>(segments, "name")) {
35 throw std::runtime_error("Multiple segments in molecule:" +
36 mol->get("mdname").as<std::string>() +
37 " have same name");
38 }
39 segments_all.insert(segments_all.end(), segments.begin(), segments.end());
40 for (tools::Property* seg : segments) {
41 std::string fragkey = "fragments.fragment";
42 std::vector<tools::Property*> fragments = seg->Select(fragkey);
43 if (SameValueForMultipleEntries<std::string>(fragments, "name")) {
44 throw std::runtime_error(
45 "Multiple fragments have same name in molecule " +
46 mol->get("mdname").as<std::string>() + " segment " +
47 seg->get("name").as<std::string>());
48 }
49
50 std::vector<std::string> atomnames_seg;
51 for (tools::Property* frag : fragments) {
52 std::vector<std::string> atomnames =
53 frag->get("mdatoms").as<std::vector<std::string>>();
54 atomnames_seg.insert(atomnames_seg.end(), atomnames.begin(),
55 atomnames.end());
56 }
57 std::sort(atomnames_seg.begin(), atomnames_seg.end()); // O(N log N)
58 if (adjacent_find(atomnames_seg.begin(), atomnames_seg.end()) !=
59 atomnames_seg.end()) {
60 throw std::runtime_error(
61 "Multiple mdatoms have same identifier in molecule " +
62 mol->get("mdname").as<std::string>() + " segment " +
63 seg->get("name").as<std::string>());
64 }
65 }
66 }
67 if (SameValueForMultipleEntries<std::string>(segments_all, "name")) {
68 throw std::runtime_error("Multiple segments have same name");
69 }
70}
71
73 const csg::Molecule* mol, const std::vector<Index>& atom_ids_map) const {
74 std::vector<Index> IDs;
75 IDs.reserve(mol->BeadCount());
76 for (const csg::Bead* bead : mol->Beads()) {
77 IDs.push_back(bead->getId());
78 }
79 std::sort(IDs.begin(), IDs.end());
80 Index offset = IDs[0] - atom_ids_map[0];
81 for (Index i = 1; i < Index(IDs.size()); i++) {
82 if (IDs[i] - atom_ids_map[i] != offset) {
83 throw std::runtime_error(
84 "AtomIds offset could not be determined, either our MD trajectory or "
85 "your mapping file have wrong Atom ids");
86 }
87 }
88 return offset;
89}
90
91bool Md2QmEngine::CheckMolWhole(const Topology& top, const Segment& seg) const {
92 Eigen::Vector3d CoM = seg.getPos();
93 bool whole = true;
94 for (const Atom& a : seg) {
95 Eigen::Vector3d r = a.getPos() - CoM;
96 Eigen::Vector3d r_pbc = top.PbShortestConnect(CoM, a.getPos());
97 Eigen::Vector3d shift = r_pbc - r;
98 if (shift.norm() > 1e-9) {
99 whole = false;
100 break;
101 }
102 }
103 return whole;
104}
105
107 for (Segment& seg : top.Segments()) {
108 seg.calcPos();
109 while (!CheckMolWhole(top, seg)) {
110 Eigen::Vector3d CoM = seg.getPos();
111 for (Atom& a : seg) {
112 Eigen::Vector3d r = a.getPos() - CoM;
113 Eigen::Vector3d r_pbc = top.PbShortestConnect(CoM, a.getPos());
114 Eigen::Vector3d shift = r_pbc - r;
115 if (shift.norm() > 1e-9) {
116 a.Translate(shift);
117 }
118 }
119 seg.calcPos();
120 }
121 }
122}
123
125
126 tools::Property topology_map;
127 topology_map.LoadFromXML(mapfile_);
128 CheckMappingFile(topology_map);
129 Topology xtptop;
130 xtptop.setStep(top.getStep());
131 xtptop.setTime(top.getTime());
132 xtptop.setBox(top.getBox() * tools::conv::nm2bohr, top.getBoxType());
133
134 // which segmentname does an atom belong to molname atomid
135 std::map<std::string, std::map<Index, std::string>> MolToSegMap;
136
137 // which atomids belong to molname
138 std::map<std::string, std::vector<Index>> MolToAtomIds;
139
140 // names of segments in one molecule;
141 std::map<std::string, std::vector<std::string>> SegsinMol;
142
143 std::string molkey = "topology.molecules.molecule";
144 std::vector<tools::Property*> molecules = topology_map.Select(molkey);
145 std::string segkey = "segments.segment";
146
147 for (tools::Property* mol : molecules) {
148 // get the name of this molecule
149 std::string molname = mol->get("mdname").as<std::string>();
150 // get all segment-mapping info
151 std::vector<tools::Property*> segments = mol->Select(segkey);
152 std::vector<std::string> segnames;
153 std::vector<Index> atomids;
154 // now go through all the defined segments
155 for (tools::Property* seg : segments) {
156 // get the name of this segment and add to segnames vector
157 std::string segname = seg->get("name").as<std::string>();
158 segnames.push_back(segname);
159 std::string fragkey = "fragments.fragment";
160 // get all fragement mapping info
161 std::vector<tools::Property*> fragments = seg->Select(fragkey);
162 // go over all fragments in this segement
163 for (tools::Property* frag : fragments) {
164 // get all mdatom names from this fragment
165 std::vector<std::string> atomnames =
166 frag->get("mdatoms").as<std::vector<std::string>>();
167 // go over all atoms
168 for (const std::string& atomname : atomnames) {
169 // split atom entry at :
170 tools::Tokenizer tok_atom_name(atomname, ":");
171 std::vector<std::string> entries = tok_atom_name.ToVector();
172 if (entries.size() != 3) {
173 throw std::runtime_error("Atom entry " + atomname +
174 " is not well formatted");
175 }
176 // format should be RESNUM:ATOMNAME:ATOMID we do not care about the
177 // first two
178 Index atomid = 0;
179 try {
180 atomid = std::stoi(entries[2]);
181 } catch (std::invalid_argument& e) {
182 throw std::runtime_error("Atom entry " + atomname +
183 " is not well formatted");
184 }
185 if (votca::Log::verbose()) {
186 std::cout << "... ... processing mapping information for atom "
187 << atomname << " with ID " << atomid << std::endl;
188 }
189 atomids.push_back(atomid);
190 MolToSegMap[molname][atomid] = segname;
191 }
192 }
193 }
194 std::sort(atomids.begin(), atomids.end());
195 MolToAtomIds[molname] = atomids;
196 SegsinMol[molname] = segnames;
197 }
198
199 // go through all molecules in MD topology
200 for (const csg::Molecule& mol : top.Molecules()) {
201
202 // lookup all segment *names* in this molecule
203 const std::vector<std::string> segnames = SegsinMol[mol.getName()];
204 std::vector<Segment>& topology_segments = xtptop.Segments();
205 Index IdOffset = DetermineAtomNumOffset(&mol, MolToAtomIds[mol.getName()]);
206
207 if (votca::Log::verbose()) {
208 std::cout << "... Mapping molecule " << mol.getId() << ", name "
209 << mol.getName() << ", # of segments " << segnames.size()
210 << ", atomID offset " << IdOffset << std::endl;
211 }
212
213 for (const std::string& segname : segnames) {
214
215 Index segid = topology_segments.size();
216 // construct a segment
217 Segment this_segment = Segment(segname, segid);
218 this_segment.AddMoleculeId(mol.getId());
219
220 // create atomlist
221 for (const csg::Bead* bead : mol.Beads()) {
222 // check if it belongs to this segment, and add it
223 if (segname == MolToSegMap[mol.getName()][bead->getId() - IdOffset]) {
224 Atom atom(bead->getResnr(), bead->getName(), bead->getId(),
225 bead->getPos() * tools::conv::nm2bohr, bead->getType());
226 this_segment.push_back(atom);
227 }
228 }
229 // add segment to topology
230 topology_segments.push_back(this_segment);
231 }
232 }
233
234 MakeSegmentsWholePBC(xtptop);
235
236 return xtptop;
237}
238
239template <class T>
241 const std::vector<tools::Property*>& props, std::string valuetag) const {
242 std::vector<T> entries;
243 for (tools::Property* prop : props) {
244 entries.push_back(prop->get(valuetag).as<T>());
245 }
246 std::sort(entries.begin(), entries.end()); // O(N log N)
247 return adjacent_find(entries.begin(), entries.end()) != entries.end();
248}
249
250} // namespace xtp
251} // namespace votca
information about a bead
Definition bead.h:50
information about molecules
Definition molecule.h:45
Index BeadCount() const
get the number of beads in the molecule
Definition molecule.h:65
const std::vector< Bead * > & Beads() const
Definition molecule.h:67
topology of the whole system
Definition topology.h:81
double getTime() const
Definition topology.h:317
BoundaryCondition::eBoxtype getBoxType() const
Definition topology.h:394
const Eigen::Matrix3d & getBox() const
Definition topology.h:298
Index getStep() const
Definition topology.h:329
MoleculeContainer & Molecules()
Definition topology.h:182
class to manage program options with xml serialization functionality
Definition property.h:55
std::vector< Property * > Select(const std::string &filter)
select property based on a filter
Definition property.cc:185
void LoadFromXML(std::string filename)
Definition property.cc:238
break string into words
Definition tokenizer.h:72
std::vector< T > ToVector()
store all words in a vector of type T, does type conversion.
Definition tokenizer.h:109
void push_back(const T &atom)
const Eigen::Vector3d & getPos() const
void CheckMappingFile(tools::Property &topology_map) const
void MakeSegmentsWholePBC(Topology &top) const
Index DetermineAtomNumOffset(const csg::Molecule *mol, const std::vector< Index > &atom_ids_map) const
bool SameValueForMultipleEntries(const std::vector< tools::Property * > &props, std::string tag) const
Topology map(const csg::Topology &top) const
bool CheckMolWhole(const Topology &top, const Segment &seg) const
void AddMoleculeId(Index id)
Definition segment.h:91
Container for segments and box and atoms.
Definition topology.h:41
Eigen::Vector3d PbShortestConnect(const Eigen::Vector3d &r1, const Eigen::Vector3d &r2) const
Definition topology.cc:129
void setTime(double time)
Definition topology.h:78
void setBox(const Eigen::Matrix3d &box, csg::BoundaryCondition::eBoxtype boxtype=csg::BoundaryCondition::typeAuto)
Definition topology.cc:74
std::vector< Segment > & Segments()
Definition topology.h:58
void setStep(Index step)
Definition topology.h:76
const double nm2bohr
Definition constants.h:47
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
static bool verbose()
Definition globals.h:32