Beispiel #1
0
int main(int argc,char *argv[])
{
  int       mmm[] = { 8, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40,
		      45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 100 };
  int       nnn[] = { 24, 32, 48, 60, 72, 84, 96 };
#define NNN asize(nnn)
  FILE      *fp,*fplog;
  int       *niter;
  int       i,j,n,nit,ntot,n3,rsize;
  double    t,nflop,start;
  double    *rt,*ct;
  t_fftgrid *g;
  t_commrec *cr;
  static gmx_bool bReproducible = FALSE;
  static int  nnode    = 1;
  static int  nitfac  = 1;
  t_pargs pa[] = {
    { "-reproducible",   FALSE, etBOOL, {&bReproducible}, 
      "Request binary reproducible results" },
    { "-np",    FALSE, etINT, {&nnode},
      "Number of NODEs" },
    { "-itfac", FALSE, etINT, {&nitfac},
      "Multiply number of iterations by this" }
  };
  static t_filenm fnm[] = {
    { efLOG, "-g", "fft",      ffWRITE },
    { efXVG, "-o", "fft",      ffWRITE }
  };
#define NFILE asize(fnm)
  
  cr = init_par(&argc,&argv);
  if (MASTER(cr))
    CopyRight(stdout,argv[0]);
  parse_common_args(&argc,argv,
		    PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET),
		    NFILE,fnm,asize(pa),pa,0,NULL,0,NULL);
  gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,1,0,&fplog);

  snew(niter,NNN);
  snew(ct,NNN);
  snew(rt,NNN);
  rsize = sizeof(real);
  for(i=0; (i<NNN); i++) {
    n  = nnn[i];
    if (n < 16)
      niter[i] = 50;
    else if (n < 26)
      niter[i] = 20;
    else if (n < 51)
      niter[i] = 10;
    else
      niter[i] = 5;
    niter[i] *= nitfac;
    nit = niter[i];
    
    if (MASTER(cr))
      fprintf(stderr,"\r3D FFT (%s precision) %3d^3, niter %3d     ",
	      (rsize == 8) ? "Double" : "Single",n,nit);
    
    g  = mk_fftgrid(n,n,n,NULL,NULL,cr,bReproducible);

    if (PAR(cr))
      start = time(NULL);
    else
      start_time();
    for(j=0; (j<nit); j++) {
      gmxfft3D(g,GMX_FFT_REAL_TO_COMPLEX,cr);
      gmxfft3D(g,GMX_FFT_COMPLEX_TO_REAL,cr);
    }
    if (PAR(cr)) 
      rt[i] = time(NULL)-start;
    else {
      update_time();
      rt[i] = node_time();
    }
    done_fftgrid(g);
    sfree(g);
  }
  if (MASTER(cr)) {
    fprintf(stderr,"\n");
    fp=xvgropen(ftp2fn(efXVG,NFILE,fnm),
		"FFT timings","n^3","t (s)");
    for(i=0; (i<NNN); i++) {
      n3 = 2*niter[i]*nnn[i]*nnn[i]*nnn[i];
      fprintf(fp,"%10d  %10g\n",nnn[i],rt[i]/(2*niter[i]));
    }
    gmx_fio_fclose(fp);
  }
  return 0;
}
Beispiel #2
0
int gmx_enemat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[TT]g_enemat[tt] extracts an energy matrix from the energy file ([TT]-f[tt]).",
        "With [TT]-groups[tt] a file must be supplied with on each",
        "line a group of atoms to be used. For these groups matrix of",
        "interaction energies will be extracted from the energy file",
        "by looking for energy groups with names corresponding to pairs",
        "of groups of atoms, e.g. if your [TT]-groups[tt] file contains:[BR]",
        "[TT]2[tt][BR]",
        "[TT]Protein[tt][BR]",
        "[TT]SOL[tt][BR]",
        "then energy groups with names like 'Coul-SR:Protein-SOL' and ",
        "'LJ:Protein-SOL' are expected in the energy file (although",
        "[TT]g_enemat[tt] is most useful if many groups are analyzed",
        "simultaneously). Matrices for different energy types are written",
        "out separately, as controlled by the",
        "[TT]-[no]coul[tt], [TT]-[no]coulr[tt], [TT]-[no]coul14[tt], ",
        "[TT]-[no]lj[tt], [TT]-[no]lj14[tt], ",
        "[TT]-[no]bham[tt] and [TT]-[no]free[tt] options.",
        "Finally, the total interaction energy energy per group can be ",
        "calculated ([TT]-etot[tt]).[PAR]",

        "An approximation of the free energy can be calculated using:",
        "[MATH]E[SUB]free[sub] = E[SUB]0[sub] + kT [LOG][CHEVRON][EXP](E-E[SUB]0[sub])/kT[exp][chevron][log][math], where '[MATH][CHEVRON][chevron][math]'",
        "stands for time-average. A file with reference free energies",
        "can be supplied to calculate the free energy difference",
        "with some reference state. Group names (e.g. residue names)",
        "in the reference file should correspond to the group names",
        "as used in the [TT]-groups[tt] file, but a appended number",
        "(e.g. residue number) in the [TT]-groups[tt] will be ignored",
        "in the comparison."
    };
    static gmx_bool bSum      = FALSE;
    static gmx_bool bMeanEmtx = TRUE;
    static int      skip      = 0, nlevels = 20;
    static real     cutmax    = 1e20, cutmin = -1e20, reftemp = 300.0;
    static gmx_bool bCoulSR   = TRUE, bCoulLR = FALSE, bCoul14 = FALSE;
    static gmx_bool bLJSR     = TRUE, bLJLR = FALSE, bLJ14 = FALSE, bBhamSR = FALSE, bBhamLR = FALSE,
                    bFree     = TRUE;
    t_pargs         pa[]      = {
        { "-sum",  FALSE, etBOOL, {&bSum},
          "Sum the energy terms selected rather than display them all" },
        { "-skip", FALSE, etINT,  {&skip},
          "Skip number of frames between data points" },
        { "-mean", FALSE, etBOOL, {&bMeanEmtx},
          "with [TT]-groups[tt] extracts matrix of mean energies instead of "
          "matrix for each timestep" },
        { "-nlevels", FALSE, etINT, {&nlevels}, "number of levels for matrix colors"},
        { "-max", FALSE, etREAL, {&cutmax}, "max value for energies"},
        { "-min", FALSE, etREAL, {&cutmin}, "min value for energies"},
        { "-coulsr", FALSE, etBOOL, {&bCoulSR}, "extract Coulomb SR energies"},
        { "-coullr", FALSE, etBOOL, {&bCoulLR}, "extract Coulomb LR energies"},
        { "-coul14", FALSE, etBOOL, {&bCoul14}, "extract Coulomb 1-4 energies"},
        { "-ljsr", FALSE, etBOOL, {&bLJSR}, "extract Lennard-Jones SR energies"},
        { "-ljlr", FALSE, etBOOL, {&bLJLR}, "extract Lennard-Jones LR energies"},
        { "-lj14", FALSE, etBOOL, {&bLJ14}, "extract Lennard-Jones 1-4 energies"},
        { "-bhamsr", FALSE, etBOOL, {&bBhamSR}, "extract Buckingham SR energies"},
        { "-bhamlr", FALSE, etBOOL, {&bBhamLR}, "extract Buckingham LR energies"},
        { "-free", FALSE, etBOOL, {&bFree}, "calculate free energy"},
        { "-temp", FALSE, etREAL, {&reftemp},
          "reference temperature for free energy calculation"}
    };
    /* We will define egSP more energy-groups:
       egTotal (total energy) */
#define egTotal egNR
#define egSP 1
    gmx_bool       egrp_use[egNR+egSP];
    ener_file_t    in;
    FILE          *out;
    int            timecheck = 0;
    gmx_enxnm_t   *enm       = NULL;
    t_enxframe    *fr;
    int            teller = 0;
    real           sum;
    gmx_bool       bCont, bRef;
    gmx_bool       bCutmax, bCutmin;
    real         **eneset, *time = NULL;
    int           *set, i, j, k, prevk, m = 0, n, nre, nset, nenergy;
    char         **groups = NULL;
    char           groupname[255], fn[255];
    int            ngroups;
    t_rgb          rlo, rhi, rmid;
    real           emax, emid, emin;
    real        ***emat, **etot, *groupnr;
    double         beta, expE, **e, *eaver, *efree = NULL, edum;
    char           label[234];
    char         **ereflines, **erefres = NULL;
    real          *eref  = NULL, *edif = NULL;
    int            neref = 0;
    output_env_t   oenv;

    t_filenm       fnm[] = {
        { efEDR, "-f", NULL, ffOPTRD },
        { efDAT, "-groups", "groups.dat", ffREAD },
        { efDAT, "-eref",   "eref.dat", ffOPTRD },
        { efXPM, "-emat",   "emat", ffWRITE },
        { efXVG, "-etot",   "energy", ffWRITE }
    };
#define NFILE asize(fnm)

    CopyRight(stderr, argv[0]);
    parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv);

    egrp_use[egCOULSR] = bCoulSR;
    egrp_use[egLJSR]   = bLJSR;
    egrp_use[egBHAMSR] = bBhamSR;
    egrp_use[egCOULLR] = bCoulLR;
    egrp_use[egLJLR]   = bLJLR;
    egrp_use[egBHAMLR] = bBhamLR;
    egrp_use[egCOUL14] = bCoul14;
    egrp_use[egLJ14]   = bLJ14;
    egrp_use[egTotal]  = TRUE;

    bRef = opt2bSet("-eref", NFILE, fnm);
    in   = open_enx(ftp2fn(efEDR, NFILE, fnm), "r");
    do_enxnms(in, &nre, &enm);

    if (nre == 0)
    {
        gmx_fatal(FARGS, "No energies!\n");
    }

    bCutmax = opt2parg_bSet("-max", asize(pa), pa);
    bCutmin = opt2parg_bSet("-min", asize(pa), pa);

    nenergy = 0;

    /* Read groupnames from input file and construct selection of
       energy groups from it*/

    fprintf(stderr, "Will read groupnames from inputfile\n");
    ngroups = get_lines(opt2fn("-groups", NFILE, fnm), &groups);
    fprintf(stderr, "Read %d groups\n", ngroups);
    snew(set, sqr(ngroups)*egNR/2);
    n     = 0;
    prevk = 0;
    for (i = 0; (i < ngroups); i++)
    {
        fprintf(stderr, "\rgroup %d", i);
        for (j = i; (j < ngroups); j++)
        {
            for (m = 0; (m < egNR); m++)
            {
                if (egrp_use[m])
                {
                    sprintf(groupname, "%s:%s-%s", egrp_nm[m], groups[i], groups[j]);
#ifdef DEBUG
                    fprintf(stderr, "\r%-15s %5d", groupname, n);
#endif
                    for (k = prevk; (k < prevk+nre); k++)
                    {
                        if (strcmp(enm[k%nre].name, groupname) == 0)
                        {
                            set[n++] = k;
                            break;
                        }
                    }
                    if (k == prevk+nre)
                    {
                        fprintf(stderr, "WARNING! could not find group %s (%d,%d)"
                                "in energy file\n", groupname, i, j);
                    }
                    else
                    {
                        prevk = k;
                    }
                }
            }
        }
    }
    fprintf(stderr, "\n");
    nset = n;
    snew(eneset, nset+1);
    fprintf(stderr, "Will select half-matrix of energies with %d elements\n", n);

    /* Start reading energy frames */
    snew(fr, 1);
    do
    {
        do
        {
            bCont = do_enx(in, fr);
            if (bCont)
            {
                timecheck = check_times(fr->t);
            }
        }
        while (bCont && (timecheck < 0));

        if (timecheck == 0)
        {
#define DONTSKIP(cnt) (skip) ? ((cnt % skip) == 0) : TRUE

            if (bCont)
            {
                fprintf(stderr, "\rRead frame: %d, Time: %.3f", teller, fr->t);

                if ((nenergy % 1000) == 0)
                {
                    srenew(time, nenergy+1000);
                    for (i = 0; (i <= nset); i++)
                    {
                        srenew(eneset[i], nenergy+1000);
                    }
                }
                time[nenergy] = fr->t;
                sum           = 0;
                for (i = 0; (i < nset); i++)
                {
                    eneset[i][nenergy] = fr->ener[set[i]].e;
                    sum               += fr->ener[set[i]].e;
                }
                if (bSum)
                {
                    eneset[nset][nenergy] = sum;
                }
                nenergy++;
            }
            teller++;
        }
    }
    while (bCont && (timecheck == 0));

    fprintf(stderr, "\n");

    fprintf(stderr, "Will build energy half-matrix of %d groups, %d elements, "
            "over %d frames\n", ngroups, nset, nenergy);

    snew(emat, egNR+egSP);
    for (j = 0; (j < egNR+egSP); j++)
    {
        if (egrp_use[m])
        {
            snew(emat[j], ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                snew(emat[j][i], ngroups);
            }
        }
    }
    snew(groupnr, ngroups);
    for (i = 0; (i < ngroups); i++)
    {
        groupnr[i] = i+1;
    }
    rlo.r  = 1.0, rlo.g  = 0.0, rlo.b  = 0.0;
    rmid.r = 1.0, rmid.g = 1.0, rmid.b = 1.0;
    rhi.r  = 0.0, rhi.g  = 0.0, rhi.b  = 1.0;
    if (bMeanEmtx)
    {
        snew(e, ngroups);
        for (i = 0; (i < ngroups); i++)
        {
            snew(e[i], nenergy);
        }
        n = 0;
        for (i = 0; (i < ngroups); i++)
        {
            for (j = i; (j < ngroups); j++)
            {
                for (m = 0; (m < egNR); m++)
                {
                    if (egrp_use[m])
                    {
                        for (k = 0; (k < nenergy); k++)
                        {
                            emat[m][i][j] += eneset[n][k];
                            e[i][k]       += eneset[n][k]; /* *0.5; */
                            e[j][k]       += eneset[n][k]; /* *0.5; */
                        }
                        n++;
                        emat[egTotal][i][j] += emat[m][i][j];
                        emat[m][i][j]       /= nenergy;
                        emat[m][j][i]        = emat[m][i][j];
                    }
                }
                emat[egTotal][i][j] /= nenergy;
                emat[egTotal][j][i]  = emat[egTotal][i][j];
            }
        }
        if (bFree)
        {
            if (bRef)
            {
                fprintf(stderr, "Will read reference energies from inputfile\n");
                neref = get_lines(opt2fn("-eref", NFILE, fnm), &ereflines);
                fprintf(stderr, "Read %d reference energies\n", neref);
                snew(eref, neref);
                snew(erefres, neref);
                for (i = 0; (i < neref); i++)
                {
                    snew(erefres[i], 5);
                    sscanf(ereflines[i], "%s %lf", erefres[i], &edum);
                    eref[i] = edum;
                }
            }
            snew(eaver, ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                for (k = 0; (k < nenergy); k++)
                {
                    eaver[i] += e[i][k];
                }
                eaver[i] /= nenergy;
            }
            beta = 1.0/(BOLTZ*reftemp);
            snew(efree, ngroups);
            snew(edif, ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                expE = 0;
                for (k = 0; (k < nenergy); k++)
                {
                    expE += exp(beta*(e[i][k]-eaver[i]));
                }
                efree[i] = log(expE/nenergy)/beta + eaver[i];
                if (bRef)
                {
                    n = search_str2(neref, erefres, groups[i]);
                    if (n != -1)
                    {
                        edif[i] = efree[i]-eref[n];
                    }
                    else
                    {
                        edif[i] = efree[i];
                        fprintf(stderr, "WARNING: group %s not found "
                                "in reference energies.\n", groups[i]);
                    }
                }
                else
                {
                    edif[i] = 0;
                }
            }
        }

        emid             = 0.0; /*(emin+emax)*0.5;*/
        egrp_nm[egTotal] = "total";
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                emin = 1e10;
                emax = -1e10;
                for (i = 0; (i < ngroups); i++)
                {
                    for (j = i; (j < ngroups); j++)
                    {
                        if (emat[m][i][j] > emax)
                        {
                            emax = emat[m][i][j];
                        }
                        else if (emat[m][i][j] < emin)
                        {
                            emin = emat[m][i][j];
                        }
                    }
                }
                if (emax == emin)
                {
                    fprintf(stderr, "Matrix of %s energy is uniform at %f "
                            "(will not produce output).\n", egrp_nm[m], emax);
                }
                else
                {
                    fprintf(stderr, "Matrix of %s energy ranges from %f to %f\n",
                            egrp_nm[m], emin, emax);
                    if ((bCutmax) || (emax > cutmax))
                    {
                        emax = cutmax;
                    }
                    if ((bCutmin) || (emin < cutmin))
                    {
                        emin = cutmin;
                    }
                    if ((emax == cutmax) || (emin == cutmin))
                    {
                        fprintf(stderr, "Energy range adjusted: %f to %f\n", emin, emax);
                    }

                    sprintf(fn, "%s%s", egrp_nm[m], ftp2fn(efXPM, NFILE, fnm));
                    sprintf(label, "%s Interaction Energies", egrp_nm[m]);
                    out = ffopen(fn, "w");
                    if (emin >= emid)
                    {
                        write_xpm(out, 0, label, "Energy (kJ/mol)",
                                  "Residue Index", "Residue Index",
                                  ngroups, ngroups, groupnr, groupnr, emat[m],
                                  emid, emax, rmid, rhi, &nlevels);
                    }
                    else if (emax <= emid)
                    {
                        write_xpm(out, 0, label, "Energy (kJ/mol)",
                                  "Residue Index", "Residue Index",
                                  ngroups, ngroups, groupnr, groupnr, emat[m],
                                  emin, emid, rlo, rmid, &nlevels);
                    }
                    else
                    {
                        write_xpm3(out, 0, label, "Energy (kJ/mol)",
                                   "Residue Index", "Residue Index",
                                   ngroups, ngroups, groupnr, groupnr, emat[m],
                                   emin, emid, emax, rlo, rmid, rhi, &nlevels);
                    }
                    ffclose(out);
                }
            }
        }
        snew(etot, egNR+egSP);
        for (m = 0; (m < egNR+egSP); m++)
        {
            snew(etot[m], ngroups);
            for (i = 0; (i < ngroups); i++)
            {
                for (j = 0; (j < ngroups); j++)
                {
                    etot[m][i] += emat[m][i][j];
                }
            }
        }

        out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Mean Energy", "Residue", "kJ/mol",
                       oenv);
        xvgr_legend(out, 0, NULL, oenv);
        j = 0;
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                fprintf(out, "@ legend string %d \"%s\"\n", j++, egrp_nm[m]);
            }
        }
        if (bFree)
        {
            fprintf(out, "@ legend string %d \"%s\"\n", j++, "Free");
        }
        if (bFree)
        {
            fprintf(out, "@ legend string %d \"%s\"\n", j++, "Diff");
        }
        fprintf(out, "@TYPE xy\n");
        fprintf(out, "#%3s", "grp");
        for (m = 0; (m < egNR+egSP); m++)
        {
            if (egrp_use[m])
            {
                fprintf(out, " %9s", egrp_nm[m]);
            }
        }
        if (bFree)
        {
            fprintf(out, " %9s", "Free");
        }
        if (bFree)
        {
            fprintf(out, " %9s", "Diff");
        }
        fprintf(out, "\n");
        for (i = 0; (i < ngroups); i++)
        {
            fprintf(out, "%3.0f", groupnr[i]);
            for (m = 0; (m < egNR+egSP); m++)
            {
                if (egrp_use[m])
                {
                    fprintf(out, " %9.5g", etot[m][i]);
                }
            }
            if (bFree)
            {
                fprintf(out, " %9.5g", efree[i]);
            }
            if (bRef)
            {
                fprintf(out, " %9.5g", edif[i]);
            }
            fprintf(out, "\n");
        }
        ffclose(out);
    }
    else
    {
        fprintf(stderr, "While typing at your keyboard, suddenly...\n"
                "...nothing happens.\nWARNING: Not Implemented Yet\n");
/*
    out=ftp2FILE(efMAT,NFILE,fnm,"w");
    n=0;
    emin=emax=0.0;
    for (k=0; (k<nenergy); k++) {
      for (i=0; (i<ngroups); i++)
    for (j=i+1; (j<ngroups); j++)
      emat[i][j]=eneset[n][k];
      sprintf(label,"t=%.0f ps",time[k]);
      write_matrix(out,ngroups,1,ngroups,groupnr,emat,label,emin,emax,nlevels);
      n++;
    }
    ffclose(out);
 */
    }
    close_enx(in);

    thanx(stderr);

    return 0;
}
int gmx_traj(int argc,char *argv[])
{
  static char *desc[] = {
    "g_traj plots coordinates, velocities, forces and/or the box.",
    "With [TT]-com[tt] the coordinates, velocities and forces are",
    "calculated for the center of mass of each group.",
    "When [TT]-mol[tt] is set, the numbers in the index file are",
    "interpreted as molecule numbers and the same procedure as with",
    "[TT]-com[tt] is used for each molecule.[PAR]",
    "Option [TT]-ot[tt] plots the temperature of each group,",
    "provided velocities are present in the trajectory file.",
    "No corrections are made for constrained degrees of freedom!",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-ekt[tt] and [TT]-ekr[tt] plot the translational and",
    "rotational kinetic energy of each group,", 
    "provided velocities are present in the trajectory file.",
    "This implies [TT]-com[tt].[PAR]",
    "Options [TT]-cv[tt] and [TT]-cf[tt] write the average velocities",
    "and average forces as temperature factors to a pdb file with",
    "the average coordinates. The temperature factors are scaled such",
    "that the maximum is 10. The scaling can be changed with the option",
    "[TT]-scale[tt]. To get the velocities or forces of one",
    "frame set both [TT]-b[tt] and [TT]-e[tt] to the time of",
    "desired frame. When averaging over frames you might need to use",
    "the [TT]-nojump[tt] option to obtain the correct average coordinates.",
    "If you select either of these option the average force and velocity",
    "for each atom are written to an xvg file as well",
    "(specified with [TT]-av[tt] or [TT]-af[tt]).[PAR]",
    "Option [TT]-vd[tt] computes a velocity distribution, i.e. the",
    "norm of the vector is plotted. In addition in the same graph",
    "the kinetic energy distribution is given."
  };
  static bool bMol=FALSE,bCom=FALSE,bNoJump=FALSE;
  static bool bX=TRUE,bY=TRUE,bZ=TRUE,bNorm=FALSE;
  static int  ngroups=1;
  static real scale=0,binwidth=1;
  t_pargs pa[] = {
    { "-com", FALSE, etBOOL, {&bCom},
      "Plot data for the com of each group" },
    { "-mol", FALSE, etBOOL, {&bMol},
      "Index contains molecule numbers iso atom numbers" },
    { "-nojump", FALSE, etBOOL, {&bNoJump},
      "Remove jumps of atoms across the box" },
    { "-x", FALSE, etBOOL, {&bX},
      "Plot X-component" },
    { "-y", FALSE, etBOOL, {&bY},
      "Plot Y-component" },
    { "-z", FALSE, etBOOL, {&bZ},
      "Plot Z-component" },
    { "-ng",       FALSE, etINT, {&ngroups},
      "Number of groups to consider" },
    { "-len", FALSE, etBOOL, {&bNorm},
      "Plot vector length" },
    { "-bin", FALSE, etREAL, {&binwidth},
      "Binwidth for velocity histogram (nm/ps)" },
    { "-scale", FALSE, etREAL, {&scale},
      "Scale factor for pdb output, 0 is autoscale" }
    
  };
  FILE       *outx=NULL,*outv=NULL,*outf=NULL,*outb=NULL,*outt=NULL;
  FILE       *outekt=NULL,*outekr=NULL;
  t_topology top;
  int        ePBC;
  real       *mass,time;
  char       title[STRLEN],*indexfn;
  t_trxframe fr,frout;
  int        flags,nvhisto=0,*vhisto=NULL;
  rvec       *xtop,*xp=NULL;
  rvec       *sumxv=NULL,*sumv=NULL,*sumxf=NULL,*sumf=NULL;
  matrix     topbox;
  int        status,status_out=-1;
  int        i,j,n;
  int        nr_xfr,nr_vfr,nr_ffr;
  char       **grpname;
  int        *isize0,*isize;
  atom_id    **index0,**index;
  atom_id    *atndx;
  t_block    *mols;
  bool       bTop,bOX,bOXT,bOV,bOF,bOB,bOT,bEKT,bEKR,bCV,bCF;
  bool       bDim[4],bDum[4],bVD;
  char       *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" };

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPS, NULL, NULL, ffREAD },
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ox", "coord.xvg", ffOPTWR },
    { efTRX, "-oxt","coord.xtc", ffOPTWR },
    { efXVG, "-ov", "veloc.xvg", ffOPTWR },
    { efXVG, "-of", "force.xvg", ffOPTWR },
    { efXVG, "-ob", "box.xvg",   ffOPTWR },
    { efXVG, "-ot", "temp.xvg",  ffOPTWR },
    { efXVG, "-ekt","ektrans.xvg", ffOPTWR },
    { efXVG, "-ekr","ekrot.xvg", ffOPTWR },
    { efXVG, "-vd", "veldist.xvg", ffOPTWR },
    { efPDB, "-cv", "veloc.pdb", ffOPTWR },
    { efPDB, "-cf", "force.pdb", ffOPTWR },
    { efXVG, "-av", "all_veloc.xvg", ffOPTWR },
    { efXVG, "-af", "all_force.xvg", ffOPTWR }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,
		    PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);

  if (bMol)
    fprintf(stderr,"Interpreting indexfile entries as molecules.\n"
	    "Using center of mass.\n");
  
  bOX  = opt2bSet("-ox",NFILE,fnm);
  bOXT = opt2bSet("-oxt",NFILE,fnm);
  bOV  = opt2bSet("-ov",NFILE,fnm);
  bOF  = opt2bSet("-of",NFILE,fnm);
  bOB  = opt2bSet("-ob",NFILE,fnm);
  bOT  = opt2bSet("-ot",NFILE,fnm);
  bEKT = opt2bSet("-ekt",NFILE,fnm);
  bEKR = opt2bSet("-ekr",NFILE,fnm);
  bCV  = opt2bSet("-cv",NFILE,fnm) || opt2bSet("-av",NFILE,fnm);
  bCF  = opt2bSet("-cf",NFILE,fnm) || opt2bSet("-af",NFILE,fnm);
  bVD  = opt2bSet("-vd",NFILE,fnm) || opt2parg_bSet("-bin",asize(pa),pa);
  if (bMol || bOT || bEKT || bEKR)
    bCom = TRUE;

  bDim[XX] = bX;
  bDim[YY] = bY;
  bDim[ZZ] = bZ;
  bDim[DIM] = bNorm;

  bTop = read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,
		       bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR));
  sfree(xtop);
  if ((bMol || bCV || bCF) && !bTop)
    gmx_fatal(FARGS,"Need a run input file for option -mol, -cv or -cf");

  if (bMol)
    indexfn = ftp2fn(efNDX,NFILE,fnm);
  else
    indexfn = ftp2fn_null(efNDX,NFILE,fnm);

  if (!(bCom && !bMol))
    ngroups = 1;
  snew(grpname,ngroups);
  snew(isize0,ngroups);
  snew(index0,ngroups);
  get_index(&(top.atoms),indexfn,ngroups,isize0,index0,grpname);
  
  if (bMol) {
    mols=&(top.mols);
    atndx = mols->index;
    ngroups = isize0[0];
    snew(isize,ngroups);
    snew(index,ngroups);
    for (i=0; i<ngroups; i++) {
      if (index0[0][i] < 0 || index0[0][i] >= mols->nr)
	gmx_fatal(FARGS,"Molecule index (%d) is out of range (%d-%d)",
		  index0[0][i]+1,1,mols->nr);
      isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]];
      snew(index[i],isize[i]);
      for(j=0; j<isize[i]; j++)
	index[i][j] = atndx[index0[0][i]] + j;
    }
  } else {
    isize = isize0;
    index = index0;
  }
  if (bCom) {
    snew(mass,top.atoms.nr);
    for(i=0; i<top.atoms.nr; i++)
      mass[i] = top.atoms.atom[i].m;
  } else
    mass = NULL;

  flags = 0;
  if (bOX) {
    flags = flags | TRX_READ_X;
    outx = xvgropen(opt2fn("-ox",NFILE,fnm),
		    bCom ? "Center of mass" : "Coordinate",
		    xvgr_tlabel(),"Coordinate (nm)");
    make_legend(outx,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOXT) {
    flags = flags | TRX_READ_X;
    status_out = open_trx(opt2fn("-oxt",NFILE,fnm),"w");
  }
  if (bOV) {
    flags = flags | TRX_READ_V;
    outv = xvgropen(opt2fn("-ov",NFILE,fnm),
		    bCom ? "Center of mass velocity" : "Velocity",
		    xvgr_tlabel(),"Velocity (nm/ps)");
   make_legend(outv,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim); 
  }
  if (bOF) {
    flags = flags | TRX_READ_F;
    outf = xvgropen(opt2fn("-of",NFILE,fnm),"Force",
		    xvgr_tlabel(),"Force (kJ mol\\S-1\\N nm\\S-1\\N)");
    make_legend(outf,ngroups,isize0[0],index0[0],grpname,bCom,bMol,bDim);
  }
  if (bOB) {
    outb = xvgropen(opt2fn("-ob",NFILE,fnm),"Box vector elements",
		    xvgr_tlabel(),"(nm)");
   
    xvgr_legend(outb,6,box_leg);
  }
  if (bOT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outt = xvgropen(opt2fn("-ot",NFILE,fnm),"Temperature",xvgr_tlabel(),"(K)");
    make_legend(outt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKT) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_V;
    outekt = xvgropen(opt2fn("-ekt",NFILE,fnm),"Center of mass translation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekt,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bEKR) {
    bDum[XX] = FALSE;
    bDum[YY] = FALSE;
    bDum[ZZ] = FALSE;
    bDum[DIM] = TRUE;
    flags = flags | TRX_READ_X | TRX_READ_V;
    outekr = xvgropen(opt2fn("-ekr",NFILE,fnm),"Center of mass rotation",
		      xvgr_tlabel(),"Energy (kJ mol\\S-1\\N)");
    make_legend(outekr,ngroups,isize[0],index[0],grpname,bCom,bMol,bDum);
  }
  if (bVD)
    flags = flags | TRX_READ_V;
  if (bCV)
    flags = flags | TRX_READ_X | TRX_READ_V;
  if (bCF)
    flags = flags | TRX_READ_X | TRX_READ_F;
  if ((flags == 0) && !bOB) {
    fprintf(stderr,"Please select one or more output file options\n");
    exit(0);
  }

  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags);

  if (bCV) {
    snew(sumxv,fr.natoms);
    snew(sumv,fr.natoms);
  }
  if (bCF) {
    snew(sumxf,fr.natoms);
    snew(sumf,fr.natoms);
  }
  nr_xfr = 0;
  nr_vfr = 0;
  nr_ffr = 0;
  
  do {
    time = convert_time(fr.time);

    if (fr.bX && bNoJump && fr.bBox) {
      if (xp)
	remove_jump(fr.box,fr.natoms,xp,fr.x);
      else 
	snew(xp,fr.natoms);
      for(i=0; i<fr.natoms; i++)
	copy_rvec(fr.x[i],xp[i]);
    }
    
    if (fr.bX && bCom)
      rm_pbc(&(top.idef),ePBC,fr.natoms,fr.box,fr.x,fr.x);

    if (bVD && fr.bV) 
      update_histo(isize[0],index[0],fr.v,&nvhisto,&vhisto,binwidth);
      
    if (bOX && fr.bX)
      print_data(outx,time,fr.x,mass,bCom,ngroups,isize,index,bDim);
    if (bOXT && fr.bX) {
      frout = fr;
      if (!frout.bAtoms) {
	frout.atoms  = &top.atoms;
	frout.bAtoms = TRUE;
      }
      write_trx_x(status_out,&frout,mass,bCom,ngroups,isize,index);
    }
    if (bOV && fr.bV)
      print_data(outv,time,fr.v,mass,bCom,ngroups,isize,index,bDim);
    if (bOF && fr.bF)
      print_data(outf,time,fr.f,NULL,bCom,ngroups,isize,index,bDim);
    if (bOB && fr.bBox)
      fprintf(outb,"\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n",fr.time,
	      fr.box[XX][XX],fr.box[YY][YY],fr.box[ZZ][ZZ],
	      fr.box[YY][XX],fr.box[ZZ][XX],fr.box[ZZ][YY]);
    if (bOT && fr.bV) {
      fprintf(outt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outt,"\t%g",temp(fr.v,mass,isize[i],index[i]));
      fprintf(outt,"\n");
    }
    if (bEKT && fr.bV) {
      fprintf(outekt," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekt,"\t%g",ektrans(fr.v,mass,isize[i],index[i]));
      fprintf(outekt,"\n");
    }
    if (bEKR && fr.bX && fr.bV) {
      fprintf(outekr," %g",time);
      for(i=0; i<ngroups; i++)
	fprintf(outekr,"\t%g",ekrot(fr.x,fr.v,mass,isize[i],index[i]));
      fprintf(outekr,"\n");
    }
    if (bCV) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxv[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bV) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumv[i],fr.v[i]);
	nr_vfr++;
      }
    }
    if (bCF) {
      if (fr.bX) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumxf[i],fr.x[i]);
	nr_xfr++;
      }
      if (fr.bF) {
	for(i=0; i<fr.natoms; i++)
	  rvec_inc(sumf[i],fr.f[i]);
	nr_ffr++;
      }
    }
    
  } while(read_next_frame(status,&fr));
  

  /* clean up a bit */
  close_trj(status);
  
  if (bOX) fclose(outx);
  if (bOXT) close_trx(status_out);
  if (bOV) fclose(outv);
  if (bOF) fclose(outf);
  if (bOB) fclose(outb);
  if (bOT) fclose(outt);
  if (bEKT) fclose(outekt);
  if (bEKR) fclose(outekr);

  if (bVD)
    print_histo(opt2fn("-vd",NFILE,fnm),nvhisto,vhisto,binwidth);
    
  if ((bCV || bCF) && (nr_vfr>1 || nr_ffr>1) && !bNoJump)
    fprintf(stderr,"WARNING: More than one frame was used for option -cv or -cf\n"
	    "If atoms jump across the box you should use the -nojump option\n");

  if (bCV)
    write_pdb_bfac(opt2fn("-cv",NFILE,fnm),
		   opt2fn("-av",NFILE,fnm),"average velocity",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxv,
		   nr_vfr,sumv,bDim,scale);
  if (bCF)
    write_pdb_bfac(opt2fn("-cf",NFILE,fnm),
		   opt2fn("-af",NFILE,fnm),"average force",&(top.atoms),
		   ePBC,topbox,isize[0],index[0],nr_xfr,sumxf,
		   nr_ffr,sumf,bDim,scale);

  /* view it */
  view_all(NFILE, fnm);
  
  thanx(stderr);
  
  return 0;
}
int gmx_genconf(int argc, char *argv[])
{
  static char *desc[] = {
    "genconf multiplies a given coordinate file by simply stacking them",
    "on top of each other, like a small child playing with wooden blocks.",
    "The program makes a grid of [IT]user defined[it]",
    "proportions ([TT]-nbox[tt]), ",
    "and interspaces the grid point with an extra space [TT]-dist[tt].[PAR]",
    "When option [TT]-rot[tt] is used the program does not check for overlap",
    "between molecules on grid points. It is recommended to make the box in",
    "the input file at least as big as the coordinates + ",
    "Van der Waals radius.[PAR]",
    "If the optional trajectory file is given, conformations are not",
    "generated, but read from this file and translated appropriately to",
    "build the grid."
    
  };
  static char *bugs[] = {
    "The program should allow for random displacement off lattice points." };

  int     vol;          
  t_atoms *atoms;       /* list with all atoms */
  char    title[STRLEN];
  rvec    *x,*xx,*v;        /* coordinates? */
  real    t;
  vec4    *xrot,*vrot;
  int     ePBC;
  matrix  box,boxx;          /* box length matrix */
  rvec    shift;         
  int     natoms;       /* number of atoms in one molecule  */
  int     nres;         /* number of molecules? */
  int     i,j,k,l,m,ndx,nrdx,nx,ny,nz,status=-1;
  bool    bTRX;
  
  t_filenm fnm[] = {
    { efSTX, "-f", "conf", ffREAD  },
    { efSTO, "-o", "out",  ffWRITE },
    { efTRX, "-trj",NULL,  ffOPTRD }
  };
#define NFILE asize(fnm)
  static rvec nrbox    = {1,1,1};
  static int  seed     = 0;          /* seed for random number generator */
  static int  nmolat   = 3;
  static int  nblock   = 1;
  static bool bShuffle = FALSE;
  static bool bSort    = FALSE;
  static bool bRandom  = FALSE;      /* False: no random rotations */
  static bool bRenum   = TRUE;       /* renumber residues */
  static rvec dist     = {0,0,0};    /* space added between molecules ? */
  static rvec max_rot  = {180,180,180}; /* maximum rotation */
  t_pargs pa[] = {
    { "-nbox",   FALSE, etRVEC, {nrbox},   "Number of boxes" },
    { "-dist",   FALSE, etRVEC, {dist},    "Distance between boxes" },
    { "-seed",   FALSE, etINT,  {&seed},   
      "Random generator seed, if 0 generated from the time" },
    { "-rot",    FALSE, etBOOL, {&bRandom}, "Randomly rotate conformations" },
    { "-shuffle",FALSE, etBOOL, {&bShuffle},"Random shuffling of molecules" },
    { "-sort",   FALSE, etBOOL, {&bSort},   "Sort molecules on X coord" },
    { "-block",  FALSE, etINT,  {&nblock},
      "Divide the box in blocks on this number of cpus" },
    { "-nmolat", FALSE, etINT,  {&nmolat}, 
      "Number of atoms per molecule, assumed to start from 0. "
      "If you set this wrong, it will screw up your system!" },
    { "-maxrot", FALSE, etRVEC, {max_rot}, "Maximum random rotation" },
    { "-renumber",FALSE,etBOOL, {&bRenum},  "Renumber residues" }
  };
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,asize(bugs),bugs);

  if (bRandom && (seed == 0))
    seed = make_seed();
		    
  bTRX = ftp2bSet(efTRX,NFILE,fnm);
  nx   = (int)(nrbox[XX]+0.5);
  ny   = (int)(nrbox[YY]+0.5);
  nz   = (int)(nrbox[ZZ]+0.5);
  
  if ((nx <= 0) || (ny <= 0) || (nz <= 0))
    gmx_fatal(FARGS,"Number of boxes (-nbox) should be larger than zero");
  if ((nmolat <= 0) && bShuffle)
    gmx_fatal(FARGS,"Can not shuffle if the molecules only have %d atoms",
		nmolat);
  
  vol=nx*ny*nz;     /* calculate volume in grid points (= nr. molecules) */

  get_stx_coordnum(opt2fn("-f",NFILE,fnm),&natoms); 
  snew(atoms,1);
  /* make space for all the atoms */
  init_t_atoms(atoms,natoms*vol,FALSE);
  snew(x,natoms*vol);              /* get space for coordinates of all atoms */
  snew(xrot,natoms);               /* get space for rotation matrix? */
  snew(v,natoms*vol);              /* velocities. not really needed? */ 
  snew(vrot,natoms); 
  /* set atoms->nr to the number in one box *
   * to avoid complaints in read_stx_conf   *
   */
  atoms->nr = natoms;
  read_stx_conf(opt2fn("-f",NFILE,fnm),title,atoms,x,v,&ePBC,box);

  nres=atoms->nres;                /* nr of residues in one element? */

  if (bTRX) {
    if (!read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&xx,boxx))
      gmx_fatal(FARGS,"No atoms in trajectory %s",ftp2fn(efTRX,NFILE,fnm));
  } else {
    snew(xx,natoms);
    for(i=0; i<natoms; i++) {
      copy_rvec(x[i],xx[i]);
    }
  }
  
  
  for(k=0; (k<nz); k++) {          /* loop over all gridpositions    */
    shift[ZZ]=k*(dist[ZZ]+box[ZZ][ZZ]);
    
    for(j=0; (j<ny); j++) {
      shift[YY]=j*(dist[YY]+box[YY][YY])+k*box[ZZ][YY];
      
      for(i=0; (i<nx); i++)  {
	 shift[XX]=i*(dist[XX]+box[XX][XX])+j*box[YY][XX]+k*box[ZZ][XX];
	
	ndx=(i*ny*nz+j*nz+k)*natoms;
	nrdx=(i*ny*nz+j*nz+k)*nres;
	
	/* Random rotation on input coords */
	if (bRandom)
	  rand_rot(natoms,xx,v,xrot,vrot,&seed,max_rot);
	
	for(l=0; (l<natoms); l++) {
	  for(m=0; (m<DIM); m++) {
	    if (bRandom) {
	      x[ndx+l][m] = xrot[l][m];
	      v[ndx+l][m] = vrot[l][m];
	    }
	    else {
	      x[ndx+l][m] = xx[l][m];
	      v[ndx+l][m] = v[l][m];
	    }
	  }
	  if (ePBC == epbcSCREW && i % 2 == 1) {
	    /* Rotate around x axis */
	    for(m=YY; m<=ZZ; m++) {
	      x[ndx+l][m] = box[YY][m] + box[ZZ][m] - x[ndx+l][m];
	      v[ndx+l][m] = -v[ndx+l][m];
	    }
	  }
	  for(m=0; (m<DIM); m++) {
	    x[ndx+l][m] += shift[m];
	  }
	  atoms->atom[ndx+l].resnr=(bRenum ? nrdx:0) + atoms->atom[l].resnr;
	  atoms->atomname[ndx+l]=atoms->atomname[l];
	}

	for(l=0; (l<nres); l++)
	  atoms->resname[nrdx+l]=atoms->resname[l];
	if (bTRX)
	  if (!read_next_x(status,&t,natoms,xx,boxx) && 
	      ((i+1)*(j+1)*(k+1) < vol))
	    gmx_fatal(FARGS,"Not enough frames in trajectory");
      }
    }
  }
  if (bTRX)
    close_trj(status);

  /* make box bigger */
  for(m=0; (m<DIM); m++)
    box[m][m] += dist[m];
  svmul(nx,box[XX],box[XX]);
  svmul(ny,box[YY],box[YY]);
  svmul(nz,box[ZZ],box[ZZ]);
  if (ePBC == epbcSCREW && nx % 2 == 0) {
    /* With an even number of boxes in x we can forgot about the screw */
    ePBC = epbcXYZ;
  }

  /* move_x(natoms*vol,x,box); */          /* put atoms in box? */

  atoms->nr*=vol;
  atoms->nres*=vol;
  
  if (bShuffle)
    randwater(0,atoms->nr/nmolat,nmolat,x,v,&seed);
  else if (bSort)
    sortwater(0,atoms->nr/nmolat,nmolat,x,v);
  else if (opt2parg_bSet("-block",asize(pa),pa))
    mkcompact(0,atoms->nr/nmolat,nmolat,x,v,nblock,box);
  
  write_sto_conf(opt2fn("-o",NFILE,fnm),title,atoms,x,v,ePBC,box);
  
  thanx(stderr);
  
  return 0;
}
Beispiel #5
0
int main(int argc,char *argv[])
{
  const char *desc[] = {
    "sas2mat converts matrix data in [IT]raw[it] format to X PixMap format,",
    "which can be digested by [TT]xpm2ps[tt] to make nice plots.",
    "These [IT]raw[it] data may be generated by [TT]g_rms[tt], [TT]do_dssp[tt] or your",
    "own program.[PAR]",
    "The program prompts the user for some parameters:[PAR]",
    "[TT]Enter nres, res0, nframes, dt, t0, nlevels:[tt][PAR]",
    "In this context nres is the number of residues, res0 the starting residue",
    "dt is the time step, t0 is the starting time, nlevels is the number",
    "of levels for coloring. By default a greyscale colormap is generated."
  };
  static gmx_bool   bCol=FALSE;
  static char   *title="Area (nm^2)";
  static real   ssmin=-1,ssmax=-1,t0=0,dt=1;
  static int    nres=1,nframes=1,r0=0,nlevels=20,nskip=0;
  t_pargs pa[] = {
    { "-col",     FALSE,  etBOOL, &bCol,
      "The user is prompted for rgb lower and upper values" },
    { "-min",     FALSE,  etREAL, &ssmin,
      "Lower values for the data, calculated from the data by default" },
    { "-max",     FALSE,  etREAL, &ssmax,
      "Upper values for the data, see above" },
    { "-title",   FALSE,  etSTR,  &title,
      "Title for the graph" },
    { "-nlevel",  FALSE,  etINT,  &nlevels,
      "Number of levels in graph" },
    { "-nres",    FALSE,  etINT,  &nres,
      "Number of residues (Y-axis)" },
    { "-nframes", FALSE,  etINT,  &nframes,
      "Number of frames (Y-axis)" },
    { "-res0",    FALSE,  etINT,  &r0,
      "Number of first residue" },
    { "-nskip",   FALSE,  etINT,  &nskip,
      "Number of frames to skip after every frame" },
    { "-dt",      FALSE,  etREAL, &dt,
      "Time between time frames" },
    { "-t0",      FALSE,  etREAL, &t0,
      "Time of first time frame" }
  };
  
  FILE   *in,*out;
  int    i,j,k,ihi;
  double s;
  real   **ss,lo,hi,s1min,s1max;
  real   *resnr,*t;
  gmx_bool   bCheck=TRUE;
  t_rgb  rlo,rhi;
  t_filenm fnm[] = {
    { efOUT, "-f", "area", ffREAD },
    { efXPM, "-o", "sas",  ffWRITE }
  };
#define NFILE asize(fnm)

  /* If we want to read all frames nskip must be greater than zero */
  nskip += 1;

  CopyRight(stderr,argv[0]);
  
  parse_common_args(&argc,argv,PCA_BE_NICE,NFILE,fnm,asize(pa),pa,asize(desc),desc,
		    0,NULL);
  
  snew(ss,nres);
  snew(resnr,nres);
  snew(t,nframes);
  for(i=0; (i<nframes); i++) 
    t[i]=t0+i*dt;
  for(i=0; (i<nres); i++) {
    snew(ss[i],nframes);
  }
  in=ftp2FILE(efOUT,NFILE,fnm,"r");
  for(i=k=0; (i<nframes); i++) {
    for(j=0; (j<nres); j++) {
      fscanf(in,"%lf",&s);
      ss[j][k]=s;
    }
    if (!nskip || ((i % nskip) == 0))
      k++;
  }
  ffclose(in);
  nframes=k;

  lo=10000;
  hi=0;
  for(j=0; (j<nres); j++) {
    /* Find lowest SAS value and subtract that from all occurrences */
    s1min=10000;
    s1max=0;
    for(i=0; (i<nframes); i++) {
      s1min=min(s1min,ss[j][i]);
      s1max=max(s1max,ss[j][i]);
    }
    printf("res %d: ssmin=%g, ssmax=%g, diff=%g\n",j,s1min,s1max,s1max-s1min);
    hi=max(hi,s1max);
    lo=min(lo,s1min);
  }
  printf("Lowest and Highest SAS value: %g %g\n",lo,hi);

  if (ssmin == -1)
    ssmin=lo;
  if (ssmax == -1)
    ssmax=hi;
  
  /*
    hi=ssmax-ssmin;
    for(j=0; (j<nres); j++) {
    for(i=0; (i<nframes); i++) 
    ss[j][i]-=ssmin;
    }
    */

  /* ihi=hi; */
  rhi.r=0,rhi.g=0,rhi.b=0;
  rlo.r=1,rlo.g=1,rlo.b=1;
  if (bCol) {
    printf("Color entries:\n""drlo glo blo rhi ghi bhi\n");
    scanf("%f%f%f%f%f%f",&rlo.r,&rlo.g,&rlo.b,&rhi.r,&rhi.g,&rhi.b);
  }
  /*
  write_mapfile(ftp2fn(efMAP,NFILE,fnm),&nlevels,rlo,rhi,ssmin,ssmax);
  */

  for(i=0;i<nres;i++)
    resnr[i]=i+1;
  out=ftp2FILE(efXPM,NFILE,fnm,"w");
  /*
  write_matrix(out,nres,nframes,resnr,t,ss,NULL,title,0,hi,nlevels);
  */
  write_xpm(out,0,"????","????","Time (ps)","Residue",
	    nres,nframes,resnr,t,ss,ssmin,ssmax,rlo,rhi,&nlevels);

  thanx(stderr);
  
  return 0;
}
Beispiel #6
0
int gmx_tilt(int argc, char *argv[])
{
    const char      *desc[] = {
        "\tLook at the tilt angle of RalGDS when docked to different\n",
        "GTPases: p21Ras (1LFD.pdb) and Rap1a (1GUA.pdb).",
        "\tUse -s for the simulated molecule topology.  Use -fr for\n",
        "the reference molecule topology.\n",
        "\n",
        "Workflow:\n",
        "\t1) VMD STAMP Structural alignment of reference structure to\n",
        "\t   1LFD.pdb chain B (Ras).\n",
        "\t2) Make a .tpr of the reference structure (which has already\n",
        "\t   been aligned to 1LFD.pdb, per step 1)\n"
        "\t3) Kabsch alignment of a single frame of the simulation\n",
        "\t   trajectory to the GTPase of the reference structure.\n",
        "\t4) Use trjconv to align the GTPase of the simulated trajectory\n",
        "\t    to the (aligned) frame from step 3.\n",
        "\t5) Run this code.\n",
    };

    gmx_bool        bVerbose = FALSE;
    const char      *struct_file, *traj_file;
    const char      *ndx_file, *xvg_file;
    const char      *ref_file;
    t_tiltdata  data;
    t_pargs         pa[] = {
        { "-v", FALSE, etBOOL, {&bVerbose},
          "Be slightly more verbose"},
    };
    t_filenm        fnm[] = {
        {efTPS, NULL, NULL, ffREAD},
        {efTRX, NULL, NULL, ffREAD},
        //{efGRO, "-fr", NULL, ffREAD},
        {efTPS, "-fr", NULL, ffREAD},
        {efXVG, "-o","tilt",ffOPTWR},
        {efNDX, NULL, NULL, ffREAD},
    };
#define NFILE asize(fnm)
#define NPA asize(pa)
    output_env_t    oenv;
    int             ngrps, nrefgrps;
    t_topology      struct_top, ref_top;
    t_atoms         *struct_atoms=NULL, *ref_atoms=NULL;
    t_trxframe      struct_fr, ref_fr;
    t_trxstatus     *struct_status, *ref_status;
    rvec            *struct_xtop, *ref_xtop;
    matrix          struct_box, ref_box;
    int             struct_ePBC, ref_ePBC;
    int             struct_flags=TRX_READ_X, ref_flags=TRX_READ_X;
    char            buffer[1024];

    CopyRight(stderr,argv[0]);
    parse_common_args(&argc, argv, 
                      PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | 
                      PCA_TIME_UNIT | PCA_BE_NICE | PCA_CAN_TIME,
                      NFILE, fnm, NPA, pa, asize(desc), desc,
                      0, NULL, &oenv);

    /* Get inputs */
    struct_file = ftp2fn(efTPS, NFILE, fnm);
    traj_file   = opt2fn( "-f", NFILE, fnm);
    ref_file    = opt2fn("-fr", NFILE, fnm); 
    ndx_file    = ftp2fn(efNDX, NFILE, fnm);
    
    /* Open inputs */
    read_tps_conf(struct_file, buffer, &struct_top, &struct_ePBC,
                  &struct_xtop, NULL, struct_box, TRUE);
    sfree(struct_xtop);
    struct_atoms = &struct_top.atoms;

    read_tps_conf(ref_file, buffer, &ref_top, &ref_ePBC,
                  &ref_xtop, NULL, ref_box, TRUE);
    ref_atoms = &ref_top.atoms;

    /* open xvg file */
    data.fp = NULL;
    data.fp = xvgropen(opt2fn("-o", NFILE, fnm), "Center of Mass displacement","Time[ps]","Tilt Angle[degrees]", oenv);
    const char *flegend[] = {
                              "Time[ps]",
                              "tilt[deg]",
                              "rmsd[nm]",
                              "CoM displacement[nm]",
                              "Rotation axis x-component[nm]",
                              "Rotation axis y-component[nm]",
                              "Rotation axis z-component[nm]",
                              "X-axis rotation[deg]",
                              "Y-axis rotation[deg]",
                              "Z-axis rotation[deg]",
                            };
    xvgr_legend(data.fp,asize(flegend),flegend,oenv);

    /* Get index information */
    static int      n_structatoms, n_refatoms;
    atom_id         *ind_structatoms, *ind_refatoms;
    char            *gn_structatoms, *gn_refatoms;
    int             i_structatoms, i_refatoms;
    std::cout<< "\nSelect group from reference structure <" << ref_file << ">." << std::endl;
    get_index(ref_atoms, ndx_file, 1, &n_refatoms, &ind_refatoms, &gn_refatoms);
    std::cout<< "\nSelect group from simulation structure(s) <" << struct_file <<"> to compare to the reference structure, <" << ref_file << ">." << std::endl;
    get_index(struct_atoms, ndx_file, 1, &n_structatoms, &ind_structatoms, &gn_structatoms);

    if ( n_structatoms != n_refatoms ) 
    {
        gmx_fatal(FARGS, "\nThe number of atoms in the index groups are different.");
    }
     
    /* read the reference file and get coordinates */
    std::vector<float> ref_coords(n_refatoms*3,0);
    readCoords(n_refatoms, ind_refatoms, ref_xtop, &ref_top, ref_coords, bVerbose);

    /* read trajectory file and loop through frames */
    int nframes = 0;
    read_first_frame(oenv, &struct_status, traj_file, &struct_fr, struct_flags);
    do {
        std::vector<float> struct_coords(n_structatoms*3,0);
        readCoords(n_structatoms, ind_structatoms, &struct_fr, &struct_top, struct_coords, bVerbose);
        displacement(ref_coords, struct_coords, data, bVerbose);
        kabsch_alignment(ref_coords,struct_coords, data, bVerbose);
        data.time.push_back(struct_fr.time);
        nframes++;
    } while(read_next_frame(oenv, struct_status, &struct_fr));
    for (int i=0; i<nframes; i++)
    {
        fprintf(data.fp,"%8.2f %8.2f %8.3f %8.3f %12.6f %12.6f %12.6f %8.2f %8.2f %8.2f\n",data.time[i],data.rotation[i],data.rmsd[i],data.distance[i],data.x_rotation_axis[i],data.y_rotation_axis[i],data.z_rotation_axis[i],data.x_rotation[i],data.y_rotation[i],data.z_rotation[i]);
    }

    return 0;
}
int gmx_saltbr(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_saltbr[tt] plots the distance between all combination of charged groups",
    "as a function of time. The groups are combined in different ways.",
    "A minimum distance can be given (i.e. a cut-off), such that groups",
    "that are never closer than that distance will not be plotted.[PAR]",
    "Output will be in a number of fixed filenames, [TT]min-min.xvg[tt], [TT]plus-min.xvg[tt]",
    "and [TT]plus-plus.xvg[tt], or files for every individual ion pair if the [TT]-sep[tt]",
    "option is selected. In this case, files are named as [TT]sb-(Resname)(Resnr)-(Atomnr)[tt].",
    "There may be [BB]many[bb] such files."
  };
  static gmx_bool bSep=FALSE;
  static real truncate=1000.0;
  t_pargs pa[] = {
    { "-t",   FALSE, etREAL, {&truncate},
      "trunc distance" },
    { "-sep", FALSE, etBOOL, {&bSep},
      "Use separate files for each interaction (may be MANY)" }
  };
  t_filenm   fnm[] = {
    { efTRX, "-f",  NULL, ffREAD },
    { efTPX, NULL,  NULL, ffREAD },
  };
