1 /*
2  * Copyright 2009-2020 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 #pragma once
19 #ifndef VOTCA_XTP_SEGMENTMAPPER_H
20 #define VOTCA_XTP_SEGMENTMAPPER_H
21 
22 // Standard includes
23 #include <type_traits>
24 
25 // VOTCA includes
26 #include <votca/csg/pdbwriter.h>
27 #include <votca/tools/property.h>
28 
29 // Local VOTCA includes
30 #include "classicalsegment.h"
31 #include "logger.h"
32 #include "qmmolecule.h"
33 #include "segid.h"
34 #include "topology.h"
35 
36 namespace votca {
37 namespace xtp {
38 template <class AtomContainer>
39 class SegmentMapper {
40  public:
41   SegmentMapper(Logger& log);
42 
43   void LoadMappingFile(const std::string& mapfile);
44 
45   AtomContainer map(const Segment& seg, const SegId& segid) const;
46 
47   AtomContainer map(const Segment& seg, QMState state) const;
48 
49   AtomContainer map(const Segment& seg, const std::string& coordfilename) const;
50 
51  private:
52   using mapAtom = typename AtomContainer::Atom_Type;
53 
54   using atom_id = std::pair<Index, std::string>;
55 
56   struct FragInfo {
57     std::vector<double> weights;
58     std::vector<atom_id> mapatom_ids;
59     std::vector<atom_id> mdatom_ids;
60     std::vector<Index> map_local_frame;
61   };
62 
63   struct Seginfo {
64     std::pair<Index, Index> minmax;
65     std::vector<Index> mdatoms;
66     std::vector<FragInfo> fragments;
67     bool map2md;
68     std::string segname;
69     std::vector<double> weights;
70     std::vector<atom_id> mapatoms;
71     std::map<std::string, std::string> coordfiles;
72   };
73   std::map<std::string, std::string> mapatom_xml_;
74   std::map<std::string, Seginfo> segment_info_;
75 
76   Index FindVectorIndexFromAtomId(
77       Index atomid, const std::vector<mapAtom*>& fragment_mapatoms) const;
78 
79   void ParseFragment(Seginfo& seginfo, const tools::Property& frag);
80 
81   template <typename T>
82   Eigen::Vector3d CalcWeightedPos(const std::vector<double>& weights,
83                                   const T& atoms) const;
84 
85   void PlaceMapAtomonMD(const std::vector<mapAtom*>& fragment_mapatoms,
86                         const std::vector<const Atom*>& fragment_mdatoms) const;
87 
88   void MapMapAtomonMD(const FragInfo& frag,
89                       const std::vector<mapAtom*>& fragment_mapatoms,
90                       const std::vector<const Atom*>& fragment_mdatoms) const;
91 
92   Logger& log_;
93   std::pair<Index, Index> CalcAtomIdRange(const Segment& seg) const;
94   std::pair<Index, Index> CalcAtomIdRange(const std::vector<Index>& seg) const;
95 
96   atom_id StringToMapIndex(const std::string& map_string) const;
97 
98   atom_id StringToMDIndex(const std::string& md_string) const;
99 
getRank(const mapAtom & atom)100   Index getRank(const mapAtom& atom) const { return atom.getRank(); }
101 
102   std::vector<double> getWeights(const tools::Property& frag) const;
103 
getFrame(const tools::Property & frag)104   std::string getFrame(const tools::Property& frag) const {
105     if (frag.exists(mapatom_xml_.at("frame"))) {
106       return frag.get(mapatom_xml_.at("frame")).template as<std::string>();
107     }
108     return frag.get("localframe").template as<std::string>();
109   }
110 
FillMap()111   void FillMap() {
112     mapatom_xml_["tag"] = "MP";
113     mapatom_xml_["name"] = "MPole";
114     mapatom_xml_["atoms"] = "mpoles";
115     mapatom_xml_["coords"] = "multipoles";
116     mapatom_xml_["weights"] = "mp_weights";
117     mapatom_xml_["frame"] = "mp_localframe";
118   }
119 };
120 
121 template <>
FillMap()122 inline void SegmentMapper<QMMolecule>::FillMap() {
123   mapatom_xml_["tag"] = "QM";
124   mapatom_xml_["name"] = "QMAtom";
125   mapatom_xml_["atoms"] = "qmatoms";
126   mapatom_xml_["coords"] = "qmcoords";
127   mapatom_xml_["weights"] = "qm_weights";
128   mapatom_xml_["frame"] = "qm_localframe";
129 }
130 
131 template <>
getRank(const QMAtom &)132 inline Index SegmentMapper<QMMolecule>::getRank(const QMAtom&) const {
133   return 0;
134 }
135 
136 using QMMapper = SegmentMapper<QMMolecule>;
137 using StaticMapper = SegmentMapper<StaticSegment>;
138 using PolarMapper = SegmentMapper<PolarSegment>;
139 }  // namespace xtp
140 }  // namespace votca
141 
142 #endif  // VOTCA_XTP_SEGMENTMAPPER_H
143