Merge branch 'master' of git://git.gromacs.org/gromacs
[gromacs/adressmacs.git] / src / gmxlib / selection / sm_position.c
blob6a3ae6a3dac143e435d41dfb1601b6caaf44db34
1 /*
3 * This source code is part of
5 * G R O M A C S
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
31 /*! \internal \file
32 * \brief Implementation of position evaluation selection methods.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #include <macros.h>
39 #include <smalloc.h>
40 #include <string2.h>
42 #include <indexutil.h>
43 #include <poscalc.h>
44 #include <position.h>
45 #include <selmethod.h>
47 #include "keywords.h"
48 #include "selelem.h"
50 /*! \internal \brief
51 * Data structure for position keyword evaluation.
53 typedef struct
55 /** Position calculation collection to use. */
56 gmx_ana_poscalc_coll_t *pcc;
57 /** Index group for which the center should be evaluated. */
58 gmx_ana_index_t g;
59 /** Position evaluation data structure. */
60 gmx_ana_poscalc_t *pc;
61 /** TRUE if periodic boundary conditions should be used. */
62 gmx_bool bPBC;
63 /** Type of positions to calculate. */
64 char *type;
65 /** Flags for the position calculation. */
66 int flags;
67 } t_methoddata_pos;
69 /** Allocates data for position evaluation selection methods. */
70 static void *
71 init_data_pos(int npar, gmx_ana_selparam_t *param);
72 /** Sets the position calculation collection for position evaluation selection methods. */
73 static void
74 set_poscoll_pos(gmx_ana_poscalc_coll_t *pcc, void *data);
75 /** Initializes position evaluation keywords. */
76 static int
77 init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
78 /** Initializes the \p cog selection method. */
79 static int
80 init_cog(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
81 /** Initializes the \p cog selection method. */
82 static int
83 init_com(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
84 /** Initializes output for position evaluation selection methods. */
85 static int
86 init_output_pos(t_topology *top, gmx_ana_selvalue_t *out, void *data);
87 /** Frees the data allocated for position evaluation selection methods. */
88 static void
89 free_data_pos(void *data);
90 /** Evaluates position evaluation selection methods. */
91 static int
92 evaluate_pos(t_topology *top, t_trxframe *fr, t_pbc *pbc,
93 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
95 /** Parameters for position keyword evaluation. */
96 static gmx_ana_selparam_t smparams_keyword_pos[] = {
97 {NULL, {GROUP_VALUE, 1, {NULL}}, NULL, SPAR_DYNAMIC},
100 /** Parameters for the \p cog and \p com selection methods. */
101 static gmx_ana_selparam_t smparams_com[] = {
102 {"of", {GROUP_VALUE, 1, {NULL}}, NULL, SPAR_DYNAMIC},
103 {"pbc", {NO_VALUE, 0, {NULL}}, NULL, 0},
106 /** \internal Selection method data for position keyword evaluation. */
107 gmx_ana_selmethod_t sm_keyword_pos = {
108 "kw_pos", POS_VALUE, SMETH_DYNAMIC | SMETH_VARNUMVAL,
109 asize(smparams_keyword_pos), smparams_keyword_pos,
110 &init_data_pos,
111 &set_poscoll_pos,
112 &init_kwpos,
113 &init_output_pos,
114 &free_data_pos,
115 NULL,
116 &evaluate_pos,
117 NULL,
118 {NULL, 0, NULL},
121 /** \internal Selection method data for the \p cog method. */
122 gmx_ana_selmethod_t sm_cog = {
123 "cog", POS_VALUE, SMETH_DYNAMIC | SMETH_SINGLEVAL,
124 asize(smparams_com), smparams_com,
125 &init_data_pos,
126 &set_poscoll_pos,
127 &init_cog,
128 &init_output_pos,
129 &free_data_pos,
130 NULL,
131 &evaluate_pos,
132 NULL,
133 {"cog of ATOM_EXPR [pbc]", 0, NULL},
136 /** \internal Selection method data for the \p com method. */
137 gmx_ana_selmethod_t sm_com = {
138 "com", POS_VALUE, SMETH_REQTOP | SMETH_DYNAMIC | SMETH_SINGLEVAL,
139 asize(smparams_com), smparams_com,
140 &init_data_pos,
141 &set_poscoll_pos,
142 &init_com,
143 &init_output_pos,
144 &free_data_pos,
145 NULL,
146 &evaluate_pos,
147 NULL,
148 {"com of ATOM_EXPR [pbc]", 0, NULL},
152 * \param[in] npar Should be 1 or 2.
153 * \param[in,out] param Method parameters (should point to
154 * \ref smparams_keyword_pos or \ref smparams_com).
155 * \returns Pointer to the allocated data (\c t_methoddata_pos).
157 * Allocates memory for a \c t_methoddata_pos structure and initializes
158 * the first parameter to define the value for \c t_methoddata_pos::g.
159 * If a second parameter is present, it is used for setting the
160 * \c t_methoddata_pos::bPBC flag.
162 static void *
163 init_data_pos(int npar, gmx_ana_selparam_t *param)
165 t_methoddata_pos *data;
167 snew(data, 1);
168 param[0].val.u.g = &data->g;
169 if (npar > 1)
171 param[1].val.u.b = &data->bPBC;
173 data->pc = NULL;
174 data->bPBC = FALSE;
175 data->type = NULL;
176 data->flags = -1;
177 return data;
181 * \param[in] pcc Position calculation collection to use.
182 * \param[in,out] data Should point to \c t_methoddata_pos.
184 static void
185 set_poscoll_pos(gmx_ana_poscalc_coll_t *pcc, void *data)
187 ((t_methoddata_pos *)data)->pcc = pcc;
191 * \param[in,out] sel Selection element to initialize.
192 * \param[in] type One of the enum values acceptable for
193 * gmx_ana_poscalc_type_from_enum().
195 * Initializes the reference position type for position evaluation.
196 * If called multiple times, the first setting takes effect, and later calls
197 * are neglected.
199 void
200 _gmx_selelem_set_kwpos_type(t_selelem *sel, const char *type)
202 t_methoddata_pos *d = (t_methoddata_pos *)sel->u.expr.mdata;
204 if (sel->type != SEL_EXPRESSION || !sel->u.expr.method
205 || sel->u.expr.method->name != sm_keyword_pos.name)
207 return;
209 if (!d->type && type)
211 d->type = strdup(type);
212 /* FIXME: It would be better not to have the string here hardcoded. */
213 if (type[0] != 'a')
215 sel->u.expr.method->flags |= SMETH_REQTOP;
221 * \param[in,out] sel Selection element to initialize.
222 * \param[in] flags Default completion flags
223 * (see gmx_ana_poscalc_type_from_enum()).
225 * Initializes the flags for position evaluation.
226 * If called multiple times, the first setting takes effect, and later calls
227 * are neglected.
229 void
230 _gmx_selelem_set_kwpos_flags(t_selelem *sel, int flags)
232 t_methoddata_pos *d = (t_methoddata_pos *)sel->u.expr.mdata;
234 if (sel->type != SEL_EXPRESSION || !sel->u.expr.method
235 || sel->u.expr.method->name != sm_keyword_pos.name)
237 return;
239 if (d->flags == -1)
241 d->flags = flags;
246 * \param[in] top Not used.
247 * \param[in] npar Not used.
248 * \param[in] param Not used.
249 * \param[in,out] data Should point to \c t_methoddata_pos.
250 * \returns 0 on success, a non-zero error code on error.
252 * The \c t_methoddata_pos::type field should have been initialized
253 * externally using _gmx_selelem_set_kwpos_type().
255 static int
256 init_kwpos(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
258 t_methoddata_pos *d = (t_methoddata_pos *)data;
259 int rc;
261 if (!(param[0].flags & SPAR_DYNAMIC))
263 d->flags &= ~(POS_DYNAMIC | POS_MASKONLY);
265 else if (!(d->flags & POS_MASKONLY))
267 d->flags |= POS_DYNAMIC;
269 rc = gmx_ana_poscalc_create_enum(&d->pc, d->pcc, d->type, d->flags);
270 if (rc != 0)
272 return rc;
274 gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
275 return 0;
279 * \param[in] top Topology data structure.
280 * \param[in] npar Not used.
281 * \param[in] param Not used.
282 * \param[in,out] data Should point to \c t_methoddata_pos.
283 * \returns 0 on success, a non-zero error code on error.
285 static int
286 init_cog(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
288 t_methoddata_pos *d = (t_methoddata_pos *)data;
289 int rc;
291 d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0;
292 rc = gmx_ana_poscalc_create(&d->pc, d->pcc, d->bPBC ? POS_ALL_PBC : POS_ALL,
293 d->flags);
294 if (rc != 0)
296 return rc;
298 gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
299 return 0;
303 * \param[in] top Topology data structure.
304 * \param[in] npar Not used.
305 * \param[in] param Not used.
306 * \param[in,out] data Should point to \c t_methoddata_pos.
307 * \returns 0 on success, a non-zero error code on error.
309 static int
310 init_com(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
312 t_methoddata_pos *d = (t_methoddata_pos *)data;
313 int rc;
315 d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0;
316 d->flags |= POS_MASS;
317 rc = gmx_ana_poscalc_create(&d->pc, d->pcc, d->bPBC ? POS_ALL_PBC : POS_ALL,
318 d->flags);
319 if (rc != 0)
321 return rc;
323 gmx_ana_poscalc_set_maxindex(d->pc, &d->g);
324 return 0;
328 * \param[in] top Topology data structure.
329 * \param[in,out] out Pointer to output data structure.
330 * \param[in,out] data Should point to \c t_methoddata_pos.
331 * \returns 0 for success.
333 static int
334 init_output_pos(t_topology *top, gmx_ana_selvalue_t *out, void *data)
336 t_methoddata_pos *d = (t_methoddata_pos *)data;
338 gmx_ana_poscalc_init_pos(d->pc, out->u.p);
339 gmx_ana_pos_set_evalgrp(out->u.p, &d->g);
340 return 0;
344 * \param data Data to free (should point to a \c t_methoddata_pos).
346 * Frees the memory allocated for \c t_methoddata_pos::g and
347 * \c t_methoddata_pos::pc.
349 static void
350 free_data_pos(void *data)
352 t_methoddata_pos *d = (t_methoddata_pos *)data;
354 sfree(d->type);
355 gmx_ana_poscalc_free(d->pc);
359 * See sel_updatefunc() for description of the parameters.
360 * \p data should point to a \c t_methoddata_pos.
362 * Calculates the positions using \c t_methoddata_pos::pc for the index group
363 * in \c t_methoddata_pos::g and stores the results in \p out->u.p.
365 static int
366 evaluate_pos(t_topology *top, t_trxframe *fr, t_pbc *pbc,
367 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
369 t_methoddata_pos *d = (t_methoddata_pos *)data;
371 gmx_ana_poscalc_update(d->pc, out->u.p, &d->g, fr, pbc);
372 return 0;