#define NFILE asize(fnm)

  FILE       *out[3],*fp;
  static const char *title[3] = {
    "Distance between positively charged groups",
    "Distance between negatively charged groups",
    "Distance between oppositely charged groups"
  };
  static const char *fn[3] = {
    "plus-plus.xvg",
    "min-min.xvg",
    "plus-min.xvg"
  };
  int        nset[3]={0,0,0};
  
  t_topology *top;
  int        ePBC;
  char       *buf;
  t_trxstatus *status;
  int        i,j,k,m,nnn,teller,ncg,n1,n2,n3,natoms;
  real       t,*time,qi,qj;
  t_charge   *cg;
  real       ***cgdist;
  int        **nWithin;
  
  double     t0,dt;
  char       label[234];
  t_pbc      pbc;
  rvec       *x;
  matrix     box;
  output_env_t oenv;
  
  CopyRight(stderr,argv[0]);

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
  
  top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC);
  cg=mk_charge(&top->atoms,&(top->cgs),&ncg);
  snew(cgdist,ncg);
  snew(nWithin,ncg);
  for(i=0; (i<ncg); i++) {
    snew(cgdist[i],ncg);
    snew(nWithin[i],ncg);
  }
  
  natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  
  teller=0;
  time=NULL;
  do {
    srenew(time,teller+1);
    time[teller]=t;
    
    set_pbc(&pbc,ePBC,box);
    
    for(i=0; (i<ncg); i++) {
      for(j=i+1; (j<ncg); j++) {
	srenew(cgdist[i][j],teller+1);
	cgdist[i][j][teller]=
	  calc_dist(&pbc,x,&(top->cgs),cg[i].cg,cg[j].cg);
	if (cgdist[i][j][teller] < truncate)
	  nWithin[i][j]=1;
      }
    }
          
    teller++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));
  fprintf(stderr,"\n");
  close_trj(status);

  if (bSep) {
    snew(buf,256);
    for(i=0; (i<ncg); i++)
      for(j=i+1; (j<ncg); j++) {
	if (nWithin[i][j]) {
	  sprintf(buf,"sb-%s:%s.xvg",cg[i].label,cg[j].label);
	  fp=xvgropen(buf,buf,"Time (ps)","Distance (nm)",oenv);
	  for(k=0; (k<teller); k++) 
	    fprintf(fp,"%10g  %10g\n",time[k],cgdist[i][j][k]);
	  ffclose(fp);
	}
      }
    sfree(buf);
  }
  else {
  
    for(m=0; (m<3); m++)
      out[m]=xvgropen(fn[m],title[m],"Time (ps)","Distance (nm)",oenv);

    snew(buf,256);
    for(i=0; (i<ncg); i++) {
      qi=cg[i].q;
      for(j=i+1; (j<ncg); j++) {
	qj=cg[j].q;
	if (nWithin[i][j]) {
	  sprintf(buf,"%s:%s",cg[i].label,cg[j].label);
	  if (qi*qj < 0) 
	    nnn=2;
	  else if (qi+qj > 0) 
	    nnn=0;
	  else 
	    nnn=1;
	  
	  if (nset[nnn] == 0) 
	    xvgr_legend(out[nnn],1,(const char**)&buf,oenv);
	  else {
	    if (output_env_get_xvg_format(oenv) == exvgXMGR) {
	      fprintf(out[nnn],"@ legend string %d \"%s\"\n",nset[nnn],buf);
	    } else if (output_env_get_xvg_format(oenv) == exvgXMGRACE) {
	      fprintf(out[nnn],"@ s%d legend \"%s\"\n",nset[nnn],buf);
	    }
	  }
	  nset[nnn]++;
	  nWithin[i][j]=nnn+1;
	}
      }  
    }
    for(k=0; (k<teller); k++) {
      for(m=0; (m<3); m++)
	fprintf(out[m],"%10g",time[k]);
    
      for(i=0; (i<ncg); i++) {
	for(j=i+1; (j<ncg); j++) {
	  nnn=nWithin[i][j];
	  if (nnn >0) 
	    fprintf(out[nnn-1],"  %10g",cgdist[i][j][k]);
	}
      }
      for(m=0; (m<3); m++) 
	fprintf(out[m],"\n");
    }
    for(m=0; (m<3); m++) {
      ffclose(out[m]);
      if (nset[m] == 0)
	remove(fn[m]);
    }
  }
  thanx(stderr);
    
  return 0;
}
Beispiel #8
0
int cmain (int argc,char *argv[])
{
    const char *desc[] = {
        "[TT]g_protonate[tt] reads (a) conformation(s) and adds all missing",
        "hydrogens as defined in [TT]gmx2.ff/aminoacids.hdb[tt]. If only [TT]-s[tt] is",
        "specified, this conformation will be protonated, if also [TT]-f[tt]",
        "is specified, the conformation(s) will be read from this file, ",
        "which can be either a single conformation or a trajectory.",
        "[PAR]",
        "If a [TT].pdb[tt] file is supplied, residue names might not correspond to",
        "to the GROMACS naming conventions, in which case these residues will",
        "probably not be properly protonated.",
        "[PAR]",
        "If an index file is specified, please note that the atom numbers",
        "should correspond to the [BB]protonated[bb] state."
    };

    char        title[STRLEN+1];
    const char  *infile;
    char        *grpnm;
    t_topology  top;
    int         ePBC;
    t_atoms     *atoms,*iatoms;
    t_protonate protdata;
    atom_id     *index;
    t_trxstatus *status;
    t_trxstatus *out;
    t_trxframe  fr,frout;
    rvec        *x,*ix;
    int         nidx,natoms,natoms_out;
    matrix      box;
    int         i,frame,resind;
    gmx_bool        bReadMultiple;
    output_env_t oenv;

    const char *bugs[] = {
        "For the moment, only .pdb files are accepted to the -s flag"
    };

    t_filenm fnm[] = {
        { efTPS, NULL, NULL,         ffREAD  },
        { efTRX, "-f", NULL,         ffOPTRD },
        { efNDX, NULL, NULL,         ffOPTRD },
        { efTRO, "-o", "protonated", ffWRITE }
    };
#define NFILE asize(fnm)

    CopyRight(stderr,argv[0]);
    parse_common_args(&argc,argv,PCA_CAN_TIME,
                      NFILE,fnm,0,NULL,asize(desc),desc,asize(bugs),bugs,&oenv);

    infile=opt2fn("-s",NFILE,fnm);
    read_tps_conf(infile,title,&top,&ePBC,&x,NULL,box,FALSE);
    atoms=&(top.atoms);
    printf("Select group to process:\n");
    get_index(atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&nidx,&index,&grpnm);
    bReadMultiple = opt2bSet("-f",NFILE,fnm);
    if (bReadMultiple) {
        infile = opt2fn("-f",NFILE,fnm);
        if ( !read_first_frame(oenv,&status, infile, &fr, TRX_NEED_X ) ) {
            gmx_fatal(FARGS,"cannot read coordinate file %s",infile);
        }
        natoms = fr.natoms;
    } else {
        clear_trxframe(&fr,TRUE);
        fr.natoms = atoms->nr;
        fr.bTitle = TRUE;
        fr.title  = title;
        fr.bX     = TRUE;
        fr.x      = x;
        fr.bBox   = TRUE;
        copy_mat(box, fr.box);
        natoms = fr.natoms;
    }

    /* check input */
    if ( natoms == 0 ) {
        gmx_fatal(FARGS,"no atoms in coordinate file %s",infile);
    }

    if ( natoms > atoms->nr ) {
        gmx_fatal(FARGS,"topology with %d atoms does not match "
                  "coordinates with %d atoms",atoms->nr,natoms);
    }

    for(i=0; i<nidx; i++) {
        if (index[i] > natoms) {
            gmx_fatal(FARGS,"An atom number in group %s is larger than the number of "
                      "atoms (%d) in the coordinate file %s",grpnm,natoms,infile);
        }
    }

    /* get indexed copy of atoms */
    snew(iatoms,1);
    init_t_atoms(iatoms,nidx,FALSE);
    snew(iatoms->atom, iatoms->nr);
    resind = 0;
    for(i=0; i<nidx; i++) {
        iatoms->atom[i] = atoms->atom[index[i]];
        iatoms->atomname[i] = atoms->atomname[index[i]];
        if ( i>0 && (atoms->atom[index[i]].resind!=atoms->atom[index[i-1]].resind) ) {
            resind++;
        }
        iatoms->atom[i].resind = resind;
        iatoms->resinfo[resind] = atoms->resinfo[atoms->atom[index[i]].resind];
        /* allocate some space for the rtp name and copy from name */
        snew(iatoms->resinfo[resind].rtp,1);
        *iatoms->resinfo[resind].rtp = gmx_strdup(*atoms->resinfo[resind].name);

        iatoms->nres = max(iatoms->nres, iatoms->atom[i].resind+1);
    }

    init_t_protonate(&protdata);

    out = open_trx(opt2fn("-o",NFILE,fnm),"w");
    snew(ix, nidx);
    frame=0;
    do {
        if (debug) {
            fprintf(debug,"FRAME %d (%d %g)\n",frame,fr.step,fr.time);
        }
        /* get indexed copy of x */
        for(i=0; i<nidx; i++) {
            copy_rvec(fr.x[index[i]], ix[i]);
        }
        /* protonate */
        natoms_out = protonate(&iatoms, &ix, &protdata);

        /* setup output frame */
        frout = fr;
        frout.natoms = natoms_out;
        frout.bAtoms = TRUE;
        frout.atoms  = iatoms;
        frout.bV     = FALSE;
        frout.bF     = FALSE;
        frout.x      = ix;

        /* write output */
        write_trxframe(out,&frout,NULL);
        frame++;
    } while ( bReadMultiple && read_next_frame(oenv,status, &fr) );

    sfree(ix);
    sfree(iatoms);

    thanx(stderr);

    return 0;
}
Beispiel #9
0
int
gmx_select(int argc, char *argv[])
{
    const char *desc[] = {
        "g_select writes out basic data about dynamic selections.",
        "It can be used for some simple analyses, or the output can",
        "be combined with output from other programs and/or external",
        "analysis programs to calculate more complex things.",
        "Any combination of the output options is possible, but note",
        "that [TT]-om[tt] only operates on the first selection.[PAR]",
        "With [TT]-os[tt], calculates the number of positions in each",
        "selection for each frame. With [TT]-norm[tt], the output is",
        "between 0 and 1 and describes the fraction from the maximum",
        "number of positions (e.g., for selection 'resname RA and x < 5'",
        "the maximum number of positions is the number of atoms in",
        "RA residues). With [TT]-cfnorm[tt], the output is divided",
        "by the fraction covered by the selection.",
        "[TT]-norm[tt] and [TT]-cfnorm[tt] can be specified independently",
        "of one another.[PAR]",
        "With [TT]-oc[tt], the fraction covered by each selection is",
        "written out as a function of time.[PAR]",
        "With [TT]-oi[tt], the selected atoms/residues/molecules are",
        "written out as a function of time. In the output, the first",
        "column contains the frame time, the second contains the number",
        "of positions, followed by the atom/residue/molecule numbers.",
        "If more than one selection is specified, the size of the second",
        "group immediately follows the last number of the first group",
        "and so on. With [TT]-dump[tt], the frame time and the number",
        "of positions is omitted from the output. In this case, only one",
        "selection can be given.[PAR]",
        "With [TT]-on[tt], the selected atoms are written as a index file",
        "compatible with make_ndx and the analyzing tools. Each selection",
        "is written as a selection group and for dynamic selections a",
        "group is written for each frame.[PAR]",
        "For residue numbers, the output of [TT]-oi[tt] can be controlled",
        "with [TT]-resnr[tt]: [TT]number[tt] (default) prints the residue",
        "numbers as they appear in the input file, while [TT]index[tt] prints",
        "unique numbers assigned to the residues in the order they appear",
        "in the input file, starting with 1. The former is more intuitive,",
        "but if the input contains multiple residues with the same number,",
        "the output can be less useful.[PAR]",
        "With [TT]-om[tt], a mask is printed for the first selection",
        "as a function of time. Each line in the output corresponds to",
        "one frame, and contains either 0/1 for each atom/residue/molecule",
        "possibly selected. 1 stands for the atom/residue/molecule being",
        "selected for the current frame, 0 for not selected.",
        "With [TT]-dump[tt], the frame time is omitted from the output.",
    };

    gmx_bool                bDump     = FALSE;
    gmx_bool                bFracNorm = FALSE;
    gmx_bool                bTotNorm  = FALSE;
    const char         *routt[] = {NULL, "number", "index", NULL};
    t_pargs             pa[] = {
        {"-dump",   FALSE, etBOOL, {&bDump},
         "Do not print the frame time (-om, -oi) or the index size (-oi)"},
        {"-norm",   FALSE, etBOOL, {&bTotNorm},
         "Normalize by total number of positions with -os"},
        {"-cfnorm", FALSE, etBOOL, {&bFracNorm},
         "Normalize by covered fraction with -os"},
        {"-resnr",  FALSE, etENUM, {routt},
         "Residue number output type"},
    };

    t_filenm            fnm[] = {
        {efXVG, "-os", "size.xvg",  ffOPTWR},
        {efXVG, "-oc", "cfrac.xvg", ffOPTWR},
        {efDAT, "-oi", "index.dat", ffOPTWR},
        {efDAT, "-om", "mask.dat",  ffOPTWR},
        {efNDX, "-on", "index.ndx", ffOPTWR},
    };
#define NFILE asize(fnm)

    gmx_ana_traj_t       *trj;
    t_topology           *top;
    int                   ngrps;
    gmx_ana_selection_t **sel;
    char                **grpnames;
    t_dsdata              d;
    const char            *fnSize, *fnFrac, *fnIndex, *fnNdx, *fnMask;
    int                   g;
    int                   rc;
    output_env_t          oenv;

    CopyRight(stderr, argv[0]);
    gmx_ana_traj_create(&trj, 0);
    gmx_ana_set_nanagrps(trj, -1);
    parse_trjana_args(trj, &argc, argv, 0,
                      NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL,
                      &oenv);
    gmx_ana_get_nanagrps(trj, &ngrps);
    gmx_ana_get_anagrps(trj, &sel);
    gmx_ana_init_coverfrac(trj, CFRAC_SOLIDANGLE);

    /* Get output file names */
    fnSize  = opt2fn_null("-os", NFILE, fnm);
    fnFrac  = opt2fn_null("-oc", NFILE, fnm);
    fnIndex = opt2fn_null("-oi", NFILE, fnm);
    fnNdx   = opt2fn_null("-on", NFILE, fnm);
    fnMask  = opt2fn_null("-om", NFILE, fnm);
    /* Write out sizes if nothing specified */
    if (!fnFrac && !fnIndex && !fnMask && !fnNdx)
    {
        fnSize = opt2fn("-os", NFILE, fnm);
    }

    if ( bDump && ngrps > 1)
    {
        gmx_fatal(FARGS, "Only one index group allowed with -dump");
    }
    if (fnNdx && sel[0]->p.m.type != INDEX_ATOM)
    {
        gmx_fatal(FARGS, "Only atom selection allowed with -on");
    }
    if (fnMask && ngrps > 1)
    {
        fprintf(stderr, "warning: the mask (-om) will only be written for the first group\n");
    }
    if (fnMask && !sel[0]->bDynamic)
    {
        fprintf(stderr, "warning: will not write the mask (-om) for a static selection\n");
        fnMask = NULL;
    }

    /* Initialize reference calculation for masks */
    if (fnMask)
    {
        gmx_ana_get_topology(trj, FALSE, &top, NULL);
        snew(d.mmap, 1);
        gmx_ana_indexmap_init(d.mmap, sel[0]->g, top, sel[0]->p.m.type);
    }

    /* Initialize calculation data */
    d.bDump     = bDump;
    d.bFracNorm = bFracNorm;
    d.routt     = routt[0];
    snew(d.size,  ngrps);
    for (g = 0; g < ngrps; ++g)
    {
        d.size[g] = bTotNorm ? sel[g]->p.nr : 1;
    }

    /* Open output files */
    d.sfp = d.cfp = d.ifp = d.mfp = NULL;
    d.block = NULL;
    gmx_ana_get_grpnames(trj, &grpnames);
    if (fnSize)
    {
        d.sfp = xvgropen(fnSize, "Selection size", "Time (ps)", "Number",oenv);
        xvgr_selections(d.sfp, trj);
        xvgr_legend(d.sfp, ngrps, (const char**)grpnames, oenv);
    }
    if (fnFrac)
    {
        d.cfp = xvgropen(fnFrac, "Covered fraction", "Time (ps)", "Fraction",
                         oenv);
        xvgr_selections(d.cfp, trj);
        xvgr_legend(d.cfp, ngrps, (const char**)grpnames, oenv);
    }
    if (fnIndex)
    {
        d.ifp = ffopen(fnIndex, "w");
        xvgr_selections(d.ifp, trj);
    }
    if (fnNdx)
    {
        d.block = new_blocka();
        d.gnames = NULL;
    }
    if (fnMask)
    {
        d.mfp = ffopen(fnMask, "w");
        xvgr_selections(d.mfp, trj);
    }

    /* Do the analysis and write out results */
    gmx_ana_do(trj, 0, &print_data, &d);

    /* Close the files */
    if (d.sfp)
    {
        ffclose(d.sfp);
    }
    if (d.cfp)
    {
        ffclose(d.cfp);
    }
    if (d.ifp)
    {
        ffclose(d.ifp);
    }
    if (d.block)
    {
        write_index(fnNdx, d.block, d.gnames);
    }
    if (d.mfp)
    {
        ffclose(d.mfp);
    }

    thanx(stderr);

    return 0;
}
int gmx_sorient(int argc,char *argv[])
{
  t_topology top;
  int      ePBC;
  char     title[STRLEN];
  int      status;
  int      natoms;
  real     t;
  rvec     *xtop,*x;
  matrix   box;
  
  FILE    *fp;
  int     i,j,p,sa0,sa1,sa2,n,ntot,nf,m,*hist1,*hist2,*histn,nbin1,nbin2,nrbin;
  real    *histi1,*histi2,invbw,invrbw;
  double  sum1,sum2;
  int     *isize,nrefgrp,nrefat;
  atom_id **index;
  char    **grpname;
  real    inp,outp,two_pi,nav,normfac,rmin2,rmax2,rcut,rcut2,r2,r,mass,mtot;
  real    c1,c2;
  char    str[STRLEN];
  bool    bTPS;
  rvec    xref,dx,dxh1,dxh2,outer;
  t_pbc   pbc;
  char    *legr[] = { "<cos(\\8q\\4\\s1\\N)>", 
		      "<3cos\\S2\\N(\\8q\\4\\s2\\N)-1>" };
  char    *legc[] = { "cos(\\8q\\4\\s1\\N)", 
		      "3cos\\S2\\N(\\8q\\4\\s2\\N)-1" };
  
  static char *desc[] = {
    "g_sorient analyzes solvent orientation around solutes.", 
    "It calculates two angles between the vector from one or more",
    "reference positions to the first atom of each solvent molecule:[BR]"
    "theta1: the angle with the vector from the first atom of the solvent",
    "molecule to the midpoint between atoms 2 and 3.[BR]",
    "theta2: the angle with the normal of the solvent plane, defined by the",
    "same three atoms, or when the option [TT]-v23[tt] is set",
    "the angle with the vector between atoms 2 and 3.[BR]",
    "The reference can be a set of atoms or",
    "the center of mass of a set of atoms. The group of solvent atoms should",
    "consist of 3 atoms per solvent molecule.",
    "Only solvent molecules between [TT]-rmin[tt] and [TT]-rmax[tt] are",
    "considered for [TT]-o[tt] and [TT]-no[tt] each frame.[PAR]",
    "[TT]-o[tt]: distribtion of cos(theta1) for rmin<=r<=rmax.[PAR]",
    "[TT]-no[tt]: distribution of cos(theta2) for rmin<=r<=rmax.[PAR]",
    "[TT]-ro[tt]: <cos(theta1)> and <3cos^2(theta2)-1> as a function of the",
    "distance.[PAR]",
    "[TT]-co[tt]: the sum over all solvent molecules within distance r",
    "of cos(theta1) and 3cos^2(theta2)-1 as a function of r.[PAR]",
    "[TT]-rc[tt]: the distribution of the solvent molecules as a function of r"
  };
  
  static bool bCom = FALSE,bVec23=FALSE,bPBC = FALSE;
  static real rmin=0.0,rmax=0.5,binwidth=0.02,rbinw=0.02;
  t_pargs pa[] = {
    { "-com",  FALSE, etBOOL,  {&bCom},
      "Use the center of mass as the reference postion" },
    { "-v23",  FALSE, etBOOL,  {&bVec23},
      "Use the vector between atoms 2 and 3" },
    { "-rmin",  FALSE, etREAL, {&rmin}, "Minimum distance (nm)" },
    { "-rmax",  FALSE, etREAL, {&rmax}, "Maximum distance (nm)" },
    { "-cbin",  FALSE, etREAL, {&binwidth}, "Binwidth for the cosine" },
    { "-rbin",  FALSE, etREAL, {&rbinw}, "Binwidth for r (nm)" },
    { "-pbc",   FALSE, etBOOL, {&bPBC}, "Check PBC for the center of mass calculation. Only necessary when your reference group consists of several molecules." }
  };
  
  t_filenm fnm[] = {
    { efTRX, NULL,  NULL,  ffREAD },
    { efTPS, NULL,  NULL,  ffREAD },
    { efNDX, NULL,  NULL,  ffOPTRD },
    { efXVG, NULL,  "sori.xvg",  ffWRITE },
    { efXVG, "-no", "snor.xvg",  ffWRITE },
    { efXVG, "-ro", "sord.xvg",  ffWRITE },
    { efXVG, "-co", "scum.xvg",  ffWRITE },
    { efXVG, "-rc", "scount.xvg",  ffWRITE }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);
  
  two_pi = 2/M_PI;

  bTPS = (opt2bSet("-s",NFILE,fnm) || !opt2bSet("-n",NFILE,fnm) || bCom);
  if (bTPS) {
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,
		  bCom);
  }

  /* get index groups */
  printf("Select a group of reference particles and a solvent group:\n"); 
  snew(grpname,2);
  snew(index,2);
  snew(isize,2);
  if (bTPS) {
    get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),2,isize,index,grpname);
  } else {
    get_index(NULL,ftp2fn(efNDX,NFILE,fnm),2,isize,index,grpname);
  }

  if (bCom) {
    nrefgrp = 1;
    nrefat  = isize[0];
  } else {
    nrefgrp = isize[0];
    nrefat  = 1;
  }

  if (isize[1] % 3)
    gmx_fatal(FARGS,"The number of solvent atoms (%d) is not a multiple of 3",
		isize[1]);

  /* initialize reading trajectory:                         */
  natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);

  rmin2 = sqr(rmin);
  rmax2 = sqr(rmax);
  rcut  = 0.99*sqrt(max_cutoff2(guess_ePBC(box),box));
  if (rcut == 0)
    rcut = 10*rmax;
  rcut2 = sqr(rcut);

  invbw = 1/binwidth;
  nbin1 = (int)(2*invbw + 0.5);
  nbin2 = (int)(invbw + 0.5);

  invrbw = 1/rbinw;
  
  snew(hist1,nbin1+1);
  snew(hist2,nbin2+1);
  nrbin = rcut/rbinw;
  if (nrbin == 0)
    nrbin = 1;
  snew(histi1,nrbin);
  snew(histi2,nrbin);
  snew(histn,nrbin);

  ntot = 0;
  nf = 0;
  sum1 = 0;
  sum2 = 0;

  /* start analysis of trajectory */
  do {
    if (bTPS) {
      /* make molecules whole again */
      rm_pbc(&top.idef,ePBC,natoms,box,x,x);
    }
    
    set_pbc(&pbc,ePBC,box);
    n    = 0;
    inp  = 0;
    outp = 0;
    for(p=0; (p<nrefgrp); p++) {
      if (bCom)
	calc_com_pbc(nrefat,&top,x,&pbc,index[0],xref,bPBC,box);
      else
	copy_rvec(x[index[0][p]],xref);

      for(m=0; m<isize[1]; m+=3) {
	sa0 = index[1][m];
	sa1 = index[1][m+1];
	sa2 = index[1][m+2];
	pbc_dx(&pbc,x[sa0],xref,dx);
	r2  = norm2(dx);
	if (r2 < rcut2) {
	  r = sqrt(r2);
	  if (!bVec23) {
	    /* Determine the normal to the plain */
	    rvec_sub(x[sa1],x[sa0],dxh1);
	    rvec_sub(x[sa2],x[sa0],dxh2);
	    rvec_inc(dxh1,dxh2);
	    svmul(1/r,dx,dx);
	    unitv(dxh1,dxh1);
	    inp = iprod(dx,dxh1);
	    cprod(dxh1,dxh2,outer);
	    unitv(outer,outer);
	    outp = iprod(dx,outer);
	  } else {
	    /* Use the vector between the 2nd and 3rd atom */
	    rvec_sub(x[sa2],x[sa1],dxh2);
	    unitv(dxh2,dxh2);
	    outp = iprod(dx,dxh2)/r;
	  }
	  (histi1[(int)(invrbw*r)]) += inp;
	  (histi2[(int)(invrbw*r)]) += 3*sqr(outp) - 1;
	  (histn[(int)(invrbw*r)])++;
	  if (r2>=rmin2 && r2<rmax2) {
	    (hist1[(int)(invbw*(inp + 1))])++;
	    (hist2[(int)(invbw*fabs(outp))])++;
	    sum1 += inp;
	    sum2 += outp;
	     n++;
	  }
	}
      }
    }
    ntot += n;
    nf++;

  }  while (read_next_x(status,&t,natoms,x,box));

  /* clean up */
  sfree(x);
  close_trj(status);

  /* Add the bin for the exact maximum to the previous bin */
  hist1[nbin1-1] += hist1[nbin1];
  hist2[nbin2-1] += hist2[nbin2];
  
  nav     = (real)ntot/(nrefgrp*nf);
  normfac = invbw/ntot;
  
  fprintf(stderr,  "Average nr of molecules between %g and %g nm: %.1f\n",
	  rmin,rmax,nav);
  if (ntot > 0) {
    sum1 /= ntot;
    sum2 /= ntot;
    fprintf(stderr,"Average cos(theta1)     between %g and %g nm: %6.3f\n",
	    rmin,rmax,sum1);
    fprintf(stderr,"Average 3cos2(theta2)-1 between %g and %g nm: %6.3f\n",
	    rmin,rmax,sum2);
  }
  
  sprintf(str,"Solvent orientation between %g and %g nm",rmin,rmax);
  fp=xvgropen(opt2fn("-o",NFILE,fnm), 
	      str,"cos(\\8q\\4\\s1\\N)",""); 
  if (bPrintXvgrCodes())
    fprintf(fp,"@ subtitle \"average shell size %.1f molecules\"\n",nav);
  for(i=0; i<nbin1; i++) {
    fprintf(fp,"%g %g\n",(i+0.5)*binwidth-1,2*normfac*hist1[i]);
  }
  fclose(fp);
  
  sprintf(str,"Solvent normal orientation between %g and %g nm",rmin,rmax);
  fp=xvgropen(opt2fn("-no",NFILE,fnm), 
	      str,"cos(\\8q\\4\\s2\\N)","");
  if (bPrintXvgrCodes())
    fprintf(fp,"@ subtitle \"average shell size %.1f molecules\"\n",nav);
  for(i=0; i<nbin2; i++) {
    fprintf(fp,"%g %g\n",(i+0.5)*binwidth,normfac*hist2[i]);
  }
  fclose(fp);

  
  sprintf(str,"Solvent orientation");
  fp=xvgropen(opt2fn("-ro",NFILE,fnm),str,"r (nm)","");
  if (bPrintXvgrCodes())
    fprintf(fp,"@ subtitle \"as a function of distance\"\n");
  xvgr_legend(fp,2,legr);
  for(i=0; i<nrbin; i++)
    fprintf(fp,"%g %g %g\n",(i+0.5)*rbinw,
	    histn[i] ? histi1[i]/histn[i] : 0,
	    histn[i] ? histi2[i]/histn[i] : 0);
  fclose(fp);
  
  sprintf(str,"Cumulative solvent orientation");
  fp=xvgropen(opt2fn("-co",NFILE,fnm),str,"r (nm)","");
  if (bPrintXvgrCodes())
    fprintf(fp,"@ subtitle \"as a function of distance\"\n");
  xvgr_legend(fp,2,legc);
  normfac = 1.0/(nrefgrp*nf);
  c1 = 0;
  c2 = 0;
  fprintf(fp,"%g %g %g\n",0.0,c1,c2);
  for(i=0; i<nrbin; i++) {
    c1 += histi1[i]*normfac;
    c2 += histi2[i]*normfac;
    fprintf(fp,"%g %g %g\n",(i+1)*rbinw,c1,c2);
  }
  fclose(fp);

  sprintf(str,"Solvent distribution");
  fp=xvgropen(opt2fn("-rc",NFILE,fnm),str,"r (nm)","molecules/nm");
  if (bPrintXvgrCodes())
    fprintf(fp,"@ subtitle \"as a function of distance\"\n");
  normfac = 1.0/(rbinw*nf);
  for(i=0; i<nrbin; i++) {
    fprintf(fp,"%g %g\n",(i+0.5)*rbinw,histn[i]*normfac);
  }
  fclose(fp);

  do_view(opt2fn("-o",NFILE,fnm),NULL);
  do_view(opt2fn("-no",NFILE,fnm),NULL);
  do_view(opt2fn("-ro",NFILE,fnm),"-nxy");
  do_view(opt2fn("-co",NFILE,fnm),"-nxy");

  thanx(stderr);
  
  return 0;
}
Beispiel #11
0
int gmx_genion(int argc, char *argv[])
{
  const char *desc[] = {
    "genion replaces solvent molecules by monoatomic ions at",
    "the position of the first atoms with the most favorable electrostatic",
    "potential or at random. The potential is calculated on all atoms, using",
    "normal GROMACS particle based methods (in contrast to other methods",
    "based on solving the Poisson-Boltzmann equation).",
    "The potential is recalculated after every ion insertion.",
    "If specified in the run input file, a reaction field, shift function",
    "or user function can be used. For the user function a table file",
    "can be specified with the option [TT]-table[tt].",
    "The group of solvent molecules should be continuous and all molecules",
    "should have the same number of atoms.",
    "The user should add the ion molecules to the topology file and include",
    "the file [TT]ions.itp[tt].",
    "Ion names for Gromos96 should include the charge.[PAR]",
    "With the option [TT]-pot[tt] the potential can be written as B-factors",
    "in a pdb file (for visualisation using e.g. rasmol).",
    "The unit of the potential is 1000 kJ/(mol e), the scaling be changed",
    "with the [TT]-scale[tt] option.[PAR]",
    "For larger ions, e.g. sulfate we recommended to use genbox."
  };
  const char *bugs[] = {
    "Calculation of the potential is not reliable, therefore the [TT]-random[tt] option is now turned on by default.",
    "If you specify a salt concentration existing ions are not taken into account. In effect you therefore specify the amount of salt to be added."
  };
  static int  p_num=0,n_num=0,p_q=1,n_q=-1;
  static const char *p_name="Na",*n_name="Cl";
  static real rmin=0.6,scale=0.001,conc=0;
  static int  seed=1993;
  static bool bRandom=TRUE,bNeutral=FALSE;
  static t_pargs pa[] = {
    { "-np",    FALSE, etINT,  {&p_num}, "Number of positive ions"       },
    { "-pname", FALSE, etSTR,  {&p_name},"Name of the positive ion"      },
    { "-pq",    FALSE, etINT,  {&p_q},   "Charge of the positive ion"    },
    { "-nn",    FALSE, etINT,  {&n_num}, "Number of negative ions"       },
    { "-nname", FALSE, etSTR,  {&n_name},"Name of the negative ion"      },
    { "-nq",    FALSE, etINT,  {&n_q},   "Charge of the negative ion"    },
    { "-rmin",  FALSE, etREAL, {&rmin},  "Minimum distance between ions" },
    { "-random",FALSE,etBOOL, {&bRandom},"Use random placement of ions instead of based on potential. The rmin option should still work" },
    { "-seed",  FALSE, etINT,  {&seed},  "Seed for random number generator" },
    { "-scale", FALSE, etREAL, {&scale}, "Scaling factor for the potential for -pot" },
    { "-conc",  FALSE, etREAL, {&conc},  
      "Specify salt concentration (mol/liter). This will add sufficient ions to reach up to the specified concentration as computed from the volume of the cell in the input tpr file. Overrides the -np and  nn options." },
    { "-neutral", FALSE, etBOOL, {&bNeutral},
      "This option will add enough ions to neutralize the system. In combination with the concentration option a neutral system at a given salt concentration will be generated." }
  };
  gmx_mtop_t  *mtop;
  gmx_localtop_t *top;
  t_inputrec  inputrec;
  t_commrec   *cr;
  t_mdatoms   *mdatoms;
  gmx_enerdata_t enerd;
  t_graph     *graph;
  t_forcerec  *fr;
  rvec        *x,*v;
  real        *pot,vol,qtot;
  matrix      box;
  t_atoms     atoms;
  t_pbc       pbc;
  int         *repl;
  atom_id     *index;
  char        *grpname;
  bool        *bSet,bPDB;
  int         i,nw,nwa,nsa,nsalt,iqtot;
  FILE        *fplog;
  t_filenm fnm[] = {
    { efTPX, NULL,  NULL,      ffREAD  },
    { efXVG, "-table","table", ffOPTRD },
    { efNDX, NULL,  NULL,      ffOPTRD },
    { efSTO, "-o",  NULL,      ffWRITE },
    { efLOG, "-g",  "genion",  ffWRITE },
    { efPDB, "-pot", "pot",    ffOPTWR },
    { efTOP, "-p",  "topol",   ffOPTRW }
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_BE_NICE,NFILE,fnm,asize(pa),pa,asize(desc),desc,
		    asize(bugs),bugs);
  bPDB = ftp2bSet(efPDB,NFILE,fnm);
  if (bRandom && bPDB) {
    fprintf(stderr,"Not computing potential with random option!\n");
    bPDB = FALSE;
  }
    
  /* Check input for something sensible */
  if ((p_num<0) || (n_num<0))
    gmx_fatal(FARGS,"Negative number of ions to add?");

  snew(mtop,1);
  snew(top,1);
  fplog = init_calcpot(ftp2fn(efLOG,NFILE,fnm),ftp2fn(efTPX,NFILE,fnm),
		       opt2fn("-table",NFILE,fnm),mtop,top,&inputrec,&cr,
		       &graph,&mdatoms,&fr,&enerd,&pot,box,&x);

  atoms = gmx_mtop_global_atoms(mtop);

  qtot = 0;
  for(i=0; (i<atoms.nr); i++)
    qtot += atoms.atom[i].q;
  iqtot = gmx_nint(qtot);
    
  if ((conc > 0) || bNeutral) {
    /* Compute number of ions to be added */
    vol = det(box);
    if (conc > 0) {
      nsalt = gmx_nint(conc*vol*AVOGADRO/1e24);
      p_num = abs(nsalt*n_q);
      n_num = abs(nsalt*p_q);
      if (bNeutral) {
	int qdelta = 0;
	do {
	  qdelta = (p_num*p_q + n_num*n_q + iqtot);
	  if (qdelta < 0) {
	    p_num  += abs(qdelta/p_q);
	    qdelta = (p_num*p_q + n_num*n_q + iqtot);
	  }
	  if (qdelta > 0) {
	    n_num  += abs(qdelta/n_q);
	    qdelta = (p_num*p_q + n_num*n_q + iqtot);
	  } 
	} while (qdelta != 0);
      }
    }
  }
	       
  if ((p_num == 0) && (n_num == 0)) {
    if (!bPDB) {
      fprintf(stderr,"No ions to add and no potential to calculate.\n");
      exit(0);
    }
    nw  = 0;
    nsa = 0; /* to keep gcc happy */
  } else {
    printf("Will try to add %d %s ions and %d %s ions.\n",
	   p_num,p_name,n_num,n_name);
    printf("Select a continuous group of solvent molecules\n");
    get_index(&atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&nwa,&index,&grpname);
    for(i=1; i<nwa; i++)
      if (index[i] != index[i-1]+1)
	gmx_fatal(FARGS,"The solvent group %s is not continuous: "
		  "index[%d]=%d, index[%d]=%d",
		  grpname,i,index[i-1]+1,i+1,index[i]+1);
    nsa = 1;
    while ((nsa<nwa) &&
	   (atoms.atom[index[nsa]].resind ==
	    atoms.atom[index[nsa-1]].resind))
      nsa++;
    if (nwa % nsa)
      gmx_fatal(FARGS,"Your solvent group size (%d) is not a multiple of %d",
		  nwa,nsa);
    nw = nwa/nsa;
    fprintf(stderr,"Number of (%d-atomic) solvent molecules: %d\n",nsa,nw);
	if (p_num+n_num > nw)
      gmx_fatal(FARGS,"Not enough solvent for adding ions");
  }
  
  if (opt2bSet("-p",NFILE,fnm)) 
    update_topol(opt2fn("-p",NFILE,fnm),p_num,n_num,p_name,n_name,grpname);
    
  snew(bSet,nw);
  snew(repl,nw);
  
  snew(v,atoms.nr);
  snew(atoms.pdbinfo,atoms.nr);

  set_pbc(&pbc,inputrec.ePBC,box);

  /* Now loop over the ions that have to be placed */
  do {
    if (!bRandom) {
      calc_pot(fplog,cr,mtop,&inputrec,top,x,fr,&enerd,mdatoms,pot,box,graph);
      if (bPDB || debug) {
	char buf[STRLEN];
	
	if (debug)
	  sprintf(buf,"%d_%s",p_num+n_num,ftp2fn(efPDB,NFILE,fnm));
	else
	  strcpy(buf,ftp2fn(efPDB,NFILE,fnm));
	for(i=0; (i<atoms.nr); i++)
	    atoms.pdbinfo[i].bfac = pot[i]*scale;
	write_sto_conf(buf,"Potential calculated by genion",
		       &atoms,x,v,inputrec.ePBC,box);
	bPDB = FALSE;
      }
    }
    if ((p_num > 0) && (p_num >= n_num))  {
      insert_ion(nsa,&nw,bSet,repl,index,pot,x,&pbc,
		 1,p_q,p_name,mdatoms,rmin,bRandom,&seed);
      p_num--;
    }
    else if (n_num > 0) {
      insert_ion(nsa,&nw,bSet,repl,index,pot,x,&pbc,
		 -1,n_q,n_name,mdatoms,rmin,bRandom,&seed);
      n_num--;
    }
  } while (p_num+n_num > 0);
  fprintf(stderr,"\n");

  if (nw)
    sort_ions(nsa,nw,repl,index,&atoms,x,p_name,n_name);
  
  sfree(atoms.pdbinfo);
  atoms.pdbinfo = NULL;
  write_sto_conf(ftp2fn(efSTO,NFILE,fnm),*mtop->name,&atoms,x,NULL,
		 inputrec.ePBC,box);
  
  thanx(stderr);

  gmx_log_close(fplog);
  
  return 0;
}
Beispiel #12
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "The [TT]pmetest[tt] program tests the scaling of the PME code. When only given",
    "a [TT].tpr[tt] file it will compute PME for one frame. When given a trajectory",
    "it will do so for all the frames in the trajectory. Before the PME",
    "routine is called the coordinates are sorted along the X-axis.[PAR]",
    "As an extra service to the public the program can also compute",
    "long-range Coulomb energies for components of the system. When the",
    "[TT]-groups[tt] flag is given to the program the energy groups",
    "from the [TT].tpr[tt] file will be read, and half an energy matrix computed."
  };
  t_commrec    *cr,*mcr;
  static t_filenm fnm[] = {
    { efTPX, NULL,      NULL,       ffREAD  },
    { efTRN, "-o",      NULL,       ffWRITE },
    { efLOG, "-g",      "pme",      ffWRITE },
    { efTRX, "-f",      NULL,       ffOPTRD },
    { efXVG, "-x",      "ener-pme", ffWRITE }
  };
