Add readConfAndTopology
[gromacs.git] / src / gromacs / selection / sm_simple.cpp
blob53dbe0f69cf09c52daf5834fba7ba4993284da17
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/topology.h"
48 #include "gromacs/utility/arraysize.h"
49 #include "gromacs/utility/exceptions.h"
51 #include "selmethod.h"
53 /** Evaluates the \p all selection keyword. */
54 static void
55 evaluate_all(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 none selection keyword. */
58 static void
59 evaluate_none(t_topology *top, t_trxframe *fr, t_pbc *pbc,
60 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
61 /** Evaluates the \p atomnr selection keyword. */
62 static void
63 evaluate_atomnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
64 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
65 /** Evaluates the \p resnr selection keyword. */
66 static void
67 evaluate_resnr(t_topology *top, t_trxframe *fr, t_pbc *pbc,
68 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
69 /** Evaluates the \p resindex selection keyword. */
70 static void
71 evaluate_resindex(t_topology *top, t_trxframe *fr, t_pbc *pbc,
72 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
73 /*! \brief
74 * Checks whether molecule information is present in the topology.
76 * \param[in] top Topology structure.
77 * \param npar Not used.
78 * \param param Not used.
79 * \param data Not used.
80 * \returns 0 if molecule info is present in the topology, -1 otherwise.
82 * If molecule information is not found, also prints an error message.
84 static void
85 check_molecules(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
86 /** Evaluates the \p molindex selection keyword. */
87 static void
88 evaluate_molindex(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 atomname selection keyword. */
91 static void
92 evaluate_atomname(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 pdbatomname selection keyword. */
95 static void
96 evaluate_pdbatomname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
97 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
98 /*! \brief
99 * Checks whether atom types are present in the topology.
101 * \param[in] top Topology structure.
102 * \param npar Not used.
103 * \param param Not used.
104 * \param data Not used.
105 * \returns 0 if atom types are present in the topology, -1 otherwise.
107 * If the atom types are not found, also prints an error message.
109 static void
110 check_atomtype(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
111 /** Evaluates the \p atomtype selection keyword. */
112 static void
113 evaluate_atomtype(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 insertcode selection keyword. */
116 static void
117 evaluate_insertcode(t_topology *top, t_trxframe *fr, t_pbc *pbc,
118 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
119 /** Evaluates the \p chain selection keyword. */
120 static void
121 evaluate_chain(t_topology *top, t_trxframe *fr, t_pbc *pbc,
122 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
123 /** Evaluates the \p mass selection keyword. */
124 static void
125 evaluate_mass(t_topology *top, t_trxframe *fr, t_pbc *pbc,
126 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
127 /** Evaluates the \p charge selection keyword. */
128 static void
129 evaluate_charge(t_topology *top, t_trxframe *fr, t_pbc *pbc,
130 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
131 /*! \brief
132 * Checks whether PDB info is present in the topology.
134 * \param[in] top Topology structure.
135 * \param npar Not used.
136 * \param param Not used.
137 * \param data Not used.
138 * \returns 0 if PDB info is present in the topology, -1 otherwise.
140 * If PDB info is not found, also prints an error message.
142 static void
143 check_pdbinfo(t_topology *top, int npar, gmx_ana_selparam_t *param, void *data);
144 /** Evaluates the \p altloc selection keyword. */
145 static void
146 evaluate_altloc(t_topology *top, t_trxframe *fr, t_pbc *pbc,
147 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
148 /** Evaluates the \p occupancy selection keyword. */
149 static void
150 evaluate_occupancy(t_topology *top, t_trxframe *fr, t_pbc *pbc,
151 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
152 /** Evaluates the \p betafactor selection keyword. */
153 static void
154 evaluate_betafactor(t_topology *top, t_trxframe *fr, t_pbc *pbc,
155 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
156 /** Evaluates the \p resname selection keyword. */
157 static void
158 evaluate_resname(t_topology *top, t_trxframe *fr, t_pbc *pbc,
159 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data);
161 /** Evaluates the \p x selection keyword. */
162 static void
163 evaluate_x(t_topology *top, t_trxframe *fr, t_pbc *pbc,
164 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
165 /** Evaluates the \p y selection keyword. */
166 static void
167 evaluate_y(t_topology *top, t_trxframe *fr, t_pbc *pbc,
168 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
169 /** Evaluates the \p z selection keyword. */
170 static void
171 evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc,
172 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data);
174 //! Help title for atom name selection keywords.
175 static const char helptitle_atomname[] = "Selecting atoms by name";
176 //! Help text for atom name selection keywords.
177 static const char *const help_atomname[] = {
178 "::",
180 " name",
181 " pdbname",
182 " atomname",
183 " pdbatomname",
185 "These keywords select atoms by name. [TT]name[tt] selects atoms using",
186 "the GROMACS atom naming convention.",
187 "For input formats other than PDB, the atom names are matched exactly",
188 "as they appear in the input file. For PDB files, 4 character atom names",
189 "that start with a digit are matched after moving the digit to the end",
190 "(e.g., to match 3HG2 from a PDB file, use [TT]name HG23[tt]).",
191 "[TT]pdbname[tt] can only be used with a PDB input file, and selects",
192 "atoms based on the exact name given in the input file, without the",
193 "transformation described above.[PAR]",
195 "[TT]atomname[tt] and [TT]pdbatomname[tt] are synonyms for the above two",
196 "keywords."
199 /** Selection method data for \p all selection keyword. */
200 gmx_ana_selmethod_t sm_all = {
201 "all", GROUP_VALUE, 0,
202 0, NULL,
203 NULL,
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 NULL,
209 &evaluate_all,
210 NULL,
213 /** Selection method data for \p none selection keyword. */
214 gmx_ana_selmethod_t sm_none = {
215 "none", GROUP_VALUE, 0,
216 0, NULL,
217 NULL,
218 NULL,
219 NULL,
220 NULL,
221 NULL,
222 NULL,
223 &evaluate_none,
224 NULL,
227 /** Selection method data for \p atomnr selection keyword. */
228 gmx_ana_selmethod_t sm_atomnr = {
229 "atomnr", INT_VALUE, 0,
230 0, NULL,
231 NULL,
232 NULL,
233 NULL,
234 NULL,
235 NULL,
236 NULL,
237 &evaluate_atomnr,
238 NULL,
241 /** Selection method data for \p resnr selection keyword. */
242 gmx_ana_selmethod_t sm_resnr = {
243 "resnr", INT_VALUE, SMETH_REQTOP,
244 0, NULL,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 NULL,
250 NULL,
251 &evaluate_resnr,
252 NULL,
255 /** Selection method data for \p resindex selection keyword. */
256 gmx_ana_selmethod_t sm_resindex = {
257 "resindex", INT_VALUE, SMETH_REQTOP,
258 0, NULL,
259 NULL,
260 NULL,
261 NULL,
262 NULL,
263 NULL,
264 NULL,
265 &evaluate_resindex,
266 NULL,
269 /** Selection method data for \p molindex selection keyword. */
270 gmx_ana_selmethod_t sm_molindex = {
271 "molindex", INT_VALUE, SMETH_REQTOP,
272 0, NULL,
273 NULL,
274 NULL,
275 &check_molecules,
276 NULL,
277 NULL,
278 NULL,
279 &evaluate_molindex,
280 NULL,
283 /** Selection method data for \p atomname selection keyword. */
284 gmx_ana_selmethod_t sm_atomname = {
285 "atomname", STR_VALUE, SMETH_REQTOP,
286 0, NULL,
287 NULL,
288 NULL,
289 NULL,
290 NULL,
291 NULL,
292 NULL,
293 &evaluate_atomname,
294 NULL,
295 {NULL, helptitle_atomname, asize(help_atomname), help_atomname}
298 /** Selection method data for \p pdbatomname selection keyword. */
299 gmx_ana_selmethod_t sm_pdbatomname = {
300 "pdbatomname", STR_VALUE, SMETH_REQTOP,
301 0, NULL,
302 NULL,
303 NULL,
304 &check_pdbinfo,
305 NULL,
306 NULL,
307 NULL,
308 &evaluate_pdbatomname,
309 NULL,
310 {NULL, helptitle_atomname, asize(help_atomname), help_atomname}
313 /** Selection method data for \p atomtype selection keyword. */
314 gmx_ana_selmethod_t sm_atomtype = {
315 "atomtype", STR_VALUE, SMETH_REQTOP,
316 0, NULL,
317 NULL,
318 NULL,
319 &check_atomtype,
320 NULL,
321 NULL,
322 NULL,
323 &evaluate_atomtype,
324 NULL,
327 /** Selection method data for \p resname selection keyword. */
328 gmx_ana_selmethod_t sm_resname = {
329 "resname", STR_VALUE, SMETH_REQTOP,
330 0, NULL,
331 NULL,
332 NULL,
333 NULL,
334 NULL,
335 NULL,
336 NULL,
337 &evaluate_resname,
338 NULL,
341 /** Selection method data for \p chain selection keyword. */
342 gmx_ana_selmethod_t sm_insertcode = {
343 "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
344 0, NULL,
345 NULL,
346 NULL,
347 NULL,
348 NULL,
349 NULL,
350 NULL,
351 &evaluate_insertcode,
352 NULL,
355 /** Selection method data for \p chain selection keyword. */
356 gmx_ana_selmethod_t sm_chain = {
357 "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
358 0, NULL,
359 NULL,
360 NULL,
361 NULL,
362 NULL,
363 NULL,
364 NULL,
365 &evaluate_chain,
366 NULL,
369 /** Selection method data for \p mass selection keyword. */
370 gmx_ana_selmethod_t sm_mass = {
371 "mass", REAL_VALUE, SMETH_REQTOP,
372 0, NULL,
373 NULL,
374 NULL,
375 NULL,
376 NULL,
377 NULL,
378 NULL,
379 &evaluate_mass,
380 NULL,
383 /** Selection method data for \p charge selection keyword. */
384 gmx_ana_selmethod_t sm_charge = {
385 "charge", REAL_VALUE, SMETH_REQTOP,
386 0, NULL,
387 NULL,
388 NULL,
389 NULL,
390 NULL,
391 NULL,
392 NULL,
393 &evaluate_charge,
394 NULL,
397 /** Selection method data for \p chain selection keyword. */
398 gmx_ana_selmethod_t sm_altloc = {
399 "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL,
400 0, NULL,
401 NULL,
402 NULL,
403 &check_pdbinfo,
404 NULL,
405 NULL,
406 NULL,
407 &evaluate_altloc,
408 NULL,
411 /** Selection method data for \p occupancy selection keyword. */
412 gmx_ana_selmethod_t sm_occupancy = {
413 "occupancy", REAL_VALUE, SMETH_REQTOP,
414 0, NULL,
415 NULL,
416 NULL,
417 &check_pdbinfo,
418 NULL,
419 NULL,
420 NULL,
421 &evaluate_occupancy,
422 NULL,
425 /** Selection method data for \p betafactor selection keyword. */
426 gmx_ana_selmethod_t sm_betafactor = {
427 "betafactor", REAL_VALUE, SMETH_REQTOP,
428 0, NULL,
429 NULL,
430 NULL,
431 &check_pdbinfo,
432 NULL,
433 NULL,
434 NULL,
435 &evaluate_betafactor,
436 NULL,
439 /** Selection method data for \p x selection keyword. */
440 gmx_ana_selmethod_t sm_x = {
441 "x", REAL_VALUE, SMETH_DYNAMIC,
442 0, NULL,
443 NULL,
444 NULL,
445 NULL,
446 NULL,
447 NULL,
448 NULL,
449 NULL,
450 &evaluate_x,
453 /** Selection method data for \p y selection keyword. */
454 gmx_ana_selmethod_t sm_y = {
455 "y", REAL_VALUE, SMETH_DYNAMIC,
456 0, NULL,
457 NULL,
458 NULL,
459 NULL,
460 NULL,
461 NULL,
462 NULL,
463 NULL,
464 &evaluate_y,
467 /** Selection method data for \p z selection keyword. */
468 gmx_ana_selmethod_t sm_z = {
469 "z", REAL_VALUE, SMETH_DYNAMIC,
470 0, NULL,
471 NULL,
472 NULL,
473 NULL,
474 NULL,
475 NULL,
476 NULL,
477 NULL,
478 &evaluate_z,
482 * See sel_updatefunc() for description of the parameters.
483 * \p data is not used.
485 * Copies \p g to \p out->u.g.
487 static void
488 evaluate_all(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
489 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
491 gmx_ana_index_copy(out->u.g, g, false);
495 * See sel_updatefunc() for description of the parameters.
496 * \p data is not used.
498 * Returns an empty \p out->u.g.
500 static void
501 evaluate_none(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
502 gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void * /* data */)
504 out->u.g->isize = 0;
508 * See sel_updatefunc() for description of the parameters.
509 * \p data is not used.
511 * Returns the indices for each atom in \p out->u.i.
513 static void
514 evaluate_atomnr(t_topology * /* top */, t_trxframe * /* fr */, t_pbc * /* pbc */,
515 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
517 int i;
519 out->nr = g->isize;
520 for (i = 0; i < g->isize; ++i)
522 out->u.i[i] = g->index[i] + 1;
527 * See sel_updatefunc() for description of the parameters.
528 * \p data is not used.
530 * Returns the residue numbers for each atom in \p out->u.i.
532 static void
533 evaluate_resnr(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
534 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
536 int i;
537 int resind;
539 out->nr = g->isize;
540 for (i = 0; i < g->isize; ++i)
542 resind = top->atoms.atom[g->index[i]].resind;
543 out->u.i[i] = top->atoms.resinfo[resind].nr;
548 * See sel_updatefunc() for description of the parameters.
549 * \p data is not used.
551 * Returns the residue indices for each atom in \p out->u.i.
553 static void
554 evaluate_resindex(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
555 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
557 int i;
559 out->nr = g->isize;
560 for (i = 0; i < g->isize; ++i)
562 out->u.i[i] = top->atoms.atom[g->index[i]].resind + 1;
566 static void
567 check_molecules(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
569 bool bOk;
571 bOk = (top != NULL && top->mols.nr > 0);
572 if (!bOk)
574 GMX_THROW(gmx::InconsistentInputError("Molecule information not available in topology"));
579 * See sel_updatefunc() for description of the parameters.
580 * \p data is not used.
582 * Returns the molecule indices for each atom in \p out->u.i.
584 static void
585 evaluate_molindex(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
586 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
588 int i, j;
590 out->nr = g->isize;
591 for (i = j = 0; i < g->isize; ++i)
593 while (top->mols.index[j + 1] <= g->index[i])
595 ++j;
597 out->u.i[i] = j + 1;
602 * See sel_updatefunc() for description of the parameters.
603 * \p data is not used.
605 * Returns the atom name for each atom in \p out->u.s.
607 static void
608 evaluate_atomname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
609 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
611 int i;
613 out->nr = g->isize;
614 for (i = 0; i < g->isize; ++i)
616 out->u.s[i] = *top->atoms.atomname[g->index[i]];
621 * See sel_updatefunc() for description of the parameters.
622 * \p data is not used.
624 * Returns the PDB atom name for each atom in \p out->u.s.
626 static void
627 evaluate_pdbatomname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
628 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
630 int i;
632 out->nr = g->isize;
633 for (i = 0; i < g->isize; ++i)
635 char *s = top->atoms.pdbinfo[g->index[i]].atomnm;
636 while (std::isspace(*s))
638 ++s;
640 out->u.s[i] = s;
644 static void
645 check_atomtype(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
647 bool bOk;
649 bOk = (top != NULL && (top->atoms.haveType));
650 if (!bOk)
652 GMX_THROW(gmx::InconsistentInputError("Atom types not available in topology"));
657 * See sel_updatefunc() for description of the parameters.
658 * \p data is not used.
660 * Returns the atom type for each atom in \p out->u.s.
661 * Segfaults if atom types are not found in the topology.
663 static void
664 evaluate_atomtype(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
665 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
667 int i;
669 out->nr = g->isize;
670 for (i = 0; i < g->isize; ++i)
672 out->u.s[i] = *top->atoms.atomtype[g->index[i]];
677 * See sel_updatefunc() for description of the parameters.
678 * \p data is not used.
680 * Returns the residue name for each atom in \p out->u.s.
682 static void
683 evaluate_resname(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
684 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
686 int i;
687 int resind;
689 out->nr = g->isize;
690 for (i = 0; i < g->isize; ++i)
692 resind = top->atoms.atom[g->index[i]].resind;
693 out->u.s[i] = *top->atoms.resinfo[resind].name;
698 * See sel_updatefunc() for description of the parameters.
699 * \p data is not used.
701 * Returns the insertion code for each atom in \p out->u.s.
703 static void
704 evaluate_insertcode(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
705 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
707 int i;
708 int resind;
710 out->nr = g->isize;
711 for (i = 0; i < g->isize; ++i)
713 resind = top->atoms.atom[g->index[i]].resind;
714 out->u.s[i][0] = top->atoms.resinfo[resind].ic;
719 * See sel_updatefunc() for description of the parameters.
720 * \p data is not used.
722 * Returns the chain for each atom in \p out->u.s.
724 static void
725 evaluate_chain(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
726 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
728 int i;
729 int resind;
731 out->nr = g->isize;
732 for (i = 0; i < g->isize; ++i)
734 resind = top->atoms.atom[g->index[i]].resind;
735 out->u.s[i][0] = top->atoms.resinfo[resind].chainid;
740 * See sel_updatefunc() for description of the parameters.
741 * \p data is not used.
743 * Returns the mass for each atom in \p out->u.r.
745 static void
746 evaluate_mass(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
747 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
749 int i;
751 out->nr = g->isize;
752 for (i = 0; i < g->isize; ++i)
754 out->u.r[i] = top->atoms.atom[g->index[i]].m;
759 * See sel_updatefunc() for description of the parameters.
760 * \p data is not used.
762 * Returns the charge for each atom in \p out->u.r.
764 static void
765 evaluate_charge(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
766 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
768 int i;
770 out->nr = g->isize;
771 for (i = 0; i < g->isize; ++i)
773 out->u.r[i] = top->atoms.atom[g->index[i]].q;
777 static void
778 check_pdbinfo(t_topology *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */)
780 bool bOk;
782 bOk = (top != NULL && top->atoms.havePdbInfo);
783 if (!bOk)
785 GMX_THROW(gmx::InconsistentInputError("PDB info not available in topology"));
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.
795 static void
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 */)
799 int i;
801 out->nr = g->isize;
802 for (i = 0; i < g->isize; ++i)
804 out->u.s[i][0] = top->atoms.pdbinfo[g->index[i]].altloc;
809 * See sel_updatefunc() for description of the parameters.
810 * \p data is not used.
812 * Returns the occupancy numbers for each atom in \p out->u.r.
813 * Segfaults if PDB info is not found in the topology.
815 static void
816 evaluate_occupancy(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
817 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
819 int i;
821 out->nr = g->isize;
822 for (i = 0; i < g->isize; ++i)
824 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].occup;
829 * See sel_updatefunc() for description of the parameters.
830 * \p data is not used.
832 * Returns the B-factors for each atom in \p out->u.r.
833 * Segfaults if PDB info is not found in the topology.
835 static void
836 evaluate_betafactor(t_topology *top, t_trxframe * /* fr */, t_pbc * /* pbc */,
837 gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */)
839 int i;
841 out->nr = g->isize;
842 for (i = 0; i < g->isize; ++i)
844 out->u.r[i] = top->atoms.pdbinfo[g->index[i]].bfac;
848 /*! \brief
849 * Internal utility function for position keyword evaluation.
851 * \param[out] out Output array.
852 * \param[in] pos Position data to use instead of atomic coordinates.
853 * \param[in] d Coordinate index to evaluate (\p XX, \p YY or \p ZZ).
855 * This function is used internally by evaluate_x(), evaluate_y() and
856 * evaluate_z() to do the actual evaluation.
858 static void
859 evaluate_coord(real out[], gmx_ana_pos_t *pos, int d)
861 for (int i = 0; i < pos->count(); ++i)
863 out[i] = pos->x[i][d];
865 // TODO: Make this more efficient by directly extracting the coordinates
866 // from the frame coordinates for atomic positions instead of going through
867 // a position calculation.
871 * See sel_updatefunc_pos() for description of the parameters.
872 * \p data is not used.
874 * Returns the \p x coordinate for each position in \p out->u.r.
876 static void
877 evaluate_x(t_topology * /*top*/, t_trxframe * /*fr*/, t_pbc * /*pbc*/,
878 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
880 out->nr = pos->count();
881 evaluate_coord(out->u.r, pos, XX);
885 * See sel_updatefunc() for description of the parameters.
886 * \p data is not used.
888 * Returns the \p y coordinate for each position in \p out->u.r.
890 static void
891 evaluate_y(t_topology * /*top*/, t_trxframe * /*fr*/, t_pbc * /*pbc*/,
892 gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/)
894 out->nr = pos->count();
895 evaluate_coord(out->u.r, pos, YY);
899 * See sel_updatefunc() for description of the parameters.
900 * \p data is not used.
902 * Returns the \p z coordinate for each position in \p out->u.r.
904 static void
905 evaluate_z(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->count();
909 evaluate_coord(out->u.r, pos, ZZ);