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 simple keyword selection methods.
42 #include <selmethod.h>
44 /** Evaluates the \p all selection keyword. */
46 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
47 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
48 /** Evaluates the \p none selection keyword. */
50 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
51 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
52 /** Evaluates the \p atomnr selection keyword. */
54 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
55 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
56 /** Evaluates the \p resnr selection keyword. */
58 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
59 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
60 /** Evaluates the \p resindex selection keyword. */
62 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
63 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
64 /** Checks whether molecule information is present in the topology. */
66 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
67 /** Evaluates the \p molindex selection keyword. */
69 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
70 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
71 /** Evaluates the \p atomname selection keyword. */
73 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
74 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
75 /** Evaluates the \p pdbatomname selection keyword. */
77 evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
78 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
79 /** Checks whether atom types are present in the topology. */
81 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
82 /** Evaluates the \p atomtype selection keyword. */
84 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
85 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
86 /** Evaluates the \p insertcode selection keyword. */
88 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
89 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
90 /** Evaluates the \p chain selection keyword. */
92 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
93 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
94 /** Evaluates the \p mass selection keyword. */
96 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
97 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
98 /** Evaluates the \p charge selection keyword. */
100 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
101 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
102 /** Checks whether PDB info is present in the topology. */
104 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
105 /** Evaluates the \p altloc selection keyword. */
107 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
108 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
109 /** Evaluates the \p occupancy selection keyword. */
111 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
112 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
113 /** Evaluates the \p betafactor selection keyword. */
115 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
116 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
117 /** Evaluates the \p resname selection keyword. */
119 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
120 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
122 /** Evaluates the \p x selection keyword. */
124 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
125 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
126 /** Evaluates the \p y selection keyword. */
128 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
129 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
130 /** Evaluates the \p z selection keyword. */
132 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
133 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
135 /** Help text for atom name selection keywords. */
136 static const char *help_atomname[] = {
137 "ATOM NAME SELECTION KEYWORDS[PAR]",
139 "[TT]name[tt] [TT]pdbname[tt] [TT]atomname[tt] [TT]pdbatomname[tt][PAR]",
141 "These keywords select atoms by name. [TT]name[tt] selects atoms using",
142 "the Gromacs atom naming convention.",
143 "For input formats other than PDB, the atom names are matched exactly",
144 "as they appear in the input file. For PDB files, 4 character atom names",
145 "that start with a digit are matched after moving the digit to the end",
146 "(e.g., to match 3HG2 from a PDB file, use [TT]name HG23[tt]).",
147 "[TT]pdbname[tt] can only be used with a PDB input file, and selects",
148 "atoms based on the exact name given in the input file, without the",
149 "transformation described above.[PAR]",
151 "[TT]atomname[tt] and [TT]pdbatomname[tt] are synonyms for the above two",
155 /** \internal Selection method data for \p all selection keyword. */
156 gmx_ana_selmethod_t sm_all = {
157 "all", GROUP_VALUE, 0,
169 /** \internal Selection method data for \p none selection keyword. */
170 gmx_ana_selmethod_t sm_none = {
171 "none", GROUP_VALUE, 0,
183 /** \internal Selection method data for \p atomnr selection keyword. */
184 gmx_ana_selmethod_t sm_atomnr = {
185 "atomnr", INT_VALUE, 0,
197 /** \internal Selection method data for \p resnr selection keyword. */
198 gmx_ana_selmethod_t sm_resnr = {
199 "resnr", INT_VALUE, SMETH_REQTOP,
211 /** \internal Selection method data for \p resindex selection keyword. */
212 gmx_ana_selmethod_t sm_resindex = {
213 "resindex", INT_VALUE, SMETH_REQTOP,
225 /** \internal Selection method data for \p molindex selection keyword. */
226 gmx_ana_selmethod_t sm_molindex = {
227 "molindex", INT_VALUE, SMETH_REQTOP,
239 /** \internal Selection method data for \p name selection keyword. */
240 gmx_ana_selmethod_t sm_atomname = {
241 "atomname", STR_VALUE, SMETH_REQTOP,
251 {NULL, asize(help_atomname), help_atomname}
254 /** \internal Selection method data for \p pdbatomname selection keyword. */
255 gmx_ana_selmethod_t sm_pdbatomname = {
256 "pdbatomname", STR_VALUE, SMETH_REQTOP,
264 &evaluate_pdbatomname,
266 {NULL, asize(help_atomname), help_atomname}
269 /** \internal Selection method data for \p type selection keyword. */
270 gmx_ana_selmethod_t sm_atomtype = {
271 "atomtype", STR_VALUE, SMETH_REQTOP,
283 /** \internal Selection method data for \p resname selection keyword. */
284 gmx_ana_selmethod_t sm_resname = {
285 "resname", STR_VALUE, SMETH_REQTOP,
297 /** \internal Selection method data for \p chain selection keyword. */
298 gmx_ana_selmethod_t sm_insertcode = {
299 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
307 &evaluate_insertcode,
311 /** \internal Selection method data for \p chain selection keyword. */
312 gmx_ana_selmethod_t sm_chain = {
313 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
325 /** \internal Selection method data for \p mass selection keyword. */
326 gmx_ana_selmethod_t sm_mass = {
327 "mass", REAL_VALUE, SMETH_REQTOP,
339 /** \internal Selection method data for \p charge selection keyword. */
340 gmx_ana_selmethod_t sm_charge = {
341 "charge", REAL_VALUE, SMETH_REQTOP,
353 /** \internal Selection method data for \p chain selection keyword. */
354 gmx_ana_selmethod_t sm_altloc = {
355 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
367 /** \internal Selection method data for \p occupancy selection keyword. */
368 gmx_ana_selmethod_t sm_occupancy = {
369 "occupancy", REAL_VALUE, SMETH_REQTOP,
381 /** \internal Selection method data for \p betafactor selection keyword. */
382 gmx_ana_selmethod_t sm_betafactor = {
383 "betafactor", REAL_VALUE, SMETH_REQTOP,
391 &evaluate_betafactor,
395 /** \internal Selection method data for \p x selection keyword. */
396 gmx_ana_selmethod_t sm_x = {
397 "x", REAL_VALUE, SMETH_DYNAMIC,
409 /** \internal Selection method data for \p y selection keyword. */
410 gmx_ana_selmethod_t sm_y = {
411 "y", REAL_VALUE, SMETH_DYNAMIC,
423 /** \internal Selection method data for \p z selection keyword. */
424 gmx_ana_selmethod_t sm_z = {
425 "z", REAL_VALUE, SMETH_DYNAMIC,
438 * See sel_updatefunc() for description of the parameters.
439 * \p data is not used.
441 * Copies \p g to \p out->u.g.
444 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
445 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
447 gmx_ana_index_copy(out->u.g, g, FALSE);
452 * See sel_updatefunc() for description of the parameters.
453 * \p data is not used.
455 * Returns an empty \p out->u.g.
458 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
459 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
466 * See sel_updatefunc() for description of the parameters.
467 * \p data is not used.
469 * Returns the indices for each atom in \p out->u.i.
472 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
473 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
478 for (i = 0; i < g->isize; ++i)
480 out->u.i[i] = g->index[i] + 1;
486 * See sel_updatefunc() for description of the parameters.
487 * \p data is not used.
489 * Returns the residue numbers for each atom in \p out->u.i.
492 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
493 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
499 for (i = 0; i < g->isize; ++i)
501 resind = top->atoms.atom[g->index[i]].resind;
502 out->u.i[i] = top->atoms.resinfo[resind].nr;
508 * See sel_updatefunc() for description of the parameters.
509 * \p data is not used.
511 * Returns the residue indices for each atom in \p out->u.i.
514 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
515 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
520 for (i = 0; i < g->isize; ++i)
522 out->u.i[i] = top->atoms.atom[g->index[i]].resind + 1;
528 * \param[in] top Topology structure.
529 * \param npar Not used.
530 * \param param Not used.
531 * \param data Not used.
532 * \returns 0 if molecule info is present in the topology, -1 otherwise.
534 * If molecule information is not found, also prints an error message.
537 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
541 bOk = (top != NULL && top->mols.nr > 0);
544 fprintf(stderr, "Molecule information not available in topology!\n");
551 * See sel_updatefunc() for description of the parameters.
552 * \p data is not used.
554 * Returns the molecule indices for each atom in \p out->u.i.
557 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
558 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
563 for (i = j = 0; i < g->isize; ++i)
565 while (top->mols.index[j + 1] <= g->index[i]) ++j;
572 * See sel_updatefunc() for description of the parameters.
573 * \p data is not used.
575 * Returns the atom name for each atom in \p out->u.s.
578 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
579 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
584 for (i = 0; i < g->isize; ++i)
586 out->u.s[i] = *top->atoms.atomname[g->index[i]];
592 * See sel_updatefunc() for description of the parameters.
593 * \p data is not used.
595 * Returns the PDB atom name for each atom in \p out->u.s.
598 evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
599 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
604 for (i = 0; i < g->isize; ++i)
606 char *s = top->atoms.pdbinfo[g->index[i]].atomnm;
617 * \param[in] top Topology structure.
618 * \param npar Not used.
619 * \param param Not used.
620 * \param data Not used.
621 * \returns 0 if atom types are present in the topology, -1 otherwise.
623 * If the atom types are not found, also prints an error message.
626 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
630 bOk = (top != NULL && top->atoms.atomtype != NULL);
633 fprintf(stderr, "Atom types not available in topology!\n");
640 * See sel_updatefunc() for description of the parameters.
641 * \p data is not used.
643 * Returns the atom type for each atom in \p out->u.s.
644 * Segfaults if atom types are not found in the topology.
647 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
648 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
653 for (i = 0; i < g->isize; ++i)
655 out->u.s[i] = *top->atoms.atomtype[g->index[i]];
661 * See sel_updatefunc() for description of the parameters.
662 * \p data is not used.
664 * Returns the residue name for each atom in \p out->u.s.
667 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
668 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
674 for (i = 0; i < g->isize; ++i)
676 resind = top->atoms.atom[g->index[i]].resind;
677 out->u.s[i] = *top->atoms.resinfo[resind].name;
683 * See sel_updatefunc() for description of the parameters.
684 * \p data is not used.
686 * Returns the insertion code for each atom in \p out->u.s.
689 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
690 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
696 for (i = 0; i < g->isize; ++i)
698 resind = top->atoms.atom[g->index[i]].resind;
699 out->u.s[i][0] = top->atoms.resinfo[resind].ic;
705 * See sel_updatefunc() for description of the parameters.
706 * \p data is not used.
708 * Returns the chain for each atom in \p out->u.s.
711 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
712 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
718 for (i = 0; i < g->isize; ++i)
720 resind = top->atoms.atom[g->index[i]].resind;
721 out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
727 * See sel_updatefunc() for description of the parameters.
728 * \p data is not used.
730 * Returns the mass for each atom in \p out->u.r.
733 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
734 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
739 for (i = 0; i < g->isize; ++i)
741 out->u.r[i] = top->atoms.atom[g->index[i]].m;
747 * See sel_updatefunc() for description of the parameters.
748 * \p data is not used.
750 * Returns the charge for each atom in \p out->u.r.
753 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
754 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
759 for (i = 0; i < g->isize; ++i)
761 out->u.r[i] = top->atoms.atom[g->index[i]].q;
767 * \param[in] top Topology structure.
768 * \param npar Not used.
769 * \param param Not used.
770 * \param data Not used.
771 * \returns 0 if PDB info is present in the topology, -1 otherwise.
773 * If PDB info is not found, also prints an error message.
776 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
780 bOk = (top != NULL && top->atoms.pdbinfo != NULL);
783 fprintf(stderr, "PDB info not available in topology!\n");
790 * See sel_updatefunc() for description of the parameters.
791 * \p data is not used.
793 * Returns the alternate location identifier for each atom in \p out->u.s.
796 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
797 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
802 for (i = 0; i < g->isize; ++i)
804 out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
810 * See sel_updatefunc() for description of the parameters.
811 * \p data is not used.
813 * Returns the occupancy numbers for each atom in \p out->u.r.
814 * Segfaults if PDB info is not found in the topology.
817 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
818 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
823 for (i = 0; i < g->isize; ++i)
825 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
831 * See sel_updatefunc() for description of the parameters.
832 * \p data is not used.
834 * Returns the B-factors for each atom in \p out->u.r.
835 * Segfaults if PDB info is not found in the topology.
838 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
839 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
844 for (i = 0; i < g->isize; ++i)
846 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
852 * Internal utility function for position keyword evaluation.
854 * \param[in] fr Current frame.
855 * \param[in] g Index group for which the coordinates should be evaluated.
856 * \param[out] out Output array.
857 * \param[in] pos Position data to use instead of atomic coordinates
859 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
861 * This function is used internally by evaluate_x(), evaluate_y() and
862 * evaluate_z() to do the actual evaluation.
865 evaluate_coord(t_trxframe *fr, gmx_ana_index_t *g, real out[],
866 gmx_ana_pos_t *pos, int d)
873 for (b = 0; b < pos->nr; ++b)
876 for (i = pos->m.mapb.index[b]; i < pos->m.mapb.index[b+1]; ++i)
884 for (i = 0; i < g->isize; ++i)
886 out[i] = fr->x[g->index[i]][d];
892 * See sel_updatefunc_pos() for description of the parameters.
893 * \p data is not used.
895 * Returns the \p x coordinate for each atom in \p out->u.r.
898 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
899 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
901 out->nr = pos->g->isize;
902 evaluate_coord(fr, pos->g, out->u.r, pos, XX);
907 * See sel_updatefunc() for description of the parameters.
908 * \p data is not used.
910 * Returns the \p y coordinate for each atom in \p out->u.r.
913 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
914 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
916 out->nr = pos->g->isize;
917 evaluate_coord(fr, pos->g, out->u.r, pos, YY);
922 * See sel_updatefunc() for description of the parameters.
923 * \p data is not used.
925 * Returns the \p z coordinate for each atom in \p out->u.r.
928 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
929 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
931 out->nr = pos->g->isize;
932 evaluate_coord(fr, pos->g, out->u.r, pos, ZZ);