#define NFILE asize(fnm)

  /* Command line options ! */
  static gmx_bool bVerbose=FALSE;
  static gmx_bool bOptFFT=FALSE;
  static gmx_bool bSort=FALSE;
  static int  ewald_geometry=eewg3D;
  static int  nnodes=1;
  static int  pme_order=0;
  static rvec grid = { -1, -1, -1 };
  static real rc   = 0.0;
  static real dtol = 0.0;
  static gmx_bool bGroups = FALSE;
  static t_pargs pa[] = {
    { "-np",      FALSE, etINT, {&nnodes},
      "Number of nodes, must be the same as used for [TT]grompp[tt]" },
    { "-v",       FALSE, etBOOL,{&bVerbose},  
      "Be loud and noisy" },
    { "-sort",    FALSE, etBOOL,{&bSort},  
      "Sort coordinates. Crucial for domain decomposition." },
    { "-grid",    FALSE, etRVEC,{&grid},
      "Number of grid cells in X, Y, Z dimension (if -1 use from [TT].tpr[tt])" },
    { "-order",   FALSE, etINT, {&pme_order},
      "Order of the PME spreading algorithm" },
    { "-groups",  FALSE, etBOOL, {&bGroups},
      "Compute half an energy matrix based on the energy groups in your [TT].tpr[tt] file" },
    { "-rc",      FALSE, etREAL, {&rc},
      "Rcoulomb for Ewald summation" },
    { "-tol",     FALSE, etREAL, {&dtol},
      "Tolerance for Ewald summation" }
  };
  FILE        *fp;
  t_inputrec  *ir;
  t_topology  top;
  t_tpxheader tpx;
  t_nrnb      nrnb;
  t_nsborder  *nsb;
  t_forcerec  *fr;
  t_mdatoms   *mdatoms;
  char        title[STRLEN];
  int         natoms,step,status,i,ncg,root;
  real        t,lambda,ewaldcoeff,qtot;
  rvec        *x,*f,*xbuf;
  int         *index;
  gmx_bool        bCont;
  real        *charge,*qbuf,*qqbuf;
  matrix      box;
  
  /* Start the actual parallel code if necessary */
  cr   = init_par(&argc,&argv);
  root = 0;
  
  if (MASTER(cr)) 
    CopyRight(stderr,argv[0]);
  
  /* Parse command line on all processors, arguments are passed on in 
   * init_par (see above)
   */
  parse_common_args(&argc,argv,
		    PCA_KEEP_ARGS | PCA_NOEXIT_ON_ARGS | PCA_BE_NICE |
		    PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET),
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);
  
#ifndef GMX_MPI
  if (nnodes > 1) 
    gmx_fatal(FARGS,"GROMACS compiled without MPI support - can't do parallel runs");
#endif

  /* Open log files on all processors */
  open_log(ftp2fn(efLOG,NFILE,fnm),cr);
  snew(ir,1);
  
  if (MASTER(cr)) {
    /* Read tpr file etc. */
    read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&tpx,FALSE,NULL,NULL);
    snew(x,tpx.natoms);
    read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,ir,
	     box,&natoms,x,NULL,NULL,&top);
    /* Charges */
    qtot = 0;
    snew(charge,natoms);
    for(i=0; (i<natoms); i++) {
      charge[i] = top.atoms.atom[i].q;
      qtot += charge[i];
    }
  
    /* Grid stuff */
    if (opt2parg_bSet("-grid",asize(pa),pa)) {
      ir->nkx = grid[XX];
      ir->nky = grid[YY];
      ir->nkz = grid[ZZ];
    }
    /* Check command line parameters for consistency */
    if ((ir->nkx <= 0) || (ir->nky <= 0) || (ir->nkz <= 0))
      gmx_fatal(FARGS,"PME grid = %d %d %d",ir->nkx,ir->nky,ir->nkz);
    if (opt2parg_bSet("-rc",asize(pa),pa)) 
      ir->rcoulomb = rc;
    if (ir->rcoulomb <= 0)
      gmx_fatal(FARGS,"rcoulomb should be > 0 (not %f)",ir->rcoulomb);
    if (opt2parg_bSet("-order",asize(pa),pa)) 
      ir->pme_order = pme_order;
    if (ir->pme_order <= 0)
      gmx_fatal(FARGS,"pme_order should be > 0 (not %d)",ir->pme_order);
    if (opt2parg_bSet("-tol",asize(pa),pa))
      ir->ewald_rtol = dtol;
    if (ir->ewald_rtol <= 0)
      gmx_fatal(FARGS,"ewald_tol should be > 0 (not %f)",ir->ewald_rtol);
  }
  else {
    init_top(&top);
  }

  /* Add parallellization code here */
  snew(nsb,1);
  if (MASTER(cr)) {
    ncg = top.blocks[ebCGS].multinr[0];
    for(i=0; (i<cr->nnodes-1); i++)
      top.blocks[ebCGS].multinr[i] = min(ncg,(ncg*(i+1))/cr->nnodes);
    for( ; (i<MAXNODES); i++)
      top.blocks[ebCGS].multinr[i] = ncg;
  }
  if (PAR(cr)) {
    /* Set some variables to zero to avoid core dumps */
    ir->opts.ngtc = ir->opts.ngacc = ir->opts.ngfrz = ir->opts.ngener = 0;
#ifdef GMX_MPI
    /* Distribute the data over processors */
    MPI_Bcast(&natoms,1,MPI_INT,root,MPI_COMM_WORLD);
    MPI_Bcast(ir,sizeof(*ir),MPI_BYTE,root,MPI_COMM_WORLD);
    MPI_Bcast(&qtot,1,GMX_MPI_REAL,root,MPI_COMM_WORLD);
#endif

    /* Call some dedicated communication routines, master sends n-1 times */
    if (MASTER(cr)) {
      for(i=1; (i<cr->nnodes); i++) {
	mv_block(i,&(top.blocks[ebCGS]));
	mv_block(i,&(top.atoms.excl));
      }
    }
    else {
      ld_block(root,&(top.blocks[ebCGS]));
      ld_block(root,&(top.atoms.excl));
    }
    if (!MASTER(cr)) {
      snew(charge,natoms);
      snew(x,natoms);
    }
#ifdef GMX_MPI
    MPI_Bcast(charge,natoms,GMX_MPI_REAL,root,MPI_COMM_WORLD);
#endif
  }
  ewaldcoeff = calc_ewaldcoeff(ir->rcoulomb,ir->ewald_rtol);
  
  
  if (bVerbose)
    pr_inputrec(stdlog,0,"Inputrec",ir);

  /* Allocate memory for temp arrays etc. */
  snew(xbuf,natoms);
  snew(f,natoms);
  snew(qbuf,natoms);
  snew(qqbuf,natoms);
  snew(index,natoms);

  /* Initialize the PME code */  
  init_pme(stdlog,cr,ir->nkx,ir->nky,ir->nkz,ir->pme_order,
	   natoms,FALSE,bOptFFT,ewald_geometry);
	   
  /* MFlops accounting */
  init_nrnb(&nrnb);
  
  /* Initialize the work division */
  calc_nsb(stdlog,&(top.blocks[ebCGS]),cr->nnodes,nsb,0);
  nsb->nodeid = cr->nodeid;
  print_nsb(stdlog,"pmetest",nsb);  

  /* Initiate forcerec */
  mdatoms = atoms2md(stdlog,&top.atoms,ir->opts.nFreeze,ir->eI,
		     ir->delta_t,0,ir->opts.tau_t,FALSE,FALSE);
  snew(fr,1);
  init_forcerec(stdlog,fr,ir,&top,cr,mdatoms,nsb,box,FALSE,NULL,NULL,FALSE);
  
  /* First do PME based on coordinates in tpr file, send them to
   * other processors if needed.
   */
  if (MASTER(cr))
    fprintf(stdlog,"-----\n"
	    "Results based on tpr file %s\n",ftp2fn(efTPX,NFILE,fnm));
#ifdef GMX_MPI
  if (PAR(cr)) {
    MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD);
    MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD);
    MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD);
  }
#endif
  do_my_pme(stdlog,0,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort,
	    cr,nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,NULL,
	    bGroups ? ir->opts.ngener : 1,mdatoms->cENER);

  /* If we have a trajectry file, we will read the frames in it and compute
   * the PME energy.
   */
  if (ftp2bSet(efTRX,NFILE,fnm)) {
    fprintf(stdlog,"-----\n"
	    "Results based on trx file %s\n",ftp2fn(efTRX,NFILE,fnm));
    if (MASTER(cr)) {
      sfree(x);
      natoms = read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); 
      if (natoms != top.atoms.nr)
	gmx_fatal(FARGS,"natoms in trx = %d, in tpr = %d",natoms,top.atoms.nr);
      fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"PME Energy","Time (ps)","E (kJ/mol)");
    }
    else
      fp = NULL;
    do {
      /* Send coordinates, box and time to the other nodes */
#ifdef GMX_MPI
      if (PAR(cr)) {
	MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD);
	MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD);
	MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD);
      }
#endif
      rm_pbc(&top.idef,nsb->natoms,box,x,x);
      /* Call the PME wrapper function */
      do_my_pme(stdlog,t,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort,cr,
		nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,fp,
		bGroups ? ir->opts.ngener : 1,mdatoms->cENER);
      /* Only the master processor reads more data */
      if (MASTER(cr))
          bCont = read_next_x(status,&t,natoms,x,box);
      /* Check whether we need to continue */
#ifdef GMX_MPI
      if (PAR(cr))
          MPI_Bcast(&bCont,1,MPI_INT,root,MPI_COMM_WORLD);
