2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2009,2010,2011,2012,2013,2014, 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.
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.
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.
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.
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.
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.
36 * \brief API for handling index files and index groups.
38 * The API contains functions and data structures for handling index
39 * files more conveniently than as several separate variables.
40 * In addition to basic functions for initializing the data structures and
41 * making copies, functions are provided for performing (most) set operations
42 * on sorted index groups.
43 * There is also a function for partitioning a index group based on
44 * topology information such as residues or molecules.
45 * Finally, there is a set of functions for constructing mappings between
46 * an index group and its subgroups such.
47 * These can be used with dynamic index group in calculations if one
48 * needs to have a unique ID for each possible atom/residue/molecule in the
49 * selection, e.g., for analysis of dynamics or for look-up tables.
51 * Mostly, these functions are used internally by the selection engine, but
52 * it is necessary to use some of these functions in order to provide external
53 * index groups to a gmx::SelectionCollection.
54 * Some of the checking functions can be useful outside the selection engine to
55 * check the validity of input groups.
57 * \author Teemu Murtola <teemu.murtola@gmail.com>
59 * \ingroup module_selection
61 #ifndef GMX_SELECTION_INDEXUTIL_H
62 #define GMX_SELECTION_INDEXUTIL_H
68 #include "../legacyheaders/types/simple.h"
69 #include "../topology/block.h"
73 /** Stores a set of index groups. */
74 struct gmx_ana_indexgrps_t;
77 * Specifies the type of index partition or index mapping in several contexts.
79 * \see gmx_ana_index_make_block(), gmx_ana_indexmap_init()
83 INDEX_UNKNOWN, /**< Unknown index type.*/
84 INDEX_ATOM, /**< Each atom in a separate block.*/
85 INDEX_RES, /**< Each residue in a separate block.*/
86 INDEX_MOL, /**< Each molecule in a separate block.*/
87 INDEX_ALL /**< All atoms in a single block.*/
91 * Stores a single index group.
93 struct gmx_ana_index_t
95 /** Number of atoms. */
99 /** Number of items allocated for \p index. */
104 * Data structure for calculating index group mappings.
106 struct gmx_ana_indexmap_t
108 /** Type of the mapping. */
111 * Current reference IDs.
113 * This array provides a mapping from the current index group (last given
114 * to gmx_ana_indexmap_update()) to the blocks in \p b, i.e., the
115 * original index group used in gmx_ana_indexmap_init().
116 * The mapping is zero-based.
117 * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), the indices
118 * for blocks not present in the current group are set to -1, otherwise
119 * they are removed completely and the \p nr field updated.
123 * Current mapped IDs.
125 * This array provides an arbitrary mapping from the current index group
126 * to the original index group. Instead of a zero-based mapping, the
127 * values from the \p orgid array are used. That is,
128 * \c mapid[i]=orgid[refid[i]].
129 * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), this array
134 * Mapped block structure.
136 * A block structure that corresponds to the current index group.
137 * \c mapb.nra and \c mapb.a correspond to the last mapped index group.
142 * Arbitrary ID numbers for the blocks.
144 * This array has \p b.nr elements, each defining an ID number for a
146 * These are initialized in gmx_ana_indexmap_init() based on the type:
147 * - \ref INDEX_ATOM : the atom indices
148 * - \ref INDEX_RES : the residue numbers
149 * - \ref INDEX_MOL : the molecule numbers
151 * All the above numbers are zero-based.
152 * After gmx_ana_indexmap_init(), the user is free to change these values
153 * if the above are not appropriate.
154 * The mapped values can be read through \p mapid.
159 * Block data that defines the mapping (internal use only).
161 * The data is initialized by gmx_ana_indexmap_init() and is not changed
163 * Hence, it cannot be directly applied to the index group passed to
164 * gmx_ana_indexmap_update() unless \p bMaskOnly was specified or the
165 * index group is identical to the one provided to gmx_ana_indexmap_init().
169 * true if the current reference IDs are for the whole group (internal use only).
171 * This is used internally to optimize the evaluation such that
172 * gmx_ana_indexmap_update() does not take any time if the group is
179 /*! \name Functions for handling gmx_ana_indexgrps_t
182 /** Reads index groups from a file or constructs them from topology. */
184 gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, t_topology *top,
186 /** Frees memory allocated for index groups. */
188 gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g);
189 /** Returns true if the index group structure is emtpy. */
191 gmx_ana_indexgrps_is_empty(gmx_ana_indexgrps_t *g);
193 /** Returns a pointer to an index group. */
195 gmx_ana_indexgrps_get_grp(gmx_ana_indexgrps_t *g, int n);
196 /** Extracts a single index group. */
198 gmx_ana_indexgrps_extract(gmx_ana_index_t *dest, std::string *destName,
199 gmx_ana_indexgrps_t *src, int n);
200 /** Finds and extracts a single index group by name. */
202 gmx_ana_indexgrps_find(gmx_ana_index_t *dest, std::string *destName,
203 gmx_ana_indexgrps_t *src, const char *name);
205 /** Writes out a list of index groups. */
207 gmx_ana_indexgrps_print(FILE *fp, gmx_ana_indexgrps_t *g, int maxn);
210 /*! \name Functions for handling gmx_ana_index_t
213 /** Reserves memory to store an index group of size \p isize. */
215 gmx_ana_index_reserve(gmx_ana_index_t *g, int isize);
216 /** Frees any memory not necessary to hold the current contents. */
218 gmx_ana_index_squeeze(gmx_ana_index_t *g);
219 /** Initializes an empty index group. */
221 gmx_ana_index_clear(gmx_ana_index_t *g);
222 /** Constructs a \c gmx_ana_index_t from given values. */
224 gmx_ana_index_set(gmx_ana_index_t *g, int isize, atom_id *index, int nalloc);
225 /** Creates a simple index group from the first to the \p natoms'th atom. */
227 gmx_ana_index_init_simple(gmx_ana_index_t *g, int natoms);
228 /** Frees memory allocated for an index group. */
230 gmx_ana_index_deinit(gmx_ana_index_t *g);
231 /** Copies a \c gmx_ana_index_t. */
233 gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc);
235 /** Writes out the contents of a index group. */
237 gmx_ana_index_dump(FILE *fp, gmx_ana_index_t *g, int maxn);
239 /** Checks whether an index group is sorted. */
241 gmx_ana_index_check_sorted(gmx_ana_index_t *g);
244 /*! \name Functions for set operations on gmx_ana_index_t
247 /** Sorts the indices within an index group. */
249 gmx_ana_index_sort(gmx_ana_index_t *g);
250 /** Checks whether two index groups are equal. */
252 gmx_ana_index_equals(gmx_ana_index_t *a, gmx_ana_index_t *b);
253 /** Checks whether a sorted index group contains another sorted index group. */
255 gmx_ana_index_contains(gmx_ana_index_t *a, gmx_ana_index_t *b);
257 /** Calculates the intersection between two sorted index groups. */
259 gmx_ana_index_intersection(gmx_ana_index_t *dest,
260 gmx_ana_index_t *a, gmx_ana_index_t *b);
261 /** Calculates the set difference between two sorted index groups. */
263 gmx_ana_index_difference(gmx_ana_index_t *dest,
264 gmx_ana_index_t *a, gmx_ana_index_t *b);
265 /** Calculates the size of the difference between two sorted index groups. */
267 gmx_ana_index_difference_size(gmx_ana_index_t *a, gmx_ana_index_t *b);
268 /** Calculates the union of two sorted index groups. */
270 gmx_ana_index_union(gmx_ana_index_t *dest,
271 gmx_ana_index_t *a, gmx_ana_index_t *b);
272 /** Merges two distinct sorted index groups. */
274 gmx_ana_index_merge(gmx_ana_index_t *dest,
275 gmx_ana_index_t *a, gmx_ana_index_t *b);
276 /** Calculates the intersection and the difference in one call. */
278 gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2,
279 gmx_ana_index_t *src, gmx_ana_index_t *g);
282 /*! \name Functions for handling gmx_ana_indexmap_t and related things
285 /** Partition a group based on topology information. */
287 gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
288 e_index_t type, bool bComplete);
289 /** Checks whether a group consists of full blocks. */
291 gmx_ana_index_has_full_blocks(gmx_ana_index_t *g, t_block *b);
292 /** Checks whether a group consists of full blocks. */
294 gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b);
295 /** Checks whether a group consists of full residues/molecules. */
297 gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, t_topology *top);
299 /** Initializes an empty index group mapping. */
301 gmx_ana_indexmap_clear(gmx_ana_indexmap_t *m);
302 /** Reserves memory for an index group mapping. */
304 gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize);
305 /** Initializes an index group mapping. */
307 gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
308 t_topology *top, e_index_t type);
309 /** Sets an index group mapping to be static. */
311 gmx_ana_indexmap_set_static(gmx_ana_indexmap_t *m, t_blocka *b);
312 /** Frees memory allocated for index group mapping. */
314 gmx_ana_indexmap_deinit(gmx_ana_indexmap_t *m);
315 /** Makes a deep copy of an index group mapping. */
317 gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst);
318 /** Updates an index group mapping. */
320 gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, bool bMaskOnly);