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, 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 Implementations of simple keyword selection methods.
49 #include <selmethod.h>
51 /** Evaluates the \p all selection keyword. */
53 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
54 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
55 /** Evaluates the \p none selection keyword. */
57 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
58 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
59 /** Evaluates the \p atomnr selection keyword. */
61 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
62 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
63 /** Evaluates the \p resnr selection keyword. */
65 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
66 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
67 /** Evaluates the \p resindex selection keyword. */
69 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
70 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
71 /** Checks whether molecule information is present in the topology. */
73 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
74 /** Evaluates the \p molindex selection keyword. */
76 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
77 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
78 /** Evaluates the \p atomname selection keyword. */
80 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
81 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
82 /** Evaluates the \p pdbatomname selection keyword. */
84 evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
85 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
86 /** Checks whether atom types are present in the topology. */
88 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
89 /** Evaluates the \p atomtype selection keyword. */
91 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
92 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
93 /** Evaluates the \p insertcode selection keyword. */
95 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
96 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
97 /** Evaluates the \p chain selection keyword. */
99 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
100 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
101 /** Evaluates the \p mass selection keyword. */
103 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
104 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
105 /** Evaluates the \p charge selection keyword. */
107 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
108 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
109 /** Checks whether PDB info is present in the topology. */
111 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
112 /** Evaluates the \p altloc selection keyword. */
114 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
115 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
116 /** Evaluates the \p occupancy selection keyword. */
118 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
119 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
120 /** Evaluates the \p betafactor selection keyword. */
122 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
123 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
124 /** Evaluates the \p resname selection keyword. */
126 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
127 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
129 /** Evaluates the \p x selection keyword. */
131 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
132 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
133 /** Evaluates the \p y selection keyword. */
135 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
136 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
137 /** Evaluates the \p z selection keyword. */
139 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
140 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
142 /** Help text for atom name selection keywords. */
143 static const char *help_atomname[] = {
144 "ATOM NAME SELECTION KEYWORDS[PAR]",
146 "[TT]name[tt] [TT]pdbname[tt] [TT]atomname[tt] [TT]pdbatomname[tt][PAR]",
148 "These keywords select atoms by name. [TT]name[tt] selects atoms using",
149 "the Gromacs atom naming convention.",
150 "For input formats other than PDB, the atom names are matched exactly",
151 "as they appear in the input file. For PDB files, 4 character atom names",
152 "that start with a digit are matched after moving the digit to the end",
153 "(e.g., to match 3HG2 from a PDB file, use [TT]name HG23[tt]).",
154 "[TT]pdbname[tt] can only be used with a PDB input file, and selects",
155 "atoms based on the exact name given in the input file, without the",
156 "transformation described above.[PAR]",
158 "[TT]atomname[tt] and [TT]pdbatomname[tt] are synonyms for the above two",
162 /** \internal Selection method data for \p all selection keyword. */
163 gmx_ana_selmethod_t sm_all = {
164 "all", GROUP_VALUE, 0,
176 /** \internal Selection method data for \p none selection keyword. */
177 gmx_ana_selmethod_t sm_none = {
178 "none", GROUP_VALUE, 0,
190 /** \internal Selection method data for \p atomnr selection keyword. */
191 gmx_ana_selmethod_t sm_atomnr = {
192 "atomnr", INT_VALUE, 0,
204 /** \internal Selection method data for \p resnr selection keyword. */
205 gmx_ana_selmethod_t sm_resnr = {
206 "resnr", INT_VALUE, SMETH_REQTOP,
218 /** \internal Selection method data for \p resindex selection keyword. */
219 gmx_ana_selmethod_t sm_resindex = {
220 "resindex", INT_VALUE, SMETH_REQTOP,
232 /** \internal Selection method data for \p molindex selection keyword. */
233 gmx_ana_selmethod_t sm_molindex = {
234 "molindex", INT_VALUE, SMETH_REQTOP,
246 /** \internal Selection method data for \p name selection keyword. */
247 gmx_ana_selmethod_t sm_atomname = {
248 "atomname", STR_VALUE, SMETH_REQTOP,
258 {NULL, asize(help_atomname), help_atomname}
261 /** \internal Selection method data for \p pdbatomname selection keyword. */
262 gmx_ana_selmethod_t sm_pdbatomname = {
263 "pdbatomname", STR_VALUE, SMETH_REQTOP,
271 &evaluate_pdbatomname,
273 {NULL, asize(help_atomname), help_atomname}
276 /** \internal Selection method data for \p type selection keyword. */
277 gmx_ana_selmethod_t sm_atomtype = {
278 "atomtype", STR_VALUE, SMETH_REQTOP,
290 /** \internal Selection method data for \p resname selection keyword. */
291 gmx_ana_selmethod_t sm_resname = {
292 "resname", STR_VALUE, SMETH_REQTOP,
304 /** \internal Selection method data for \p chain selection keyword. */
305 gmx_ana_selmethod_t sm_insertcode = {
306 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
314 &evaluate_insertcode,
318 /** \internal Selection method data for \p chain selection keyword. */
319 gmx_ana_selmethod_t sm_chain = {
320 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
332 /** \internal Selection method data for \p mass selection keyword. */
333 gmx_ana_selmethod_t sm_mass = {
334 "mass", REAL_VALUE, SMETH_REQTOP,
346 /** \internal Selection method data for \p charge selection keyword. */
347 gmx_ana_selmethod_t sm_charge = {
348 "charge", REAL_VALUE, SMETH_REQTOP,
360 /** \internal Selection method data for \p chain selection keyword. */
361 gmx_ana_selmethod_t sm_altloc = {
362 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
374 /** \internal Selection method data for \p occupancy selection keyword. */
375 gmx_ana_selmethod_t sm_occupancy = {
376 "occupancy", REAL_VALUE, SMETH_REQTOP,
388 /** \internal Selection method data for \p betafactor selection keyword. */
389 gmx_ana_selmethod_t sm_betafactor = {
390 "betafactor", REAL_VALUE, SMETH_REQTOP,
398 &evaluate_betafactor,
402 /** \internal Selection method data for \p x selection keyword. */
403 gmx_ana_selmethod_t sm_x = {
404 "x", REAL_VALUE, SMETH_DYNAMIC,
416 /** \internal Selection method data for \p y selection keyword. */
417 gmx_ana_selmethod_t sm_y = {
418 "y", REAL_VALUE, SMETH_DYNAMIC,
430 /** \internal Selection method data for \p z selection keyword. */
431 gmx_ana_selmethod_t sm_z = {
432 "z", REAL_VALUE, SMETH_DYNAMIC,
445 * See sel_updatefunc() for description of the parameters.
446 * \p data is not used.
448 * Copies \p g to \p out->u.g.
451 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
452 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
454 gmx_ana_index_copy(out->u.g, g, FALSE);
459 * See sel_updatefunc() for description of the parameters.
460 * \p data is not used.
462 * Returns an empty \p out->u.g.
465 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
466 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
473 * See sel_updatefunc() for description of the parameters.
474 * \p data is not used.
476 * Returns the indices for each atom in \p out->u.i.
479 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
480 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
485 for (i = 0; i < g->isize; ++i)
487 out->u.i[i] = g->index[i] + 1;
493 * See sel_updatefunc() for description of the parameters.
494 * \p data is not used.
496 * Returns the residue numbers for each atom in \p out->u.i.
499 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
500 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
506 for (i = 0; i < g->isize; ++i)
508 resind = top->atoms.atom[g->index[i]].resind;
509 out->u.i[i] = top->atoms.resinfo[resind].nr;
515 * See sel_updatefunc() for description of the parameters.
516 * \p data is not used.
518 * Returns the residue indices for each atom in \p out->u.i.
521 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
522 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
527 for (i = 0; i < g->isize; ++i)
529 out->u.i[i] = top->atoms.atom[g->index[i]].resind + 1;
535 * \param[in] top Topology structure.
536 * \param npar Not used.
537 * \param param Not used.
538 * \param data Not used.
539 * \returns 0 if molecule info is present in the topology, -1 otherwise.
541 * If molecule information is not found, also prints an error message.
544 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
548 bOk = (top != NULL && top->mols.nr > 0);
551 fprintf(stderr, "Molecule information not available in topology!\n");
558 * See sel_updatefunc() for description of the parameters.
559 * \p data is not used.
561 * Returns the molecule indices for each atom in \p out->u.i.
564 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
565 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
570 for (i = j = 0; i < g->isize; ++i)
572 while (top->mols.index[j + 1] <= g->index[i]) ++j;
579 * See sel_updatefunc() for description of the parameters.
580 * \p data is not used.
582 * Returns the atom name for each atom in \p out->u.s.
585 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
586 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
591 for (i = 0; i < g->isize; ++i)
593 out->u.s[i] = *top->atoms.atomname[g->index[i]];
599 * See sel_updatefunc() for description of the parameters.
600 * \p data is not used.
602 * Returns the PDB atom name for each atom in \p out->u.s.
605 evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
606 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
611 for (i = 0; i < g->isize; ++i)
613 char *s = top->atoms.pdbinfo[g->index[i]].atomnm;
624 * \param[in] top Topology structure.
625 * \param npar Not used.
626 * \param param Not used.
627 * \param data Not used.
628 * \returns 0 if atom types are present in the topology, -1 otherwise.
630 * If the atom types are not found, also prints an error message.
633 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
637 bOk = (top != NULL && top->atoms.atomtype != NULL);
640 fprintf(stderr, "Atom types not available in topology!\n");
647 * See sel_updatefunc() for description of the parameters.
648 * \p data is not used.
650 * Returns the atom type for each atom in \p out->u.s.
651 * Segfaults if atom types are not found in the topology.
654 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
655 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
660 for (i = 0; i < g->isize; ++i)
662 out->u.s[i] = *top->atoms.atomtype[g->index[i]];
668 * See sel_updatefunc() for description of the parameters.
669 * \p data is not used.
671 * Returns the residue name for each atom in \p out->u.s.
674 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
675 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
681 for (i = 0; i < g->isize; ++i)
683 resind = top->atoms.atom[g->index[i]].resind;
684 out->u.s[i] = *top->atoms.resinfo[resind].name;
690 * See sel_updatefunc() for description of the parameters.
691 * \p data is not used.
693 * Returns the insertion code for each atom in \p out->u.s.
696 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
697 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
703 for (i = 0; i < g->isize; ++i)
705 resind = top->atoms.atom[g->index[i]].resind;
706 out->u.s[i][0] = top->atoms.resinfo[resind].ic;
712 * See sel_updatefunc() for description of the parameters.
713 * \p data is not used.
715 * Returns the chain for each atom in \p out->u.s.
718 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
719 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
725 for (i = 0; i < g->isize; ++i)
727 resind = top->atoms.atom[g->index[i]].resind;
728 out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
734 * See sel_updatefunc() for description of the parameters.
735 * \p data is not used.
737 * Returns the mass for each atom in \p out->u.r.
740 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
741 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
746 for (i = 0; i < g->isize; ++i)
748 out->u.r[i] = top->atoms.atom[g->index[i]].m;
754 * See sel_updatefunc() for description of the parameters.
755 * \p data is not used.
757 * Returns the charge for each atom in \p out->u.r.
760 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
761 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
766 for (i = 0; i < g->isize; ++i)
768 out->u.r[i] = top->atoms.atom[g->index[i]].q;
774 * \param[in] top Topology structure.
775 * \param npar Not used.
776 * \param param Not used.
777 * \param data Not used.
778 * \returns 0 if PDB info is present in the topology, -1 otherwise.
780 * If PDB info is not found, also prints an error message.
783 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
787 bOk = (top != NULL && top->atoms.pdbinfo != NULL);
790 fprintf(stderr, "PDB info not available in topology!\n");
797 * See sel_updatefunc() for description of the parameters.
798 * \p data is not used.
800 * Returns the alternate location identifier for each atom in \p out->u.s.
803 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
804 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
809 for (i = 0; i < g->isize; ++i)
811 out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
817 * See sel_updatefunc() for description of the parameters.
818 * \p data is not used.
820 * Returns the occupancy numbers for each atom in \p out->u.r.
821 * Segfaults if PDB info is not found in the topology.
824 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
825 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
830 for (i = 0; i < g->isize; ++i)
832 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
838 * See sel_updatefunc() for description of the parameters.
839 * \p data is not used.
841 * Returns the B-factors for each atom in \p out->u.r.
842 * Segfaults if PDB info is not found in the topology.
845 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
846 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
851 for (i = 0; i < g->isize; ++i)
853 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
859 * Internal utility function for position keyword evaluation.
861 * \param[in] fr Current frame.
862 * \param[in] g Index group for which the coordinates should be evaluated.
863 * \param[out] out Output array.
864 * \param[in] pos Position data to use instead of atomic coordinates
866 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
868 * This function is used internally by evaluate_x(), evaluate_y() and
869 * evaluate_z() to do the actual evaluation.
872 evaluate_coord(t_trxframe *fr, gmx_ana_index_t *g, real out[],
873 gmx_ana_pos_t *pos, int d)
880 for (b = 0; b < pos->nr; ++b)
883 for (i = pos->m.mapb.index[b]; i < pos->m.mapb.index[b+1]; ++i)
891 for (i = 0; i < g->isize; ++i)
893 out[i] = fr->x[g->index[i]][d];
899 * See sel_updatefunc_pos() for description of the parameters.
900 * \p data is not used.
902 * Returns the \p x coordinate for each atom in \p out->u.r.
905 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
906 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
908 out->nr = pos->g->isize;
909 evaluate_coord(fr, pos->g, out->u.r, pos, XX);
914 * See sel_updatefunc() for description of the parameters.
915 * \p data is not used.
917 * Returns the \p y coordinate for each atom in \p out->u.r.
920 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
921 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
923 out->nr = pos->g->isize;
924 evaluate_coord(fr, pos->g, out->u.r, pos, YY);
929 * See sel_updatefunc() for description of the parameters.
930 * \p data is not used.
932 * Returns the \p z coordinate for each atom in \p out->u.r.
935 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
936 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
938 out->nr = pos->g->isize;
939 evaluate_coord(fr, pos->g, out->u.r, pos, ZZ);