/*! \brief * Adds the position symbols to the symbol list. * * \param[in,out] tab Symbol table to which the symbols are added. */ static void add_position_symbols(gmx_sel_symtab_t *tab) { const char **postypes; gmx_sel_symrec_t *sym; gmx_sel_symrec_t *last; int i; postypes = gmx_ana_poscalc_create_type_enum(TRUE); last = tab->first; while (last && last->next) { last = last->next; } for (i = 1; postypes[i] != NULL; ++i) { snew(sym, 1); sym->name = strdup(postypes[i]); sym->type = SYMBOL_POS; sym->next = NULL; if (last) { last->next = sym; } else { tab->first = sym; } last = sym; } sfree(postypes); }
Options * SelectionCollection::initOptions() { static const char * const debug_levels[] = {"no", "basic", "compile", "eval", "full", NULL}; /* static const char * const desc[] = { "This program supports selections in addition to traditional", "index files. Use [TT]-select help[tt] for additional information,", "or type 'help' in the selection prompt.", NULL, }; options.setDescription(desc); */ Options &options = _impl->_options; const char **postypes = gmx_ana_poscalc_create_type_enum(true); if (postypes == NULL) { // TODO: Use an out-of-memory exception here GMX_THROW(InternalError("Could not create position calculation enum")); } options.addOption(StringOption("selrpos").enumValue(postypes + 1) .store(&_impl->_rpost).defaultValue(postypes[1]) .description("Selection reference positions")); options.addOption(StringOption("seltype").enumValue(postypes + 1) .store(&_impl->_spost).defaultValue(postypes[1]) .description("Default selection output positions")); GMX_RELEASE_ASSERT(_impl->_debugLevel >= 0 && _impl->_debugLevel <= 4, "Debug level out of range"); options.addOption(StringOption("seldebug").hidden(_impl->_debugLevel == 0) .enumValue(debug_levels) .defaultValue(debug_levels[_impl->_debugLevel]) .storeEnumIndex(&_impl->_debugLevel) .description("Print out selection trees for debugging")); sfree(postypes); return &_impl->_options; }
/*! * \param[in,out] d Trajectory analysis data structure. * \returns 0 on success, a non-zero error code on error. * * This function should be called first in the analysis program, much in * the same way as parse_common_args() in traditional Gromacs analysis * programs. It adds some command-line arguments of its own, and uses * parse_common_args() to parse the command-line arguments. * It also loads topology information if required or if a topology is * provided on the command line. * Selection handling is also initialized if it is enabled and * the user has selected it on the command line. * * The rest of the parameters are passed on to the Gromacs routine * parse_common_args(), and the use of this function should be identical * to parse_common_args(), with the exception that for \p pca_flags, * \p PCA_CAN_TIME and \p PCA_BE_NICE flags are automatically added. * \param argc * \param argv * \param pca_flags * \param nfile * \param fnm * \param npargs * \param pa * \param ndesc * \param desc * \param nbugs * \param bugs */ int parse_trjana_args(gmx_ana_traj_t *d, int *argc, char *argv[], unsigned long pca_flags, int nfile, t_filenm fnm[], int npargs, t_pargs *pa, int ndesc, const char **desc, int nbugs, const char **bugs) { t_filenm *all_fnm = NULL; int max_fnm, nfall; int *fnm_map; t_pargs *all_pa = NULL; int max_pa, npall; size_t i; int k; int rc; t_filenm def_fnm[] = { {efTRX, NULL, NULL, ffREAD}, {efTPS, NULL, NULL, ffREAD}, {efDAT, "-sf", "selection", ffOPTRD}, {efNDX, NULL, NULL, ffOPTRD}, }; bool bPBC = TRUE; t_pargs pbc_pa[] = { {"-pbc", FALSE, etBOOL, {&bPBC}, "Use periodic boundary conditions for distance calculation"}, }; bool bRmPBC = TRUE; t_pargs rmpbc_pa[] = { {"-rmpbc", FALSE, etBOOL, {&bRmPBC}, "Make molecules whole for each frame"}, }; char *selection = NULL; const char **rpost = NULL; bool bSelDump = FALSE; t_pargs sel_pa[] = { {"-select", FALSE, etSTR, {&selection}, "Selection string"}, {"-seldebug", FALSE, etBOOL, {&bSelDump}, "HIDDENPrint out the parsed and compiled selection trees"}, }; t_pargs dsel_pa[] = { {"-selrpos", FALSE, etENUM, {NULL}, "Selection reference position"}, }; const char **spost = NULL; t_pargs selpt_pa[] = { {"-seltype", FALSE, etENUM, {NULL}, "Default analysis positions"}, }; #define MAX_PA asize(sel_pa)+asize(dsel_pa)+5 if (d->nrefgrps < 0) { gmx_incons("number of reference groups is negative"); return EINVAL; } if (d->flags & ANA_DEBUG_SELECTION) { bSelDump = TRUE; } rpost = gmx_ana_poscalc_create_type_enum(!(d->flags & ANA_REQUIRE_WHOLE)); if (rpost == NULL) { return ENOMEM; } spost = gmx_ana_poscalc_create_type_enum(TRUE); if (spost == NULL) { sfree(rpost); return ENOMEM; } /* Construct the file name argument array */ max_fnm = nfile + asize(def_fnm); snew(all_fnm, max_fnm); nfall = 0; if (!(d->flags & ANA_REQUIRE_TOP)) { def_fnm[1].flag |= ffOPT; } snew(fnm_map, nfile); for (k = 0; k < nfile; ++k) { fnm_map[k] = -1; } for (i = 0; i < asize(def_fnm); ++i) { for (k = 0; k < nfile; ++k) { if (fnm_map[k] == -1 && def_fnm[i].opt == NULL && fnm[k].ftp == def_fnm[i].ftp) { break; } } if (k < nfile) { fnm_map[k] = nfall; nfall = add_fnmarg(nfall, all_fnm, &(fnm[k])); } else { nfall = add_fnmarg(nfall, all_fnm, &(def_fnm[i])); } } for (k = 0; k < nfile; ++k) { if (fnm_map[k] == -1) { fnm_map[k] = nfall; nfall = add_fnmarg(nfall, all_fnm, &(fnm[k])); } } /* Construct the argument array */ max_pa = npargs + MAX_PA; snew(all_pa, max_pa); npall = 0; if (!(d->flags & ANA_NOUSER_RMPBC)) { for (i = 0; i < asize(rmpbc_pa); ++i) { npall = add_parg(npall, all_pa, &(rmpbc_pa[i])); } } if (!(d->flags & ANA_NOUSER_PBC)) { for (i = 0; i < asize(pbc_pa); ++i) { npall = add_parg(npall, all_pa, &(pbc_pa[i])); } } for (i = 0; i < asize(sel_pa); ++i) { npall = add_parg(npall, all_pa, &(sel_pa[i])); } if (!(d->flags & ANA_NO_DYNSEL)) { dsel_pa[0].u.c = rpost; for (i = 0; i < asize(dsel_pa); ++i) { npall = add_parg(npall, all_pa, &(dsel_pa[i])); } } if (!(d->flags & ANA_ONLY_ATOMPOS)) { selpt_pa[0].u.c = spost; for (i = 0; i < asize(selpt_pa); ++i) { npall = add_parg(npall, all_pa, &(selpt_pa[i])); } } for (k = 0; k < npargs; ++k) { npall = add_parg(npall, all_pa, &(pa[k])); } pca_flags |= PCA_CAN_TIME | PCA_BE_NICE; parse_common_args(argc, argv, pca_flags, nfall, all_fnm, npall, all_pa, ndesc, desc, nbugs, bugs); /* Copy the results back */ for (k = 0; k < nfile; ++k) { memcpy(&(fnm[k]), &(all_fnm[fnm_map[k]]), sizeof(fnm[k])); } for (i = 0, k = npall - npargs; i < (size_t)npargs; ++i, ++k) { memcpy(&(pa[i]), &(all_pa[k]), sizeof(pa[i])); } d->trjfile = ftp2fn(efTRX, nfall, all_fnm); d->topfile = ftp2fn_null(efTPS, nfall, all_fnm); d->topfile_notnull = ftp2fn(efTPS, nfall, all_fnm); d->ndxfile = ftp2fn_null(efNDX, nfall, all_fnm); if (!(d->flags & ANA_NOUSER_RMPBC)) { d->bRmPBC = bRmPBC; } if (!(d->flags & ANA_NOUSER_PBC)) { d->bPBC = bPBC; } d->selection = selection; d->selfile = opt2fn_null("-sf", nfall, all_fnm); sfree(all_fnm); sfree(fnm_map); sfree(all_pa); if (!(d->flags & ANA_NO_DYNSEL)) { gmx_ana_selcollection_set_refpostype(d->sc, rpost[0]); } else { gmx_ana_selcollection_set_refpostype(d->sc, rpost[1]); } sfree(rpost); if (bSelDump) { d->flags |= ANA_DEBUG_SELECTION; } else { d->flags &= ~ANA_DEBUG_SELECTION; } if (!(d->flags & ANA_ONLY_ATOMPOS)) { gmx_ana_selcollection_set_outpostype(d->sc, spost[0], d->flags & ANA_USE_POSMASK); } else { gmx_ana_selcollection_set_outpostype(d->sc, spost[1], d->flags & ANA_USE_POSMASK); } sfree(spost); /* Load the topology if so requested. */ rc = load_topology(d, (d->flags & ANA_REQUIRE_TOP)); if (rc != 0) { return rc; } /* Initialize the selections/index groups */ if (!(d->flags & ANA_USER_SELINIT)) { rc = gmx_ana_init_selections(d); } return rc; }