コード例 #1
0
int gmx_mk_angndx(int argc, char *argv[])
{
    static const char *desc[] = {
        "[THISMODULE] makes an index file for calculation of",
        "angle distributions etc. It uses a run input file ([REF].tpx[ref]) 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[] = {
        { efTPR, NULL, NULL, ffREAD  },
        { efNDX, NULL, "angle", ffWRITE }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                           asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    GMX_RELEASE_ASSERT(opt[0] != 0, "Options inconsistency; opt[0] is NULL");

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

    top = read_top(ftp2fn(efTPR, 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");
        }
    }
    gmx_ffclose(out);

    return 0;
}
コード例 #2
0
ファイル: g_x2top.c プロジェクト: exianshine/gromacs
int gmx_x2top(int argc, char *argv[])
{
    const char        *desc[] = {
        "[THISMODULE] generates a primitive topology from a coordinate file.",
        "The program assumes all hydrogens are present when defining",
        "the hybridization from the atom name and the number of bonds.",
        "The program can also make an [TT].rtp[tt] entry, which you can then add",
        "to the [TT].rtp[tt] database.[PAR]",
        "When [TT]-param[tt] is set, equilibrium distances and angles",
        "and force constants will be printed in the topology for all",
        "interactions. The equilibrium distances and angles are taken",
        "from the input coordinates, the force constant are set with",
        "command line options.",
        "The force fields somewhat supported currently are:[PAR]",
        "G53a5  GROMOS96 53a5 Forcefield (official distribution)[PAR]",
        "oplsaa OPLS-AA/L all-atom force field (2001 aminoacid dihedrals)[PAR]",
        "The corresponding data files can be found in the library directory",
        "with name [TT]atomname2type.n2t[tt]. Check Chapter 5 of the manual for more",
        "information about file formats. By default, the force field selection",
        "is interactive, but you can use the [TT]-ff[tt] option to specify",
        "one of the short names above on the command line instead. In that",
        "case [THISMODULE] just looks for the corresponding file.[PAR]",
    };
    const char        *bugs[] = {
        "The atom type selection is primitive. Virtually no chemical knowledge is used",
        "Periodic boundary conditions screw up the bonding",
        "No improper dihedrals are generated",
        "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew."
    };
    FILE              *fp;
    t_params           plist[F_NRE];
    t_excls           *excls;
    t_atoms           *atoms; /* list with all atoms */
    gpp_atomtype_t     atype;
    t_nextnb           nnb;
    t_nm2type         *nm2t;
    t_mols             mymol;
    int                nnm;
    char               title[STRLEN], forcefield[32], ffdir[STRLEN];
    rvec              *x; /* coordinates? */
    int               *nbonds, *cgnr;
    int                bts[] = { 1, 1, 1, 2 };
    matrix             box;    /* box length matrix */
    int                natoms; /* number of atoms in one molecule  */
    int                nres;   /* number of molecules? */
    int                i, j, k, l, m, ndih;
    int                epbc;
    gmx_bool           bRTP, bTOP, bOPLS;
    t_symtab           symtab;
    real               cutoff, qtot, mtot;
    char               n2t[STRLEN];
    output_env_t       oenv;

    t_filenm           fnm[] = {
        { efSTX, "-f", "conf", ffREAD  },
        { efTOP, "-o", "out",  ffOPTWR },
        { efRTP, "-r", "out",  ffOPTWR }
    };
#define NFILE asize(fnm)
    static real        scale = 1.1, kb = 4e5, kt = 400, kp = 5;
    static t_restp     rtp_header_settings;
    static gmx_bool    bRemoveDihedralIfWithImproper = FALSE;
    static gmx_bool    bGenerateHH14Interactions     = TRUE;
    static gmx_bool    bKeepAllGeneratedDihedrals    = FALSE;
    static int         nrexcl                        = 3;
    static gmx_bool    bParam                        = TRUE, bRound = TRUE;
    static gmx_bool    bPairs                        = TRUE, bPBC = TRUE;
    static gmx_bool    bUsePDBcharge                 = FALSE, bVerbose = FALSE;
    static const char *molnm                         = "ICE";
    static const char *ff                            = "oplsaa";
    t_pargs            pa[]                          = {
        { "-ff",     FALSE, etSTR, {&ff},
          "Force field for your simulation. Type \"select\" for interactive selection." },
        { "-v",      FALSE, etBOOL, {&bVerbose},
          "Generate verbose output in the top file." },
        { "-nexcl", FALSE, etINT,  {&nrexcl},
          "Number of exclusions" },
        { "-H14",    FALSE, etBOOL, {&bGenerateHH14Interactions},
          "Use 3rd neighbour interactions for hydrogen atoms" },
        { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals},
          "Generate all proper dihedrals" },
        { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper},
          "Remove dihedrals on the same bond as an improper" },
        { "-pairs",  FALSE, etBOOL, {&bPairs},
          "Output 1-4 interactions (pairs) in topology file" },
        { "-name",   FALSE, etSTR,  {&molnm},
          "Name of your molecule" },
        { "-pbc",    FALSE, etBOOL, {&bPBC},
          "Use periodic boundary conditions." },
        { "-pdbq",  FALSE, etBOOL, {&bUsePDBcharge},
          "Use the B-factor supplied in a [TT].pdb[tt] file for the atomic charges" },
        { "-param", FALSE, etBOOL, {&bParam},
          "Print parameters in the output" },
        { "-round",  FALSE, etBOOL, {&bRound},
          "Round off measured values" },
        { "-kb",    FALSE, etREAL, {&kb},
          "Bonded force constant (kJ/mol/nm^2)" },
        { "-kt",    FALSE, etREAL, {&kt},
          "Angle force constant (kJ/mol/rad^2)" },
        { "-kp",    FALSE, etREAL, {&kp},
          "Dihedral angle force constant (kJ/mol/rad^2)" }
    };

    if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
                           asize(desc), desc, asize(bugs), bugs, &oenv))
    {
        return 0;
    }
    bRTP = opt2bSet("-r", NFILE, fnm);
    bTOP = opt2bSet("-o", NFILE, fnm);
    /* C89 requirements mean that these struct members cannot be used in
     * the declaration of pa. So some temporary variables are needed. */
    rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper;
    rtp_header_settings.bGenerateHH14Interactions     = bGenerateHH14Interactions;
    rtp_header_settings.bKeepAllGeneratedDihedrals    = bKeepAllGeneratedDihedrals;
    rtp_header_settings.nrexcl = nrexcl;

    if (!bRTP && !bTOP)
    {
        gmx_fatal(FARGS, "Specify at least one output file");
    }

    /* Force field selection, interactive or direct */
    choose_ff(strcmp(ff, "select") == 0 ? NULL : ff,
              forcefield, sizeof(forcefield),
              ffdir, sizeof(ffdir));

    bOPLS = (strcmp(forcefield, "oplsaa") == 0);


    mymol.name = strdup(molnm);
    mymol.nr   = 1;

    /* Init parameter lists */
    init_plist(plist);

    /* Read coordinates */
    get_stx_coordnum(opt2fn("-f", NFILE, fnm), &natoms);
    snew(atoms, 1);

    /* make space for all the atoms */
    init_t_atoms(atoms, natoms, TRUE);
    snew(x, natoms);

    read_stx_conf(opt2fn("-f", NFILE, fnm), title, atoms, x, NULL, &epbc, box);

    sprintf(n2t, "%s", ffdir);
    nm2t = rd_nm2type(n2t, &nnm);
    if (nnm == 0)
    {
        gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)",
                  n2t);
    }
    else
    {
        printf("There are %d name to type translations in file %s\n", nnm, n2t);
    }
    if (debug)
    {
        dump_nm2type(debug, nnm, nm2t);
    }
    printf("Generating bonds from distances...\n");
    snew(nbonds, atoms->nr);
    mk_bonds(nnm, nm2t, atoms, x, &(plist[F_BONDS]), nbonds, bPBC, box);

    open_symtab(&symtab);
    atype = set_atom_type(&symtab, atoms, &(plist[F_BONDS]), nbonds, nnm, nm2t);

    /* Make Angles and Dihedrals */
    snew(excls, atoms->nr);
    printf("Generating angles and dihedrals from bonds...\n");
    init_nnb(&nnb, atoms->nr, 4);
    gen_nnb(&nnb, plist);
    print_nnb(&nnb, "NNB");
    gen_pad(&nnb, atoms, &rtp_header_settings, plist, excls, NULL, TRUE);
    done_nnb(&nnb);

    if (!bPairs)
    {
        plist[F_LJ14].nr = 0;
    }
    fprintf(stderr,
            "There are %4d %s dihedrals, %4d impropers, %4d angles\n"
            "          %4d pairs,     %4d bonds and  %4d atoms\n",
            plist[F_PDIHS].nr,
            bOPLS ? "Ryckaert-Bellemans" : "proper",
            plist[F_IDIHS].nr, plist[F_ANGLES].nr,
            plist[F_LJ14].nr, plist[F_BONDS].nr, atoms->nr);

    calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box);

    set_force_const(plist, kb, kt, kp, bRound, bParam);

    cgnr = set_cgnr(atoms, bUsePDBcharge, &qtot, &mtot);
    printf("Total charge is %g, total mass is %g\n", qtot, mtot);
    if (bOPLS)
    {
        bts[2] = 3;
        bts[3] = 1;
    }

    if (bTOP)
    {
        fp = ftp2FILE(efTOP, NFILE, fnm, "w");
        print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0);

        write_top(fp, NULL, mymol.name, atoms, FALSE, bts, plist, excls, atype,
                  cgnr, rtp_header_settings.nrexcl);
        print_top_mols(fp, mymol.name, ffdir, NULL, 0, NULL, 1, &mymol);

        ffclose(fp);
    }
    if (bRTP)
    {
        print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top",
                  atoms, plist, atype, cgnr);
    }

    if (debug)
    {
        dump_hybridization(debug, atoms, nbonds);
    }
    close_symtab(&symtab);
    free(mymol.name);

    printf("\nWARNING: topologies generated by %s can not be trusted at face value.\n",
           ShortProgram());
    printf("         Please verify atomtypes and charges by comparison to other\n");
    printf("         topologies.\n");

    return 0;
}
コード例 #3
0
ファイル: g_anavel.c プロジェクト: cudabigdata/gromacs
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "[TT]g_anavel[tt] computes temperature profiles in a sample. The sample",
    "can be analysed radial, i.e. the temperature as a function of",
    "distance from the center, cylindrical, i.e. as a function of distance",
    "from the vector (0,0,1) through the center of the box, or otherwise",
    "(will be specified later)"
  };
  t_filenm fnm[] = {
    { efTRN,  "-f",  NULL, ffREAD },
    { efTPX,  "-s",  NULL, ffREAD },
    { efXPM,  "-o", "xcm", ffWRITE }
  };
