/*! * \param[in] sc Selection collection (used for position evaluation). * \param[in] method Method to use for initialization. * \param[in] params Pointer to the first parameter. * \param[in] rpost Reference position type to use (NULL = default). * \returns The created selection element. * * This function handles the creation of a \c t_selelem object for * selection methods that take parameters. */ t_selelem * _gmx_sel_init_method(gmx_ana_selcollection_t *sc, gmx_ana_selmethod_t *method, t_selexpr_param *params, const char *rpost) { t_selelem *root; int rc; root = _gmx_selelem_create(SEL_EXPRESSION); set_method(sc, root, method); /* Process the parameters */ if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root)) { _gmx_selelem_free(root); return NULL; } rc = set_refpos_type(sc->pcc, root, rpost); if (rc != 0) { _gmx_selelem_free(root); return NULL; } return root; }
/*! * \param[in] sc Selection collection (used for position evaluation). * \param[in] method Method to use. * \param[in] nargs Number of arguments for keyword matching. * \param[in] args Pointer to the first argument. * \param[in] rpost Reference position type to use (NULL = default). * \returns The created selection element. * * This function handles the creation of a \c t_selelem object for * selection methods that do not take parameters. */ t_selelem * _gmx_sel_init_keyword(gmx_ana_selcollection_t *sc, gmx_ana_selmethod_t *method, int nargs, t_selexpr_value *args, const char *rpost) { t_selelem *root, *child; t_selexpr_param *params, *param; int rc; if (method->nparams > 0) { gmx_bug("internal error"); return NULL; } root = _gmx_selelem_create(SEL_EXPRESSION); child = root; set_method(sc, child, method); /* Initialize the evaluation of keyword matching if values are provided */ if (nargs > 0) { gmx_ana_selmethod_t *kwmethod; switch (method->type) { case INT_VALUE: kwmethod = &sm_keyword_int; break; case STR_VALUE: kwmethod = &sm_keyword_str; break; default: _gmx_selparser_error("unknown type for keyword selection"); goto on_error; } root = _gmx_selelem_create(SEL_EXPRESSION); set_method(sc, root, kwmethod); params = param = _gmx_selexpr_create_param(NULL); param->nval = 1; param->value = _gmx_selexpr_create_value_expr(child); param = _gmx_selexpr_create_param(NULL); param->nval = nargs; param->value = args; params->next = param; if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root)) { _gmx_selparser_error("error in keyword selection initialization"); goto on_error; } } rc = set_refpos_type(sc->pcc, child, rpost); if (rc != 0) { goto on_error; } return root; /* On error, free all memory and return NULL. */ on_error: _gmx_selelem_free(root); return NULL; }
/*! * \param[in] sc Selection collection. * \param[in] left Selection element for the left hand side. * \param[in] right Selection element for the right hand side. * \param[in] cmpop String representation of the comparison operator. * \returns The created selection element. * * This function handles the creation of a \c t_selelem object for * comparison expressions. */ t_selelem * _gmx_sel_init_comparison(gmx_ana_selcollection_t *sc, t_selelem *left, t_selelem *right, char *cmpop) { t_selelem *sel; t_selexpr_param *params, *param; int rc; sel = _gmx_selelem_create(SEL_EXPRESSION); set_method(sc, sel, &sm_compare); /* Create the parameter for the left expression */ params = param = _gmx_selexpr_create_param(left->v.type == INT_VALUE ? "int1" : "real1"); param->nval = 1; param->value = _gmx_selexpr_create_value_expr(left); /* Create the parameter for the right expression */ param = _gmx_selexpr_create_param(right->v.type == INT_VALUE ? "int2" : "real2"); param->nval = 1; param->value = _gmx_selexpr_create_value_expr(right); params->next = param; /* Create the parameter for the operator */ param = _gmx_selexpr_create_param("op"); param->nval = 1; param->value = _gmx_selexpr_create_value(STR_VALUE); param->value->u.s = cmpop; params->next->next = param; if (!_gmx_sel_parse_params(params, sel->u.expr.method->nparams, sel->u.expr.method->param, sel)) { _gmx_selparser_error("error in comparison initialization"); _gmx_selelem_free(sel); return NULL; } return sel; }
/*! * \param[out] selp Pointer to receive a pointer to the created selection * element (set to NULL on error). * \param[in] method Keyword selection method to evaluate. * \param[in] param Parameter that gives the group to evaluate \p method in. * \param[in] scanner Scanner data structure. * \returns 0 on success, non-zero error code on error. * * Creates a \ref SEL_EXPRESSION selection element (pointer put in \c *selp) * that evaluates the keyword method given by \p method in the group given by * \p param. */ int _gmx_sel_init_keyword_evaluator(t_selelem **selp, gmx_ana_selmethod_t *method, t_selexpr_param *param, void *scanner) { t_selelem *sel; t_methoddata_kweval *data; gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner); char buf[1024]; sprintf(buf, "In evaluation of '%s'", method->name); gmx::MessageStringContext context(errors, buf); if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) || method->outinit || method->pupdate) { _gmx_selexpr_free_params(param); GMX_ERROR(gmx::eeInternalError, "Unsupported keyword method for arbitrary group evaluation"); } *selp = NULL; sel = _gmx_selelem_create(SEL_EXPRESSION); _gmx_selelem_set_method(sel, method, scanner); snew(data, 1); data->kwmethod = sel->u.expr.method; data->kwmdata = sel->u.expr.mdata; gmx_ana_index_clear(&data->g); snew(sel->u.expr.method, 1); memcpy(sel->u.expr.method, data->kwmethod, sizeof(gmx_ana_selmethod_t)); sel->u.expr.method->flags |= SMETH_VARNUMVAL; sel->u.expr.method->init_data = NULL; sel->u.expr.method->set_poscoll = NULL; sel->u.expr.method->init = method->init ? &init_kweval : NULL; sel->u.expr.method->outinit = &init_output_kweval; sel->u.expr.method->free = &free_data_kweval; sel->u.expr.method->init_frame = method->init_frame ? &init_frame_kweval : NULL; sel->u.expr.method->update = &evaluate_kweval; sel->u.expr.method->pupdate = NULL; sel->u.expr.method->nparams = asize(smparams_kweval); sel->u.expr.method->param = smparams_kweval; _gmx_selelem_init_method_params(sel, scanner); sel->u.expr.mdata = data; sel->u.expr.method->param[0].val.u.g = &data->g; sfree(param->name); param->name = NULL; if (!_gmx_sel_parse_params(param, sel->u.expr.method->nparams, sel->u.expr.method->param, sel, scanner)) { _gmx_selelem_free(sel); return -1; } *selp = sel; return 0; }
/*! * \param[in] sc Selection collection. * \param[in] method Modifier to use for initialization. * \param[in] params Pointer to the first parameter. * \param[in] sel Selection element that the modifier should act on. * \returns The created selection element. * * This function handles the creation of a \c t_selelem object for * selection modifiers. */ t_selelem * _gmx_sel_init_modifier(gmx_ana_selcollection_t *sc, gmx_ana_selmethod_t *method, t_selexpr_param *params, t_selelem *sel) { t_selelem *root; t_selelem *mod; t_selexpr_param *vparam; int i; mod = _gmx_selelem_create(SEL_MODIFIER); set_method(sc, mod, method); if (method->type == NO_VALUE) { t_selelem *child; child = sel; while (child->next) { child = child->next; } child->next = mod; root = sel; } else { vparam = _gmx_selexpr_create_param(NULL); vparam->nval = 1; vparam->value = _gmx_selexpr_create_value_expr(sel); vparam->next = params; params = vparam; root = mod; } /* Process the parameters */ if (!_gmx_sel_parse_params(params, mod->u.expr.method->nparams, mod->u.expr.method->param, mod)) { if (mod->child != sel) { _gmx_selelem_free(sel); } _gmx_selelem_free(mod); return NULL; } return root; }
/*! * \param[in] sc Selection collection. * \param[in] expr Input selection element for the position calculation. * \param[in] type Reference position type or NULL for default. * \param[in] bSelPos Whether the element evaluates the positions for a * selection. * \returns The created selection element. * * This function handles the creation of a \c t_selelem object for * evaluation of reference positions. */ t_selelem * _gmx_sel_init_position(gmx_ana_selcollection_t *sc, t_selelem *expr, const char *type, bool bSelPos) { t_selelem *root; t_selexpr_param *params; int flags; root = _gmx_selelem_create(SEL_EXPRESSION); set_method(sc, root, &sm_keyword_pos); /* Selections use largest static group by default, while * reference positions use the whole residue/molecule. */ flags = bSelPos ? POS_COMPLMAX : POS_COMPLWHOLE; if (bSelPos && sc->bMaskOnly) { flags |= POS_MASKONLY; } /* FIXME: It would be better not to have the string here hardcoded. */ if (type[0] != 'a') { root->u.expr.method->flags |= SMETH_REQTOP; } _gmx_selelem_set_kwpos_type(type, flags, root->u.expr.mdata); /* Create the parameters for the parameter parser. */ params = _gmx_selexpr_create_param(NULL); params->nval = 1; params->value = _gmx_selexpr_create_value_expr(expr); /* Parse the parameters. */ if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root)) { _gmx_selelem_free(root); return NULL; } return root; }