#endif
      
    } while (bCont);
    
    /* Finish I/O, close files */
    if (MASTER(cr)) {
      close_trx(status);
      ffclose(fp);
    }
  }
  
  if (bVerbose) {
    /* Do some final I/O about performance, might be useful in debugging */
    fprintf(stdlog,"-----\n");
    print_nrnb(stdlog,&nrnb);
  }
  
  /* Finish the parallel stuff */  
  if (gmx_parallel_env_initialized())
    gmx_finalize(cr);

  /* Thank the audience, as usual */
  if (MASTER(cr)) 
    gmx_thanx(stderr);

  return 0;
}
Beispiel #13
0
int gmx_helix(int argc,char *argv[])
{
  const char *desc[] = {
    "g_helix computes all kind of helix properties. First, the peptide",
    "is checked to find the longest helical part. This is determined by",
    "Hydrogen bonds and Phi/Psi angles.",
    "That bit is fitted",
    "to an ideal helix around the Z-axis and centered around the origin.",
    "Then the following properties are computed:[PAR]",
    "[BB]1.[bb] Helix radius (file radius.xvg). This is merely the",
    "RMS deviation in two dimensions for all Calpha atoms.",
    "it is calced as sqrt((SUM i(x^2(i)+y^2(i)))/N), where N is the number",
    "of backbone atoms. For an ideal helix the radius is 0.23 nm[BR]",
    "[BB]2.[bb] Twist (file twist.xvg). The average helical angle per",
    "residue is calculated. For alpha helix it is 100 degrees,",
    "for 3-10 helices it will be smaller,", 
    "for 5-helices it will be larger.[BR]",
    "[BB]3.[bb] Rise per residue (file rise.xvg). The helical rise per", 
    "residue is plotted as the difference in Z-coordinate between Ca", 
    "atoms. For an ideal helix this is 0.15 nm[BR]",
    "[BB]4.[bb] Total helix length (file len-ahx.xvg). The total length", 
    "of the", 
    "helix in nm. This is simply the average rise (see above) times the",  
    "number of helical residues (see below).[BR]",
    "[BB]5.[bb] Number of helical residues (file n-ahx.xvg). The title says",
    "it all.[BR]",
    "[BB]6.[bb] Helix Dipole, backbone only (file dip-ahx.xvg).[BR]",
    "[BB]7.[bb] RMS deviation from ideal helix, calculated for the Calpha",
    "atoms only (file rms-ahx.xvg).[BR]",
    "[BB]8.[bb] Average Calpha-Calpha dihedral angle (file phi-ahx.xvg).[BR]",
    "[BB]9.[bb] Average Phi and Psi angles (file phipsi.xvg).[BR]",
    "[BB]10.[bb] Ellipticity at 222 nm according to [IT]Hirst and Brooks[it]",
    "[PAR]"
  };
  static const char *ppp[efhNR+2] = { 
    NULL, "RAD", "TWIST", "RISE", "LEN", "NHX", "DIP", "RMS", "CPHI", 
    "RMSA", "PHI", "PSI", "HB3", "HB4", "HB5", "CD222", NULL
  };
  static gmx_bool bCheck=FALSE,bFit=TRUE,bDBG=FALSE,bEV=FALSE;
  static int  rStart=0,rEnd=0,r0=1;
  t_pargs pa [] = {
    { "-r0", FALSE, etINT, {&r0},
      "The first residue number in the sequence" },
    { "-q",  FALSE, etBOOL,{&bCheck},
      "Check at every step which part of the sequence is helical" },
    { "-F",  FALSE, etBOOL,{&bFit},
      "Toggle fit to a perfect helix" },
    { "-db", FALSE, etBOOL,{&bDBG},
      "Print debug info" },
    { "-prop", FALSE, etENUM, {ppp},
      "Select property to weight eigenvectors with. WARNING experimental stuff" },
    { "-ev", FALSE, etBOOL,{&bEV},
      "Write a new 'trajectory' file for ED" },
    { "-ahxstart", FALSE, etINT, {&rStart},
      "First residue in helix" },
    { "-ahxend", FALSE, etINT, {&rEnd},
      "Last residue in helix" }
  };

  typedef struct {
    FILE *fp,*fp2;
    gmx_bool bfp2;
    const char *filenm;
    const char *title;
    const char *xaxis;
    const char *yaxis;
    real val;
  } t_xvgrfile;
  
  t_xvgrfile xf[efhNR] = {
    { NULL, NULL, TRUE,  "radius",  "Helix radius",               NULL, "r (nm)" , 0.0 },
    { NULL, NULL, TRUE,  "twist",   "Twist per residue",          NULL, "Angle (deg)", 0.0 },
    { NULL, NULL, TRUE,  "rise",    "Rise per residue",           NULL, "Rise (nm)", 0.0 },
    { NULL, NULL, FALSE, "len-ahx", "Length of the Helix",        NULL, "Length (nm)", 0.0 },
    { NULL, NULL, FALSE, "dip-ahx", "Helix Backbone Dipole",      NULL, "rq (nm e)", 0.0 },
    { NULL, NULL, TRUE,  "rms-ahx", "RMS Deviation from Ideal Helix", NULL, "RMS (nm)", 0.0 },
    { NULL, NULL, FALSE, "rmsa-ahx","Average RMSD per Residue",   "Residue", "RMS (nm)", 0.0 },
    { NULL, NULL,FALSE,  "cd222",   "Ellipticity at 222 nm", NULL, "nm", 0.0 },
    { NULL, NULL, TRUE,  "pprms",   "RMS Distance from \\8a\\4-helix", NULL, "deg" , 0.0 },
    { NULL, NULL, TRUE,  "caphi",   "Average Ca-Ca Dihedral",     NULL, "\\8F\\4(deg)", 0.0 },
    { NULL, NULL, TRUE,  "phi",     "Average \\8F\\4 angles", NULL, "deg" , 0.0 },
    { NULL, NULL, TRUE,  "psi",     "Average \\8Y\\4 angles", NULL, "deg" , 0.0 },
    { NULL, NULL, TRUE,  "hb3",     "Average n-n+3 hbond length", NULL, "nm" , 0.0 },
    { NULL, NULL, TRUE,  "hb4",     "Average n-n+4 hbond length", NULL, "nm" , 0.0 },
    { NULL, NULL, TRUE,  "hb5",     "Average n-n+5 hbond length", NULL, "nm" , 0.0 },
    { NULL, NULL,FALSE,  "JCaHa",   "J-Coupling Values",        "Residue", "Hz" , 0.0 },
    { NULL, NULL,FALSE,  "helicity","Helicity per Residue",     "Residue", "% of time" , 0.0 }
  };
 
  output_env_t oenv;
  FILE       *otrj;
  char       buf[54],prop[256];
  t_trxstatus *status;
  int        natoms,nre,nres;
  t_bb       *bb;
  int        i,j,ai,m,nall,nbb,nca,teller,nSel=0;
  atom_id    *bbindex,*caindex,*allindex;
  t_topology *top;
  int        ePBC;
  rvec       *x,*xref,*xav;
  real       t;
  real       rms,fac;
  matrix     box;
  gmx_rmpbc_t  gpbc=NULL;
  gmx_bool       bRange;
  t_filenm  fnm[] = {
    { efTPX, NULL,  NULL,   ffREAD  },
    { efNDX, NULL,  NULL,   ffREAD  },
    { efTRX, "-f",  NULL,   ffREAD  },
    { efG87, "-to", NULL,   ffOPTWR },
    { efSTO, "-cz", "zconf",ffWRITE },
    { efSTO, "-co", "waver",ffWRITE }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv);
  
  bRange=(opt2parg_bSet("-ahxstart",asize(pa),pa) &&
	  opt2parg_bSet("-ahxend",asize(pa),pa));
		        
  top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC);
  
  natoms=read_first_x(oenv,&status,opt2fn("-f",NFILE,fnm),&t,&x,box);

  if (opt2bSet("-to",NFILE,fnm)) {
    otrj=opt2FILE("-to",NFILE,fnm,"w");
    strcpy(prop,ppp[0]);
    fprintf(otrj,"%s Weighted Trajectory: %d atoms, NO box\n",prop,natoms);
  }
  else
    otrj=NULL;
    
  if (natoms != top->atoms.nr)
    gmx_fatal(FARGS,"Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)",
	    top->atoms.nr,natoms);
	    
  bb=mkbbind(ftp2fn(efNDX,NFILE,fnm),&nres,&nbb,r0,&nall,&allindex,
	     top->atoms.atomname,top->atoms.atom,top->atoms.resinfo);
  snew(bbindex,natoms);
  snew(caindex,nres);
  
  fprintf(stderr,"nall=%d\n",nall);
    
  /* Open output files, default x-axis is time */
  for(i=0; (i<efhNR); i++) {
    sprintf(buf,"%s.xvg",xf[i].filenm);
    remove(buf);
    xf[i].fp=xvgropen(buf,xf[i].title,
                      xf[i].xaxis ? xf[i].xaxis : "Time (ps)",
		      xf[i].yaxis,oenv);
    if (xf[i].bfp2) {
      sprintf(buf,"%s.out",xf[i].filenm);
      remove(buf);
      xf[i].fp2=ffopen(buf,"w");
    }
  }

  /* Read reference frame from tpx file to compute helix length */
  snew(xref,top->atoms.nr);
  read_tpx(ftp2fn(efTPX,NFILE,fnm),
	   NULL,NULL,&natoms,xref,NULL,NULL,NULL);
  calc_hxprops(nres,bb,xref,box);
  do_start_end(nres,bb,xref,&nbb,bbindex,&nca,caindex,bRange,rStart,rEnd);
  sfree(xref);
  if (bDBG) {
    fprintf(stderr,"nca=%d, nbb=%d\n",nca,nbb);
    pr_bb(stdout,nres,bb);
  }
  
  gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box);

  snew(xav,natoms);
  teller=0;
  do {
    if ((teller++ % 10) == 0)
      fprintf(stderr,"\rt=%.2f",t);
    gmx_rmpbc(gpbc,natoms,box,x);

    
    calc_hxprops(nres,bb,x,box);
    if (bCheck)
      do_start_end(nres,bb,x,&nbb,bbindex,&nca,caindex,FALSE,0,0);
    
    if (nca >= 5) {
      rms=fit_ahx(nres,bb,natoms,nall,allindex,x,nca,caindex,box,bFit);
      
      if (teller == 1) {
	write_sto_conf(opt2fn("-cz",NFILE,fnm),"Helix fitted to Z-Axis",
		       &(top->atoms),x,NULL,ePBC,box);
      }
            
      xf[efhRAD].val   = radius(xf[efhRAD].fp2,nca,caindex,x);
      xf[efhTWIST].val = twist(xf[efhTWIST].fp2,nca,caindex,x);
      xf[efhRISE].val  = rise(nca,caindex,x);
      xf[efhLEN].val   = ahx_len(nca,caindex,x,box);
      xf[efhCD222].val = ellipticity(nres,bb);
      xf[efhDIP].val   = dip(nbb,bbindex,x,top->atoms.atom);
      xf[efhRMS].val   = rms;
      xf[efhCPHI].val  = ca_phi(nca,caindex,x,box);
      xf[efhPPRMS].val = pprms(xf[efhPPRMS].fp2,nres,bb);
      
      for(j=0; (j<=efhCPHI); j++)
	fprintf(xf[j].fp,   "%10g  %10g\n",t,xf[j].val);
      
      av_phipsi(xf[efhPHI].fp,xf[efhPSI].fp,xf[efhPHI].fp2,xf[efhPSI].fp2,
		t,nres,bb);
      av_hblen(xf[efhHB3].fp,xf[efhHB3].fp2,
	       xf[efhHB4].fp,xf[efhHB4].fp2,
	       xf[efhHB5].fp,xf[efhHB5].fp2,
	       t,nres,bb);
      
      if (otrj) 
	dump_otrj(otrj,nall,allindex,x,xf[nSel].val,xav);
    }
  } while (read_next_x(oenv,status,&t,natoms,x,box));
  fprintf(stderr,"\n");
  
  gmx_rmpbc_done(gpbc);

  close_trj(status);

  if (otrj) {
    ffclose(otrj);
    fac=1.0/teller;
    for(i=0; (i<nall); i++) {
      ai=allindex[i];
      for(m=0; (m<DIM); m++)
	xav[ai][m]*=fac;
    }
    write_sto_conf_indexed(opt2fn("-co",NFILE,fnm),
			   "Weighted and Averaged conformation",
			   &(top->atoms),xav,NULL,ePBC,box,nall,allindex);
  }
  
  for(i=0; (i<nres); i++) {
    if (bb[i].nrms > 0) {
      fprintf(xf[efhRMSA].fp,"%10d  %10g\n",r0+i,bb[i].rmsa/bb[i].nrms);
    }
    fprintf(xf[efhAHX].fp,"%10d  %10g\n",r0+i,(bb[i].nhx*100.0)/(real )teller);
    fprintf(xf[efhJCA].fp,"%10d  %10g\n",
	    r0+i,140.3+(bb[i].jcaha/(double)teller));
  }
  
  for(i=0; (i<efhNR); i++) {
    ffclose(xf[i].fp);
    if (xf[i].bfp2)
      ffclose(xf[i].fp2);
    do_view(oenv,xf[i].filenm,"-nxy");
  }
  
  thanx(stderr);
  
  return 0;
}
Beispiel #14
0
int gmx_mk_angndx(int argc, char *argv[])
{
    static const char *desc[] = {
        "[TT]mk_angndx[tt] makes an index file for calculation of",
        "angle distributions etc. It uses a run input file ([TT].tpx[tt]) for the",
        "definitions of the angles, dihedrals etc."
    };
    static const char *opt[] = { NULL, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL };
    static gmx_bool    bH    = TRUE;
    static real        hq    = -1;
    t_pargs            pa[]  = {
        { "-type", FALSE, etENUM, {opt},
          "Type of angle" },
        { "-hyd", FALSE, etBOOL, {&bH},
          "Include angles with atoms with mass < 1.5" },
        { "-hq", FALSE, etREAL, {&hq},
          "Ignore angles with atoms with mass < 1.5 and magnitude of their charge less than this value" }
    };

    output_env_t       oenv;
    FILE              *out;
    t_topology        *top;
    int                i, j, ntype;
    int                nft = 0, *ft, mult = 0;
    int              **index;
    int               *ft_ind;
    int               *nr;
    char             **grpnames;
    t_filenm           fnm[] = {
        { efTPX, NULL, NULL, ffREAD  },
        { efNDX, NULL, "angle", ffWRITE }
    };
#define NFILE asize(fnm)

    CopyRight(stderr, argv[0]);
    parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                      asize(desc), desc, 0, NULL, &oenv);


    ft = select_ftype(opt[0], &nft, &mult);

    top = read_top(ftp2fn(efTPX, NFILE, fnm), NULL);

    ntype = calc_ntype(nft, ft, &(top->idef));
    snew(grpnames, ntype);
    snew(ft_ind, top->idef.ntypes);
    fill_ft_ind(nft, ft, &top->idef, ft_ind, grpnames);

    snew(nr, ntype);
    snew(index, ntype);
    fill_ang(nft, ft, mult, nr, index, ft_ind, top, !bH, hq);

    out = ftp2FILE(efNDX, NFILE, fnm, "w");
    for (i = 0; (i < ntype); i++)
    {
        if (nr[i] > 0)
        {
            fprintf(out, "[ %s ]\n", grpnames[i]);
            for (j = 0; (j < nr[i]*mult); j++)
            {
                fprintf(out, " %5d", index[i][j]+1);
                if ((j % 12) == 11)
                {
                    fprintf(out, "\n");
                }
            }
            fprintf(out, "\n");
        }
    }
    ffclose(out);

    thanx(stderr);

    return 0;
}
int gmx_bundle(int argc,char *argv[])
{
  static char *desc[] = {
    "g_bundle analyzes bundles of axes. The axes can be for instance",
    "helix axes. The program reads two index groups and divides both",
    "of them in [TT]-na[tt] parts. The centers of mass of these parts",
    "define the tops and bottoms of the axes.",
    "Several quantities are written to file:",
    "the axis length, the distance and the z-shift of the axis mid-points",
    "with respect to the average center of all axes, the total tilt,",
    "the radial tilt and the lateral tilt with respect to the average axis.",
    "[PAR]",
    "With options [TT]-ok[tt], [TT]-okr[tt] and [TT]-okl[tt] the total,",
    "radial and lateral kinks of the axes are plotted. An extra index",
    "group of kink atoms is required, which is also divided into [TT]-na[tt]",
    "parts. The kink angle is defined as the angle between the kink-top and",
    "the bottom-kink vectors.",
    "[PAR]",
    "With option [TT]-oa[tt] the top, mid (or kink when [TT]-ok[tt] is set)",
    "and bottom points of each axis",
    "are written to a pdb file each frame. The residue numbers correspond",
    "to the axis numbers. When viewing this file with [TT]rasmol[tt], use the",
    "command line option [TT]-nmrpdb[tt], and type [TT]set axis true[tt] to",
    "display the reference axis."
  };
  static int  n=0;
  static bool bZ=FALSE;
  t_pargs pa[] = {
    { "-na", FALSE, etINT, {&n},
	"Number of axes" },
    { "-z", FALSE, etBOOL, {&bZ},
	"Use the Z-axis as reference iso the average axis" }
  };
  FILE       *out,*flen,*fdist,*fz,*ftilt,*ftiltr,*ftiltl;
  FILE       *fkink=NULL,*fkinkr=NULL,*fkinkl=NULL;
  int        status,fpdb;
  t_topology top;
  int        ePBC;
  rvec       *xtop;
  matrix     box;
  t_trxframe fr;
  t_atoms    outatoms;
  real       t,comp;
  int        natoms;
  char       *grpname[MAX_ENDS],title[256],*anm="CA",*rnm="GLY";
  int        i,j,gnx[MAX_ENDS];
  atom_id    *index[MAX_ENDS];
  t_bundle   bun;
  bool       bKink;
  rvec       va,vb,vc,vr,vl;
#define NLEG asize(leg) 
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD }, 
    { efTPS, NULL, NULL, ffREAD }, 
    { efNDX, NULL, NULL, ffOPTRD },
    { efXVG, "-ol", "bun_len", ffWRITE },
    { efXVG, "-od", "bun_dist", ffWRITE },
    { efXVG, "-oz", "bun_z", ffWRITE },
    { efXVG, "-ot", "bun_tilt", ffWRITE },
    { efXVG, "-otr", "bun_tiltr", ffWRITE },
    { efXVG, "-otl", "bun_tiltl", ffWRITE },
    { efXVG, "-ok", "bun_kink", ffOPTWR },
    { efXVG, "-okr", "bun_kinkr", ffOPTWR },
    { efXVG, "-okl", "bun_kinkl", ffOPTWR },
    { efPDB, "-oa", "axes", ffOPTWR }
  }; 
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); 

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,TRUE);

  bKink = opt2bSet("-ok",NFILE,fnm) || opt2bSet("-okr",NFILE,fnm) 
    || opt2bSet("-okl",NFILE,fnm);
  if (bKink)
    bun.nend = 3;
  else
    bun.nend = 2;
  
  fprintf(stderr,"Select a group of top and a group of bottom ");
  if (bKink)
    fprintf(stderr,"and a group of kink ");
  fprintf(stderr,"atoms\n");
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),bun.nend,
	    gnx,index,grpname);

  if (n<=0 || gnx[0] % n || gnx[1] % n || (bKink && gnx[2] % n))
    gmx_fatal(FARGS,
		"The size of one of your index groups is not a multiple of n");
  bun.n = n;
  snew(bun.end[0],n);
  snew(bun.end[1],n);
  if (bKink)
    snew(bun.end[2],n);
  snew(bun.mid,n);
  snew(bun.dir,n);
  snew(bun.len,n);

  flen   = xvgropen(opt2fn("-ol",NFILE,fnm),"Axis lengths",
		    xvgr_tlabel(),"(nm)");
  fdist  = xvgropen(opt2fn("-od",NFILE,fnm),"Distance of axis centers",
		    xvgr_tlabel(),"(nm)");
  fz     = xvgropen(opt2fn("-oz",NFILE,fnm),"Z-shift of axis centers",
		    xvgr_tlabel(),"(nm)");
  ftilt  = xvgropen(opt2fn("-ot",NFILE,fnm),"Axis tilts",
		    xvgr_tlabel(),"(degrees)");
  ftiltr = xvgropen(opt2fn("-otr",NFILE,fnm),"Radial axis tilts",
		    xvgr_tlabel(),"(degrees)");
  ftiltl = xvgropen(opt2fn("-otl",NFILE,fnm),"Lateral axis tilts",
		    xvgr_tlabel(),"(degrees)");
  
  if (bKink) {
    fkink  = xvgropen(opt2fn("-ok",NFILE,fnm),"Kink angles",
		      xvgr_tlabel(),"(degrees)");
    fkinkr = xvgropen(opt2fn("-okr",NFILE,fnm),"Radial kink angles",
		      xvgr_tlabel(),"(degrees)");
    if (bPrintXvgrCodes())
      fprintf(fkinkr,"@ subtitle \"+ = ) (   - = ( )\"\n");
    fkinkl = xvgropen(opt2fn("-okl",NFILE,fnm),"Lateral kink angles",
		      xvgr_tlabel(),"(degrees)");
  }

  if (opt2bSet("-oa",NFILE,fnm)) {
    init_t_atoms(&outatoms,3*n,FALSE);
    outatoms.nr = 3*n;
    for(i=0; i<3*n; i++) {
      outatoms.atomname[i] = &anm;
      outatoms.atom[i].resnr = i/3;
      outatoms.resname[i/3] = &rnm;
    }
    fpdb = open_trx(opt2fn("-oa",NFILE,fnm),"w");
  } else
    fpdb = -1;
  
  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,TRX_NEED_X); 
  
  do {
    rm_pbc(&top.idef,ePBC,fr.natoms,fr.box,fr.x,fr.x);
    calc_axes(fr.x,top.atoms.atom,gnx,index,!bZ,&bun);
    t = convert_time(fr.time);
    fprintf(flen," %10g",t);
    fprintf(fdist," %10g",t);
    fprintf(fz," %10g",t);
    fprintf(ftilt," %10g",t);
    fprintf(ftiltr," %10g",t);
    fprintf(ftiltl," %10g",t);
    if (bKink) {
      fprintf(fkink," %10g",t);
      fprintf(fkinkr," %10g",t);
      fprintf(fkinkl," %10g",t);
    }

    for(i=0; i<bun.n; i++) {
      fprintf(flen," %6g",bun.len[i]);
      fprintf(fdist," %6g",norm(bun.mid[i]));
      fprintf(fz," %6g",bun.mid[i][ZZ]);
      fprintf(ftilt," %6g",RAD2DEG*acos(bun.dir[i][ZZ]));
      comp = bun.mid[i][XX]*bun.dir[i][XX]+bun.mid[i][YY]*bun.dir[i][YY];
      fprintf(ftiltr," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      comp = bun.mid[i][YY]*bun.dir[i][XX]-bun.mid[i][XX]*bun.dir[i][YY];
      fprintf(ftiltl," %6g",RAD2DEG*
	      asin(comp/sqrt(sqr(comp)+sqr(bun.dir[i][ZZ]))));
      if (bKink) {
	rvec_sub(bun.end[0][i],bun.end[2][i],va);
	rvec_sub(bun.end[2][i],bun.end[1][i],vb);
	unitv_no_table(va,va);
	unitv_no_table(vb,vb);
	fprintf(fkink," %6g",RAD2DEG*acos(iprod(va,vb)));
	cprod(va,vb,vc);
	copy_rvec(bun.mid[i],vr);
	vr[ZZ] = 0;
	unitv_no_table(vr,vr);
	fprintf(fkinkr," %6g",RAD2DEG*asin(iprod(vc,vr)));
	vl[XX] = vr[YY];
	vl[YY] = -vr[XX];
	vl[ZZ] = 0;
	fprintf(fkinkl," %6g",RAD2DEG*asin(iprod(vc,vl)));
      }
    }
    fprintf(flen,"\n");
    fprintf(fdist,"\n");
    fprintf(fz,"\n");
    fprintf(ftilt,"\n");
    fprintf(ftiltr,"\n");
    fprintf(ftiltl,"\n");
    if (bKink) {
      fprintf(fkink,"\n");
      fprintf(fkinkr,"\n");
      fprintf(fkinkl,"\n");
    }
    if (fpdb >= 0)
      dump_axes(fpdb,&fr,&outatoms,&bun);
  } while(read_next_frame(status,&fr));

  close_trx(status);
  
  if (fpdb >= 0)
    close_trx(fpdb);
  fclose(flen);
  fclose(fdist);
  fclose(fz);
  fclose(ftilt);
  fclose(ftiltr);
  fclose(ftiltl);
  if (bKink) {
    fclose(fkink);
    fclose(fkinkr);
    fclose(fkinkl);
  }
  
  thanx(stderr);
  
  return 0;
}
Beispiel #16
0
int gmx_rmsf(int argc,char *argv[])
{
  static char *desc[] = {
    "g_rmsf computes the root mean square fluctuation (RMSF, i.e. standard ",
    "deviation) of atomic positions ",
    "after (optionally) fitting to a reference frame.[PAR]",
    "With option [TT]-oq[tt] the RMSF values are converted to B-factor",
    "values, which are written to a pdb file with the coordinates, of the",
    "structure file, or of a pdb file when [TT]-q[tt] is specified.",
    "Option [TT]-ox[tt] writes the B-factors to a file with the average",
    "coordinates.[PAR]",
    "With the option [TT]-od[tt] the root mean square deviation with",
    "respect to the reference structure is calculated.[PAR]",
    "With the option [TT]aniso[tt] g_rmsf will compute anisotropic",
    "temperature factors and then it will also output average coordinates",
    "and a pdb file with ANISOU records (corresonding to the [TT]-oq[tt]",
    "or [TT]-ox[tt] option). Please note that the U values",
    "are orientation dependent, so before comparison with experimental data",
    "you should verify that you fit to the experimental coordinates.[PAR]",
    "When a pdb input file is passed to the program and the [TT]-aniso[tt]",
    "flag is set",
    "a correlation plot of the Uij will be created, if any anisotropic",
    "temperature factors are present in the pdb file.[PAR]",
    "With option [TT]-dir[tt] the average MSF (3x3) matrix is diagonalized.",
    "This shows the directions in which the atoms fluctuate the most and",
    "the least."
  };
  static bool bRes=FALSE,bAniso=FALSE,bdevX=FALSE,bFit=TRUE;
  t_pargs pargs[] = { 
    { "-res", FALSE, etBOOL, {&bRes},
      "Calculate averages for each residue" },
    { "-aniso",FALSE, etBOOL, {&bAniso},
      "Compute anisotropic termperature factors" },
    { "-fit", FALSE, etBOOL, {&bFit},
      "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." }
  };
  int          step,nre,natom,natoms,i,g,m,teller=0;
  real         t,lambda,*w_rls,*w_rms;
  
  t_tpxheader  header;
  t_inputrec   ir;
  t_topology   top;
  int          ePBC;
  t_atoms      *pdbatoms,*refatoms;
  bool         bCont;

  matrix       box,pdbbox;
  rvec         *x,*pdbx,*xref;
  int          status,npdbatoms,res0;
  char         buf[256],*label;
  char         title[STRLEN];
  
  FILE         *fp;               /* the graphics file */
  char         *devfn,*dirfn;
  int          resnr;

  bool         bReadPDB;  
  atom_id      *index;
  int          isize;
  char         *grpnames;

  real         bfac,pdb_bfac,*Uaver;
  double       **U,*xav;
  atom_id      aid;
  rvec         *rmsd_x=NULL;
  real         *rmsf,invcount,totmass;
  int          d;
  real         count=0;
  rvec         xcm;

  char         *leg[2] = { "MD", "X-Ray" };

  t_filenm fnm[] = {
    { efTRX, "-f",  NULL,     ffREAD  },
    { efTPS, NULL,  NULL,     ffREAD  },
    { efNDX, NULL,  NULL,     ffOPTRD },
    { efPDB, "-q",  NULL,     ffOPTRD },
    { efPDB, "-oq", "bfac",   ffOPTWR },
    { efPDB, "-ox", "xaver",  ffOPTWR },
    { efXVG, "-o",  "rmsf",   ffWRITE },
    { efXVG, "-od", "rmsdev", ffOPTWR },
    { efXVG, "-oc", "correl", ffOPTWR },
    { efLOG, "-dir", "rmsf",  ffOPTWR }
  };
#define NFILE asize(fnm)
 
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE ,
		    NFILE,fnm,asize(pargs),pargs,asize(desc),desc,0,NULL);

  bReadPDB = ftp2bSet(efPDB,NFILE,fnm);
  devfn    = opt2fn_null("-od",NFILE,fnm);
  dirfn    = opt2fn_null("-dir",NFILE,fnm);

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xref,NULL,box,TRUE);
  snew(w_rls,top.atoms.nr);

  fprintf(stderr,"Select group(s) for root mean square calculation\n");
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpnames);

  /* Set the weight */
  for(i=0; i<isize; i++) 
    w_rls[index[i]]=top.atoms.atom[index[i]].m;

  /* Malloc the rmsf arrays */
  snew(xav,isize*DIM);
  snew(U,isize);
  for(i=0; i<isize; i++)
    snew(U[i],DIM*DIM);
  snew(rmsf,isize);
  if (devfn)
    snew(rmsd_x, isize);
  
  if (bReadPDB) {
    get_stx_coordnum(opt2fn("-q",NFILE,fnm),&npdbatoms);
    snew(pdbatoms,1);
    snew(refatoms,1);
    init_t_atoms(pdbatoms,npdbatoms,TRUE);
    init_t_atoms(refatoms,npdbatoms,TRUE);
    snew(pdbx,npdbatoms);
    /* Read coordinates twice */
    read_stx_conf(opt2fn("-q",NFILE,fnm),title,pdbatoms,pdbx,NULL,NULL,pdbbox);
    read_stx_conf(opt2fn("-q",NFILE,fnm),title,refatoms,pdbx,NULL,NULL,pdbbox);
  } else {
    pdbatoms  = &top.atoms;
    refatoms  = &top.atoms;
    pdbx      = xref;
    npdbatoms = pdbatoms->nr;
    snew(pdbatoms->pdbinfo,npdbatoms);
    copy_mat(box,pdbbox);
  }
  
  if (bFit)
    sub_xcm(xref,isize,index,top.atoms.atom,xcm,FALSE);
  
  natom = read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
    
  /* Now read the trj again to compute fluctuations */
  teller = 0;
  do {
    if (bFit) {
      /* Remove periodic boundary */
      rm_pbc(&(top.idef),ePBC,natom,box,x,x);
      
      /* Set center of mass to zero */
      sub_xcm(x,isize,index,top.atoms.atom,xcm,FALSE);
      
      /* Fit to reference structure */
      do_fit(natom,w_rls,xref,x);
    }
     
    /* Calculate Anisotropic U Tensor */  
    for(i=0; i<isize; i++) {
      aid = index[i];
      for(d=0; d<DIM; d++) {
	xav[i*DIM + d] += x[aid][d];
	for(m=0; m<DIM; m++)
	  U[i][d*DIM + m] += x[aid][d]*x[aid][m];
      }
    }
    
    if (devfn) {
      /* Calculate RMS Deviation */
      for(i=0;(i<isize);i++) {
	aid = index[i];
	for(d=0;(d<DIM);d++) {
	  rmsd_x[i][d] += sqr(x[aid][d]-xref[aid][d]);
	}
      }
    } 
    count += 1.0;
    teller++;
  } while(read_next_x(status,&t,natom,x,box));
  close_trj(status);
  
  invcount = 1.0/count;
  snew(Uaver,DIM*DIM);
  totmass = 0;
  for(i=0; i<isize; i++) {
    for(d=0; d<DIM; d++)
      xav[i*DIM + d] *= invcount;
    for(d=0; d<DIM; d++)
      for(m=0; m<DIM; m++) {
	U[i][d*DIM + m] = U[i][d*DIM + m]*invcount 
	  - xav[i*DIM + d]*xav[i*DIM + m];
	Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m];
      }
    totmass += top.atoms.atom[index[i]].m;
  }
  for(d=0; d<DIM*DIM; d++)
    Uaver[d] /= totmass;

  if (bAniso) {
    for(i=0; i<isize; i++) {
      aid = index[i];
      pdbatoms->pdbinfo[aid].bAnisotropic = TRUE;
      pdbatoms->pdbinfo[aid].uij[U11] = 1e6*U[i][XX*DIM + XX];
      pdbatoms->pdbinfo[aid].uij[U22] = 1e6*U[i][YY*DIM + YY];
      pdbatoms->pdbinfo[aid].uij[U33] = 1e6*U[i][ZZ*DIM + ZZ];
      pdbatoms->pdbinfo[aid].uij[U12] = 1e6*U[i][XX*DIM + YY];
      pdbatoms->pdbinfo[aid].uij[U13] = 1e6*U[i][XX*DIM + ZZ];
      pdbatoms->pdbinfo[aid].uij[U23] = 1e6*U[i][YY*DIM + ZZ];
    }
  }
  if (bRes) {
    average_residues(rmsf,isize,index,w_rls,&top.atoms);
    label = "Residue";
  } else
    label = "Atom";

  for(i=0; i<isize; i++)
    rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ];
  
  if (dirfn) {
    fprintf(stdout,"\n");
    print_dir(stdout,Uaver);
    fp = ffopen(dirfn,"w");
    print_dir(fp,Uaver);
    fclose(fp);
  }

  for(i=0; i<isize; i++)
    sfree(U[i]);
  sfree(U);

  /* Write RMSF output */
  if (bReadPDB) {
    bfac = 8.0*M_PI*M_PI/3.0*100;
    fp   = xvgropen(ftp2fn(efXVG,NFILE,fnm),"B-Factors",
		    label,"(A\\b\\S\\So\\N\\S2\\N)");
    xvgr_legend(fp,2,leg);
    for(i=0;(i<isize);i++) {
      if (!bRes || i+1==isize ||
	  top.atoms.atom[index[i]].resnr!=top.atoms.atom[index[i+1]].resnr) {
	resnr    = top.atoms.atom[index[i]].resnr;
	pdb_bfac = find_pdb_bfac(pdbatoms,*(top.atoms.resname[resnr]),resnr,
				 *(top.atoms.atomname[index[i]]));
	
	fprintf(fp,"%5d  %10.5f  %10.5f\n",
		bRes ? top.atoms.atom[index[i]].resnr+1 : i+1,rmsf[i]*bfac,
		pdb_bfac);
      }
    }
    fclose(fp);
  } else {
    fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"RMS fluctuation",label,"(nm)");
    for(i=0; i<isize; i++)
      if (!bRes || i+1==isize ||
	  top.atoms.atom[index[i]].resnr!=top.atoms.atom[index[i+1]].resnr)
	fprintf(fp,"%5d %8.4f\n",
		bRes ? top.atoms.atom[index[i]].resnr+1 : i+1,sqrt(rmsf[i]));
    fclose(fp);
  }
  
  for(i=0; i<isize; i++)
    pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i];

  if (devfn) {
    for(i=0; i<isize; i++)
      rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count;
    if (bRes)
      average_residues(rmsf,isize,index,w_rls,&top.atoms); 
    /* Write RMSD output */
    fp = xvgropen(devfn,"RMS Deviation",label,"(nm)");
    for(i=0; i<isize; i++)
      if (!bRes || i+1==isize ||
	  top.atoms.atom[index[i]].resnr!=top.atoms.atom[index[i+1]].resnr)
	fprintf(fp,"%5d %8.4f\n",
		bRes ? top.atoms.atom[index[i]].resnr+1 : i+1,sqrt(rmsf[i]));
    fclose(fp);
  }

  if (opt2bSet("-oq",NFILE,fnm)) {
    /* Write a pdb file with B-factors and optionally anisou records */
    for(i=0; i<isize; i++)
      rvec_inc(xref[index[i]],xcm);
    write_sto_conf_indexed(opt2fn("-oq",NFILE,fnm),title,pdbatoms,pdbx,
			   NULL,ePBC,pdbbox,isize,index);
  }
  if (opt2bSet("-ox",NFILE,fnm)) {
    /* Misuse xref as a temporary array */
    for(i=0; i<isize; i++)
      for(d=0; d<DIM; d++)
	xref[index[i]][d] = xcm[d] + xav[i*DIM + d];
    /* Write a pdb file with B-factors and optionally anisou records */
    write_sto_conf_indexed(opt2fn("-ox",NFILE,fnm),title,pdbatoms,xref,NULL,
			   ePBC,pdbbox,isize,index);
  }
  if (bAniso) { 
    correlate_aniso(opt2fn("-oc",NFILE,fnm),refatoms,pdbatoms);
    do_view(opt2fn("-oc",NFILE,fnm),"-nxy");
  }
  do_view(opt2fn("-o",NFILE,fnm),"-nxy");
  if (devfn)
    do_view(opt2fn("-od",NFILE,fnm),"-nxy");
    
  thanx(stderr);
  
  return 0;
}
Beispiel #17
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "[TT]compnl[tt] compares two neighborlists as generated by [TT]mdrun[tt]",
    "in the log file, when the environment variable DUMPNL is set to",
    "a number larger than 0. [TT]compnl[tt] is mainly used for debugging the",
    "[TT]mdrun[tt] internals and not for end-users."
  };
  FILE    *in,*out;
  int     i,j,nmiss,mod;
  char    **fn,title[256];
  int     ***mat,nnb;
  real    mb;
  gmx_bool    bConf;
  rvec    *x = NULL;
  rvec    dx;
  matrix  box;
  t_atoms atoms;
  t_pbc   pbc;
  
  t_filenm fnm[] = {
    { efLOG, "-f1", NULL, ffREAD },
    { efLOG, "-f2", NULL, ffREAD },
    { efOUT, "-o",  "compnl", ffWRITE },
    { efSTX, "-c",  NULL, ffOPTRD }
  };
