votca 2026-dev
Loading...
Searching...
No Matches
segmentmapper.cc
Go to the documentation of this file.
1/*
2 * Copyright 2016 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Standard includes
21#include <regex>
22
23// Local VOTCA includes
25
26namespace votca {
27namespace xtp {
28
29template <class AtomContainer>
33
34template <class AtomContainer>
36 const SegId& segid) const {
37 if (segid.hasFile()) {
38 std::string filename = segid.FileName();
39 filename = std::regex_replace(filename, std::regex("\\$SEGID"),
40 std::to_string(seg.getId()));
41 filename =
42 std::regex_replace(filename, std::regex("\\$SEGNAME"), seg.getType());
43 return map(seg, filename);
44 } else {
45 QMState state = segid.getQMState();
46 return map(seg, state);
47 }
48}
49
50template <class AtomContainer>
51template <typename T>
53 const std::vector<double>& weights, const T& atoms) const {
54 Eigen::Vector3d map_pos = Eigen::Vector3d::Zero();
55 double map_weight = 0.0;
56 for (Index i = 0; i < Index(atoms.size()); i++) {
57 map_pos += atoms[i]->getPos() * weights[i];
58 map_weight += weights[i];
59 }
60 return map_pos = map_pos / map_weight;
61}
62
63template <class AtomContainer>
65 const tools::Property& frag) const {
66
67 std::vector<double> weights;
68 if (frag.exists(mapatom_xml_.at("weights"))) {
69 weights =
70 frag.get(mapatom_xml_.at("weights")).template as<std::vector<double>>();
71 } else if (frag.exists("weights")) {
72 weights = frag.get("weights").template as<std::vector<double>>();
73 } else {
74 XTP_LOG(Log::error, log_) << " Did not find weights for fragment "
75 << frag.get("name").as<std::string>()
76 << " Using atomic masses" << std::flush;
77 std::string frags =
78 frag.get(mapatom_xml_.at("atoms")).template as<std::string>();
79 tools::Tokenizer tok_atoms(frags, " \t\n");
80 std::vector<std::string> atom_strings = tok_atoms.ToVector();
82 for (auto a_string : atom_strings) {
83 tools::Tokenizer tok_atom(a_string, ":");
84 std::vector<std::string> entries = tok_atom.ToVector();
85 if (entries.size() != 2) {
86 throw std::runtime_error("Cannot get weight from Element for " +
87 a_string);
88 }
89
90 double weight = e.getMass(entries[1]);
91 XTP_LOG(Log::info, log_) << entries[1] << ":" << weight << " ";
92 weights.push_back(weight);
93 }
94 XTP_LOG(Log::error, log_) << std::endl;
95 }
96
97 return weights;
98}
99
100template <class AtomContainer>
102 const tools::Property& frag) {
103 std::vector<std::string> map_atoms =
104 frag.get(mapatom_xml_["atoms"]).template as<std::vector<std::string>>();
105 std::vector<std::string> md_atoms =
106 frag.get("mdatoms").as<std::vector<std::string>>();
107
108 if (md_atoms.size() != map_atoms.size()) {
109 throw std::runtime_error(
110 "Mapping for segment " + seginfo.segname + " fragment " +
111 frag.get("name").as<std::string>() +
112 " does not have same numbers of md and " + mapatom_xml_["atoms"] +
113 "."
114 "If you want to leave a qmatom out, place a ':' instead");
115 }
116
117 std::vector<double> weights = getWeights(frag);
118
119 if (md_atoms.size() != weights.size()) {
120 throw std::runtime_error("Mapping for segment " + seginfo.segname +
121 " fragment " + frag.get("name").as<std::string>() +
122 " does not have same numbers of md and weights. "
123 "If you want to leave a " +
124 mapatom_xml_["name"] +
125 " out, place a '0' instead");
126 }
127
128 FragInfo mapfragment;
129 std::vector<Index> mapatom_ids;
130
131 for (Index i = 0; i < Index(map_atoms.size()); i++) {
132 const std::string& map_string = map_atoms[i];
133 const std::string& md_string = md_atoms[i];
134 const double& weight = weights[i];
135 atom_id md_result = StringToMDIndex(md_string);
136 seginfo.mdatoms.push_back(md_result.first);
137
138 if (map_string == ":") {
139 continue;
140 }
141 atom_id map_result = StringToMapIndex(map_string);
142 mapatom_ids.push_back(map_result.first);
143 seginfo.mapatoms.push_back(map_result);
144 if (Atom::GetElementFromString(md_result.second) != map_result.second) {
146 << "WARNING: mdatom'" << md_result.second << "' and "
147 << mapatom_xml_["name"] << " '" << map_result.second
148 << "' do not have same element" << std::flush;
149 }
150 mapfragment.mapatom_ids.push_back(map_result);
151 mapfragment.weights.push_back(weight);
152 mapfragment.mdatom_ids.push_back(md_result);
153 }
154
155 std::vector<Index> frame =
156 tools::Tokenizer(getFrame(frag), " \t\n").ToVector<Index>();
157 if (frame.size() > 3) {
158 throw std::runtime_error(
159 "Local frame for segment " + seginfo.segname + " fragment " +
160 frag.get("name").as<std::string>() +
161 " has more than 3 atoms, please specify only up to three atoms");
162 } else if (frame.empty()) {
163 throw std::runtime_error("No local frame for segment " + seginfo.segname +
164 " fragment " + frag.get("name").as<std::string>() +
165 " specified");
166 }
167 for (Index atomid : frame) {
168 if (std::find(mapatom_ids.begin(), mapatom_ids.end(), atomid) ==
169 mapatom_ids.end()) {
170 throw std::runtime_error("Atom " + std::to_string(atomid) +
171 " in local frame cannot be found in " +
172 mapatom_xml_["atoms"] + ".");
173 }
174 }
175
176 mapfragment.map_local_frame = frame;
177 seginfo.fragments.push_back(mapfragment);
178}
179
180template <class AtomContainer>
181void SegmentMapper<AtomContainer>::LoadMappingFile(const std::string& mapfile) {
182 tools::Property topology_map;
183 topology_map.LoadFromXML(mapfile);
184
185 std::string molkey = "topology.molecules.molecule";
186 std::vector<tools::Property*> molecules = topology_map.Select(molkey);
187 std::string segkey = "segments.segment";
188 for (tools::Property* mol : molecules) {
189 std::vector<tools::Property*> segments = mol->Select(segkey);
190 for (tools::Property* seg : segments) {
191 Seginfo seginfo;
192
193 std::string coordfile_key = mapatom_xml_["coords"] + "_*";
194 std::vector<tools::Property*> files = seg->Select(coordfile_key);
195 for (tools::Property* file : files) {
196 seginfo.coordfiles[file->name()] = file->as<std::string>();
197 }
198 for (tools::Property* file : seg->Select("chargeresponse_*")) {
199 seginfo.crfiles[file->name()] = file->as<std::string>();
200 }
201 std::string segname = seg->get("name").as<std::string>();
202 seginfo.segname = segname;
203 std::string fragkey = "fragments.fragment";
204
205 seginfo.map2md = seg->get("map2md").as<bool>();
206
207 std::vector<tools::Property*> fragments = seg->Select(fragkey);
208 for (tools::Property* frag : fragments) {
209 ParseFragment(seginfo, *frag);
210 }
211
212 Index map_atom_min_id =
213 std::min_element(seginfo.mapatoms.begin(), seginfo.mapatoms.end(),
214 [](const atom_id& a, const atom_id& b) {
215 return a.first < b.first;
216 })
217 ->first;
218 if (map_atom_min_id != 0) {
219 throw std::runtime_error(
220 mapatom_xml_["atoms"] + " for segment " + seginfo.segname +
221 " do not start at zero index. Each segment "
222 "should have its own coordinate file. If you use an old ctp "
223 "mapping file run 'xtp_update_mapfile' on it.");
224 }
225
226 seginfo.minmax = CalcAtomIdRange(seginfo.mdatoms);
227 segment_info_[segname] = seginfo;
228 }
229 }
230}
231
232template <class AtomContainer>
234 const std::string& map_string) const {
235 tools::Tokenizer tok(map_string, ":");
236 std::vector<std::string> result = tok.ToVector();
237 if (result.size() != 2) {
238 throw std::runtime_error("Entry " + map_string +
239 " is not properly formatted.");
240 }
241 return std::pair<Index, std::string>(std::stoi(result[0]), result[1]);
242}
243template <class AtomContainer>
245 const std::string& md_string) const {
246 tools::Tokenizer tok(md_string, ":");
247 std::vector<std::string> result = tok.ToVector();
248 if (result.size() != 3) {
249 throw std::runtime_error("Entry " + md_string +
250 " is not properly formatted.");
251 }
252 Index atomid = 0;
253 try {
254 atomid = std::stoi(result[2]);
255 } catch (std::invalid_argument&) {
256 throw std::runtime_error("Atom entry " + md_string +
257 " is not well formatted");
258 }
259 return std::pair<Index, std::string>(atomid, result[1]);
260}
261
262template <class AtomContainer>
264 const std::vector<Index>& seg) const {
265 Index max_res_id = *std::max_element(seg.begin(), seg.end());
266 Index min_res_id = *std::min_element(seg.begin(), seg.end());
267 return std::pair<Index, Index>(min_res_id, max_res_id);
268}
269template <class AtomContainer>
271 const Segment& seg) const {
272 Index max_res_id = std::max_element(seg.begin(), seg.end(),
273 [](const Atom& a, const Atom& b) {
274 return a.getId() < b.getId();
275 })
276 ->getId();
277
278 Index min_res_id = std::min_element(seg.begin(), seg.end(),
279 [](const Atom& a, const Atom& b) {
280 return a.getId() < b.getId();
281 })
282 ->getId();
283 return std::pair<Index, Index>(min_res_id, max_res_id);
284}
285
286template <class AtomContainer>
288 const std::vector<mapAtom*>& fragment_mapatoms,
289 const std::vector<const Atom*>& fragment_mdatoms) const {
290 for (Index i = 0; i < Index(fragment_mapatoms.size()); i++) {
291 const Atom* a = fragment_mdatoms[i];
292 mapAtom* b = fragment_mapatoms[i];
293 b->setPos(a->getPos());
294 // No local frame is used here, positions are copied unrotated, so the
295 // bond direction is transferred with the identity.
296 TransferExternalBondDirection(b, a, Eigen::Matrix3d::Identity());
297 }
298}
299
300template <class AtomContainer>
302 Index atomid, const std::vector<mapAtom*>& fragment_mapatoms) const {
303 Index i = 0;
304 for (; i < Index(fragment_mapatoms.size()); i++) {
305 if (fragment_mapatoms[i]->getId() == atomid) {
306 break;
307 }
308 }
309 return i;
310}
311template <class AtomContainer>
313 const FragInfo& frag, const std::vector<mapAtom*>& fragment_mapatoms,
314 const std::vector<const Atom*>& fragment_mdatoms) const {
315 std::vector<Eigen::Vector3d> local_map_frame;
316 std::vector<Eigen::Vector3d> local_md_frame;
317 for (Index id : frag.map_local_frame) {
318 Index i = FindVectorIndexFromAtomId(id, fragment_mapatoms);
319 local_map_frame.push_back(fragment_mapatoms[i]->getPos());
320 local_md_frame.push_back(fragment_mdatoms[i]->getPos());
321 }
322
323 Index symmetry = frag.map_local_frame.size();
324 Eigen::Vector3d map_com = CalcWeightedPos(frag.weights, fragment_mapatoms);
325 Eigen::Vector3d md_com = CalcWeightedPos(frag.weights, fragment_mdatoms);
326
327 Eigen::Vector3d shift_map2md = md_com - map_com;
328
329 Eigen::Matrix3d rot_map = Eigen::Matrix3d::Identity();
330 Eigen::Matrix3d rot_md = Eigen::Matrix3d::Identity();
331
332 // building local frame
333 if (symmetry > 1) {
334 // middle atom is the origin
335 Eigen::Vector3d x_map = local_map_frame[0] - local_map_frame[1];
336 Eigen::Vector3d x_md = local_md_frame[0] - local_md_frame[1];
337 Eigen::Vector3d y_map;
338 Eigen::Vector3d y_md;
339 Eigen::Vector3d z_map;
340 Eigen::Vector3d z_md;
341 if (symmetry == 3) {
342 y_map = local_map_frame[2] - local_map_frame[1];
343 y_md = local_md_frame[2] - local_md_frame[1];
344 z_map = x_map.cross(y_map);
345 z_md = x_md.cross(y_md);
346 y_map = z_map.cross(x_map);
347 y_md = z_md.cross(x_md);
348
349 } else {
350 Eigen::Vector3d unit = Eigen::Vector3d::UnitX();
351 if (std::abs(unit.dot(x_map) / x_map.norm()) < 1e-6) {
352 unit = Eigen::Vector3d::UnitY();
353 }
354 y_map = (x_map.cross(unit));
355 if (std::abs(unit.dot(x_md) / x_md.norm()) < 1e-6) {
356 unit = Eigen::Vector3d::UnitX();
357 }
358 y_md = (x_md.cross(unit));
359 z_map = x_map.cross(y_map);
360 z_md = x_md.cross(y_md);
361 }
362
363 if (x_map.squaredNorm() < 1e-18 || y_map.squaredNorm() < 1e-18 ||
364 z_map.squaredNorm() < 1e-18) {
365 throw std::runtime_error(
366 mapatom_xml_.at("tag") +
367 " basis vectors are very small, choose different local basis");
368 }
369 rot_map.col(0) = x_map.normalized();
370 rot_map.col(1) = y_map.normalized();
371 rot_map.col(2) = z_map.normalized();
372
373 if (x_md.squaredNorm() < 1e-18 || y_md.squaredNorm() < 1e-18 ||
374 z_md.squaredNorm() < 1e-18) {
375 throw std::runtime_error(
376 "MD basis vectors are very small, choose different local basis");
377 }
378 rot_md.col(0) = x_md.normalized();
379 rot_md.col(1) = y_md.normalized();
380 rot_md.col(2) = z_md.normalized();
381 }
382 Eigen::Matrix3d rotateMAP2MD = rot_md * rot_map.transpose();
383 for (Index i = 0; i < Index(fragment_mapatoms.size()); i++) {
384 mapAtom* atom = fragment_mapatoms[i];
385 if (getRank(*atom) > 0 && symmetry < 3) {
386 throw std::runtime_error(
387 "Local frame has less than 3 atoms, thus higher rank multipoles "
388 "cannot be mapped.");
389 }
390 atom->Translate(shift_map2md);
391 atom->Rotate(rotateMAP2MD, md_com);
392 // A direction is translation invariant, so only the rotation applies.
393 TransferExternalBondDirection(atom, fragment_mdatoms[i], rotateMAP2MD);
394 }
395}
396template <class AtomContainer>
398 QMState state) const {
399 if (segment_info_.count(seg.getType()) == 0) {
400 throw std::runtime_error(
401 "Could not find a Segment of name: " + seg.getType() + " in mapfile.");
402 }
403 Seginfo seginfo = segment_info_.at(seg.getType());
404 std::string coordsfiletag =
405 mapatom_xml_.at("coords") + "_" + state.Type().ToString();
406 if (seginfo.coordfiles.count(coordsfiletag) == 0) {
407 throw std::runtime_error("Could not find a coordinate file for " +
408 seg.getType() +
409 " id:" + std::to_string(seg.getId()) +
410 " segment/state: " + coordsfiletag);
411 }
412 std::string coordsfilename = seginfo.coordfiles.at(coordsfiletag);
413 AtomContainer result = map(seg, coordsfilename);
414 AttachChargeResponse(result, seginfo, state);
415 return result;
416}
417
418template <>
420 PolarSegment& result, const Seginfo& seginfo, const QMState& state) const {
421 const std::string tag = "chargeresponse_" + state.Type().ToString();
422 if (seginfo.crfiles.count(tag) == 0) {
423 return;
424 }
425 const std::string& filename = seginfo.crfiles.at(tag);
427 cr.LoadFromFile(filename);
428 // The mapped segment holds the template atoms seginfo.mapatoms in that
429 // order; Pi must follow them. Every atom must be mapped: Pi of a part of
430 // a molecule does not conserve charge.
431 std::vector<Index> order;
432 for (const atom_id& id : seginfo.mapatoms) {
433 if (id.first >= cr.size() ||
434 cr.Elements()[std::size_t(id.first)] != id.second) {
435 throw std::runtime_error(
436 "Segment " + seginfo.segname + ": " + mapatom_xml_.at("atoms") +
437 " entry " + std::to_string(id.first) + ":" + id.second +
438 " does not match the charge-response file " + filename +
439 " (same atoms in the same order as the multipoles file needed)");
440 }
441 order.push_back(id.first);
442 }
443 if (Index(order.size()) != cr.size()) {
444 throw std::runtime_error(
445 "Segment " + seginfo.segname + " maps " + std::to_string(order.size()) +
446 " of the " + std::to_string(cr.size()) +
447 " atoms of its charge-response file " + filename +
448 "; the charge-response model needs the whole molecule");
449 }
450 result.setChargeResponse(cr.Permuted(order));
451 XTP_LOG(Log::info, log_) << "Segment " << seginfo.segname << " "
452 << result.getId() << ": charge response from "
453 << filename << std::flush;
454}
455
456template <class AtomContainer>
458 const Segment& seg, const std::string& coordfilename) const {
459
460 if (segment_info_.count(seg.getType()) == 0) {
461 throw std::runtime_error(
462 "Could not find a Segment of name: " + seg.getType() + " in mapfile.");
463 }
464 Seginfo seginfo = segment_info_.at(seg.getType());
465 if (Index(seginfo.mdatoms.size()) != seg.size()) {
466 throw std::runtime_error(
467 "Segment '" + seg.getType() +
468 "' does not contain the same number of atoms as mapping file: " +
469 std::to_string(seginfo.mdatoms.size()) + " vs. " +
470 std::to_string(seg.size()));
471 }
472
473 std::pair<Index, Index> minmax_map = seginfo.minmax;
474 std::pair<Index, Index> minmax = CalcAtomIdRange(seg);
475
476 if ((minmax_map.first - minmax_map.second) !=
477 (minmax.first - minmax.second)) {
478 throw std::runtime_error("AtomId range for segment " + seg.getType() + ":" +
479 std::to_string(seg.getId()) +
480 " and the mapping do not agree: Segment[" +
481 std::to_string(minmax.first) + "," +
482 std::to_string(minmax.second) + "] Map[" +
483 std::to_string(minmax_map.first) + "," +
484 std::to_string(minmax_map.second) + "]");
485 }
486
487 Index atomidoffset = minmax.first - minmax_map.first;
488
489 AtomContainer Result(seg.getType(), seg.getId());
490 Result.LoadFromFile(coordfilename);
491
492 // The coordinate file may contain more atoms than the mapping references
493 // (e.g. one template file reused for differently truncated mappings);
494 // only too few atoms is an error.
495 if (Result.size() < Index(seginfo.mapatoms.size())) {
496 throw std::runtime_error(
497 mapatom_xml_.at("tag") + "Segment '" + seg.getType() +
498 "' does not contain enough atoms for the mapping file: needs at "
499 "least " +
500 std::to_string(seginfo.mapatoms.size()) + ", has " +
501 std::to_string(Result.size()));
502 }
503 // The count check above does not guarantee that each referenced index is
504 // in range, since the indices need not be 0..N-1.
505 for (const atom_id& id : seginfo.mapatoms) {
506 if (id.first < 0 || id.first >= Result.size()) {
507 throw std::runtime_error(
508 mapatom_xml_.at("tag") + "Segment '" + seg.getType() +
509 "' references " + mapatom_xml_.at("atoms") + " index " +
510 std::to_string(id.first) +
511 ", which is out of range for the coordinate file '" + coordfilename +
512 "' (" + std::to_string(Result.size()) + " atoms).");
513 }
514 }
515
516 // MD atom ID -> mapped atom for the whole segment (a bonded partner may be
517 // in another fragment); used by TransferBondedPartners below.
518 std::map<Index, mapAtom*> md_id_to_map_atom;
519
520 for (FragInfo& frag : seginfo.fragments) {
521 for (atom_id& id : frag.mdatom_ids) {
522 id.first += atomidoffset;
523 }
524
525 std::vector<mapAtom*> fragment_mapatoms;
526 for (const atom_id& id : frag.mapatom_ids) {
527 if (id.second != Result[id.first].getElement()) {
528 throw std::runtime_error(
529 "Element of mapping atom " + std::to_string(id.first) + ":" +
530 id.second + " does not agree with Element of parsed Atom " +
531 Result[id.first].getElement());
532 }
533 fragment_mapatoms.push_back(&Result[id.first]);
534 }
535 std::vector<const Atom*> fragment_mdatoms;
536 for (const atom_id& id : frag.mdatom_ids) {
537 const Atom* atom = seg.getAtom(id.first);
538 if (atom == nullptr) {
539 throw std::runtime_error(
540 "Could not find an atom with name:" + id.second + "id" +
541 std::to_string(id.first) + " in segment " + seg.getType());
542 }
543 fragment_mdatoms.push_back(atom);
544 }
545
546 for (Index i = 0; i < Index(fragment_mdatoms.size()); i++) {
547 md_id_to_map_atom[fragment_mdatoms[i]->getId()] = fragment_mapatoms[i];
548 }
549
550 if (seginfo.map2md) {
551 PlaceMapAtomonMD(fragment_mapatoms, fragment_mdatoms);
552 } else {
553 MapMapAtomonMD(frag, fragment_mapatoms, fragment_mdatoms);
554 }
555 }
556
557 // Second pass, once md_id_to_map_atom is complete: translate MD-level
558 // bonded-partner IDs to mapped IDs. Partners in later fragments are not in
559 // the lookup during the first loop.
560 for (FragInfo& frag : seginfo.fragments) {
561 for (const atom_id& id : frag.mdatom_ids) {
562 const Atom* md_atom = seg.getAtom(id.first);
563 if (md_atom == nullptr) {
564 continue;
565 }
566 auto it = md_id_to_map_atom.find(id.first);
567 if (it != md_id_to_map_atom.end()) {
568 TransferBondedPartners(it->second, md_atom, md_id_to_map_atom);
569 }
570 }
571 }
572
573 // Return only the atoms referenced by seginfo.mapatoms, in mapping-file
574 // order (parallel to mdatoms); unreferenced template atoms must not leak
575 // into the result. The qmatoms entries may be reordered (e.g.
576 // 0:C 2:H 1:H 3:H), so each copy is renumbered with setID() to keep
577 // getId() equal to the position in the container, which e.g. the
578 // fragment A/B classification in IPodCoupling::EvalJob relies on.
579 // Atoms are copied rather than rebuilt to keep multipole data of
580 // StaticSite/PolarSite. Bonded-partner IDs refer to template atom IDs and
581 // are rewritten to the new numbering.
582 std::map<Index, Index> old_to_new;
583 for (Index k = 0; k < Index(seginfo.mapatoms.size()); k++) {
584 old_to_new[Result[seginfo.mapatoms[k].first].getId()] = k;
585 }
586 AtomContainer filtered(seg.getType(), seg.getId());
587 for (const atom_id& id : seginfo.mapatoms) {
588 mapAtom atom_copy = Result[id.first];
589 atom_copy.setID(filtered.size());
590 RemapBondedPartners(atom_copy, old_to_new);
591 filtered.push_back(atom_copy);
592 }
593 filtered.calcPos();
594 return filtered;
595}
596
597template class SegmentMapper<QMMolecule>;
598template class SegmentMapper<StaticSegment>;
599template class SegmentMapper<PolarSegment>;
600
601} // namespace xtp
602} // namespace votca
information about an element
Definition elements.h:42
class to manage program options with xml serialization functionality
Definition property.h:55
Property & get(const std::string &key)
get existing property
Definition property.cc:79
bool exists(const std::string &key) const
check whether property exists
Definition property.cc:122
T as() const
return value as type
Definition property.h:283
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
const std::string & getType() const
void push_back(const T &atom)
std::vector< T >::iterator end()
std::vector< T >::iterator begin()
static std::string GetElementFromString(const std::string &MDName)
Definition atom.cc:71
const Eigen::Vector3d & getPos() const
Definition atom.h:77
Charge-response matrix Pi of one molecule type.
const std::vector< std::string > & Elements() const
ChargeResponse Permuted(const std::vector< Index > &order) const
void LoadFromFile(const std::string &filename)
Reads a .crm file and checks it (see Check). Positions are in bohr.
void setChargeResponse(const ChargeResponse &cr)
Logger is used for thread-safe output of messages.
Definition logger.h:164
std::string ToString() const
Definition qmstate.cc:35
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
Definition qmstate.h:135
const QMStateType & Type() const
Definition qmstate.h:154
QMState getQMState() const
Definition segid.h:63
std::string FileName() const
Definition segid.h:62
bool hasFile() const
Definition segid.h:61
std::pair< Index, std::string > atom_id
void LoadMappingFile(const std::string &mapfile)
std::map< std::string, Seginfo > segment_info_
void MapMapAtomonMD(const FragInfo &frag, const std::vector< mapAtom * > &fragment_mapatoms, const std::vector< const Atom * > &fragment_mdatoms) const
std::map< std::string, std::string > mapatom_xml_
void ParseFragment(Seginfo &seginfo, const tools::Property &frag)
std::pair< Index, Index > CalcAtomIdRange(const Segment &seg) const
atom_id StringToMapIndex(const std::string &map_string) const
atom_id StringToMDIndex(const std::string &md_string) const
void AttachChargeResponse(AtomContainer &, const Seginfo &, const QMState &) const
Index getRank(const mapAtom &atom) const
void TransferExternalBondDirection(mapAtom *, const Atom *, const Eigen::Matrix3d &) const
void PlaceMapAtomonMD(const std::vector< mapAtom * > &fragment_mapatoms, const std::vector< const Atom * > &fragment_mdatoms) const
Index FindVectorIndexFromAtomId(Index atomid, const std::vector< mapAtom * > &fragment_mapatoms) const
Eigen::Vector3d CalcWeightedPos(const std::vector< double > &weights, const T &atoms) const
std::string getFrame(const tools::Property &frag) const
void RemapBondedPartners(mapAtom &, const std::map< Index, Index > &) const
AtomContainer map(const Segment &seg, const SegId &segid) const
typename AtomContainer::Atom_Type mapAtom
std::vector< double > getWeights(const tools::Property &frag) const
void TransferBondedPartners(mapAtom *, const Atom *, const std::map< Index, mapAtom * > &) const
const Atom * getAtom(Index id) const
Definition segment.cc:32
#define XTP_LOG(level, log)
Definition logger.h:40
Charge transport classes.
Definition ERIs.h:28
ClassicalSegment< PolarSite > PolarSegment
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
std::vector< Index > map_local_frame
std::vector< atom_id > mapatom_ids
std::vector< atom_id > mdatom_ids
std::pair< Index, Index > minmax
std::vector< FragInfo > fragments
std::map< std::string, std::string > crfiles
std::map< std::string, std::string > coordfiles
std::vector< atom_id > mapatoms