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 Implementations of internal selection methods for integer and
33 * string keyword evaluation.
46 #include <selmethod.h>
48 /** Allocates data for integer keyword evaluation. */
50 init_data_kwint(int npar
, gmx_ana_selparam_t
*param
);
51 /** Allocates data for string keyword evaluation. */
53 init_data_kwstr(int npar
, gmx_ana_selparam_t
*param
);
54 /** Initializes data for integer keyword evaluation. */
56 init_kwint(t_topology
*top
, int npar
, gmx_ana_selparam_t
*param
, void *data
);
57 /** Initializes data for string keyword evaluation. */
59 init_kwstr(t_topology
*top
, int npar
, gmx_ana_selparam_t
*param
, void *data
);
60 /** Frees the memory allocated for integer keyword evaluation. */
62 free_data_kwint(void *data
);
63 /** Frees the memory allocated for string keyword evaluation. */
65 free_data_kwstr(void *data
);
66 /** Evaluates integer selection keywords. */
68 evaluate_keyword_int(t_topology
*top
, t_trxframe
*fr
, t_pbc
*pbc
,
69 gmx_ana_index_t
*g
, gmx_ana_selvalue_t
*out
, void *data
);
70 /** Evaluates string selection keywords. */
72 evaluate_keyword_str(t_topology
*top
, t_trxframe
*fr
, t_pbc
*pbc
,
73 gmx_ana_index_t
*g
, gmx_ana_selvalue_t
*out
, void *data
);
76 * Data structure for integer keyword expression evaluation.
78 typedef struct t_methoddata_kwint
80 /** Array of values for the keyword. */
82 /** Number of ranges in the \p r array. */
85 * Array of sorted integer ranges to match against.
87 * Each range is made of two integers, giving the endpoints (inclusive).
88 * This field stores the pointer to the ranges allocated by the
89 * parameter parser; see \ref SPAR_RANGES for more information.
95 * Data structure for string keyword expression evaluation.
97 typedef struct t_methoddata_kwstr
99 /** Array of values for the keyword. */
101 /** Number of elements in the \p val array. */
104 * Array of strings/regular expressions to match against.
106 struct t_methoddata_kwstr_match
{
107 /** TRUE if the expression is a regular expression, FALSE otherwise. */
109 /** The value to match against. */
111 /** Compiled regular expression if \p bRegExp is TRUE. */
113 /** The string if \p bRegExp is FALSE; */
117 } t_methoddata_kwstr
;
119 /** Parameters for integer keyword evaluation. */
120 static gmx_ana_selparam_t smparams_keyword_int
[] = {
121 {NULL
, {INT_VALUE
, -1, {NULL
}}, NULL
, SPAR_ATOMVAL
},
122 {NULL
, {INT_VALUE
, -1, {NULL
}}, NULL
, SPAR_RANGES
| SPAR_VARNUM
},
125 /** Parameters for string keyword evaluation. */
126 static gmx_ana_selparam_t smparams_keyword_str
[] = {
127 {NULL
, {STR_VALUE
, -1, {NULL
}}, NULL
, SPAR_ATOMVAL
},
128 {NULL
, {STR_VALUE
, -1, {NULL
}}, NULL
, SPAR_VARNUM
},
131 /** \internal Selection method data for integer keyword evaluation. */
132 gmx_ana_selmethod_t sm_keyword_int
= {
133 "kw_int", GROUP_VALUE
, SMETH_SINGLEVAL
,
134 asize(smparams_keyword_int
), smparams_keyword_int
,
141 &evaluate_keyword_int
,
146 /** \internal Selection method data for string keyword evaluation. */
147 gmx_ana_selmethod_t sm_keyword_str
= {
148 "kw_str", GROUP_VALUE
, SMETH_SINGLEVAL
,
149 asize(smparams_keyword_str
), smparams_keyword_str
,
156 &evaluate_keyword_str
,
162 /********************************************************************
163 * INTEGER KEYWORD EVALUATION
164 ********************************************************************/
167 * \param[in] npar Not used.
168 * \param param Not used.
169 * \returns Pointer to the allocated data (\ref t_methoddata_kwint).
171 * Allocates memory for a \ref t_methoddata_kwint structure.
174 init_data_kwint(int npar
, gmx_ana_selparam_t
*param
)
176 t_methoddata_kwint
*data
;
183 * \param[in] top Not used.
184 * \param[in] npar Not used (should be 2).
185 * \param[in] param Method parameters (should point to \ref smparams_keyword_int).
186 * \param[in] data Should point to \ref t_methoddata_kwint.
187 * \returns 0 (the initialization always succeeds).
190 init_kwint(t_topology
*top
, int npar
, gmx_ana_selparam_t
*param
, void *data
)
192 t_methoddata_kwint
*d
= (t_methoddata_kwint
*)data
;
194 d
->v
= param
[0].val
.u
.i
;
195 d
->n
= param
[1].val
.nr
;
196 d
->r
= param
[1].val
.u
.i
;
201 * \param data Data to free (should point to a \ref t_methoddata_kwint).
203 * Frees the memory allocated for t_methoddata_kwint::r.
206 free_data_kwint(void *data
)
208 t_methoddata_kwint
*d
= (t_methoddata_kwint
*)data
;
215 * See sel_updatefunc() for description of the parameters.
216 * \p data should point to a \c t_methoddata_kwint.
218 * Does a binary search to find which atoms match the ranges in the
219 * \c t_methoddata_kwint structure for this selection.
220 * Matching atoms are stored in \p out->u.g.
223 evaluate_keyword_int(t_topology
*top
, t_trxframe
*fr
, t_pbc
*pbc
,
224 gmx_ana_index_t
*g
, gmx_ana_selvalue_t
*out
, void *data
)
226 t_methoddata_kwint
*d
= (t_methoddata_kwint
*)data
;
227 int n
, i
, j
, jmin
, jmax
;
232 for (i
= 0; i
< g
->isize
; ++i
)
235 if (d
->r
[0] > val
|| d
->r
[2*n
-1] < val
)
241 while (jmax
- jmin
> 1)
243 j
= jmin
+ (jmax
- jmin
) / 2;
251 if (val
<= d
->r
[2*j
+1])
258 if (val
<= d
->r
[2*jmin
+1])
260 out
->u
.g
->index
[out
->u
.g
->isize
++] = g
->index
[i
];
267 /********************************************************************
268 * STRING KEYWORD EVALUATION
269 ********************************************************************/
272 * \param[in] npar Not used.
273 * \param param Not used.
274 * \returns Pointer to the allocated data (\ref t_methoddata_kwstr).
276 * Allocates memory for a \ref t_methoddata_kwstr structure.
279 init_data_kwstr(int npar
, gmx_ana_selparam_t
*param
)
281 t_methoddata_kwstr
*data
;
288 * \param[in] top Not used.
289 * \param[in] npar Not used (should be 2).
290 * \param[in] param Method parameters (should point to \ref smparams_keyword_str).
291 * \param[in] data Should point to \ref t_methoddata_kwstr.
292 * \returns 0 (the initialization always succeeds).
295 init_kwstr(t_topology
*top
, int npar
, gmx_ana_selparam_t
*param
, void *data
)
297 t_methoddata_kwstr
*d
= (t_methoddata_kwstr
*)data
;
304 d
->v
= param
[0].val
.u
.s
;
305 d
->n
= param
[1].val
.nr
;
306 /* Return if this is not the first time */
312 for (i
= 0; i
< d
->n
; ++i
)
314 s
= param
[1].val
.u
.s
[i
];
316 for (j
= 0; j
< strlen(s
); ++j
)
318 if (ispunct(s
[j
]) && s
[j
] != '?' && s
[j
] != '*')
326 snew(buf
, strlen(s
) + 3);
327 sprintf(buf
, "^%s$", s
);
328 if (regcomp(&d
->m
[i
].u
.r
, buf
, REG_EXTENDED
| REG_NOSUB
))
331 fprintf(stderr
, "warning: will match '%s' as a simple string\n", s
);
343 d
->m
[i
].bRegExp
= bRegExp
;
345 sfree(param
[1].val
.u
.s
);
350 * \param data Data to free (should point to a \ref t_methoddata_kwstr).
352 * Frees the memory allocated for t_methoddata_kwstr::val.
355 free_data_kwstr(void *data
)
357 t_methoddata_kwstr
*d
= (t_methoddata_kwstr
*)data
;
361 for (i
= 0; i
< d
->n
; ++i
)
365 regfree(&d
->m
[i
].u
.r
);
376 * See sel_updatefunc() for description of the parameters.
377 * \p data should point to a \c t_methoddata_kwstr.
379 * Does a linear search to find which atoms match the strings in the
380 * \c t_methoddata_kwstr structure for this selection.
381 * Wildcards are allowed in the strings.
382 * Matching atoms are stored in \p out->u.g.
385 evaluate_keyword_str(t_topology
*top
, t_trxframe
*fr
, t_pbc
*pbc
,
386 gmx_ana_index_t
*g
, gmx_ana_selvalue_t
*out
, void *data
)
388 t_methoddata_kwstr
*d
= (t_methoddata_kwstr
*)data
;
393 for (i
= 0; i
< g
->isize
; ++i
)
396 for (j
= 0; j
< d
->n
&& !bFound
; ++j
)
400 if (!regexec(&d
->m
[j
].u
.r
, d
->v
[i
], 0, NULL
, 0))
407 if (gmx_wcmatch(d
->m
[j
].u
.s
, d
->v
[i
]) == 0)
415 out
->u
.g
->index
[out
->u
.g
->isize
++] = g
->index
[i
];