e9f9d5374d47be1e683ade016c4402e0d1595192
[alexxy/gromacs.git] / src / gromacs / trajectoryanalysis / topologyinformation.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2018,2019, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::TopologyInformation.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \author Mark Abraham <mark.j.abraham@gmail.com>
41  * \inlibraryapi
42  * \ingroup module_trajectoryanalysis
43  */
44 #ifndef GMX_TRAJECTORYANALYSIS_TOPOLOGYINFORMATION_H
45 #define GMX_TRAJECTORYANALYSIS_TOPOLOGYINFORMATION_H
46
47 #include <memory>
48 #include <string>
49 #include <vector>
50
51 #include "gromacs/math/vectypes.h"
52 #include "gromacs/topology/atoms.h"
53 #include "gromacs/topology/topology.h"
54 #include "gromacs/utility/classhelpers.h"
55
56 //! Forward declaration
57 typedef struct gmx_rmpbc* gmx_rmpbc_t;
58
59 namespace gmx
60 {
61
62 template<typename T>
63 class ArrayRef;
64
65 class TopologyInformation;
66 class TrajectoryAnalysisRunnerCommon;
67
68 /*! \libinternal
69  * \brief Topology information available to a trajectory analysis module.
70  *
71  * This class is used to provide topology information to trajectory
72  * analysis modules and to manage memory for them. Having a single
73  * wrapper object instead of passing each item separately makes
74  * TrajectoryAnalysisModule interface simpler, and also reduces the
75  * need to change existing code if additional information is added.
76  *
77  * It is intended that eventually most clients of this class will be
78  * analysis tools ported to the new analysis framework, but we will
79  * use this infrastructure also from the legacy analysis tools during
80  * the transition period. That will make it easier to put those tools
81  * under tests, and eventually port them.
82  *
83  * Methods in this class do not throw if not explicitly stated.
84  *
85  * The main data content is constant once loaded, but some content is
86  * constructed only when required (e.g. atoms_ and
87  * expandedTopology_). Their data members are mutable, so that the
88  * lazy construction idiom works properly. Some clients wish to modify
89  * the t_atoms, so there is an efficient mechanism for them to get a
90  * copy they can modify without disturbing this class. (The
91  * implementation releases the cached lazily constructed atoms_, but
92  * from the point of view of the caller, that is a copy.) The getters
93  * and copy functions are const for callers, which correctly expresses
94  * that the topology information is not being changed, merely copied
95  * and presented in a different form.
96  *
97  * \ingroup module_trajectoryanalysis
98  */
99 class TopologyInformation
100 {
101 public:
102     //! Returns true if a topology file was loaded.
103     bool hasTopology() const { return hasLoadedMtop_; }
104     //! Returns true if a full topology file was loaded.
105     bool hasFullTopology() const { return bTop_; }
106     /*! \brief Builder function to fill the contents of
107      * TopologyInformation in \c topInfo from \c filename.
108      *
109      * Different tools require, might need, would benefit from, or
110      * do not need topology information. This functions implements
111      * the two-phase construction that is currently needed to
112      * support that.
113      *
114      * Any coordinate or run input file format will work, but the
115      * kind of data available from the getter methods afterwards
116      * will vary. For example, the mtop() available after reading
117      * a plain structure file will have a single molecule block and
118      * molecule type, regardless of contents.
119      *
120      * After reading, this object can return many kinds of primary
121      * and derived data structures to its caller.
122      *
123      * \todo This should throw upon error but currently does
124      * not. */
125     void fillFromInputFile(const std::string& filename);
126     /*! \brief Returns the loaded topology, or nullptr if not loaded. */
127     gmx_mtop_t* mtop() const { return mtop_.get(); }
128     //! Returns the loaded topology fully expanded, or nullptr if no topology is available.
129     const gmx_localtop_t* expandedTopology() const;
130     /*! \brief Returns a read-only handle to the fully expanded
131      * atom data arrays, which might be valid but empty if no
132      * topology is available. */
133     const t_atoms* atoms() const;
134     /*! \brief Copies the fully expanded atom data arrays, which
135      * might be valid but empty if no topology is available. */
136     AtomsDataPtr copyAtoms() const;
137     //! Returns the ePBC field from the topology.
138     int ePBC() const { return ePBC_; }
139     /*! \brief
140      * Gets the configuration positions from the topology file.
141      *
142      * If TrajectoryAnalysisSettings::efUseTopX has not been specified,
143      * this method should not be called.
144      *
145      * \throws  APIError if topology position coordinates are not available
146      */
147     ArrayRef<const RVec> x() const;
148     /*! \brief
149      * Gets the configuration velocities from the topology file.
150      *
151      * If TrajectoryAnalysisSettings::efUseTopV has not been specified,
152      * this method should not be called.
153      *
154      * \throws  APIError if topology velocity coordinates are not available
155      */
156     ArrayRef<const RVec> v() const;
157     /*! \brief
158      * Gets the configuration box from the topology file.
159      *
160      * \param[out] box   Box size from the topology file, must not be nullptr.
161      */
162     void getBox(matrix box) const;
163     /*! \brief Returns a name for the topology.
164      *
165      * If a full topology was read from a a file, returns the name
166      * it contained, otherwise the empty string. */
167     const char* name() const;
168
169     TopologyInformation();
170     ~TopologyInformation();
171
172 private:
173     //! The topology structure, or nullptr if no topology loaded.
174     std::unique_ptr<gmx_mtop_t> mtop_;
175     //! Whether a topology has been loaded.
176     bool hasLoadedMtop_;
177     //! The fully expanded topology structure, nullptr if not yet constructed.
178     mutable ExpandedTopologyPtr expandedTopology_;
179     //! The fully expanded atoms data structure, nullptr if not yet constructed.
180     mutable AtomsDataPtr atoms_;
181     //! true if full tpx file was loaded, false otherwise.
182     bool bTop_;
183     //! Position coordinates from the topology (can be nullptr).
184     std::vector<RVec> xtop_;
185     //! Velocity coordinates from the topology (can be nullptr).
186     std::vector<RVec> vtop_;
187     //! The box loaded from the topology file.
188     matrix boxtop_{};
189     //! The ePBC field loaded from the topology file.
190     int ePBC_;
191
192     // TODO This type is probably movable if we need that.
193     GMX_DISALLOW_COPY_AND_ASSIGN(TopologyInformation);
194
195     /*! \brief
196      * Needed to initialize the data.
197      */
198     friend class TrajectoryAnalysisRunnerCommon;
199 };
200
201 //! Convenience overload useful for implementing legacy tools.
202 gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation& topInfo);
203
204 } // namespace gmx
205
206 #endif