8674f2c0f7bcd11e4c2e946b8094118e75a17226
[alexxy/gromacs.git] / src / gmxlib / selection / sm_keywords.c
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
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.
13
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.
18  *
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.
25  *
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.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief Implementations of internal selection methods for numeric and
33  * string keyword evaluation.
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <ctype.h>
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>  /*old Mac needs types before regex.h*/
42 #endif
43 #ifdef HAVE_REGEX_H
44 #include <regex.h>
45 #define USE_REGEX
46 #endif
47
48 #include <gmx_fatal.h>
49 #include <macros.h>
50 #include <smalloc.h>
51 #include <string2.h>
52
53 #include <selmethod.h>
54
55 #include "keywords.h"
56 #include "parsetree.h"
57 #include "selelem.h"
58
59 /** Allocates data for integer keyword evaluation. */
60 static void *
61 init_data_kwint(int npar, gmx_ana_selparam_t *param);
62 /** Allocates data for real keyword evaluation. */
63 static void *
64 init_data_kwreal(int npar, gmx_ana_selparam_t *param);
65 /** Allocates data for string keyword evaluation. */
66 static void *
67 init_data_kwstr(int npar, gmx_ana_selparam_t *param);
68 /** Initializes data for integer keyword evaluation. */
69 static int
70 init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
71 /** Initializes data for real keyword evaluation. */
72 static int
73 init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
74 /** Initializes data for string keyword evaluation. */
75 static int
76 init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
77 /** Frees the memory allocated for string keyword evaluation. */
78 static void
79 free_data_kwstr(void *data);
80 /** Evaluates integer selection keywords. */
81 static int
82 evaluate_keyword_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
83                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
84 /** Evaluates real selection keywords. */
85 static int
86 evaluate_keyword_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
87                       gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
88 /** Evaluates string selection keywords. */
89 static int
90 evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
91                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
92
93 /*! \internal \brief
94  * Data structure for integer keyword expression evaluation.
95  */
96 typedef struct t_methoddata_kwint
97 {
98     /** Array of values for the keyword. */
99     int               *v;
100     /** Number of ranges in the \p r array. */
101     int                n;
102     /*! \brief
103      * Array of sorted integer ranges to match against.
104      *
105      * Each range is made of two integers, giving the endpoints (inclusive).
106      * This field stores the pointer to the ranges allocated by the
107      * parameter parser; see \ref SPAR_RANGES for more information.
108      */
109     int               *r;
110 } t_methoddata_kwint;
111
112 /*! \internal \brief
113  * Data structure for real keyword expression evaluation.
114  */
115 typedef struct t_methoddata_kwreal
116 {
117     /** Array of values for the keyword. */
118     real              *v;
119     /** Number of ranges in the \p r array. */
120     int                n;
121     /*! \brief
122      * Array of sorted ranges to match against.
123      *
124      * Each range is made of two values, giving the endpoints (inclusive).
125      * This field stores the pointer to the ranges allocated by the
126      * parameter parser; see \ref SPAR_RANGES for more information.
127      */
128     real              *r;
129 } t_methoddata_kwreal;
130
131 /*! \internal \brief
132  * Data structure for string keyword expression evaluation.
133  */
134 typedef struct t_methoddata_kwstr
135 {
136     /** Array of values for the keyword. */
137     char             **v;
138     /** Number of elements in the \p val array. */
139     int                n;
140     /*! \internal \brief
141      * Array of strings/regular expressions to match against.
142      */
143     struct t_methoddata_kwstr_match {
144         /** TRUE if the expression is a regular expression, FALSE otherwise. */
145         bool           bRegExp;
146         /** The value to match against. */
147         union {
148 #ifdef USE_REGEX
149             /** Compiled regular expression if \p bRegExp is TRUE. */
150             regex_t    r;
151 #endif
152             /** The string if \p bRegExp is FALSE; */
153             char      *s;
154         }              u;
155     }                 *m;
156 } t_methoddata_kwstr;
157
158 /** Parameters for integer keyword evaluation. */
159 static gmx_ana_selparam_t smparams_keyword_int[] = {
160     {NULL, {INT_VALUE, -1, {NULL}}, NULL, SPAR_ATOMVAL},
161     {NULL, {INT_VALUE, -1, {NULL}}, NULL, SPAR_RANGES | SPAR_VARNUM},
162 };
163
164 /** Parameters for real keyword evaluation. */
165 static gmx_ana_selparam_t smparams_keyword_real[] = {
166     {NULL, {REAL_VALUE, -1, {NULL}}, NULL, SPAR_ATOMVAL | SPAR_DYNAMIC},
167     {NULL, {REAL_VALUE, -1, {NULL}}, NULL, SPAR_RANGES | SPAR_VARNUM},
168 };
169
170 /** Parameters for string keyword evaluation. */
171 static gmx_ana_selparam_t smparams_keyword_str[] = {
172     {NULL, {STR_VALUE, -1, {NULL}}, NULL, SPAR_ATOMVAL},
173     {NULL, {STR_VALUE, -1, {NULL}}, NULL, SPAR_VARNUM},
174 };
175
176 /** \internal Selection method data for integer keyword evaluation. */
177 gmx_ana_selmethod_t sm_keyword_int = {
178     "kw_int", GROUP_VALUE, SMETH_SINGLEVAL,
179     asize(smparams_keyword_int), smparams_keyword_int,
180     &init_data_kwint,
181      NULL,
182     &init_kwint,
183      NULL,
184      NULL,
185      NULL,
186     &evaluate_keyword_int,
187      NULL,
188     {NULL, 0, NULL},
189 };
190
191 /** \internal Selection method data for real keyword evaluation. */
192 gmx_ana_selmethod_t sm_keyword_real = {
193     "kw_real", GROUP_VALUE, SMETH_SINGLEVAL,
194     asize(smparams_keyword_real), smparams_keyword_real,
195     &init_data_kwreal,
196      NULL,
197     &init_kwreal,
198      NULL,
199      NULL,
200      NULL,
201     &evaluate_keyword_real,
202      NULL,
203     {NULL, 0, NULL},
204 };
205
206 /** \internal Selection method data for string keyword evaluation. */
207 gmx_ana_selmethod_t sm_keyword_str = {
208     "kw_str", GROUP_VALUE, SMETH_SINGLEVAL,
209     asize(smparams_keyword_str), smparams_keyword_str,
210     &init_data_kwstr,
211      NULL,
212     &init_kwstr,
213      NULL,
214     &free_data_kwstr,
215      NULL,
216     &evaluate_keyword_str,
217      NULL,
218     {NULL, 0, NULL},
219 };
220
221 /** Initializes keyword evaluation for an arbitrary group. */
222 static int
223 init_kweval(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
224 /** Initializes output for keyword evaluation in an arbitrary group. */
225 static int
226 init_output_kweval(t_topology *top, gmx_ana_selvalue_t *out, void *data);
227 /** Frees the data allocated for keyword evaluation in an arbitrary group. */
228 static void
229 free_data_kweval(void *data);
230 /** Initializes frame evaluation for keyword evaluation in an arbitrary group. */
231 static int
232 init_frame_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data);
233 /** Evaluates keywords in an arbitrary group. */
234 static int
235 evaluate_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc,
236                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
237
238 /*! \internal \brief
239  * Data structure for keyword evaluation in arbitrary groups.
240  */
241 typedef struct
242 {
243     /** Wrapped keyword method for evaluating the values. */
244     gmx_ana_selmethod_t  *kwmethod;
245     /** Method data for \p kwmethod. */
246     void                 *kwmdata;
247     /** Group in which \p kwmethod should be evaluated. */
248     gmx_ana_index_t       g;
249 } t_methoddata_kweval;
250
251 /** Parameters for keyword evaluation in an arbitrary group. */
252 static gmx_ana_selparam_t smparams_kweval[] = {
253     {NULL,   {GROUP_VALUE, 1, {NULL}}, NULL, SPAR_DYNAMIC},
254 };
255
256
257 /********************************************************************
258  * INTEGER KEYWORD EVALUATION
259  ********************************************************************/
260
261 /*!
262  * \param[in] npar  Not used.
263  * \param     param Not used.
264  * \returns   Pointer to the allocated data (\ref t_methoddata_kwint).
265  *
266  * Allocates memory for a \ref t_methoddata_kwint structure.
267  */
268 static void *
269 init_data_kwint(int npar, gmx_ana_selparam_t *param)
270 {
271     t_methoddata_kwint *data;
272
273     snew(data, 1);
274     return data;
275 }
276
277 /*!
278  * \param[in] top   Not used.
279  * \param[in] npar  Not used (should be 2).
280  * \param[in] param Method parameters (should point to \ref smparams_keyword_int).
281  * \param[in] data  Should point to \ref t_methoddata_kwint.
282  * \returns   0 (the initialization always succeeds).
283  */
284 static int
285 init_kwint(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
286 {
287     t_methoddata_kwint *d = (t_methoddata_kwint *)data;
288
289     d->v = param[0].val.u.i;
290     d->n = param[1].val.nr;
291     d->r = param[1].val.u.i;
292     return 0;
293 }
294
295 /*!
296  * See sel_updatefunc() for description of the parameters.
297  * \p data should point to a \c t_methoddata_kwint.
298  *
299  * Does a binary search to find which atoms match the ranges in the
300  * \c t_methoddata_kwint structure for this selection.
301  * Matching atoms are stored in \p out->u.g.
302  */
303 static int
304 evaluate_keyword_int(t_topology *top, t_trxframe *fr, t_pbc *pbc,
305                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
306 {
307     t_methoddata_kwint *d = (t_methoddata_kwint *)data;
308     int                 n, i, j, jmin, jmax;
309     int                 val;
310
311     out->u.g->isize = 0;
312     n    = d->n;
313     for (i = 0; i < g->isize; ++i)
314     {
315         val = d->v[i];
316         if (d->r[0] > val || d->r[2*n-1] < val)
317         {
318             continue;
319         }
320         jmin = 0;
321         jmax = n;
322         while (jmax - jmin > 1)
323         {
324             j = jmin + (jmax - jmin) / 2;
325             if (val < d->r[2*j])
326             {
327                 jmax = j;
328             }
329             else
330             {
331                 jmin = j;
332                 if (val <= d->r[2*j+1])
333                 {
334                     break;
335                 }
336                 /* ++jmin;*/
337             }
338         }
339         if (val <= d->r[2*jmin+1])
340         {
341             out->u.g->index[out->u.g->isize++] = g->index[i];
342         }
343     }
344     return 0;
345 }
346
347
348 /********************************************************************
349  * REAL KEYWORD EVALUATION
350  ********************************************************************/
351
352 /*!
353  * \param[in] npar  Not used.
354  * \param     param Not used.
355  * \returns   Pointer to the allocated data (\ref t_methoddata_kwreal).
356  *
357  * Allocates memory for a \ref t_methoddata_kwreal structure.
358  */
359 static void *
360 init_data_kwreal(int npar, gmx_ana_selparam_t *param)
361 {
362     t_methoddata_kwreal *data;
363
364     snew(data, 1);
365     return data;
366 }
367
368 /*!
369  * \param[in] top   Not used.
370  * \param[in] npar  Not used (should be 2).
371  * \param[in] param Method parameters (should point to \ref smparams_keyword_real).
372  * \param[in] data  Should point to \ref t_methoddata_kwreal.
373  * \returns   0 (the initialization always succeeds).
374  */
375 static int
376 init_kwreal(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
377 {
378     t_methoddata_kwreal *d = (t_methoddata_kwreal *)data;
379
380     d->v = param[0].val.u.r;
381     d->n = param[1].val.nr;
382     d->r = param[1].val.u.r;
383     return 0;
384 }
385
386 /*!
387  * See sel_updatefunc() for description of the parameters.
388  * \p data should point to a \c t_methoddata_kwreal.
389  *
390  * Does a binary search to find which atoms match the ranges in the
391  * \c t_methoddata_kwreal structure for this selection.
392  * Matching atoms are stored in \p out->u.g.
393  */
394 static int
395 evaluate_keyword_real(t_topology *top, t_trxframe *fr, t_pbc *pbc,
396                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
397 {
398     t_methoddata_kwreal *d = (t_methoddata_kwreal *)data;
399     int                  n, i, j, jmin, jmax;
400     real                 val;
401
402     out->u.g->isize = 0;
403     n    = d->n;
404     for (i = 0; i < g->isize; ++i)
405     {
406         val = d->v[i];
407         if (d->r[0] > val || d->r[2*n-1] < val)
408         {
409             continue;
410         }
411         jmin = 0;
412         jmax = n;
413         while (jmax - jmin > 1)
414         {
415             j = jmin + (jmax - jmin) / 2;
416             if (val < d->r[2*j])
417             {
418                 jmax = j;
419             }
420             else
421             {
422                 jmin = j;
423                 if (val <= d->r[2*j+1])
424                 {
425                     break;
426                 }
427                 /* ++jmin;*/
428             }
429         }
430         if (val <= d->r[2*jmin+1])
431         {
432             out->u.g->index[out->u.g->isize++] = g->index[i];
433         }
434     }
435     return 0;
436 }
437
438
439 /********************************************************************
440  * STRING KEYWORD EVALUATION
441  ********************************************************************/
442
443 /*!
444  * \param[in] npar  Not used.
445  * \param     param Not used.
446  * \returns Pointer to the allocated data (\ref t_methoddata_kwstr).
447  *
448  * Allocates memory for a \ref t_methoddata_kwstr structure.
449  */
450 static void *
451 init_data_kwstr(int npar, gmx_ana_selparam_t *param)
452 {
453     t_methoddata_kwstr *data;
454
455     snew(data, 1);
456     return data;
457 }
458
459 /*!
460  * \param[in] top   Not used.
461  * \param[in] npar  Not used (should be 2).
462  * \param[in] param Method parameters (should point to \ref smparams_keyword_str).
463  * \param[in] data  Should point to \ref t_methoddata_kwstr.
464  * \returns   0 (the initialization always succeeds).
465  */
466 static int
467 init_kwstr(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
468 {
469     t_methoddata_kwstr *d = (t_methoddata_kwstr *)data;
470     char               *buf;
471     char               *s;
472     int                 i;
473     size_t              j;
474     bool                bRegExp;
475
476     d->v   = param[0].val.u.s;
477     d->n   = param[1].val.nr;
478     /* Return if this is not the first time */
479     if (d->m)
480     {
481         return 0;
482     }
483     snew(d->m, d->n);
484     for (i = 0; i < d->n; ++i)
485     {
486         s = param[1].val.u.s[i];
487         bRegExp = FALSE;
488         for (j = 0; j < strlen(s); ++j)
489         {
490             if (ispunct(s[j]) && s[j] != '?' && s[j] != '*')
491             {
492                 bRegExp = TRUE;
493                 break;
494             }
495         }
496         if (bRegExp)
497         {
498 #ifdef USE_REGEX
499             snew(buf, strlen(s) + 3);
500             sprintf(buf, "^%s$", s);
501             if (regcomp(&d->m[i].u.r, buf, REG_EXTENDED | REG_NOSUB))
502             {
503                 bRegExp = FALSE;
504                 fprintf(stderr, "WARNING: error in regular expression,\n"
505                                 "         will match '%s' as a simple string\n", s);
506             }
507             sfree(buf);
508 #else
509             bRegExp = FALSE;
510             fprintf(stderr, "WARNING: no regular expressions support,\n"
511                             "         will match '%s' as a simple string\n", s);
512 #endif
513         }
514         if (!bRegExp)
515         {
516             d->m[i].u.s = s;
517         }
518         d->m[i].bRegExp = bRegExp;
519     }
520     return 0;
521 }
522
523 /*!
524  * \param data Data to free (should point to a \ref t_methoddata_kwstr).
525  *
526  * Frees the memory allocated for t_methoddata_kwstr::val.
527  */
528 static void
529 free_data_kwstr(void *data)
530 {
531     t_methoddata_kwstr *d = (t_methoddata_kwstr *)data;
532     int                 i;
533
534     for (i = 0; i < d->n; ++i)
535     {
536         if (d->m[i].bRegExp)
537         {
538 #ifdef USE_REGEX
539             /* This branch should only be taken if regular expressions
540              * are available, but the ifdef is still needed. */
541             regfree(&d->m[i].u.r);
542 #endif
543         }
544     }
545     sfree(d->m);
546 }
547
548 /*!
549  * See sel_updatefunc() for description of the parameters.
550  * \p data should point to a \c t_methoddata_kwstr.
551  *
552  * Does a linear search to find which atoms match the strings in the
553  * \c t_methoddata_kwstr structure for this selection.
554  * Wildcards are allowed in the strings.
555  * Matching atoms are stored in \p out->u.g.
556  */
557 static int
558 evaluate_keyword_str(t_topology *top, t_trxframe *fr, t_pbc *pbc,
559                      gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
560 {
561     t_methoddata_kwstr *d = (t_methoddata_kwstr *)data;
562     int                 i, j;
563     bool                bFound;
564
565     out->u.g->isize = 0;
566     for (i = 0; i < g->isize; ++i)
567     {
568         bFound = FALSE;
569         for (j = 0; j < d->n && !bFound; ++j)
570         {
571             if (d->m[j].bRegExp)
572             {
573 #ifdef USE_REGEX
574                 /* This branch should only be taken if regular expressions
575                  * are available, but the ifdef is still needed. */
576                 if (!regexec(&d->m[j].u.r, d->v[i], 0, NULL, 0))
577                 {
578                     bFound = TRUE;
579                 }
580 #endif
581             }
582             else
583             {
584                 if (gmx_wcmatch(d->m[j].u.s, d->v[i]) == 0)
585                 {
586                     bFound = TRUE;
587                 }
588             }
589         }
590         if (bFound)
591         {
592             out->u.g->index[out->u.g->isize++] = g->index[i];
593         }
594     }
595     return 0;
596 }
597
598
599 /********************************************************************
600  * KEYWORD EVALUATION FOR ARBITRARY GROUPS
601  ********************************************************************/
602
603 /*!
604  * \param[in] top   Not used.
605  * \param[in] npar  Not used.
606  * \param[in] param Not used.
607  * \param[in] data  Should point to \ref t_methoddata_kweval.
608  * \returns   0 on success, a non-zero error code on return.
609  *
610  * Calls the initialization method of the wrapped keyword.
611  */
612 static int
613 init_kweval(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
614 {
615     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
616
617     return d->kwmethod->init(top, 0, NULL, d->kwmdata);
618 }
619
620 /*!
621  * \param[in]     top   Not used.
622  * \param[in,out] out   Pointer to output data structure.
623  * \param[in,out] data  Should point to \c t_methoddata_kweval.
624  * \returns       0 for success.
625  */
626 static int
627 init_output_kweval(t_topology *top, gmx_ana_selvalue_t *out, void *data)
628 {
629     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
630
631     out->nr = d->g.isize;
632     return 0;
633 }
634
635 /*!
636  * \param data Data to free (should point to a \c t_methoddata_kweval).
637  *
638  * Frees the memory allocated for all the members of \c t_methoddata_kweval.
639  */
640 static void
641 free_data_kweval(void *data)
642 {
643     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
644
645     _gmx_selelem_free_method(d->kwmethod, d->kwmdata);
646 }
647
648 /*!
649  * \param[in]  top  Topology.
650  * \param[in]  fr   Current frame.
651  * \param[in]  pbc  PBC structure.
652  * \param      data Should point to a \ref t_methoddata_kweval.
653  * \returns    0 on success, a non-zero error code on error.
654  *
655  * Creates a lookup structure that enables fast queries of whether a point
656  * is within the solid angle or not.
657  */
658 static int
659 init_frame_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc, void *data)
660 {
661     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
662
663     return d->kwmethod->init_frame(top, fr, pbc, d->kwmdata);
664 }
665
666 /*!
667  * See sel_updatefunc() for description of the parameters.
668  * \p data should point to a \c t_methoddata_kweval.
669  *
670  * Calls the evaluation function of the wrapped keyword with the given
671  * parameters, with the exception of using \c t_methoddata_kweval::g for the
672  * evaluation group.
673  */
674 static int
675 evaluate_kweval(t_topology *top, t_trxframe *fr, t_pbc *pbc,
676                 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
677 {
678     t_methoddata_kweval *d = (t_methoddata_kweval *)data;
679
680     return d->kwmethod->update(top, fr, pbc, &d->g, out, d->kwmdata);
681 }
682
683 /*!
684  * \param[out]  selp    Pointer to receive a pointer to the created selection
685  *      element (set to NULL on error).
686  * \param[in]   method  Keyword selection method to evaluate.
687  * \param[in]   param   Parameter that gives the group to evaluate \p method in.
688  * \param[in]   scanner Scanner data structure.
689  * \returns     0 on success, non-zero error code on error.
690  *
691  * Creates a \ref SEL_EXPRESSION selection element (pointer put in \c *selp)
692  * that evaluates the keyword method given by \p method in the group given by
693  * \p param.
694  */
695 int
696 _gmx_sel_init_keyword_evaluator(t_selelem **selp, gmx_ana_selmethod_t *method,
697                                 t_selexpr_param *param, void *scanner)
698 {
699     t_selelem            *sel;
700     t_methoddata_kweval  *data;
701
702     if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL))
703         || method->outinit || method->pupdate)
704     {
705         _gmx_selexpr_free_params(param);
706         gmx_incons("unsupported keyword method for arbitrary group evaluation");
707         return -1;
708     }
709
710     *selp = NULL;
711     sel = _gmx_selelem_create(SEL_EXPRESSION);
712     _gmx_selelem_set_method(sel, method, scanner);
713
714     snew(data, 1);
715     data->kwmethod = sel->u.expr.method;
716     data->kwmdata  = sel->u.expr.mdata;
717     gmx_ana_index_clear(&data->g);
718
719     snew(sel->u.expr.method, 1);
720     memcpy(sel->u.expr.method, data->kwmethod, sizeof(gmx_ana_selmethod_t));
721     sel->u.expr.method->flags       |= SMETH_VARNUMVAL;
722     sel->u.expr.method->init_data    = NULL;
723     sel->u.expr.method->set_poscoll  = NULL;
724     sel->u.expr.method->init         = method->init ? &init_kweval : NULL;
725     sel->u.expr.method->outinit      = &init_output_kweval;
726     sel->u.expr.method->free         = &free_data_kweval;
727     sel->u.expr.method->init_frame   = method->init_frame ? &init_frame_kweval : NULL;
728     sel->u.expr.method->update       = &evaluate_kweval;
729     sel->u.expr.method->pupdate      = NULL;
730     sel->u.expr.method->nparams      = asize(smparams_kweval);
731     sel->u.expr.method->param        = smparams_kweval;
732     _gmx_selelem_init_method_params(sel, scanner);
733     sel->u.expr.mdata = data;
734
735     sel->u.expr.method->param[0].val.u.g = &data->g;
736
737     sfree(param->name);
738     param->name = NULL;
739     if (!_gmx_sel_parse_params(param, sel->u.expr.method->nparams,
740                                sel->u.expr.method->param, sel, scanner))
741     {
742         _gmx_selelem_free(sel);
743         return -1;
744     }
745     *selp = sel;
746     return 0;
747 }