2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2009, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
39 * \brief Implementation of distance-based selection methods.
41 * This file implements the \p distance, \p mindistance and \p within
55 #include <selmethod.h>
58 * Data structure for distance-based selection method.
60 * The same data structure is used by all the distance-based methods.
64 /** Cutoff distance. */
66 /** Positions of the reference points. */
68 /** Neighborhood search data. */
69 gmx_ana_nbsearch_t *nb;
70 } t_methoddata_distance;
72 /** Allocates data for distance-based selection methods. */
74 init_data_common(int npar, gmx_ana_selparam_t *param);
75 /** Initializes a distance-based selection method. */
77 init_common(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
78 /** Frees the data allocated for a distance-based selection method. */
80 free_data_common(void *data);
81 /** Initializes the evaluation of a distance-based within selection method for a frame. */
83 init_frame_common(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
84 /** Evaluates the \p distance selection method. */
86 evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
87 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
88 /** Evaluates the \p within selection method. */
90 evaluate_within(t_topology *top, t_trxframe *fr, t_pbc *pbc,
91 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
93 /** Parameters for the \p distance selection method. */
94 static gmx_ana_selparam_t smparams_distance[] = {
95 {"cutoff", {REAL_VALUE, 1, {NULL}}, NULL, SPAR_OPTIONAL},
96 {"from", {POS_VALUE, 1, {NULL}}, NULL, SPAR_DYNAMIC},
99 /** Parameters for the \p mindistance selection method. */
100 static gmx_ana_selparam_t smparams_mindistance[] = {
101 {"cutoff", {REAL_VALUE, 1, {NULL}}, NULL, SPAR_OPTIONAL},
102 {"from", {POS_VALUE, -1, {NULL}}, NULL, SPAR_DYNAMIC | SPAR_VARNUM},
105 /** Parameters for the \p within selection method. */
106 static gmx_ana_selparam_t smparams_within[] = {
107 {NULL, {REAL_VALUE, 1, {NULL}}, NULL, 0},
108 {"of", {POS_VALUE, -1, {NULL}}, NULL, SPAR_DYNAMIC | SPAR_VARNUM},
111 /** Help text for the distance selection methods. */
112 static const char *help_distance[] = {
113 "DISTANCE-BASED SELECTION KEYWORDS[PAR]",
115 "[TT]distance from POS [cutoff REAL][tt][BR]",
116 "[TT]mindistance from POS_EXPR [cutoff REAL][tt][BR]",
117 "[TT]within REAL of POS_EXPR[tt][PAR]",
119 "[TT]distance[tt] and [TT]mindistance[tt] calculate the distance from the",
120 "given position(s), the only difference being in that [TT]distance[tt]",
121 "only accepts a single position, while any number of positions can be",
122 "given for [TT]mindistance[tt], which then calculates the distance to the",
124 "[TT]within[tt] directly selects atoms that are within [TT]REAL[tt] of",
125 "[TT]POS_EXPR[tt].[PAR]",
127 "For the first two keywords, it is possible to specify a cutoff to speed",
128 "up the evaluation: all distances above the specified cutoff are",
129 "returned as equal to the cutoff.",
130 "Currently, this does nothing, but in the future, it allows the use of",
131 "grid-based neighborhood search techniques.",
134 /** \internal Selection method data for the \p distance method. */
135 gmx_ana_selmethod_t sm_distance = {
136 "distance", REAL_VALUE, SMETH_DYNAMIC,
137 asize(smparams_distance), smparams_distance,
146 {"distance from POS [cutoff REAL]", asize(help_distance), help_distance},
149 /** \internal Selection method data for the \p distance method. */
150 gmx_ana_selmethod_t sm_mindistance = {
151 "mindistance", REAL_VALUE, SMETH_DYNAMIC,
152 asize(smparams_mindistance), smparams_mindistance,
161 {"mindistance from POS_EXPR [cutoff REAL]", asize(help_distance), help_distance},
164 /** \internal Selection method data for the \p within method. */
165 gmx_ana_selmethod_t sm_within = {
166 "within", GROUP_VALUE, SMETH_DYNAMIC,
167 asize(smparams_within), smparams_within,
176 {"within REAL of POS_EXPR", asize(help_distance), help_distance},
180 * \param[in] npar Not used (should be 2).
181 * \param[in,out] param Method parameters (should point to one of the distance
183 * \returns Pointer to the allocated data (\c t_methoddata_distance).
185 * Allocates memory for a \c t_methoddata_distance structure and
186 * initializes the parameter as follows:
187 * - the first parameter defines the value for
188 * \c t_methoddata_distance::cutoff.
189 * - the second parameter defines the reference positions and the value is
190 * stored in \c t_methoddata_distance::p.
193 init_data_common(int npar, gmx_ana_selparam_t *param)
195 t_methoddata_distance *data;
199 param[0].val.u.r = &data->cutoff;
200 param[1].val.u.p = &data->p;
205 * \param top Not used.
206 * \param npar Not used (should be 2).
207 * \param param Method parameters (should point to one of the distance
209 * \param data Pointer to \c t_methoddata_distance to initialize.
210 * \returns 0 on success, a non-zero error code on failure.
212 * Initializes the neighborhood search data structure
213 * (\c t_methoddata_distance::nb).
214 * Also checks that the cutoff is valid.
217 init_common(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
219 t_methoddata_distance *d = (t_methoddata_distance *)data;
221 if ((param[0].flags & SPAR_SET) && d->cutoff <= 0)
223 fprintf(stderr, "error: distance cutoff should be > 0");
226 return gmx_ana_nbsearch_create(&d->nb, d->cutoff, d->p.nr);
230 * \param data Data to free (should point to a \c t_methoddata_distance).
232 * Frees the memory allocated for \c t_methoddata_distance::xref and
233 * \c t_methoddata_distance::nb.
236 free_data_common(void *data)
238 t_methoddata_distance *d = (t_methoddata_distance *)data;
242 gmx_ana_nbsearch_free(d->nb);
247 * \param[in] top Not used.
248 * \param[in] fr Current frame.
249 * \param[in] pbc PBC structure.
250 * \param data Should point to a \c t_methoddata_distance.
251 * \returns 0 on success, a non-zero error code on error.
253 * Initializes the neighborhood search for the current frame.
256 init_frame_common(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
258 t_methoddata_distance *d = (t_methoddata_distance *)data;
260 return gmx_ana_nbsearch_pos_init(d->nb, pbc, &d->p);
264 * See sel_updatefunc_pos() for description of the parameters.
265 * \p data should point to a \c t_methoddata_distance.
267 * Calculates the distance of each position from \c t_methoddata_distance::p
268 * and puts them in \p out->u.r.
271 evaluate_distance(t_topology *top, t_trxframe *fr, t_pbc *pbc,
272 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
274 t_methoddata_distance *d = (t_methoddata_distance *)data;
278 out->nr = pos->g->isize;
279 for (b = 0; b < pos->nr; ++b)
281 n = gmx_ana_nbsearch_pos_mindist(d->nb, pos, b);
282 for (i = pos->m.mapb.index[b]; i < pos->m.mapb.index[b+1]; ++i)
291 * See sel_updatefunc() for description of the parameters.
292 * \p data should point to a \c t_methoddata_distance.
294 * Finds the atoms that are closer than the defined cutoff to
295 * \c t_methoddata_distance::xref and puts them in \p out.g.
298 evaluate_within(t_topology *top, t_trxframe *fr, t_pbc *pbc,
299 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
301 t_methoddata_distance *d = (t_methoddata_distance *)data;
305 for (b = 0; b < pos->nr; ++b)
307 if (gmx_ana_nbsearch_pos_is_within(d->nb, pos, b))
309 gmx_ana_pos_append(NULL, out->u.g, pos, b, 0);