Rename remaining large_int to int64
[gromacs.git] / doxygen / analysistemplate.md
blobac7dada4e668e1926aebe724e675c428e513d0de
1 Example code for writing trajectory analysis tools {#page_analysistemplate}
2 ==================================================
4 \Gromacs installation includes a template for writing trajectory analysis
5 tools using \ref page_analysisframework.
6 It can be found from `share/gromacs/template/` under the installation
7 directory, and from `share/template/` in the source distribution.
9 The full source code for the file is also included in this documentation:
10 \ref template.cpp "template.cpp"
11 The rest of this page walks through the code to explain the different parts.
13 \dontinclude template.cpp
15 Global definitions
16 ==================
18 We start by including some generic C++ headers:
19 \skip  <string>
20 \until <vector>
21 and continue by including the header for the analysis library:
22 \skipline <gromacs/trajectoryanalysis.h>
23 This header includes other headers that together define all the basic data
24 types needed for writing trajectory analysis tools.
25 For convenience, we also import all names from the ::gmx namespace into the
26 global scope to avoid repeating the name everywhere:
27 \skipline using namespace
30 Tool module class declaration
31 =============================
33 We then define a class that implements our analysis tool:
34 \skip  AnalysisTemplate
35 \until };
36 The analysis tool class inherits from gmx::TrajectoryAnalysisModule, which
37 is an interface with a few convenience functions for easier interfacing
38 with other code.
39 Below, we walk through the different methods as implemented in the
40 template (note that the template does not implement some of the virtual
41 methods because they are less often needed), discussing some issues that can
42 arise in more complex cases.
43 See documentation of gmx::TrajectoryAnalysisModule for a full description of
44 the available virtual methods and convenience functions.
45 The first block of member variables are used to contain values provided to
46 the different options.  They will vary depending on the needs of the
47 analysis tool.
48 The AnalysisNeighborhood object provides neighborhood searching that is used
49 in the analysis.
50 The final block of variables are used to process output data.
51 See initAnalysis() for details on how they are used.
53 For the template, we do not need any custom frame-local data.  If you think
54 you need some for more complex analysis needs, see documentation of
55 gmx::TrajectoryAnalysisModuleData for more details.
56 If you do not care about parallelization, you do not need to consider this
57 part.  You can simply declare all variables in the module class itself,
58 initialize them in gmx::TrajectoryAnalysisModule::initAnalysis(), and do any
59 postprocessing in gmx::TrajectoryAnalysisModule::finishAnalysis()).
62 Construction
63 ============
65 The constructor (and possible destructor) of the analysis module should be
66 simple: the constructor should just initialize default values, and the
67 destructor should free any memory managed by the module.  For the template,
68 we have no attributes in our class that need to be explicitly freed, so we
69 declare only a constructor:
70 \skip  AnalysisTemplate
71 \until }
72 In addition to initializing local variables that don't have default
73 constructors, we also provide a title and one-line description of our module
74 to the \p options_ object.  These values will only affect the help output.
77 Input options
78 =============
80 Initialization of the module is split into a few methods, two of which are
81 used in the template.  gmx::TrajectoryAnalysisModule::initOptions() is used
82 to set up options understood by the module, as well as for setting up
83 different options through gmx::TrajectoryAnalysisSettings (see the
84 documentation of that class for more details):
85 \skip  void
86 \until settings->
87 \until }
88 For the template, we first set a description text for the tool (used for
89 help text).  Then we declare an option to specify the output file name,
90 followed by options that are used to set selections, and finally an option
91 to set a cutoff value.  For the cutoff, the default value will be the one
92 that was set in the constructor, but it would also be possible to explicitly
93 set it here.  The values provided by the user for the options will be stored
94 in member variables.  Finally, we indicate that the tool always requires
95 topology information.  This is done for demonstration purposes only; the
96 code in the template works even without a topology.
98 For additional documentation on how to define different kinds of options, see
99 gmx::Options, basicoptions.h, and gmx::SelectionOption.  You only need to
100 define options that are specific to the analysis; common options, e.g., for
101 specifying input topology and trajectories are added by the framework.
103 To adjust settings or selection options (e.g., the number of accepted
104 selections) based on option values, you need to override
105 gmx::TrajectoryAnalysisModule::optionsFinished().  For simplicity,
106 this is not done in the template.
109 Analysis initialization
110 =======================
112 The actual analysis is initialized in
113 gmx::TrajectoryAnalysisModule::initAnalysis():
114 \skip  void
115 \until }
116 \until }
117 Information about the topology is passed as a parameter.  The settings
118 object can also be used to access information about user input.
120 One of the main tasks of this method is to set up appropriate
121 gmx::AnalysisData objects and modules for them (see
122 gmx::TrajectoryAnalysisModule for the general approach).
123 These objects will be used to process output from the tool.  Their main
124 purpose is to support parallelization, but even if you don't care about
125 parallelism, they still provide convenient building blocks, e.g., for
126 histogramming and file output.
128 For the template, we first set the cutoff for the neighborhood search.
130 Then, we create and register one gmx::AnalysisData object
131 that will contain, for each frame, one column for each input selection.
132 This will contain the main output from the tool: minimum distance between
133 the reference selection and that particular selection.
134 We then create and setup a module that will compute the average distance
135 for each selection (see writeOutput() for how it is used).
136 Finally, if an output file has been provided, we create and setup a module
137 that will plot the per-frame distances to a file.
139 If the analysis module needs some temporary storage during processing of a
140 frame (i.e., it uses a custom class derived from
141 gmx::TrajectoryAnalysisModuleData), this should be allocated in
142 gmx::TrajectoryAnalysisModule::startFrames() (see below) if parallelization
143 is to be supported.
145 If you need to do initialization based on data from the first frame (most
146 commonly, based on the box size), you need to override
147 gmx::TrajectoryAnalysisModule::initAfterFirstFrame(), but this is not used
148 in the template.
151 Analyzing the frames
152 ====================
154 There is one more initialization method that needs to be overridden to
155 support automatic parallelization: gmx::TrajectoryAnalysisModule::startFrames().
156 If you do not need custom frame-local data (or parallelization at all), you
157 can skip this method and ignore the last parameter to
158 gmx::TrajectoryAnalysisModule::analyzeFrame() to make things simpler.
159 In the template, this method is not necessary.
161 The main part of the analysis is (in most analysis codes) done in the
162 gmx::TrajectoryAnalysisModule::analyzeFrame() method, which is called once
163 for each frame:
164 \skip  void
165 \until {
166 The \p frnr parameter gives a zero-based index of the current frame
167 (mostly for use with gmx::AnalysisData), \p pbc contains the PBC
168 information for the current frame for distance calculations with,
169 e.g., pbc_dx(), and \p pdata points to a data structure created in
170 startFrames().
171 Although usually not necessary (except for the time field), raw frame
172 data can be accessed through \p fr.
173 In most cases, the analysis should be written such that it gets all
174 position data through selections, and does not assume a constant size for
175 them.  This is all that is required to support the full flexibility of the
176 selection engine.
178 For the template, we first get data from our custom data structure for
179 shorthand access (if you use a custom data object, you need a \c static_cast
180 here):
181 \skip  AnalysisDataHandle
182 \until parallelSelection
184 We then do a simple calculation and use the AnalysisDataHandle class to set
185 the per-frame output for the tool:
186 \skip  nb
187 \until finishFrame()
189 After all the frames have been processed,
190 gmx::TrajectoryAnalysisModule::finishAnalysis() is called once.  This is the
191 place to do any custom postprocessing of the data.  For the template, we do
192 nothing, because all necessary processing is done in the data modules:
193 \skip  void
194 \until }
196 If the data structure created in gmx::TrajectoryAnalysisModule::startFrames()
197 is used to aggregate data across frames, you need to override
198 gmx::TrajectoryAnalysisModule::finishFrames() to combine the data from the
199 data structures (see documentation of the method for details).
200 This is not necessary for the template, because the ModuleData structure
201 only contains data used during the analysis of a single frame.
204 Output
205 ======
207 Finally, most programs need to write out some values after the analysis is
208 complete.  In some cases, this can be achieved with proper chaining of data
209 modules, but often it is necessary to do some custom processing.
210 All such activities should be done in
211 gmx::TrajectoryAnalysisModule::writeOutput().  This makes it easier to reuse
212 analysis modules in, e.g., scripting languages, where output into files
213 might not be desired.  The template simply prints out the average distances
214 for each analysis group:
215 \skip  void
216 \until }
217 \until }
218 Here, we use the \c avem_ module, which we initialized in initAnalysis() to
219 aggregate the averages of the computed distances.
222 Definition of main()
223 ====================
225 Now, the only thing remaining is to define the main() function.
226 To implement a command-line tool, it should create a module and run it using
227 gmx::TrajectoryAnalysisCommandLineRunner using the boilerplate code below:
228 \skip  int
229 \until }
232 \if libapi
233 Tools within \Gromacs
234 ====================
236 Analysis tools implemented using the template can also be easily included into
237 the \Gromacs library.  To do this, follow these steps:
239  1. Put your tool source code into `src/gromacs/trajectoryanalysis/modules/`.
240  2. Remove `using namespace gmx;` and enclose all the code into
241     `gmx::analysismodules` namespace, and the tool class into an unnamed
242     namespace within this.
243  3. Create a header file corresponding to your tool and add the following class
244     into it withing `gmx::analysismodules` namespace (replace `Template` with
245     the name of your tool):
246 ~~~~{.cpp}
247     class TemplateInfo
248     {
249         public:
250             static const char name[];
251             static const char shortDescription[];
252             static TrajectoryAnalysisModulePointer create();
253     };
254 ~~~~
255  4. Add definition for these items in the source file, outside the unnamed
256     namespace (replace `Template`, `AnalysisTemplate` and the strings with
257     correct values):
258 ~~~~{.cpp}
259     const char TemplateInfo::name[]             = "template";
260     const char TemplateInfo::shortDescription[] =
261         "Compute something";
263     TrajectoryAnalysisModulePointer TemplateInfo::create()
264     {
265         return TrajectoryAnalysisModulePointer(new AnalysisTemplate);
266     }
267 ~~~~
268  5. Change the constructor of your tool to refer to the strings in the new
269     class:
270 ~~~~{.cpp}
271     AnalysisTemplate::AnalysisTemplate()
272         : TrajectoryAnalysisModule(TemplateInfo::name, TemplateInfo::shortDescription),
273 ~~~~
274  6. Register your module in `src/gromacs/trajectoryanalysis/modules.cpp`.
275  7. Done.  Your tool can now be invoked as `gmx template`, using the string you
276     specified as the name.
278 See existing tools within the `src/gromacs/trajectoryanalysis/modules/` for
279 concrete examples and preferred layout of the files.  Please document yourself
280 as the author of the files, using Doxygen comments like in the existing files.
282 \endif