#define NFILE asize(fnm)

  static int  mode = 0,   nlevels = 10;
  static real tmax = 300, xmax    = -1;
  t_pargs pa[] = {
    { "-mode",    FALSE, etINT,  {&mode},    "mode" },
    { "-nlevels", FALSE, etINT,  {&nlevels}, "number of levels" },
    { "-tmax",    FALSE, etREAL, {&tmax},    "max temperature in output" },
    { "-xmax",    FALSE, etREAL, {&xmax},    "max distance from center" }
  };
  
  FILE       *fp;
  int        *npts,nmax;
  int        status;
  int        i,j,idum,step,nframe=0,index;
  real       temp,rdum,hboxx,hboxy,scale,xnorm=0;
  real       **profile=NULL;
  real       *t_x=NULL,*t_y,hi=0;
  t_topology *top;
  int        d,m,n;
  matrix     box;
  atom_id    *sysindex;
  gmx_bool       bHaveV,bReadV;
  t_rgb      rgblo = { 0, 0, 1 },rgbhi = { 1, 0, 0 };
  int        flags = TRX_READ_X | TRX_READ_V;
  t_trxframe fr;

  
  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);

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

  read_first_frame(&status,ftp2fn(efTRX,NFILE,fnm),&fr,flags);
	
  if (xmax > 0) {
    scale  = 5;
    nmax   = xmax*scale;
  }
  else {
    scale  = 5;
    nmax   = (0.5*sqrt(sqr(box[XX][XX])+sqr(box[YY][YY])))*scale; 
  }
  snew(npts,nmax+1);
  snew(t_y,nmax+1);
  for(i=0; (i<=nmax); i++) {
    npts[i] = 0;
    t_y[i]  = i/scale;
  }
  do {
    srenew(profile,++nframe);
    snew(profile[nframe-1],nmax+1);
    srenew(t_x,nframe);
    t_x[nframe-1] = fr.time*1000;
    hboxx = box[XX][XX]/2;
    hboxy = box[YY][YY]/2;
    for(i=0; (i<fr.natoms); i++) {
      /* determine position dependent on mode */
      switch (mode) {
      case 0:
	xnorm = sqrt(sqr(fr.x[i][XX]-hboxx) + sqr(fr.x[i][YY]-hboxy));
	break;
      default:
	gmx_fatal(FARGS,"Unknown mode %d",mode);
      }
      index = xnorm*scale;
      if (index <= nmax) {
	temp = top->atoms.atom[i].m*iprod(fr.v[i],fr.v[i])/(2*BOLTZ);
	if (temp > hi)
	  hi = temp;
	npts[index]++;
	profile[nframe-1][index] += temp;
      }
    }
    for(i=0; (i<=nmax); i++) {
      if (npts[i] != 0) 
	profile[nframe-1][i] /= npts[i];
      npts[i] = 0;
    }
  } while (read_next_frame(status,&fr));
  close_trx(status);

  fp = ftp2FILE(efXPM,NFILE,fnm,"w");
  write_xpm(fp,0,"Temp. profile","T (a.u.)",
	    "t (fs)","R (nm)",
	    nframe,nmax+1,t_x,t_y,profile,0,tmax,
	    rgblo,rgbhi,&nlevels);
  
  gmx_thanx(stderr);
  
  return 0;
}
コード例 #4
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 xpm2ps to make nice plots.",
    "These [IT]raw[it] data may be generated by g_rms, do_dssp 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 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;
  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++;
  }
  fclose(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;
}
コード例 #5
0
ファイル: gmx_rms.c プロジェクト: rbharath/gromacs
int gmx_rms(int argc, char *argv[])
{
    const char     *desc[] =
    {
        "[THISMODULE] compares two structures by computing the root mean square",
        "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter",
        "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ",
        "see Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).",
        "This is selected by [TT]-what[tt].[PAR]"

        "Each structure from a trajectory ([TT]-f[tt]) is compared to a",
        "reference structure. The reference structure",
        "is taken from the structure file ([TT]-s[tt]).[PAR]",

        "With option [TT]-mir[tt] also a comparison with the mirror image of",
        "the reference structure is calculated.",
        "This is useful as a reference for 'significant' values, see",
        "Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).[PAR]",

        "Option [TT]-prev[tt] produces the comparison with a previous frame",
        "the specified number of frames ago.[PAR]",

        "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of",
        "comparison values of each structure in the trajectory with respect to",
        "each other structure. This file can be visualized with for instance",
        "[TT]xv[tt] and can be converted to postscript with [gmx-xpm2ps].[PAR]",

        "Option [TT]-fit[tt] controls the least-squares fitting of",
        "the structures on top of each other: complete fit (rotation and",
        "translation), translation only, or no fitting at all.[PAR]",

        "Option [TT]-mw[tt] controls whether mass weighting is done or not.",
        "If you select the option (default) and ",
        "supply a valid [TT].tpr[tt] file masses will be taken from there, ",
        "otherwise the masses will be deduced from the [TT]atommass.dat[tt] file in",
        "[TT]GMXLIB[tt]. This is fine for proteins, but not",
        "necessarily for other molecules. A default mass of 12.011 amu (carbon)",
        "is assigned to unknown atoms. You can check whether this happend by",
        "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]",

        "With [TT]-f2[tt], the 'other structures' are taken from a second",
        "trajectory, this generates a comparison matrix of one trajectory",
        "versus the other.[PAR]",

        "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]",

        "Option [TT]-bm[tt] produces a matrix of average bond angle deviations",
        "analogously to the [TT]-m[tt] option. Only bonds between atoms in the",
        "comparison group are considered."
    };
    static gmx_bool bPBC              = TRUE, bFitAll = TRUE, bSplit = FALSE;
    static gmx_bool bDeltaLog         = FALSE;
    static int      prev              = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0;
    static real     rmsd_user_max     = -1, rmsd_user_min = -1, bond_user_max = -1,
                    bond_user_min     = -1, delta_maxy = 0.0;
    /* strings and things for selecting difference method */
    enum
    {
        ewSel, ewRMSD, ewRho, ewRhoSc, ewNR
    };
    int         ewhat;
    const char *what[ewNR + 1] =
    { NULL, "rmsd", "rho", "rhosc", NULL };
    const char *whatname[ewNR] =
    { NULL, "RMSD", "Rho", "Rho sc" };
    const char *whatlabel[ewNR] =
    { NULL, "RMSD (nm)", "Rho", "Rho sc" };
    const char *whatxvgname[ewNR] =
    { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    const char *whatxvglabel[ewNR] =
    { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" };
    /* strings and things for fitting methods */
    enum
    {
        efSel, efFit, efReset, efNone, efNR
    };
    int             efit;
    const char     *fit[efNR + 1] =
    { NULL, "rot+trans", "translation", "none", NULL };
    const char     *fitgraphlabel[efNR + 1] =
    { NULL, "lsq fit", "translational fit", "no fit" };
    static int      nrms          = 1;
    static gmx_bool bMassWeighted = TRUE;
    t_pargs         pa[]          =
    {
        { "-what", FALSE, etENUM,
          { what }, "Structural difference measure" },
        { "-pbc", FALSE, etBOOL,
          { &bPBC }, "PBC check" },
        { "-fit", FALSE, etENUM,
          { fit }, "Fit to reference structure" },
        { "-prev", FALSE, etINT,
          { &prev }, "Compare with previous frame" },
        { "-split", FALSE, etBOOL,
          { &bSplit }, "Split graph where time is zero" },
        { "-fitall", FALSE, etBOOL,
          { &bFitAll }, "HIDDENFit all pairs of structures in matrix" },
        { "-skip", FALSE, etINT,
          { &freq }, "Only write every nr-th frame to matrix" },
        { "-skip2", FALSE, etINT,
          { &freq2 }, "Only write every nr-th frame to matrix" },
        { "-max", FALSE, etREAL,
          { &rmsd_user_max }, "Maximum level in comparison matrix" },
        { "-min", FALSE, etREAL,
          { &rmsd_user_min }, "Minimum level in comparison matrix" },
        { "-bmax", FALSE, etREAL,
          { &bond_user_max }, "Maximum level in bond angle matrix" },
        { "-bmin", FALSE, etREAL,
          { &bond_user_min }, "Minimum level in bond angle matrix" },
        { "-mw", FALSE, etBOOL,
          { &bMassWeighted }, "Use mass weighting for superposition" },
        { "-nlevels", FALSE, etINT,
          { &nlevels }, "Number of levels in the matrices" },
        { "-ng", FALSE, etINT,
          { &nrms }, "Number of groups to compute RMS between" },
        { "-dlog", FALSE, etBOOL,
          { &bDeltaLog },
          "HIDDENUse a log x-axis in the delta t matrix" },
        { "-dmax", FALSE, etREAL,
          { &delta_maxy }, "HIDDENMaximum level in delta matrix" },
        { "-aver", FALSE, etINT,
          { &avl },
          "HIDDENAverage over this distance in the RMSD matrix" }
    };
    int             natoms_trx, natoms_trx2, natoms;
    int             i, j, k, m, teller, teller2, tel_mat, tel_mat2;
#define NFRAME 5000
    int             maxframe = NFRAME, maxframe2 = NFRAME;
    real            t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL;
    gmx_bool        bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass;
    gmx_bool        bFit, bReset;
    t_topology      top;
    int             ePBC;
    t_iatom        *iatom = NULL;

    matrix          box;
    rvec           *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1,
                    vec2;
    t_trxstatus    *status;
    char            buf[256], buf2[256];
    int             ncons = 0;
    FILE           *fp;
    real            rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL,
    **rmsd_mat             = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis,
    *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang;
    real       **rmsdav_mat = NULL, av_tot, weight, weight_tot;
    real       **delta      = NULL, delta_max, delta_scalex = 0, delta_scaley = 0,
    *delta_tot;
    int          delta_xsize = 0, del_lev = 100, mx, my, abs_my;
    gmx_bool     bA1, bA2, bPrev, bTop, *bInMat = NULL;
    int          ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m =
        0;
    atom_id     *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m =
        NULL;
    char        *gn_fit, **gn_rms;
    t_rgb        rlo, rhi;
    output_env_t oenv;
    gmx_rmpbc_t  gpbc = NULL;

    t_filenm     fnm[] =
    {
        { efTPS, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efTRX, "-f2", NULL, ffOPTRD },
        { efNDX, NULL, NULL, ffOPTRD },
        { efXVG, NULL, "rmsd", ffWRITE },
        { efXVG, "-mir", "rmsdmir", ffOPTWR },
        { efXVG, "-a", "avgrp", ffOPTWR },
        { efXVG, "-dist", "rmsd-dist", ffOPTWR },
        { efXPM, "-m", "rmsd", ffOPTWR },
        { efDAT, "-bin", "rmsd", ffOPTWR },
        { efXPM, "-bm", "bond", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!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,
                           &oenv))
    {
        return 0;
    }
    /* parse enumerated options: */
    ewhat = nenum(what);
    if (ewhat == ewRho || ewhat == ewRhoSc)
    {
        please_cite(stdout, "Maiorov95");
    }
    efit   = nenum(fit);
    bFit   = efit == efFit;
    bReset = efit == efReset;
    if (bFit)
    {
        bReset = TRUE; /* for fit, reset *must* be set */
    }
    else
    {
        bFitAll = FALSE;
    }

    /* mark active cmdline options */
    bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */
    bFile2  = opt2bSet("-f2", NFILE, fnm);
    bMat    = opt2bSet("-m", NFILE, fnm);
    bBond   = opt2bSet("-bm", NFILE, fnm);
    bDelta  = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from *
                                 *	your RMSD matrix (hidden option       */
    bNorm   = opt2bSet("-a", NFILE, fnm);
    bFreq2  = opt2parg_bSet("-skip2", asize(pa), pa);
    if (freq <= 0)
    {
        fprintf(stderr, "The number of frames to skip is <= 0. "
                "Writing out all frames.\n\n");
        freq = 1;
    }
    if (!bFreq2)
    {
        freq2 = freq;
    }
    else if (bFile2 && freq2 <= 0)
    {
        fprintf(stderr,
                "The number of frames to skip in second trajectory is <= 0.\n"
                "  Writing out all frames.\n\n");
        freq2 = 1;
    }

    bPrev = (prev > 0);
    if (bPrev)
    {
        prev = abs(prev);
        if (freq != 1)
        {
            fprintf(stderr, "WARNING: option -skip also applies to -prev\n");
        }
    }

    if (bFile2 && !bMat && !bBond)
    {
        fprintf(
                stderr,
                "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n"
                "         will not read from %s\n", opt2fn("-f2", NFILE,
                                                           fnm));
        bFile2 = FALSE;
    }

    if (bDelta)
    {
        bMat = TRUE;
        if (bFile2)
        {
            fprintf(stderr,
                    "WARNING: second trajectory (-f2) useless when making delta matrix,\n"
                    "         will not read from %s\n", opt2fn("-f2",
                                                               NFILE, fnm));
            bFile2 = FALSE;
        }
    }

    bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp,
                         NULL, box, TRUE);
    snew(w_rls, top.atoms.nr);
    snew(w_rms, top.atoms.nr);

    if (!bTop && bBond)
    {
        fprintf(stderr,
                "WARNING: Need a run input file for bond angle matrix,\n"
                "         will not calculate bond angle matrix.\n");
        bBond = FALSE;
    }

    if (bReset)
    {
        fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares"
                : "translational");
        get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit,
                  &ind_fit, &gn_fit);
    }
    else
    {
        ifit = 0;
    }

    if (bReset)
    {
        if (bFit && ifit < 3)
        {
            gmx_fatal(FARGS, "Need >= 3 points to fit!\n" );
        }

        bMass = FALSE;
        for (i = 0; i < ifit; i++)
        {
            if (bMassWeighted)
            {
                w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m;
            }
            else
            {
                w_rls[ind_fit[i]] = 1;
            }
            bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in the fit group are 0, using masses of 1\n");
            for (i = 0; i < ifit; i++)
            {
                w_rls[ind_fit[i]] = 1;
            }
        }
    }

    if (bMat || bBond)
    {
        nrms = 1;
    }

    snew(gn_rms, nrms);
    snew(ind_rms, nrms);
    snew(irms, nrms);

    fprintf(stderr, "Select group%s for %s calculation\n",
            (nrms > 1) ? "s" : "", whatname[ewhat]);
    get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm),
              nrms, irms, ind_rms, gn_rms);

    if (bNorm)
    {
        snew(rlsnorm, irms[0]);
    }
    snew(rls, nrms);
    for (j = 0; j < nrms; j++)
    {
        snew(rls[j], maxframe);
    }
    if (bMirror)
    {
        snew(rlsm, nrms);
        for (j = 0; j < nrms; j++)
        {
            snew(rlsm[j], maxframe);
        }
    }
    snew(time, maxframe);
    for (j = 0; j < nrms; j++)
    {
        bMass = FALSE;
        for (i = 0; i < irms[j]; i++)
        {
            if (bMassWeighted)
            {
                w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m;
            }
            else
            {
                w_rms[ind_rms[j][i]] = 1.0;
            }
            bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0);
        }
        if (!bMass)
        {
            fprintf(stderr, "All masses in group %d are 0, using masses of 1\n", j);
            for (i = 0; i < irms[j]; i++)
            {
                w_rms[ind_rms[j][i]] = 1;
            }
        }
    }
    /* Prepare reference frame */
    if (bPBC)
    {
        gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr);
        gmx_rmpbc(gpbc, top.atoms.nr, box, xp);
    }
    if (bReset)
    {
        reset_x(ifit, ind_fit, top.atoms.nr, NULL, xp, w_rls);
    }
    if (bMirror)
    {
        /* generate reference structure mirror image: */
        snew(xm, top.atoms.nr);
        for (i = 0; i < top.atoms.nr; i++)
        {
            copy_rvec(xp[i], xm[i]);
            xm[i][XX] = -xm[i][XX];
        }
    }
    if (ewhat == ewRhoSc)
    {
        norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp);
    }

    /* 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);
    }
    natoms = min(top.atoms.nr, natoms_trx);
    if (bMat || bBond || bPrev)
    {
        snew(mat_x, NFRAME);

        if (bPrev)
        {
            /* With -prev we use all atoms for simplicity */
            n_ind_m = natoms;
        }
        else
        {
            /* Check which atoms we need (fit/rms) */
            snew(bInMat, natoms);
            for (i = 0; i < ifit; i++)
            {
                bInMat[ind_fit[i]] = TRUE;
            }
            n_ind_m = ifit;
            for (i = 0; i < irms[0]; i++)
            {
                if (!bInMat[ind_rms[0][i]])
                {
                    bInMat[ind_rms[0][i]] = TRUE;
                    n_ind_m++;
                }
            }
        }
        /* Make an index of needed atoms */
        snew(ind_m, n_ind_m);
        snew(rev_ind_m, natoms);
        j = 0;
        for (i = 0; i < natoms; i++)
        {
            if (bPrev || bInMat[i])
            {
                ind_m[j]     = i;
                rev_ind_m[i] = j;
                j++;
            }
        }
        snew(w_rls_m, n_ind_m);
        snew(ind_rms_m, irms[0]);
        snew(w_rms_m, n_ind_m);
        for (i = 0; i < ifit; i++)
        {
            w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]];
        }
        for (i = 0; i < irms[0]; i++)
        {
            ind_rms_m[i]          = rev_ind_m[ind_rms[0][i]];
            w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]];
        }
        sfree(bInMat);
    }

    if (bBond)
    {
        ncons = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom  = top.idef.il[k].iatoms;
                ncons += top.idef.il[k].nr/3;
            }
        }
        fprintf(stderr, "Found %d bonds in topology\n", ncons);
        snew(ind_bond1, ncons);
        snew(ind_bond2, ncons);
        ibond = 0;
        for (k = 0; k < F_NRE; k++)
        {
            if (IS_CHEMBOND(k))
            {
                iatom = top.idef.il[k].iatoms;
                ncons = top.idef.il[k].nr/3;
                for (i = 0; i < ncons; i++)
                {
                    bA1 = FALSE;
                    bA2 = FALSE;
                    for (j = 0; j < irms[0]; j++)
                    {
                        if (iatom[3*i+1] == ind_rms[0][j])
                        {
                            bA1 = TRUE;
                        }
                        if (iatom[3*i+2] == ind_rms[0][j])
                        {
                            bA2 = TRUE;
                        }
                    }
                    if (bA1 && bA2)
                    {
                        ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]];
                        ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]];
                        ibond++;
                    }
                }
            }
        }
        fprintf(stderr, "Using %d bonds for bond angle matrix\n", ibond);
        if (ibond == 0)
        {
            gmx_fatal(FARGS, "0 bonds found");
        }
    }

    /* start looping over frames: */
    tel_mat = 0;
    teller  = 0;
    do
    {
        if (bPBC)
        {
            gmx_rmpbc(gpbc, natoms, box, x);
        }

        if (bReset)
        {
            reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
        }
        if (ewhat == ewRhoSc)
        {
            norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
        }

        if (bFit)
        {
            /*do the least squares fit to original structure*/
            do_fit(natoms, w_rls, xp, x);
        }

        if (teller % freq == 0)
        {
            /* keep frame for matrix calculation */
            if (bMat || bBond || bPrev)
            {
                if (tel_mat >= NFRAME)
                {
                    srenew(mat_x, tel_mat+1);
                }
                snew(mat_x[tel_mat], n_ind_m);
                for (i = 0; i < n_ind_m; i++)
                {
                    copy_rvec(x[ind_m[i]], mat_x[tel_mat][i]);
                }
            }
            tel_mat++;
        }

        /*calculate energy of root_least_squares*/
        if (bPrev)
        {
            j = tel_mat-prev-1;
            if (j < 0)
            {
                j = 0;
            }
            for (i = 0; i < n_ind_m; i++)
            {
                copy_rvec(mat_x[j][i], xp[ind_m[i]]);
            }
            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, xp, w_rls);
            }
            if (bFit)
            {
                do_fit(natoms, w_rls, x, xp);
            }
        }
        for (j = 0; (j < nrms); j++)
        {
            rls[j][teller] =
                calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp);
        }
        if (bNorm)
        {
            for (j = 0; (j < irms[0]); j++)
            {
                rlsnorm[j] +=
                    calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp);
            }
        }

        if (bMirror)
        {
            if (bFit)
            {
                /*do the least squares fit to mirror of original structure*/
                do_fit(natoms, w_rls, xm, x);
            }

            for (j = 0; j < nrms; j++)
            {
                rlsm[j][teller] =
                    calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm);
            }
        }
        time[teller] = output_env_conv_time(oenv, t);

        teller++;
        if (teller >= maxframe)
        {
            maxframe += NFRAME;
            srenew(time, maxframe);
            for (j = 0; (j < nrms); j++)
            {
                srenew(rls[j], maxframe);
            }
            if (bMirror)
            {
                for (j = 0; (j < nrms); j++)
                {
                    srenew(rlsm[j], maxframe);
                }
            }
        }
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);

    if (bFile2)
    {
        snew(time2, maxframe2);

        fprintf(stderr, "\nWill read second trajectory file\n");
        snew(mat_x2, NFRAME);
        natoms_trx2 =
            read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box);
        if (natoms_trx2 != natoms_trx)
        {
            gmx_fatal(FARGS,
                      "Second trajectory (%d atoms) does not match the first one"
                      " (%d atoms)", natoms_trx2, natoms_trx);
        }
        tel_mat2 = 0;
        teller2  = 0;
        do
        {
            if (bPBC)
            {
                gmx_rmpbc(gpbc, natoms, box, x);
            }

            if (bReset)
            {
                reset_x(ifit, ind_fit, natoms, NULL, x, w_rls);
            }
            if (ewhat == ewRhoSc)
            {
                norm_princ(&top.atoms, ifit, ind_fit, natoms, x);
            }

            if (bFit)
            {
                /*do the least squares fit to original structure*/
                do_fit(natoms, w_rls, xp, x);
            }

            if (teller2 % freq2 == 0)
            {
                /* keep frame for matrix calculation */
                if (bMat)
                {
                    if (tel_mat2 >= NFRAME)
                    {
                        srenew(mat_x2, tel_mat2+1);
                    }
                    snew(mat_x2[tel_mat2], n_ind_m);
                    for (i = 0; i < n_ind_m; i++)
                    {
                        copy_rvec(x[ind_m[i]], mat_x2[tel_mat2][i]);
                    }
                }
                tel_mat2++;
            }

            time2[teller2] = output_env_conv_time(oenv, t);

            teller2++;
            if (teller2 >= maxframe2)
            {
                maxframe2 += NFRAME;
                srenew(time2, maxframe2);
            }
        }
        while (read_next_x(oenv, status, &t, x, box));
        close_trj(status);
    }
    else
    {
        mat_x2   = mat_x;
        time2    = time;
        tel_mat2 = tel_mat;
        freq2    = freq;
    }
    gmx_rmpbc_done(gpbc);

    if (bMat || bBond)
    {
        /* calculate RMS matrix */
        fprintf(stderr, "\n");
        if (bMat)
        {
            fprintf(stderr, "Building %s matrix, %dx%d elements\n",
                    whatname[ewhat], tel_mat, tel_mat2);
            snew(rmsd_mat, tel_mat);
        }
        if (bBond)
        {
            fprintf(stderr, "Building bond angle matrix, %dx%d elements\n",
                    tel_mat, tel_mat2);
            snew(bond_mat, tel_mat);
        }
        snew(axis, tel_mat);
        snew(axis2, tel_mat2);
        rmsd_max = 0;
        if (bFile2)
        {
            rmsd_min = 1e10;
        }
        else
        {
            rmsd_min = 0;
        }
        rmsd_avg = 0;
        bond_max = 0;
        bond_min = 1e10;
        for (j = 0; j < tel_mat2; j++)
        {
            axis2[j] = time2[freq2*j];
        }
        if (bDelta)
        {
            if (bDeltaLog)
            {
                delta_scalex = 8.0/log(2.0);
                delta_xsize  = (int)(log(tel_mat/2)*delta_scalex+0.5)+1;
            }
            else
            {
                delta_xsize = tel_mat/2;
            }
            delta_scaley = 1.0/delta_maxy;
            snew(delta, delta_xsize);
            for (j = 0; j < delta_xsize; j++)
            {
                snew(delta[j], del_lev+1);
            }
            if (avl > 0)
            {
                snew(rmsdav_mat, tel_mat);
                for (j = 0; j < tel_mat; j++)
                {
                    snew(rmsdav_mat[j], tel_mat);
                }
            }
        }

        if (bFitAll)
        {
            snew(mat_x2_j, natoms);
        }
        for (i = 0; i < tel_mat; i++)
        {
            axis[i] = time[freq*i];
            fprintf(stderr, "\r element %5d; time %5.2f  ", i, axis[i]);
            if (bMat)
            {
                snew(rmsd_mat[i], tel_mat2);
            }
            if (bBond)
            {
                snew(bond_mat[i], tel_mat2);
            }
            for (j = 0; j < tel_mat2; j++)
            {
                if (bFitAll)
                {
                    for (k = 0; k < n_ind_m; k++)
                    {
                        copy_rvec(mat_x2[j][k], mat_x2_j[k]);
                    }
                    do_fit(n_ind_m, w_rls_m, mat_x[i], mat_x2_j);
                }
                else
                {
                    mat_x2_j = mat_x2[j];
                }
                if (bMat)
                {
                    if (bFile2 || (i < j))
                    {
                        rmsd_mat[i][j] =
                            calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m,
                                             w_rms_m, mat_x[i], mat_x2_j);
                        if (rmsd_mat[i][j] > rmsd_max)
                        {
                            rmsd_max = rmsd_mat[i][j];
                        }
                        if (rmsd_mat[i][j] < rmsd_min)
                        {
                            rmsd_min = rmsd_mat[i][j];
                        }
                        rmsd_avg += rmsd_mat[i][j];
                    }
                    else
                    {
                        rmsd_mat[i][j] = rmsd_mat[j][i];
                    }
                }
                if (bBond)
                {
                    if (bFile2 || (i <= j))
                    {
                        ang = 0.0;
                        for (m = 0; m < ibond; m++)
                        {
                            rvec_sub(mat_x[i][ind_bond1[m]], mat_x[i][ind_bond2[m]], vec1);
                            rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2);
                            ang += acos(cos_angle(vec1, vec2));
                        }
                        bond_mat[i][j] = ang*180.0/(M_PI*ibond);
                        if (bond_mat[i][j] > bond_max)
                        {
                            bond_max = bond_mat[i][j];
                        }
                        if (bond_mat[i][j] < bond_min)
                        {
                            bond_min = bond_mat[i][j];
                        }
                    }
                    else
                    {
                        bond_mat[i][j] = bond_mat[j][i];
                    }
                }
            }
        }
        if (bFile2)
        {
            rmsd_avg /= tel_mat*tel_mat2;
        }
        else
        {
            rmsd_avg /= tel_mat*(tel_mat - 1)/2;
        }
        if (bMat && (avl > 0))
        {
            rmsd_max = 0.0;
            rmsd_min = 0.0;
            rmsd_avg = 0.0;
            for (j = 0; j < tel_mat-1; j++)
            {
                for (i = j+1; i < tel_mat; i++)
                {
                    av_tot     = 0;
                    weight_tot = 0;
                    for (my = -avl; my <= avl; my++)
                    {
                        if ((j+my >= 0) && (j+my < tel_mat))
                        {
                            abs_my = abs(my);
                            for (mx = -avl; mx <= avl; mx++)
                            {
                                if ((i+mx >= 0) && (i+mx < tel_mat))
                                {
                                    weight      = (real)(avl+1-max(abs(mx), abs_my));
                                    av_tot     += weight*rmsd_mat[i+mx][j+my];
                                    weight_tot += weight;
                                }
                            }
                        }
                    }
                    rmsdav_mat[i][j] = av_tot/weight_tot;
                    rmsdav_mat[j][i] = rmsdav_mat[i][j];
                    if (rmsdav_mat[i][j] > rmsd_max)
                    {
                        rmsd_max = rmsdav_mat[i][j];
                    }
                }
            }
            rmsd_mat = rmsdav_mat;
        }

        if (bMat)
        {
            fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n",
                    whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg);
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            if (rmsd_user_max != -1)
            {
                rmsd_max = rmsd_user_max;
            }
            if (rmsd_user_min != -1)
            {
                rmsd_min = rmsd_user_min;
            }
            if ((rmsd_user_max !=  -1) || (rmsd_user_min != -1))
            {
                fprintf(stderr, "Min and Max value set to resp. %f and %f\n",
                        rmsd_min, rmsd_max);
            }
            sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]);
            write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat],
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels);
            /* Print the distribution of RMSD values */
            if (opt2bSet("-dist", NFILE, fnm))
            {
                low_rmsd_dist(opt2fn("-dist", NFILE, fnm), rmsd_max, tel_mat, rmsd_mat, oenv);
            }

            if (bDelta)
            {
                snew(delta_tot, delta_xsize);
                for (j = 0; j < tel_mat-1; j++)
                {
                    for (i = j+1; i < tel_mat; i++)
                    {
                        mx = i-j;
                        if (mx < tel_mat/2)
                        {
                            if (bDeltaLog)
                            {
                                mx = (int)(log(mx)*delta_scalex+0.5);
                            }
                            my             = (int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5);
                            delta_tot[mx] += 1.0;
                            if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy))
                            {
                                delta[mx][my] += 1.0;
                            }
                        }
                    }
                }
                delta_max = 0;
                for (i = 0; i < delta_xsize; i++)
                {
                    if (delta_tot[i] > 0.0)
                    {
                        delta_tot[i] = 1.0/delta_tot[i];
                        for (j = 0; j <= del_lev; j++)
                        {
                            delta[i][j] *= delta_tot[i];
                            if (delta[i][j] > delta_max)
                            {
                                delta_max = delta[i][j];
                            }
                        }
                    }
                }
                fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max);
                snew(del_xaxis, delta_xsize);
                snew(del_yaxis, del_lev+1);
                for (i = 0; i < delta_xsize; i++)
                {
                    del_xaxis[i] = axis[i]-axis[0];
                }
                for (i = 0; i < del_lev+1; i++)
                {
                    del_yaxis[i] = delta_maxy*i/del_lev;
                }
                sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]);
                fp = gmx_ffopen("delta.xpm", "w");
                write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat],
                          delta_xsize, del_lev+1, del_xaxis, del_yaxis,
                          delta, 0.0, delta_max, rlo, rhi, &nlevels);
                gmx_ffclose(fp);
            }
            if (opt2bSet("-bin", NFILE, fnm))
            {
                /* NB: File must be binary if we use fwrite */
                fp = ftp2FILE(efDAT, NFILE, fnm, "wb");
                for (i = 0; i < tel_mat; i++)
                {
                    if (fwrite(rmsd_mat[i], sizeof(**rmsd_mat), tel_mat2, fp) != tel_mat2)
                    {
                        gmx_fatal(FARGS, "Error writing to output file");
                    }
                }
                gmx_ffclose(fp);
            }
        }
        if (bBond)
        {
            fprintf(stderr, "\nMin. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            if (bond_user_max != -1)
            {
                bond_max = bond_user_max;
            }
            if (bond_user_min != -1)
            {
                bond_min = bond_user_min;
            }
            if ((bond_user_max !=  -1) || (bond_user_min != -1))
            {
                fprintf(stderr, "Bond angle Min and Max set to:\n"
                        "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max);
            }
            rlo.r = 1; rlo.g = 1; rlo.b = 1;
            rhi.r = 0; rhi.g = 0; rhi.b = 0;
            sprintf(buf, "%s av. bond angle deviation", gn_rms[0]);
            write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees",
                      output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2,
                      axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels);
        }
    }

    bAv = opt2bSet("-a", NFILE, fnm);

    /* Write the RMSD's to file */
    if (!bPrev)
    {
        sprintf(buf, "%s", whatxvgname[ewhat]);
    }
    else
    {
        sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat],
                time[prev*freq]-time[0], output_env_get_time_label(oenv));
    }
    fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                  whatxvglabel[ewhat], oenv);
    if (output_env_get_print_xvgr_codes(oenv))
    {
        fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n",
                (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit],
                bFit     ? " to " : "", bFit ? gn_fit : "");
    }
    if (nrms != 1)
    {
        xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
    }
    for (i = 0; (i < teller); i++)
    {
        if (bSplit && i > 0 &&
            abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5)
        {
            fprintf(fp, "&\n");
        }
        fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, " %12.7f", rls[j][i]);
            if (bAv)
            {
                rlstot += rls[j][i];
            }
        }
        fprintf(fp, "\n");
    }
    gmx_ffclose(fp);

    if (bMirror)
    {
        /* Write the mirror RMSD's to file */
        sprintf(buf, "%s with Mirror", whatxvgname[ewhat]);
        sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv),
                      buf2, oenv);
        if (nrms == 1)
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n",
                        gn_rms[0], gn_fit);
            }
        }
        else
        {
            if (output_env_get_print_xvgr_codes(oenv))
            {
                fprintf(fp, "@ subtitle \"after lsq fit to mirror %s\"\n", gn_fit);
            }
            xvgr_legend(fp, nrms, (const char**)gn_rms, oenv);
        }
        for (i = 0; (i < teller); i++)
        {
            if (bSplit && i > 0 && abs(time[i]) < 1e-5)
            {
                fprintf(fp, "&\n");
            }
            fprintf(fp, "%12.7f", time[i]);
            for (j = 0; (j < nrms); j++)
            {
                fprintf(fp, " %12.7f", rlsm[j][i]);
            }
            fprintf(fp, "\n");
        }
        gmx_ffclose(fp);
    }

    if (bAv)
    {
        sprintf(buf, "Average %s", whatxvgname[ewhat]);
        sprintf(buf2, "Average %s", whatxvglabel[ewhat]);
        fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv);
        for (j = 0; (j < nrms); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlstot/teller);
        }
        gmx_ffclose(fp);
    }

    if (bNorm)
    {
        fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv);
        for (j = 0; (j < irms[0]); j++)
        {
            fprintf(fp, "%10d  %10g\n", j, rlsnorm[j]/teller);
        }
        gmx_ffclose(fp);
    }
    do_view(oenv, opt2fn_null("-a", NFILE, fnm), "-graphtype bar");
    do_view(oenv, opt2fn("-o", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-mir", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-m", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-bm", NFILE, fnm), NULL);
    do_view(oenv, opt2fn_null("-dist", NFILE, fnm), NULL);

    return 0;
}
コード例 #6
0
void sas_plot(int nfile,t_filenm fnm[],real solsize,int ndots,
	      real qcut,gmx_bool bSave,real minarea,gmx_bool bPBC,
	      real dgs_default,gmx_bool bFindex, const output_env_t oenv)
{
  FILE         *fp,*fp2,*fp3=NULL,*vp;
  const char   *flegend[] = { "Hydrophobic", "Hydrophilic", 
			      "Total", "D Gsolv" };
  const char   *vlegend[] = { "Volume (nm\\S3\\N)", "Density (g/l)" };
  const char   *or_and_oa_legend[] = { "Average (nm\\S2\\N)", "Standard deviation (nm\\S2\\N)" };
  const char   *vfile;
  real         t;
  gmx_atomprop_t aps=NULL;
  gmx_rmpbc_t  gpbc=NULL;
  t_trxstatus  *status;
  int          ndefault;
  int          i,j,ii,nfr,natoms,flag,nsurfacedots,res;
  rvec         *xtop,*x;
  matrix       topbox,box;
  t_topology   top;
  char         title[STRLEN];
  int          ePBC;
  gmx_bool         bTop;
  t_atoms      *atoms;
  gmx_bool         *bOut,*bPhobic;
  gmx_bool         bConnelly;
  gmx_bool         bResAt,bITP,bDGsol;
  real         *radius,*dgs_factor=NULL,*area=NULL,*surfacedots=NULL;
  real         at_area,*atom_area=NULL,*atom_area2=NULL;
  real         *res_a=NULL,*res_area=NULL,*res_area2=NULL;
  real         totarea,totvolume,totmass=0,density,harea,tarea,fluc2;
  atom_id      **index,*findex;
  int          *nx,nphobic,npcheck,retval;
  char         **grpname,*fgrpname;
  real         dgsolv;

  bITP   = opt2bSet("-i",nfile,fnm);
  bResAt = opt2bSet("-or",nfile,fnm) || opt2bSet("-oa",nfile,fnm) || bITP;

  bTop = read_tps_conf(ftp2fn(efTPS,nfile,fnm),title,&top,&ePBC,
		       &xtop,NULL,topbox,FALSE);
  atoms = &(top.atoms);
  
  if (!bTop) {
    fprintf(stderr,"No tpr file, will not compute Delta G of solvation\n");
    bDGsol = FALSE;
  } else {
    bDGsol = strcmp(*(atoms->atomtype[0]),"?") != 0;
    if (!bDGsol) {
      fprintf(stderr,"Warning: your tpr file is too old, will not compute "
	      "Delta G of solvation\n");
    } else {
      printf("In case you use free energy of solvation predictions:\n");
      please_cite(stdout,"Eisenberg86a");
    }
  }

  aps = gmx_atomprop_init();
  
  if ((natoms=read_first_x(oenv,&status,ftp2fn(efTRX,nfile,fnm),
			   &t,&x,box))==0)
    gmx_fatal(FARGS,"Could not read coordinates from statusfile\n");

  if ((ePBC != epbcXYZ) || (TRICLINIC(box))) {
    fprintf(stderr,"\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n"
	    "Analysis based on vacuum simulations (with the possibility of evaporation)\n" 
	    "will certainly crash the analysis.\n\n");
  }
  snew(nx,2);
  snew(index,2);
  snew(grpname,2);
  fprintf(stderr,"Select a group for calculation of surface and a group for output:\n");
  get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),2,nx,index,grpname);

  if (bFindex) {
    fprintf(stderr,"Select a group of hydrophobic atoms:\n");
    get_index(atoms,ftp2fn_null(efNDX,nfile,fnm),1,&nphobic,&findex,&fgrpname);
  }
  snew(bOut,natoms);
  for(i=0; i<nx[1]; i++)
    bOut[index[1][i]] = TRUE;

  /* Now compute atomic readii including solvent probe size */
  snew(radius,natoms);
  snew(bPhobic,nx[0]);
  if (bResAt) {
    snew(atom_area,nx[0]);
    snew(atom_area2,nx[0]);
    snew(res_a,atoms->nres);
    snew(res_area,atoms->nres);
    snew(res_area2,atoms->nres);
  }
  if (bDGsol)
    snew(dgs_factor,nx[0]);

  /* Get a Van der Waals radius for each atom */
  ndefault = 0;
  for(i=0; (i<natoms); i++) {
    if (!gmx_atomprop_query(aps,epropVDW,
			    *(atoms->resinfo[atoms->atom[i].resind].name),
			    *(atoms->atomname[i]),&radius[i]))
      ndefault++;
    /* radius[i] = calc_radius(*(top->atoms.atomname[i])); */
    radius[i] += solsize;
  }
  if (ndefault > 0)
    fprintf(stderr,"WARNING: could not find a Van der Waals radius for %d atoms\n",ndefault);
  /* Determine which atom is counted as hydrophobic */
  if (bFindex) {
    npcheck = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      for(j=0; (j<nphobic); j++) {
	if (findex[j] == ii) {
	  bPhobic[i] = TRUE;
	  if (bOut[ii])
	    npcheck++;
	}
      }
    }
    if (npcheck != nphobic)
      gmx_fatal(FARGS,"Consistency check failed: not all %d atoms in the hydrophobic index\n"
		  "found in the normal index selection (%d atoms)",nphobic,npcheck);
  }
  else
    nphobic = 0;
    
  for(i=0; (i<nx[0]); i++) {
    ii = index[0][i];
    if (!bFindex) {
      bPhobic[i] = fabs(atoms->atom[ii].q) <= qcut;
      if (bPhobic[i] && bOut[ii])
	nphobic++;
    }
    if (bDGsol)
      if (!gmx_atomprop_query(aps,epropDGsol,
			      *(atoms->resinfo[atoms->atom[ii].resind].name),
			      *(atoms->atomtype[ii]),&(dgs_factor[i])))
	dgs_factor[i] = dgs_default;
    if (debug)
      fprintf(debug,"Atom %5d %5s-%5s: q= %6.3f, r= %6.3f, dgsol= %6.3f, hydrophobic= %s\n",
	      ii+1,*(atoms->resinfo[atoms->atom[ii].resind].name),
	      *(atoms->atomname[ii]),
	      atoms->atom[ii].q,radius[ii]-solsize,dgs_factor[i],
	      BOOL(bPhobic[i]));
  }
  fprintf(stderr,"%d out of %d atoms were classified as hydrophobic\n",
	  nphobic,nx[1]);
  
  fp=xvgropen(opt2fn("-o",nfile,fnm),"Solvent Accessible Surface","Time (ps)",
	      "Area (nm\\S2\\N)",oenv);
  xvgr_legend(fp,asize(flegend) - (bDGsol ? 0 : 1),flegend,oenv);
  vfile = opt2fn_null("-tv",nfile,fnm);
  if (vfile) {
    if (!bTop) {
      gmx_fatal(FARGS,"Need a tpr file for option -tv");
    }
    vp=xvgropen(vfile,"Volume and Density","Time (ps)","",oenv);
    xvgr_legend(vp,asize(vlegend),vlegend,oenv);
    totmass  = 0;
    ndefault = 0;
    for(i=0; (i<nx[0]); i++) {
      real mm;
      ii = index[0][i];
      /*
      if (!query_atomprop(atomprop,epropMass,
			  *(top->atoms.resname[top->atoms.atom[ii].resnr]),
			  *(top->atoms.atomname[ii]),&mm))
	ndefault++;
      totmass += mm;
      */
      totmass += atoms->atom[ii].m;
    }
    if (ndefault)
      fprintf(stderr,"WARNING: Using %d default masses for density calculation, which most likely are inaccurate\n",ndefault);
  }
  else
    vp = NULL;
    
  gmx_atomprop_destroy(aps);

  if (bPBC)
    gpbc = gmx_rmpbc_init(&top.idef,ePBC,natoms,box);
  
  nfr=0;
  do {
    if (bPBC)
      gmx_rmpbc(gpbc,natoms,box,x);
    
    bConnelly = (nfr==0 && opt2bSet("-q",nfile,fnm));
    if (bConnelly) {
      if (!bTop)
	gmx_fatal(FARGS,"Need a tpr file for Connelly plot");
      flag = FLAG_ATOM_AREA | FLAG_DOTS;
    } else {
      flag = FLAG_ATOM_AREA;
    }
    if (vp) {
      flag = flag | FLAG_VOLUME;
    }
      
    if (debug)
      write_sto_conf("check.pdb","pbc check",atoms,x,NULL,ePBC,box);

    retval = nsc_dclm_pbc(x,radius,nx[0],ndots,flag,&totarea,
			  &area,&totvolume,&surfacedots,&nsurfacedots,
			  index[0],ePBC,bPBC ? box : NULL);
    if (retval)
      gmx_fatal(FARGS,"Something wrong in nsc_dclm_pbc");
    
    if (bConnelly)
      connelly_plot(ftp2fn(efPDB,nfile,fnm),
		    nsurfacedots,surfacedots,x,atoms,
		    &(top.symtab),ePBC,box,bSave);
    harea  = 0; 
    tarea  = 0;
    dgsolv = 0;
    if (bResAt)
      for(i=0; i<atoms->nres; i++)
	res_a[i] = 0;
    for(i=0; (i<nx[0]); i++) {
      ii = index[0][i];
      if (bOut[ii]) {
	at_area = area[i];
	if (bResAt) {
	  atom_area[i] += at_area;
	  atom_area2[i] += sqr(at_area);
	  res_a[atoms->atom[ii].resind] += at_area;
	}
	tarea += at_area;
	if (bDGsol)
	  dgsolv += at_area*dgs_factor[i];
	if (bPhobic[i])
	  harea += at_area;
      }
    }
    if (bResAt)
      for(i=0; i<atoms->nres; i++) {
	res_area[i] += res_a[i];
	res_area2[i] += sqr(res_a[i]);
      }
    fprintf(fp,"%10g  %10g  %10g  %10g",t,harea,tarea-harea,tarea);
    if (bDGsol)
      fprintf(fp,"  %10g\n",dgsolv);
    else
      fprintf(fp,"\n");
    
    /* Print volume */
    if (vp) {
      density = totmass*AMU/(totvolume*NANO*NANO*NANO);
      fprintf(vp,"%12.5e  %12.5e  %12.5e\n",t,totvolume,density);
    }
    if (area) {
      sfree(area);
      area = NULL;
    }
    if (surfacedots) {
      sfree(surfacedots);
      surfacedots = NULL;
    }
    nfr++;
  } while (read_next_x(oenv,status,&t,natoms,x,box));

  if (bPBC)  
    gmx_rmpbc_done(gpbc);

  fprintf(stderr,"\n");
  close_trj(status);
  ffclose(fp);
  if (vp)
    ffclose(vp);
    
  /* if necessary, print areas per atom to file too: */
  if (bResAt) {
    for(i=0; i<atoms->nres; i++) {
      res_area[i] /= nfr;
      res_area2[i] /= nfr;
    }
    for(i=0; i<nx[0]; i++) {
      atom_area[i] /= nfr;
      atom_area2[i] /= nfr;
    }
    fprintf(stderr,"Printing out areas per atom\n");
    fp  = xvgropen(opt2fn("-or",nfile,fnm),"Area per residue over the trajectory","Residue",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    fp2 = xvgropen(opt2fn("-oa",nfile,fnm),"Area per atom over the trajectory","Atom #",
		   "Area (nm\\S2\\N)",oenv);
    xvgr_legend(fp2, asize(or_and_oa_legend),or_and_oa_legend,oenv);
    if (bITP) {
      fp3 = ftp2FILE(efITP,nfile,fnm,"w");
      fprintf(fp3,"[ position_restraints ]\n"
	      "#define FCX 1000\n"
	      "#define FCY 1000\n"
	      "#define FCZ 1000\n"
	      "; Atom  Type  fx   fy   fz\n");
    }
    for(i=0; i<nx[0]; i++) {
      ii = index[0][i];
      res = atoms->atom[ii].resind;
      if (i==nx[0]-1 || res!=atoms->atom[index[0][i+1]].resind) {
	fluc2 = res_area2[res]-sqr(res_area[res]);
	if (fluc2 < 0)
	  fluc2 = 0;
	fprintf(fp,"%10d  %10g %10g\n",
		atoms->resinfo[res].nr,res_area[res],sqrt(fluc2));
      }
      fluc2 = atom_area2[i]-sqr(atom_area[i]);
      if (fluc2 < 0)
	fluc2 = 0;
      fprintf(fp2,"%d %g %g\n",index[0][i]+1,atom_area[i],sqrt(fluc2));
      if (bITP && (atom_area[i] > minarea))
	fprintf(fp3,"%5d   1     FCX  FCX  FCZ\n",ii+1);
    }
    if (bITP)
      ffclose(fp3);
    ffclose(fp);
  }

    /* Be a good citizen, keep our memory free! */
    sfree(x);
    sfree(nx);
    for(i=0;i<2;i++)
    {
        sfree(index[i]);
        sfree(grpname[i]);
    }
    sfree(bOut);
    sfree(radius);
    sfree(bPhobic);
    
    if(bResAt)
    {
        sfree(atom_area);
        sfree(atom_area2);
        sfree(res_a);
        sfree(res_area);
        sfree(res_area2);
    }
    if(bDGsol)
    {
        sfree(dgs_factor);
    }
}
コード例 #7
0
int gmx_dih(int argc,char *argv[])
{
  const char *desc[] = {
    "g_dih can do two things. The default is to analyze dihedral transitions",
    "by merely computing all the dihedral angles defined in your topology",
    "for the whole trajectory. When a dihedral flips over to another minimum",
    "an angle/time plot is made.[PAR]",
    "The opther option is to discretize the dihedral space into a number of",
    "bins, and group each conformation in dihedral space in the",
    "appropriate bin. The output is then given as a number of dihedral",
    "conformations sorted according to occupancy."
  };
  static int  mult = -1;
  static bool bSA  = FALSE;
  t_pargs pa[] = {
    { "-sa", FALSE, etBOOL, {&bSA},
      "Perform cluster analysis in dihedral space instead of analysing dihedral transitions." },
    { "-mult", FALSE, etINT, {&mult},
      "mulitiplicity for dihedral angles (by default read from topology)" }
  };
  FILE       *out;
  t_xrama    *xr;
  t_topology *top;
  real       **dih,*time;
  real       dd;
  int        i,nframes,maxframes=1000;
  t_filenm   fnm[] = {
    { efTRX, "-f", NULL, ffREAD },
    { efTPX, NULL, NULL, ffREAD },
    { efOUT, NULL, NULL, 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);
  
  if (mult != -1)
    fprintf(stderr,"Using %d for dihedral multiplicity rather than topology values\n",mult);
    
  snew(xr,1);
  init_rama(ftp2fn(efTRX,NFILE,fnm),
	    ftp2fn(efTPX,NFILE,fnm),xr,3);
  top=read_top(ftp2fn(efTPX,NFILE,fnm),NULL);
	       
  /* Brute force malloc, may be too big... */
  snew(dih,xr->ndih);
  for(i=0; (i<xr->ndih); i++)
    snew(dih[i],maxframes);
  snew(time,maxframes);

  fprintf(stderr,"\n");
  nframes = 0;
  while (new_data(xr)) {
    for(i=0; (i<xr->ndih); i++) {
      dd=xr->dih[i].ang*RAD2DEG;
      while (dd < 0)
	dd+=360;
      while (dd > 360)
	dd-=360;
      dih[i][nframes]=dd;
    }
    time[nframes]=xr->t;
    nframes++;
    if (nframes > maxframes) {
      maxframes += 1000;
      for(i=0; (i<xr->ndih); i++)
	srenew(dih[i],maxframes);
      srenew(time,maxframes);
    }
  } 

  fprintf(stderr,"\nCalculated all dihedrals, now analysing...\n");

  out=ftp2FILE(efOUT,NFILE,fnm,"w");

  if (bSA) {
    /* Cluster and structure analysis */
    ana_cluster(out,xr,dih,time,top,nframes,mult);
  }
  else {
    /* Analyse transitions... */
    ana_trans(out,xr,dih,time,top,nframes);
  }
  fclose(out);
    
  thanx(stderr);
    
  return 0;
}
コード例 #8
0
int gmx_genpr(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]genrestr[tt] produces an include file for a topology containing",
    "a list of atom numbers and three force constants for the",
    "[IT]x[it]-, [IT]y[it]-, and [IT]z[it]-direction. A single isotropic force constant may",
    "be given on the command line instead of three components.[PAR]",
    "WARNING: position restraints only work for the one molecule at a time.",
    "Position restraints are interactions within molecules, therefore",
    "they should be included within the correct [TT][ moleculetype ][tt]",
    "block in the topology. Since the atom numbers in every moleculetype",
    "in the topology start at 1 and the numbers in the input file for",
    "[TT]genrestr[tt] number consecutively from 1, [TT]genrestr[tt] will only",
    "produce a useful file for the first molecule.[PAR]",
    "The [TT]-of[tt] option produces an index file that can be used for",
    "freezing atoms. In this case, the input file must be a [TT].pdb[tt] file.[PAR]",
    "With the [TT]-disre[tt] option, half a matrix of distance restraints",
    "is generated instead of position restraints. With this matrix, that",
    "one typically would apply to C[GRK]alpha[grk] atoms in a protein, one can",
    "maintain the overall conformation of a protein without tieing it to",
    "a specific position (as with position restraints)."
  };
  static rvec    fc={1000.0,1000.0,1000.0};
  static real    freeze_level = 0.0;
  static real    disre_dist = 0.1;
  static real    disre_frac = 0.0;
  static real    disre_up2  = 1.0;
  static gmx_bool    bDisre=FALSE;
  static gmx_bool    bConstr=FALSE;
  static real    cutoff = -1.0;
	
  t_pargs pa[] = {
    { "-fc", FALSE, etRVEC, {fc}, 
      "force constants (kJ/mol nm^2)" },
    { "-freeze", FALSE, etREAL, {&freeze_level},
      "if the [TT]-of[tt] option or this one is given an index file will be written containing atom numbers of all atoms that have a B-factor less than the level given here" },
    { "-disre", FALSE, etBOOL, {&bDisre},
      "Generate a distance restraint matrix for all the atoms in index" },
    { "-disre_dist", FALSE, etREAL, {&disre_dist},
      "Distance range around the actual distance for generating distance restraints" },
    { "-disre_frac", FALSE, etREAL, {&disre_frac},
      "Fraction of distance to be used as interval rather than a fixed distance. If the fraction of the distance that you specify here is less than the distance given in the previous option, that one is used instead." },
    { "-disre_up2", FALSE, etREAL, {&disre_up2},
      "Distance between upper bound for distance restraints, and the distance at which the force becomes constant (see manual)" },
    { "-cutoff", FALSE, etREAL, {&cutoff},
      "Only generate distance restraints for atoms pairs within cutoff (nm)" },
    { "-constr", FALSE, etBOOL, {&bConstr},
      "Generate a constraint matrix rather than distance restraints. Constraints of type 2 will be generated that do generate exclusions." }
  };
