Make PBC type enumeration into PbcType enum class
[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,2020, 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 enum class PbcType : int;
59
60 namespace gmx
61 {
62
63 template<typename T>
64 class ArrayRef;
65
66 class TopologyInformation;
67 class TrajectoryAnalysisRunnerCommon;
68
69 /*! \libinternal
70  * \brief Topology information available to a trajectory analysis module.
71  *
72  * This class is used to provide topology information to trajectory
73  * analysis modules and to manage memory for them. Having a single
74  * wrapper object instead of passing each item separately makes
75  * TrajectoryAnalysisModule interface simpler, and also reduces the
76  * need to change existing code if additional information is added.
77  *
78  * It is intended that eventually most clients of this class will be
79  * analysis tools ported to the new analysis framework, but we will
80  * use this infrastructure also from the legacy analysis tools during
81  * the transition period. That will make it easier to put those tools
82  * under tests, and eventually port them.
83  *
84  * Methods in this class do not throw if not explicitly stated.
85  *
86  * The main data content is constant once loaded, but some content is
87  * constructed only when required (e.g. atoms_ and
88  * expandedTopology_). Their data members are mutable, so that the
89  * lazy construction idiom works properly. Some clients wish to modify
90  * the t_atoms, so there is an efficient mechanism for them to get a
91  * copy they can modify without disturbing this class. (The
92  * implementation releases the cached lazily constructed atoms_, but
93  * from the point of view of the caller, that is a copy.) The getters
94  * and copy functions are const for callers, which correctly expresses
95  * that the topology information is not being changed, merely copied
96  * and presented in a different form.
97  *
98  * \ingroup module_trajectoryanalysis
99  */
100 class TopologyInformation
101 {
102 public:
103     //! Returns true if a topology file was loaded.
104     bool hasTopology() const { return hasLoadedMtop_; }
105     //! Returns true if a full topology file was loaded.
106     bool hasFullTopology() const { return bTop_; }
107     /*! \brief Builder function to fill the contents of
108      * TopologyInformation in \c topInfo from \c filename.
109      *
110      * Different tools require, might need, would benefit from, or
111      * do not need topology information. This functions implements
112      * the two-phase construction that is currently needed to
113      * support that.
114      *
115      * Any coordinate or run input file format will work, but the
116      * kind of data available from the getter methods afterwards
117      * will vary. For example, the mtop() available after reading
118      * a plain structure file will have a single molecule block and
119      * molecule type, regardless of contents.
120      *
121      * After reading, this object can return many kinds of primary
122      * and derived data structures to its caller.
123      *
124      * \todo This should throw upon error but currently does
125      * not. */
126     void fillFromInputFile(const std::string& filename);
127     /*! \brief Returns the loaded topology, or nullptr if not loaded. */
128     gmx_mtop_t* mtop() const { return mtop_.get(); }
129     //! Returns the loaded topology fully expanded, or nullptr if no topology is available.
130     const gmx_localtop_t* expandedTopology() const;
131     /*! \brief Returns a read-only handle to the fully expanded
132      * atom data arrays, which might be valid but empty if no
133      * topology is available. */
134     const t_atoms* atoms() const;
135     /*! \brief Copies the fully expanded atom data arrays, which
136      * might be valid but empty if no topology is available. */
137     AtomsDataPtr copyAtoms() const;
138     //! Returns the pbcType field from the topology.
139     PbcType pbcType() const { return pbcType_; }
140     /*! \brief
141      * Gets the configuration positions from the topology file.
142      *
143      * If TrajectoryAnalysisSettings::efUseTopX has not been specified,
144      * this method should not be called.
145      *
146      * \throws  APIError if topology position coordinates are not available
147      */
148     ArrayRef<const RVec> x() const;
149     /*! \brief
150      * Gets the configuration velocities from the topology file.
151      *
152      * If TrajectoryAnalysisSettings::efUseTopV has not been specified,
153      * this method should not be called.
154      *
155      * \throws  APIError if topology velocity coordinates are not available
156      */
157     ArrayRef<const RVec> v() const;
158     /*! \brief
159      * Gets the configuration box from the topology file.
160      *
161      * \param[out] box   Box size from the topology file, must not be nullptr.
162      */
163     void getBox(matrix box) const;
164     /*! \brief Returns a name for the topology.
165      *
166      * If a full topology was read from a a file, returns the name
167      * it contained, otherwise the empty string. */
168     const char* name() const;
169
170     TopologyInformation();
171     ~TopologyInformation();
172
173 private:
174     //! The topology structure, or nullptr if no topology loaded.
175     std::unique_ptr<gmx_mtop_t> mtop_;
176     //! Whether a topology has been loaded.
177     bool hasLoadedMtop_;
178     //! The fully expanded topology structure, nullptr if not yet constructed.
179     mutable ExpandedTopologyPtr expandedTopology_;
180     //! The fully expanded atoms data structure, nullptr if not yet constructed.
181     mutable AtomsDataPtr atoms_;
182     //! true if full tpx file was loaded, false otherwise.
183     bool bTop_;
184     //! Position coordinates from the topology (can be nullptr).
185     std::vector<RVec> xtop_;
186     //! Velocity coordinates from the topology (can be nullptr).
187     std::vector<RVec> vtop_;
188     //! The box loaded from the topology file.
189     matrix boxtop_{};
190     //! The pbcType field loaded from the topology file.
191     PbcType pbcType_;
192
193     // TODO This type is probably movable if we need that.
194     GMX_DISALLOW_COPY_AND_ASSIGN(TopologyInformation);
195
196     /*! \brief
197      * Needed to initialize the data.
198      */
199     friend class TrajectoryAnalysisRunnerCommon;
200 };
201
202 //! Convenience overload useful for implementing legacy tools.
203 gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation& topInfo);
204
205 } // namespace gmx
206
207 #endif