void TrajectoryAnalysisRunnerCommon::doneIndexGroups(SelectionCollection *selections) { if (impl_->grps_ != NULL) { selections->setIndexGroups(NULL); gmx_ana_indexgrps_free(impl_->grps_); impl_->grps_ = NULL; } }
TrajectoryAnalysisRunnerCommon::Impl::~Impl() { if (grps_ != NULL) { gmx_ana_indexgrps_free(grps_); } finishTrajectory(); if (fr) { // There doesn't seem to be a function for freeing frame data sfree(fr->x); sfree(fr->v); sfree(fr->f); sfree(fr); } if (oenv_ != NULL) { output_env_done(oenv_); } }
/*! * \param[in,out] d Trajectory analysis data structure. * \returns 0 on success, a non-zero error code on error. * * Initializes the selection data in \c gmx_ana_traj_t based on * the selection options and/or index files provided on the command line. * * This function is called automatically by parse_trjana_args() and should * not be called directly unless \ref ANA_USER_SELINIT is specified. * * \see ANA_USER_SELINIT */ int gmx_ana_init_selections(gmx_ana_traj_t *d) { int rc; int i; int nr; gmx_ana_indexgrps_t *grps; int natoms; bool bStdIn; bool bInteractive; bool bOk; if (d->sel) { gmx_call("init_selections called more than once\n" "perhaps you forgot ANA_USER_SELINIT"); return -1; } /* Check if we need some information from the topology */ if (gmx_ana_selcollection_requires_top(d->sc)) { rc = load_topology(d, TRUE); if (rc != 0) { return rc; } } /* Load the topology and init the index groups */ gmx_ana_indexgrps_init(&grps, d->top, d->ndxfile); /* Parse the selection */ rc = gmx_ana_selmethod_register_defaults(d->sc); if (rc != 0) { gmx_fatal(FARGS, "default selection method registration failed"); return rc; } bStdIn = (d->selfile && d->selfile[0] == '-' && d->selfile[1] == 0) || (d->selection && d->selection[0] == 0) || (!d->selfile && !d->selection); bInteractive = bStdIn && isatty(fileno(stdin)); if (bStdIn && bInteractive) { /* Parse from stdin */ /* First we parse the reference groups if there are any */ if (d->nrefgrps > 0) { fprintf(stderr, "\nSpecify "); if (d->nrefgrps == 1) { fprintf(stderr, "a reference selection"); } else { fprintf(stderr, "%d reference selections", d->nrefgrps); } fprintf(stderr, ":\n"); fprintf(stderr, "(one selection per line, use \\ for line continuation)\n"); rc = gmx_ana_selcollection_parse_stdin(d->sc, d->nrefgrps, grps, TRUE); nr = gmx_ana_selcollection_get_count(d->sc); if (rc != 0 || nr != d->nrefgrps) { gmx_ana_traj_free(d); gmx_input("unrecoverable error in selection parsing"); return rc; } } /* Then, we parse the analysis groups */ fprintf(stderr, "\nSpecify "); if (d->nanagrps == 1) { fprintf(stderr, "a selection"); } else if (d->nanagrps == -1) { fprintf(stderr, "any number of selections"); } else { fprintf(stderr, "%d selections", d->nanagrps); } fprintf(stderr, " for analysis:\n"); fprintf(stderr, "(one selection per line, use \\ for line continuation%s)\n", d->nanagrps == -1 ? ", Ctrl-D to end" : ""); rc = gmx_ana_selcollection_parse_stdin(d->sc, d->nanagrps, grps, TRUE); fprintf(stderr, "\n"); } else if (bStdIn) { rc = gmx_ana_selcollection_parse_stdin(d->sc, -1, grps, FALSE); } else if (d->selection) { rc = gmx_ana_selcollection_parse_str(d->sc, d->selection, grps); } else { rc = gmx_ana_selcollection_parse_file(d->sc, d->selfile, grps); } gmx_ana_indexgrps_free(grps); if (rc != 0) { /* Free memory for memory leak checking */ gmx_ana_traj_free(d); gmx_input("selection(s) could not be parsed"); return rc; } /* Check the number of groups */ nr = gmx_ana_selcollection_get_count(d->sc); if (nr <= d->nrefgrps) { gmx_input("selection does not specify enough index groups"); return -1; } if (d->nanagrps <= 0) { d->nanagrps = nr - d->nrefgrps; } else if (nr != d->nrefgrps + d->nanagrps) { gmx_input("selection does not specify the correct number of index groups"); return -1; } if (d->flags & ANA_DEBUG_SELECTION) { gmx_ana_selcollection_print_tree(stderr, d->sc, FALSE); } if (gmx_ana_selcollection_requires_top(d->sc)) { rc = load_topology(d, TRUE); if (rc != 0) { return rc; } } if (d->top) { natoms = -1; } else { rc = init_first_frame(d); if (rc != 0) { return rc; } natoms = d->fr->natoms; } gmx_ana_selcollection_set_topology(d->sc, d->top, natoms); rc = gmx_ana_selcollection_compile(d->sc); if (rc != 0) { /* Free memory for memory leak checking */ gmx_ana_traj_free(d); gmx_input("selection could not be compiled"); return rc; } /* Create the selection array */ d->ngrps = gmx_ana_selcollection_get_count(d->sc); if (!(d->flags & ANA_USE_FULLGRPS)) { d->ngrps -= d->nrefgrps; } snew(d->sel, d->ngrps); for (i = 0; i < d->ngrps; ++i) { if (d->flags & ANA_USE_FULLGRPS) { d->sel[i] = gmx_ana_selcollection_get_selection(d->sc, i); } else { d->sel[i] = gmx_ana_selcollection_get_selection(d->sc, i + d->nrefgrps); } } if (d->flags & ANA_DEBUG_SELECTION) { fprintf(stderr, "\n"); gmx_ana_selcollection_print_tree(stderr, d->sc, FALSE); fprintf(stderr, "\n"); gmx_ana_poscalc_coll_print_tree(stderr, d->pcc); fprintf(stderr, "\n"); } /* Initialize the position evaluation */ gmx_ana_poscalc_init_eval(d->pcc); if (d->flags & ANA_DEBUG_SELECTION) { gmx_ana_poscalc_coll_print_tree(stderr, d->pcc); fprintf(stderr, "\n"); } /* Check that dynamic selections are not provided if not allowed */ if (d->flags & ANA_NO_DYNSEL) { for (i = 0; i < d->nrefgrps + d->nanagrps; ++i) { gmx_ana_selection_t *sel; sel = gmx_ana_selcollection_get_selection(d->sc, i); if (sel->bDynamic) { gmx_fatal(FARGS, "%s does not support dynamic selections", ShortProgram()); return -1; } } } /* Check that non-atom positions are not provided if not allowed. * TODO: It would be better to have these checks in the parser. */ if (d->flags & ANA_ONLY_ATOMPOS) { for (i = 0; i < d->nanagrps; ++i) { gmx_ana_selection_t *sel; sel = gmx_ana_selcollection_get_selection(d->sc, i + d->nrefgrps); if (sel->p.m.type != INDEX_ATOM) { gmx_fatal(FARGS, "%s does not support non-atom positions", ShortProgram()); return -1; } } } /* Create the names array */ snew(d->grpnames, d->ngrps); for (i = 0; i < d->ngrps; ++i) { d->grpnames[i] = gmx_ana_selection_name(d->sel[i]); } return 0; }