3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
32 * \brief API for handling index files and index groups.
34 * The API contains functions and data structures for handling index
35 * files more conveniently than as several separate variables.
36 * In addition to basic functions for initializing the data structures and
37 * making copies, functions are provided for performing (most) set operations
38 * on sorted index groups.
39 * There is also a function for partitioning a index group based on
40 * topology information such as residues or molecules.
41 * Finally, there is a set of functions for constructing mappings between
42 * an index group and its subgroups such.
43 * These can be used with dynamic index group in calculations if one
44 * needs to have a unique ID for each possible atom/residue/molecule in the
45 * selection, e.g., for analysis of dynamics or for look-up tables.
47 * Mostly, these functions are used internally by the selection engine, but
48 * it is necessary to use some of these functions in order to provide external
49 * index groups to a gmx::SelectionCollection.
50 * Some of the checking functions can be useful outside the selection engine to
51 * check the validity of input groups.
53 * \author Teemu Murtola <teemu.murtola@gmail.com>
55 * \ingroup module_selection
57 #ifndef GMX_SELECTION_INDEXUTIL_H
58 #define GMX_SELECTION_INDEXUTIL_H
60 #include "../legacyheaders/typedefs.h"
62 /** Stores a set of index groups. */
63 typedef struct gmx_ana_indexgrps_t gmx_ana_indexgrps_t;
66 * Specifies the type of index partition or index mapping in several contexts.
68 * \see gmx_ana_index_make_block(), gmx_ana_indexmap_init()
72 INDEX_UNKNOWN, /**< Unknown index type.*/
73 INDEX_ATOM, /**< Each atom in a separate block.*/
74 INDEX_RES, /**< Each residue in a separate block.*/
75 INDEX_MOL, /**< Each molecule in a separate block.*/
76 INDEX_ALL /**< All atoms in a single block.*/
80 * Stores a single index group.
82 typedef struct gmx_ana_index_t
84 /** Number of atoms. */
90 /** Number of items allocated for \p index. */
95 * Data structure for calculating index group mappings.
97 typedef struct gmx_ana_indexmap_t
99 /** Type of the mapping. */
102 * Current number of mapped values.
104 * This is the current number of values in the \p refid and \p mapid
106 * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), this
107 * is always equal to \p b.nr, i.e., the number of blocks in the
108 * original index group.
112 * Current reference IDs.
114 * This array provides a mapping from the current index group (last given
115 * to gmx_ana_indexmap_update()) to the blocks in \p b, i.e., the
116 * original index group used in gmx_ana_indexmap_init().
117 * The mapping is zero-based.
118 * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), the indices
119 * for blocks not present in the current group are set to -1, otherwise
120 * they are removed completely and the \p nr field updated.
124 * Current mapped IDs.
126 * This array provides an arbitrary mapping from the current index group
127 * to the original index group. Instead of a zero-based mapping, the
128 * values from the \p orgid array are used. That is,
129 * \c mapid[i]=orgid[refid[i]].
130 * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), this array
135 * Mapped block structure.
137 * A block structure that corresponds to the current 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
177 * true if the current mapping is for the whole group (internal use only).
179 * This is used internally to optimize the evaluation such that
180 * gmx_ana_indexmap_update() does not take any time if the group is
184 } gmx_ana_indexmap_t;
187 /*! \name Functions for handling gmx_ana_indexgrps_t
190 /** Allocate memory for index groups. */
192 gmx_ana_indexgrps_alloc(gmx_ana_indexgrps_t **g, int ngrps);
193 /** Reads index groups from a file or constructs them from topology. */
195 gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, t_topology *top,
197 /** Frees memory allocated for index groups. */
199 gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g);
200 /** Create a deep copy of \c gmx_ana_indexgrps_t. */
202 gmx_ana_indexgrps_clone(gmx_ana_indexgrps_t **dest, gmx_ana_indexgrps_t *src);
203 /** Returns true if the index group structure is emtpy. */
205 gmx_ana_indexgrps_is_empty(gmx_ana_indexgrps_t *g);
207 /** Returns a pointer to an index group. */
209 gmx_ana_indexgrps_get_grp(gmx_ana_indexgrps_t *g, int n);
210 /** Extracts a single index group. */
212 gmx_ana_indexgrps_extract(gmx_ana_index_t *dest, gmx_ana_indexgrps_t *src, int n);
213 /** Finds and extracts a single index group by name. */
215 gmx_ana_indexgrps_find(gmx_ana_index_t *dest, gmx_ana_indexgrps_t *src, char *name);
217 /** Writes out a list of index groups. */
219 gmx_ana_indexgrps_print(FILE *fp, gmx_ana_indexgrps_t *g, int maxn);
222 /*! \name Functions for handling gmx_ana_index_t
225 /** Reserves memory to store an index group of size \p isize. */
227 gmx_ana_index_reserve(gmx_ana_index_t *g, int isize);
228 /** Frees any memory not necessary to hold the current contents. */
230 gmx_ana_index_squeeze(gmx_ana_index_t *g);
231 /** Initializes an empty index group. */
233 gmx_ana_index_clear(gmx_ana_index_t *g);
234 /** Constructs a \c gmx_ana_index_t from given values. */
236 gmx_ana_index_set(gmx_ana_index_t *g, int isize, atom_id *index, char *name,
238 /** Creates a simple index group from the first to the \p natoms'th atom. */
240 gmx_ana_index_init_simple(gmx_ana_index_t *g, int natoms, char *name);
241 /** Frees memory allocated for an index group. */
243 gmx_ana_index_deinit(gmx_ana_index_t *g);
244 /** Copies a \c gmx_ana_index_t. */
246 gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc);
248 /** Writes out the contents of a index group. */
250 gmx_ana_index_dump(FILE *fp, gmx_ana_index_t *g, int i, int maxn);
252 /** Checks whether all indices are between 0 and \p natoms. */
254 gmx_ana_index_check(gmx_ana_index_t *g, int natoms);
255 /** Checks whether an index group is sorted. */
257 gmx_ana_index_check_sorted(gmx_ana_index_t *g);
260 /*! \name Functions for set operations on gmx_ana_index_t
263 /** Sorts the indices within an index group. */
265 gmx_ana_index_sort(gmx_ana_index_t *g);
266 /** Checks whether two index groups are equal. */
268 gmx_ana_index_equals(gmx_ana_index_t *a, gmx_ana_index_t *b);
269 /** Checks whether a sorted index group contains another sorted index group. */
271 gmx_ana_index_contains(gmx_ana_index_t *a, gmx_ana_index_t *b);
273 /** Calculates the intersection between two sorted index groups. */
275 gmx_ana_index_intersection(gmx_ana_index_t *dest,
276 gmx_ana_index_t *a, gmx_ana_index_t *b);
277 /** Calculates the set difference between two sorted index groups. */
279 gmx_ana_index_difference(gmx_ana_index_t *dest,
280 gmx_ana_index_t *a, gmx_ana_index_t *b);
281 /** Calculates the size of the difference between two sorted index groups. */
283 gmx_ana_index_difference_size(gmx_ana_index_t *a, gmx_ana_index_t *b);
284 /** Calculates the union of two sorted index groups. */
286 gmx_ana_index_union(gmx_ana_index_t *dest,
287 gmx_ana_index_t *a, gmx_ana_index_t *b);
288 /** Merges two distinct sorted index groups. */
290 gmx_ana_index_merge(gmx_ana_index_t *dest,
291 gmx_ana_index_t *a, gmx_ana_index_t *b);
292 /** Calculates the intersection and the difference in one call. */
294 gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2,
295 gmx_ana_index_t *src, gmx_ana_index_t *g);
298 /*! \name Functions for handling gmx_ana_indexmap_t and related things
301 /** Partition a group based on topology information. */
303 gmx_ana_index_make_block(t_blocka *t, t_topology *top, gmx_ana_index_t *g,
304 e_index_t type, bool bComplete);
305 /** Checks whether a group consists of full blocks. */
307 gmx_ana_index_has_full_blocks(gmx_ana_index_t *g, t_block *b);
308 /** Checks whether a group consists of full blocks. */
310 gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b);
311 /** Checks whether a group consists of full residues/molecules. */
313 gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, t_topology *top);
315 /** Initializes an empty index group mapping. */
317 gmx_ana_indexmap_clear(gmx_ana_indexmap_t *m);
318 /** Reserves memory for an index group mapping. */
320 gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize);
321 /** Initializes an index group mapping. */
323 gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g,
324 t_topology *top, e_index_t type);
325 /** Sets an index group mapping to be static. */
327 gmx_ana_indexmap_set_static(gmx_ana_indexmap_t *m, t_blocka *b);
328 /** Frees memory allocated for index group mapping. */
330 gmx_ana_indexmap_deinit(gmx_ana_indexmap_t *m);
331 /** Makes a deep copy of an index group mapping. */
333 gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst);
334 /** Updates an index group mapping. */
336 gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, bool bMaskOnly);