#define NFILE asize(fnm)
  static int natoms=648;
  static gmx_bool bSymm=TRUE;
  static t_pargs pa[] = {
    { "-nat",  FALSE, etINT, { &natoms }, "Number of atoms" },
    { "-symm", FALSE, etBOOL,{ &bSymm  }, "Symmetrize the matrices" },
  };

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);

  bConf = (opt2bSet("-c",NFILE,fnm));
  if (bConf) {
    get_stx_coordnum (opt2fn("-c",NFILE,fnm),&natoms);
    init_t_atoms(&atoms,natoms,FALSE);
    snew(x,natoms);
    read_stx_conf(opt2fn("-c",NFILE,fnm),title,&atoms,x,NULL,box);
    set_pbc(&pbc,box);
  }
  snew(fn,2);
  fn[0] = opt2fn("-f1",NFILE,fnm);
  fn[1] = opt2fn("-f2",NFILE,fnm);
  
  snew(mat,2);  
  out = gmx_fio_fopen(ftp2fn(efOUT,NFILE,fnm),"w");
  mb  = sizeof(int)*sqr(natoms/1024.0);
  for(i=0; (i<2); i++) {
    in = gmx_fio_fopen(fn[i],"r");
    fprintf(stderr,"Reading %s\n",fn[i]);
    fprintf(out,   "Reading %s\n",fn[i]);
    fprintf(stderr,"Going to allocate %.0f Mb of memory\n",mb);
    fprintf(out,   "Going to allocate %.0f Mb of memory\n",mb);
    snew(mat[i],natoms);
    for(j=0; (j<natoms); j++) 
      snew(mat[i][j],natoms);
    nnb = read_nblist(in,out,mat[i],natoms,bSymm);
    gmx_fio_fclose(in);
    fprintf(stderr,"Interaction matrix %d has %d entries\n",i,nnb);
    fprintf(out,   "Interaction matrix %d has %d entries\n",i,nnb);
  }
  fprintf(stderr,"Comparing Interaction Matrices\n");
  mod=1;
  nmiss = 0;
  for(i=0; (i<natoms); i+=mod) {
    for(j=0; (j<natoms); j+=mod) {
      if (mat[0][i][j] != mat[1][i][j]) {
	fprintf(out,"i: %5d, j: %5d, shift[%s]: %3d, shift[%s]: %3d",
		i,j,fn[0],mat[0][i][j]-1,fn[1],mat[1][i][j]-1);
	if (bConf) {
	  pbc_dx(&pbc,x[i],x[j],dx);
	  fprintf(out," dist: %8.3f\n",norm(dx));
	}
	else
	  fprintf(out,"\n");
	nmiss++;
      }
    }
  }
  fprintf(out,"There were %d mismatches\n",nmiss);
  fprintf(out,"Done.\n");
  gmx_fio_fclose(out);
  fprintf(stderr,"There were %d mismatches\n",nmiss);
  fprintf(stderr,"Finished\n");
  
  thanx(stdout);
  
  return 0;
}
int gmx_trjorder(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]trjorder[tt] orders molecules according to the smallest distance",
    "to atoms in a reference group",
    "or on z-coordinate (with option [TT]-z[tt]).",
    "With distance ordering, it will ask for a group of reference",
    "atoms and a group of molecules. For each frame of the trajectory",
    "the selected molecules will be reordered according to the shortest",
    "distance between atom number [TT]-da[tt] in the molecule and all the",
    "atoms in the reference group. The center of mass of the molecules can",
    "be used instead of a reference atom by setting [TT]-da[tt] to 0.",
    "All atoms in the trajectory are written",
    "to the output trajectory.[PAR]",
    "[TT]trjorder[tt] can be useful for e.g. analyzing the n waters closest to a",
    "protein.",
    "In that case the reference group would be the protein and the group",
    "of molecules would consist of all the water atoms. When an index group",
    "of the first n waters is made, the ordered trajectory can be used",
    "with any Gromacs program to analyze the n closest waters.",
    "[PAR]",
    "If the output file is a [TT].pdb[tt] file, the distance to the reference target",
    "will be stored in the B-factor field in order to color with e.g. Rasmol.",
    "[PAR]",
    "With option [TT]-nshell[tt] the number of molecules within a shell",
    "of radius [TT]-r[tt] around the reference group are printed."
  };
  static int na=3,ref_a=1;
  static real rcut=0;
  static gmx_bool bCOM=FALSE,bZ=FALSE;
  t_pargs pa[] = {
    { "-na", FALSE, etINT,  {&na},
      "Number of atoms in a molecule" },
    { "-da", FALSE, etINT,  {&ref_a},
      "Atom used for the distance calculation, 0 is COM" },
    { "-com", FALSE, etBOOL, {&bCOM},
      "Use the distance to the center of mass of the reference group" },
    { "-r",  FALSE, etREAL, {&rcut},
      "Cutoff used for the distance calculation when computing the number of molecules in a shell around e.g. a protein" },
    { "-z", FALSE, etBOOL, {&bZ},
      "Order molecules on z-coordinate" }
  };
  FILE       *fp;
  t_trxstatus *out;
  t_trxstatus *status;
  gmx_bool       bNShell,bPDBout;
  t_topology top;
  int        ePBC;
  rvec       *x,*xsol,xcom,dx;
  matrix     box;
  t_pbc      pbc;
  gmx_rmpbc_t gpbc;
  real       t,totmass,mass,rcut2=0,n2;
  int        natoms,nwat,ncut;
  char       **grpname,title[256];
  int        i,j,d,*isize,isize_ref=0,isize_sol;
  atom_id    sa,sr,*swi,**index,*ind_ref=NULL,*ind_sol;
  output_env_t oenv;
  t_filenm fnm[] = { 
    { efTRX, "-f", NULL, ffREAD  }, 
    { efTPS, NULL, NULL, ffREAD  }, 
    { efNDX, NULL, NULL, ffOPTRD },
    { efTRO, "-o", "ordered", ffOPTWR },
    { efXVG, "-nshell", "nshell", ffOPTWR } 
  }; 
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); 

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,TRUE);
  sfree(x);

  /* get index groups */
  printf("Select %sa group of molecules to be ordered:\n",
	 bZ ? "" : "a group of reference atoms and "); 
  snew(grpname,2);
  snew(index,2);
  snew(isize,2);
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),bZ ? 1 : 2,
	    isize,index,grpname);

  if (!bZ) {
    isize_ref = isize[0];
    isize_sol = isize[1];
    ind_ref   = index[0];
    ind_sol   = index[1];
  } else {
    isize_sol = isize[0];
    ind_sol   = index[0];
  }

  natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); 
  if (natoms > top.atoms.nr)
    gmx_fatal(FARGS,"Number of atoms in the run input file is larger than in the trjactory");
  for(i=0; (i<2); i++)
    for(j=0; (j<isize[i]); j++)
      if (index[i][j] > natoms)
	gmx_fatal(FARGS,"An atom number in group %s is larger than the number of atoms in the trajectory");
  
  if ((isize_sol % na) != 0)
    gmx_fatal(FARGS,"Number of atoms in the molecule group (%d) is not a multiple of na (%d)",
		isize[1],na);
		
  nwat = isize_sol/na;
  if (ref_a > na)
    gmx_fatal(FARGS,"The reference atom can not be larger than the number of atoms in a molecule");
  ref_a--;
  snew(xsol,nwat);
  snew(order,nwat);
  snew(swi,natoms);
  for(i=0; (i<natoms); i++)
    swi[i] = i;

  out     = NULL;
  fp      = NULL;
  bNShell = ((opt2bSet("-nshell",NFILE,fnm)) ||
	     (opt2parg_bSet("-r",asize(pa),pa)));
  bPDBout = FALSE;
  if (bNShell) {
    rcut2   = rcut*rcut;
    fp = xvgropen(opt2fn("-nshell",NFILE,fnm),"Number of molecules",
		  "Time (ps)","N",oenv);
    printf("Will compute the number of molecules within a radius of %g\n",
	   rcut);
  }
  if (!bNShell || opt2bSet("-o",NFILE,fnm)) {
    bPDBout = (fn2ftp(opt2fn("-o",NFILE,fnm)) == efPDB);
    if (bPDBout && !top.atoms.pdbinfo) {
      fprintf(stderr,"Creating pdbfino records\n");
      snew(top.atoms.pdbinfo,top.atoms.nr);
    }
    out = open_trx(opt2fn("-o",NFILE,fnm),"w");
  }
  gpbc = gmx_rmpbc_init(&top.idef,ePBC,natoms,box);
  do {
    gmx_rmpbc(gpbc,natoms,box,x);
    set_pbc(&pbc,ePBC,box);

    if (ref_a == -1) {
      /* Calculate the COM of all solvent molecules */
      for(i=0; i<nwat; i++) {
	totmass = 0;
	clear_rvec(xsol[i]);
	for(j=0; j<na; j++) {
	  sa = ind_sol[i*na+j];
	  mass = top.atoms.atom[sa].m;
	  totmass += mass;
	  for(d=0; d<DIM; d++) {
	    xsol[i][d] += mass*x[sa][d];
	  }
	}
	svmul(1/totmass,xsol[i],xsol[i]);
      }
    } else {
      /* Copy the reference atom of all solvent molecules */
      for(i=0; i<nwat; i++) {
	copy_rvec(x[ind_sol[i*na+ref_a]],xsol[i]);
      }
    }

    if (bZ) {
      for(i=0; (i<nwat); i++) {
	sa = ind_sol[na*i];
	order[i].i   = sa;
	order[i].d2  = xsol[i][ZZ]; 
      }
    } else if (bCOM) {
      totmass = 0;
      clear_rvec(xcom);
      for(i=0; i<isize_ref; i++) {
	mass = top.atoms.atom[ind_ref[i]].m;
	totmass += mass;
	for(j=0; j<DIM; j++)
	  xcom[j] += mass*x[ind_ref[i]][j];
      }
      svmul(1/totmass,xcom,xcom);
      for(i=0; (i<nwat); i++) {
	sa = ind_sol[na*i];
	pbc_dx(&pbc,xcom,xsol[i],dx);
	order[i].i   = sa;
	order[i].d2  = norm2(dx); 
      }
    } else {
      /* Set distance to first atom */
      for(i=0; (i<nwat); i++) {
	sa = ind_sol[na*i];
	pbc_dx(&pbc,x[ind_ref[0]],xsol[i],dx);
	order[i].i   = sa;
	order[i].d2  = norm2(dx); 
      }
      for(j=1; (j<isize_ref); j++) {
	sr = ind_ref[j];
	for(i=0; (i<nwat); i++) {
	  sa = ind_sol[na*i];
	  pbc_dx(&pbc,x[sr],xsol[i],dx);
	  n2 = norm2(dx);
	  if (n2 < order[i].d2)
	    order[i].d2  = n2;
	}
      }
    }

    if (bNShell) {
      ncut = 0;
      for(i=0; (i<nwat); i++)
	if (order[i].d2 <= rcut2)
	  ncut++;
      fprintf(fp,"%10.3f  %8d\n",t,ncut);
    }
    if (out) {
      qsort(order,nwat,sizeof(*order),ocomp);
      for(i=0; (i<nwat); i++)
	for(j=0; (j<na); j++) 
	  swi[ind_sol[na*i]+j] = order[i].i+j;
      
      /* Store the distance as the B-factor */
      if (bPDBout) {
	for(i=0; (i<nwat); i++) {
	  for(j=0; (j<na); j++) {
	    top.atoms.pdbinfo[order[i].i+j].bfac = sqrt(order[i].d2);
	  }
	}
      }
      write_trx(out,natoms,swi,&top.atoms,0,t,box,x,NULL,NULL);
    }
  } while(read_next_x(oenv,status,&t,natoms,x,box));
  close_trj(status);
  if (out)
    close_trx(out);
  if (fp)
    ffclose(fp);
  gmx_rmpbc_done(gpbc);
  
  thanx(stderr);
  
  return 0;
}
Beispiel #19
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "testlr tests the PPPM and Ewald method for the",
    "long range electrostatics problem."
  };
  static t_filenm  fnm[] = {
    { efTPX, NULL,   NULL,       ffREAD },
    { efHAT, "-g",   "ghat",     ffOPTRD },
    { efOUT, "-o",   "rho",      ffOPTWR },
    { efOUT, "-op",  "lr-pb",    ffOPTWR },
    { efOUT, "-of",  "lr-four",  ffOPTWR },
    { efOUT, "-opt", "tot-pb",   ffOPTWR },
    { efOUT, "-oft", "tot-four", ffOPTWR },
    { efOUT, "-fin", "lr-four",  ffOPTWR },
    { efEPS, "-es",  "sr",       ffOPTWR },
    { efEPS, "-elf", "lr-four",  ffOPTWR },
    { efEPS, "-etf", "tot-four", ffOPTWR },
    { efEPS, "-qr",  "qk-real",  ffOPTWR },
    { efEPS, "-qi",  "qk-im",    ffOPTWR },
    { efEPS, "-elp", "lr-pb",    ffOPTWR },
    { efEPS, "-etp", "tot-pb",   ffOPTWR },
    { efEPS, "-rho", "rho",      ffOPTWR },
    { efEPS, "-qq",  "charge",   ffOPTWR },
    { efXVG, "-gt",  "gk-tab",   ffOPTWR },
    { efXVG, "-fcorr","fcorr",   ffWRITE },
    { efXVG, "-pcorr","pcorr",   ffWRITE },
    { efXVG, "-ftotcorr","ftotcorr",   ffWRITE },
    { efXVG, "-ptotcorr","ptotcorr",   ffWRITE },
    { efLOG, "-l",   "fptest",   ffWRITE },
    { efXVG, "-gr",  "spread",   ffOPTWR },
    { efPDB, "-pf",  "pqr-four", ffOPTWR },
    { efPDB, "-phitot", "pppm-phitot", ffOPTWR }
  };
