Exemple #1
0
void read_adressparams(int *ninp_p,t_inpfile **inp_p,t_adress *adress, warninp_t wi)
{
  int     nadress_refs,i;
  const char *tmp;
  char    *ptr1[MAXPTR];


  int    ninp;
  t_inpfile *inp;

  ninp   = *ninp_p;
  inp    = *inp_p;

  EETYPE("adress_type",                adress->type,         eAdresstype_names);
  RTYPE ("adress_const_wf",            adress->const_wf,     1);
  RTYPE ("adress_ex_width",            adress->ex_width,     0);
  RTYPE ("adress_hy_width",            adress->hy_width,     0);
  RTYPE ("adress_ex_forcecap",         adress->ex_forcecap,     0);
  EETYPE("adress_interface_correction",adress->icor,         eAdressICtype_names);
  EETYPE("adress_site",                adress->site,         eAdressSITEtype_names);
  STYPE ("adress_reference_coords",    adress_refs,             NULL);
  STYPE ("adress_tf_grp_names",        adress_tf_grp_names,     NULL);
  STYPE ("adress_cg_grp_names",        adress_cg_grp_names,     NULL);
  EETYPE("adress_do_hybridpairs",      adress->do_hybridpairs, yesno_names);
  
  nadress_refs = str_nelem(adress_refs,MAXPTR,ptr1);

  for(i=0; (i<nadress_refs); i++) /*read vector components*/
    adress->refs[i]=strtod(ptr1[i],NULL);
  for( ;(i<DIM); i++) /*remaining undefined components of the vector set to zero*/
    adress->refs[i]=0;

  *ninp_p   = ninp;
  *inp_p    = inp;
}
Exemple #2
0
void get_input(const char *membed_input, real *xy_fac, real *xy_max, real *z_fac, real *z_max,
		int *it_xy, int *it_z, real *probe_rad, int *low_up_rm, int *maxwarn, 
		int *pieces, gmx_bool *bALLOW_ASYMMETRY)
{
    warninp_t wi;
    t_inpfile *inp;
    int       ninp;

    wi = init_warning(TRUE,0);
    
    inp = read_inpfile(membed_input, &ninp, NULL, wi);
    ITYPE ("nxy", *it_xy, 1000);
    ITYPE ("nz", *it_z, 0);
    RTYPE ("xyinit", *xy_fac, 0.5);
    RTYPE ("xyend", *xy_max, 1.0);
    RTYPE ("zinit", *z_fac, 1.0);
    RTYPE ("zend", *z_max, 1.0);
    RTYPE ("rad", *probe_rad, 0.22);
    ITYPE ("ndiff", *low_up_rm, 0);
    ITYPE ("maxwarn", *maxwarn, 0);
    ITYPE ("pieces", *pieces, 1);
    EETYPE("asymmetry", *bALLOW_ASYMMETRY, yesno_names);
 
    write_inpfile(membed_input,ninp,inp,FALSE,wi);
}
Exemple #3
0
int ReadInput	(char *fnMdp, gmx_bool *bPolar, gmx_bool *bAPolar, t_PolKey *PolKey, t_APolKey *APolKey)	{
	warninp_t wi;
	gmx_bool bAllowWarnings=FALSE;
	int maxwarning = 99;
	t_inpfile *inp;
	int ninp;
	const char *tmp;


	wi = init_warning(bAllowWarnings,maxwarning);
	inp = read_inpfile(fnMdp, &ninp, wi);

	char *ptr[MAXPTR];
	int n;

	//To check for polar solvation calculation
	STYPE ("polar",                 polar,                  NULL);
	n= str_nelem(polar,MAXPTR,ptr);
	if ( (n>1) || ((strcmp(ptr[0],"yes")!=0) && (strcmp(ptr[0],"no")!=0)) )
		gmx_fatal(FARGS, "Polar should be yes or no\n");
	if(strcmp(ptr[0],"yes")==0)
		*bPolar = TRUE;

	//To check for APolar calculation
	STYPE ("apolar",               apolar,           NULL);
	n= str_nelem(apolar,MAXPTR,ptr);
	if ( (n>1) || ((strcmp(ptr[0],"yes")!=0) && (strcmp(ptr[0],"no")!=0)) )
		gmx_fatal(FARGS, "Polar should be yes or no\n");
	if(strcmp(ptr[0],"yes")==0)
		*bAPolar = TRUE;


	if(*bPolar)
	{
		//Psize keywords
		RTYPE ("cfac", 			PolKey->cfac, 		2);
		RTYPE ("gridspace", 	PolKey->gridspace, 	0.5);
		RTYPE ("gmemceil", 		PolKey->gmemceil, 	400);
		RTYPE ("fadd",			PolKey->fadd, 		20);
		RTYPE ("ofrac",			PolKey->ofrac, 		0.1);

		//Polar Keywords
		EETYPE("mg-type",       PolKey->mg_type,    mg_words);
		RTYPE ("pcharge",       PolKey->pcharge,    	0);
		RTYPE ("ncharge",   	PolKey->ncharge,    	0);
		RTYPE ("prad", 	 	 	PolKey->prad,    	0);
		RTYPE ("nrad",   		PolKey->nrad,    	0);
		RTYPE ("pconc",   		PolKey->pconc,    	0);
		RTYPE ("nconc",   		PolKey->nconc,    	0);
		RTYPE ("pdie",   		PolKey->pdie,    	4);
		RTYPE ("sdie",   		PolKey->sdie,    	78.4);
		RTYPE ("vdie",   		PolKey->vdie,    	1);
		RTYPE ("srad",   		PolKey->srad,    	1.4);
		RTYPE ("swin",   		PolKey->swin,    	0.30);
		RTYPE ("sdens",   		PolKey->sdens,    	10);
		RTYPE ("temp",   		PolKey->temp,    	300);
		EETYPE("srfm",			PolKey->srfm, 		srfm_words);
		EETYPE("chgm",			PolKey->chgm,    	chgm_words);
		EETYPE("bcfl",			PolKey->bcfl,    	bcfl_words);
		EETYPE("PBsolver",		PolKey->pbsolver,   	PBsolver);
	}

	if (*bAPolar)
	{
		//APolar Keywords
		RTYPE ("gamma",         APolKey->gamma,           0.030096);
		RTYPE ("sasconst",     APolKey->sasaconst,           0.0);
		RTYPE ("sasrad",        APolKey->sasrad,          1.4);

		RTYPE ("press",         APolKey->press,           0.0);
		RTYPE ("savconst",      APolKey->savconst,        0.0);
		RTYPE ("savrad",        APolKey->savrad,          1.4);

		APolKey->bWCA = FALSE;
		STYPE("WCA",               wca,           NULL);
		n= str_nelem(wca,MAXPTR,ptr);
		if ( (n>1) || ((strcmp(ptr[0],"yes")!=0) && (strcmp(ptr[0],"no")!=0)) )
			gmx_fatal(FARGS, "Polar should be yes or no\n");
		if(strcmp(ptr[0],"yes")==0)
			APolKey->bWCA = TRUE;

		RTYPE ("wcarad",        APolKey->wcarad,          1.4);
		RTYPE ("bconc",         APolKey->bconc,          0.033428);
		RTYPE ("dpos",          APolKey->dpos,           0.05);
		RTYPE ("APsdens",       APolKey->sdens,          200);
		STYPE ("grid",          grid,                    NULL);
		EETYPE("APsrfm",        APolKey->srfm,          APsrfm_words);
		RTYPE ("APswin",        APolKey->swin,          0.2);
		RTYPE ("APtemp",        APolKey->temp,          300);

		n= str_nelem(grid,MAXPTR,ptr);
		if ((n<3) || (n>3))
			gmx_fatal(FARGS, "Number of grid point should be three\n");
		APolKey->grid[0] = strtod(ptr[0],NULL);
		APolKey->grid[1] = strtod(ptr[1],NULL);
		APolKey->grid[2] = strtod(ptr[2],NULL);
	}
	return 0;
}
void get_params(char *mpin,char *mpout,t_psrec *psr)
{
  static const char *bools[BOOL_NR+1]  = { "no", "yes", NULL };
  /* this must correspond to t_rgb *linecolors[] below */
  static const char *colors[] = { "none", "black", "white", NULL };
  t_inpfile *inp;
  char      *tmp;
  int       ninp=0;
  
  if (mpin)
    inp = read_inpfile(mpin,&ninp);
  else
    inp = NULL;
  ETYPE("black&white",    psr->bw,             bools);
  RTYPE("linewidth",      psr->linewidth,      1.0);
  STYPE("titlefont",      psr->titfont,        "Helvetica");
  RTYPE("titlefontsize",  psr->titfontsize,    20.0);
  ETYPE("legend",         psr->legend,         bools);
  STYPE("legendfont",     psr->legfont,        psr->titfont);
  STYPE("legendlabel",    psr->leglabel,       "");
  STYPE("legend2label",   psr->leg2label,      psr->leglabel);
  RTYPE("legendfontsize", psr->legfontsize,    14.0);
  RTYPE("xbox",           psr->xboxsize,       0.0);
  RTYPE("ybox",           psr->yboxsize,       0.0);
  RTYPE("matrixspacing",  psr->boxspacing,     20.0);
  RTYPE("xoffset",        psr->xoffs,          0.0);
  RTYPE("yoffset",        psr->yoffs,          psr->xoffs);
  RTYPE("boxlinewidth",   psr->boxlinewidth,   psr->linewidth);
  RTYPE("ticklinewidth",  psr->ticklinewidth,  psr->linewidth);
  RTYPE("zerolinewidth",  psr->zerolinewidth,  psr->ticklinewidth);
  ETYPE("x-lineat0value", psr->X.lineatzero,   colors);
  RTYPE("x-major",        psr->X.major,        NOTSET);
  RTYPE("x-minor",        psr->X.minor,        NOTSET);
  RTYPE("x-firstmajor",   psr->X.offset,       0.0);
  ETYPE("x-majorat0",     psr->X.first,        bools);
  RTYPE("x-majorticklen", psr->X.majorticklen, 8.0);
  RTYPE("x-minorticklen", psr->X.minorticklen, 4.0);
  STYPE("x-label",        psr->X.label,        "");
  RTYPE("x-fontsize",     psr->X.fontsize,     16.0);
  STYPE("x-font",         psr->X.font,         psr->titfont);
  RTYPE("x-tickfontsize", psr->X.tickfontsize, 10.0);
  STYPE("x-tickfont",     psr->X.tickfont,     psr->X.font);
  ETYPE("y-lineat0value", psr->Y.lineatzero,   colors);
  RTYPE("y-major",        psr->Y.major,        psr->X.major);
  RTYPE("y-minor",        psr->Y.minor,        psr->X.minor);
  RTYPE("y-firstmajor",   psr->Y.offset,       psr->X.offset);
  ETYPE("y-majorat0",     psr->Y.first,        bools);
  RTYPE("y-majorticklen", psr->Y.majorticklen, psr->X.majorticklen);
  RTYPE("y-minorticklen", psr->Y.minorticklen, psr->X.minorticklen);
  STYPE("y-label",        psr->Y.label,        psr->X.label);
  RTYPE("y-fontsize",     psr->Y.fontsize,     psr->X.fontsize);
  STYPE("y-font",         psr->Y.font,         psr->X.font);
  RTYPE("y-tickfontsize", psr->Y.tickfontsize, psr->X.tickfontsize);
  STYPE("y-tickfont",     psr->Y.tickfont,     psr->Y.font);
  if (mpout)
    write_inpfile(mpout,ninp,inp,TRUE);
}
Exemple #5
0
/*! \brief
 * Read parameters of an AWH bias dimension.
 *
 * \param[in,out] ninp_p     Number of read input file entries.
 * \param[in,out] inp_p      Input file entries.
 * \param[in] prefix         Prefix for dimension parameters.
 * \param[in,out] dimParams  AWH dimensional parameters.
 * \param[in] pull_params    Pull parameters.
 * \param[in,out] wi         Struct for bookeeping warnings.
 * \param[in] bComment       True if comments should be printed.
 */
