Don't use POSIX fnmatch() for pattern matching.
[gromacs/qmmm-gamess-us.git] / src / gmxlib / selection / sm_simple.c
blobc7828121df1c94d155c89722d60642ca1e2a1f13
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 Implementations of simple keyword selection methods.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #include <position.h>
39 #include <selmethod.h>
41 /** Evaluates the \p all selection keyword. */
42 static int
43 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
44 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
45 /** Evaluates the \p none selection keyword. */
46 static int
47 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
48 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
49 /** Evaluates the \p atomnr selection keyword. */
50 static int
51 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
52 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
53 /** Evaluates the \p resnr selection keyword. */
54 static int
55 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
56 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
57 /** Evaluates the \p name selection keyword. */
58 static int
59 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
60 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
61 /** Checks whether atom types are present in the topology. */
62 static int
63 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
64 /** Evaluates the \p type selection keyword. */
65 static int
66 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
67 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
68 /** Evaluates the \p insertcode selection keyword. */
69 static int
70 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
71 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
72 /** Evaluates the \p chain selection keyword. */
73 static int
74 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
75 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
76 /** Evaluates the \p mass selection keyword. */
77 static int
78 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
79 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
80 /** Evaluates the \p charge selection keyword. */
81 static int
82 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
83 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
84 /** Checks whether PDB info is present in the topology. */
85 static int
86 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
87 /** Evaluates the \p altloc selection keyword. */
88 static int
89 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
90 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
91 /** Evaluates the \p occupancy selection keyword. */
92 static int
93 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
94 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
95 /** Evaluates the \p betafactor selection keyword. */
96 static int
97 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
98 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
99 /** Evaluates the \p resname selection keyword. */
100 static int
101 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
102 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
104 /** Evaluates the \p x selection keyword. */
105 static int
106 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
107 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
108 /** Evaluates the \p y selection keyword. */
109 static int
110 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
111 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
112 /** Evaluates the \p z selection keyword. */
113 static int
114 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
115 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
117 /** \internal Selection method data for \p all selection keyword. */
118 gmx_ana_selmethod_t sm_all = {
119 "all", GROUP_VALUE, 0,
120 0, NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 &evaluate_all,
128 NULL,
131 /** \internal Selection method data for \p none selection keyword. */
132 gmx_ana_selmethod_t sm_none = {
133 "none", GROUP_VALUE, 0,
134 0, NULL,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 &evaluate_none,
142 NULL,
145 /** \internal Selection method data for \p atomnr selection keyword. */
146 gmx_ana_selmethod_t sm_atomnr = {
147 "atomnr", INT_VALUE, 0,
148 0, NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 &evaluate_atomnr,
156 NULL,
159 /** \internal Selection method data for \p resnr selection keyword. */
160 gmx_ana_selmethod_t sm_resnr = {
161 "resnr", INT_VALUE, SMETH_REQTOP,
162 0, NULL,
163 NULL,
164 NULL,
165 NULL,
166 NULL,
167 NULL,
168 NULL,
169 &evaluate_resnr,
170 NULL,
173 /** \internal Selection method data for \p name selection keyword. */
174 gmx_ana_selmethod_t sm_atomname = {
175 "name", STR_VALUE, SMETH_REQTOP,
176 0, NULL,
177 NULL,
178 NULL,
179 NULL,
180 NULL,
181 NULL,
182 NULL,
183 &evaluate_atomname,
184 NULL,
187 /** \internal Selection method data for \p type selection keyword. */
188 gmx_ana_selmethod_t sm_atomtype = {
189 "type", STR_VALUE, SMETH_REQTOP,
190 0, NULL,
191 NULL,
192 NULL,
193 &check_atomtype,
194 NULL,
195 NULL,
196 NULL,
197 &evaluate_atomtype,
198 NULL,
201 /** \internal Selection method data for \p resname selection keyword. */
202 gmx_ana_selmethod_t sm_resname = {
203 "resname", STR_VALUE, SMETH_REQTOP,
204 0, NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 NULL,
210 NULL,
211 &evaluate_resname,
212 NULL,
215 /** \internal Selection method data for \p chain selection keyword. */
216 gmx_ana_selmethod_t sm_insertcode = {
217 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
218 0, NULL,
219 NULL,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 &evaluate_insertcode,
226 NULL,
229 /** \internal Selection method data for \p chain selection keyword. */
230 gmx_ana_selmethod_t sm_chain = {
231 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
232 0, NULL,
233 NULL,
234 NULL,
235 NULL,
236 NULL,
237 NULL,
238 NULL,
239 &evaluate_chain,
240 NULL,
243 /** \internal Selection method data for \p mass selection keyword. */
244 gmx_ana_selmethod_t sm_mass = {
245 "mass", REAL_VALUE, SMETH_REQTOP,
246 0, NULL,
247 NULL,
248 NULL,
249 NULL,
250 NULL,
251 NULL,
252 NULL,
253 &evaluate_mass,
254 NULL,
257 /** \internal Selection method data for \p charge selection keyword. */
258 gmx_ana_selmethod_t sm_charge = {
259 "charge", REAL_VALUE, SMETH_REQTOP,
260 0, NULL,
261 NULL,
262 NULL,
263 NULL,
264 NULL,
265 NULL,
266 NULL,
267 &evaluate_charge,
268 NULL,
271 /** \internal Selection method data for \p chain selection keyword. */
272 gmx_ana_selmethod_t sm_altloc = {
273 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
274 0, NULL,
275 NULL,
276 NULL,
277 &check_pdbinfo,
278 NULL,
279 NULL,
280 NULL,
281 &evaluate_altloc,
282 NULL,
285 /** \internal Selection method data for \p occupancy selection keyword. */
286 gmx_ana_selmethod_t sm_occupancy = {
287 "occupancy", REAL_VALUE, SMETH_REQTOP,
288 0, NULL,
289 NULL,
290 NULL,
291 &check_pdbinfo,
292 NULL,
293 NULL,
294 NULL,
295 &evaluate_occupancy,
296 NULL,
299 /** \internal Selection method data for \p betafactor selection keyword. */
300 gmx_ana_selmethod_t sm_betafactor = {
301 "betafactor", REAL_VALUE, SMETH_REQTOP,
302 0, NULL,
303 NULL,
304 NULL,
305 &check_pdbinfo,
306 NULL,
307 NULL,
308 NULL,
309 &evaluate_betafactor,
310 NULL,
313 /** \internal Selection method data for \p x selection keyword. */
314 gmx_ana_selmethod_t sm_x = {
315 "x", REAL_VALUE, SMETH_DYNAMIC,
316 0, NULL,
317 NULL,
318 NULL,
319 NULL,
320 NULL,
321 NULL,
322 NULL,
323 NULL,
324 &evaluate_x,
327 /** \internal Selection method data for \p y selection keyword. */
328 gmx_ana_selmethod_t sm_y = {
329 "y", REAL_VALUE, SMETH_DYNAMIC,
330 0, NULL,
331 NULL,
332 NULL,
333 NULL,
334 NULL,
335 NULL,
336 NULL,
337 NULL,
338 &evaluate_y,
341 /** \internal Selection method data for \p z selection keyword. */
342 gmx_ana_selmethod_t sm_z = {
343 "z", REAL_VALUE, SMETH_DYNAMIC,
344 0, NULL,
345 NULL,
346 NULL,
347 NULL,
348 NULL,
349 NULL,
350 NULL,
351 NULL,
352 &evaluate_z,
356 * See sel_updatefunc() for description of the parameters.
357 * \p data is not used.
359 * Copies \p g to \p out->u.g.
361 static int
362 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
363 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
365 gmx_ana_index_copy(out->u.g, g, FALSE);
366 return 0;
370 * See sel_updatefunc() for description of the parameters.
371 * \p data is not used.
373 * Returns an empty \p out->u.g.
375 static int
376 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
377 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
379 out->u.g->isize = 0;
380 return 0;
384 * See sel_updatefunc() for description of the parameters.
385 * \p data is not used.
387 * Returns the indices for each atom in \p out->u.i.
389 static int
390 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
391 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
393 int i;
395 out->nr = g->isize;
396 for (i = 0; i < g->isize; ++i)
398 out->u.i[i] = g->index[i] + 1;
400 return 0;
404 * See sel_updatefunc() for description of the parameters.
405 * \p data is not used.
407 * Returns the residue numbers for each atom in \p out->u.i.
409 static int
410 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
411 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
413 int i;
414 int resind;
416 out->nr = g->isize;
417 for (i = 0; i < g->isize; ++i)
419 resind = top->atoms.atom[g->index[i]].resind;
420 out->u.i[i] = top->atoms.resinfo[resind].nr;
422 return 0;
426 * See sel_updatefunc() for description of the parameters.
427 * \p data is not used.
429 * Returns the atom name for each atom in \p out->u.s.
431 static int
432 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
433 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
435 int i;
437 out->nr = g->isize;
438 for (i = 0; i < g->isize; ++i)
440 out->u.s[i] = *top->atoms.atomname[g->index[i]];
442 return 0;
446 * \param[in] top Topology structure.
447 * \param npar Not used.
448 * \param param Not used.
449 * \param data Not used.
450 * \returns 0 if atom types are present in the topology, -1 otherwise.
452 * If the atom types are not found, also prints an error message.
454 static int
455 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
457 bool bOk;
459 bOk = (top != NULL && top->atoms.atomtype != NULL);
460 if (!bOk)
462 fprintf(stderr, "Atom types not available in topology!\n");
463 return -1;
465 return 0;
469 * See sel_updatefunc() for description of the parameters.
470 * \p data is not used.
472 * Returns the atom type for each atom in \p out->u.s.
473 * Segfaults if atom types are not found in the topology.
475 static int
476 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
477 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
479 int i;
481 out->nr = g->isize;
482 for (i = 0; i < g->isize; ++i)
484 out->u.s[i] = *top->atoms.atomtype[g->index[i]];
486 return 0;
490 * See sel_updatefunc() for description of the parameters.
491 * \p data is not used.
493 * Returns the residue name for each atom in \p out->u.s.
495 static int
496 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
497 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
499 int i;
500 int resind;
502 out->nr = g->isize;
503 for (i = 0; i < g->isize; ++i)
505 resind = top->atoms.atom[g->index[i]].resind;
506 out->u.s[i] = *top->atoms.resinfo[resind].name;
508 return 0;
512 * See sel_updatefunc() for description of the parameters.
513 * \p data is not used.
515 * Returns the insertion code for each atom in \p out->u.s.
517 static int
518 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
519 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
521 int i;
522 int resind;
524 out->nr = g->isize;
525 for (i = 0; i < g->isize; ++i)
527 resind = top->atoms.atom[g->index[i]].resind;
528 out->u.s[i][0] = top->atoms.resinfo[resind].ic;
530 return 0;
534 * See sel_updatefunc() for description of the parameters.
535 * \p data is not used.
537 * Returns the chain for each atom in \p out->u.s.
539 static int
540 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
541 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
543 int i;
544 int resind;
546 out->nr = g->isize;
547 for (i = 0; i < g->isize; ++i)
549 resind = top->atoms.atom[g->index[i]].resind;
550 out->u.s[i][0] = top->atoms.resinfo[resind].chain;
552 return 0;
556 * See sel_updatefunc() for description of the parameters.
557 * \p data is not used.
559 * Returns the mass for each atom in \p out->u.r.
561 static int
562 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
563 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
565 int i;
567 out->nr = g->isize;
568 for (i = 0; i < g->isize; ++i)
570 out->u.r[i] = top->atoms.atom[g->index[i]].m;
572 return 0;
576 * See sel_updatefunc() for description of the parameters.
577 * \p data is not used.
579 * Returns the charge for each atom in \p out->u.r.
581 static int
582 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
583 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
585 int i;
587 out->nr = g->isize;
588 for (i = 0; i < g->isize; ++i)
590 out->u.r[i] = top->atoms.atom[g->index[i]].q;
592 return 0;
596 * \param[in] top Topology structure.
597 * \param npar Not used.
598 * \param param Not used.
599 * \param data Not used.
600 * \returns 0 if PDB info is present in the topology, -1 otherwise.
602 * If PDB info is not found, also prints an error message.
604 static int
605 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
607 bool bOk;
609 bOk = (top != NULL && top->atoms.pdbinfo != NULL);
610 if (!bOk)
612 fprintf(stderr, "PDB info not available in topology!\n");
613 return -1;
615 return 0;
619 * See sel_updatefunc() for description of the parameters.
620 * \p data is not used.
622 * Returns the alternate location identifier for each atom in \p out->u.s.
624 static int
625 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
626 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
628 int i;
630 out->nr = g->isize;
631 for (i = 0; i < g->isize; ++i)
633 out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
635 return 0;
639 * See sel_updatefunc() for description of the parameters.
640 * \p data is not used.
642 * Returns the occupancy numbers for each atom in \p out->u.r.
643 * Segfaults if PDB info is not found in the topology.
645 static int
646 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
647 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
649 int i;
651 out->nr = g->isize;
652 for (i = 0; i < g->isize; ++i)
654 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
656 return 0;
660 * See sel_updatefunc() for description of the parameters.
661 * \p data is not used.
663 * Returns the B-factors for each atom in \p out->u.r.
664 * Segfaults if PDB info is not found in the topology.
666 static int
667 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
668 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
670 int i;
672 out->nr = g->isize;
673 for (i = 0; i < g->isize; ++i)
675 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
677 return 0;
680 /*! \brief
681 * Internal utility function for position keyword evaluation.
683 * \param[in] fr Current frame.
684 * \param[in] g Index group for which the coordinates should be evaluated.
685 * \param[out] out Output array.
686 * \param[in] pos Position data to use instead of atomic coordinates
687 * (can be NULL).
688 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
690 * This function is used internally by evaluate_x(), evaluate_y() and
691 * evaluate_z() to do the actual evaluation.
693 static void
694 evaluate_coord(t_trxframe *fr, gmx_ana_index_t *g, real out[],
695 gmx_ana_pos_t *pos, int d)
697 int b, i;
698 real v;
700 if (pos)
702 for (b = 0; b < pos->nr; ++b)
704 v = pos->x[b][d];
705 for (i = pos->m.mapb.index[b]; i < pos->m.mapb.index[b+1]; ++i)
707 out[i] = v;
711 else
713 for (i = 0; i < g->isize; ++i)
715 out[i] = fr->x[g->index[i]][d];
721 * See sel_updatefunc_pos() for description of the parameters.
722 * \p data is not used.
724 * Returns the \p x coordinate for each atom in \p out->u.r.
726 static int
727 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
728 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
730 out->nr = pos->g->isize;
731 evaluate_coord(fr, pos->g, out->u.r, pos, XX);
732 return 0;
736 * See sel_updatefunc() for description of the parameters.
737 * \p data is not used.
739 * Returns the \p y coordinate for each atom in \p out->u.r.
741 static int
742 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
743 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
745 out->nr = pos->g->isize;
746 evaluate_coord(fr, pos->g, out->u.r, pos, YY);
747 return 0;
751 * See sel_updatefunc() for description of the parameters.
752 * \p data is not used.
754 * Returns the \p z coordinate for each atom in \p out->u.r.
756 static int
757 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
758 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
760 out->nr = pos->g->isize;
761 evaluate_coord(fr, pos->g, out->u.r, pos, ZZ);
762 return 0;