Fixing copyright issues and code contributors
[alexxy/gromacs.git] / src / gmxlib / trajana / trajana.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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,2013, 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.
11  *
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.
16  *
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.
21  *
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.
26  *
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.
34  *
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.
37  */
38 /*! \page libtrajana Library for trajectory analysis
39  *
40  * This is a trajectory analysis library for Gromacs.
41  *
42  * The main features of the library are:
43  *  - \subpage selengine "Flexible handling of textual selections" that can
44  *    also be dynamic, i.e., depend of the trajectory frame through
45  *    positions of the particles.
46  *    Selections evaluate directly to positions, which can then be used in
47  *    the analysis program.
48  *  - \subpage selmethods "Custom selection keywords" can also be easily
49  *    implemented, also on a tool-by-tool basis.
50  *  - Efficient \subpage nbsearch "neighborhood searching"
51  *    (currently not very efficient...).
52  *  - \subpage displacements "On-the-fly calculation of displacement vectors"
53  *    during a single pass over the trajectory.
54  *  - \subpage histograms "Calculation of histograms" with error estimates
55  *    through block averaging.
56  *
57  * The functions also automate several things common to most analysis programs
58  * such as making molecules whole if required, reading input files, and
59  * setting up index groups for analysis.
60  * The library unifies the structure of analysis programs (at least a bit)
61  * and makes it easier to add common functionality to all analysis programs.
62  *
63  *
64  * \section main_using Using the library
65  *
66  * There is a \ref share/template/template.c "template" for writing
67  * analysis programs, the documentation for it and links from there should
68  * help getting started.
69  *
70  *
71  * \internal
72  * \section libtrajana_impl Implementation details
73  *
74  * Some internal implementation details of the library are documented on
75  * separate pages:
76  *  - \subpage poscalcengine
77  *  - \subpage selparser
78  *  - \subpage selcompiler
79  */
80 /*! \page selengine Text-based selections
81  *
82  * \section selection_basics Basics
83  *
84  * Selections are enabled automatically for an analysis program that uses
85  * the library. The selection syntax is described in an online help that is
86  * accessible from all tools that use the library.
87  * By default, dynamic selections are allowed, and the user can freely
88  * choose whether to analyze atoms or centers of mass/geometry of
89  * residues/molecules.
90  * These defaults, as well as some others, can be changed by specifying
91  * flags for gmx_ana_traj_create().
92  *
93  * The analysis program can then access the selected positions for each frame
94  * through a \p gmx_ana_selection_t array that is passed to the frame
95  * analysis function (see gmx_analysisfunc()).
96  * As long as the analysis program is written such that it does not assume
97  * that the number of positions or the atoms in the groups groups remain
98  * constant, any kind of selection expression can be used.
99  *
100  * Some analysis programs may require a special structure for the index groups
101  * (e.g., \c g_angle requires the index group to be made of groups of three or
102  * four atoms).
103  * For such programs, it is up to the user to provide a proper selection
104  * expression that always returns such positions.
105  * Such analysis program can define \ref ANA_REQUIRE_WHOLE to make the
106  * default behavior appropriate for the most common uses where the groups
107  * should consist of atoms within a single residue/molecule.
108  *
109  * \section selection_methods Implementing new keywords
110  *
111  * New selection keywords can be easily implemented, either directly into the
112  * library or as part of analysis programs (the latter may be useful for
113  * testing or methods very specific to some analysis).
114  * For both cases, you should first create a \c gmx_ana_selmethod_t structure
115  * and fill it with the necessary information.
116  * Details can be found on a separate page: \ref selmethods.
117  */
118 /*! \internal \file
119  * \brief Implementation of functions in trajana.h.
120  */
121 /*! \internal \dir src/gmxlib/trajana
122  * \brief Source code for common trajectory analysis functions.
123  *
124  * Selection handling is found in \ref src/gmxlib/selection.
125  */
126 #ifdef HAVE_CONFIG_H
127 #include <config.h>
128 #endif
129
130 #include <string.h>
131
132 #include <filenm.h>
133 #include <futil.h>
134 #include <macros.h>
135 #include <pbc.h>
136 #include <rmpbc.h>
137 #include <smalloc.h>
138 #include <statutil.h>
139 #include <typedefs.h>
140 #include <tpxio.h>
141 #include <vec.h>
142
143 #include <poscalc.h>
144 #include <selection.h>
145 #include <selmethod.h>
146 #include <trajana.h>
147
148 /*! \internal \brief
149  * Data structure for trajectory analysis tools.
150  */
151 struct gmx_ana_traj_t
152 {
153     /*! \brief
154      * Flags that alter the behavior of the analysis library.
155      *
156      * This variable stores the flags passed to gmx_ana_traj_create() for use
157      * in the other functions.
158      */
159     unsigned long             flags;
160     /** Number of input reference groups. */
161     int                       nrefgrps;
162     /*! \brief
163      * Number of input analysis groups.
164      *
165      * This is the number of groups in addition to the reference groups
166      * that are required.
167      * If -1, any number of groups (at least one) is acceptable.
168      */
169     int                       nanagrps;
170     /*! \brief
171      * Flags for init_first_frame() to specify what to read from the
172      * trajectory.
173      */
174     int                       frflags;
175     /** TRUE if molecules should be made whole for each frame. */
176     gmx_bool                      bRmPBC;
177     /*! \brief
178      * TRUE if periodic boundary conditions should be used.
179      *
180      * If the flag is FALSE, the \p pbc pointer passed to gmx_analysisfunc()
181      * is NULL.
182      */
183     gmx_bool                      bPBC;
184
185     /** Name of the trajectory file (NULL if not provided). */
186     char                     *trjfile;
187     /** Name of the topology file (NULL if no topology loaded). */
188     char                     *topfile;
189     /** Non-NULL name of the topology file. */
190     char                     *topfile_notnull;
191     /** Name of the index file (NULL if no index file provided). */
192     char                     *ndxfile;
193     /** Name of the selection file (NULL if no file provided). */
194     char                     *selfile;
195     /** The selection string (NULL if not provided). */
196     char                     *selection;
197
198     /** The topology structure, or \p NULL if no topology loaded. */
199     t_topology               *top;
200     /** TRUE if full tpx file was loaded, FALSE otherwise. */
201     gmx_bool                      bTop;
202     /** Coordinates from the topology (see \p bTopX). */
203     rvec                     *xtop;
204     /** The box loaded from the topology file. */
205     matrix                    boxtop;
206     /** The ePBC field loaded from the topology file. */
207     int                       ePBC;
208
209     /** The current frame, or \p NULL if no frame loaded yet. */
210     t_trxframe               *fr;
211     /** Used to store the status variable from read_first_frame(). */
212     t_trxstatus              *status;
213     /** The number of frames read. */
214     int                       nframes;
215
216     /** Number of elements in the \p sel array. */
217     int                       ngrps;
218     /*! \brief
219      * Array of selection information (one element for each index group).
220      *
221      * After the call to gmx_ana_init_selections(), this array contains
222      * information about the selections the user has provided.
223      * The array contains \p ngrps elements;
224      * if \p nanagrps was -1, the number may vary.
225      * See \c gmx_ana_selection_t for details of the contents.
226      *
227      * The largest possible index groups for dynamic selections can be found
228      * in \p sel[i]->g, i.e., the program can assume that any index group
229      * passed to gmx_analysisfunc() is a subset of the provided group.
230      * After gmx_ana_do(), the same groups can be used in post-processing.
231      */
232     gmx_ana_selection_t     **sel;
233     /** Array of names of the selections for convenience. */
234     char                    **grpnames;
235     /** Position calculation data. */
236     gmx_ana_poscalc_coll_t   *pcc;
237     /** Selection data. */
238     gmx_ana_selcollection_t  *sc;
239
240     /** Data for statutil.c utilities. */
241     output_env_t              oenv;
242 };
243
244 /** Loads the topology. */
245 static int load_topology(gmx_ana_traj_t *d, gmx_bool bReq);
246 /** Loads the first frame and does some checks. */
247 static int init_first_frame(gmx_ana_traj_t *d);
248
249 static int add_fnmarg(int nfile, t_filenm *fnm, t_filenm *fnm_add)
250 {
251     memcpy(&(fnm[nfile]), fnm_add, sizeof(*fnm_add));
252     return nfile + 1;
253 }
254
255 /* Copied from src/gmxlib/statutil.c */
256 static int
257 add_parg(int npargs, t_pargs *pa, t_pargs *pa_add)
258 {
259     memcpy(&(pa[npargs]), pa_add, sizeof(*pa_add));
260     return npargs + 1;
261 }
262
263 /*!
264  * \param[out] data  Trajectory analysis data structure poitner to initialize.
265  * \param[in]  flags Combination of flags (see \ref analysis_flags).
266  * \returns    0 on success.
267  */
268 int
269 gmx_ana_traj_create(gmx_ana_traj_t **data, unsigned long flags)
270 {
271     gmx_ana_traj_t     *d;
272     int                 rc;
273
274     snew(d, 1);
275
276     d->nrefgrps        = 0;
277     d->nanagrps        = 1;
278     d->frflags         = TRX_NEED_X;
279     d->bRmPBC          = TRUE;
280     d->bPBC            = TRUE;
281
282     d->trjfile         = NULL;
283     d->topfile         = NULL;
284     d->ndxfile         = NULL;
285     d->selfile         = NULL;
286     d->selection       = NULL;
287
288     d->top             = NULL;
289     d->bTop            = FALSE;
290     d->xtop            = NULL;
291     d->ePBC            = -1;
292     d->fr              = NULL;
293     d->nframes         = 0;
294
295     d->ngrps           = 0;
296     d->sel             = NULL;
297     d->grpnames        = NULL;
298
299     d->flags           = flags;
300     d->topfile_notnull = NULL;
301     rc = gmx_ana_poscalc_coll_create(&d->pcc);
302     if (rc != 0)
303     {
304         sfree(d);
305         *data = NULL;
306         return rc;
307     }
308     rc = gmx_ana_selcollection_create(&d->sc, d->pcc);
309     if (rc != 0)
310     {
311         gmx_ana_poscalc_coll_free(d->pcc);
312         sfree(d);
313         *data = NULL;
314         return rc;
315     }
316     d->status          = NULL;
317     d->oenv            = NULL;
318
319     *data              = d;
320     return 0;
321 }
322
323 /*!
324  * \param   d  Trajectory analysis data to free.
325  */
326 void
327 gmx_ana_traj_free(gmx_ana_traj_t *d)
328 {
329     int                 i;
330
331     sfree(d->trjfile);
332     sfree(d->topfile);
333     sfree(d->topfile_notnull);
334     sfree(d->ndxfile);
335     sfree(d->selfile);
336     if (d->top)
337     {
338         done_top(d->top);
339         sfree(d->top);
340     }
341     if (d->fr)
342     {
343         /* Gromacs does not seem to have a function for freeing frame data */
344         sfree(d->fr->x);
345         sfree(d->fr->v);
346         sfree(d->fr->f);
347         sfree(d->fr);
348     }
349     sfree(d->xtop);
350     sfree(d->sel);
351     gmx_ana_selcollection_free(d->sc);
352     gmx_ana_poscalc_coll_free(d->pcc);
353     sfree(d->grpnames);
354     output_env_done(d->oenv);
355     sfree(d);
356 }
357
358 /*!
359  * \param[in,out] d      Trajectory analysis data structure.
360  * \param[in]     flags  Additional flags to set.
361  * \returns       0 on success, a non-zero error code on error.
362  *
363  * Currently there are no checks whether the flags make sense or not.
364  */
365 int
366 gmx_ana_add_flags(gmx_ana_traj_t *d, unsigned long flags)
367 {
368     d->flags |= flags;
369     return 0;
370 }
371
372 /*!
373  * \param[in,out] d      Trajectory analysis data structure.
374  * \param[in]     bPBC   TRUE if periodic boundary conditions should be used.
375  * \returns       0 on success.
376  * 
377  * If this function is called before parse_trjana_args(), it sets the default
378  * for whether PBC are used in the analysis or not.
379  * If \ref ANA_NOUSER_PBC is not set, a command-line option is provided for the
380  * user to override the default value.
381  * If called after parse_trjana_args(), it overrides the setting provided by
382  * the user or an earlier call.
383  *
384  * If this function is not called, the default is to use PBC.
385  *
386  * If PBC are not used, the \p pbc pointer passed to gmx_analysisfunc()
387  * is NULL.
388  *
389  * \see \ref ANA_NOUSER_PBC
390  */
391 int
392 gmx_ana_set_pbc(gmx_ana_traj_t *d, gmx_bool bPBC)
393 {
394     d->bPBC = bPBC;
395     return 0;
396 }
397
398 /*!
399  * \param[in] d      Trajectory analysis data structure.
400  * \returns   TRUE if periodic boundary conditions are set to be used.
401  */
402 gmx_bool
403 gmx_ana_has_pbc(gmx_ana_traj_t *d)
404 {
405     return d->bPBC;
406 }
407
408 /*!
409  * \param[in,out] d      Trajectory analysis data structure.
410  * \param[in]     bRmPBC TRUE if molecules should be made whole.
411  * \returns       0 on success.
412  * 
413  * If this function is called before parse_trjana_args(), it sets the default
414  * for whether molecules are made whole.
415  * If \ref ANA_NOUSER_RMPBC is not set, a command-line option is provided for
416  * the user to override the default value.
417  * If called after parse_trjana_args(), it overrides the setting provided by
418  * the user or an earlier call.
419  *
420  * If this function is not called, the default is to make molecules whole.
421  *
422  * The main use of this function is to call it with FALSE if your analysis
423  * program does not require whole molecules as this can increase the
424  * performance.
425  * In such a case, you can also specify \ref ANA_NOUSER_RMPBC to not to
426  * confuse the user with an option that would only slow the program
427  * down.
428  *
429  * \see \ref ANA_NOUSER_RMPBC
430  */
431 int
432 gmx_ana_set_rmpbc(gmx_ana_traj_t *d, gmx_bool bRmPBC)
433 {
434     d->bRmPBC = bRmPBC;
435     return 0;
436 }
437
438 /*!
439  * \param[in,out] d       Trajectory analysis data structure.
440  * \param[in]     frflags Flags for what to read from the trajectory file.
441  * \returns       0 on success, an error code on error.
442  *
443  * The TRX_NEED_X flag is always set.
444  * If the analysis tools needs some other information (velocities, forces),
445  * it can call this function to load additional information from the
446  * trajectory.
447  */
448 int
449 gmx_ana_set_frflags(gmx_ana_traj_t *d, int frflags)
450 {
451     if (d->sel)
452     {
453         gmx_call("cannot set trajectory flags after initializing selections");
454         return -1;
455     }
456     if (d->fr)
457     {
458         gmx_call("cannot set trajectory flags after the first frame has been read");
459         return -1;
460     }
461     frflags |= TRX_NEED_X;
462     d->frflags = frflags;
463     return 0;
464 }
465
466 /*!
467  * \param[in,out] d        Trajectory analysis data structure.
468  * \param[in]     nrefgrps Number of reference groups required.
469  * \returns       0 on success, a non-zero error code on error.
470  *
471  * \p nrefgrps should be a non-negative integer.
472  * If this function is not called (or \p nrefgrps is 0), all selections are
473  * treated as reference groups.
474  */
475 int
476 gmx_ana_set_nrefgrps(gmx_ana_traj_t *d, int nrefgrps)
477 {
478     if (nrefgrps < 0)
479     {
480         d->nrefgrps = 0;
481         gmx_incons("number of reference groups is negative");
482         return EINVAL;
483     }
484     d->nrefgrps = nrefgrps;
485     return 0;
486 }
487
488 /*!
489  * \param[in,out] d        Trajectory analysis data structure.
490  * \param[in]     nanagrps Number of analysis groups required
491  *   (-1 stands for any number of analysis groups).
492  * \returns       0 on success, a non-zero error code on error.
493  *
494  * \p nanagrps should be a positive integer or -1.
495  * In the latter case, any number of groups (but at least one) is acceptable.
496  * gmx_ana_get_nanagrps() can be used to access the actual value after
497  * gmx_ana_init_selections() has been called.
498  * If this function is not called, a single analysis group is expected.
499  */
500 int
501 gmx_ana_set_nanagrps(gmx_ana_traj_t *d, int nanagrps)
502 {
503     if (nanagrps <= 0 && nanagrps != -1)
504     {
505         d->nanagrps = 1;
506         gmx_incons("number of analysis groups is invalid");
507         return EINVAL;
508     }
509     d->nanagrps = nanagrps;
510     return 0;
511 }
512
513 /*!
514  * \param[in]  d     Trajectory analysis data structure.
515  * \param[out] ngrps Total number of selections specified by the user.
516  * \returns    0 on success, a non-zero error code on error.
517  *
518  * The value stored in \p *ngrps is the sum of the number of reference groups
519  * and the number of analysis groups.
520  * If a specific number (not -1) of analysis groups has been set with
521  * gmx_ana_set_nanagrps(), the value is always the sum of the values provided
522  * to gmx_ana_set_nrefgrps() and gmx_ana_set_nanagrps().
523  *
524  * Should only be called after gmx_ana_init_selections().
525  */
526 int
527 gmx_ana_get_ngrps(gmx_ana_traj_t *d, int *ngrps)
528 {
529     if (d->nanagrps == -1)
530     {
531         *ngrps = 0;
532         gmx_call("gmx_ana_init_selections() not called");
533         return EINVAL;
534     }
535     *ngrps = d->nrefgrps + d->nanagrps;
536     return 0;
537 }
538
539 /*!
540  * \param[in]  d        Trajectory analysis data structure.
541  * \param[out] nanagrps Number of analysis groups specified by the user.
542  * \returns    0 on success, a non-zero error code on error.
543  *
544  * If a specific number (not -1) of analysis groups has been set with
545  * gmx_ana_set_nanagrps(), the value is always the same value.
546  * Hence, you only need to call this function if gmx_ana_set_nanagrps() has
547  * been called with \p nanagrps set to -1.
548  *
549  * Should only be called after gmx_ana_init_selections().
550  */
551 int
552 gmx_ana_get_nanagrps(gmx_ana_traj_t *d, int *nanagrps)
553 {
554     if (d->nanagrps == -1)
555     {
556         *nanagrps = 0;
557         gmx_call("gmx_ana_init_selections() not called");
558         return EINVAL;
559     }
560     *nanagrps = d->nanagrps;
561     return 0;
562 }
563
564 /*!
565  * \param[in]  d   Trajectory analysis data structure.
566  * \param[in]  i   Ordinal number of the reference selection to get.
567  * \param[out] sel Selection object for the \p i'th reference group.
568  * \returns    0 on success, a non-zero error code on error.
569  *
570  * The pointer returned in \p *sel should not be freed.
571  * Should only be called after gmx_ana_init_selections().
572  */
573 int
574 gmx_ana_get_refsel(gmx_ana_traj_t *d, int i, gmx_ana_selection_t **sel)
575 {
576     if (i < 0 || i >= d->nrefgrps)
577     {
578         *sel = NULL;
579         gmx_call("invalid reference group number");
580         return EINVAL;
581     }
582     *sel = gmx_ana_selcollection_get_selection(d->sc, i);
583     if (!*sel)
584     {
585         gmx_incons("gmx_ana_init_selections() not called");
586         return EINVAL;
587     }
588     return 0;
589 }
590
591 /*!
592  * \param[in]  d   Trajectory analysis data structure.
593  * \param[out] sel Array of analysis selections.
594  * \returns    0 on success, a non-zero error code on error.
595  *
596  * The pointer returned in \p *sel should not be freed.
597  * Should only be called after gmx_ana_init_selections().
598  */
599 int
600 gmx_ana_get_anagrps(gmx_ana_traj_t *d, gmx_ana_selection_t ***sel)
601 {
602     if (!d->sel)
603     {
604         *sel = NULL;
605         gmx_incons("gmx_ana_init_selections() not called");
606         return EINVAL;
607     }
608     *sel = d->sel;
609     return 0;
610 }
611
612 /*!
613  * \param[in]  d        Trajectory analysis data structure.
614  * \param[out] grpnames Array of selection names.
615  * \returns    0 on success, a non-zero error code on error.
616  *
617  * The pointer returned in \p *grpnames should not be freed.
618  * Should only be called after gmx_ana_init_selections().
619  */
620 int
621 gmx_ana_get_grpnames(gmx_ana_traj_t *d, char ***grpnames)
622 {
623     if (!d->grpnames)
624     {
625         *grpnames = NULL;
626         gmx_call("gmx_ana_init_selections() not called");
627         return EINVAL;
628     }
629     *grpnames = d->grpnames;
630     return 0;
631 }
632
633 /*!
634  * \param[in]  d   Trajectory analysis data structure.
635  * \param[out] sc  Selection collection object.
636  * \returns    0 on success.
637  *
638  * This function is mostly useful for debugging purposes.
639  * The information commonly required in analysis programs is accessible
640  * more conveniently through other means.
641  *
642  * The pointer returned in \p *sc should not be freed.
643  * Can be called at any point.
644  */
645 int
646 gmx_ana_get_selcollection(gmx_ana_traj_t *d, gmx_ana_selcollection_t **sc)
647 {
648     *sc = d->sc;
649     return 0;
650 }
651
652 /*!
653  * \param[in,out] d     Trajectory analysis data structure.
654  * \returns    0 on success, a non-zero error code on error.
655  *
656  * This function should be called first in the analysis program, much in
657  * the same way as parse_common_args() in traditional Gromacs analysis
658  * programs. It adds some command-line arguments of its own, and uses
659  * parse_common_args() to parse the command-line arguments.
660  * It also loads topology information if required or if a topology is
661  * provided on the command line.
662  * Selection handling is also initialized if it is enabled and
663  * the user has selected it on the command line.
664  *
665  * The rest of the parameters are passed on to the Gromacs routine
666  * parse_common_args(), and the use of this function should be identical
667  * to parse_common_args(), with the exception that for \p pca_flags,
668  * \p PCA_CAN_TIME and \p PCA_BE_NICE flags are automatically added.
669  * \param      argc
670  * \param      argv
671  * \param      pca_flags
672  * \param      nfile
673  * \param      fnm
674  * \param      npargs
675  * \param      pa
676  * \param      ndesc
677  * \param      desc
678  * \param      nbugs
679  * \param      bugs
680  * \param      oenv
681  */
682 int
683 parse_trjana_args(gmx_ana_traj_t *d,
684                   int *argc, char *argv[], unsigned long pca_flags,
685                   int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
686                   int ndesc, const char **desc,
687                   int nbugs, const char **bugs,
688                   output_env_t *oenv)
689 {
690     t_filenm           *all_fnm = NULL;
691     int                 max_fnm, nfall;
692     int                *fnm_map;
693     t_pargs            *all_pa = NULL;
694     int                 max_pa, npall;
695     size_t              i;
696     int                 k;
697     int                 rc;
698     const char         *tmp_fnm;
699
700     t_filenm            def_fnm[] = {
701         {efTRX, NULL,  NULL,        ffOPTRD},
702         {efTPS, NULL,  NULL,        ffREAD},
703         {efDAT, "-sf", "selection", ffOPTRD},
704         {efNDX, NULL,  NULL,        ffOPTRD},
705     };
706     gmx_bool                bPBC = TRUE;
707     t_pargs             pbc_pa[] = {
708         {"-pbc",      FALSE, etBOOL, {&bPBC},
709          "Use periodic boundary conditions for distance calculation"},
710     };
711     gmx_bool                bRmPBC = TRUE;
712     t_pargs             rmpbc_pa[] = {
713         {"-rmpbc",    FALSE, etBOOL, {&bRmPBC},
714          "Make molecules whole for each frame"},
715     };
716     char               *selection = NULL;
717     const char        **rpost     = NULL;
718     gmx_bool                bSelDump  = FALSE;
719     t_pargs             sel_pa[] = {
720         {"-select",   FALSE, etSTR,  {&selection},
721          "Selection string (use 'help' for help). Note that the "
722          "whole selection string will need to be quoted so that "
723          "your shell will pass it in as a string. Example: "
724          "[TT]g_select -select '\"Nearby water\" resname SOL "
725          "and within 0.25 of group Protein'[tt]"},
726         {"-seldebug", FALSE, etBOOL, {&bSelDump},
727          "HIDDENPrint out the parsed and compiled selection trees"},
728     };
729     t_pargs             dsel_pa[] = {
730         {"-selrpos",  FALSE, etENUM, {NULL},
731          "Selection reference position"},
732     };
733     const char        **spost = NULL;
734     t_pargs             selpt_pa[] = {
735         {"-seltype",  FALSE, etENUM, {NULL},
736          "Default analysis positions"},
737     };
738 #define MAX_PA asize(sel_pa)+asize(dsel_pa)+5
739
740     if (d->nrefgrps < 0)
741     {
742         gmx_incons("number of reference groups is negative");
743         return EINVAL;
744     }
745
746     if (d->flags & ANA_DEBUG_SELECTION)
747     {
748         bSelDump = TRUE;
749     }
750
751     rpost = gmx_ana_poscalc_create_type_enum(!(d->flags & ANA_REQUIRE_WHOLE));
752     if (rpost == NULL)
753     {
754         return ENOMEM;
755     }
756     spost = gmx_ana_poscalc_create_type_enum(TRUE);
757     if (spost == NULL)
758     {
759         sfree(rpost);
760         return ENOMEM;
761     }
762
763     /* Construct the file name argument array */
764     max_fnm = nfile + asize(def_fnm);
765     snew(all_fnm, max_fnm);
766     nfall = 0;
767     if (!(d->flags & ANA_REQUIRE_TOP))
768     {
769         def_fnm[1].flag |= ffOPT;
770     }
771     snew(fnm_map, nfile);
772     for (k = 0; k < nfile; ++k)
773     {
774         fnm_map[k] = -1;
775     }
776
777     for (i = 0; i < asize(def_fnm); ++i)
778     {
779         for (k = 0; k < nfile; ++k)
780         {
781             if (fnm_map[k] == -1 && def_fnm[i].opt == NULL
782                 && fnm[k].opt == NULL && fnm[k].ftp == def_fnm[i].ftp)
783             {
784                 break;
785             }
786         }
787         if (k < nfile)
788         {
789             fnm_map[k] = nfall;
790             nfall = add_fnmarg(nfall, all_fnm, &(fnm[k]));
791         }
792         else
793         {
794             nfall = add_fnmarg(nfall, all_fnm, &(def_fnm[i]));
795         }
796     }
797
798     for (k = 0; k < nfile; ++k)
799     {
800         if (fnm_map[k] == -1)
801         {
802             fnm_map[k] = nfall;
803             nfall = add_fnmarg(nfall, all_fnm, &(fnm[k]));
804         }
805     }
806
807     /* Construct the argument array */
808     max_pa = npargs + MAX_PA;
809     snew(all_pa, max_pa);
810     npall = 0;
811
812     if (!(d->flags & ANA_NOUSER_RMPBC))
813     {
814         for (i = 0; i < asize(rmpbc_pa); ++i)
815         {
816             npall = add_parg(npall, all_pa, &(rmpbc_pa[i]));
817         }
818     }
819     if (!(d->flags & ANA_NOUSER_PBC))
820     {
821         for (i = 0; i < asize(pbc_pa); ++i)
822         {
823             npall = add_parg(npall, all_pa, &(pbc_pa[i]));
824         }
825     }
826
827     for (i = 0; i < asize(sel_pa); ++i)
828     {
829         npall = add_parg(npall, all_pa, &(sel_pa[i]));
830     }
831     if (!(d->flags & ANA_NO_DYNSEL))
832     {
833         dsel_pa[0].u.c = rpost;
834         for (i = 0; i < asize(dsel_pa); ++i)
835         {
836             npall = add_parg(npall, all_pa, &(dsel_pa[i]));
837         }
838     }
839
840     if (!(d->flags & ANA_ONLY_ATOMPOS))
841     {
842         selpt_pa[0].u.c = spost;
843         for (i = 0; i < asize(selpt_pa); ++i)
844         {
845             npall = add_parg(npall, all_pa, &(selpt_pa[i]));
846         }
847     }
848
849     for (k = 0; k < npargs; ++k)
850     {
851         npall = add_parg(npall, all_pa, &(pa[k]));
852     }
853
854     pca_flags |= PCA_CAN_TIME | PCA_BE_NICE;
855     parse_common_args(argc, argv, pca_flags, nfall, all_fnm, npall, all_pa,
856                       ndesc, desc, nbugs, bugs,oenv);
857     d->oenv = *oenv;
858
859     /* Process our own options.
860      * Make copies of file names for easier memory management. */
861     tmp_fnm            = ftp2fn_null(efTRX, nfall, all_fnm);
862     d->trjfile         = tmp_fnm ? strdup(tmp_fnm) : NULL;
863     tmp_fnm            = ftp2fn_null(efTPS, nfall, all_fnm);
864     d->topfile         = tmp_fnm ? strdup(tmp_fnm) : NULL;
865     d->topfile_notnull = strdup(ftp2fn(efTPS, nfall, all_fnm));
866     tmp_fnm            = ftp2fn_null(efNDX, nfall, all_fnm);
867     d->ndxfile         = tmp_fnm ? strdup(tmp_fnm) : NULL;
868     if (!(d->flags & ANA_NOUSER_RMPBC))
869     {
870         d->bRmPBC      = bRmPBC;
871     }
872     if (!(d->flags & ANA_NOUSER_PBC))
873     {
874         d->bPBC        = bPBC;
875     }
876     d->selection       = selection;
877     tmp_fnm            = opt2fn_null("-sf", nfall, all_fnm);
878     d->selfile         = tmp_fnm ? strdup(tmp_fnm) : NULL;
879
880     /* Copy the results back */
881     for (k = 0; k < nfile; ++k)
882     {
883         memcpy(&(fnm[k]), &(all_fnm[fnm_map[k]]), sizeof(fnm[k]));
884         /* Delegate responsibility of freeing the file names to caller. */
885         all_fnm[fnm_map[k]].nfiles = 0;
886         all_fnm[fnm_map[k]].fns    = NULL;
887     }
888     for (i = 0, k = npall - npargs; i < (size_t)npargs; ++i, ++k)
889     {
890         memcpy(&(pa[i]), &(all_pa[k]), sizeof(pa[i]));
891     }
892
893     /* Free memory we have allocated. */
894     done_filenms(nfall, all_fnm);
895     sfree(all_fnm);
896     sfree(fnm_map);
897     sfree(all_pa);
898
899     if (!(d->flags & ANA_NO_DYNSEL))
900     {
901         gmx_ana_selcollection_set_refpostype(d->sc, rpost[0]);
902     }
903     else
904     {
905         gmx_ana_selcollection_set_refpostype(d->sc, rpost[1]);
906     }
907     sfree(rpost);
908     if (bSelDump)
909     {
910         d->flags |= ANA_DEBUG_SELECTION;
911     }
912     else
913     {
914         d->flags &= ~ANA_DEBUG_SELECTION;
915     }
916
917     if (!(d->flags & ANA_ONLY_ATOMPOS))
918     {
919         gmx_ana_selcollection_set_outpostype(d->sc, spost[0], d->flags & ANA_USE_POSMASK);
920     }
921     else
922     {
923         gmx_ana_selcollection_set_outpostype(d->sc, spost[1], d->flags & ANA_USE_POSMASK);
924     }
925     sfree(spost);
926
927     /* Check if the user requested help on selections.
928      * If so, call gmx_ana_init_selections() to print the help and exit. */
929     if (selection && strncmp(selection, "help", 4) == 0)
930     {
931         gmx_ana_init_selections(d);
932     }
933
934     /* If no trajectory file is given, we need to set some flags to be able
935      * to prepare a frame from the loaded topology information. Also, check
936      * that a topology is provided. */
937     if (!d->trjfile)
938     {
939         if (!d->topfile)
940         {
941             gmx_input("No trajectory or topology provided, nothing to do!");
942             return -1;
943         }
944         d->flags |= ANA_REQUIRE_TOP;
945         d->flags |= ANA_USE_TOPX;
946     }
947
948     /* Load the topology if so requested. */
949     rc = load_topology(d, (d->flags & ANA_REQUIRE_TOP));
950     if (rc != 0)
951     {
952         return rc;
953     }
954
955     /* Initialize the selections/index groups */
956     if (!(d->flags & ANA_USER_SELINIT))
957     {
958         rc = gmx_ana_init_selections(d);
959     }
960
961     return rc;
962 }
963
964 /*!
965  * \param[in,out] d     Trajectory analysis data structure.
966  * \param[in]     bReq  If TRUE, topology loading is forced.
967  * \returns       0 on success, a non-zero error code on error.
968  *
969  * Initializes the \c gmx_ana_traj_t::top, \c gmx_ana_traj_t::bTop,
970  * \c gmx_ana_traj_t::boxtop and \c gmx_ana_traj_t::ePBC fields of the
971  * analysis structure.
972  * If \p bReq is TRUE, the topology is loaded even if it is not given on
973  * the command line.
974  *
975  * The function can be called multiple times safely; extra calls are
976  * ignored.
977  */
978 static int load_topology(gmx_ana_traj_t *d, gmx_bool bReq)
979 {
980     char                title[STRLEN];
981
982     /* Return if topology already loaded */
983     if (d->top)
984     {
985         return 0;
986     }
987
988     if (d->topfile || bReq)
989     {
990         snew(d->top, 1);
991         d->bTop = read_tps_conf(d->topfile_notnull, title, d->top,
992                                 &d->ePBC, &d->xtop, NULL, d->boxtop, TRUE);
993         if (!(d->flags & ANA_USE_TOPX))
994         {
995             sfree(d->xtop);
996             d->xtop = NULL;
997         }
998     }
999     return 0;
1000 }
1001
1002 /*!
1003  * \param[in]  d     Trajectory analysis data structure.
1004  * \param[in]  bReq  If TRUE, topology loading is forced.
1005  * \param[out] top   Topology data pointer to initialize.
1006  * \param[out] bTop  TRUE if a full tpx file was loaded, FALSE otherwise
1007  *   (can be NULL, in which case it is not used).
1008  * \returns    0 on success, a non-zero error code on error.
1009  *
1010  * If \ref ANA_REQUIRE_TOP has not been specified and \p bReq is FALSE,
1011  * the pointer stored in \p *top may be NULL if no topology has been provided
1012  * on the command line.
1013  *
1014  * The pointer returned in \p *top should not be freed.
1015  */
1016 int
1017 gmx_ana_get_topology(gmx_ana_traj_t *d, gmx_bool bReq, t_topology **top, gmx_bool *bTop)
1018 {
1019     int rc;
1020
1021     rc = load_topology(d, bReq);
1022     if (rc != 0)
1023     {
1024         *top = NULL;
1025         return rc;
1026     }
1027     *top = d->top;
1028     if (bTop)
1029     {
1030         *bTop = d->bTop;
1031     }
1032     return 0;
1033 }
1034
1035 /*!
1036  * \param[in]  d     Trajectory analysis data structure.
1037  * \param[out] x     Topology data pointer to initialize.
1038  *   (can be NULL, in which case it is not used).
1039  * \param[out] box   Box size from the topology file
1040  *   (can be NULL, in which case it is not used).
1041  * \param[out] ePBC  The ePBC field from the topology
1042  *   (can be NULL, in which case it is not used).
1043  * \returns    0 on success, a non-zero error code on error.
1044  *
1045  * If \ref ANA_USE_TOPX has not been specified, the \p x parameter should be
1046  * NULL.
1047  *
1048  * The pointer returned in \p *x should not be freed.
1049  */
1050 int
1051 gmx_ana_get_topconf(gmx_ana_traj_t *d, rvec **x, matrix box, int *ePBC)
1052 {
1053     if (box)
1054     {
1055         copy_mat(d->boxtop, box);
1056     }
1057     if (ePBC)
1058     {
1059         *ePBC = d->ePBC;
1060     }
1061     if (x)
1062     {
1063         if (!(d->flags & ANA_USE_TOPX))
1064         {
1065             gmx_incons("topology coordinates requested by ANA_USE_TOPX not set");
1066             *x = NULL;
1067             return EINVAL;
1068         }
1069         *x = d->xtop;
1070     }
1071     return 0;
1072 }
1073
1074 /*! \brief
1075  * Loads default index groups from a selection file.
1076  *
1077  * \param[in,out] d     Trajectory analysis data structure.
1078  * \param[out]    grps  Pointer to receive the default groups.
1079  * \returns       0 on success, a non-zero error code on error.
1080  */
1081 static int
1082 init_default_selections(gmx_ana_traj_t *d, gmx_ana_indexgrps_t **grps)
1083 {
1084     gmx_ana_selcollection_t  *sc;
1085     char                     *fnm;
1086     int                       nr, nr_notempty, i;
1087     int                       rc;
1088
1089     /* If an index file is provided, just load it and exit. */
1090     if (d->ndxfile)
1091     {
1092         gmx_ana_indexgrps_init(grps, d->top, d->ndxfile);
1093         return 0;
1094     }
1095     /* Initialize groups to NULL if we return prematurely. */
1096     *grps = NULL;
1097     /* Return immediately if no topology provided. */
1098     if (!d->top)
1099     {
1100         return 0;
1101     }
1102
1103     /* Find the default selection file, return if none found. */
1104     fnm = low_gmxlibfn("defselection.dat", TRUE, FALSE);
1105     if (fnm == NULL)
1106     {
1107         return 0;
1108     }
1109
1110     /* Create a temporary selection collection. */
1111     rc = gmx_ana_selcollection_create(&sc, d->pcc);
1112     if (rc != 0)
1113     {
1114         sfree(fnm);
1115         return rc;
1116     }
1117     rc = gmx_ana_selmethod_register_defaults(sc);
1118     if (rc != 0)
1119     {
1120         gmx_ana_selcollection_free(sc);
1121         sfree(fnm);
1122         gmx_fatal(FARGS, "default selection method registration failed");
1123         return rc;
1124     }
1125     /* FIXME: It would be better to not have the strings here hard-coded. */
1126     gmx_ana_selcollection_set_refpostype(sc, "atom");
1127     gmx_ana_selcollection_set_outpostype(sc, "atom", FALSE);
1128
1129     /* Parse and compile the file with no external groups. */
1130     rc = gmx_ana_selcollection_parse_file(sc, fnm, NULL);
1131     sfree(fnm);
1132     if (rc != 0)
1133     {
1134         gmx_ana_selcollection_free(sc);
1135         fprintf(stderr, "\nWARNING: default selection(s) could not be parsed\n");
1136         return rc;
1137     }
1138     gmx_ana_selcollection_set_topology(sc, d->top, -1);
1139     rc = gmx_ana_selcollection_compile(sc);
1140     if (rc != 0)
1141     {
1142         gmx_ana_selcollection_free(sc);
1143         fprintf(stderr, "\nWARNING: default selection(s) could not be compiled\n");
1144         return rc;
1145     }
1146
1147     /* Count the non-empty groups and check that there are no dynamic
1148      * selections. */
1149     nr = gmx_ana_selcollection_get_count(sc);
1150     nr_notempty = 0;
1151     for (i = 0; i < nr; ++i)
1152     {
1153         gmx_ana_selection_t  *sel;
1154
1155         sel = gmx_ana_selcollection_get_selection(sc, i);
1156         if (sel->bDynamic)
1157         {
1158             fprintf(stderr, "\nWARNING: dynamic default selection ignored\n");
1159         }
1160         else if (sel->g->isize > 0)
1161         {
1162             ++nr_notempty;
1163         }
1164     }
1165
1166     /* Copy the groups to the output structure */
1167     gmx_ana_indexgrps_alloc(grps, nr_notempty);
1168     nr_notempty = 0;
1169     for (i = 0; i < nr; ++i)
1170     {
1171         gmx_ana_selection_t  *sel;
1172
1173         sel = gmx_ana_selcollection_get_selection(sc, i);
1174         if (!sel->bDynamic && sel->g->isize > 0)
1175         {
1176             gmx_ana_index_t  *g;
1177
1178             g = gmx_ana_indexgrps_get_grp(*grps, nr_notempty);
1179             gmx_ana_index_copy(g, sel->g, TRUE);
1180             g->name = strdup(sel->name);
1181             ++nr_notempty;
1182         }
1183     }
1184
1185     gmx_ana_selcollection_free(sc);
1186     return 0;
1187 }
1188
1189 /*!
1190  * \param[in,out] d     Trajectory analysis data structure.
1191  * \returns       0 on success, a non-zero error code on error.
1192  *
1193  * Initializes the selection data in \c gmx_ana_traj_t based on
1194  * the selection options and/or index files provided on the command line.
1195  *
1196  * This function is called automatically by parse_trjana_args() and should
1197  * not be called directly unless \ref ANA_USER_SELINIT is specified.
1198  *
1199  * \see ANA_USER_SELINIT
1200  */
1201 int
1202 gmx_ana_init_selections(gmx_ana_traj_t *d)
1203 {
1204     int                  rc;
1205     int                  i;
1206     int                  nr;
1207     gmx_ana_indexgrps_t *grps;
1208     int                  natoms;
1209     gmx_bool                 bStdIn;
1210     gmx_bool                 bInteractive;
1211     gmx_bool                 bOk;
1212
1213     if (d->sel)
1214     {
1215         gmx_call("init_selections called more than once\n"
1216                  "perhaps you forgot ANA_USER_SELINIT");
1217         return -1;
1218     }
1219
1220     gmx_ana_selcollection_set_veloutput(d->sc,
1221             d->frflags & (TRX_READ_V | TRX_NEED_V));
1222     gmx_ana_selcollection_set_forceoutput(d->sc,
1223             d->frflags & (TRX_READ_F | TRX_NEED_F));
1224     /* Check if we need some information from the topology */
1225     if (gmx_ana_selcollection_requires_top(d->sc))
1226     {
1227         rc = load_topology(d, TRUE);
1228         if (rc != 0)
1229         {
1230             return rc;
1231         }
1232     }
1233     /* Initialize the default selection methods */
1234     rc = gmx_ana_selmethod_register_defaults(d->sc);
1235     if (rc != 0)
1236     {
1237         gmx_fatal(FARGS, "default selection method registration failed");
1238         return rc;
1239     }
1240     /* Initialize index groups.
1241      * We ignore the return value to continue without the default groups if
1242      * there is an error there. */
1243     init_default_selections(d, &grps);
1244     /* Parse the selections */
1245     bStdIn = (d->selfile && d->selfile[0] == '-' && d->selfile[1] == 0)
1246              || (d->selection && d->selection[0] == 0)
1247              || (!d->selfile && !d->selection);
1248     /* Behavior is not very pretty if we cannot check for interactive input,
1249      * but at least it should compile and work in most cases. */
1250 #ifdef HAVE_UNISTD_H
1251     bInteractive = bStdIn && isatty(fileno(stdin));
1252 #else
1253     bInteractive = bStdIn;
1254 #endif
1255     if (bStdIn && bInteractive)
1256     {
1257         /* Parse from stdin */
1258         /* First we parse the reference groups if there are any */
1259         if (d->nrefgrps > 0)
1260         {
1261             fprintf(stderr, "\nSpecify ");
1262             if (d->nrefgrps == 1)
1263             {
1264                 fprintf(stderr, "a reference selection");
1265             }
1266             else
1267             {
1268                 fprintf(stderr, "%d reference selections", d->nrefgrps);
1269             }
1270             fprintf(stderr, ":\n");
1271             fprintf(stderr, "(one selection per line, 'help' for help)\n");
1272             rc = gmx_ana_selcollection_parse_stdin(d->sc, d->nrefgrps, grps, TRUE);
1273             nr = gmx_ana_selcollection_get_count(d->sc);
1274             if (rc != 0 || nr != d->nrefgrps)
1275             {
1276                 gmx_ana_traj_free(d);
1277                 gmx_input("unrecoverable error in selection parsing");
1278                 return rc;
1279             }
1280         }
1281         /* Then, we parse the analysis groups */
1282         fprintf(stderr, "\nSpecify ");
1283         if (d->nanagrps == 1)
1284         {
1285             fprintf(stderr, "a selection");
1286         }
1287         else if (d->nanagrps == -1)
1288         {
1289             fprintf(stderr, "any number of selections");
1290         }
1291         else
1292         {
1293             fprintf(stderr, "%d selections", d->nanagrps);
1294         }
1295         fprintf(stderr, " for analysis:\n");
1296         fprintf(stderr, "(one selection per line, 'help' for help%s)\n",
1297                 d->nanagrps == -1 ? ", Ctrl-D to end" : "");
1298         rc = gmx_ana_selcollection_parse_stdin(d->sc, d->nanagrps, grps, TRUE);
1299         fprintf(stderr, "\n");
1300     }
1301     else if (bStdIn)
1302     {
1303         rc = gmx_ana_selcollection_parse_stdin(d->sc, -1, grps, FALSE);
1304     }
1305     else if (d->selection)
1306     {
1307         rc = gmx_ana_selcollection_parse_str(d->sc, d->selection, grps);
1308     }
1309     else
1310     {
1311         rc = gmx_ana_selcollection_parse_file(d->sc, d->selfile, grps);
1312     }
1313     if (grps)
1314     {
1315         gmx_ana_indexgrps_free(grps);
1316     }
1317     if (rc != 0)
1318     {
1319         /* Free memory for memory leak checking */
1320         gmx_ana_traj_free(d);
1321         gmx_input("selection(s) could not be parsed");
1322         return rc;
1323     }
1324
1325     /* Check the number of groups */
1326     nr = gmx_ana_selcollection_get_count(d->sc);
1327     if (nr == 0)
1328     {
1329         /* TODO: Don't print this if the user has requested help */
1330         fprintf(stderr, "Nothing selected, finishing up.\n");
1331         gmx_ana_traj_free(d);
1332         /* TODO: It would be better to return some code that tells the caller
1333          * that one should exit. */
1334         exit(0);
1335     }
1336     if (nr <= d->nrefgrps)
1337     {
1338         gmx_input("selection does not specify enough index groups");
1339         return -1;
1340     }
1341     if (d->nanagrps <= 0)
1342     {
1343         d->nanagrps = nr - d->nrefgrps;
1344     }
1345     else if (nr != d->nrefgrps + d->nanagrps)
1346     {
1347         gmx_input("selection does not specify the correct number of index groups");
1348         return -1;
1349     }
1350
1351     if (d->flags & ANA_DEBUG_SELECTION)
1352     {
1353         gmx_ana_selcollection_print_tree(stderr, d->sc, FALSE);
1354     }
1355     if (gmx_ana_selcollection_requires_top(d->sc))
1356     {
1357         rc = load_topology(d, TRUE);
1358         if (rc != 0)
1359         {
1360             return rc;
1361         }
1362     }
1363     if (d->top)
1364     {
1365         natoms = -1;
1366     }
1367     else
1368     {
1369         rc = init_first_frame(d);
1370         if (rc != 0)
1371         {
1372             return rc;
1373         }
1374         natoms = d->fr->natoms;
1375     }
1376     gmx_ana_selcollection_set_topology(d->sc, d->top, natoms);
1377     rc = gmx_ana_selcollection_compile(d->sc);
1378     if (rc != 0)
1379     {
1380         /* Free memory for memory leak checking */
1381         gmx_ana_traj_free(d);
1382         gmx_input("selection could not be compiled");
1383         return rc;
1384     }
1385     /* Create the selection array */
1386     d->ngrps = gmx_ana_selcollection_get_count(d->sc);
1387     if (!(d->flags & ANA_USE_FULLGRPS))
1388     {
1389         d->ngrps -= d->nrefgrps;
1390     }
1391     snew(d->sel, d->ngrps);
1392     for (i = 0; i < d->ngrps; ++i)
1393     {
1394         if (d->flags & ANA_USE_FULLGRPS)
1395         {
1396             d->sel[i] = gmx_ana_selcollection_get_selection(d->sc, i);
1397         }
1398         else
1399         {
1400             d->sel[i] = gmx_ana_selcollection_get_selection(d->sc, i + d->nrefgrps);
1401         }
1402     }
1403     if (d->flags & ANA_DEBUG_SELECTION)
1404     {
1405         fprintf(stderr, "\n");
1406         gmx_ana_selcollection_print_tree(stderr, d->sc, FALSE);
1407         fprintf(stderr, "\n");
1408         gmx_ana_poscalc_coll_print_tree(stderr, d->pcc);
1409         fprintf(stderr, "\n");
1410     }
1411
1412     /* Initialize the position evaluation */
1413     gmx_ana_poscalc_init_eval(d->pcc);
1414     if (d->flags & ANA_DEBUG_SELECTION)
1415     {
1416         gmx_ana_poscalc_coll_print_tree(stderr, d->pcc);
1417         fprintf(stderr, "\n");
1418     }
1419
1420     /* Check that dynamic selections are not provided if not allowed */
1421     if (d->flags & ANA_NO_DYNSEL)
1422     {
1423         for (i = 0; i < d->nrefgrps + d->nanagrps; ++i)
1424         {
1425             gmx_ana_selection_t *sel;
1426
1427             sel = gmx_ana_selcollection_get_selection(d->sc, i);
1428             if (sel->bDynamic)
1429             {
1430                 gmx_fatal(FARGS, "%s does not support dynamic selections",
1431                           ShortProgram());
1432                 return -1;
1433             }
1434         }
1435     }
1436     /* Check that non-atom positions are not provided if not allowed.
1437      * TODO: It would be better to have these checks in the parser. */
1438     if (d->flags & ANA_ONLY_ATOMPOS)
1439     {
1440         for (i = 0; i < d->nanagrps; ++i)
1441         {
1442             gmx_ana_selection_t *sel;
1443
1444             sel = gmx_ana_selcollection_get_selection(d->sc, i + d->nrefgrps);
1445             if (sel->p.m.type != INDEX_ATOM)
1446             {
1447                 gmx_fatal(FARGS, "%s does not support non-atom positions",
1448                           ShortProgram());
1449                 return -1;
1450             }
1451         }
1452     }
1453     /* Create the names array */
1454     snew(d->grpnames, d->ngrps);
1455     for (i = 0; i < d->ngrps; ++i)
1456     {
1457         d->grpnames[i] = gmx_ana_selection_name(d->sel[i]);
1458     }
1459
1460     return 0;
1461 }
1462
1463 /*!
1464  * \param[in,out] d       Trajectory analysis data structure.
1465  * \param[in]     type    Type of covered fractions to calculate.
1466  * \returns       0 on success, a non-zero error code on error.
1467  *
1468  * By default, covered fractions are not calculated.
1469  * If this function is called, the covered fraction calculation is
1470  * initialize to calculate the fractions of type \p type for each selection.
1471  * The function must be called after gmx_ana_init_selections() has been
1472  * called.
1473  *
1474  * For more fine-grained control of the calculation, you can use
1475  * gmx_ana_selection_init_coverfrac(): if you initialize some selections
1476  * this function to something else than CFRAC_NONE before calling
1477  * gmx_ana_init_coverfrac(), these settings are not overwritten.
1478  *
1479  * You only need to call this function if your program needs to have
1480  * information about the covered fractions, e.g., for normalization.
1481  *
1482  * \see gmx_ana_selection_init_coverfrac()
1483  */
1484 int
1485 gmx_ana_init_coverfrac(gmx_ana_traj_t *d, e_coverfrac_t type)
1486 {
1487     int                 g;
1488
1489     if (type == CFRAC_NONE)
1490     {
1491         return 0;
1492     }
1493
1494     for (g = 0; g < d->ngrps; ++g)
1495     {
1496         if (d->sel[g]->cfractype == CFRAC_NONE)
1497         {
1498             gmx_ana_selection_init_coverfrac(d->sel[g], type);
1499         }
1500     }
1501     return 0;
1502 }
1503
1504 /*!
1505  * \param[in] out  Output file.
1506  * \param[in] d    Trajectory analysis data structure.
1507  * \returns   0 on success, a non-zero error code on error.
1508  */
1509 int xvgr_selections(FILE *out, gmx_ana_traj_t *d)
1510 {
1511     xvgr_selcollection(out, d->sc, d->oenv);
1512     return 0;
1513 }
1514
1515 /*!
1516  * \param[in,out] d       Trajectory analysis data structure.
1517  * \returns       0 on success, a non-zero error code on error.
1518  */
1519 static int init_first_frame(gmx_ana_traj_t *d)
1520 {
1521     int                 i;
1522
1523     /* Return if we have already initialized the trajectory */
1524     if (d->fr)
1525     {
1526         return 0;
1527     }
1528
1529     d->frflags |= TRX_NEED_X;
1530
1531     snew(d->fr, 1);
1532
1533     if (d->trjfile)
1534     {
1535         if (!read_first_frame(d->oenv, &d->status, d->trjfile, d->fr, d->frflags))
1536         {
1537             gmx_input("could not read coordinates from trajectory");
1538             return EIO;
1539         }
1540
1541         if (d->top && d->fr->natoms > d->top->atoms.nr)
1542         {
1543             gmx_fatal(FARGS, "Trajectory (%d atoms) does not match topology (%d atoms)",
1544                       d->fr->natoms, d->top->atoms.nr);
1545             return -1;
1546         }
1547         /* check index groups */
1548         for (i = 0; i < d->ngrps; ++i)
1549         {
1550             gmx_ana_index_check(d->sel[i]->g, d->fr->natoms);
1551         }
1552     }
1553     else
1554     {
1555         /* Prepare a frame from topology information */
1556         /* TODO: Initialize more of the fields */
1557         if (d->frflags & (TRX_NEED_V))
1558         {
1559             gmx_impl("Velocity reading from a topology not implemented");
1560             return -1;
1561         }
1562         if (d->frflags & (TRX_NEED_F))
1563         {
1564             gmx_input("Forces cannot be read from a topology");
1565             return -1;
1566         }
1567         d->fr->flags  = d->frflags;
1568         d->fr->natoms = d->top->atoms.nr;
1569         d->fr->bX     = TRUE;
1570         snew(d->fr->x, d->fr->natoms);
1571         memcpy(d->fr->x, d->xtop, sizeof(*d->fr->x)*d->fr->natoms);
1572         d->fr->bBox   = TRUE;
1573         copy_mat(d->boxtop, d->fr->box);
1574     }
1575
1576     set_trxframe_ePBC(d->fr, d->ePBC);
1577
1578     return 0;
1579 }
1580
1581 /*!
1582  * \param[in,out] d       Trajectory analysis data structure.
1583  * \param[out]    fr      First frame in the trajectory.
1584  * \returns       0 on success, a non-zero error code on error.
1585  *
1586  * The pointer stored in \p *fr should not be freed by the caller.
1587  *
1588  * You only need to call this function if your program needs to do some
1589  * initialization for which it requires data from the first frame.
1590  *
1591  * \see gmx_ana_do()
1592  */
1593 int gmx_ana_get_first_frame(gmx_ana_traj_t *d, t_trxframe **fr)
1594 {
1595     int rc;
1596
1597     rc = init_first_frame(d);
1598     if (rc != 0)
1599     {
1600         *fr = NULL;
1601         return rc;
1602     }
1603     *fr = d->fr;
1604     return 0;
1605 }
1606
1607 /*!
1608  * \param[in,out] d   Trajectory analysis data structure.
1609  * \param[in] flags   Combination of flags
1610  *      (currently, there are no flags defined).
1611  * \param[in] analyze Pointer to frame analysis function.
1612  * \param     data    User data to be passed to \p analyze.
1613  * \returns   0 on success, a non-zero error code on error.
1614  *
1615  * This function performs the actual analysis of the trajectory.
1616  * It loops through all the frames in the trajectory, and calls
1617  * \p analyze for each frame to perform the actual analysis.
1618  * Before calling \p analyze, selections are updated (if there are any).
1619  * See gmx_analysisfunc() for description of \p analyze parameters.
1620  *
1621  * This function also calculates the number of frames during the run.
1622  */
1623 int gmx_ana_do(gmx_ana_traj_t *d, int flags, gmx_analysisfunc analyze, void *data)
1624 {
1625     t_pbc               pbc;
1626     t_pbc              *ppbc;
1627     int                 rc;
1628     gmx_rmpbc_t         gpbc=NULL;
1629     
1630     rc = init_first_frame(d);
1631     if (rc != 0)
1632     {
1633         return rc;
1634     }
1635
1636     ppbc = d->bPBC ? &pbc : 0;
1637     if (!d->top)
1638     {
1639         d->bRmPBC = FALSE;
1640     }
1641     if (d->bRmPBC) 
1642     {
1643         gpbc = gmx_rmpbc_init(&d->top->idef,d->ePBC,d->fr->natoms,d->fr->box);
1644     }
1645     d->nframes = 0;
1646     do
1647     {
1648         if (d->bRmPBC)
1649         {
1650             gmx_rmpbc_trxfr(gpbc,d->fr);
1651         }
1652         if (ppbc)
1653         {
1654             set_pbc(&pbc, d->ePBC, d->fr->box);
1655         }
1656
1657         gmx_ana_poscalc_init_frame(d->pcc);
1658         rc = gmx_ana_selcollection_evaluate(d->sc, d->fr, ppbc);
1659         if (rc != 0)
1660         {
1661             close_trj(d->status);
1662             gmx_fatal(FARGS, "selection evaluation failed");
1663             return rc;
1664         }
1665         rc = analyze(d->top, d->fr, ppbc, d->ngrps, d->sel, data);
1666         if (rc != 0)
1667         {
1668             close_trj(d->status);
1669             return rc;
1670         }
1671
1672         d->nframes++;
1673     }
1674     while (d->trjfile && read_next_frame(d->oenv, d->status, d->fr));
1675     if (d->bRmPBC)
1676     {
1677         gmx_rmpbc_done(gpbc);
1678     }
1679     if (d->trjfile)
1680     {
1681         close_trj(d->status);
1682         fprintf(stderr, "Analyzed %d frames, last time %.3f\n",
1683                 d->nframes, d->fr->time);
1684     }
1685     else
1686     {
1687         fprintf(stderr, "Analyzed topology coordinates\n");
1688     }
1689
1690     /* Restore the maximal groups for dynamic selections */
1691     rc = gmx_ana_selcollection_evaluate_fin(d->sc, d->nframes);
1692     if (rc != 0)
1693     {
1694         gmx_fatal(FARGS, "selection evaluation failed");
1695     }
1696
1697     return rc;
1698 }
1699
1700 /*!
1701  * \param[in,out] d       Trajectory analysis data structure.
1702  * \param[out]    nframes Number of frames.
1703  * \returns   0 on success, a non-zero error code on error.
1704  *
1705  * If called before gmx_ana_do(), the behavior is currently undefined.
1706  */
1707 extern int
1708 gmx_ana_get_nframes(gmx_ana_traj_t *d, int *nframes)
1709 {
1710     *nframes = d->nframes;
1711     return 0;
1712 }