static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
                          AwhDimParams *dimParams, const pull_params_t *pull_params,
                          warninp_t wi, bool bComment)
{
    char       warningmsg[STRLEN];

    int        ninp = *ninp_p;
    t_inpfile *inp  = *inp_p;

    if (bComment)
    {
        CTYPE("The provider of the reaction coordinate, currently only pull is supported");
    }
    char opt[STRLEN];
    sprintf(opt, "%s-coord-provider", prefix);
    EETYPE(opt, dimParams->eCoordProvider, eawhcoordprovider_names);

    if (bComment)
    {
        CTYPE("The coordinate index for this dimension");
    }
    sprintf(opt, "%s-coord-index", prefix);
    int coordIndexInput;
    ITYPE(opt, coordIndexInput, 1);
    if (coordIndexInput <  1)
    {
        gmx_fatal(FARGS, "Failed to read a valid coordinate index for %s. "
                  "Note that the pull coordinate indexing starts at 1.", opt);
    }

    /* The pull coordinate indices start at 1 in the input file, at 0 internally */
    dimParams->coordIndex = coordIndexInput - 1;

    /* The pull settings need to be consistent with the AWH settings */
    if (!(pull_params->coord[dimParams->coordIndex].eType == epullEXTERNAL) )
    {
        gmx_fatal(FARGS, "AWH biasing can only be  applied to pull type %s",
                  EPULLTYPE(epullEXTERNAL));
    }

    if (dimParams->coordIndex >= pull_params->ncoord)
    {
        gmx_fatal(FARGS, "The given AWH coordinate index (%d) is larger than the number of pull coordinates (%d)",
                  coordIndexInput, pull_params->ncoord);
    }
    if (pull_params->coord[dimParams->coordIndex].rate != 0)
    {
        sprintf(warningmsg, "Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate", coordIndexInput, pull_params->coord[dimParams->coordIndex].rate);
        warning_error(wi, warningmsg);
    }

    /* Grid params for each axis */
    int eGeom = pull_params->coord[dimParams->coordIndex].eGeom;

    if (bComment)
    {
        CTYPE("Start and end values for each coordinate dimension");
    }

    sprintf(opt, "%s-start", prefix);
    RTYPE(opt, dimParams->origin, 0.);

    sprintf(opt, "%s-end", prefix);
    RTYPE(opt, dimParams->end, 0.);

    if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS))
    {
        sprintf(warningmsg, "The given interval length given by %s-start (%g) and %s-end (%g) is zero. "
                "This will result in only one point along this axis in the coordinate value grid.",
                prefix, dimParams->origin, prefix, dimParams->end);
        warning(wi, warningmsg);
    }
    /* Check that the requested interval is in allowed range */
    if (eGeom == epullgDIST)
    {
        if (dimParams->origin < 0 || dimParams->end < 0)
        {
            gmx_fatal(FARGS, "%s-start (%g) or %s-end (%g) set to a negative value. With pull geometry distance coordinate values are non-negative. "
                      "Perhaps you want to use geometry %s instead?",
                      prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIR));
        }
    }
    else if (eGeom == epullgANGLE || eGeom == epullgANGLEAXIS)
    {
        if (dimParams->origin < 0 || dimParams->end > 180)
        {
            gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range 0 to 180 deg for pull geometries %s and %s ",
                      prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS));
        }
    }
    else if (eGeom == epullgDIHEDRAL)
    {
        if (dimParams->origin < -180 || dimParams->end > 180)
        {
            gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range -180 to 180 deg for pull geometry %s. ",
                      prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIHEDRAL));
        }
    }

    if (bComment)
    {
        CTYPE("The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)");
    }
    sprintf(opt, "%s-force-constant", prefix);
    RTYPE(opt, dimParams->forceConstant, 0);
    if (dimParams->forceConstant <= 0)
    {
        warning_error(wi, "The force AWH bias force constant should be > 0");
    }

    if (bComment)
    {
        CTYPE("Estimated diffusion constant (nm^2/ps or rad^2/ps)");
    }
    sprintf(opt, "%s-diffusion", prefix);
    RTYPE(opt, dimParams->diffusion, 0);

    if (dimParams->diffusion <= 0)
    {
        const double diffusion_default = 1e-5;
        sprintf(warningmsg, "%s not explicitly set by user."
                " You can choose to use a default value (%g nm^2/ps or rad^2/ps) but this may very well be non-optimal for your system!",
                opt, diffusion_default);
        warning(wi, warningmsg);
        dimParams->diffusion = diffusion_default;
    }

    if (bComment)
    {
        CTYPE("Diameter that needs to be sampled around a point before it is considered covered.");
    }
    sprintf(opt, "%s-cover-diameter", prefix);
    RTYPE(opt, dimParams->coverDiameter, 0);

    if (dimParams->coverDiameter < 0)
    {
        gmx_fatal(FARGS, "%s (%g) cannot be negative.",
                  opt, dimParams->coverDiameter);
    }

    *ninp_p   = ninp;
    *inp_p    = inp;
}
Exemple #6
0
/*! \brief
 * Read parameters of an AWH bias.
 *
 * \param[in,out] ninp_p         Number of read input file entries.
 * \param[in,out] inp_p          Input file entries.
 * \param[in,out] awhBiasParams  AWH dimensional parameters.
 * \param[in]     prefix         Prefix for bias parameters.
 * \param[in]     ir             Input parameter struct.
 * \param[in,out] wi             Struct for bookeeping warnings.
 * \param[in]     bComment       True if comments should be printed.
 */