#define npargs asize(pa)

  output_env_t oenv;
  t_atoms      *atoms=NULL;
  int          i,j,k;
  FILE         *out;
  int          igrp;
  real         d,dd,lo,hi;
  atom_id      *ind_grp;
  const char   *xfn,*nfn;
  char         *gn_grp;
  char         title[STRLEN];
  matrix       box;
  gmx_bool         bFreeze;
  rvec         dx,*x=NULL,*v=NULL;
  
  t_filenm fnm[] = {
    { efSTX, "-f",  NULL,    ffREAD },
    { efNDX, "-n",  NULL,    ffOPTRD },
    { efITP, "-o",  "posre", ffWRITE },
    { efNDX, "-of", "freeze",    ffOPTWR }
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,0,NFILE,fnm,npargs,pa,
		    asize(desc),desc,0,NULL,&oenv);
  
  bFreeze = opt2bSet("-of",NFILE,fnm) || opt2parg_bSet("-freeze",asize(pa),pa);
  bDisre  = bDisre || opt2parg_bSet("-disre_dist",npargs,pa);
  xfn     = opt2fn_null("-f",NFILE,fnm);
  nfn     = opt2fn_null("-n",NFILE,fnm);
  
  if (( nfn == NULL ) && ( xfn == NULL))
    gmx_fatal(FARGS,"no index file and no structure file suplied");
      
  if ((disre_frac < 0) || (disre_frac >= 1))
    gmx_fatal(FARGS,"disre_frac should be between 0 and 1");
  if (disre_dist < 0)
    gmx_fatal(FARGS,"disre_dist should be >= 0");
    
  if (xfn != NULL) {
    snew(atoms,1);
    get_stx_coordnum(xfn,&(atoms->nr));
    init_t_atoms(atoms,atoms->nr,TRUE);
    snew(x,atoms->nr);
    snew(v,atoms->nr);
    fprintf(stderr,"\nReading structure file\n");
    read_stx_conf(xfn,title,atoms,x,v,NULL,box);
  }
  
  if (bFreeze) {
    if (atoms && atoms->pdbinfo) 
      gmx_fatal(FARGS,"No B-factors in input file %s, use a pdb file next time.",
		xfn);
    
    out=opt2FILE("-of",NFILE,fnm,"w");
    fprintf(out,"[ freeze ]\n");
    for(i=0; (i<atoms->nr); i++) {
      if (atoms->pdbinfo[i].bfac <= freeze_level)
	fprintf(out,"%d\n",i+1);
    }
    ffclose(out);
  }
  else if ((bDisre || bConstr) && x) {
    printf("Select group to generate %s matrix from\n",
	   bConstr ? "constraint" : "distance restraint");
    get_index(atoms,nfn,1,&igrp,&ind_grp,&gn_grp);
    
    out=ftp2FILE(efITP,NFILE,fnm,"w");
    if (bConstr) {
      fprintf(out,"; constraints for %s of %s\n\n",gn_grp,title);
      fprintf(out,"[ constraints ]\n");
      fprintf(out,";%4s %5s %1s %10s\n","i","j","tp","dist");
    }
    else {
      fprintf(out,"; distance restraints for %s of %s\n\n",gn_grp,title);
      fprintf(out,"[ distance_restraints ]\n");
      fprintf(out,";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n","i","j","?",
	      "label","funct","lo","up1","up2","weight");
    }
    for(i=k=0; i<igrp; i++) 
      for(j=i+1; j<igrp; j++,k++) {
	rvec_sub(x[ind_grp[i]],x[ind_grp[j]],dx);
	d = norm(dx);
	if (bConstr) 
	  fprintf(out,"%5d %5d %1d %10g\n",ind_grp[i]+1,ind_grp[j]+1,2,d);
	else {
	  if (cutoff < 0 || d < cutoff)
	  {
	    if (disre_frac > 0) 
	      dd = min(disre_dist,disre_frac*d);
	    else 
	      dd = disre_dist;
	    lo = max(0,d-dd);
	    hi = d+dd;
	    fprintf(out,"%5d %5d %1d %5d %10d %10g %10g %10g %10g\n",
		  ind_grp[i]+1,ind_grp[j]+1,1,k,1,
		  lo,hi,hi+1,1.0);
		}
	}
      }
    ffclose(out);
  }
  else {
    printf("Select group to position restrain\n");
    get_index(atoms,nfn,1,&igrp,&ind_grp,&gn_grp);
    
    out=ftp2FILE(efITP,NFILE,fnm,"w");
    fprintf(out,"; position restraints for %s of %s\n\n",gn_grp,title);
    fprintf(out,"[ position_restraints ]\n");
    fprintf(out,";%3s %5s %9s %10s %10s\n","i","funct","fcx","fcy","fcz");
    for(i=0; i<igrp; i++) 
      fprintf(out,"%4d %4d %10g %10g %10g\n",
	      ind_grp[i]+1,1,fc[XX],fc[YY],fc[ZZ]);
    ffclose(out);
  }
  if (xfn) {
    sfree(x);
    sfree(v);
  }  
  
  thanx(stderr);
 
  return 0;
}
コード例 #9
0
int gmx_bond(int argc,char *argv[])
{
  static char *desc[] = {
    "g_bond makes a distribution of bond lengths. If all is well a",
    "gaussian distribution should be made when using a harmonic potential.",
    "bonds are read from a single group in the index file in order i1-j1",
    "i2-j2 thru in-jn.[PAR]",
    "[TT]-tol[tt] gives the half-width of the distribution as a fraction",
    "of the bondlength ([TT]-blen[tt]). That means, for a bond of 0.2",
    "a tol of 0.1 gives a distribution from 0.18 to 0.22.[PAR]",
    "Option [TT]-d[tt] plots all the distances as a function of time.",
    "This requires a structure file for the atom and residue names in",
    "the output. If however the option [TT]-averdist[tt] is given (as well",
    "or separately) the average bond length is plotted instead."
  };
  static char *bugs[] = {
    "It should be possible to get bond information from the topology."
  };
  static real blen=-1.0,tol=0.1;
  static bool bAver=TRUE,bAverDist=TRUE;
  t_pargs pa[] = {
    { "-blen", FALSE, etREAL, {&blen}, 
      "Bond length. By default length of first bond" },
    { "-tol",  FALSE, etREAL, {&tol}, 
      "Half width of distribution as fraction of blen" },
    { "-aver", FALSE, etBOOL, {&bAver},
      "Average bond length distributions" },
    { "-averdist", FALSE, etBOOL, {&bAverDist},
      "Average distances (turns on -d)" }
  };
  FILE      *fp;
  char      *grpname,*fdist;
  int       gnx;
  atom_id   *index;
  char      title[STRLEN];
  t_topology top;
  int       ePBC=-1;
  rvec      *x;
  matrix    box;

  t_filenm fnm[] = {
    { efTRX, "-f", NULL, ffREAD  },
    { efNDX, NULL, NULL, ffREAD  },
    { efTPS, NULL, NULL, ffOPTRD },
    { efXVG, "-o", "bonds", ffWRITE },
    { efLOG, NULL, "bonds", ffOPTWR },
    { efXVG, "-d", "distance", ffOPTWR }
  };
#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,asize(bugs),bugs);
  
  if (bAverDist)
    fdist = opt2fn("-d",NFILE,fnm);
  else {
    fdist = opt2fn_null("-d",NFILE,fnm);
    if (fdist)
      read_tps_conf(ftp2fn(efTPS,NFILE,fnm),title,&top,&ePBC,&x,NULL,box,
		    FALSE);
  }
  
  rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpname);
  if ( !even(gnx) )
    fprintf(stderr,"WARNING: odd number of atoms (%d) in group!\n",gnx);
  fprintf(stderr,"Will gather information on %d bonds\n",gnx/2);
  
  if (!bAver)
    fp = ftp2FILE(efLOG,NFILE,fnm,"w");
  else
    fp = NULL;
  
  do_bonds(fp,ftp2fn(efTRX,NFILE,fnm),opt2fn("-o",NFILE,fnm),fdist,gnx,index,
	   blen,tol,bAver,&top,ePBC,bAverDist);
  
  do_view(opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(opt2fn_null("-d",NFILE,fnm),"-nxy");
  
  thanx(stderr);
  
  return 0;
}
コード例 #10
0
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "mk_angndx 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 char *opt[] = { NULL, "angle", "dihedral", "improper", "ryckaert-bellemans", NULL };
  static bool bH=TRUE;
  t_pargs pa[] = {
    { "-type", FALSE, etENUM, {opt},
      "Type of angle" },
    { "-hyd", FALSE, etBOOL, {&bH},
      "Include angles with atoms with mass < 1.5" }
  };
  
  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);


  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);
  
  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");
    }
  }
  fclose(out);
  
  thanx(stderr);
  
  return 0;
}
コード例 #11
0
ファイル: gmx_disre.cpp プロジェクト: mpharrigan/gromacs
int gmx_disre(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] computes violations of distance restraints.",
        "The program always",
        "computes the instantaneous violations rather than time-averaged,",
        "because this analysis is done from a trajectory file afterwards",
        "it does not make sense to use time averaging. However,",
        "the time averaged values per restraint are given in the log file.[PAR]",
        "An index file may be used to select specific restraints for",
        "printing.[PAR]",
        "When the optional [TT]-q[tt] flag is given a [REF].pdb[ref] file coloured by the",
        "amount of average violations.[PAR]",
        "When the [TT]-c[tt] option is given, an index file will be read",
        "containing the frames in your trajectory corresponding to the clusters",
        "(defined in another manner) that you want to analyze. For these clusters",
        "the program will compute average violations using the third power",
        "averaging algorithm and print them in the log file."
    };
    static int      ntop      = 0;
    static int      nlevels   = 20;
    static real     max_dr    = 0;
    static gmx_bool bThird    = TRUE;
    t_pargs         pa[]      = {
        { "-ntop", FALSE, etINT,  {&ntop},
          "Number of large violations that are stored in the log file every step" },
        { "-maxdr", FALSE, etREAL, {&max_dr},
          "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." },
        { "-nlevels", FALSE, etINT, {&nlevels},
          "Number of levels in the matrix output" },
        { "-third", FALSE, etBOOL, {&bThird},
          "Use inverse third power averaging or linear for matrix output" }
    };

    FILE           *out = NULL, *aver = NULL, *numv = NULL, *maxxv = NULL, *xvg = NULL;
    t_tpxheader     header;
    t_inputrec      ir;
    gmx_mtop_t      mtop;
    rvec           *xtop;
    gmx_localtop_t *top;
    t_atoms        *atoms = NULL;
    t_fcdata        fcd;
    t_nrnb          nrnb;
    t_graph        *g;
    int             ntopatoms, natoms, i, j, kkk;
    t_trxstatus    *status;
    real            t;
    rvec           *x, *f, *xav = NULL;
    matrix          box;
    gmx_bool        bPDB;
    int             isize;
    atom_id        *index = NULL, *ind_fit = NULL;
    char           *grpname;
    t_cluster_ndx  *clust = NULL;
    t_dr_result     dr, *dr_clust = NULL;
    char          **leg;
    real           *vvindex = NULL, *w_rls = NULL;
    t_mdatoms      *mdatoms;
    t_pbc           pbc, *pbc_null;
    int             my_clust;
    FILE           *fplog;
    output_env_t    oenv;
    gmx_rmpbc_t     gpbc = NULL;

    t_filenm        fnm[] = {
        { efTPR, NULL, NULL, ffREAD },
        { efTRX, "-f", NULL, ffREAD },
        { efXVG, "-ds", "drsum",  ffWRITE },
        { efXVG, "-da", "draver", ffWRITE },
        { efXVG, "-dn", "drnum",  ffWRITE },
        { efXVG, "-dm", "drmax",  ffWRITE },
        { efXVG, "-dr", "restr",  ffWRITE },
        { efLOG, "-l",  "disres", ffWRITE },
        { efNDX, NULL,  "viol",   ffOPTRD },
        { efPDB, "-q",  "viol",   ffOPTWR },
        { efNDX, "-c",  "clust",  ffOPTRD },
        { efXPM, "-x",  "matrix", ffOPTWR }
    };