#define NFILE asize(fnm)
  FILE         *log;
  t_topology   top;
  t_tpxheader  stath;
  t_inputrec   ir;
  t_block      *excl;
  t_forcerec   *fr;
  t_commrec    *cr;
  t_mdatoms    *mdatoms;
  t_graph      *graph;
  int          i,step,nre,natoms,nmol;
  rvec         *x,*f_sr,*f_excl,*f_four,*f_pppm,*f_pois,box_size,hbox;
  matrix       box;
  real         t,lambda,vsr,*charge,*phi_f,*phi_pois,*phi_s,*phi_p3m,*rho;
  
  static bool bFour=FALSE,bVerbose=FALSE,bGGhat=FALSE,bPPPM=TRUE,
    bPoisson=FALSE,bOld=FALSE,bOldEwald=TRUE;
  static int nprocs = 1;
  static t_pargs pa[] = {
    { "-np",     FALSE, etINT,  &nprocs,  "Do it in parallel" },
    { "-ewald",  FALSE, etBOOL, &bFour,   "Do an Ewald solution"},
    { "-pppm",   FALSE, etBOOL, &bPPPM,   "Do a PPPM solution" },
    { "-poisson",FALSE, etBOOL, &bPoisson,"Do a Poisson solution" },
    {    "-v",   FALSE, etBOOL, &bVerbose,"Verbose on"},
    { "-ghat",   FALSE, etBOOL, &bGGhat,  "Generate Ghat function"},
    { "-old",    FALSE, etBOOL, &bOld,    "Use old function types"},
    { "-oldewald",FALSE,etBOOL, &bOldEwald,"Use old Ewald code"}
  };

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); 

  if (nprocs > 1) {
    cr = init_par(&argc,argv);
    open_log(ftp2fn(efLOG,NFILE,fnm),cr);
    log = stdlog;
  }
  else {
    cr     = init_par(&argc,argv);
    log    = ftp2FILE(efLOG,NFILE,fnm,"w");
    stdlog = log;  }
  

  /* Read topology and coordinates */
  read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&stath,FALSE);
  snew(x,stath.natoms);
  snew(f_sr,stath.natoms);
  snew(f_excl,stath.natoms);
  snew(f_four,stath.natoms);
  snew(f_pppm,stath.natoms);
  snew(f_pois,stath.natoms);
  read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,&ir,
	   box,&natoms,x,NULL,NULL,&top);
  excl=&(top.atoms.excl);
  nmol=top.blocks[ebMOLS].nr;

  /* Allocate space for potential, charges and rho (charge density) */
  snew(charge,stath.natoms);
  snew(phi_f,stath.natoms);
  snew(phi_p3m,stath.natoms);
  snew(phi_pois,stath.natoms);
  snew(phi_s,stath.natoms);
  snew(rho,stath.natoms);
  
  /* Set the charges */
  for(i=0; (i<natoms); i++)
    charge[i]=top.atoms.atom[i].q;

  /* Make a simple box vector instead of tensor */
  for(i=0; (i<DIM); i++) 
    box_size[i]=box[i][i];
  
  /* Set some constants */
  fr      = mk_forcerec();
  mdatoms = atoms2md(&(top.atoms),FALSE,FALSE);
  
  set_LRconsts(log,ir.rcoulomb_switch,ir.rcoulomb,box_size,fr);
  init_forcerec(log,fr,&ir,&(top.blocks[ebMOLS]),cr,
		&(top.blocks[ebCGS]),&(top.idef),mdatoms,box,FALSE);
  calc_shifts(box,box_size,fr->shift_vec,FALSE);

  /* Periodicity stuff */  
  graph = mk_graph(&(top.idef),top.atoms.nr,FALSE,FALSE);
  shift_self(graph,fr->shift_vec,x);

  calc_LRcorrections(log,0,natoms,ir.rcoulomb_switch,
		     ir.rcoulomb,charge,excl,x,f_excl,bOld);
  pr_f("f_excl.dat",natoms,f_excl);
  
  /* Compute the short range potential */
  put_atoms_in_box(natoms,box,x);
  vsr=phi_sr(log,natoms,x,charge,ir.rcoulomb,
	     ir.rcoulomb_switch,box_size,phi_s,excl,f_sr,bOld); 
  pr_f("f_sr.dat",natoms,f_sr);
  
  /* Plot the short range potential in a matrix */    
  calc_ener(log,"Short Range",TRUE,nmol,natoms,phi_s,charge,excl);
  
  
  if (bFour)   
    test_four(log,NFILE,fnm,&(top.atoms),&ir,x,f_four,box_size,charge,phi_f,
	      phi_s,nmol,cr,bOld,bOldEwald);
  
  if (bPPPM) 
    test_pppm(log,bVerbose,bGGhat,opt2fn("-g",NFILE,fnm),
	      &(top.atoms),&ir,x,f_pppm,charge,box_size,phi_p3m,phi_s,nmol,
	      cr,bOld,&(top.blocks[ebCGS]));
  
  if (bPoisson)
    test_poisson(log,bVerbose,
		 &(top.atoms),&ir,x,f_pois,charge,box_size,phi_pois,
		 phi_s,nmol,cr,bFour,f_four,phi_f,bOld);
	        
  if (bPPPM && bFour) 
    analyse_diff(log,"PPPM",
		 top.atoms.nr,f_four,f_pppm,phi_f,phi_p3m,phi_s,
		 opt2fn("-fcorr",NFILE,fnm),
		 opt2fn("-pcorr",NFILE,fnm),
		 opt2fn("-ftotcorr",NFILE,fnm),
		 opt2fn("-ptotcorr",NFILE,fnm));
  
  if (bPoisson && bFour) 
    analyse_diff(log,"Poisson",
		 top.atoms.nr,f_four,f_pois,phi_f,phi_pois,phi_s,
		 opt2fn("-fcorr",NFILE,fnm),
		 opt2fn("-pcorr",NFILE,fnm),
		 opt2fn("-ftotcorr",NFILE,fnm),
		 opt2fn("-ptotcorr",NFILE,fnm));
  
  gmx_fio_fclose(log);
  
  thanx(stderr);
  
  return 0;
}
int gmx_editconf(int argc, char *argv[])
{
  static char *desc[] = {
    "editconf converts generic structure format to [TT].gro[tt], [TT].g96[tt]",
    "or [TT].pdb[tt].",
    "[PAR]",
    "The box can be modified with options [TT]-box[tt], [TT]-d[tt] and",
    "[TT]-angles[tt]. Both [TT]-box[tt] and [TT]-d[tt]",
    "will center the system in the box, unless [TT]-noc[tt] is used.",
    "[PAR]",
    "Option [TT]-bt[tt] determines the box type: [TT]triclinic[tt] is a",
    "triclinic box, [TT]cubic[tt] is a rectangular box with all sides equal", 
    "[TT]dodecahedron[tt] represents a rhombic dodecahedron and "
    "[TT]octahedron[tt] is a truncated octahedron.",
    "The last two are special cases of a triclinic box.",
    "The length of the three box vectors of the truncated octahedron is the",
    "shortest distance between two opposite hexagons.",
    "The volume of a dodecahedron is 0.71 and that of a truncated octahedron",
    "is 0.77 of that of a cubic box with the same periodic image distance.",
    "[PAR]",
    "Option [TT]-box[tt] requires only",
    "one value for a cubic box, dodecahedron and a truncated octahedron.",
    "[PAR]",
    "With [TT]-d[tt] and a [TT]triclinic[tt] box the size of the system in the x, y",
    "and z directions is used. With [TT]-d[tt] and [TT]cubic[tt],",
    "[TT]dodecahedron[tt] or [TT]octahedron[tt] boxes, the dimensions are set",
    "to the diameter of the system (largest distance between atoms) plus twice",
    "the specified distance.",
    "[PAR]",
    "Option [TT]-angles[tt] is only meaningful with option [TT]-box[tt] and",
    "a triclinic box and can not be used with option [TT]-d[tt].",
    "[PAR]",
    "When [TT]-n[tt] or [TT]-ndef[tt] is set, a group",
    "can be selected for calculating the size and the geometric center,",
    "otherwise the whole system is used.",
    "[PAR]",
    "[TT]-rotate[tt] rotates the coordinates and velocities.",
    "[PAR]",
    "[TT]-princ[tt] aligns the principal axes of the system along the",
    "coordinate axes, this may allow you to decrease the box volume,",
    "but beware that molecules can rotate significantly in a nanosecond.",
    "[PAR]",
    "Scaling is applied before any of the other operations are",
    "performed. Boxes and coordinates can be scaled to give a certain density (option",
    "[TT]-density[tt]). Note that this may be inaccurate in case a gro",
    "file is given as input. A special feature of the scaling option, when the",
    "factor -1 is given in one dimension, one obtains a mirror image,",
    "mirrored in one of the plains, when one uses -1 in three dimensions",
    "a point-mirror image is obtained.[PAR]",
    "Groups are selected after all operations have been applied.[PAR]",
    "Periodicity can be removed in a crude manner.",
    "It is important that the box sizes at the bottom of your input file",
    "are correct when the periodicity is to be removed.",
    "[PAR]",
    "When writing [TT].pdb[tt] files, B-factors can be",
    "added with the [TT]-bf[tt] option. B-factors are read",
    "from a file with with following format: first line states number of",
    "entries in the file, next lines state an index",
    "followed by a B-factor. The B-factors will be attached per residue",
    "unless an index is larger than the number of residues or unless the",
    "[TT]-atom[tt] option is set. Obviously, any type of numeric data can",
    "be added instead of B-factors. [TT]-legend[tt] will produce",
    "a row of CA atoms with B-factors ranging from the minimum to the",
    "maximum value found, effectively making a legend for viewing.",
    "[PAR]",
    "With the option -mead a special pdb (pqr) file for the MEAD electrostatics",
    "program (Poisson-Boltzmann solver) can be made. A further prerequisite",
    "is that the input file is a run input file.",
    "The B-factor field is then filled with the Van der Waals radius",
    "of the atoms while the occupancy field will hold the charge.",
    "[PAR]",
    "The option -grasp is similar, but it puts the charges in the B-factor",
    "and the radius in the occupancy.",
    "[PAR]",
    "Finally with option [TT]-label[tt] editconf can add a chain identifier",
    "to a pdb file, which can be useful for analysis with e.g. rasmol."
    "[PAR]",
    "To convert a truncated octrahedron file produced by a package which uses",
    "a cubic box with the corners cut off (such as Gromos) use:[BR]",
    "[TT]editconf -f <in> -rotate 0 45 35.264 -bt o -box <veclen> -o <out>[tt][BR]",
    "where [TT]veclen[tt] is the size of the cubic box times sqrt(3)/2."
  };
  static char *bugs[] = {
    "For complex molecules, the periodicity removal routine may break down, "
    "in that case you can use trjconv"
  };
  static real dist=0.0,rbox=0.0,to_diam=0.0;
  static bool bNDEF=FALSE,bRMPBC=FALSE,bCenter=FALSE,bReadVDW=FALSE;
  static bool peratom=FALSE,bLegend=FALSE,bOrient=FALSE,bMead=FALSE,bGrasp=FALSE,bSig56=FALSE;
  static rvec scale={1,1,1},newbox={0,0,0},newang={90,90,90};
  static real rho=1000.0,rvdw=0.12;
  static rvec center={0,0,0},translation={0,0,0},rotangles={0,0,0};
  static char *btype[]={ NULL, "triclinic", "cubic", "dodecahedron", "octahedron", NULL },*label="A";
  static rvec visbox={0,0,0};
  t_pargs pa[] = {
    { "-ndef",   FALSE, etBOOL, {&bNDEF}, 
      "Choose output from default index groups" },
    { "-visbox",    FALSE, etRVEC, {visbox}, 
      "HIDDENVisualize a grid of boxes, -1 visualizes the 14 box images" },
    { "-bt",   FALSE, etENUM, {btype}, 
      "Box type for -box and -d" },
    { "-box",    FALSE, etRVEC, {newbox}, "Box vector lengths (a,b,c)" },
    { "-angles", FALSE, etRVEC, {newang},
	"Angles between the box vectors (bc,ac,ab)" },
    { "-d",      FALSE, etREAL, {&dist}, 
      "Distance between the solute and the box" },
    { "-c",      FALSE, etBOOL, {&bCenter},
      "Center molecule in box (implied by -box and -d)" },
    { "-center", FALSE, etRVEC, {center}, "Coordinates of geometrical center"},
    { "-translate", FALSE, etRVEC, {translation},
      "Translation" },
    { "-rotate", FALSE, etRVEC, {rotangles},
      "Rotation around the X, Y and Z axes in degrees" },
    { "-princ",  FALSE, etBOOL, {&bOrient}, "Orient molecule(s) along their principal axes" },
    { "-scale",  FALSE, etRVEC, {scale}, "Scaling factor" },
    { "-density",FALSE, etREAL, {&rho}, 
      "Density (g/l) of the output box achieved by scaling" },
    { "-pbc",    FALSE, etBOOL, {&bRMPBC}, 
      "Remove the periodicity (make molecule whole again)" },
    { "-grasp",  FALSE, etBOOL, {&bGrasp},
      "Store the charge of the atom in the B-factor field and the radius of the atom in the occupancy field" },
    { "-rvdw",   FALSE, etREAL, {&rvdw},
      "Default Van der Waals radius (in nm) if one can not be found in the database or if no parameters are present in the topology file" },
    { "-sig56",  FALSE, etREAL, {&bSig56},
      "Use rmin/2 (minimum in the Van der Waals potential) rather than sigma/2 " },
    { "-vdwread",FALSE, etBOOL, {&bReadVDW},
      "Read the Van der Waals radii from the file vdwradii.dat rather than computing the radii based on the force field" },
    { "-atom",   FALSE, etBOOL, {&peratom}, "Force B-factor attachment per atom" },
    { "-legend", FALSE, etBOOL, {&bLegend}, "Make B-factor legend" },
    { "-label",  FALSE, etSTR,  {&label},   "Add chain label for all residues" }
  };
#define NPA asize(pa)

  FILE       *out;
  char       *infile,*outfile,title[STRLEN];
  int        outftp,natom,i,j,n_bfac,itype,ntype;
  double     *bfac=NULL,c6,c12;
  int        *bfac_nr=NULL;
  t_topology *top;
  t_atoms    atoms;
  char       *grpname,*sgrpname;
  int        isize,ssize,tsize;
  atom_id    *index,*sindex,*tindex;
  rvec       *x,*v,gc,min,max,size;
  int        ePBC;
  matrix     box;
  bool       bIndex,bSetSize,bSetAng,bCubic,bDist,bSetCenter;
  bool       bHaveV,bScale,bRho,bTranslate,bRotate,bCalcGeom,bCalcDiam;
  real       xs,ys,zs,xcent,ycent,zcent,diam=0,mass=0,d,vdw;
  gmx_atomprop_t aps;
  t_filenm fnm[] = {
    { efSTX, "-f",    NULL,    ffREAD },
    { efNDX, "-n",    NULL,    ffOPTRD },
    { efSTO, NULL,    NULL,    ffOPTWR },
    { efPQR, "-mead", "mead",  ffOPTWR },
    { efDAT, "-bf",   "bfact", ffOPTRD }
  };
#define NFILE asize(fnm)

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW,NFILE,fnm,NPA,pa,
		    asize(desc),desc,asize(bugs),bugs);

  bIndex    = opt2bSet("-n",NFILE,fnm) || bNDEF;
  bMead     = opt2bSet("-mead",NFILE,fnm);
  bSetSize  = opt2parg_bSet("-box" ,NPA,pa);
  bSetAng   = opt2parg_bSet("-angles" ,NPA,pa);
  bSetCenter= opt2parg_bSet("-center" ,NPA,pa);
  bDist     = opt2parg_bSet("-d" ,NPA,pa);
  /* Only automatically turn on centering without -noc */
  if ((bDist || bSetSize || bSetCenter) && !opt2parg_bSet("-c",NPA,pa)) {
    bCenter = TRUE;
  }
  bScale    = opt2parg_bSet("-scale" ,NPA,pa);
  bRho      = opt2parg_bSet("-density",NPA,pa);
  bTranslate= opt2parg_bSet("-translate",NPA,pa);
  bRotate   = opt2parg_bSet("-rotate",NPA,pa);
  if (bScale && bRho)
    fprintf(stderr,"WARNING: setting -density overrides -scale\n");
  bScale    = bScale || bRho;
  bCalcGeom = bCenter || bRotate || bOrient || bScale;
  bCalcDiam = btype[0][0]=='c' || btype[0][0]=='d' || btype[0][0]=='o';
  
  infile  = ftp2fn(efSTX,NFILE,fnm);
  if (bMead) 
    outfile = ftp2fn(efPQR,NFILE,fnm);
  else
    outfile = ftp2fn(efSTO,NFILE,fnm);
  outftp  = fn2ftp(outfile);
  
  aps = gmx_atomprop_init();

  if (bMead && bGrasp) {
    printf("Incompatible options -mead and -grasp. Turning off -grasp\n");
    bGrasp = FALSE;
  }
  if (bGrasp && (outftp != efPDB))
    gmx_fatal(FARGS,"Output file should be a .pdb file"
	      " when using the -grasp option\n");
  if ((bMead || bGrasp) && !((fn2ftp(infile) == efTPR) || 
			     (fn2ftp(infile) == efTPA) ||
			     (fn2ftp(infile) == efTPB)))
    gmx_fatal(FARGS,"Input file should be a .tp[abr] file"
	      " when using the -mead option\n");
  
  get_stx_coordnum(infile,&natom);
  init_t_atoms(&atoms,natom,TRUE);
  snew(x,natom);
  snew(v,natom);
  read_stx_conf(infile,title,&atoms,x,v,&ePBC,box);
  printf("Read %d atoms\n",atoms.nr); 
  if (ePBC != epbcNONE) {
    real vol = det(box);
    printf("Volume: %g nm^3, corresponds to roughly %d electrons\n",
	   vol,100*((int)(vol*4.5)));
  }

  if (bMead || bGrasp) {
    top = read_top(infile,NULL);
    if (atoms.nr != top->atoms.nr)
      gmx_fatal(FARGS,"Atom numbers don't match (%d vs. %d)",
		  atoms.nr,top->atoms.nr);
    snew(atoms.pdbinfo,top->atoms.nr); 
    ntype = top->idef.atnr;
    for(i=0; (i<atoms.nr); i++) {
      /* Determine the Van der Waals radius from the force field */
      if (bReadVDW) {
	if (!gmx_atomprop_query(aps,epropVDW,
				*top->atoms.resname[top->atoms.atom[i].resnr],
				*top->atoms.atomname[i],&vdw))
	  vdw = rvdw;
      }
      else {
	itype = top->atoms.atom[i].type;
	c12   = top->idef.iparams[itype*ntype+itype].lj.c12;
	c6    = top->idef.iparams[itype*ntype+itype].lj.c6;
	if ((c6 != 0) && (c12 != 0)) {
	  real sig6; 
	  if (bSig56)
	    sig6 = 2*c12/c6;
	  else
	    sig6 = c12/c6;
	  vdw   = 0.5*pow(sig6,1.0/6.0);
	}
	else
	  vdw = rvdw;
      }
      /* Factor of 10 for nm -> Angstroms */
      vdw *= 10;
      
      if (bMead) {
	atoms.pdbinfo[i].occup = top->atoms.atom[i].q;
	atoms.pdbinfo[i].bfac  = vdw;
      }
      else {
	atoms.pdbinfo[i].occup = vdw;
	atoms.pdbinfo[i].bfac  = top->atoms.atom[i].q;
      }
    }
  }
  bHaveV=FALSE;
  for (i=0; (i<natom) && !bHaveV; i++)
    for (j=0; (j<DIM) && !bHaveV; j++)
      bHaveV=bHaveV || (v[i][j]!=0);
  printf("%selocities found\n",bHaveV?"V":"No v");

  if (visbox[0] > 0) {
    if (bIndex)
      gmx_fatal(FARGS,"Sorry, can not visualize box with index groups");
    if (outftp != efPDB)
      gmx_fatal(FARGS,"Sorry, can only visualize box with a pdb file");
  } else if (visbox[0] == -1)
    visualize_images("images.pdb",ePBC,box);

  /* remove pbc */
  if (bRMPBC) 
    rm_gropbc(&atoms,x,box);

  if (bCalcGeom) {
    if (bIndex) {
      fprintf(stderr,"\nSelect a group for determining the system size:\n");
      get_index(&atoms,ftp2fn_null(efNDX,NFILE,fnm),
		1,&ssize,&sindex,&sgrpname);
    } else {
      ssize = atoms.nr;
      sindex = NULL;
    }
    diam=calc_geom(ssize,sindex,x,gc,min,max,bCalcDiam);
    rvec_sub(max, min, size);
    printf("    system size :%7.3f%7.3f%7.3f (nm)\n",
	   size[XX], size[YY], size[ZZ]);
    if (bCalcDiam)
      printf("    diameter    :%7.3f               (nm)\n",diam);
    printf("    center      :%7.3f%7.3f%7.3f (nm)\n", gc[XX], gc[YY], gc[ZZ]);
    printf("    box vectors :%7.3f%7.3f%7.3f (nm)\n", 
	   norm(box[XX]), norm(box[YY]), norm(box[ZZ]));
    printf("    box angles  :%7.2f%7.2f%7.2f (degrees)\n",
	   norm2(box[ZZ])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[YY],box[ZZ])),
	   norm2(box[ZZ])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[XX],box[ZZ])),
	   norm2(box[YY])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[XX],box[YY])));
    printf("    box volume  :%7.2f               (nm^3)\n",det(box));
  }
  
  if (bRho || bOrient)
    mass = calc_mass(&atoms,!fn2bTPX(infile),aps);
  
  if (bOrient) {
    atom_id *index;
    char    *grpnames;
    
    /* Get a group for principal component analysis */
    fprintf(stderr,"\nSelect group for the determining the orientation\n");
    get_index(&atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpnames);
    
    /* Orient the principal axes along the coordinate axes */
    orient_princ(&atoms,isize,index,natom,x,bHaveV ? v : NULL, NULL);
    sfree(index);
    sfree(grpnames);
  }
  
  if ( bScale ) {
    /* scale coordinates and box */
    if (bRho) {
      /* Compute scaling constant */
      real vol,dens;
      
      vol = det(box);
      dens = (mass*AMU)/(vol*NANO*NANO*NANO);
      fprintf(stderr,"Volume  of input %g (nm^3)\n",vol);
      fprintf(stderr,"Mass    of input %g (a.m.u.)\n",mass);
      fprintf(stderr,"Density of input %g (g/l)\n",dens);
      if (vol==0 || mass==0)
	gmx_fatal(FARGS,"Cannot scale density with "
		    "zero mass (%g) or volume (%g)\n",mass,vol);
      
      scale[XX] = scale[YY] = scale[ZZ] = pow(dens/rho,1.0/3.0);
      fprintf(stderr,"Scaling all box vectors by %g\n",scale[XX]);
    }
    scale_conf(atoms.nr,x,box,scale);
  }
  
  if (bTranslate) {
    if (bIndex) {
      fprintf(stderr,"\nSelect a group that you want to translate:\n");
      get_index(&atoms,ftp2fn_null(efNDX,NFILE,fnm),
		1,&ssize,&sindex,&sgrpname);
    } else {
      ssize = atoms.nr;
      sindex = NULL;
    }
    printf("Translating %d atoms (out of %d) by %g %g %g nm\n",ssize,natom,
	   translation[XX],translation[YY],translation[ZZ]);
    if (sindex) {
      for(i=0; i<ssize; i++)
	rvec_inc(x[sindex[i]],translation);
    }
    else {
      for(i=0; i<natom; i++)
	rvec_inc(x[i],translation);
    }
  }
  if (bRotate) {
    /* Rotate */
    printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n",rotangles[XX],rotangles[YY],rotangles[ZZ]);
    for(i=0; i<DIM; i++)
      rotangles[i] *= DEG2RAD;
    rotate_conf(natom,x,v,rotangles[XX],rotangles[YY],rotangles[ZZ]);
  }
  
  if (bCalcGeom) {
    /* recalc geometrical center and max and min coordinates and size */
    calc_geom(ssize,sindex,x,gc,min,max,FALSE);
    rvec_sub(max, min, size);
    if (bScale || bOrient || bRotate)
      printf("new system size : %6.3f %6.3f %6.3f\n",
	     size[XX],size[YY],size[ZZ]);
  }
  
  if (bSetSize || bDist || (btype[0][0]=='t' && bSetAng)) {
    ePBC = epbcXYZ;
    if (!(bSetSize || bDist))
      for (i=0; i<DIM; i++)
	newbox[i] = norm(box[i]);
    clear_mat(box);
    /* calculate new boxsize */
    switch(btype[0][0]){
    case 't':
      if (bDist)
	for(i=0; i<DIM; i++)
	  newbox[i] = size[i]+2*dist;
      if (!bSetAng) {
	box[XX][XX] = newbox[XX];
	box[YY][YY] = newbox[YY];
	box[ZZ][ZZ] = newbox[ZZ];
      } else {
	svmul(DEG2RAD,newang,newang);
	box[XX][XX] = newbox[XX];
	box[YY][XX] = newbox[YY]*cos(newang[ZZ]);
	box[YY][YY] = newbox[YY]*sin(newang[ZZ]);
	box[ZZ][XX] = newbox[ZZ]*cos(newang[YY]);
	box[ZZ][YY] = newbox[ZZ]
	  *(cos(newang[XX])-cos(newang[YY])*cos(newang[ZZ]))/sin(newang[ZZ]);
	box[ZZ][ZZ] = sqrt(sqr(newbox[ZZ])
			   -box[ZZ][XX]*box[ZZ][XX]-box[ZZ][YY]*box[ZZ][YY]);
      }
      break;
    case 'c':
    case 'd':
    case 'o':
      if (bSetSize)
	d = newbox[0];
      else
	d = diam+2*dist;
      if (btype[0][0] == 'c')
	for(i=0; i<DIM; i++)
	  box[i][i] = d;
      else if (btype[0][0] == 'd') {
	box[XX][XX] = d;
	box[YY][YY] = d;
	box[ZZ][XX] = d/2;
	box[ZZ][YY] = d/2;
	box[ZZ][ZZ] = d*sqrt(2)/2;
      } else {
	box[XX][XX] = d;
	box[YY][XX] = d/3;
	box[YY][YY] = d*sqrt(2)*2/3;
	box[ZZ][XX] = -d/3;
	box[ZZ][YY] = d*sqrt(2)/3;
	box[ZZ][ZZ] = d*sqrt(6)/3;
      }
     break;
    } 
  }

  /* calculate new coords for geometrical center */
  if (!bSetCenter)
    calc_box_center(ecenterDEF,box,center);

  /* center molecule on 'center' */
  if (bCenter)
    center_conf(natom,x,center,gc);
    
  /* print some */
  if (bCalcGeom) {
    calc_geom(ssize,sindex,x, gc, min, max, FALSE);
    printf("new center      :%7.3f%7.3f%7.3f (nm)\n",gc[XX],gc[YY],gc[ZZ]);
  }
  if (bOrient || bScale || bDist || bSetSize) {
    printf("new box vectors :%7.3f%7.3f%7.3f (nm)\n", 
	   norm(box[XX]), norm(box[YY]), norm(box[ZZ]));
    printf("new box angles  :%7.2f%7.2f%7.2f (degrees)\n",
	   norm2(box[ZZ])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[YY],box[ZZ])),
	   norm2(box[ZZ])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[XX],box[ZZ])),
	   norm2(box[YY])==0 ? 0 :
	   RAD2DEG*acos(cos_angle_no_table(box[XX],box[YY])));
    printf("new box volume  :%7.2f               (nm^3)\n",det(box));
  }  

  if (check_box(epbcXYZ,box))
    printf("\nWARNING: %s\n",check_box(epbcXYZ,box));

  if (bDist && btype[0][0]=='t')
  {
      if(TRICLINIC(box))
      {
          printf("\nWARNING: Your box is triclinic with non-orthogonal axes. In this case, the\n"
                 "distance from the solute to a box surface along the corresponding normal\n"
                 "vector might be somewhat smaller than your specified value %f.\n"
                 "You can check the actual value with g_mindist -pi\n",dist);
      }
      else
      {
          printf("\nWARNING: No boxtype specified - distance condition applied in each dimension.\n"
                 "If the molecule rotates the actual distance will be smaller. You might want\n"
                 "to use a cubic box instead, or why not try a dodecahedron today?\n");
      }
  }  
  
  if (bIndex) {
    fprintf(stderr,"\nSelect a group for output:\n");
    get_index(&atoms,opt2fn_null("-n",NFILE,fnm),
	      1,&isize,&index,&grpname);
    if (opt2bSet("-bf",NFILE,fnm))
      gmx_fatal(FARGS,"combination not implemented: -bf -n  or -bf -ndef");
    else
      write_sto_conf_indexed(outfile,title,&atoms,x,bHaveV?v:NULL,ePBC,box,
			     isize,index); 
  }
  else {
    if ((outftp == efPDB) || (outftp == efPQR)) {
      out=ffopen(outfile,"w");
      if (bMead) {
	set_pdb_wide_format(TRUE);
	fprintf(out,"REMARK    "
		"The B-factors in this file hold atomic radii\n");
	fprintf(out,"REMARK    "
		"The occupancy in this file hold atomic charges\n");
      }
      else if (bGrasp) {
	fprintf(out,"GRASP PDB FILE\nFORMAT NUMBER=1\n");
	fprintf(out,"REMARK    "
		"The B-factors in this file hold atomic charges\n");
	fprintf(out,"REMARK    "
		"The occupancy in this file hold atomic radii\n");
      }
      else if (opt2bSet("-bf",NFILE,fnm)) {
	read_bfac(opt2fn("-bf",NFILE,fnm),&n_bfac,&bfac,&bfac_nr);
	set_pdb_conf_bfac(atoms.nr,atoms.nres,&atoms,
			  n_bfac,bfac,bfac_nr,peratom);
      }
      if (opt2parg_bSet("-label",NPA,pa)) {
	for(i=0; (i<atoms.nr); i++) 
	  atoms.atom[i].chain=label[0];
      }
      write_pdbfile(out,title,&atoms,x,ePBC,box,0,-1);
      if (bLegend)
	pdb_legend(out,atoms.nr,atoms.nres,&atoms,x);
      if (visbox[0] > 0)
	visualize_box(out,bLegend ? atoms.nr+12 : atoms.nr,
		      bLegend? atoms.nres=12 : atoms.nres,box,visbox);
      fclose(out);
    }
    else
      write_sto_conf(outfile,title,&atoms,x,bHaveV?v:NULL,ePBC,box); 
  }
  gmx_atomprop_destroy(aps);

  do_view(outfile,NULL);
    
  thanx(stderr);
  
  return 0;
}
int gmx_eneconv(int argc,char *argv[])
{
  static char *desc[] = {
    "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[BR]",
    "Concatenates several energy files in sorted order.",
    "In case of double time frames the one",
    "in the later file is used. By specifying [TT]-settime[tt] you will be",
    "asked for the start time of each file. The input files are taken",
    "from the command line,",
    "such that the command [TT]eneconv -o fixed.edr *.edr[tt] should do",
    "the trick. [PAR]",
    "With [IT]one file[it] specified for [TT]-f[tt]:[BR]",
    "Reads one energy file and writes another, applying the [TT]-dt[tt],",
    "[TT]-offset[tt], [TT]-t0[tt] and [TT]-settime[tt] options and",
    "converting to a different format if necessary (indicated by file",
    "extentions).[PAR]",
    "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]",
    "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write."
  };
  static char *bugs[] = {
    "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way."
  };
  int        in,out=0;
  t_enxframe *fr,*fro;
  t_energy   *lastee,*startee;
  int        laststep,startstep,startstep_file=0,noutfr;
  int        nre,nremax,this_nre,nfile,i,j,kkk,nset,*set=NULL;
  real       t=0; 
  char       **fnms;
  char       **enm=NULL;
  real       *readtime,*settime,timestep,t1,tadjust;
  char       inputstring[STRLEN],*chptr;
  bool       ok;
  int        *cont_type;
  bool       bNewFile,bFirst,bNewOutput;
  
  t_filenm fnm[] = {
    { efENX, "-f", NULL,    ffRDMULT },
    { efENX, "-o", "fixed", ffWRITE  },
  };

#define NFILE asize(fnm)  
  bool   bWrite;
  static real  delta_t=0.0, toffset=0,scalefac=1;
  static bool  bSetTime=FALSE;
  static bool  bSort=TRUE,bError=TRUE;
  static real  begin=-1;
  static real  end=-1;
  
  t_pargs pa[] = {
    { "-b",        FALSE, etREAL, {&begin},
      "First time to use"},
    { "-e",        FALSE, etREAL, {&end},
      "Last time to use"},
    { "-dt",       FALSE, etREAL, {&delta_t},
      "Only write out frame when t MOD dt = offset" },
    { "-offset",   FALSE, etREAL, {&toffset},
      "Time offset for -dt option" }, 
    { "-settime",  FALSE, etBOOL, {&bSetTime}, 
      "Change starting time interactively" },
    { "-sort",     FALSE, etBOOL, {&bSort},
      "Sort energy files (not frames)"},
    { "-scalefac", FALSE, etREAL, {&scalefac},
      "Multiply energy component by this factor" },
    { "-error",    FALSE, etBOOL, {&bError},
      "Stop on errors in the file" }
  };
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_BE_NICE ,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,asize(bugs),bugs);
  tadjust  = 0;
  nremax   = 0;
  nset     = 0;
  timestep = 0.0;
  snew(fnms,argc);
  nfile=0;
  laststep=startstep=0;
  
  nfile = opt2fns(&fnms,"-f",NFILE,fnm);
  
  if (!nfile)
    gmx_fatal(FARGS,"No input files!");
  
  snew(settime,nfile+1);
  snew(readtime,nfile+1);
  snew(cont_type,nfile+1);
  
  nre=scan_ene_files(fnms,nfile,readtime,&timestep,&nremax);   
  edit_files(fnms,nfile,readtime,settime,cont_type,bSetTime,bSort);     

  snew(fr,1);
  snew(fro,1);
  fro->t = -1;
  fro->nre = nre;
  snew(fro->ener,nremax);

  if(nfile>1)
    snew(lastee,nremax);
  else
    lastee=NULL;

  snew(startee,nremax);
    
  noutfr=0;
  bFirst=TRUE;

  for(i=0;i<nfile;i++) {
    bNewFile=TRUE;
    bNewOutput=TRUE;
    in=open_enx(fnms[i],"r");
    do_enxnms(in,&this_nre,&enm);
    if(i==0) {
      if (scalefac != 1)
	set = select_it(nre,enm,&nset);
      
      /* write names to the output file */
      out=open_enx(opt2fn("-o",NFILE,fnm),"w");  
      do_enxnms(out,&nre,&enm);
    }
    
    /* start reading from the next file */
    while((t<(settime[i+1]-GMX_REAL_EPS)) &&
	  do_enx(in,fr)) {
      if(bNewFile) {
	startstep_file = fr->step;
	tadjust = settime[i] - fr->t;	  
	if(cont_type[i+1]==TIME_LAST) {
	  settime[i+1]   = readtime[i+1]-readtime[i]+settime[i];
	  cont_type[i+1] = TIME_EXPLICIT;
	}
	bNewFile = FALSE;
      }
      fro->step = laststep + fr->step - startstep_file;
      t = tadjust + fr->t;

      /*bWrite = ((begin<0 || (begin>=0 && (t >= begin-GMX_REAL_EPS))) && 
		(end  <0 || (end  >=0 && (t <= end  +GMX_REAL_EPS))) &&
		(t < settime[i+1]-GMX_REAL_EPS));*/
      bWrite = ((begin<0 || (begin>=0 && (t >= begin-GMX_REAL_EPS))) && 
		(end  <0 || (end  >=0 && (t <= end  +GMX_REAL_EPS))) &&
		(t < settime[i+1]-0.5*timestep));
      
      if (bError)      
	if ((end > 0) && (t > end+GMX_REAL_EPS)) {
	  i = nfile;
	  break;
	}
      
      if (t >= begin-GMX_REAL_EPS) {
	if (bFirst) {
	  bFirst = FALSE;
	  startstep = fr->step;	
	  if (begin > 0)
	    copy_ee(fr->ener,startee,nre);
	}
	update_ee(lastee,laststep,startee,startstep,
		  fr->ener,fro->step,fro->ener,nre);
      }	  
      
      /* determine if we should write it */
      if (bWrite && (delta_t==0 || bRmod(t,toffset,delta_t))) {
	fro->t = t;
	if(bNewOutput) {
	  bNewOutput=FALSE;
	  fprintf(stderr,"\nContinue writing frames from t=%g, step=%d\n",
		  t,fro->step);
	}
	if (scalefac != 1) {
	  for(kkk=0; kkk<nset; kkk++) {
	    fro->ener[set[kkk]].e    *= scalefac;
	    fro->ener[set[kkk]].eav  *= scalefac;
	    fro->ener[set[kkk]].esum *= scalefac;
	  }
	}
	/* Copy restraint stuff */
	fro->ndisre       = fr->ndisre;
	fro->disre_rm3tav = fr->disre_rm3tav;
	fro->disre_rt     = fr->disre_rt;
	fro->nblock       = fr->nblock;
	fro->nr           = fr->nr;
	fro->block        = fr->block;
	
	do_enx(out,fro);
	if (noutfr % 1000 == 0)
	  fprintf(stderr,"Writing frame time %g    ",fro->t);
	noutfr++;
      }
    }
    /* copy statistics to old */
    if (lastee != NULL) {
	update_last_ee(lastee,laststep,fr->ener,fro->step,nre);
	laststep = fro->step;
	/* remove the last frame from statistics since gromacs2.0 
	 * repeats it in the next file 
	 */
	remove_last_eeframe(lastee,laststep,fr->ener,nre);
	/* the old part now has (laststep) values, and the new (step+1) */
	printf("laststep=%d step=%d\n",laststep,fro->step);
    }
    
    /* set the next time from the last in previous file */
    if (cont_type[i+1]==TIME_CONTINUE) {
	settime[i+1] = fro->t;
	/* in this case we have already written the last frame of
	 * previous file, so update begin to avoid doubling it
	 * with the start of the next file
	 */
	begin = fro->t+0.5*timestep;
	/* cont_type[i+1]==TIME_EXPLICIT; */
    }
    
    if ((fro->t < end) && (i < nfile-1) &&
	(fro->t < settime[i+1]-1.5*timestep)) 
      fprintf(stderr,
	      "\nWARNING: There might be a gap around t=%g\n",t);
    
    /* move energies to lastee */
    close_enx(in);
    for(kkk=0; kkk<this_nre; kkk++)
      sfree(enm[kkk]);
    sfree(enm);
    enm = NULL;

    fprintf(stderr,"\n");
  }
  if (noutfr == 0)
    fprintf(stderr,"No frames written.\n");
  else {
    fprintf(stderr,"Last frame written was at step %d, time %f\n",
	    fro->step,fro->t);
    fprintf(stderr,"Wrote %d frames\n",noutfr);
  }

  thanx(stderr);
  return 0;
}
Beispiel #22
0
int cmain(int argc, char *argv[])
{
    const char   *desc[] = {
        "The [TT]mdrun[tt] program is the main computational chemistry engine",
        "within GROMACS. Obviously, it performs Molecular Dynamics simulations,",
        "but it can also perform Stochastic Dynamics, Energy Minimization,",
        "test particle insertion or (re)calculation of energies.",
        "Normal mode analysis is another option. In this case [TT]mdrun[tt]",
        "builds a Hessian matrix from single conformation.",
        "For usual Normal Modes-like calculations, make sure that",
        "the structure provided is properly energy-minimized.",
        "The generated matrix can be diagonalized by [TT]g_nmeig[tt].[PAR]",
        "The [TT]mdrun[tt] program reads the run input file ([TT]-s[tt])",
        "and distributes the topology over nodes if needed.",
        "[TT]mdrun[tt] produces at least four output files.",
        "A single log file ([TT]-g[tt]) is written, unless the option",
        "[TT]-seppot[tt] is used, in which case each node writes a log file.",
        "The trajectory file ([TT]-o[tt]), contains coordinates, velocities and",
        "optionally forces.",
        "The structure file ([TT]-c[tt]) contains the coordinates and",
        "velocities of the last step.",
        "The energy file ([TT]-e[tt]) contains energies, the temperature,",
        "pressure, etc, a lot of these things are also printed in the log file.",
        "Optionally coordinates can be written to a compressed trajectory file",
        "([TT]-x[tt]).[PAR]",
        "The option [TT]-dhdl[tt] is only used when free energy calculation is",
        "turned on.[PAR]",
        "A simulation can be run in parallel using two different parallelization",
        "schemes: MPI parallelization and/or OpenMP thread parallelization.",
        "The MPI parallelization uses multiple processes when [TT]mdrun[tt] is",
        "compiled with a normal MPI library or threads when [TT]mdrun[tt] is",
        "compiled with the GROMACS built-in thread-MPI library. OpenMP threads",
        "are supported when mdrun is compiled with OpenMP. Full OpenMP support",
        "is only available with the Verlet cut-off scheme, with the (older)",
        "group scheme only PME-only processes can use OpenMP parallelization.",
        "In all cases [TT]mdrun[tt] will by default try to use all the available",
        "hardware resources. With a normal MPI library only the options",
        "[TT]-ntomp[tt] (with the Verlet cut-off scheme) and [TT]-ntomp_pme[tt],",
        "for PME-only processes, can be used to control the number of threads.",
        "With thread-MPI there are additional options [TT]-nt[tt], which sets",
        "the total number of threads, and [TT]-ntmpi[tt], which sets the number",
        "of thread-MPI threads.",
        "Note that using combined MPI+OpenMP parallelization is almost always",
        "slower than single parallelization, except at the scaling limit, where",
        "especially OpenMP parallelization of PME reduces the communication cost.",
        "OpenMP-only parallelization is much faster than MPI-only parallelization",
        "on a single CPU(-die). Since we currently don't have proper hardware",
        "topology detection, [TT]mdrun[tt] compiled with thread-MPI will only",
        "automatically use OpenMP-only parallelization when you use up to 4",
        "threads, up to 12 threads with Intel Nehalem/Westmere, or up to 16",
        "threads with Intel Sandy Bridge or newer CPUs. Otherwise MPI-only",
        "parallelization is used (except with GPUs, see below).",
        "[PAR]",
        "To quickly test the performance of the new Verlet cut-off scheme",
        "with old [TT].tpr[tt] files, either on CPUs or CPUs+GPUs, you can use",
        "the [TT]-testverlet[tt] option. This should not be used for production,",
        "since it can slightly modify potentials and it will remove charge groups",
        "making analysis difficult, as the [TT].tpr[tt] file will still contain",
        "charge groups. For production simulations it is highly recommended",
        "to specify [TT]cutoff-scheme = Verlet[tt] in the [TT].mdp[tt] file.",
        "[PAR]",
        "With GPUs (only supported with the Verlet cut-off scheme), the number",
        "of GPUs should match the number of MPI processes or MPI threads,",
        "excluding PME-only processes/threads. With thread-MPI, unless set on the command line, the number",
        "of MPI threads will automatically be set to the number of GPUs detected.",
        "To use a subset of the available GPUs, or to manually provide a mapping of",
        "GPUs to PP ranks, you can use the [TT]-gpu_id[tt] option. The argument of [TT]-gpu_id[tt] is",
        "a string of digits (without delimiter) representing device id-s of the GPUs to be used.",
        "For example, \"[TT]02[tt]\" specifies using GPUs 0 and 2 in the first and second PP ranks per compute node",
        "respectively. To select different sets of GPU-s",
        "on different nodes of a compute cluster, use the [TT]GMX_GPU_ID[tt] environment",
        "variable instead. The format for [TT]GMX_GPU_ID[tt] is identical to ",
        "[TT]-gpu_id[tt], with the difference that an environment variable can have",
        "different values on different compute nodes. Multiple MPI ranks on each node",
        "can share GPUs. This is accomplished by specifying the id(s) of the GPU(s)",
        "multiple times, e.g. \"[TT]0011[tt]\" for four ranks sharing two GPUs in this node.",
        "This works within a single simulation, or a multi-simulation, with any form of MPI.",
        "[PAR]",
        "When using PME with separate PME nodes or with a GPU, the two major",
        "compute tasks, the non-bonded force calculation and the PME calculation",
        "run on different compute resources. If this load is not balanced,",
        "some of the resources will be idle part of time. With the Verlet",
        "cut-off scheme this load is automatically balanced when the PME load",
        "is too high (but not when it is too low). This is done by scaling",
        "the Coulomb cut-off and PME grid spacing by the same amount. In the first",
        "few hundred steps different settings are tried and the fastest is chosen",
        "for the rest of the simulation. This does not affect the accuracy of",
        "the results, but it does affect the decomposition of the Coulomb energy",
        "into particle and mesh contributions. The auto-tuning can be turned off",
        "with the option [TT]-notunepme[tt].",
        "[PAR]",
        "[TT]mdrun[tt] pins (sets affinity of) threads to specific cores,",
        "when all (logical) cores on a compute node are used by [TT]mdrun[tt],",
        "even when no multi-threading is used,",
        "as this usually results in significantly better performance.",
        "If the queuing systems or the OpenMP library pinned threads, we honor",
        "this and don't pin again, even though the layout may be sub-optimal.",
        "If you want to have [TT]mdrun[tt] override an already set thread affinity",
        "or pin threads when using less cores, use [TT]-pin on[tt].",
        "With SMT (simultaneous multithreading), e.g. Intel Hyper-Threading,",
        "there are multiple logical cores per physical core.",
        "The option [TT]-pinstride[tt] sets the stride in logical cores for",
        "pinning consecutive threads. Without SMT, 1 is usually the best choice.",
        "With Intel Hyper-Threading 2 is best when using half or less of the",
        "logical cores, 1 otherwise. The default value of 0 do exactly that:",
        "it minimizes the threads per logical core, to optimize performance.",
        "If you want to run multiple mdrun jobs on the same physical node,"
        "you should set [TT]-pinstride[tt] to 1 when using all logical cores.",
        "When running multiple mdrun (or other) simulations on the same physical",
        "node, some simulations need to start pinning from a non-zero core",
        "to avoid overloading cores; with [TT]-pinoffset[tt] you can specify",
        "the offset in logical cores for pinning.",
        "[PAR]",
        "When [TT]mdrun[tt] is started using MPI with more than 1 process",
        "or with thread-MPI with more than 1 thread, MPI parallelization is used.",
        "By default domain decomposition is used, unless the [TT]-pd[tt]",
        "option is set, which selects particle decomposition.",
        "[PAR]",
        "With domain decomposition, the spatial decomposition can be set",
        "with option [TT]-dd[tt]. By default [TT]mdrun[tt] selects a good decomposition.",
        "The user only needs to change this when the system is very inhomogeneous.",
        "Dynamic load balancing is set with the option [TT]-dlb[tt],",
        "which can give a significant performance improvement,",
        "especially for inhomogeneous systems. The only disadvantage of",
        "dynamic load balancing is that runs are no longer binary reproducible,",
        "but in most cases this is not important.",
        "By default the dynamic load balancing is automatically turned on",
        "when the measured performance loss due to load imbalance is 5% or more.",
        "At low parallelization these are the only important options",
        "for domain decomposition.",
        "At high parallelization the options in the next two sections",
        "could be important for increasing the performace.",
        "[PAR]",
        "When PME is used with domain decomposition, separate nodes can",
        "be assigned to do only the PME mesh calculation;",
        "this is computationally more efficient starting at about 12 nodes.",
        "The number of PME nodes is set with option [TT]-npme[tt],",
        "this can not be more than half of the nodes.",
        "By default [TT]mdrun[tt] makes a guess for the number of PME",
        "nodes when the number of nodes is larger than 11 or performance wise",
        "not compatible with the PME grid x dimension.",
        "But the user should optimize npme. Performance statistics on this issue",
        "are written at the end of the log file.",
        "For good load balancing at high parallelization, the PME grid x and y",
        "dimensions should be divisible by the number of PME nodes",
        "(the simulation will run correctly also when this is not the case).",
        "[PAR]",
        "This section lists all options that affect the domain decomposition.",
        "[PAR]",
        "Option [TT]-rdd[tt] can be used to set the required maximum distance",
        "for inter charge-group bonded interactions.",
        "Communication for two-body bonded interactions below the non-bonded",
        "cut-off distance always comes for free with the non-bonded communication.",
        "Atoms beyond the non-bonded cut-off are only communicated when they have",
        "missing bonded interactions; this means that the extra cost is minor",
        "and nearly indepedent of the value of [TT]-rdd[tt].",
        "With dynamic load balancing option [TT]-rdd[tt] also sets",
        "the lower limit for the domain decomposition cell sizes.",
        "By default [TT]-rdd[tt] is determined by [TT]mdrun[tt] based on",
        "the initial coordinates. The chosen value will be a balance",
        "between interaction range and communication cost.",
        "[PAR]",
        "When inter charge-group bonded interactions are beyond",
        "the bonded cut-off distance, [TT]mdrun[tt] terminates with an error message.",
        "For pair interactions and tabulated bonds",
        "that do not generate exclusions, this check can be turned off",
        "with the option [TT]-noddcheck[tt].",
        "[PAR]",
        "When constraints are present, option [TT]-rcon[tt] influences",
        "the cell size limit as well.",
        "Atoms connected by NC constraints, where NC is the LINCS order plus 1,",
        "should not be beyond the smallest cell size. A error message is",
        "generated when this happens and the user should change the decomposition",
        "or decrease the LINCS order and increase the number of LINCS iterations.",
        "By default [TT]mdrun[tt] estimates the minimum cell size required for P-LINCS",
        "in a conservative fashion. For high parallelization it can be useful",
        "to set the distance required for P-LINCS with the option [TT]-rcon[tt].",
        "[PAR]",
        "The [TT]-dds[tt] option sets the minimum allowed x, y and/or z scaling",
        "of the cells with dynamic load balancing. [TT]mdrun[tt] will ensure that",
        "the cells can scale down by at least this factor. This option is used",
        "for the automated spatial decomposition (when not using [TT]-dd[tt])",
        "as well as for determining the number of grid pulses, which in turn",
        "sets the minimum allowed cell size. Under certain circumstances",
        "the value of [TT]-dds[tt] might need to be adjusted to account for",
        "high or low spatial inhomogeneity of the system.",
        "[PAR]",
        "The option [TT]-gcom[tt] can be used to only do global communication",
        "every n steps.",
        "This can improve performance for highly parallel simulations",
        "where this global communication step becomes the bottleneck.",
        "For a global thermostat and/or barostat the temperature",
        "and/or pressure will also only be updated every [TT]-gcom[tt] steps.",
        "By default it is set to the minimum of nstcalcenergy and nstlist.[PAR]",
        "With [TT]-rerun[tt] an input trajectory can be given for which ",
        "forces and energies will be (re)calculated. Neighbor searching will be",
        "performed for every frame, unless [TT]nstlist[tt] is zero",
        "(see the [TT].mdp[tt] file).[PAR]",
        "ED (essential dynamics) sampling and/or additional flooding potentials",
        "are switched on by using the [TT]-ei[tt] flag followed by an [TT].edi[tt]",
        "file. The [TT].edi[tt] file can be produced with the [TT]make_edi[tt] tool",
        "or by using options in the essdyn menu of the WHAT IF program.",
        "[TT]mdrun[tt] produces a [TT].xvg[tt] output file that",
        "contains projections of positions, velocities and forces onto selected",
        "eigenvectors.[PAR]",
        "When user-defined potential functions have been selected in the",
        "[TT].mdp[tt] file the [TT]-table[tt] option is used to pass [TT]mdrun[tt]",
        "a formatted table with potential functions. The file is read from",
        "either the current directory or from the [TT]GMXLIB[tt] directory.",
        "A number of pre-formatted tables are presented in the [TT]GMXLIB[tt] dir,",
        "for 6-8, 6-9, 6-10, 6-11, 6-12 Lennard-Jones potentials with",
        "normal Coulomb.",
        "When pair interactions are present, a separate table for pair interaction",
        "functions is read using the [TT]-tablep[tt] option.[PAR]",
        "When tabulated bonded functions are present in the topology,",
        "interaction functions are read using the [TT]-tableb[tt] option.",
        "For each different tabulated interaction type the table file name is",
        "modified in a different way: before the file extension an underscore is",
        "appended, then a 'b' for bonds, an 'a' for angles or a 'd' for dihedrals",
        "and finally the table number of the interaction type.[PAR]",
        "The options [TT]-px[tt] and [TT]-pf[tt] are used for writing pull COM",
        "coordinates and forces when pulling is selected",
        "in the [TT].mdp[tt] file.[PAR]",
        "With [TT]-multi[tt] or [TT]-multidir[tt], multiple systems can be ",
        "simulated in parallel.",
        "As many input files/directories are required as the number of systems. ",
        "The [TT]-multidir[tt] option takes a list of directories (one for each ",
        "system) and runs in each of them, using the input/output file names, ",
        "such as specified by e.g. the [TT]-s[tt] option, relative to these ",
        "directories.",
        "With [TT]-multi[tt], the system number is appended to the run input ",
        "and each output filename, for instance [TT]topol.tpr[tt] becomes",
        "[TT]topol0.tpr[tt], [TT]topol1.tpr[tt] etc.",
        "The number of nodes per system is the total number of nodes",
        "divided by the number of systems.",
        "One use of this option is for NMR refinement: when distance",
        "or orientation restraints are present these can be ensemble averaged",
        "over all the systems.[PAR]",
        "With [TT]-replex[tt] replica exchange is attempted every given number",
        "of steps. The number of replicas is set with the [TT]-multi[tt] or ",
        "[TT]-multidir[tt] option, described above.",
        "All run input files should use a different coupling temperature,",
        "the order of the files is not important. The random seed is set with",
        "[TT]-reseed[tt]. The velocities are scaled and neighbor searching",
        "is performed after every exchange.[PAR]",
        "Finally some experimental algorithms can be tested when the",
        "appropriate options have been given. Currently under",
        "investigation are: polarizability and X-ray bombardments.",
        "[PAR]",
        "The option [TT]-membed[tt] does what used to be g_membed, i.e. embed",
        "a protein into a membrane. The data file should contain the options",
        "that where passed to g_membed before. The [TT]-mn[tt] and [TT]-mp[tt]",
        "both apply to this as well.",
        "[PAR]",
        "The option [TT]-pforce[tt] is useful when you suspect a simulation",
        "crashes due to too large forces. With this option coordinates and",
        "forces of atoms with a force larger than a certain value will",
        "be printed to stderr.",
        "[PAR]",
        "Checkpoints containing the complete state of the system are written",
        "at regular intervals (option [TT]-cpt[tt]) to the file [TT]-cpo[tt],",
        "unless option [TT]-cpt[tt] is set to -1.",
        "The previous checkpoint is backed up to [TT]state_prev.cpt[tt] to",
        "make sure that a recent state of the system is always available,",
        "even when the simulation is terminated while writing a checkpoint.",
        "With [TT]-cpnum[tt] all checkpoint files are kept and appended",
        "with the step number.",
        "A simulation can be continued by reading the full state from file",
        "with option [TT]-cpi[tt]. This option is intelligent in the way that",
        "if no checkpoint file is found, Gromacs just assumes a normal run and",
        "starts from the first step of the [TT].tpr[tt] file. By default the output",
        "will be appending to the existing output files. The checkpoint file",
        "contains checksums of all output files, such that you will never",
        "loose data when some output files are modified, corrupt or removed.",
        "There are three scenarios with [TT]-cpi[tt]:[PAR]",
        "[TT]*[tt] no files with matching names are present: new output files are written[PAR]",
        "[TT]*[tt] all files are present with names and checksums matching those stored",
        "in the checkpoint file: files are appended[PAR]",
        "[TT]*[tt] otherwise no files are modified and a fatal error is generated[PAR]",
        "With [TT]-noappend[tt] new output files are opened and the simulation",
        "part number is added to all output file names.",
        "Note that in all cases the checkpoint file itself is not renamed",
        "and will be overwritten, unless its name does not match",
        "the [TT]-cpo[tt] option.",
        "[PAR]",
        "With checkpointing the output is appended to previously written",
        "output files, unless [TT]-noappend[tt] is used or none of the previous",
        "output files are present (except for the checkpoint file).",
        "The integrity of the files to be appended is verified using checksums",
        "which are stored in the checkpoint file. This ensures that output can",
        "not be mixed up or corrupted due to file appending. When only some",
        "of the previous output files are present, a fatal error is generated",
        "and no old output files are modified and no new output files are opened.",
        "The result with appending will be the same as from a single run.",
        "The contents will be binary identical, unless you use a different number",
        "of nodes or dynamic load balancing or the FFT library uses optimizations",
        "through timing.",
        "[PAR]",
        "With option [TT]-maxh[tt] a simulation is terminated and a checkpoint",
        "file is written at the first neighbor search step where the run time",
        "exceeds [TT]-maxh[tt]*0.99 hours.",
        "[PAR]",
        "When [TT]mdrun[tt] receives a TERM signal, it will set nsteps to the current",
        "step plus one. When [TT]mdrun[tt] receives an INT signal (e.g. when ctrl+C is",
        "pressed), it will stop after the next neighbor search step ",
        "(with nstlist=0 at the next step).",
        "In both cases all the usual output will be written to file.",
        "When running with MPI, a signal to one of the [TT]mdrun[tt] processes",
        "is sufficient, this signal should not be sent to mpirun or",
        "the [TT]mdrun[tt] process that is the parent of the others.",
        "[PAR]",
        "When [TT]mdrun[tt] is started with MPI, it does not run niced by default."
    };
    t_commrec    *cr;
    t_filenm      fnm[] = {
        { efTPX, NULL,      NULL,       ffREAD },
        { efTRN, "-o",      NULL,       ffWRITE },
        { efXTC, "-x",      NULL,       ffOPTWR },
        { efCPT, "-cpi",    NULL,       ffOPTRD },
        { efCPT, "-cpo",    NULL,       ffOPTWR },
        { efSTO, "-c",      "confout",  ffWRITE },
        { efEDR, "-e",      "ener",     ffWRITE },
        { efLOG, "-g",      "md",       ffWRITE },
        { efXVG, "-dhdl",   "dhdl",     ffOPTWR },
        { efXVG, "-field",  "field",    ffOPTWR },
        { efXVG, "-table",  "table",    ffOPTRD },
        { efXVG, "-tabletf", "tabletf",    ffOPTRD },
        { efXVG, "-tablep", "tablep",   ffOPTRD },
        { efXVG, "-tableb", "table",    ffOPTRD },
        { efTRX, "-rerun",  "rerun",    ffOPTRD },
        { efXVG, "-tpi",    "tpi",      ffOPTWR },
        { efXVG, "-tpid",   "tpidist",  ffOPTWR },
        { efEDI, "-ei",     "sam",      ffOPTRD },
        { efXVG, "-eo",     "edsam",    ffOPTWR },
        { efGCT, "-j",      "wham",     ffOPTRD },
        { efGCT, "-jo",     "bam",      ffOPTWR },
        { efXVG, "-ffout",  "gct",      ffOPTWR },
        { efXVG, "-devout", "deviatie", ffOPTWR },
        { efXVG, "-runav",  "runaver",  ffOPTWR },
        { efXVG, "-px",     "pullx",    ffOPTWR },
        { efXVG, "-pf",     "pullf",    ffOPTWR },
        { efXVG, "-ro",     "rotation", ffOPTWR },
        { efLOG, "-ra",     "rotangles", ffOPTWR },
        { efLOG, "-rs",     "rotslabs", ffOPTWR },
        { efLOG, "-rt",     "rottorque", ffOPTWR },
        { efMTX, "-mtx",    "nm",       ffOPTWR },
        { efNDX, "-dn",     "dipole",   ffOPTWR },
        { efRND, "-multidir", NULL,      ffOPTRDMULT},
        { efDAT, "-plumed", "plumed",   ffOPTRD },   /* PLUMED */
        { efDAT, "-membed", "membed",   ffOPTRD },
        { efTOP, "-mp",     "membed",   ffOPTRD },
        { efNDX, "-mn",     "membed",   ffOPTRD }
    };
#define NFILE asize(fnm)

    /* Command line options ! */
    gmx_bool      bCart         = FALSE;
    gmx_bool      bPPPME        = FALSE;
    gmx_bool      bPartDec      = FALSE;
    gmx_bool      bDDBondCheck  = TRUE;
    gmx_bool      bDDBondComm   = TRUE;
    gmx_bool      bTunePME      = TRUE;
    gmx_bool      bTestVerlet   = FALSE;
    gmx_bool      bVerbose      = FALSE;
    gmx_bool      bCompact      = TRUE;
    gmx_bool      bSepPot       = FALSE;
    gmx_bool      bRerunVSite   = FALSE;
    gmx_bool      bIonize       = FALSE;
    gmx_bool      bConfout      = TRUE;
    gmx_bool      bReproducible = FALSE;

    int           npme          = -1;
    int           nmultisim     = 0;
    int           nstglobalcomm = -1;
    int           repl_ex_nst   = 0;
    int           repl_ex_seed  = -1;
    int           repl_ex_nex   = 0;
    int           nstepout      = 100;
    int           resetstep     = -1;
    gmx_large_int_t nsteps      = -2; /* the value -2 means that the mdp option will be used */

    rvec          realddxyz          = {0, 0, 0};
    const char   *ddno_opt[ddnoNR+1] =
    { NULL, "interleave", "pp_pme", "cartesian", NULL };
    const char   *dddlb_opt[] =
    { NULL, "auto", "no", "yes", NULL };
    const char   *thread_aff_opt[threadaffNR+1] =
    { NULL, "auto", "on", "off", NULL };
    const char   *nbpu_opt[] =
    { NULL, "auto", "cpu", "gpu", "gpu_cpu", NULL };
    real          rdd                   = 0.0, rconstr = 0.0, dlb_scale = 0.8, pforce = -1;
    char         *ddcsx                 = NULL, *ddcsy = NULL, *ddcsz = NULL;
    real          cpt_period            = 15.0, max_hours = -1;
    gmx_bool      bAppendFiles          = TRUE;
    gmx_bool      bKeepAndNumCPT        = FALSE;
    gmx_bool      bResetCountersHalfWay = FALSE;
    output_env_t  oenv                  = NULL;
    const char   *deviceOptions         = "";

    /* Non transparent initialization of a complex gmx_hw_opt_t struct.
     * But unfortunately we are not allowed to call a function here,
     * since declarations follow below.
     */
    gmx_hw_opt_t  hw_opt = { 0, 0, 0, 0, threadaffSEL, 0, 0,
                             { NULL, FALSE, 0, NULL } };

    t_pargs       pa[] = {

        { "-pd",      FALSE, etBOOL, {&bPartDec},
          "Use particle decompostion" },
        { "-dd",      FALSE, etRVEC, {&realddxyz},
          "Domain decomposition grid, 0 is optimize" },
        { "-ddorder", FALSE, etENUM, {ddno_opt},
          "DD node order" },
        { "-npme",    FALSE, etINT, {&npme},
          "Number of separate nodes to be used for PME, -1 is guess" },
        { "-nt",      FALSE, etINT, {&hw_opt.nthreads_tot},
          "Total number of threads to start (0 is guess)" },
        { "-ntmpi",   FALSE, etINT, {&hw_opt.nthreads_tmpi},
          "Number of thread-MPI threads to start (0 is guess)" },
        { "-ntomp",   FALSE, etINT, {&hw_opt.nthreads_omp},
          "Number of OpenMP threads per MPI process/thread to start (0 is guess)" },
        { "-ntomp_pme", FALSE, etINT, {&hw_opt.nthreads_omp_pme},
          "Number of OpenMP threads per MPI process/thread to start (0 is -ntomp)" },
        { "-pin",     FALSE, etENUM, {thread_aff_opt},
          "Fix threads (or processes) to specific cores" },
        { "-pinoffset", FALSE, etINT, {&hw_opt.core_pinning_offset},
          "The starting logical core number for pinning to cores; used to avoid pinning threads from different mdrun instances to the same core" },
        { "-pinstride", FALSE, etINT, {&hw_opt.core_pinning_stride},
          "Pinning distance in logical cores for threads, use 0 to minimize the number of threads per physical core" },
        { "-gpu_id",  FALSE, etSTR, {&hw_opt.gpu_opt.gpu_id},
          "List of GPU device id-s to use, specifies the per-node PP rank to GPU mapping" },
        { "-ddcheck", FALSE, etBOOL, {&bDDBondCheck},
          "Check for all bonded interactions with DD" },
        { "-ddbondcomm", FALSE, etBOOL, {&bDDBondComm},
          "HIDDENUse special bonded atom communication when [TT]-rdd[tt] > cut-off" },
        { "-rdd",     FALSE, etREAL, {&rdd},
          "The maximum distance for bonded interactions with DD (nm), 0 is determine from initial coordinates" },
        { "-rcon",    FALSE, etREAL, {&rconstr},
          "Maximum distance for P-LINCS (nm), 0 is estimate" },
        { "-dlb",     FALSE, etENUM, {dddlb_opt},
          "Dynamic load balancing (with DD)" },
        { "-dds",     FALSE, etREAL, {&dlb_scale},
          "Minimum allowed dlb scaling of the DD cell size" },
        { "-ddcsx",   FALSE, etSTR, {&ddcsx},
          "HIDDENThe DD cell sizes in x" },
        { "-ddcsy",   FALSE, etSTR, {&ddcsy},
          "HIDDENThe DD cell sizes in y" },
        { "-ddcsz",   FALSE, etSTR, {&ddcsz},
          "HIDDENThe DD cell sizes in z" },
        { "-gcom",    FALSE, etINT, {&nstglobalcomm},
          "Global communication frequency" },
        { "-nb",      FALSE, etENUM, {&nbpu_opt},
          "Calculate non-bonded interactions on" },
        { "-tunepme", FALSE, etBOOL, {&bTunePME},
          "Optimize PME load between PP/PME nodes or GPU/CPU" },
        { "-testverlet", FALSE, etBOOL, {&bTestVerlet},
          "Test the Verlet non-bonded scheme" },
        { "-v",       FALSE, etBOOL, {&bVerbose},
          "Be loud and noisy" },
        { "-compact", FALSE, etBOOL, {&bCompact},
          "Write a compact log file" },
        { "-seppot",  FALSE, etBOOL, {&bSepPot},
          "Write separate V and dVdl terms for each interaction type and node to the log file(s)" },
        { "-pforce",  FALSE, etREAL, {&pforce},
          "Print all forces larger than this (kJ/mol nm)" },
        { "-reprod",  FALSE, etBOOL, {&bReproducible},
          "Try to avoid optimizations that affect binary reproducibility" },
        { "-cpt",     FALSE, etREAL, {&cpt_period},
          "Checkpoint interval (minutes)" },
        { "-cpnum",   FALSE, etBOOL, {&bKeepAndNumCPT},
          "Keep and number checkpoint files" },
        { "-append",  FALSE, etBOOL, {&bAppendFiles},
          "Append to previous output files when continuing from checkpoint instead of adding the simulation part number to all file names" },
        { "-nsteps",  FALSE, etGMX_LARGE_INT, {&nsteps},
          "Run this number of steps, overrides .mdp file option" },
        { "-maxh",   FALSE, etREAL, {&max_hours},
          "Terminate after 0.99 times this time (hours)" },
        { "-multi",   FALSE, etINT, {&nmultisim},
          "Do multiple simulations in parallel" },
        { "-replex",  FALSE, etINT, {&repl_ex_nst},
          "Attempt replica exchange periodically with this period (steps)" },
        { "-nex",  FALSE, etINT, {&repl_ex_nex},
          "Number of random exchanges to carry out each exchange interval (N^3 is one suggestion).  -nex zero or not specified gives neighbor replica exchange." },
        { "-reseed",  FALSE, etINT, {&repl_ex_seed},
          "Seed for replica exchange, -1 is generate a seed" },
        { "-rerunvsite", FALSE, etBOOL, {&bRerunVSite},
          "HIDDENRecalculate virtual site coordinates with [TT]-rerun[tt]" },
        { "-ionize",  FALSE, etBOOL, {&bIonize},
          "Do a simulation including the effect of an X-Ray bombardment on your system" },
        { "-confout", FALSE, etBOOL, {&bConfout},
          "HIDDENWrite the last configuration with [TT]-c[tt] and force checkpointing at the last step" },
        { "-stepout", FALSE, etINT, {&nstepout},
          "HIDDENFrequency of writing the remaining runtime" },
        { "-resetstep", FALSE, etINT, {&resetstep},
          "HIDDENReset cycle counters after these many time steps" },
        { "-resethway", FALSE, etBOOL, {&bResetCountersHalfWay},
          "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt]" }
    };
    gmx_edsam_t   ed;
    unsigned long Flags, PCA_Flags;
    ivec          ddxyz;
    int           dd_node_order;
    gmx_bool      bAddPart;
    FILE         *fplog, *fpmulti;
    int           sim_part, sim_part_fn;
    const char   *part_suffix = ".part";
    char          suffix[STRLEN];
    int           rc;
    char        **multidir = NULL;


    cr = init_par(&argc, &argv);

    if (MASTER(cr))
    {
        CopyRight(stderr, argv[0]);
    }

    PCA_Flags = (PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET));

    /* Comment this in to do fexist calls only on master
     * works not with rerun or tables at the moment
     * also comment out the version of init_forcerec in md.c
     * with NULL instead of opt2fn
     */
    /*
       if (!MASTER(cr))
       {
       PCA_Flags |= PCA_NOT_READ_NODE;
       }
     */

    parse_common_args(&argc, argv, PCA_Flags, NFILE, fnm, asize(pa), pa,
                      asize(desc), desc, 0, NULL, &oenv);


    /* we set these early because they might be used in init_multisystem()
       Note that there is the potential for npme>nnodes until the number of
       threads is set later on, if there's thread parallelization. That shouldn't
       lead to problems. */
    dd_node_order = nenum(ddno_opt);
    cr->npmenodes = npme;

    hw_opt.thread_affinity = nenum(thread_aff_opt);

    /* now check the -multi and -multidir option */
    if (opt2bSet("-multidir", NFILE, fnm))
    {
        int i;
        if (nmultisim > 0)
        {
            gmx_fatal(FARGS, "mdrun -multi and -multidir options are mutually exclusive.");
        }
        nmultisim = opt2fns(&multidir, "-multidir", NFILE, fnm);
    }


    if (repl_ex_nst != 0 && nmultisim < 2)
    {
        gmx_fatal(FARGS, "Need at least two replicas for replica exchange (option -multi)");
    }

    if (repl_ex_nex < 0)
    {
        gmx_fatal(FARGS, "Replica exchange number of exchanges needs to be positive");
    }

    if (nmultisim > 1)
    {
#ifndef GMX_THREAD_MPI
        gmx_bool bParFn = (multidir == NULL);
        init_multisystem(cr, nmultisim, multidir, NFILE, fnm, bParFn);
#else
        gmx_fatal(FARGS, "mdrun -multi is not supported with the thread library.Please compile GROMACS with MPI support");
#endif
    }

    bAddPart = !bAppendFiles;

    /* Check if there is ANY checkpoint file available */
    sim_part    = 1;
    sim_part_fn = sim_part;
    if (opt2bSet("-cpi", NFILE, fnm))
    {
        if (bSepPot && bAppendFiles)
        {
            gmx_fatal(FARGS, "Output file appending is not supported with -seppot");
        }

        bAppendFiles =
            read_checkpoint_simulation_part(opt2fn_master("-cpi", NFILE,
                                                          fnm, cr),
                                            &sim_part_fn, NULL, cr,
                                            bAppendFiles, NFILE, fnm,
                                            part_suffix, &bAddPart);
        if (sim_part_fn == 0 && MULTIMASTER(cr))
        {
            fprintf(stdout, "No previous checkpoint file present, assuming this is a new run.\n");
        }
        else
        {
            sim_part = sim_part_fn + 1;
        }

        if (MULTISIM(cr) && MASTER(cr))
        {
            if (MULTIMASTER(cr))
            {
                /* Log file is not yet available, so if there's a
                 * problem we can only write to stderr. */
                fpmulti = stderr;
            }
            else
            {
                fpmulti = NULL;
            }
            check_multi_int(fpmulti, cr->ms, sim_part, "simulation part", TRUE);
        }
    }
    else
    {
        bAppendFiles = FALSE;
    }

    if (!bAppendFiles)
    {
        sim_part_fn = sim_part;
    }

    if (bAddPart)
    {
        /* Rename all output files (except checkpoint files) */
        /* create new part name first (zero-filled) */
        sprintf(suffix, "%s%04d", part_suffix, sim_part_fn);

        add_suffix_to_output_names(fnm, NFILE, suffix);
        if (MULTIMASTER(cr))
        {
            fprintf(stdout, "Checkpoint file is from part %d, new output files will be suffixed '%s'.\n", sim_part-1, suffix);
        }
    }

    Flags = opt2bSet("-rerun", NFILE, fnm) ? MD_RERUN : 0;
    Flags = Flags | (bSepPot       ? MD_SEPPOT       : 0);
    Flags = Flags | (bIonize       ? MD_IONIZE       : 0);
    Flags = Flags | (bPartDec      ? MD_PARTDEC      : 0);
    Flags = Flags | (bDDBondCheck  ? MD_DDBONDCHECK  : 0);
    Flags = Flags | (bDDBondComm   ? MD_DDBONDCOMM   : 0);
    Flags = Flags | (bTunePME      ? MD_TUNEPME      : 0);
    Flags = Flags | (bTestVerlet   ? MD_TESTVERLET   : 0);
    Flags = Flags | (bConfout      ? MD_CONFOUT      : 0);
    Flags = Flags | (bRerunVSite   ? MD_RERUN_VSITE  : 0);
    Flags = Flags | (bReproducible ? MD_REPRODUCIBLE : 0);
    Flags = Flags | (bAppendFiles  ? MD_APPENDFILES  : 0);
    Flags = Flags | (opt2parg_bSet("-append", asize(pa), pa) ? MD_APPENDFILESSET : 0);
    Flags = Flags | (bKeepAndNumCPT ? MD_KEEPANDNUMCPT : 0);
    Flags = Flags | (sim_part > 1    ? MD_STARTFROMCPT : 0);
    Flags = Flags | (bResetCountersHalfWay ? MD_RESETCOUNTERSHALFWAY : 0);


    /* We postpone opening the log file if we are appending, so we can
       first truncate the old log file and append to the correct position
       there instead.  */
    if ((MASTER(cr) || bSepPot) && !bAppendFiles)
    {
        gmx_log_open(ftp2fn(efLOG, NFILE, fnm), cr,
                     !bSepPot, Flags & MD_APPENDFILES, &fplog);
        CopyRight(fplog, argv[0]);
        please_cite(fplog, "Hess2008b");
        please_cite(fplog, "Spoel2005a");
        please_cite(fplog, "Lindahl2001a");
        please_cite(fplog, "Berendsen95a");
    }
    else if (!MASTER(cr) && bSepPot)
    {
        gmx_log_open(ftp2fn(efLOG, NFILE, fnm), cr, !bSepPot, Flags, &fplog);
    }
    else
    {
        fplog = NULL;
    }

    ddxyz[XX] = (int)(realddxyz[XX] + 0.5);
    ddxyz[YY] = (int)(realddxyz[YY] + 0.5);
    ddxyz[ZZ] = (int)(realddxyz[ZZ] + 0.5);
    /* PLUMED */
    plumedswitch=0;
    if (opt2bSet("-plumed",NFILE,fnm)) plumedswitch=1;
    if(plumedswitch){ plumedcmd=plumed_cmd;
      int plumed_is_there=0;
      int real_precision=sizeof(real);
      real energyUnits=1.0;
      real lengthUnits=1.0;
      real timeUnits=1.0;
  
  
      if(!plumed_installed()){
        gmx_fatal(FARGS,"Plumed is not available. Check your PLUMED_KERNEL variable.");
      }
      plumedmain=plumed_create();
      plumed_cmd(plumedmain,"setRealPrecision",&real_precision);
      // this is not necessary for gromacs units:
      plumed_cmd(plumedmain,"setMDEnergyUnits",&energyUnits);
      plumed_cmd(plumedmain,"setMDLengthUnits",&lengthUnits);
      plumed_cmd(plumedmain,"setMDTimeUnits",&timeUnits);
      //
      plumed_cmd(plumedmain,"setPlumedDat",ftp2fn(efDAT,NFILE,fnm));
      plumedswitch=1;
    }
    /* END PLUMED */

    rc = mdrunner(&hw_opt, fplog, cr, NFILE, fnm, oenv, bVerbose, bCompact,
                  nstglobalcomm, ddxyz, dd_node_order, rdd, rconstr,
                  dddlb_opt[0], dlb_scale, ddcsx, ddcsy, ddcsz,
                  nbpu_opt[0],
                  nsteps, nstepout, resetstep,
                  nmultisim, repl_ex_nst, repl_ex_nex, repl_ex_seed,
                  pforce, cpt_period, max_hours, deviceOptions, Flags);

    /* PLUMED */
    if(plumedswitch){
      plumed_finalize(plumedmain);
    }
    /* END PLUMED */
  
    gmx_finalize_par();

    if (MULTIMASTER(cr))
    {
        thanx(stderr);
    }

    /* Log file has to be closed in mdrunner if we are appending to it
       (fplog not set here) */
    if (MASTER(cr) && !bAppendFiles)
    {
        gmx_log_close(fplog);
    }

    return rc;
}
int gmx_wheel(int argc,char *argv[])
{
  static char *desc[] = {
    "wheel plots a helical wheel representation of your sequence."
    "The input sequence is in the .dat file where the first line contains",
    "the number of residues and each consecutive line contains a residue"
    "name."
  };
  static real rot0=0;
  static bool bNum=TRUE;
  static char *title=NULL;
  static int  r0=1;
  t_pargs pa [] = {
    { "-r0",  FALSE, etINT, {&r0},
      "The first residue number in the sequence" },
    { "-rot0",FALSE, etREAL,{&rot0},
      "Rotate around an angle initially (90 degrees makes sense)" },
    { "-T",   FALSE, etSTR, {&title},
      "Plot a title in the center of the wheel (must be shorter than 10 characters, or it will overwrite the wheel)" },
    { "-nn",  FALSE, etBOOL,{&bNum},
      "Toggle numbers" }
  };
  t_filenm  fnm[] = {
    { efDAT, "-f", NULL,  ffREAD  },
    { efEPS, "-o", NULL,  ffWRITE }
  };
#define NFILE asize(fnm)
  
  int  i,nres;
  char **resnm;
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_BE_NICE,NFILE,fnm,asize(pa),pa,
		    asize(desc),desc,0,NULL);
  
  for(i=1; (i<argc); i++) {
    if (strcmp(argv[i],"-r0") == 0) {
      r0=atoi(argv[++i]);
      fprintf(stderr,"First residue is %d\n",r0);
    }
    else if (strcmp(argv[i],"-rot0") == 0) {
      rot0=atof(argv[++i]);
      fprintf(stderr,"Initial rotation is %g\n",rot0);
    }
    else if (strcmp(argv[i],"-T") == 0) {
      title=strdup(argv[++i]);
      fprintf(stderr,"Title will be '%s'\n",title);
    }
    else if (strcmp(argv[i],"-nn") == 0) {
      bNum=FALSE;
      fprintf(stderr,"No residue numbers\n");
    }
    else
      gmx_fatal(FARGS,"Incorrect usage of option %s",argv[i]);
  }
    
  nres=get_lines(ftp2fn(efDAT,NFILE,fnm),&resnm);
  if (bNum)
    wheel(ftp2fn(efEPS,NFILE,fnm),nres,resnm,r0,rot0,title);
  else
    wheel2(ftp2fn(efEPS,NFILE,fnm),nres,resnm,r0,rot0,title);
    
  thanx(stderr);
  
  return 0;
}
Beispiel #24
0
int main()
{
	gfxInitDefault();
        gfxSet3D(true); // uncomment if using stereoscopic 3D

        gfxFlushBuffers();

        transparent = BLACK;
	 gfxSetScreenFormat(GFX_TOP, GSP_BGR8_OES);
	 gfxSetScreenFormat(GFX_BOTTOM, GSP_BGR8_OES);
        InitParx(BLACK);
/*
	ParxLeft = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); 
	ParxRight = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL); 
	ParxBot = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); 

	ClrParx(ParxLeft, BLACK); 
	ClrParx(ParxRight, BLACK); 
	ClrParx(ParxBot, BLACK);
*/

	char* str[256];
        int l, k, j, i=20, posx = 100, posy = 100;
        TBGR rgbsam;
        TBGR rgb;
	u64 time; 
	u8* tempScr;
	bool Dbuf;	
	
	circlePosition pos;
	touchPosition touch;

	// Main loop
	while (aptMainLoop())
	{
//		gspWaitForVBlank();

//		  	ParxLeft = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); 
//			ParxRight = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL); 
//			ParxBot = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); 

		hidScanInput();              
		u32 kDown = hidKeysHeld();

         
		//Read the CirclePad position
		hidCircleRead(&pos);

		//Print the CirclePad position
//-		printf("\x1b[2;0H%04d; %04d", pos.dx, pos.dy);
		

		//Read the touch screen coordinates
		hidTouchRead(&touch);
		
		//Print the touch screen coordinates
//		printf("\x1b[2;0H%03d; %03d", touch.px, touch.py);
		

		if (kDown & KEY_START)
			break; // break in order to return to hbmenu
                if (kDown & KEY_A)
			{
                          CanvasString(ParxBot, CopyRight(), 10,10, LIGHT_GREEN);
			}
                if (kDown & KEY_B)
			{
                          time= osGetTime();
			
			rgb.r= 0xCC;
			rgb.g= 0x33;
			rgb.b= 0xCC;
			
                        for (k=0;k<400;k++)
                          for (l=0;l<240;l++)
{
  SetPixL(k,l,rgb); //TopLCD
  SetPixR(k,l,rgb);
  if (k<320) SetPixB(k,l,rgb); //BotLCD
}

time = osGetTime() - time; 
sprintf(str, "%i:ms ParxPro SetPix L/R/B,kdl", time);
CanvasString(ParxBot, str, 10,10, GREEN);  

			}
                if (kDown & KEY_X)
			{
                          TestPattern();
			}
                if (kDown & KEY_Y)
			{
			InitParx(BLACK);
		  	
//			  PasBotfill(ParxBot);
			rgb.r= 0xFF;
			rgb.g= 0x00;
			rgb.b= 0x8F;
			  PasClrSrc(ParxBot, rgb);
			  CanvasString(ParxBot, "InitParx", 10,10, GREEN);  
			}
                if(kDown & KEY_CPAD_DOWN)
                        {	     
			rgb.r= 0x00;
			rgb.g= 0x00;
			rgb.b= 0XFF;
			PasTopfill(ParxLeft, rgb);
			PasTopfill(ParxRight, rgb);
			}

                if(kDown & KEY_CPAD_UP) 
                        {	
                        
			rgb.r= 0xFF;
			rgb.g= 0x00;
			rgb.b= 0x00;		
			PasTopfill(ParxLeft, rgb);
			PasTopfill(ParxRight, rgb);
			}
                if(kDown & KEY_CPAD_RIGHT) 
                        {	
                        
			rgb.r= 0x00;
			rgb.g= 0xFF;
			rgb.b= 0x00;
time= osGetTime();
			PasTopfill(ParxLeft, rgb);
			PasTopfill(ParxRight, rgb);

time = osGetTime() - time; 
sprintf(str, "%i:ms L&R BGRTop,kdl", time);
CanvasString(ParxBot, str, 10,10, GREEN);  
			}

                if(kDown & KEY_CPAD_LEFT)
                        {
                        
			rgb.r= 0x00;
			rgb.g= 0x11;
			rgb.b= 0x00;
time= osGetTime();					
						
			HexTopfill(ParxLeft);
			HexTopfill(ParxRight);

time = osGetTime() - time; 
sprintf(str, "%i:ms L&R TopMapLED,kdl", time);
CanvasString(ParxBot, str, 10,10, GREEN);  
			}               
                if(kDown & KEY_R)
                        {	
                              	//InitBufSingle(BLACK);
                                ClrParx(ParxBot, BLACK);
                                //i of linearSpaceFree(); //no effect
                                //i of vramSpaceFree(); //reads as Zero 
                                //i of mappableSpaceFree(); //no change in alloc & free 
                                
                                sprintf(str, "v:%i  m:%i  l:%i", vramSpaceFree, mappableSpaceFree, linearSpaceFree);
				CanvasString(ParxBot, str, 0, 10, RED);
				
                                Topfill2;
                                sprintf(str, "v:%i  m:%i  l:%i", vramSpaceFree, mappableSpaceFree, linearSpaceFree);
				CanvasString(ParxBot, str, 0, 20, RED);
				
                               // Topfill3;
                               // sprintf(str, "Topfill3 Free :%i", vramSpaceFree);
				//CanvasString(ParxBot, str, 0, 40, RED);
				
                                //sprintf(str, "Topfill3 Free :%i", );
				//CanvasString(ParxBot, str, 0, 40, RED);
			}

                if(kDown & KEY_L) 
                        {	
                        	if (Dbuf) InitBufDub(BLACK); else InitBufSingle(BLACK);		
			        Topfill1;
                                ClrParx(ParxBot, BLACK);
                              //  sprintf(str, "Dergibal Rad:%i  X:%i  Y:%i", i, posx, posy);
                              
                        	if (Dbuf) CanvasString(ParxBot, "InitBufDub", 0, 40, RED); else
                        	CanvasString(ParxBot, "InitBufSingle", 0, 40, RED); (BLACK);	
                        	Dbuf = !Dbuf;
			}
                if(kDown & KEY_DUP)
                        {	
                        for (k=0;k<400;k++)
                          for (l=0;l<240;l++)
{
  if (k<320) PSetPixT(ParxRight,k,l, GetPixB(k,l));
} 

			}

                if(kDown & KEY_DDOWN)
                        {	
time= osGetTime();
			
			rgb.r= 0xCC;
			rgb.g= 0x11;
			rgb.b= 0xCC;
			
                        for (k=0;k<400;k++)
                          for (l=0;l<240;l++)
{
  PSetPixT(ParxRight,k,l, rgb); //TopLCD
  PSetPixT(ParxLeft,k,l, rgb);
  if (k<320) PSetPixB(ParxBot,k,l, rgb); //BotLCD
}

time = osGetTime() - time; 
sprintf(str, "%i:ms ParxPro,kdl", time);
CanvasString(ParxBot, str, 10,10, GREEN);  
		
			}                
		if(kDown & KEY_DRIGHT)
                        {

                         ClrParx(ParxBot, BLACK);    
                          
			rgb.r= 0xEE;
			rgb.g= 0x00;
			rgb.b= 0xCC;
		
time= osGetTime();			
                       for (k=0;k<400;k++)
                          for (l=0;l<240;l++) SetPixL(k,l,rgb); //TopLCD
time = osGetTime() - time; 
sprintf(str, "Left %i:ms ParxPro,kdl", time);
CanvasString(ParxBot, str, 10,10, LIGHT_GREEN); 

time= osGetTime();				
//ParxLeft = GetSrcL(-1); // good!!			
//tempScr = GetSrcL(0); // good!!	
//tempScr = GetSrcL(1); // good!!
//                       for (k=0;k<400;k++)
//                        { 
//                            ParxLeft = GetSrcL(-1); // good!!
//                          for (l=0;l<80;l++) PSetPixT(ParxRight,k,l, GetPixL(k,l)); // 
//       			    ParxLeft = GetSrcL(0); // good!!
//                          for (l=80;l<160;l++) PSetPixT(ParxRight,k,l, GetPixL(k,l));   		
//     			    ParxLeft = GetSrcL(1); // good!!
//                          for (l=160;l<240;l++) PSetPixT(ParxRight,k,l, GetPixL(k,l)); 
//                          //assignment to eg PSetPixT(GetSrcR(-1),k,l, GetPixL(k,l)) poops out                      
//                        }  
time = osGetTime() - time; 
sprintf(str, "ParxLeft = GetSrcL(-1&0&1); %i:ms ,kdl", time);
CanvasString(ParxBot, str, 10,20, LIGHT_GREEN); 

time= osGetTime();			
//SetSrcR(0,tempScr);	// No Good 

//SetSrcL(-1,ParxLeft);	// 
//sprintf(str, "SetSrcL(-1,ParxLeft); %i:ms ,kdl", time);
//CanvasString(ParxBot, str, 10,40, LIGHT_GREEN); 

//BufSub(-1);
//BufSub(-2);
//BufSub(-3);

//SetSrcL(-1,ParxLeft);	// 
sprintf(str, "SetSrcL(1,ParxLeft); %i:ms ,kdl", time);
CanvasString(ParxBot, str, 10,50, LIGHT_GREEN); 
//SetSrcR(0,ParxRight);	//
//sprintf(str, "SetSrcR(0,ParxRight) %i:ms ,kdl", time);
//CanvasString(ParxBot, str, 10,60, LIGHT_GREEN); 

                    //   for (k=0;k<400;k++)
                    //      for (l=0;l<240;l++) PSetPixT(GetSrcR(0),k,l,rgb); //GetSrcR(0) works                      
time = osGetTime() - time; 
sprintf(str, "SetSrc L&R(-1,(ParxLeft & ParxRight); %i:ms ,kdl", time);
CanvasString(ParxBot, str, 10,30, LIGHT_GREEN); 
			}

                if(kDown & KEY_DLEFT)
                        {				
                     //   SetTopFramebuffers(0);  
time= osGetTime();
			
                        for (k=0;k<400;k++)
                          for (l=0;l<240;l++)
{
  SetPix(ParxRight,k,l,BLACK);
  SetPix(ParxLeft,k,l,BLACK);
  if (k<320) SetPix(ParxBot,k,l,BLACK);
}

time = osGetTime() - time; 
sprintf(str, "%i:ms Parx-GDI,kdl", time);
CanvasString(ParxBot, str, 10,10, GREEN);  
		}
//gfxString(ParxRight, str, 30,30, 3, rgb); 
//gfxString(ParxLeft, str, 30,30, 3, rgb);   
//for (l=1;l<16;l++) print3d(rgb,10*l,10*l,l-1,3,str);



		//render rainbow
//		renderEffect();
		//copy buffer to lower screen (don't have to do it every frame)
//		memcpy(gfxGetFramebuffer(GFX_BOTTOM, GFX_BOTTOM, NULL, NULL), buffer, size);
		//wait & swap
//		gfxSwapBuffersGpu();
//		gspWaitForEvent(GSPGPU_EVENT_VBlank0, false);

		// Flush and swap framebuffers
	//	gfxFlushBuffers();
	//	gfxSwapBuffers();
        	RefreshBuffer();
		//Wait for VBlank
		gspWaitForVBlank();
	}

	gfxExit();
	return 0;
}
Beispiel #25
0
int gmx_gmx2pqr(int argc, const char * argv[])
{
    const char *desc[] = {
        "\tThis convert from gromacs to APBS pqr files.",
        "Use the -a1 flag for the start of the bond vector",
        "and the -a2 flag for the end of the bond vector."
        "\n"
    };
    t_topology      top;
    t_atoms         *atoms = NULL, useatoms;
    int             ePBC;
    char            title[STRLEN];
    t_trxframe      fr;
    rvec            *xtop;
    matrix          box;
    t_trxstatus     *status;
    int             flags = TRX_READ_X;
    const char      *parm_name, *atp_name;
    output_env_t    oenv;
    const char      *tpr_file, *xtc_file, *index_file, *out_file = NULL;
    char            tpr_title[256], pqr[256];
    rvec            bondvector,midpoint;
    double          bondlength;
    int             a1=-1, a2=-1;   // Initializing these negative as a check
    gmx_bool        nn=FALSE;
    float           pdie=1;
    double          pfield,pcfield,pnfield,psfield;
    gmx_bool        bVerbose=FALSE;     // Remember, 0=False, 1=True
    static char     *a3=NULL;
    
    t_pargs pa[] = {
        { "-nn", TRUE, etBOOL,
            {&nn}, "Use a separate index file for each frame, IE: dynamic index files created through g_select."},
        { "-a1", TRUE, etINT,
            {&a1}, "Atom number 1 (CNC CD, must be set!)"},
        { "-a2", TRUE, etINT,
            {&a2}, "Atom number 2 (CNC NE, must be set!)"},
        { "-a3", TRUE, etSTR,
            {&a3},"String, in quotations, for atoms you want to know the field due to"},
        { "-pdie", TRUE, etREAL,
            {&pdie}, "Protein dielectric"},
        { "-v", FALSE, etBOOL, {&bVerbose},
            "Be slightly more verbose"}
    };
    
    t_filenm fnm[] = {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efDAT, "-d", "/Users/ritchie/Utilities/apbs/AMBER.DAT", ffREAD },
        { efPQR, "-o", NULL, ffWRITE },
        { efXVG, "-of", "field_projection", ffWRITE },
        { efNDX, NULL, NULL, ffREAD }
    };
    