static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhBiasParams, const char *prefix,
                             const t_inputrec *ir, warninp_t wi, bool bComment)
{
    int        ninp;
    t_inpfile *inp;
    char       opt[STRLEN], prefixdim[STRLEN];
    char       warningmsg[STRLEN];

    /* These are assumed to be declared by the gromacs reading functions */
    ninp   = *ninp_p;
    inp    = *inp_p;

    if (bComment)
    {
        CTYPE("Estimated initial PMF error (kJ/mol)");
    }
    sprintf(opt, "%s-error-init", prefix);

    /* We allow using a default value here without warning (but warn the user if the diffusion constant is not set). */
    RTYPE(opt, awhBiasParams->errorInitial, 10);
    if (awhBiasParams->errorInitial <= 0)
    {
        gmx_fatal(FARGS, "%s (%d) needs to be > 0.", opt);
    }

    if (bComment)
    {
        CTYPE("Growth rate of the reference histogram determining the bias update size: exp-linear or linear");
    }
    sprintf(opt, "%s-growth", prefix);
    EETYPE(opt, awhBiasParams->eGrowth, eawhgrowth_names);

    if (bComment)
    {
        CTYPE("Start the simulation by equilibrating histogram towards the target distribution: no or yes");
    }
    sprintf(opt, "%s-equilibrate-histogram", prefix);
    EETYPE(opt, awhBiasParams->equilibrateHistogram, yesno_names);
    if (awhBiasParams->equilibrateHistogram && awhBiasParams->eGrowth != eawhgrowthEXP_LINEAR)
    {
        sprintf(warningmsg, "Option %s will only have an effect for histogram growth type '%s'.",
                opt, EAWHGROWTH(eawhgrowthEXP_LINEAR));
        warning(wi, warningmsg);
    }

    if (bComment)
    {
        CTYPE("Target distribution type: constant, cutoff, boltzmann or local-boltzmann");
    }
    sprintf(opt, "%s-target", prefix);
    EETYPE(opt, awhBiasParams->eTarget, eawhtarget_names);

    if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) &&
        (awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR))
    {
        sprintf(warningmsg, "Target type '%s' combined with histogram growth type '%s' is not "
                "expected to give stable bias updates. You probably want to use growth type "
                "'%s' instead.",
                EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR),
                EAWHGROWTH(eawhgrowthLINEAR));
        warning(wi, warningmsg);
    }

    if (bComment)
    {
        CTYPE("Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'");
    }
    sprintf(opt, "%s-target-beta-scaling", prefix);
    RTYPE(opt, awhBiasParams->targetBetaScaling, 0);

    switch (awhBiasParams->eTarget)
    {
        case eawhtargetBOLTZMANN:
        case eawhtargetLOCALBOLTZMANN:
            if (awhBiasParams->targetBetaScaling < 0 || awhBiasParams->targetBetaScaling > 1)
            {
                gmx_fatal(FARGS, "%s = %g is not useful for target type %s.",
                          opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
            }
            break;
        default:
            if (awhBiasParams->targetBetaScaling != 0)
            {
                gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.",
                          opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
            }
            break;
    }

    if (bComment)
    {
        CTYPE("Free energy cutoff value for target distribution type 'cutoff'");
    }
    sprintf(opt, "%s-target-cutoff", prefix);
    RTYPE(opt, awhBiasParams->targetCutoff, 0);

    switch (awhBiasParams->eTarget)
    {
        case eawhtargetCUTOFF:
            if (awhBiasParams->targetCutoff <= 0)
            {
                gmx_fatal(FARGS, "%s = %g is not useful for target type %s.",
                          opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
            }
            break;
        default:
            if (awhBiasParams->targetCutoff != 0)
            {
                gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.",
                          opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
            }
            break;
    }

    if (bComment)
    {
        CTYPE("Initialize PMF and target with user data: no or yes");
    }
    sprintf(opt, "%s-user-data", prefix);
    EETYPE(opt, awhBiasParams->bUserData, yesno_names);

    if (bComment)
    {
        CTYPE("Group index to share the bias with, 0 means not shared");
    }
    sprintf(opt, "%s-share-group", prefix);
    ITYPE(opt, awhBiasParams->shareGroup, 0);
    if (awhBiasParams->shareGroup < 0)
    {
        warning_error(wi, "AWH bias share-group should be >= 0");
    }

    if (bComment)
    {
        CTYPE("Dimensionality of the coordinate");
    }
    sprintf(opt, "%s-ndim", prefix);
    ITYPE(opt, awhBiasParams->ndim, 0);

    if (awhBiasParams->ndim <= 0 ||
        awhBiasParams->ndim > c_biasMaxNumDim)
    {
        gmx_fatal(FARGS, "%s-ndim (%d) needs to be > 0 and at most %d\n", prefix,  awhBiasParams->ndim, c_biasMaxNumDim);
    }
    if (awhBiasParams->ndim > 2)
    {
        warning_note(wi, "For awh-dim > 2 the estimate based on the diffusion and the initial error is currently only a rough guideline."
                     " You should verify its usefulness for your system before production runs!");
    }
    snew(awhBiasParams->dimParams, awhBiasParams->ndim);
    for (int d = 0; d < awhBiasParams->ndim; d++)
    {
        bComment = bComment && d == 0;
        sprintf(prefixdim, "%s-dim%d", prefix, d + 1);
        readDimParams(&ninp, &inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment);
    }

    /* Check consistencies here that cannot be checked at read time at a lower level. */
    checkInputConsistencyAwhBias(*awhBiasParams, wi);

    *ninp_p   = ninp;
    *inp_p    = inp;
}
Exemple #7
0
void read_pullparams(t_pull *pull, char *infile, char *outfile) 
{
  t_inpfile *inp;
  int ninp,i;
  char *tmp;           /* for the input parsing macros */
  char dummy[STRLEN];  /* idem */
  char grp1buf[STRLEN], grp2buf[STRLEN], grp3buf[STRLEN], grp4buf[STRLEN],
       grp5buf[STRLEN],
       bf1[STRLEN], bf2[STRLEN], dir[STRLEN], 
       refdir1[STRLEN],refdir2[STRLEN];

  int bReverse; int tmpref; int tmprun; 

  enum {erunSTART, erunAFM, erunConstraint, erunUmbrella, erunTest, erunNR};
  static char *runtypes[erunNR+1] = { 
    "start", "afm", "constraint", "umbrella", "test", NULL
  };
  enum {erefCom, erefComT0, erefDyn, erefDynT0, erefNR};
  static char *reftypes[erefNR+1] = {
    "com", "com_t0", "dynamic", "dynamic_t0", NULL
  };
  enum {ereverseTO_REF, ereverseFROM_REF, ereverseNR};
  static char *reversetypes[ereverseNR+1] = {
    "from_reference", "to_reference", NULL
  };
  enum {everboseYES, everboseNO, everboseNR};
  static char *verbosetypes[erefNR+1] = {
    "no", "yes", NULL
  };
  int nerror = 0;

  /* read input parameter file */
  fprintf(stderr,"Reading parameter file %s\n",infile);
  inp=read_inpfile(infile,&ninp);

  /* general options */
  CTYPE("GENERAL");
  EETYPE("verbose",         pull->bVerbose, verbosetypes, &nerror, TRUE);
  CTYPE("Runtype: start, afm, constraint, umbrella, test");
  EETYPE("runtype",         tmprun, runtypes, &nerror, TRUE);
  CTYPE("Groups to be pulled");
  STYPE("group_1",          grp1buf, "");
  STYPE("group_2",          grp2buf, "");
  STYPE("group_3",          grp3buf, "");
  STYPE("group_4",          grp4buf, "");
  CTYPE("The group for the reaction force.");
  STYPE("reference_group",  grp5buf, "");
  CTYPE("Ref. type: com, com_t0, dynamic, dynamic_t0");
  EETYPE("reftype",         tmpref, reftypes, &nerror, TRUE);
  CTYPE("Use running average for reflag steps for com calculation");
  ITYPE("reflag",           pull->reflag, 1);
  CTYPE("Select components for constraint vector. default: z-only");
  STYPE("direction",        dir, "0.0 0.0 1.0");
  CTYPE("Direction for start/afm: to_reference, from_reference");
  EETYPE("reverse",          pull->bReverse, reversetypes, &nerror, TRUE);

  /* options for dynamic reference groups */
  CTYPE("DYNAMIC REFERENCE GROUP OPTIONS");
  CTYPE("Cylinder radius for dynamic reaction force groups (nm)");
  RTYPE("r",                pull->r, 0.0);
  CTYPE("Switch from r to rc in case of dynamic reaction force");
  RTYPE("rc",   pull->rc,   0.0);
  CTYPE("Update frequency for dynamic reference groups (steps)");
  ITYPE("update",           pull->update, 1);

  /* constraint run options */
  CCTYPE("CONSTRAINT RUN OPTIONS");
  CTYPE("Tolerance of constraints, in nm");
  RTYPE("constraint_tolerance",            pull->constr_tol, 1E-6);

  /* options for AFM type pulling simulations */
  CCTYPE("AFM OPTIONS");
  CTYPE("pull rate in nm/timestep");
  RTYPE("pullrate",         pull->rate,    0.0);
  CTYPE("forceconstant in kJ/(mol*nm^2)");
  RTYPE("forceconstant",    pull->k, 0.0);

  /* umbrella sampling options */
  CCTYPE("UMBRELLA SAMPLING OPTIONS");
  CTYPE("Width of umbrella sampling potential in kJ/(mol*nm^2)");
  RTYPE("width",            pull->um_width, 0.0);

  /* options for making starting structures */
  CCTYPE("STARTING STRUCTURE OPTIONS");
  CTYPE("Start coord. for making starting struct, rel. to ref. grp.: x y z");
  STYPE("r0_group1",        bf1, "");
  STYPE("r0_group2",        bf2, ""); 
  /*  CTYPE("Constrain rotations around principle axes? Needs work");
      ITYPE("rotation_x",       pull->bRot[0], 0);
      ITYPE("rotation_y",       pull->bRot[1], 0);
      ITYPE("rotation_z",       pull->bRot[2], 0);
      CTYPE("Rate of rotation (degrees/step)");
      RTYPE("rotation_rate",    pull->rot_rate, 0.0);
  */
  RTYPE("tolerance",        pull->tolerance, 0.05);
  CTYPE("Rate of translation in all directions (nm/step)");
  RTYPE("translation_rate", pull->xlt_rate, 0.0); 
  CTYPE("Write out structure every ndegr degrees, transstep nm");
  ITYPE("ndegr",            pull->rot_incr, 0);
  RTYPE("transstep",        pull->xlt_incr, 0.001);

  write_inpfile(outfile,ninp,inp);
  for (i=0; (i<ninp); i++) {
    sfree(inp[i].name);
    sfree(inp[i].value);
  }
  sfree(inp);

  pull->runtype = (t_runtype)tmprun;
  pull->reftype = (t_reftype)tmpref;

  /* sort out the groups */
  fprintf(stderr,"Groups: %s %s %s %s %s\n",
	  grp1buf,grp2buf,grp3buf,grp4buf,grp4buf);

  if (!strcmp(grp1buf,"") || !strcmp(grp5buf,"")) 
    fatal_error(0,"Need to specify at least group_1 and reference_group");
  pull->pull.n = 1;
  if (strcmp(grp2buf,"")) 
    pull->pull.n += 1;
  if (strcmp(grp3buf,"")) 
    pull->pull.n += 1;
  if (strcmp(grp4buf,""))
    pull->pull.n += 1;
     
  fprintf(stderr,"Using %d pull groups\n",pull->pull.n);
     
  /* initialize the names of the groups */
  snew(pull->pull.grps,pull->pull.n);
  snew(pull->ref.grps,1);
  pull->pull.grps[0] = (char *)strdup(grp1buf);
  pull->pull.grps[1] = (char *)strdup(grp2buf);
  pull->pull.grps[2] = (char *)strdup(grp3buf);
  pull->pull.grps[3] = (char *)strdup(grp4buf);
  pull->ref.grps[0]  = (char *)strdup(grp5buf);

  if (pull->runtype == eStart) {
    snew(pull->pull.xtarget,pull->pull.n);
    string2rvec(bf1,pull->pull.xtarget[0]);
    if (pull->pull.n == 2)
      string2rvec(bf2,pull->pull.xtarget[1]);
  }

  string2rvec(dir,pull->dims);
  fprintf(stderr,"Using distance components %2.1f %2.1f %2.1f\n",
	  pull->dims[0],pull->dims[1],pull->dims[2]);

  if (pull->r > 0.001) 
    pull->bCyl = TRUE;
  else
    pull->bCyl = FALSE;
}