#define NFILE asize(fnm)

    if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW,
                           NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv))
    {
        return 0;
    }

    fplog = ftp2FILE(efLOG, NFILE, fnm, "w");

    if (ntop)
    {
        init5(ntop);
    }

    read_tpxheader(ftp2fn(efTPR, NFILE, fnm), &header, FALSE, NULL, NULL);
    snew(xtop, header.natoms);
    read_tpx(ftp2fn(efTPR, NFILE, fnm), &ir, box, &ntopatoms, xtop, NULL, &mtop);
    bPDB = opt2bSet("-q", NFILE, fnm);
    if (bPDB)
    {
        snew(xav, ntopatoms);
        snew(ind_fit, ntopatoms);
        snew(w_rls, ntopatoms);
        for (kkk = 0; (kkk < ntopatoms); kkk++)
        {
            w_rls[kkk]   = 1;
            ind_fit[kkk] = kkk;
        }

        snew(atoms, 1);
        *atoms = gmx_mtop_global_atoms(&mtop);

        if (atoms->pdbinfo == NULL)
        {
            snew(atoms->pdbinfo, atoms->nr);
        }
    }

    top = gmx_mtop_generate_local_top(&mtop, &ir);

    g        = NULL;
    pbc_null = NULL;
    if (ir.ePBC != epbcNONE)
    {
        if (ir.bPeriodicMols)
        {
            pbc_null = &pbc;
        }
        else
        {
            g = mk_graph(fplog, &top->idef, 0, mtop.natoms, FALSE, FALSE);
        }
    }

    if (ftp2bSet(efNDX, NFILE, fnm))
    {
        /* TODO: Nothing is written to this file if -c is provided, but it is
         * still opened... */
        rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname);
        xvg = xvgropen(opt2fn("-dr", NFILE, fnm), "Individual Restraints", "Time (ps)",
                       "nm", oenv);
        snew(vvindex, isize);
        snew(leg, isize);
        for (i = 0; (i < isize); i++)
        {
            index[i]++;
            snew(leg[i], 12);
            sprintf(leg[i], "index %d", index[i]);
        }
        xvgr_legend(xvg, isize, (const char**)leg, oenv);
    }
    else
    {
        isize = 0;
    }

    ir.dr_tau = 0.0;
    init_disres(fplog, &mtop, &ir, NULL, &fcd, NULL, FALSE);

    natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box);
    snew(f, 5*natoms);

    init_dr_res(&dr, fcd.disres.nres);
    if (opt2bSet("-c", NFILE, fnm))
    {
        clust = cluster_index(fplog, opt2fn("-c", NFILE, fnm));
        snew(dr_clust, clust->clust->nr+1);
        for (i = 0; (i <= clust->clust->nr); i++)
        {
            init_dr_res(&dr_clust[i], fcd.disres.nres);
        }
    }
    else
    {
        out = xvgropen(opt2fn("-ds", NFILE, fnm),
                       "Sum of Violations", "Time (ps)", "nm", oenv);
        aver = xvgropen(opt2fn("-da", NFILE, fnm),
                        "Average Violation", "Time (ps)", "nm", oenv);
        numv = xvgropen(opt2fn("-dn", NFILE, fnm),
                        "# Violations", "Time (ps)", "#", oenv);
        maxxv = xvgropen(opt2fn("-dm", NFILE, fnm),
                         "Largest Violation", "Time (ps)", "nm", oenv);
    }

    mdatoms = init_mdatoms(fplog, &mtop, ir.efep != efepNO);
    atoms2md(&mtop, &ir, 0, NULL, mtop.natoms, mdatoms);
    update_mdatoms(mdatoms, ir.fepvals->init_lambda);
    init_nrnb(&nrnb);
    if (ir.ePBC != epbcNONE)
    {
        gpbc = gmx_rmpbc_init(&top->idef, ir.ePBC, natoms);
    }

    j = 0;
    do
    {
        if (ir.ePBC != epbcNONE)
        {
            if (ir.bPeriodicMols)
            {
                set_pbc(&pbc, ir.ePBC, box);
            }
            else
            {
                gmx_rmpbc(gpbc, natoms, box, x);
            }
        }

        if (clust)
        {
            if (j > clust->maxframe)
            {
                gmx_fatal(FARGS, "There are more frames in the trajectory than in the cluster index file. t = %8f\n", t);
            }
            my_clust = clust->inv_clust[j];
            range_check(my_clust, 0, clust->clust->nr);
            check_viol(fplog, &(top->idef.il[F_DISRES]),
                       top->idef.iparams,
                       x, f, pbc_null, g, dr_clust, my_clust, isize, index, vvindex, &fcd);
        }
        else
        {
            check_viol(fplog, &(top->idef.il[F_DISRES]),
                       top->idef.iparams,
                       x, f, pbc_null, g, &dr, 0, isize, index, vvindex, &fcd);
        }
        if (bPDB)
        {
            reset_x(atoms->nr, ind_fit, atoms->nr, NULL, x, w_rls);
            do_fit(atoms->nr, w_rls, x, x);
            if (j == 0)
            {
                /* Store the first frame of the trajectory as 'characteristic'
                 * for colouring with violations.
                 */
                for (kkk = 0; (kkk < atoms->nr); kkk++)
                {
                    copy_rvec(x[kkk], xav[kkk]);
                }
            }
        }
        if (!clust)
        {
            if (isize > 0)
            {
                fprintf(xvg, "%10g", t);
                for (i = 0; (i < isize); i++)
                {
                    fprintf(xvg, "  %10g", vvindex[i]);
                }
                fprintf(xvg, "\n");
            }
            fprintf(out,  "%10g  %10g\n", t, dr.sumv);
            fprintf(aver, "%10g  %10g\n", t, dr.averv);
            fprintf(maxxv, "%10g  %10g\n", t, dr.maxv);
            fprintf(numv, "%10g  %10d\n", t, dr.nv);
        }
        j++;
    }
    while (read_next_x(oenv, status, &t, x, box));
    close_trj(status);
    if (ir.ePBC != epbcNONE)
    {
        gmx_rmpbc_done(gpbc);
    }

    if (clust)
    {
        dump_clust_stats(fplog, fcd.disres.nres, &(top->idef.il[F_DISRES]),
                         top->idef.iparams, clust->clust, dr_clust,
                         clust->grpname, isize, index);
    }
    else
    {
        dump_stats(fplog, j, fcd.disres.nres, &(top->idef.il[F_DISRES]),
                   top->idef.iparams, &dr, isize, index,
                   bPDB ? atoms : NULL);
        if (bPDB)
        {
            write_sto_conf(opt2fn("-q", NFILE, fnm),
                           "Coloured by average violation in Angstrom",
                           atoms, xav, NULL, ir.ePBC, box);
        }
        dump_disre_matrix(opt2fn_null("-x", NFILE, fnm), &dr, fcd.disres.nres,
                          j, &top->idef, &mtop, max_dr, nlevels, bThird);
        xvgrclose(out);
        xvgrclose(aver);
        xvgrclose(numv);
        xvgrclose(maxxv);
        do_view(oenv, opt2fn("-dn", NFILE, fnm), "-nxy");
        do_view(oenv, opt2fn("-da", NFILE, fnm), "-nxy");
        do_view(oenv, opt2fn("-ds", NFILE, fnm), "-nxy");
        do_view(oenv, opt2fn("-dm", NFILE, fnm), "-nxy");
    }
    if (isize > 0)
    {
        xvgrclose(xvg);
        if (!clust)
        {
            do_view(oenv, opt2fn("-dr", NFILE, fnm), "-nxy");
        }
    }

    gmx_log_close(fplog);

    return 0;
}
コード例 #12
0
int gmx_cluster(int argc,char *argv[])
{
  static char *desc[] = {
    "g_cluster can cluster structures with several different methods.",
    "Distances between structures can be determined from a trajectory",
    "or read from an XPM matrix file with the [TT]-dm[tt] option.",
    "RMS deviation after fitting or RMS deviation of atom-pair distances",
    "can be used to define the distance between structures.[PAR]",
    
    "single linkage: add a structure to a cluster when its distance to any",
    "element of the cluster is less than [TT]cutoff[tt].[PAR]",
    
    "Jarvis Patrick: add a structure to a cluster when this structure",
    "and a structure in the cluster have each other as neighbors and",
    "they have a least [TT]P[tt] neighbors in common. The neighbors",
    "of a structure are the M closest structures or all structures within",
    "[TT]cutoff[tt].[PAR]",
    
    "Monte Carlo: reorder the RMSD matrix using Monte Carlo.[PAR]",
    
    "diagonalization: diagonalize the RMSD matrix.[PAR]"
    
    "gromos: use algorithm as described in Daura [IT]et al.[it]",
    "([IT]Angew. Chem. Int. Ed.[it] [BB]1999[bb], [IT]38[it], pp 236-240).",
    "Count number of neighbors using cut-off, take structure with",
    "largest number of neighbors with all its neighbors as cluster",
    "and eleminate it from the pool of clusters. Repeat for remaining",
    "structures in pool.[PAR]",
    
    "When the clustering algorithm assigns each structure to exactly one",
    "cluster (single linkage, Jarvis Patrick and gromos) and a trajectory",
    "file is supplied, the structure with",
    "the smallest average distance to the others or the average structure",
    "or all structures for each cluster will be written to a trajectory",
    "file. When writing all structures, separate numbered files are made",
    "for each cluster.[PAR]"
    
    "Two output files are always written:[BR]",
    "[TT]-o[tt] writes the RMSD values in the upper left half of the matrix",
    "and a graphical depiction of the clusters in the lower right half",
    "When [TT]-minstruct[tt] = 1 the graphical depiction is black",
    "when two structures are in the same cluster.",
    "When [TT]-minstruct[tt] > 1 different colors will be used for each",
    "cluster.[BR]",
    "[TT]-g[tt] writes information on the options used and a detailed list",
    "of all clusters and their members.[PAR]",
    
    "Additionally, a number of optional output files can be written:[BR]",
    "[TT]-dist[tt] writes the RMSD distribution.[BR]",
    "[TT]-ev[tt] writes the eigenvectors of the RMSD matrix",
    "diagonalization.[BR]",
    "[TT]-sz[tt] writes the cluster sizes.[BR]",
    "[TT]-tr[tt] writes a matrix of the number transitions between",
    "cluster pairs.[BR]",
    "[TT]-ntr[tt] writes the total number of transitions to or from",
    "each cluster.[BR]",
    "[TT]-clid[tt] writes the cluster number as a function of time.[BR]",
    "[TT]-cl[tt] writes average (with option [TT]-av[tt]) or central",
    "structure of each cluster or writes numbered files with cluster members",
    "for a selected set of clusters (with option [TT]-wcl[tt], depends on",
    "[TT]-nst[tt] and [TT]-rmsmin[tt]).[BR]",
  };
  
  FILE         *fp,*log;
  int          i,i1,i2,j,nf,nrms;

  matrix       box;
  rvec         *xtps,*usextps,*x1,**xx=NULL;
  char         *fn,*trx_out_fn;
  t_clusters   clust;
  t_mat        *rms;
  real         *eigval;
  t_topology   top;
  int          ePBC;
  t_atoms      useatoms;
  t_matrix     *readmat;
  real         *tmp;
  
  int      isize=0,ifsize=0,iosize=0;
  atom_id  *index=NULL, *fitidx, *outidx;
  char     *grpname;
  real     rmsd,**d1,**d2,*time,time_invfac,*mass=NULL;
  char     buf[STRLEN],buf1[80],title[STRLEN];
  bool     bAnalyze,bUseRmsdCut,bJP_RMSD=FALSE,bReadMat,bReadTraj;

  int method,ncluster=0;  
  static char *methodname[] = { 
    NULL, "linkage", "jarvis-patrick","monte-carlo", 
    "diagonalization", "gromos", NULL
  };
  enum { m_null, m_linkage, m_jarvis_patrick, 
	 m_monte_carlo, m_diagonalize, m_gromos, m_nr };
  /* Set colors for plotting: white = zero RMS, black = maximum */
  static t_rgb rlo_top = { 1.0, 1.0, 1.0 };
  static t_rgb rhi_top = { 0.0, 0.0, 0.0 };
  static t_rgb rlo_bot = { 1.0, 1.0, 1.0 };
  static t_rgb rhi_bot = { 0.0, 0.0, 1.0 };
  static int  nlevels=40,skip=1;
  static real scalemax=-1.0,rmsdcut=0.1,rmsmin=0.0;
  static bool bRMSdist=FALSE,bBinary=FALSE,bAverage=FALSE,bFit=TRUE;
  static int  niter=10000,seed=1993,write_ncl=0,write_nst=1,minstruct=1;
  static real kT=1e-3;
  static int  M=10,P=3;
  t_pargs pa[] = {
    { "-dista", FALSE, etBOOL, {&bRMSdist},
      "Use RMSD of distances instead of RMS deviation" },
    { "-nlevels",FALSE,etINT,  {&nlevels},
      "Discretize RMSD matrix in # levels" },
    { "-cutoff",FALSE, etREAL, {&rmsdcut},
      "RMSD cut-off (nm) for two structures to be neighbor" },
    { "-fit",   FALSE, etBOOL, {&bFit},
      "Use least squares fitting before RMSD calculation" },
    { "-max",   FALSE, etREAL, {&scalemax},
      "Maximum level in RMSD matrix" },
    { "-skip",  FALSE, etINT,  {&skip},
      "Only analyze every nr-th frame" },
    { "-av",    FALSE, etBOOL, {&bAverage},
      "Write average iso middle structure for each cluster" },
    { "-wcl",   FALSE, etINT,  {&write_ncl},
      "Write all structures for first # clusters to numbered files" },
    { "-nst",   FALSE, etINT,  {&write_nst},
      "Only write all structures if more than # per cluster" },
    { "-rmsmin",FALSE, etREAL, {&rmsmin},
      "minimum rms difference with rest of cluster for writing structures" },
    { "-method",FALSE, etENUM, {methodname},
      "Method for cluster determination" },
    { "-minstruct", FALSE, etINT, {&minstruct},
      "Minimum number of structures in cluster for coloring in the xpm file" },
    { "-binary",FALSE, etBOOL, {&bBinary},
      "Treat the RMSD matrix as consisting of 0 and 1, where the cut-off "
      "is given by -cutoff" },
    { "-M",     FALSE, etINT,  {&M},
      "Number of nearest neighbors considered for Jarvis-Patrick algorithm, "
      "0 is use cutoff" },
    { "-P",     FALSE, etINT,  {&P},
      "Number of identical nearest neighbors required to form a cluster" },
    { "-seed",  FALSE, etINT,  {&seed},
      "Random number seed for Monte Carlo clustering algorithm" },
    { "-niter", FALSE, etINT,  {&niter},
      "Number of iterations for MC" },
    { "-kT",    FALSE, etREAL, {&kT},
      "Boltzmann weighting factor for Monte Carlo optimization "
      "(zero turns off uphill steps)" }
  };
  t_filenm fnm[] = {
    { efTRX, "-f",     NULL,        ffOPTRD },
    { efTPS, "-s",     NULL,        ffOPTRD },
    { efNDX, NULL,     NULL,        ffOPTRD },
    { efXPM, "-dm",   "rmsd",       ffOPTRD },     
    { efXPM, "-o",    "rmsd-clust", ffWRITE },
    { efLOG, "-g",    "cluster",    ffWRITE },
    { efXVG, "-dist", "rmsd-dist",  ffOPTWR },
    { efXVG, "-ev",   "rmsd-eig",   ffOPTWR },
    { efXVG, "-sz",   "clust-size", ffOPTWR},
    { efXPM, "-tr",   "clust-trans",ffOPTWR},
    { efXVG, "-ntr",  "clust-trans",ffOPTWR},
    { efXVG, "-clid", "clust-id.xvg",ffOPTWR},
    { efTRX, "-cl",   "clusters.pdb", ffOPTWR }
  };
#define NFILE asize(fnm)
  
  CopyRight(stderr,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT | PCA_BE_NICE,
		    NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL);

  /* parse options */
  bReadMat   = opt2bSet("-dm",NFILE,fnm);
  bReadTraj  = opt2bSet("-f",NFILE,fnm) || !bReadMat;
  if ( opt2parg_bSet("-av",asize(pa),pa) ||
       opt2parg_bSet("-wcl",asize(pa),pa) ||
       opt2parg_bSet("-nst",asize(pa),pa) ||
       opt2parg_bSet("-rmsmin",asize(pa),pa) ||
       opt2bSet("-cl",NFILE,fnm) )
    trx_out_fn = opt2fn("-cl",NFILE,fnm);
  else
    trx_out_fn = NULL;
  if (bReadMat && time_factor()!=1) {
    fprintf(stderr,
	    "\nWarning: assuming the time unit in %s is %s\n",
	    opt2fn("-dm",NFILE,fnm),time_unit());
  }
  if (trx_out_fn && !bReadTraj)
    fprintf(stderr,"\nWarning: "
	    "cannot write cluster structures without reading trajectory\n"
	    "         ignoring option -cl %s\n", trx_out_fn);

  method=1;
  while ( method < m_nr && strcasecmp(methodname[0], methodname[method])!=0 )
    method++;
  if (method == m_nr)
    gmx_fatal(FARGS,"Invalid method");
  
  bAnalyze = (method == m_linkage || method == m_jarvis_patrick ||
	      method == m_gromos );
  
  /* Open log file */
  log = ftp2FILE(efLOG,NFILE,fnm,"w");

  fprintf(stderr,"Using %s method for clustering\n",methodname[0]);
  fprintf(log,"Using %s method for clustering\n",methodname[0]);

  /* check input and write parameters to log file */
  bUseRmsdCut = FALSE;
  if (method == m_jarvis_patrick) {
    bJP_RMSD = (M == 0) || opt2parg_bSet("-cutoff",asize(pa),pa);
    if ((M<0) || (M == 1))
      gmx_fatal(FARGS,"M (%d) must be 0 or larger than 1",M);
    if (M < 2) {
      sprintf(buf1,"Will use P=%d and RMSD cutoff (%g)",P,rmsdcut);
      bUseRmsdCut = TRUE;
    } else {
      if (P >= M)
	gmx_fatal(FARGS,"Number of neighbors required (P) must be less than M");
      if (bJP_RMSD) {
	sprintf(buf1,"Will use P=%d, M=%d and RMSD cutoff (%g)",P,M,rmsdcut);
	bUseRmsdCut = TRUE;
      } else
	sprintf(buf1,"Will use P=%d, M=%d",P,M);
    }
    ffprintf1(stderr,log,buf,"%s for determining the neighbors\n\n",buf1);
  } else /* method != m_jarvis */
    bUseRmsdCut = ( bBinary || method == m_linkage || method == m_gromos );
  if (bUseRmsdCut && method != m_jarvis_patrick)
    fprintf(log,"Using RMSD cutoff %g nm\n",rmsdcut);
  if ( method==m_monte_carlo )
    fprintf(log,"Using %d iterations\n",niter);
  
  if (skip < 1)
    gmx_fatal(FARGS,"skip (%d) should be >= 1",skip);

  /* get input */
  if (bReadTraj) {
    /* don't read mass-database as masses (and top) are not used */
    read_tps_conf(ftp2fn(efTPS,NFILE,fnm),buf,&top,&ePBC,&xtps,NULL,box,
		  bAnalyze);
    
    fprintf(stderr,"\nSelect group for least squares fit%s:\n",
	    bReadMat?"":" and RMSD calculation");
    get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm),
	      1,&ifsize,&fitidx,&grpname);
    if (trx_out_fn) {
      fprintf(stderr,"\nSelect group for output:\n");
      get_index(&(top.atoms),ftp2fn_null(efNDX,NFILE,fnm),
		1,&iosize,&outidx,&grpname);
      /* merge and convert both index groups: */
      /* first copy outidx to index. let outidx refer to elements in index */
      snew(index,iosize);
      isize = iosize;
      for(i=0; i<iosize; i++) {
	index[i]=outidx[i];
	outidx[i]=i;
      }
      /* now lookup elements from fitidx in index, add them if necessary
	 and also let fitidx refer to elements in index */
      for(i=0; i<ifsize; i++) {
	j=0;
	while (j<isize && index[j]!=fitidx[i])
	  j++;
	if (j>=isize) {
	  /* slow this way, but doesn't matter much */
	  isize++;
	  srenew(index,isize);
	}
	index[j]=fitidx[i];
	fitidx[i]=j;
      }
    } else { /* !trx_out_fn */
      isize = ifsize;
      snew(index, isize);
      for(i=0; i<ifsize; i++) {
	index[i]=fitidx[i];
	fitidx[i]=i;
      }
    }
  }
  /* Initiate arrays */
  snew(d1,isize);
  snew(d2,isize);
  for(i=0; (i<isize); i++) {
    snew(d1[i],isize);
    snew(d2[i],isize);
  }

  if (bReadTraj) {
    /* Loop over first coordinate file */
    fn = opt2fn("-f",NFILE,fnm);
    
    xx = read_whole_trj(fn,isize,index,skip,&nf,&time);
    convert_times(nf, time);
    if (!bRMSdist || bAnalyze) {
      /* Center all frames on zero */
      snew(mass,isize);
      for(i=0; i<ifsize; i++)
	mass[fitidx[i]] = top.atoms.atom[index[fitidx[i]]].m;
      if (bFit)
      for(i=0; i<nf; i++)
	reset_x(ifsize,fitidx,isize,NULL,xx[i],mass);
    }
  }
  if (bReadMat) {
    fprintf(stderr,"Reading rms distance matrix ");
    read_xpm_matrix(opt2fn("-dm",NFILE,fnm),&readmat);
    fprintf(stderr,"\n");
    if (readmat[0].nx != readmat[0].ny)
      gmx_fatal(FARGS,"Matrix (%dx%d) is not square",
		  readmat[0].nx,readmat[0].ny);
    if (bReadTraj && bAnalyze && (readmat[0].nx != nf))
      gmx_fatal(FARGS,"Matrix size (%dx%d) does not match the number of "
		  "frames (%d)",readmat[0].nx,readmat[0].ny,nf);

    nf = readmat[0].nx;
    sfree(time);
    time = readmat[0].axis_x;
    time_invfac = time_invfactor();
    for(i=0; i<nf; i++)
      time[i] *= time_invfac;

    rms = init_mat(readmat[0].nx,method == m_diagonalize);
    convert_mat(&(readmat[0]),rms);
    
    nlevels = readmat[0].nmap;
  } else { /* !bReadMat */
    rms = init_mat(nf,method == m_diagonalize);
    nrms = (nf*(nf-1))/2;
    if (!bRMSdist) {
      fprintf(stderr,"Computing %dx%d RMS deviation matrix\n",nf,nf);
      snew(x1,isize);
      for(i1=0; (i1<nf); i1++) {
	for(i2=i1+1; (i2<nf); i2++) {
	  for(i=0; i<isize; i++)
	    copy_rvec(xx[i1][i],x1[i]);
	  if (bFit)
	    do_fit(isize,mass,xx[i2],x1);
	  rmsd = rmsdev(isize,mass,xx[i2],x1);
	  set_mat_entry(rms,i1,i2,rmsd);
	}
	nrms -= (nf-i1-1);
	fprintf(stderr,"\r# RMSD calculations left: %d   ",nrms);
      }
    } else { /* bRMSdist */
      fprintf(stderr,"Computing %dx%d RMS distance deviation matrix\n",nf,nf);
      for(i1=0; (i1<nf); i1++) {
	calc_dist(isize,xx[i1],d1);
	for(i2=i1+1; (i2<nf); i2++) {
	  calc_dist(isize,xx[i2],d2);
	  set_mat_entry(rms,i1,i2,rms_dist(isize,d1,d2));
      }
	nrms -= (nf-i1-1);
	fprintf(stderr,"\r# RMSD calculations left: %d   ",nrms);
      }
    }
    fprintf(stderr,"\n\n");
  }
  ffprintf2(stderr,log,buf,"The RMSD ranges from %g to %g nm\n",
	    rms->minrms,rms->maxrms);
  ffprintf1(stderr,log,buf,"Average RMSD is %g\n",2*rms->sumrms/(nf*(nf-1)));
  ffprintf1(stderr,log,buf,"Number of structures for matrix %d\n",nf);
  ffprintf1(stderr,log,buf,"Energy of the matrix is %g nm\n",mat_energy(rms));
  if (bUseRmsdCut && (rmsdcut < rms->minrms || rmsdcut > rms->maxrms) )
    fprintf(stderr,"WARNING: rmsd cutoff %g is outside range of rmsd values "
	    "%g to %g\n",rmsdcut,rms->minrms,rms->maxrms);
  if (bAnalyze && (rmsmin < rms->minrms) )
    fprintf(stderr,"WARNING: rmsd minimum %g is below lowest rmsd value %g\n",
	    rmsmin,rms->minrms);
  if (bAnalyze && (rmsmin > rmsdcut) )
    fprintf(stderr,"WARNING: rmsd minimum %g is above rmsd cutoff %g\n",
	    rmsmin,rmsdcut);
  
  /* Plot the rmsd distribution */
  rmsd_distribution(opt2fn("-dist",NFILE,fnm),rms);
  
  if (bBinary) {
    for(i1=0; (i1 < nf); i1++) 
      for(i2=0; (i2 < nf); i2++)
	if (rms->mat[i1][i2] < rmsdcut)
	  rms->mat[i1][i2] = 0;
	else
	  rms->mat[i1][i2] = 1;
  }

  snew(clust.cl,nf);
  switch (method) {
  case m_linkage: 
    /* Now sort the matrix and write it out again */
    gather(rms,rmsdcut,&clust);
    break;
  case m_diagonalize:
    /* Do a diagonalization */
      snew(eigval,nf);
      snew(tmp,nf*nf);
      memcpy(tmp,rms->mat[0],nf*nf*sizeof(real));
      eigensolver(tmp,nf,0,nf,eigval,rms->mat[0]);
      sfree(tmp);
      
      fp = xvgropen(opt2fn("-ev",NFILE,fnm),"RMSD matrix Eigenvalues",
                    "Eigenvector index","Eigenvalues (nm\\S2\\N)");
      for(i=0; (i<nf); i++)
          fprintf(fp,"%10d  %10g\n",i,eigval[i]);
          ffclose(fp);
      break;
  case m_monte_carlo:
    mc_optimize(log,rms,niter,&seed,kT);
    swap_mat(rms);
    reset_index(rms);
    break;
  case m_jarvis_patrick:
    jarvis_patrick(rms->nn,rms->mat,M,P,bJP_RMSD ? rmsdcut : -1,&clust);
    break;
  case m_gromos:
    gromos(rms->nn,rms->mat,rmsdcut,&clust);
    break;
  default:
    gmx_fatal(FARGS,"DEATH HORROR unknown method \"%s\"",methodname[0]);
  }
  
  if (method == m_monte_carlo || method == m_diagonalize)
    fprintf(stderr,"Energy of the matrix after clustering is %g nm\n",
	    mat_energy(rms));
  
  if (bAnalyze) {
    if (minstruct > 1) {
      ncluster = plot_clusters(nf,rms->mat,&clust,nlevels,minstruct);
    } else {
      mark_clusters(nf,rms->mat,rms->maxrms,&clust);
    }
    init_t_atoms(&useatoms,isize,FALSE);
    snew(usextps, isize);
    useatoms.resname=top.atoms.resname;
    for(i=0; i<isize; i++) {
      useatoms.atomname[i]=top.atoms.atomname[index[i]];
      useatoms.atom[i].resnr=top.atoms.atom[index[i]].resnr;
      useatoms.nres=max(useatoms.nres,useatoms.atom[i].resnr+1);
      copy_rvec(xtps[index[i]],usextps[i]);
    }
    useatoms.nr=isize;
    analyze_clusters(nf,&clust,rms->mat,isize,&useatoms,usextps,mass,xx,time,
		     ifsize,fitidx,iosize,outidx,
		     bReadTraj?trx_out_fn:NULL,
		     opt2fn_null("-sz",NFILE,fnm),
		     opt2fn_null("-tr",NFILE,fnm),
		     opt2fn_null("-ntr",NFILE,fnm),
		     opt2fn_null("-clid",NFILE,fnm),
		     bAverage, write_ncl, write_nst, rmsmin, bFit, log,
		     rlo_bot,rhi_bot);
  }
  ffclose(log);
  
  if (bBinary && !bAnalyze)
    /* Make the clustering visible */
    for(i2=0; (i2 < nf); i2++)
       for(i1=i2+1; (i1 < nf); i1++)
	 if (rms->mat[i1][i2])
	   rms->mat[i1][i2] = rms->maxrms;

  fp = opt2FILE("-o",NFILE,fnm,"w");
  fprintf(stderr,"Writing rms distance/clustering matrix ");
  if (bReadMat) {
    write_xpm(fp,0,readmat[0].title,readmat[0].legend,readmat[0].label_x,
	      readmat[0].label_y,nf,nf,readmat[0].axis_x,readmat[0].axis_y,
	      rms->mat,0.0,rms->maxrms,rlo_top,rhi_top,&nlevels);
  } 
  else {
    sprintf(buf,"Time (%s)",time_unit());
    sprintf(title,"RMS%sDeviation / Cluster Index",
 	    bRMSdist ? " Distance " : " ");
    if (minstruct > 1) {
      write_xpm_split(fp,0,title,"RMSD (nm)",buf,buf,
		      nf,nf,time,time,rms->mat,0.0,rms->maxrms,&nlevels,
		      rlo_top,rhi_top,0.0,(real) ncluster,
		      &ncluster,TRUE,rlo_bot,rhi_bot);
    } else {
      write_xpm(fp,0,title,"RMSD (nm)",buf,buf,
		nf,nf,time,time,rms->mat,0.0,rms->maxrms,
		rlo_top,rhi_top,&nlevels);
    }
  }
  fprintf(stderr,"\n");
  ffclose(fp);
  
  /* now show what we've done */
  do_view(opt2fn("-o",NFILE,fnm),"-nxy");
  do_view(opt2fn_null("-sz",NFILE,fnm),"-nxy");
  if (method == m_diagonalize)
    do_view(opt2fn_null("-ev",NFILE,fnm),"-nxy");
  do_view(opt2fn("-dist",NFILE,fnm),"-nxy");
  if (bAnalyze) {
    do_view(opt2fn_null("-tr",NFILE,fnm),"-nxy");
    do_view(opt2fn_null("-ntr",NFILE,fnm),"-nxy");
    do_view(opt2fn_null("-clid",NFILE,fnm),"-nxy");
  }
  
  /* Thank the user for her patience */  
  thanx(stderr);
  
  return 0;
}
コード例 #13
0
ファイル: do_shift.c プロジェクト: daniellandau/gromacs
int main(int argc,char *argv[])
{
  static char *desc[] = {
    "[TT]do_shift[tt] reads a trajectory file and computes the chemical",
    "shift for each time frame (or every [BB]dt[bb] ps) by",
    "calling the 'total' program. If you do not have the total program,",
    "get it. do_shift assumes that the total executable is in",
    "[TT]/home/mdgroup/total/total[tt]. If that is not the case, then you should",
    "set an environment variable [BB]TOTAL[bb] as in: [PAR]",
    "[TT]setenv TOTAL /usr/local/bin/total[tt][PAR]",
    "where the right hand side should point to the total executable.[PAR]",
    "Output is printed in files [TT]shift.out[tt] where t is the time of the frame.[PAR]",
    "The program also needs an input file called [BB]random.dat[bb] which",
    "contains the random coil chemical shifts of all protons."
  };
  static real dt=0.0;
  t_pargs pa[] = {
    { "-dt", FALSE, etREAL, { &dt }, "Time interval between frames." }
  };
  static char *bugs[] = {
    "The program is very slow"
  };
  static     char *OXYGEN="O";
  FILE       *out,*tot,*fp;
  t_topology *top;
  t_atoms    *atoms;
  int        status,nres;
  real       t,nt;
  int        i,natoms,nframe=0;
  matrix     box;
  int        gnx;
  char       *grpnm,*randf;
  atom_id    *index;
  rvec       *x,*x_s;
  char       pdbfile[32],tmpfile[32];
  char       total[256],*dptr;
  t_filenm   fnm[] = {
    { efTRX, "-f",   NULL,     ffREAD },
    { efTPX, NULL,   NULL,     ffREAD },
    { efNDX, NULL,   NULL,     ffREAD },
    { efOUT, "-o",   "shift",  ffWRITE },
    { efDAT, "-d",   "random", ffREAD }
  };
  char *leg[] = { "shift","ring","anisCO","anisCN","sigmaE","sum" };
#define NFILE asize(fnm)

  CopyRight(stdout,argv[0]);
  parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_BE_NICE ,NFILE,fnm,
		    asize(pa),pa,asize(desc),desc,asize(bugs),bugs);
		    
  top=read_top(ftp2fn(efTPX,NFILE,fnm));
  atoms=&(top->atoms);
  nres=atoms->nres;
  for(i=0; (i<atoms->nr); i++)
    if ((strcmp(*atoms->atomname[i],"O1") == 0) ||
	(strcmp(*atoms->atomname[i],"O2") == 0) ||
	(strcmp(*atoms->atomname[i],"OXT") == 0) ||
	(strcmp(*atoms->atomname[i],"OT") == 0))
      atoms->atomname[i]=&OXYGEN;
  rd_index(ftp2fn(efNDX,NFILE,fnm),1,&gnx,&index,&grpnm);
  
  snew(x_s,atoms->nr);

  strcpy(pdbfile,"dsXXXXXX");
  gmx_tmpnam(pdbfile);
  strcpy(tmpfile,"dsXXXXXX");
  gmx_tmpnam(tmpfile);
  fprintf(stderr,"pdbfile = %s\ntmpfile = %s\n",pdbfile,tmpfile);
  
  if ((dptr=getenv("TOTAL")) == NULL)
    dptr="/home/mdgroup/total/total";
  sprintf(total,"%s > /dev/null",dptr);
  fprintf(stderr,"total cmd='%s'\n",total);
  randf=ftp2fn(efDAT,NFILE,fnm);
  
  natoms=read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box);
  if (natoms != atoms->nr) 
    gmx_fatal(FARGS,"Trajectory does not match topology!");
  out=ftp2FILE(efOUT,NFILE,fnm,"w");
  xvgr_legend(out,asize(leg),leg);
  nt=t;
  do {
    if (t >= nt) {
      rm_pbc(&(top->idef),top->atoms.nr,box,x,x_s);
      fp=gmx_ffopen(pdbfile,"w");
      write_pdbfile_indexed(fp,"Generated by do_shift",
			    atoms,x_s,box,0,-1,gnx,index);
      gmx_ffclose(fp);
      
      if ((tot=popen(total,"w")) == NULL)
	perror("opening pipe to total");
      fprintf(tot,"%s\n",pdbfile);
      fprintf(tot,"%s\n",tmpfile);
      fprintf(tot,"3\n");
      fprintf(tot,"N\n");
      fprintf(tot,"%s\n",randf);
      fprintf(tot,"N\n");
      fprintf(tot,"N\n");
      if (pclose(tot) != 0)
	perror("closing pipe to total");
      cat(out,tmpfile,t);
      remove(pdbfile);
      remove(tmpfile);
      nt+=dt;
      nframe++;
    }
  } while(read_next_x(status,&t,natoms,x,box));
  close_trj(status);
  gmx_ffclose(out);
  
  gmx_thanx(stderr);
  
  return 0;
}
コード例 #14
0
ファイル: testlr.c プロジェクト: aar2163/GROMACS
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;
}