#define NFILE asize(fnm)
#define NPA asize(pa)
    
    CopyRight(stderr,argv[0]);
    
    parse_common_args(&argc, argv,
                      PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW |
                      PCA_TIME_UNIT | PCA_BE_NICE,
                      NFILE, fnm, NPA, pa, asize(desc), desc,
                      0, NULL, &oenv);
    tpr_file = ftp2fn(efTPS, NFILE, fnm);
    xtc_file = opt2fn("-f", NFILE, fnm);
    parm_name = opt2fn("-d", NFILE, fnm);
    atp_name = opt2fn("-a", NFILE, fnm);
    out_file = opt2fn("-o", NFILE,fnm);
    
    read_tps_conf(tpr_file, tpr_title, &top, &ePBC, &xtop, NULL, box, TRUE);
    sfree(xtop);
    atoms = &top.atoms;

    printf("Select group for to save atom coordinates:\n");
    index_file = ftp2fn(efNDX, NFILE, fnm);
//    int             *i_index = (int*)malloc(sizeof(int)*nn);
//    atom_id         **ind_index = (atom_id*)malloc(sizeof(atom_id)*nn);
//    char            **gn_index = (char*)malloc(sizeof(char)*nn);
    int i_index;
    atom_id *ind_index;
    char *gn_index;
    get_index(atoms,index_file,1,&i_index,&ind_index,&gn_index);

    
    /* The first time we read data is a little special */
    read_first_frame(oenv, &status, xtc_file, &fr, flags);
    
    /* check for required parameters */
    if( a1<1 || a2<1 )
        gmx_fatal(FARGS, "Atom numbers a1 and a2 defining the bond vector must be specified\n" );
    a1--;a2--; //internally, numbering starts at 0
    /* check that these atoms exists */
    if(a1<0 || a1>(top.atoms.nr))
    {
        fprintf(stderr,"Error: Atom number %d is out of range.\n",a1);
        exit(1);
    }
    if(a2<0 || a2>(top.atoms.nr))
    {
        fprintf(stderr,"Error: Atom number %d is out of range.\n",a2);
        exit(1);
    }
    
    /* Get all of the atoms indices for finding the field of */
    char *sep = " ,;:/'\"";
    char *word, *brkt;
    int field_due_to_atom[1000], n_field_atoms=0;
    if (a3) {
        for (word = strtok_r(a3, sep, &brkt); word; word = strtok_r(NULL, sep, &brkt))
        {
            int field_atom = atoi(word);
            if (field_atom>(top.atoms.nr))
            {
                fprintf(stderr,"Error: Atom number %d is out of range.\n",field_atom);
                exit(1);
            }
            field_due_to_atom[n_field_atoms] = field_atom - 1;
            n_field_atoms++;
        }
        printf("\nWill include field due to atoms: ");
        for (int i=0;i<n_field_atoms;i++){printf("%i ",field_due_to_atom[i]+1);}
        printf("\n");
    }
    
    fprintf(stderr,"\nWill read reference charges and radii from %s\n",(opt2fn("-d",NFILE,fnm)));
    gmx2amb_dat dat;
    dat = read_DAT(parm_name,atp_name,dat,bVerbose);
    
    /* This is the main loop over frames */
    int framen=0;
    int resid=0;
    double charge=0.0,radius;
    double radii[100000]; // lazy, I should make this dynamic
    char *atomname, *resname;
    char *pqr_file = out_file;
    pqr_file[strlen(pqr_file)-4] = 0;
    FILE *fout = ffopen( opt2fn("-of",NFILE,fnm),"w");
    fprintf(fout,";%13i-%i %18i %18i ",ind_index[0]+1,ind_index[i_index-1]+1,a1+1,a2+1);
    if (a3) {
        for (int i=0;i<n_field_atoms;i++){fprintf(fout,"%18i ",field_due_to_atom[i]+1); }
    }
    fprintf(fout,"%18s","F-excpt");
    do {
        if (nn && framen > 0) {
            get_index(atoms,index_file,1,&i_index,&ind_index,&gn_index);
        }
        
        sprintf(pqr,"%s%i.pqr",pqr_file,framen);
        FILE *pqrout = ffopen(pqr,"w");
        if ( pqrout == NULL ) {
            gmx_fatal(FARGS,"\nFailed to open output file, '%s'\n",pqr);
        }
        
        rvec_sub(fr.x[a2],fr.x[a1],bondvector); // Nitrile ond vector we're looking at
        bondlength = pow(iprod(bondvector,bondvector),.5);
        midpoint[0] = fr.x[a1][XX] + 0.5 * bondvector[0];
        midpoint[1] = fr.x[a1][YY] + 0.5 * bondvector[1];
        midpoint[2] = fr.x[a1][ZZ] + 0.5 * bondvector[2];

//        fprintf(stderr,"\n%1.12f %1.12f %1.12f : %1.12f\n",bondvector[0],bondvector[1],bondvector[2],bondlength);
        
        double x,y,z;
        int npoints = 50;
        for (int n=0; n < npoints+1 ; n++ )
        {
            x = fr.x[a1][XX]*10 + n*bondvector[0]*10/npoints;
            y = fr.x[a1][YY]*10 + n*bondvector[1]*10/npoints;
            z = fr.x[a1][ZZ]*10 + n*bondvector[2]*10/npoints;
            fprintf(pqrout,"ATOM %6i %4s %4s %5i %11.3f %7.3f %7.3f %7.4f %7.3f\n",0,"DUM","CNC",0,x,y,z,0.0,0.0);
        }

        pcfield = calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength) / pdie;
        pnfield = calculate_field(a2,a2,top,fr,midpoint,bondvector,bondlength) / pdie;
        pfield = 0;
