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
33 * Implements simple keyword selection methods.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_selection
42 #include "gromacs/selection/position.h"
43 #include "gromacs/selection/selmethod.h"
44 #include "gromacs/utility/exceptions.h"
46 /** Evaluates the \p all selection keyword. */
48 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
49 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
50 /** Evaluates the \p none selection keyword. */
52 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
53 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
54 /** Evaluates the \p atomnr selection keyword. */
56 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
57 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
58 /** Evaluates the \p resnr selection keyword. */
60 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
61 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
62 /** Evaluates the \p resindex selection keyword. */
64 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
65 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
66 /** Checks whether molecule information is present in the topology. */
68 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
69 /** Evaluates the \p molindex selection keyword. */
71 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
72 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
73 /** Evaluates the \p name selection keyword. */
75 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
76 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
77 /** Checks whether atom types are present in the topology. */
79 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
80 /** Evaluates the \p type selection keyword. */
82 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
83 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
84 /** Evaluates the \p insertcode selection keyword. */
86 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
87 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
88 /** Evaluates the \p chain selection keyword. */
90 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
91 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
92 /** Evaluates the \p mass selection keyword. */
94 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
95 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
96 /** Evaluates the \p charge selection keyword. */
98 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
99 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
100 /** Checks whether PDB info is present in the topology. */
102 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
103 /** Evaluates the \p altloc selection keyword. */
105 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
106 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
107 /** Evaluates the \p occupancy selection keyword. */
109 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
110 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
111 /** Evaluates the \p betafactor selection keyword. */
113 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
114 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
115 /** Evaluates the \p resname selection keyword. */
117 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
118 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
120 /** Evaluates the \p x selection keyword. */
122 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
123 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
124 /** Evaluates the \p y selection keyword. */
126 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
127 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
128 /** Evaluates the \p z selection keyword. */
130 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
131 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
133 /** \internal Selection method data for \p all selection keyword. */
134 gmx_ana_selmethod_t sm_all = {
135 "all", GROUP_VALUE, 0,
147 /** \internal Selection method data for \p none selection keyword. */
148 gmx_ana_selmethod_t sm_none = {
149 "none", GROUP_VALUE, 0,
161 /** \internal Selection method data for \p atomnr selection keyword. */
162 gmx_ana_selmethod_t sm_atomnr = {
163 "atomnr", INT_VALUE, 0,
175 /** \internal Selection method data for \p resnr selection keyword. */
176 gmx_ana_selmethod_t sm_resnr = {
177 "resnr", INT_VALUE, SMETH_REQTOP,
189 /** \internal Selection method data for \p resindex selection keyword. */
190 gmx_ana_selmethod_t sm_resindex = {
191 "resindex", INT_VALUE, SMETH_REQTOP,
203 /** \internal Selection method data for \p molindex selection keyword. */
204 gmx_ana_selmethod_t sm_molindex = {
205 "molindex", INT_VALUE, SMETH_REQTOP,
217 /** \internal Selection method data for \p name selection keyword. */
218 gmx_ana_selmethod_t sm_atomname = {
219 "name", STR_VALUE, SMETH_REQTOP,
231 /** \internal Selection method data for \p type selection keyword. */
232 gmx_ana_selmethod_t sm_atomtype = {
233 "type", STR_VALUE, SMETH_REQTOP,
245 /** \internal Selection method data for \p resname selection keyword. */
246 gmx_ana_selmethod_t sm_resname = {
247 "resname", STR_VALUE, SMETH_REQTOP,
259 /** \internal Selection method data for \p chain selection keyword. */
260 gmx_ana_selmethod_t sm_insertcode = {
261 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
269 &evaluate_insertcode,
273 /** \internal Selection method data for \p chain selection keyword. */
274 gmx_ana_selmethod_t sm_chain = {
275 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
287 /** \internal Selection method data for \p mass selection keyword. */
288 gmx_ana_selmethod_t sm_mass = {
289 "mass", REAL_VALUE, SMETH_REQTOP,
301 /** \internal Selection method data for \p charge selection keyword. */
302 gmx_ana_selmethod_t sm_charge = {
303 "charge", REAL_VALUE, SMETH_REQTOP,
315 /** \internal Selection method data for \p chain selection keyword. */
316 gmx_ana_selmethod_t sm_altloc = {
317 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
329 /** \internal Selection method data for \p occupancy selection keyword. */
330 gmx_ana_selmethod_t sm_occupancy = {
331 "occupancy", REAL_VALUE, SMETH_REQTOP,
343 /** \internal Selection method data for \p betafactor selection keyword. */
344 gmx_ana_selmethod_t sm_betafactor = {
345 "betafactor", REAL_VALUE, SMETH_REQTOP,
353 &evaluate_betafactor,
357 /** \internal Selection method data for \p x selection keyword. */
358 gmx_ana_selmethod_t sm_x = {
359 "x", REAL_VALUE, SMETH_DYNAMIC,
371 /** \internal Selection method data for \p y selection keyword. */
372 gmx_ana_selmethod_t sm_y = {
373 "y", REAL_VALUE, SMETH_DYNAMIC,
385 /** \internal Selection method data for \p z selection keyword. */
386 gmx_ana_selmethod_t sm_z = {
387 "z", REAL_VALUE, SMETH_DYNAMIC,
400 * See sel_updatefunc() for description of the parameters.
401 * \p data is not used.
403 * Copies \p g to \p out->u.g.
406 evaluate_all(t_topology *top, t_trxframe *fr, t_pbc *pbc,
407 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
409 gmx_ana_index_copy(out->u.g, g, false);
413 * See sel_updatefunc() for description of the parameters.
414 * \p data is not used.
416 * Returns an empty \p out->u.g.
419 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
420 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
426 * See sel_updatefunc() for description of the parameters.
427 * \p data is not used.
429 * Returns the indices for each atom in \p out->u.i.
432 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
433 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
438 for (i = 0; i < g->isize; ++i)
440 out->u.i[i] = g->index[i] + 1;
445 * See sel_updatefunc() for description of the parameters.
446 * \p data is not used.
448 * Returns the residue numbers for each atom in \p out->u.i.
451 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
452 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
458 for (i = 0; i < g->isize; ++i)
460 resind = top->atoms.atom[g->index[i]].resind;
461 out->u.i[i] = top->atoms.resinfo[resind].nr;
466 * See sel_updatefunc() for description of the parameters.
467 * \p data is not used.
469 * Returns the residue indices for each atom in \p out->u.i.
472 evaluate_resindex(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] = top->atoms.atom[g->index[i]].resind + 1;
485 * \param[in] top Topology structure.
486 * \param npar Not used.
487 * \param param Not used.
488 * \param data Not used.
489 * \returns 0 if molecule info is present in the topology, -1 otherwise.
491 * If molecule information is not found, also prints an error message.
494 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
498 bOk = (top != NULL && top->mols.nr > 0);
501 GMX_THROW(gmx::InconsistentInputError("Molecule information not available in topology"));
506 * See sel_updatefunc() for description of the parameters.
507 * \p data is not used.
509 * Returns the molecule indices for each atom in \p out->u.i.
512 evaluate_molindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
513 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
518 for (i = j = 0; i < g->isize; ++i)
520 while (top->mols.index[j + 1] <= g->index[i]) ++j;
526 * See sel_updatefunc() for description of the parameters.
527 * \p data is not used.
529 * Returns the atom name for each atom in \p out->u.s.
532 evaluate_atomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
533 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
538 for (i = 0; i < g->isize; ++i)
540 out->u.s[i] = *top->atoms.atomname[g->index[i]];
545 * \param[in] top Topology structure.
546 * \param npar Not used.
547 * \param param Not used.
548 * \param data Not used.
549 * \returns 0 if atom types are present in the topology, -1 otherwise.
551 * If the atom types are not found, also prints an error message.
554 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
558 bOk = (top != NULL && top->atoms.atomtype != NULL);
561 GMX_THROW(gmx::InconsistentInputError("Atom types not available in topology"));
566 * See sel_updatefunc() for description of the parameters.
567 * \p data is not used.
569 * Returns the atom type for each atom in \p out->u.s.
570 * Segfaults if atom types are not found in the topology.
573 evaluate_atomtype(t_topology *top, t_trxframe *fr, t_pbc *pbc,
574 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
579 for (i = 0; i < g->isize; ++i)
581 out->u.s[i] = *top->atoms.atomtype[g->index[i]];
586 * See sel_updatefunc() for description of the parameters.
587 * \p data is not used.
589 * Returns the residue name for each atom in \p out->u.s.
592 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
593 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
599 for (i = 0; i < g->isize; ++i)
601 resind = top->atoms.atom[g->index[i]].resind;
602 out->u.s[i] = *top->atoms.resinfo[resind].name;
607 * See sel_updatefunc() for description of the parameters.
608 * \p data is not used.
610 * Returns the insertion code for each atom in \p out->u.s.
613 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
614 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
620 for (i = 0; i < g->isize; ++i)
622 resind = top->atoms.atom[g->index[i]].resind;
623 out->u.s[i][0] = top->atoms.resinfo[resind].ic;
628 * See sel_updatefunc() for description of the parameters.
629 * \p data is not used.
631 * Returns the chain for each atom in \p out->u.s.
634 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
635 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
641 for (i = 0; i < g->isize; ++i)
643 resind = top->atoms.atom[g->index[i]].resind;
644 out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
649 * See sel_updatefunc() for description of the parameters.
650 * \p data is not used.
652 * Returns the mass for each atom in \p out->u.r.
655 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
656 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
661 for (i = 0; i < g->isize; ++i)
663 out->u.r[i] = top->atoms.atom[g->index[i]].m;
668 * See sel_updatefunc() for description of the parameters.
669 * \p data is not used.
671 * Returns the charge for each atom in \p out->u.r.
674 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
675 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
680 for (i = 0; i < g->isize; ++i)
682 out->u.r[i] = top->atoms.atom[g->index[i]].q;
687 * \param[in] top Topology structure.
688 * \param npar Not used.
689 * \param param Not used.
690 * \param data Not used.
691 * \returns 0 if PDB info is present in the topology, -1 otherwise.
693 * If PDB info is not found, also prints an error message.
696 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data)
700 bOk = (top != NULL && top->atoms.pdbinfo != NULL);
703 GMX_THROW(gmx::InconsistentInputError("PDB info not available in topology"));
708 * See sel_updatefunc() for description of the parameters.
709 * \p data is not used.
711 * Returns the alternate location identifier for each atom in \p out->u.s.
714 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
715 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
720 for (i = 0; i < g->isize; ++i)
722 out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
727 * See sel_updatefunc() for description of the parameters.
728 * \p data is not used.
730 * Returns the occupancy numbers for each atom in \p out->u.r.
731 * Segfaults if PDB info is not found in the topology.
734 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
735 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
740 for (i = 0; i < g->isize; ++i)
742 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
747 * See sel_updatefunc() for description of the parameters.
748 * \p data is not used.
750 * Returns the B-factors for each atom in \p out->u.r.
751 * Segfaults if PDB info is not found in the topology.
754 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
755 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data)
760 for (i = 0; i < g->isize; ++i)
762 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
767 * Internal utility function for position keyword evaluation.
769 * \param[in] fr Current frame.
770 * \param[in] g Index group for which the coordinates should be evaluated.
771 * \param[out] out Output array.
772 * \param[in] pos Position data to use instead of atomic coordinates
774 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
776 * This function is used internally by evaluate_x(), evaluate_y() and
777 * evaluate_z() to do the actual evaluation.
780 evaluate_coord(t_trxframe *fr, gmx_ana_index_t *g, real out[],
781 gmx_ana_pos_t *pos, int d)
788 for (b = 0; b < pos->nr; ++b)
791 for (i = pos->m.mapb.index[b]; i < pos->m.mapb.index[b+1]; ++i)
799 for (i = 0; i < g->isize; ++i)
801 out[i] = fr->x[g->index[i]][d];
807 * See sel_updatefunc_pos() for description of the parameters.
808 * \p data is not used.
810 * Returns the \p x coordinate for each atom in \p out->u.r.
813 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
814 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
816 out->nr = pos->g->isize;
817 evaluate_coord(fr, pos->g, out->u.r, pos, XX);
821 * See sel_updatefunc() for description of the parameters.
822 * \p data is not used.
824 * Returns the \p y coordinate for each atom in \p out->u.r.
827 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
828 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
830 out->nr = pos->g->isize;
831 evaluate_coord(fr, pos->g, out->u.r, pos, YY);
835 * See sel_updatefunc() for description of the parameters.
836 * \p data is not used.
838 * Returns the \p z coordinate for each atom in \p out->u.r.
841 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
842 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data)
844 out->nr = pos->g->isize;
845 evaluate_coord(fr, pos->g, out->u.r, pos, ZZ);