Use gmx_mtop_t in selections, part 3
[gromacs.git] / src / gromacs / selection / sm_simple.cpp
blob4af50ee16347c9c3f1f3bde89f02d89b9c784ac7
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \internal \file
36 * \brief
37 * Implements simple keyword selection methods.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_selection
42 #include "gmxpre.h"
44 #include <cctype>
46 #include "gromacs/selection/position.h"
47 #include "gromacs/topology/mtop_lookup.h"
48 #include "gromacs/topology/topology.h"
49 #include "gromacs/utility/arraysize.h"
50 #include "gromacs/utility/exceptions.h"
51 #include "gromacs/utility/gmxassert.h"
53 #include "selmethod.h"
55 /** Evaluates the \p all selection keyword. */
56 static void
57 evaluate_all(const gmx::SelMethodEvalContext &context,
58 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
59 /** Evaluates the \p none selection keyword. */
60 static void
61 evaluate_none(const gmx::SelMethodEvalContext &context,
62 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
63 /** Evaluates the \p atomnr selection keyword. */
64 static void
65 evaluate_atomnr(const gmx::SelMethodEvalContext &context,
66 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
67 /** Evaluates the \p resnr selection keyword. */
68 static void
69 evaluate_resnr(const gmx::SelMethodEvalContext &context,
70 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
71 /** Evaluates the \p resindex selection keyword. */
72 static void
73 evaluate_resindex(const gmx::SelMethodEvalContext &context,
74 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
75 /*! \brief
76 * Checks whether molecule information is present in the topology.
78 * \param[in] top Topology structure.
79 * \param npar Not used.
80 * \param param Not used.
81 * \param data Not used.
82 * \returns 0 if molecule info is present in the topology, -1 otherwise.
84 * If molecule information is not found, also prints an error message.
86 static void
87 check_molecules(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
88 /** Evaluates the \p molindex selection keyword. */
89 static void
90 evaluate_molindex(const gmx::SelMethodEvalContext &context,
91 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
92 /** Evaluates the \p atomname selection keyword. */
93 static void
94 evaluate_atomname(const gmx::SelMethodEvalContext &context,
95 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
96 /** Evaluates the \p pdbatomname selection keyword. */
97 static void
98 evaluate_pdbatomname(const gmx::SelMethodEvalContext &context,
99 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
100 /*! \brief
101 * Checks whether atom types are present in the topology.
103 * \param[in] top Topology structure.
104 * \param npar Not used.
105 * \param param Not used.
106 * \param data Not used.
108 static void
109 check_atomtype(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
110 /** Evaluates the \p atomtype selection keyword. */
111 static void
112 evaluate_atomtype(const gmx::SelMethodEvalContext &context,
113 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
114 /** Evaluates the \p insertcode selection keyword. */
115 static void
116 evaluate_insertcode(const gmx::SelMethodEvalContext &context,
117 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
118 /** Evaluates the \p chain selection keyword. */
119 static void
120 evaluate_chain(const gmx::SelMethodEvalContext &context,
121 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
122 /** Evaluates the \p mass selection keyword. */
123 static void
124 evaluate_mass(const gmx::SelMethodEvalContext &context,
125 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
126 /*! \brief
127 * Checks whether charges are present in the topology.
129 * \param[in] top Topology structure.
130 * \param npar Not used.
131 * \param param Not used.
132 * \param data Not used.
134 static void
135 check_charge(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
136 /** Evaluates the \p charge selection keyword. */
137 static void
138 evaluate_charge(const gmx::SelMethodEvalContext &context,
139 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
140 /*! \brief
141 * Checks whether PDB info is present in the topology.
143 * \param[in] top Topology structure.
144 * \param npar Not used.
145 * \param param Not used.
146 * \param data Not used.
147 * \returns 0 if PDB info is present in the topology, -1 otherwise.
149 * If PDB info is not found, also prints an error message.
151 static void
152 check_pdbinfo(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data);
153 /** Evaluates the \p altloc selection keyword. */
154 static void
155 evaluate_altloc(const gmx::SelMethodEvalContext &context,
156 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
157 /** Evaluates the \p occupancy selection keyword. */
158 static void
159 evaluate_occupancy(const gmx::SelMethodEvalContext &context,
160 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
161 /** Evaluates the \p betafactor selection keyword. */
162 static void
163 evaluate_betafactor(const gmx::SelMethodEvalContext &context,
164 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
165 /** Evaluates the \p resname selection keyword. */
166 static void
167 evaluate_resname(const gmx::SelMethodEvalContext &context,
168 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
170 /** Evaluates the \p x selection keyword. */
171 static void
172 evaluate_x(const gmx::SelMethodEvalContext &context,
173 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
174 /** Evaluates the \p y selection keyword. */
175 static void
176 evaluate_y(const gmx::SelMethodEvalContext &context,
177 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
178 /** Evaluates the \p z selection keyword. */
179 static void
180 evaluate_z(const gmx::SelMethodEvalContext &context,
181 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
183 //! Help title for atom name selection keywords.
184 static const char helptitle_atomname[] = "Selecting atoms by name";
185 //! Help text for atom name selection keywords.
186 static const char *const help_atomname[] = {
187 "::",
189 " name",
190 " pdbname",
191 " atomname",
192 " pdbatomname",
194 "These keywords select atoms by name. [TT]name[tt] selects atoms using",
195 "the GROMACS atom naming convention.",
196 "For input formats other than PDB, the atom names are matched exactly",
197 "as they appear in the input file. For PDB files, 4 character atom names",
198 "that start with a digit are matched after moving the digit to the end",
199 "(e.g., to match 3HG2 from a PDB file, use [TT]name HG23[tt]).",
200 "[TT]pdbname[tt] can only be used with a PDB input file, and selects",
201 "atoms based on the exact name given in the input file, without the",
202 "transformation described above.[PAR]",
204 "[TT]atomname[tt] and [TT]pdbatomname[tt] are synonyms for the above two",
205 "keywords."
208 /** Selection method data for \p all selection keyword. */
209 gmx_ana_selmethod_t sm_all = {
210 "all", GROUP_VALUE, 0,
211 0, NULL,
212 NULL,
213 NULL,
214 NULL,
215 NULL,
216 NULL,
217 NULL,
218 &evaluate_all,
219 NULL,
222 /** Selection method data for \p none selection keyword. */
223 gmx_ana_selmethod_t sm_none = {
224 "none", GROUP_VALUE, 0,
225 0, NULL,
226 NULL,
227 NULL,
228 NULL,
229 NULL,
230 NULL,
231 NULL,
232 &evaluate_none,
233 NULL,
236 /** Selection method data for \p atomnr selection keyword. */
237 gmx_ana_selmethod_t sm_atomnr = {
238 "atomnr", INT_VALUE, 0,
239 0, NULL,
240 NULL,
241 NULL,
242 NULL,
243 NULL,
244 NULL,
245 NULL,
246 &evaluate_atomnr,
247 NULL,
250 /** Selection method data for \p resnr selection keyword. */
251 gmx_ana_selmethod_t sm_resnr = {
252 "resnr", INT_VALUE, SMETH_REQTOP,
253 0, NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 NULL,
259 NULL,
260 &evaluate_resnr,
261 NULL,
264 /** Selection method data for \p resindex selection keyword. */
265 gmx_ana_selmethod_t sm_resindex = {
266 "resindex", INT_VALUE, SMETH_REQTOP,
267 0, NULL,
268 NULL,
269 NULL,
270 NULL,
271 NULL,
272 NULL,
273 NULL,
274 &evaluate_resindex,
275 NULL,
278 /** Selection method data for \p molindex selection keyword. */
279 gmx_ana_selmethod_t sm_molindex = {
280 "molindex", INT_VALUE, SMETH_REQTOP,
281 0, NULL,
282 NULL,
283 NULL,
284 &check_molecules,
285 NULL,
286 NULL,
287 NULL,
288 &evaluate_molindex,
289 NULL,
292 /** Selection method data for \p atomname selection keyword. */
293 gmx_ana_selmethod_t sm_atomname = {
294 "atomname", STR_VALUE, SMETH_REQTOP,
295 0, NULL,
296 NULL,
297 NULL,
298 NULL,
299 NULL,
300 NULL,
301 NULL,
302 &evaluate_atomname,
303 NULL,
304 {NULL, helptitle_atomname, asize(help_atomname), help_atomname}
307 /** Selection method data for \p pdbatomname selection keyword. */
308 gmx_ana_selmethod_t sm_pdbatomname = {
309 "pdbatomname", STR_VALUE, SMETH_REQTOP,
310 0, NULL,
311 NULL,
312 NULL,
313 &check_pdbinfo,
314 NULL,
315 NULL,
316 NULL,
317 &evaluate_pdbatomname,
318 NULL,
319 {NULL, helptitle_atomname, asize(help_atomname), help_atomname}
322 /** Selection method data for \p atomtype selection keyword. */
323 gmx_ana_selmethod_t sm_atomtype = {
324 "atomtype", STR_VALUE, SMETH_REQTOP,
325 0, NULL,
326 NULL,
327 NULL,
328 &check_atomtype,
329 NULL,
330 NULL,
331 NULL,
332 &evaluate_atomtype,
333 NULL,
336 /** Selection method data for \p resname selection keyword. */
337 gmx_ana_selmethod_t sm_resname = {
338 "resname", STR_VALUE, SMETH_REQTOP,
339 0, NULL,
340 NULL,
341 NULL,
342 NULL,
343 NULL,
344 NULL,
345 NULL,
346 &evaluate_resname,
347 NULL,
350 /** Selection method data for \p chain selection keyword. */
351 gmx_ana_selmethod_t sm_insertcode = {
352 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
353 0, NULL,
354 NULL,
355 NULL,
356 NULL,
357 NULL,
358 NULL,
359 NULL,
360 &evaluate_insertcode,
361 NULL,
364 /** Selection method data for \p chain selection keyword. */
365 gmx_ana_selmethod_t sm_chain = {
366 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
367 0, NULL,
368 NULL,
369 NULL,
370 NULL,
371 NULL,
372 NULL,
373 NULL,
374 &evaluate_chain,
375 NULL,
378 /** Selection method data for \p mass selection keyword. */
379 gmx_ana_selmethod_t sm_mass = {
380 "mass", REAL_VALUE, SMETH_REQMASS,
381 0, NULL,
382 NULL,
383 NULL,
384 NULL,
385 NULL,
386 NULL,
387 NULL,
388 &evaluate_mass,
389 NULL,
392 /** Selection method data for \p charge selection keyword. */
393 gmx_ana_selmethod_t sm_charge = {
394 "charge", REAL_VALUE, SMETH_REQTOP,
395 0, NULL,
396 NULL,
397 NULL,
398 &check_charge,
399 NULL,
400 NULL,
401 NULL,
402 &evaluate_charge,
403 NULL,
406 /** Selection method data for \p chain selection keyword. */
407 gmx_ana_selmethod_t sm_altloc = {
408 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
409 0, NULL,
410 NULL,
411 NULL,
412 &check_pdbinfo,
413 NULL,
414 NULL,
415 NULL,
416 &evaluate_altloc,
417 NULL,
420 /** Selection method data for \p occupancy selection keyword. */
421 gmx_ana_selmethod_t sm_occupancy = {
422 "occupancy", REAL_VALUE, SMETH_REQTOP,
423 0, NULL,
424 NULL,
425 NULL,
426 &check_pdbinfo,
427 NULL,
428 NULL,
429 NULL,
430 &evaluate_occupancy,
431 NULL,
434 /** Selection method data for \p betafactor selection keyword. */
435 gmx_ana_selmethod_t sm_betafactor = {
436 "betafactor", REAL_VALUE, SMETH_REQTOP,
437 0, NULL,
438 NULL,
439 NULL,
440 &check_pdbinfo,
441 NULL,
442 NULL,
443 NULL,
444 &evaluate_betafactor,
445 NULL,
448 /** Selection method data for \p x selection keyword. */
449 gmx_ana_selmethod_t sm_x = {
450 "x", REAL_VALUE, SMETH_DYNAMIC,
451 0, NULL,
452 NULL,
453 NULL,
454 NULL,
455 NULL,
456 NULL,
457 NULL,
458 NULL,
459 &evaluate_x,
462 /** Selection method data for \p y selection keyword. */
463 gmx_ana_selmethod_t sm_y = {
464 "y", REAL_VALUE, SMETH_DYNAMIC,
465 0, NULL,
466 NULL,
467 NULL,
468 NULL,
469 NULL,
470 NULL,
471 NULL,
472 NULL,
473 &evaluate_y,
476 /** Selection method data for \p z selection keyword. */
477 gmx_ana_selmethod_t sm_z = {
478 "z", REAL_VALUE, SMETH_DYNAMIC,
479 0, NULL,
480 NULL,
481 NULL,
482 NULL,
483 NULL,
484 NULL,
485 NULL,
486 NULL,
487 &evaluate_z,
491 * See sel_updatefunc() for description of the parameters.
492 * \p data is not used.
494 * Copies \p g to \p out->u.g.
496 static void
497 evaluate_all(const gmx::SelMethodEvalContext & /*context*/,
498 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
500 gmx_ana_index_copy(out->u.g, g, false);
504 * See sel_updatefunc() for description of the parameters.
505 * \p data is not used.
507 * Returns an empty \p out->u.g.
509 static void
510 evaluate_none(const gmx::SelMethodEvalContext & /*context*/,
511 gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void * /* data */)
513 out->u.g->isize = 0;
517 * See sel_updatefunc() for description of the parameters.
518 * \p data is not used.
520 * Returns the indices for each atom in \p out->u.i.
522 static void
523 evaluate_atomnr(const gmx::SelMethodEvalContext & /*context*/,
524 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
526 int i;
528 out->nr = g->isize;
529 for (i = 0; i < g->isize; ++i)
531 out->u.i[i] = g->index[i] + 1;
536 * See sel_updatefunc() for description of the parameters.
537 * \p data is not used.
539 * Returns the residue numbers for each atom in \p out->u.i.
541 static void
542 evaluate_resnr(const gmx::SelMethodEvalContext &context,
543 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
545 out->nr = g->isize;
546 int molb = 0;
547 for (int i = 0; i < g->isize; ++i)
549 mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
550 nullptr, &out->u.i[i], nullptr, nullptr);
555 * See sel_updatefunc() for description of the parameters.
556 * \p data is not used.
558 * Returns the residue indices for each atom in \p out->u.i.
560 static void
561 evaluate_resindex(const gmx::SelMethodEvalContext &context,
562 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
564 out->nr = g->isize;
565 int molb = 0;
566 for (int i = 0; i < g->isize; ++i)
568 int resind;
569 mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
570 nullptr, nullptr, nullptr, &resind);
571 out->u.i[i] = resind + 1;
575 static void
576 check_molecules(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
578 bool bOk;
580 bOk = (top != NULL && top->mols.nr > 0);
581 if (!bOk)
583 GMX_THROW(gmx::InconsistentInputError("Molecule information not available in topology"));
588 * See sel_updatefunc() for description of the parameters.
589 * \p data is not used.
591 * Returns the molecule indices for each atom in \p out->u.i.
593 static void
594 evaluate_molindex(const gmx::SelMethodEvalContext &context,
595 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
597 int i, j;
599 out->nr = g->isize;
600 for (i = j = 0; i < g->isize; ++i)
602 while (context.top->mols.index[j + 1] <= g->index[i])
604 ++j;
606 out->u.i[i] = j + 1;
611 * See sel_updatefunc() for description of the parameters.
612 * \p data is not used.
614 * Returns the atom name for each atom in \p out->u.s.
616 static void
617 evaluate_atomname(const gmx::SelMethodEvalContext &context,
618 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
620 out->nr = g->isize;
621 int molb = 0;
622 for (int i = 0; i < g->isize; ++i)
624 const char *atom_name;
625 mtopGetAtomAndResidueName(context.top, g->index[i], &molb,
626 &atom_name, nullptr, nullptr, nullptr);
627 out->u.s[i] = const_cast<char *>(atom_name);
632 * See sel_updatefunc() for description of the parameters.
633 * \p data is not used.
635 * Returns the PDB atom name for each atom in \p out->u.s.
637 static void
638 evaluate_pdbatomname(const gmx::SelMethodEvalContext &context,
639 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
641 out->nr = g->isize;
642 int molb = 0;
643 for (int i = 0; i < g->isize; ++i)
645 const char *s = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).atomnm;
646 while (std::isspace(*s))
648 ++s;
650 out->u.s[i] = const_cast<char *>(s);
654 static void
655 check_atomtype(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
657 if (!gmx_mtop_has_atomtypes(top))
659 GMX_THROW(gmx::InconsistentInputError("Atom types not available in topology"));
664 * See sel_updatefunc() for description of the parameters.
665 * \p data is not used.
667 * Returns the atom type for each atom in \p out->u.s.
668 * Segfaults if atom types are not found in the topology.
670 static void
671 evaluate_atomtype(const gmx::SelMethodEvalContext &context,
672 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
674 out->nr = g->isize;
675 int molb = 0;
676 for (int i = 0; i < g->isize; ++i)
678 int atomIndexInMolecule;
679 mtopGetMolblockIndex(context.top, g->index[i], &molb,
680 nullptr, &atomIndexInMolecule);
681 const gmx_moltype_t &moltype = context.top->moltype[context.top->molblock[molb].type];
682 out->u.s[i] = *moltype.atoms.atomtype[atomIndexInMolecule];
687 * See sel_updatefunc() for description of the parameters.
688 * \p data is not used.
690 * Returns the residue name for each atom in \p out->u.s.
692 static void
693 evaluate_resname(const gmx::SelMethodEvalContext &context,
694 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
696 out->nr = g->isize;
697 int molb = 0;
698 for (int i = 0; i < g->isize; ++i)
700 out->u.s[i] = *mtopGetResidueInfo(context.top, g->index[i], &molb).name;
705 * See sel_updatefunc() for description of the parameters.
706 * \p data is not used.
708 * Returns the insertion code for each atom in \p out->u.s.
710 static void
711 evaluate_insertcode(const gmx::SelMethodEvalContext &context,
712 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
714 out->nr = g->isize;
715 int molb = 0;
716 for (int i = 0; i < g->isize; ++i)
718 out->u.s[i][0] = mtopGetResidueInfo(context.top, g->index[i], &molb).ic;
723 * See sel_updatefunc() for description of the parameters.
724 * \p data is not used.
726 * Returns the chain for each atom in \p out->u.s.
728 static void
729 evaluate_chain(const gmx::SelMethodEvalContext &context,
730 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
732 out->nr = g->isize;
733 int molb = 0;
734 for (int i = 0; i < g->isize; ++i)
736 out->u.s[i][0] = mtopGetResidueInfo(context.top, g->index[i], &molb).chainid;
741 * See sel_updatefunc() for description of the parameters.
742 * \p data is not used.
744 * Returns the mass for each atom in \p out->u.r.
746 static void
747 evaluate_mass(const gmx::SelMethodEvalContext &context,
748 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
750 GMX_RELEASE_ASSERT(gmx_mtop_has_masses(context.top),
751 "Masses not available for evaluation");
752 out->nr = g->isize;
753 int molb = 0;
754 for (int i = 0; i < g->isize; ++i)
756 out->u.r[i] = mtopGetAtomMass(context.top, g->index[i], &molb);
761 static void
762 check_charge(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
764 if (!gmx_mtop_has_charges(top))
766 GMX_THROW(gmx::InconsistentInputError("Charges not available in topology"));
771 * See sel_updatefunc() for description of the parameters.
772 * \p data is not used.
774 * Returns the charge for each atom in \p out->u.r.
776 static void
777 evaluate_charge(const gmx::SelMethodEvalContext &context,
778 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
780 out->nr = g->isize;
781 int molb = 0;
782 for (int i = 0; i < g->isize; ++i)
784 out->u.r[i] = mtopGetAtomParameters(context.top, g->index[i], &molb).q;
788 static void
789 check_pdbinfo(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
791 if (!gmx_mtop_has_pdbinfo(top))
793 GMX_THROW(gmx::InconsistentInputError("PDB info not available in topology"));
798 * See sel_updatefunc() for description of the parameters.
799 * \p data is not used.
801 * Returns the alternate location identifier for each atom in \p out->u.s.
803 static void
804 evaluate_altloc(const gmx::SelMethodEvalContext &context,
805 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
807 out->nr = g->isize;
808 int molb = 0;
809 for (int i = 0; i < g->isize; ++i)
811 out->u.s[i][0] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).altloc;
816 * See sel_updatefunc() for description of the parameters.
817 * \p data is not used.
819 * Returns the occupancy numbers for each atom in \p out->u.r.
820 * Segfaults if PDB info is not found in the topology.
822 static void
823 evaluate_occupancy(const gmx::SelMethodEvalContext &context,
824 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
826 out->nr = g->isize;
827 int molb = 0;
828 for (int i = 0; i < g->isize; ++i)
830 out->u.r[i] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).occup;
835 * See sel_updatefunc() for description of the parameters.
836 * \p data is not used.
838 * Returns the B-factors for each atom in \p out->u.r.
839 * Segfaults if PDB info is not found in the topology.
841 static void
842 evaluate_betafactor(const gmx::SelMethodEvalContext &context,
843 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
845 out->nr = g->isize;
846 int molb = 0;
847 for (int i = 0; i < g->isize; ++i)
849 out->u.r[i] = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).bfac;
853 /*! \brief
854 * Internal utility function for position keyword evaluation.
856 * \param[out] out Output array.
857 * \param[in] pos Position data to use instead of atomic coordinates.
858 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
860 * This function is used internally by evaluate_x(), evaluate_y() and
861 * evaluate_z() to do the actual evaluation.
863 static void
864 evaluate_coord(real out[], gmx_ana_pos_t *pos, int d)
866 for (int i = 0; i < pos->count(); ++i)
868 out[i] = pos->x[i][d];
870 // TODO: Make this more efficient by directly extracting the coordinates
871 // from the frame coordinates for atomic positions instead of going through
872 // a position calculation.
876 * See sel_updatefunc_pos() for description of the parameters.
877 * \p data is not used.
879 * Returns the \p x coordinate for each position in \p out->u.r.
881 static void
882 evaluate_x(const gmx::SelMethodEvalContext & /*context*/,
883 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
885 out->nr = pos->count();
886 evaluate_coord(out->u.r, pos, XX);
890 * See sel_updatefunc() for description of the parameters.
891 * \p data is not used.
893 * Returns the \p y coordinate for each position in \p out->u.r.
895 static void
896 evaluate_y(const gmx::SelMethodEvalContext & /*context*/,
897 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
899 out->nr = pos->count();
900 evaluate_coord(out->u.r, pos, YY);
904 * See sel_updatefunc() for description of the parameters.
905 * \p data is not used.
907 * Returns the \p z coordinate for each position in \p out->u.r.
909 static void
910 evaluate_z(const gmx::SelMethodEvalContext & /*context*/,
911 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
913 out->nr = pos->count();
914 evaluate_coord(out->u.r, pos, ZZ);