//        fprintf(stderr,"\nfields, pdie=%.2f: %.4f %.4f\n",pdie,calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength)/pdie,calculate_field(a1,a1,top,fr,midpoint,bondvector,bondlength));

        // Let's get the radii from the first frame, then use the same radii for every other frame.
        // I don't see a significant performance increase relative to re-matching every frame.
        if ( framen == 0 ) {
            for (int n=0; n < i_index ; n++ ) {
                radii[n] = -1000. ;
                int i = ind_index[n];
                resid = top.atoms.atom[i].resind;
                charge = top.atoms.atom[i].q;
                atomname = *top.atoms.atomname[i];
                resname = *top.atoms.resinfo[resid].name;
                for ( int j=0; j < dat.n ; j++ ) {
                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
                    if (strncmp(*top.atoms.atomtype[i],dat.dat[j].ambername,(strlen(*top.atoms.atomtype[i])+1)) == 0 ) {
                        radii[n] = dat.dat[j].radius;
                        if (bVerbose){fprintf(stderr,"\nMatched %s on %s to %s! (%d/%d)\n",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
                        break;
                    }
                }
                if (radii[n] == -1000.0) {
                    fprintf(stderr,"\nFrame %d : Could not match %s %s %s %i\n",framen,atomname,resname,*top.atoms.atomtype[i],n+1);
                    exit(1);
                }
            }
        }
        for (int n=0 ; n < i_index ; n++ )
        {
            radius = -1000.;
            int i = ind_index[n];
            //
            pfield += calculate_field(i,i,top,fr,midpoint,bondvector,bondlength) / pdie;
            //
            resid = top.atoms.atom[i].resind;
            charge = top.atoms.atom[i].q;
            atomname = *top.atoms.atomname[i];
            resname = *top.atoms.resinfo[resid].name;
/*            for (int j=0;j<dat.n;j++){
//                if (strncmp(resname,dat.dat[j].resname,strlen(resname)+1) == 0 ) {
                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].ambername,j,dat.n);}
//                    if ( bVerbose) {fprintf(stderr,"\nTrying to match: %s %s to %s %s (%d/%d)",resname,*top.atoms.atomtype[i],dat.dat[j].resname,dat.dat[j].ambername,j,dat.n);}

                    if (strncmp(*top.atoms.atomtype[i],dat.dat[j].ambername,(strlen(*top.atoms.atomtype[i])+1)) == 0 ) {
                        radius = dat.dat[j].radius;
//                      fprintf(stderr,"\n%s =? %s -> %s", *top.atoms.atomtype[i], dat.dat[j].gmxname, dat.dat[j].ambername);
                            break;
                    }
//                }
            }
            if (radius == -1000.0) {
                fprintf(stderr,"\nFrame %d : Could not match %s %s %s %i\n",framen,atomname,resname,*top.atoms.atomtype[i],n+1);
                exit(1);
            }
 */
            fprintf(pqrout,"ATOM %6i %4s %4s %5i %11.3f %7.3f %7.3f %7.4f %7.3f\n",i+1,atomname,resname,resid+1,fr.x[i][XX]*10,fr.x[i][YY]*10,fr.x[i][ZZ]*10,charge,radii[n]);
        }
        fclose(pqrout);
        framen++;
        //
        fprintf(fout,"\n %18.6e %18.6e %18.6e ",pfield,pcfield,pnfield);
        double efield = pfield - pcfield - pnfield;
        if (a3) {
            for (int i=0;i<n_field_atoms;i++) {
                double afield = calculate_field(field_due_to_atom[i],field_due_to_atom[i],top,fr,midpoint,bondvector,bondlength)/pdie;
                fprintf(fout,"%18.6e ",afield);
                efield -= afield;
            }
        }
        fprintf(fout,"%18.6e\n",efield);

    } while(read_next_frame(oenv, status, &fr));
    fclose(fout);
    return 0;
}
Beispiel #26
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "All GROMACS programs have 6 standard options,",
    "of which some are hidden by default:"
  };

  static char *bugs[] = {
    "If the configuration script found Motif or Lesstif on your system, "
    "you can use the graphical interface (if not, you will get an error):[BR]"
    "[TT]-X[tt] bool [TT]no[tt] Use dialog box GUI to edit command line options",
    
    "When compiled on an SGI-IRIX system, all GROMACS programs have an "
    "additional option:[BR]"
    "[TT]-npri[tt] int [TT]0[tt] Set non blocking priority (try 128)",

    "Optional files are not used unless the option is set, in contrast to "
    "non optional files, where the default file name is used when the "
    "option is not set.",

    "All GROMACS programs will accept file options without a file extension "
    "or filename being specified. In such cases the default filenames will "
    "be used. With multiple input file types, such as generic structure "
    "format, the directory will be searched for files of each type with the "
    "supplied or default name. When no such file is found, or with output "
    "files the first file type will be used.",

    "All GROMACS programs with the exception of [TT]mdrun[tt], "
    "[TT]nmrun[tt] and [TT]eneconv[tt] check if the command line options "
    "are valid.  If this is not the case, the program will be halted.",

    "Enumerated options (enum) should be used with one of the arguments "
    "listed in the option description, the argument may be abbreviated. "
    "The first match to the shortest argument in the list will be selected.",

    "Vector options can be used with 1 or 3 parameters. When only one "
    "parameter is supplied the two others are also set to this value.",

    "For many GROMACS programs, the time options can be supplied in different "
    "time units, depending on the setting of the [TT]-tu[tt] option.",
    
    "All GROMACS programs can read compressed or g-zipped files. There "
    "might be a problem with reading compressed [TT].xtc[tt], "
    "[TT].trr[tt] and [TT].trj[tt] files, but these will not compress "
    "very well anyway.",

    "Most GROMACS programs can process a trajectory with less atoms than "
    "the run input or structure file, but only if the trajectory consists "
    "of the first n atoms of the run input or structure file.",
    
    "Many GROMACS programs will accept the [TT]-tu[tt] option to set the "
    "time units to use in output files (e.g. for [TT]xmgr[tt] graphs or "
    "[TT]xpm[tt] matrices) and in all time options."
  };

  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,
		    0,NULL,0,NULL,asize(desc),desc,asize(bugs),bugs);
  
  thanx(stderr);
  
  return 0;
}
Beispiel #27
0
int gmx_nmtraj(int argc,char *argv[])
{
    const char *desc[] = 
    {
        "[TT]g_nmtraj[tt] generates an virtual trajectory from an eigenvector, ",
        "corresponding to a harmonic cartesian oscillation around the average ",
        "structure. The eigenvectors should normally be mass-weighted, but you can ",
        "use non-weighted eigenvectors to generate orthogonal motions. ",
        "The output frames are written as a trajectory file covering an entire period, and ",
        "the first frame is the average structure. If you write the trajectory in (or convert to) ",
        "PDB format you can view it directly in PyMol and also render a photorealistic movie. ",
        "Motion amplitudes are calculated from the eigenvalues and a preset temperature, ",
        "assuming equipartition of the energy over all modes. To make the motion clearly visible ",
        "in PyMol you might want to amplify it by setting an unrealistic high temperature. ", 
        "However, be aware that both the linear cartesian displacements and mass weighting will ",
        "lead to serious structure deformation for high amplitudes - this is is simply a limitation ",
        "of the cartesian normal mode model. By default the selected eigenvector is set to 7, since ",
        " the first six normal modes are the translational and rotational degrees of freedom." 
    };

    static real refamplitude=0.25;
    static int  nframes=30;
    static real temp=300.0;
    static const char *eignrvec = "7";
    static const char *phasevec  = "0.0";
    
    t_pargs pa[] =
    {
        { "-eignr",     FALSE, etSTR,  {&eignrvec}, "String of eigenvectors to use (first is 1)" },
        { "-phases",    FALSE, etSTR,  {&phasevec}, "String of phases (default is 0.0)" },
        { "-temp",      FALSE, etREAL, {&temp},      "Temperature in Kelvin" },
        { "-amplitude", FALSE, etREAL, {&refamplitude}, "Amplitude for modes with eigenvalue<=0" },
        { "-nframes",   FALSE, etINT,  {&nframes},   "Number of frames to generate" }
    };
    
#define NPA asize(pa)
  
  int        out;
  t_topology top;
  int        ePBC;
  t_atoms    *atoms;
  rvec       *xtop,*xref,*xav,*xout;
  int        nvec,*eignr=NULL;
  int        *eigvalnr;
  rvec       **eigvec=NULL;
  matrix     box;
  int        natoms;
  int        i,j,k,kmode,d,s,v;
  bool       bDMR,bDMA,bFit;
  char *     indexfile;
  
  char *     grpname;
  real *     eigval;
  int        neigval;
  int *      dummy;
  real *     invsqrtm;
  char       title[STRLEN];
  real       fraction;
  int        *out_eigidx;
  real       *out_eigval;
  rvec *     this_eigvec;
  real       omega,Ekin,sum,m,vel;
  bool       found;
  int        nmodes,nphases;
  int        *imodes;
  real       *amplitude;
  real       *phases;
  real       dum;
  const char       *p;
  char *pe;  
    
  t_filenm fnm[] = 
  { 
      { efTPS, NULL,    NULL,          ffREAD },
      { efTRN, "-v",    "eigenvec",    ffREAD  },
      { efTRO, "-o",    "nmtraj",      ffWRITE }
  }; 
  
#define NFILE asize(fnm) 

  CopyRight(stderr,argv[0]); 
  parse_common_args(&argc,argv,PCA_BE_NICE,
		    NFILE,fnm,NPA,pa,asize(desc),desc,0,NULL); 

  read_eigenvectors(opt2fn("-v",NFILE,fnm),&natoms,&bFit,
		    &xref,&bDMR,&xav,&bDMA,&nvec,&eignr,&eigvec,&eigval);

  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&xtop,NULL,box,bDMA);
	
  /* Find vectors and phases */
  
  /* first find number of args in string */
  nmodes=0;
  p=eignrvec;
  while(*p!=0)
  {
      dum=strtod(p,&pe);
      p=pe;
      nmodes++;
  }

  snew(imodes,nmodes);
  p=eignrvec;
  for(i=0;i<nmodes;i++)
  {
	  /* C indices start on 0 */
      imodes[i]=strtol(p,&pe,10)-1;
      p = pe;
  }
 
  /* Now read phases */
  nphases=0;
  p=phasevec;
  while(*p!=0)
  {
      dum=strtod(p,&pe);
      p=pe;
      nphases++;
  }
  if(nphases>nmodes)
  {
      gmx_fatal(FARGS,"More phases than eigenvector indices specified.\n");
  }
    
  snew(phases,nmodes);
  p=phasevec;

  for(i=0;i<nphases;i++)
  {
      phases[i]=strtod(p,&pe);
      p = pe;
  }

  if(nmodes>nphases)
  {
      printf("Warning: Setting phase of last %d modes to zero...\n",nmodes-nphases);
  }
    
  for(i=nphases;i<nmodes;i++)
  {
      phases[i]=0;
  }
        
  atoms=&top.atoms;

  if(atoms->nr != natoms)
  {
      gmx_fatal(FARGS,"Different number of atoms in topology and eigenvectors.\n");
  }
  
  snew(dummy,natoms);
  for(i=0;i<natoms;i++)
      dummy[i]=i;

  /* Find the eigenvalue/vector to match our select one */ 
  snew(out_eigidx,nmodes);
  for(i=0;i<nmodes;i++)
    out_eigidx[i]=-1;
  
  for(i=0;i<nvec;i++)
  {
      for(j=0;j<nmodes;j++)
      {
          if(imodes[j]==eignr[i])
              out_eigidx[j]=i;
      }
  }
    for(i=0;i<nmodes;i++)
        if(out_eigidx[i]==-1)
            gmx_fatal(FARGS,"Could not find mode %d in eigenvector file.\n",imodes[i]);
    
  
  snew(invsqrtm,natoms);
  
  if (bDMA) 
  {
      for(i=0; (i<natoms); i++)
          invsqrtm[i] = invsqrt(atoms->atom[i].m);
  }
  else 
  {
      for(i=0; (i<natoms); i++)
          invsqrtm[i]=1.0;
  }

  snew(xout,natoms);
  snew(amplitude,nmodes);

  	printf("mode phases: %g %g\n",phases[0],phases[1]);
	
  for(i=0;i<nmodes;i++)
  {
      kmode = out_eigidx[i];
      this_eigvec=eigvec[kmode];
   
      if( (kmode >= 6) && (eigval[kmode] > 0))
      {		  		  
          /* Derive amplitude from temperature and eigenvalue if we can */
          
          /* Convert eigenvalue to angular frequency, in units s^(-1) */
          omega = sqrt(eigval[kmode]*1.0E21/(AVOGADRO*AMU));
          /* Harmonic motion will be x=x0 + A*sin(omega*t)*eigenvec.
           * The velocity is thus:
           * 
           * v = A*omega*cos(omega*t)*eigenvec.
           *
           * And the average kinetic energy the integral of mass*v*v/2 over a
           * period:
           *
           * (1/4)*mass*A*omega*eigenvec
           *
           * For t =2*pi*n, all energy will be kinetic, and v=A*omega*eigenvec.
           * The kinetic energy will be sum(0.5*mass*v*v) if we temporarily set A to 1,
		   * and the average over a period half of this.
           */
          
          Ekin = 0;
          for(k=0;k<natoms;k++)
          {
              m = atoms->atom[k].m;
              for(d=0;d<DIM;d++)
              {
                  vel   = omega*this_eigvec[k][d];
                  Ekin += 0.5*0.5*m*vel*vel;
              }
          }
		  
          /* Convert Ekin from amu*(nm/s)^2 to J, i.e., kg*(m/s)^2
           * This will also be proportional to A^2 
           */   
          Ekin *= AMU*1E-18;
          
          /* Set the amplitude so the energy is kT/2 */
          amplitude[i] = sqrt(0.5*BOLTZMANN*temp/Ekin);		  
	  }
	  else
	  {
		  amplitude[i] = refamplitude;
	  }
  }
	
  out=open_trx(ftp2fn(efTRO,NFILE,fnm),"w");
	
    /* Write a sine oscillation around the average structure, 
     * modulated by the eigenvector with selected amplitude.
     */
    
    for(i=0;i<nframes;i++)
    {
        fraction = (real)i/(real)nframes;
		for(j=0;j<natoms;j++)
		{
			copy_rvec(xav[j],xout[j]);
		}
		
        for(k=0;k<nmodes;k++)
        {
            kmode=out_eigidx[k];
            this_eigvec=eigvec[kmode];

            for(j=0;j<natoms;j++)
            {
                for(d=0;d<DIM;d++)
                {
					xout[j][d] += amplitude[k]*sin(2*M_PI*(fraction+phases[k]/360.0))*this_eigvec[j][d];
                }
            }
        }
        write_trx(out,natoms,dummy,atoms,i,(real)i/(real)nframes,box,xout,NULL,NULL);
    }    
    
    fprintf(stderr,"\n");
    close_trx(out);
    
    return 0;
}
int gmx_mdmat(int argc,char *argv[])
{
  static char *desc[] = {
    "g_mdmat makes distance matrices consisting of the smallest distance",
    "between residue pairs. With -frames these distance matrices can be",
    "stored as a function",
    "of time, to be able to see differences in tertiary structure as a",
    "funcion of time. If you choose your options unwise, this may generate",
    "a large output file. Default only an averaged matrix over the whole",
    "trajectory is output.",
    "Also a count of the number of different atomic contacts between",
    "residues over the whole trajectory can be made.",
    "The output can be processed with xpm2ps to make a PostScript (tm) plot."
  };
  static real truncate=1.5;
  static bool bAtom=FALSE;
  static int  nlevels=40;
  t_pargs pa[] = { 
    { "-t",   FALSE, etREAL, {&truncate},
      "trunc distance" },
    { "-nlevels",   FALSE, etINT,  {&nlevels},
      "Discretize distance in # levels" }
  };
  t_filenm   fnm[] = {
    { efTRX, "-f",  NULL, ffREAD },
    { efTPS, NULL,  NULL, ffREAD },
    { efNDX, NULL,  NULL, ffOPTRD },
    { efXPM, "-mean", "dm", ffWRITE },
    { efXPM, "-frames", "dmf", ffOPTWR },
    { efXVG, "-no", "num",ffOPTWR },
  };
#define NFILE asize(fnm)

  FILE       *out=NULL,*fp;
  t_topology top;
  int        ePBC;
  t_atoms    useatoms;
  int        isize;
  atom_id    *index;
  char       *grpname;
  int        *rndx,*natm,prevres,newres;
  
  int        i,j,status,nres,natoms,nframes,it,trxnat;
  int        nr0;
  bool       bCalcN,bFrames;
  real       t,ratio;
  char       title[256],label[234];
  t_rgb      rlo,rhi;
  rvec       *x;
  real       **mdmat,*resnr,**totmdmat;
  int        **nmat,**totnmat;
  real       *mean_n;
  int        *tot_n;
  matrix     box;
  
  CopyRight(stderr,argv[0]);

  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE,NFILE,fnm,
		    asize(pa),pa,asize(desc),desc,0,NULL);
  
  fprintf(stderr,"Will truncate at %f nm\n",truncate);
  bCalcN = opt2bSet("-no",NFILE,fnm);
  bFrames= opt2bSet("-frames",NFILE,fnm);
  if ( bCalcN ) 
    fprintf(stderr,"Will calculate number of different contacts\n");
    
  read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,FALSE);
  
  fprintf(stderr,"Select group for analysis\n");
  get_index(&top.atoms,ftp2fn_null(efNDX,NFILE,fnm),1,&isize,&index,&grpname);
  
  natoms=isize;
  snew(useatoms.atom,natoms);
  snew(useatoms.atomname,natoms);
    
  useatoms.nres = 0;
  snew(useatoms.resname,natoms);
  
  prevres = top.atoms.atom[index[0]].resnr;
  newres  = 0;
  for(i=0;(i<isize);i++) {
    int ii = index[i];
    useatoms.atomname[i]=top.atoms.atomname[ii];
    if (top.atoms.atom[ii].resnr != prevres) {
      prevres = top.atoms.atom[ii].resnr;
      newres++;
      useatoms.resname[i] = top.atoms.resname[prevres];
      if (debug) {
	fprintf(debug,"New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n",
		*(top.atoms.resname[top.atoms.atom[ii].resnr]),
		*(top.atoms.atomname[ii]),
		ii,i,newres);
      }
    }
    useatoms.atom[i].resnr = newres;
  }
  useatoms.nres = newres+1;
  useatoms.nr = isize;
    
  rndx=res_ndx(&(useatoms));
  natm=res_natm(&(useatoms));
  nres=useatoms.nres;
  fprintf(stderr,"There are %d residues with %d atoms\n",nres,natoms);
    
  snew(resnr,nres);
  snew(mdmat,nres);
  snew(nmat,nres);
  snew(totnmat,nres);
  snew(mean_n,nres);
  snew(tot_n,nres);
  for(i=0; (i<nres); i++) {
    snew(mdmat[i],nres);
    snew(nmat[i],natoms);
    snew(totnmat[i],natoms);
    resnr[i]=i+1;
  }
  snew(totmdmat,nres);
  for(i=0; (i<nres); i++)
    snew(totmdmat[i],nres);
  
  trxnat=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  
  nframes=0;
  
  rlo.r=1.0, rlo.g=1.0, rlo.b=1.0;
  rhi.r=0.0, rhi.g=0.0, rhi.b=0.0;
  if (bFrames)
    out=opt2FILE("-frames",NFILE,fnm,"w");
  do {
    rm_pbc(&top.idef,ePBC,trxnat,box,x,x);
    nframes++;
    calc_mat(nres,natoms,rndx,x,index,truncate,mdmat,nmat,ePBC,box);
    for (i=0; (i<nres); i++)
      for (j=0; (j<natoms); j++)
	if (nmat[i][j]) 
	  totnmat[i][j]++;
    for (i=0; (i<nres); i++)
      for (j=0; (j<nres); j++)
	totmdmat[i][j] += mdmat[i][j];
    if (bFrames) {
      sprintf(label,"t=%.0f ps",t);
      write_xpm(out,0,label,"Distance (nm)","Residue Index","Residue Index",
		nres,nres,resnr,resnr,mdmat,0,truncate,rlo,rhi,&nlevels);
    }
  } while (read_next_x(status,&t,trxnat,x,box));
  fprintf(stderr,"\n");
  close_trj(status);
  if (bFrames)
    fclose(out);
  
  fprintf(stderr,"Processed %d frames\n",nframes);
    
  for (i=0; (i<nres); i++)
    for (j=0; (j<nres); j++)
      totmdmat[i][j] /= nframes;
  write_xpm(opt2FILE("-mean",NFILE,fnm,"w"),0,"Mean smallest distance",
	    "Distance (nm)","Residue Index","Residue Index",
	    nres,nres,resnr,resnr,totmdmat,0,truncate,rlo,rhi,&nlevels);
  
  if ( bCalcN ) {
    tot_nmat(nres,natoms,nframes,totnmat,tot_n,mean_n);
    fp=xvgropen(ftp2fn(efXVG,NFILE,fnm),
		"Increase in number of contacts","Residue","Ratio");
    fprintf(fp,"@ legend on\n");
    fprintf(fp,"@ legend box on\n");
    fprintf(fp,"@ legend loctype view\n");
    fprintf(fp,"@ legend 0.75, 0.8\n");
    fprintf(fp,"@ legend string 0 \"Total/mean\"\n");
    fprintf(fp,"@ legend string 1 \"Total\"\n");
    fprintf(fp,"@ legend string 2 \"Mean\"\n");
    fprintf(fp,"@ legend string 3 \"# atoms\"\n");
    fprintf(fp,"@ legend string 4 \"Mean/# atoms\"\n");
    fprintf(fp,"#%3s %8s  %3s  %8s  %3s  %8s\n",
	    "res","ratio","tot","mean","natm","mean/atm");
    for (i=0; (i<nres); i++) {
      if (mean_n[i]==0)
	ratio=1;
      else
	ratio=tot_n[i]/mean_n[i];
      fprintf(fp,"%3d  %8.3f  %3d  %8.3f  %3d  %8.3f\n",
	      i+1,ratio,tot_n[i],mean_n[i],natm[i],mean_n[i]/natm[i]);
    }
    fclose(fp);
  }
    
  thanx(stderr);
    
  return 0;
}
Beispiel #29
0
int main(int argc, char *argv[]) 
{
  const char *desc[] = { "Do statistics on pair distance", 
    "from an existing molecular dynamics trajectory." };
  gmx_bool bGREC = FALSE;
  gmx_bool bTraj = FALSE;
  int i, j;
  rvec           *x = NULL, *x_ref = NULL;
  matrix          box;
  char            buf[256];
  t_topology      top;
  output_env_t    oenv;
  int             ePBC;
  t_trxstatus    *status;
  int             natoms_trx;
  real            t;
  
  t_filenm        fnm[] =
  {
    { efTPS, NULL, NULL, ffREAD },
    { efLOG, "-n", NULL, ffREAD },
    { efTRX, "-f", NULL, ffOPTRD },
    { efLOG, "-o", NULL, ffWRITE },
  };
  t_pargs         pa[] = 
  {
    { "-grec", FALSE, etBOOL, {&bGREC}, 
      "Using GREC"}
  };
  #define NFILE asize(fnm)
  #define NPA asize(pa)
  
  CopyRight(stderr, argv[0]);
  parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW  
                    | PCA_BE_NICE, NFILE, fnm, NPA, pa, asize(desc),          
                    desc, 0, NULL, &oenv);
  
  read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &x_ref,      
                       NULL, box, TRUE);
  
  bTraj = opt2bSet("-f", NFILE, fnm);
  
  /* obtain GREC_FA */
  int *GREC_ind;
  if (bGREC)
  {
    FILE *fgrec;
    fgrec = fopen("GREC", "r");
    int grec_size;

    fscanf(fgrec, "%d", &grec_size);
    snew(GREC_ind, grec_size);

    for(i=0; i<grec_size; i++)
      fscanf(fgrec, "%d", GREC_ind + i);

    fclose(fgrec);
  }
#define myIndex(i) (bGREC ? GREC_ind[i] : i)
  
  /* read index file */
  FILE *findex;
  findex = fopen(opt2fn("-n", NFILE, fnm), "r");
  int ind1, ind2;
  hashTable *h = Hash_init(113);

  while (fscanf(findex, "%d", &ind1) != EOF)
  {
    fscanf(findex, "%d", &ind2);
    Hash_insertKey(h, "dd", ind1, ind2);
  }
  fclose(findex);

  int size;
  void ***vectorKeyList;
  
  Hash_getSize(h, &size);
  snew(vectorKeyList, size);
  
  Hash_dump(h, NULL, NULL, NULL, NULL, vectorKeyList);

  printf("size=%d\n", size);
  
  /* set reference value from the topology file */
  double diff;
  for(i=0; i< size; i++)
  {
    ind1 = *(int *)(vectorKeyList[i][0]);
    ind2 = *(int *)(vectorKeyList[i][1]);
  
    /* indicating coordinate data is missing in the topology file */
    if(fabs(x_ref[myIndex(ind1)][0]) < 5e-6 && 
       fabs(x_ref[myIndex(ind1)][1]) < 5e-6 &&
       fabs(x_ref[myIndex(ind1)][2]) < 5e-6 )
          continue;
    if(fabs(x_ref[myIndex(ind2)][0]) < 5e-6 && 
       fabs(x_ref[myIndex(ind2)][1]) < 5e-6 &&
       fabs(x_ref[myIndex(ind2)][2]) < 5e-6 )
          continue;

    diff = 0;
    diff += (x_ref[myIndex(ind1)][0] - x_ref[myIndex(ind2)][0]) * 
            (x_ref[myIndex(ind1)][0] - x_ref[myIndex(ind2)][0]);
    diff += (x_ref[myIndex(ind1)][1] - x_ref[myIndex(ind2)][1]) * 
            (x_ref[myIndex(ind1)][1] - x_ref[myIndex(ind2)][1]);
    diff += (x_ref[myIndex(ind1)][2] - x_ref[myIndex(ind2)][2]) * 
            (x_ref[myIndex(ind1)][2] - x_ref[myIndex(ind2)][2]);
    diff = sqrt(diff);

    Hash_setReferenceValue(h, diff, "dd", ind1, ind2);
  }

  if(bTraj)
  {
    /* read first frame */
    natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, 
                            &x, box);
    if (natoms_trx != top.atoms.nr)
      fprintf(stderr, 
              "\nWARNING: topology has %d atoms, whereas trajectory has %d\n",
              top.atoms.nr, natoms_trx);
  
    /* start looping over frames: */
    do
    {
      for(i=0; i< size; i++)
      {
        ind1 = *(int *)(vectorKeyList[i][0]);
        ind2 = *(int *)(vectorKeyList[i][1]);
    
        diff = 0;
        diff += (x[myIndex(ind1)][0] - x[myIndex(ind2)][0]) * 
                (x[myIndex(ind1)][0] - x[myIndex(ind2)][0]);
        diff += (x[myIndex(ind1)][1] - x[myIndex(ind2)][1]) * 
                (x[myIndex(ind1)][1] - x[myIndex(ind2)][1]);
        diff += (x[myIndex(ind1)][2] - x[myIndex(ind2)][2]) * 
                (x[myIndex(ind1)][2] - x[myIndex(ind2)][2]);
        diff = sqrt(diff);

        Hash_addData(h, diff, "dd", ind1, ind2);
      }
    }
    while (read_next_x(oenv, status, &t, natoms_trx, x, box));

    close_trj(status);
  }

  /* output the statistics */
  FILE *fopt;
  fopt = fopen(opt2fn("-o", NFILE, fnm), "w");
  double **a;
  snew(a, size);
  for(i=0; i<size; i++)
    snew(a[i], 3);
  
  Hash_dump(h, a, NULL, NULL, NULL, NULL);
  
  for(i=0; i<size; i++)
  {
    ind1 = *(int *)(vectorKeyList[i][0]);
    ind2 = *(int *)(vectorKeyList[i][1]);
    /* using standard deviation */

    fprintf(fopt, "%4d    %4d    %13.6f    %13.6f    %13.6f\n", 
        ind1, ind2, a[i][0], sqrt(a[i][1]), a[i][2]);
  }

  fclose(fopt);

  Hash_del(h);

  sfree(x_ref);
  sfree(x);

  sfree(GREC_ind);
  sfree(vectorKeyList);

  for(i=0; i<size; i++)
    sfree(a[i]);
  sfree(a);
}
Beispiel #30
0
int main(int argc, char *argv[])
{
  t_symtab tab;
  static char *desc[] = {
    "[TT]hexamer[tt] takes a single input coordinate file and makes five symmetry",
    "related copies."
  };
#define NPA asize(pa)
  t_filenm fnm[] = {
    { efSTX, "-f", NULL, ffREAD },
    { efPDB, "-o", NULL, ffWRITE }
  };
#define NFILE asize(fnm)
  gmx_bool bCenter    = FALSE;
  gmx_bool bTrimer    = FALSE;
  gmx_bool bAlternate = FALSE;
  real rDist = 0,rAngleZ = 0,rAngleX = 0, alterz = 0;
  t_pargs pa[] = {
    { "-center",   FALSE, etBOOL,  {&bCenter}, 
      "Center molecule on Z-axis first" },
    { "-trimer",   FALSE, etBOOL,  {&bTrimer},
      "Make trimer rather than hexamer" },
    { "-alternate",FALSE, etBOOL,  {&bAlternate},
      "Turn every other molecule upside down" },
    { "-alterz",   FALSE, etREAL,  {&alterz},
      "Add this amount to Z-coordinate in every other molecule" },
    { "-radius",   FALSE, etREAL,  {&rDist},
      "Distance of protein axis from Z-axis (implies [TT]-center[tt])" },
    { "-anglez",   FALSE, etREAL,  {&rAngleZ},
      "Initial angle of rotation around Z-axis of protein" },
    { "-anglex",   FALSE, etREAL,  {&rAngleX},
      "Initial angle of rotation around X-axis of protein" }
  };
#define NPA asize(pa)
  FILE    *fp;
  int     i,iout,now,natom;
  rvec    *xin,*vin,*xout;
  matrix  box;
  t_atoms atoms,aout;
  char    *infile,*outfile,title[256],buf[32];
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,NPA,pa,
		    asize(desc),desc,0,NULL);
  bCenter = bCenter || (rDist > 0) || bAlternate;
  
  infile  = ftp2fn(efSTX,NFILE,fnm);
  outfile = ftp2fn(efPDB,NFILE,fnm);
  
  get_stx_coordnum(infile,&natom);
  init_t_atoms(&atoms,natom,TRUE);
  snew(xin,natom);
  snew(xout,natom);
  snew(vin,natom);
  read_stx_conf(infile,title,&atoms,xin,vin,box);
  printf("Read %d atoms\n",atoms.nr); 
  
  if (bCenter) 
    prep_x(atoms.nr,xin,rDist,rAngleZ,rAngleX);
  
  fp = ffopen(outfile,"w");
  for(i=0; (i<(bTrimer ? 3 : 6)); i++) {
    rotate_x(atoms.nr,xin,i*(bTrimer ? 120.0 : 60.0),xout,TRUE,
	     bAlternate && ((i % 2) != 0),alterz*(((i % 2) == 0) ? 0 : 1));
    sprintf(buf,"Rotated %d degrees",i*(bTrimer ? 120 : 60));
    write_pdbfile(fp,buf,&atoms,xout,box,'A'+i,1+i);
  }
  ffclose(fp);
  
  thanx(stderr);
  
  return 0;
}