Esempio n. 1
0
static FILE *rama_file(const char *fn,const char *title,const char *xaxis,
                       const char *yaxis,const output_env_t oenv)
{
  FILE *fp;

  fp = xvgropen(fn,title,xaxis,yaxis,oenv);  
  fprintf(fp,"@ with g0\n");
  xvgr_world(fp,-180,-180,180,180,oenv);
  fprintf(fp,"@ xaxis tick on\n");
  fprintf(fp,"@ xaxis tick major 90\n");
  fprintf(fp,"@ xaxis tick minor 30\n");
  fprintf(fp,"@ xaxis ticklabel prec 0\n");
  fprintf(fp,"@ yaxis tick on\n");
  fprintf(fp,"@ yaxis tick major 90\n");
  fprintf(fp,"@ yaxis tick minor 30\n");
  fprintf(fp,"@ yaxis ticklabel prec 0\n");
  fprintf(fp,"@    s0 type xy\n");
  fprintf(fp,"@    s0 symbol 2\n");
  fprintf(fp,"@    s0 symbol size 0.410000\n");
  fprintf(fp,"@    s0 symbol fill 1\n");
  fprintf(fp,"@    s0 symbol color 1\n");
  fprintf(fp,"@    s0 symbol linewidth 1\n");
  fprintf(fp,"@    s0 symbol linestyle 1\n");
  fprintf(fp,"@    s0 symbol center false\n");
  fprintf(fp,"@    s0 symbol char 0\n");
  fprintf(fp,"@    s0 skip 0\n");
  fprintf(fp,"@    s0 linestyle 0\n");
  fprintf(fp,"@    s0 linewidth 1\n");
  fprintf(fp,"@ type xy\n");
  
  return fp;
}
Esempio n. 2
0
int gmx_rama(int argc,char *argv[])
{
  const char *desc[] = {
    "[TT]g_rama[tt] selects the [GRK]phi[grk]/[GRK]psi[grk] dihedral combinations from your topology file",
    "and computes these as a function of time.",
    "Using simple Unix tools such as [IT]grep[it] you can select out", 
    "specific residues."
  };

  FILE      *out;
  t_xrama   *xr;
  int       j;
  output_env_t oenv;
  t_filenm  fnm[] = {
    { efTRX, "-f", NULL,  ffREAD },
    { efTPX, NULL, NULL,  ffREAD },
    { efXVG, NULL, "rama",ffWRITE }
  };
#define NFILE asize(fnm)

  parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
		    NFILE,fnm,0,NULL,asize(desc),desc,0,NULL,&oenv);

		      
  snew(xr,1);
  init_rama(oenv,ftp2fn(efTRX,NFILE,fnm),ftp2fn(efTPX,NFILE,fnm),xr,3);
  
  out=xvgropen(ftp2fn(efXVG,NFILE,fnm),"Ramachandran Plot","Phi","Psi",oenv);
  xvgr_line_props(out,0,elNone,ecFrank,oenv);
  xvgr_view(out,0.2,0.2,0.8,0.8,oenv);
  xvgr_world(out,-180,-180,180,180,oenv);
  fprintf(out,"@    xaxis  tick on\n@    xaxis  tick major 60\n@    xaxis  tick minor 30\n");
  fprintf(out,"@    yaxis  tick on\n@    yaxis  tick major 60\n@    yaxis  tick minor 30\n");
  fprintf(out,"@ s0 symbol 2\n@ s0 symbol size 0.4\n@ s0 symbol fill 1\n");
  
  j=0;
  do {
    plot_rama(out,xr);
    j++;
  } while (new_data(xr));
  fprintf(stderr,"\n");
  ffclose(out);
  
  do_view(oenv,ftp2fn(efXVG,NFILE,fnm),NULL);
  
  thanx(stderr);
  
  return 0;
}
Esempio n. 3
0
int gmx_polystat(int argc, char *argv[])
{
    const char     *desc[] = {
        "[THISMODULE] plots static properties of polymers as a function of time",
        "and prints the average.[PAR]",
        "By default it determines the average end-to-end distance and radii",
        "of gyration of polymers. It asks for an index group and split this",
        "into molecules. The end-to-end distance is then determined using",
        "the first and the last atom in the index group for each molecules.",
        "For the radius of gyration the total and the three principal components",
        "for the average gyration tensor are written.",
        "With option [TT]-v[tt] the eigenvectors are written.",
        "With option [TT]-pc[tt] also the average eigenvalues of the individual",
        "gyration tensors are written.",
        "With option [TT]-i[tt] the mean square internal distances are",
        "written.[PAR]",
        "With option [TT]-p[tt] the persistence length is determined.",
        "The chosen index group should consist of atoms that are",
        "consecutively bonded in the polymer mainchains.",
        "The persistence length is then determined from the cosine of",
        "the angles between bonds with an index difference that is even,",
        "the odd pairs are not used, because straight polymer backbones",
        "are usually all trans and therefore only every second bond aligns.",
        "The persistence length is defined as number of bonds where",
        "the average cos reaches a value of 1/e. This point is determined",
        "by a linear interpolation of [LOG]<cos>[log]."
    };
    static gmx_bool bMW  = TRUE, bPC = FALSE;
    t_pargs         pa[] = {
        { "-mw", FALSE, etBOOL, {&bMW},
          "Use the mass weighting for radii of gyration" },
        { "-pc", FALSE, etBOOL, {&bPC},
          "Plot average eigenvalues" }
    };

    t_filenm        fnm[] = {
        { efTPR, nullptr, nullptr,  ffREAD  },
        { efTRX, "-f", nullptr,  ffREAD  },
        { efNDX, nullptr, nullptr,  ffOPTRD },
        { efXVG, "-o", "polystat",  ffWRITE },
        { efXVG, "-v", "polyvec", ffOPTWR },
        { efXVG, "-p", "persist",  ffOPTWR },
        { efXVG, "-i", "intdist", ffOPTWR }
    };
#define NFILE asize(fnm)

    t_topology       *top;
    gmx_output_env_t *oenv;
    int               ePBC;
    int               isize, *index, nmol, *molind, mol, nat_min = 0, nat_max = 0;
    char             *grpname;
    t_trxstatus      *status;
    real              t;
    rvec             *x, *bond = nullptr;
    matrix            box;
    int               natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = {0};
    dvec              cm, sum_eig = {0, 0, 0};
    double          **gyr, **gyr_all, eig[DIM], **eigv;
    double            sum_eed2, sum_eed2_tot, sum_gyro, sum_gyro_tot, sum_pers_tot;
    int              *ninp    = nullptr;
    double           *sum_inp = nullptr, pers;
    double           *intd, ymax, ymin;
    double            mmol, m;
    char              title[STRLEN];
    FILE             *out, *outv, *outp, *outi;
    const char       *leg[8] = {
        "end to end", "<R\\sg\\N>",
        "<R\\sg\\N> eig1", "<R\\sg\\N> eig2", "<R\\sg\\N> eig3",
        "<R\\sg\\N eig1>", "<R\\sg\\N eig2>", "<R\\sg\\N eig3>"
    };
    char            **legp, buf[STRLEN];
    gmx_rmpbc_t       gpbc = nullptr;

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

    snew(top, 1);
    ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm),
                        nullptr, box, &natoms, nullptr, nullptr, top);

    fprintf(stderr, "Select a group of polymer mainchain atoms:\n");
    get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm),
              1, &isize, &index, &grpname);

    snew(molind, top->mols.nr+1);
    nmol = 0;
    mol  = -1;
    for (i = 0; i < isize; i++)
    {
        if (i == 0 || index[i] >= top->mols.index[mol+1])
        {
            molind[nmol++] = i;
            do
            {
                mol++;
            }
            while (index[i] >= top->mols.index[mol+1]);
        }
    }
    molind[nmol] = i;
    nat_min      = top->atoms.nr;
    nat_max      = 0;
    for (mol = 0; mol < nmol; mol++)
    {
        nat_min = std::min(nat_min, molind[mol+1]-molind[mol]);
        nat_max = std::max(nat_max, molind[mol+1]-molind[mol]);
    }
    fprintf(stderr, "Group %s consists of %d molecules\n", grpname, nmol);
    fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n",
            nat_min, nat_max);

    sprintf(title, "Size of %d polymers", nmol);
    out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)",
                   oenv);
    xvgr_legend(out, bPC ? 8 : 5, leg, oenv);

    if (opt2bSet("-v", NFILE, fnm))
    {
        outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components",
                        output_env_get_xvgr_tlabel(oenv), "(nm)", oenv);
        snew(legp, DIM*DIM);
        for (d = 0; d < DIM; d++)
        {
            for (d2 = 0; d2 < DIM; d2++)
            {
                sprintf(buf, "eig%d %c", d+1, 'x'+d2);
                legp[d*DIM+d2] = gmx_strdup(buf);
            }
        }
        xvgr_legend(outv, DIM*DIM, (const char**)legp, oenv);
    }
    else
    {
        outv = nullptr;
    }

    if (opt2bSet("-p", NFILE, fnm))
    {
        outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length",
                        output_env_get_xvgr_tlabel(oenv), "bonds", oenv);
        snew(bond, nat_max-1);
        snew(sum_inp, nat_min/2);
        snew(ninp, nat_min/2);
    }
    else
    {
        outp = nullptr;
    }

    if (opt2bSet("-i", NFILE, fnm))
    {
        outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances",
                        "n", "<R\\S2\\N(n)>/n (nm\\S2\\N)", oenv);
        i = index[molind[1]-1] - index[molind[0]]; /* Length of polymer -1 */
        snew(intd, i);
    }
    else
    {
        intd = nullptr;
        outi = nullptr;
    }

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

    snew(gyr, DIM);
    snew(gyr_all, DIM);
    snew(eigv, DIM);
    for (d = 0; d < DIM; d++)
    {
        snew(gyr[d], DIM);
        snew(gyr_all[d], DIM);
        snew(eigv[d], DIM);
    }

    frame        = 0;
    sum_eed2_tot = 0;
    sum_gyro_tot = 0;
    sum_pers_tot = 0;

    gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms);

    do
    {
        gmx_rmpbc(gpbc, natoms, box, x);

        sum_eed2 = 0;
        for (d = 0; d < DIM; d++)
        {
            clear_dvec(gyr_all[d]);
        }

        if (bPC)
        {
            clear_dvec(sum_eig);
        }

        if (outp)
        {
            for (i = 0; i < nat_min/2; i++)
            {
                sum_inp[i] = 0;
                ninp[i]    = 0;
            }
        }

        for (mol = 0; mol < nmol; mol++)
        {
            ind0 = molind[mol];
            ind1 = molind[mol+1];

            /* Determine end to end distance */
            sum_eed2 += distance2(x[index[ind0]], x[index[ind1-1]]);

            /* Determine internal distances */
            if (outi)
            {
                calc_int_dist(intd, x, index[ind0], index[ind1-1]);
            }

            /* Determine the radius of gyration */
            clear_dvec(cm);
            for (d = 0; d < DIM; d++)
            {
                clear_dvec(gyr[d]);
            }
            mmol = 0;

            for (i = ind0; i < ind1; i++)
            {
                a = index[i];
                if (bMW)
                {
                    m = top->atoms.atom[a].m;
                }
                else
                {
                    m = 1;
                }
                mmol += m;
                for (d = 0; d < DIM; d++)
                {
                    cm[d] += m*x[a][d];
                    for (d2 = 0; d2 < DIM; d2++)
                    {
                        gyr[d][d2] += m*x[a][d]*x[a][d2];
                    }
                }
            }
            dsvmul(1/mmol, cm, cm);
            for (d = 0; d < DIM; d++)
            {
                for (d2 = 0; d2 < DIM; d2++)
                {
                    gyr[d][d2]      = gyr[d][d2]/mmol - cm[d]*cm[d2];
                    gyr_all[d][d2] += gyr[d][d2];
                }
            }
            if (bPC)
            {
                gyro_eigen(gyr, eig, eigv, ord);
                for (d = 0; d < DIM; d++)
                {
                    sum_eig[d] += eig[ord[d]];
                }
            }
            if (outp)
            {
                for (i = ind0; i < ind1-1; i++)
                {
                    rvec_sub(x[index[i+1]], x[index[i]], bond[i-ind0]);
                    unitv(bond[i-ind0], bond[i-ind0]);
                }
                for (i = ind0; i < ind1-1; i++)
                {
                    for (j = 0; (i+j < ind1-1 && j < nat_min/2); j += 2)
                    {
                        sum_inp[j] += iprod(bond[i-ind0], bond[i-ind0+j]);
                        ninp[j]++;
                    }
                }
            }
        }
        sum_eed2 /= nmol;

        sum_gyro = 0;
        for (d = 0; d < DIM; d++)
        {
            for (d2 = 0; d2 < DIM; d2++)
            {
                gyr_all[d][d2] /= nmol;
            }
            sum_gyro += gyr_all[d][d];
        }

        gyro_eigen(gyr_all, eig, eigv, ord);

        fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f",
                t*output_env_get_time_factor(oenv),
                std::sqrt(sum_eed2), sqrt(sum_gyro),
                std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), std::sqrt(eig[ord[2]]));
        if (bPC)
        {
            for (d = 0; d < DIM; d++)
            {
                fprintf(out, " %8.4f", std::sqrt(sum_eig[d]/nmol));
            }
        }
        fprintf(out, "\n");

        if (outv)
        {
            fprintf(outv, "%10.3f", t*output_env_get_time_factor(oenv));
            for (d = 0; d < DIM; d++)
            {
                for (d2 = 0; d2 < DIM; d2++)
                {
                    fprintf(outv, " %6.3f", eigv[ord[d]][d2]);
                }
            }
            fprintf(outv, "\n");
        }

        sum_eed2_tot += sum_eed2;
        sum_gyro_tot += sum_gyro;

        if (outp)
        {
            i = -1;
            for (j = 0; j < nat_min/2; j += 2)
            {
                sum_inp[j] /= ninp[j];
                if (i == -1 && sum_inp[j] <= std::exp(-1.0))
                {
                    i = j;
                }
            }
            if (i == -1)
            {
                pers = j;
            }
            else
            {
                /* Do linear interpolation on a log scale */
                pers = i - 2.0
                    + 2.0*(std::log(sum_inp[i-2]) + 1.0)/(std::log(sum_inp[i-2]) - std::log(sum_inp[i]));
            }
            fprintf(outp, "%10.3f %8.4f\n", t*output_env_get_time_factor(oenv), pers);
            sum_pers_tot += pers;
        }

        frame++;
    }
    while (read_next_x(oenv, status, &t, x, box));

    gmx_rmpbc_done(gpbc);

    close_trx(status);

    xvgrclose(out);
    if (outv)
    {
        xvgrclose(outv);
    }
    if (outp)
    {
        xvgrclose(outp);
    }

    sum_eed2_tot /= frame;
    sum_gyro_tot /= frame;
    sum_pers_tot /= frame;
    fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n",
            std::sqrt(sum_eed2_tot));
    fprintf(stdout, "\nAverage radius of gyration:  %.3f (nm)\n",
            std::sqrt(sum_gyro_tot));
    if (opt2bSet("-p", NFILE, fnm))
    {
        fprintf(stdout, "\nAverage persistence length:  %.2f bonds\n",
                sum_pers_tot);
    }

    /* Handle printing of internal distances. */
    if (outi)
    {
        if (output_env_get_print_xvgr_codes(oenv))
        {
            fprintf(outi, "@    xaxes scale Logarithmic\n");
        }
        ymax = -1;
        ymin = 1e300;
        j    = index[molind[1]-1] - index[molind[0]]; /* Polymer length -1. */
        for (i = 0; i < j; i++)
        {
            intd[i] /= (i + 1) * frame * nmol;
            if (intd[i] > ymax)
            {
                ymax = intd[i];
            }
            if (intd[i] < ymin)
            {
                ymin = intd[i];
            }
        }
        xvgr_world(outi, 1, ymin, j, ymax, oenv);
        for (i = 0; i < j; i++)
        {
            fprintf(outi, "%d  %8.4f\n", i+1, intd[i]);
        }
        xvgrclose(outi);
    }

    do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
    if (opt2bSet("-v", NFILE, fnm))
    {
        do_view(oenv, opt2fn("-v", NFILE, fnm), "-nxy");
    }
    if (opt2bSet("-p", NFILE, fnm))
    {
        do_view(oenv, opt2fn("-p", NFILE, fnm), "-nxy");
    }

    return 0;
}
Esempio n. 4
0
static void histogramming(FILE *log,int nbin,gmx_residuetype_t rt,
			  int nf,int maxchi,real **dih,
			  int nlist,t_dlist dlist[],
			  atom_id index[],
			  gmx_bool bPhi,gmx_bool bPsi,gmx_bool bOmega,gmx_bool bChi,
			  gmx_bool bNormalize,gmx_bool bSSHisto,const char *ssdump,
			  real bfac_max,t_atoms *atoms, 
			  gmx_bool bDo_jc, const char *fn,
                          const output_env_t oenv)
{
  /* also gets 3J couplings and order parameters S2 */ 
  t_karplus kkkphi[] = {
    { "J_NHa1",    6.51, -1.76,  1.6, -M_PI/3,   0.0,  0.0 },
    { "J_NHa2",    6.51, -1.76,  1.6,  M_PI/3,   0.0,  0.0 },
    { "J_HaC'",    4.0,   1.1,   0.1,  0.0,      0.0,  0.0 },
    { "J_NHCb",    4.7,  -1.5,  -0.2,  M_PI/3,   0.0,  0.0 },
    { "J_Ci-1Hai", 4.5,  -1.3,  -1.2,  2*M_PI/3, 0.0,  0.0 }
  };
  t_karplus kkkpsi[] = {
    { "J_HaN",   -0.88, -0.61,-0.27,M_PI/3,  0.0,  0.0 }
  };
  t_karplus kkkchi1[] = {
    { "JHaHb2",       9.5, -1.6, 1.8, -M_PI/3, 0,  0.0 },
    { "JHaHb3",       9.5, -1.6, 1.8, 0, 0,  0.0 }
  };
#define NKKKPHI asize(kkkphi)
#define NKKKPSI asize(kkkpsi)
#define NKKKCHI asize(kkkchi1)
#define NJC (NKKKPHI+NKKKPSI+NKKKCHI)
  
  FILE    *fp,*ssfp[3]={NULL,NULL,NULL};
  const char *sss[3] = { "sheet", "helix", "coil" };
  real    S2;
  real    *normhisto;
  real    **Jc,**Jcsig;
  int     ****his_aa_ss=NULL;
  int     ***his_aa,**his_aa1,*histmp;
  int     i,j,k,m,n,nn,Dih,nres,hindex,angle;
  gmx_bool    bBfac,bOccup;
  char    hisfile[256],hhisfile[256],sshisfile[256],title[256],*ss_str=NULL;
  char **leg; 
  const char *residue_name;
  int     rt_size;

  rt_size = gmx_residuetype_get_size(rt);
  if (bSSHisto) {
    fp = ffopen(ssdump,"r");
    if(1 != fscanf(fp,"%d",&nres))
    {
      gmx_fatal(FARGS,"Error reading from file %s",ssdump);
    }

    snew(ss_str,nres+1);
    if( 1 != fscanf(fp,"%s",ss_str))
    {
      gmx_fatal(FARGS,"Error reading from file %s",ssdump);
    }

    ffclose(fp);
    /* Four dimensional array... Very cool */
    snew(his_aa_ss,3);
    for(i=0; (i<3); i++) {
      snew(his_aa_ss[i],rt_size+1);
      for(j=0; (j<=rt_size); j++) {
	snew(his_aa_ss[i][j],edMax);
	for(Dih=0; (Dih<edMax); Dih++)
	  snew(his_aa_ss[i][j][Dih],nbin+1);
      }
    }
  }
  snew(his_aa,edMax);
  for(Dih=0; (Dih<edMax); Dih++) {
    snew(his_aa[Dih],rt_size+1);
    for(i=0; (i<=rt_size); i++) {
      snew(his_aa[Dih][i],nbin+1);
    }
  }
  snew(histmp,nbin);
  
  snew(Jc,nlist);
  snew(Jcsig,nlist);
  for(i=0; (i<nlist); i++) {
    snew(Jc[i],NJC);
    snew(Jcsig[i],NJC);
  }
  
  j=0;
  n=0;
  for (Dih=0; (Dih<NONCHI+maxchi); Dih++) {    
    for(i=0; (i<nlist); i++) {
      if (((Dih  < edOmega) ) ||
	  ((Dih == edOmega) && (has_dihedral(edOmega,&(dlist[i])))) ||
	  ((Dih  > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1))) {
      	make_histo(log,nf,dih[j],nbin,histmp,-M_PI,M_PI);
	
	if (bSSHisto) {
	  /* Assume there is only one structure, the first. 
	   * Compute index in histogram.
	   */
	  /* Check the atoms to see whether their B-factors are low enough 
	   * Check atoms to see their occupancy is 1.
	   */
	  bBfac = bOccup = TRUE;
	  for(nn=0; (nn<4); nn++,n++) {
	    bBfac  = bBfac  && (atoms->pdbinfo[index[n]].bfac <= bfac_max);
	    bOccup = bOccup && (atoms->pdbinfo[index[n]].occup == 1);
	  }
	  if (bOccup && ((bfac_max <= 0) || ((bfac_max > 0) && bBfac))) {
	    hindex = ((dih[j][0]+M_PI)*nbin)/(2*M_PI);
	    range_check(hindex,0,nbin);
	    
	    /* Assign dihedral to either of the structure determined 
	     * histograms
	     */
	    switch(ss_str[dlist[i].resnr]) {
	    case 'E':
	      his_aa_ss[0][dlist[i].index][Dih][hindex]++;
	      break;
	    case 'H':
	      his_aa_ss[1][dlist[i].index][Dih][hindex]++;
	      break;
	    default:
	      his_aa_ss[2][dlist[i].index][Dih][hindex]++;
	      break;
	    }
	  }
	  else if (debug) 
	    fprintf(debug,"Res. %d has imcomplete occupancy or bfacs > %g\n",
		    dlist[i].resnr,bfac_max);
	}
	else
	  n += 4;
	  
	switch (Dih) {
	case edPhi:
	  calc_distribution_props(nbin,histmp,-M_PI,NKKKPHI,kkkphi,&S2);
	  
	  for(m=0; (m<NKKKPHI); m++) {
	    Jc[i][m]    = kkkphi[m].Jc;
	    Jcsig[i][m] = kkkphi[m].Jcsig;
	  }
	  break;
	case edPsi:
	  calc_distribution_props(nbin,histmp,-M_PI,NKKKPSI,kkkpsi,&S2);
	  
	  for(m=0; (m<NKKKPSI); m++) {
	    Jc[i][NKKKPHI+m]    = kkkpsi[m].Jc;
	    Jcsig[i][NKKKPHI+m] = kkkpsi[m].Jcsig;
	  }
	  break;
	case edChi1:
	  calc_distribution_props(nbin,histmp,-M_PI,NKKKCHI,kkkchi1,&S2);
	  for(m=0; (m<NKKKCHI); m++) {
	    Jc[i][NKKKPHI+NKKKPSI+m]    = kkkchi1[m].Jc;
	    Jcsig[i][NKKKPHI+NKKKPSI+m] = kkkchi1[m].Jcsig;
	  }
	  break;
	default: /* covers edOmega and higher Chis than Chi1 */ 
	  calc_distribution_props(nbin,histmp,-M_PI,0,NULL,&S2);
	  break;
	}
	dlist[i].S2[Dih]        = S2;
	
	/* Sum distribution per amino acid type as well */
	for(k=0; (k<nbin); k++) {
	  his_aa[Dih][dlist[i].index][k] += histmp[k];
	  histmp[k] = 0;
	}
	j++;
      } else { /* dihed not defined */
	dlist[i].S2[Dih] = 0.0 ; 
      }
    }
  }
  sfree(histmp);
  
  /* Print out Jcouplings */
  fprintf(log,"\n *** J-Couplings from simulation (plus std. dev.) ***\n\n");
  fprintf(log,"Residue   ");
  for(i=0; (i<NKKKPHI); i++)
    fprintf(log,"%7s   SD",kkkphi[i].name);
  for(i=0; (i<NKKKPSI); i++)
    fprintf(log,"%7s   SD",kkkpsi[i].name);
  for(i=0; (i<NKKKCHI); i++)
    fprintf(log,"%7s   SD",kkkchi1[i].name);
  fprintf(log,"\n");
  for(i=0; (i<NJC+1); i++)
    fprintf(log,"------------");
  fprintf(log,"\n");
  for(i=0; (i<nlist); i++) {
    fprintf(log,"%-10s",dlist[i].name);
    for(j=0; (j<NJC); j++)
      fprintf(log,"  %5.2f %4.2f",Jc[i][j],Jcsig[i][j]);
    fprintf(log,"\n");
  }
  fprintf(log,"\n");

  /* and to -jc file... */ 
  if (bDo_jc) {
    fp=xvgropen(fn,"\\S3\\NJ-Couplings from Karplus Equation","Residue",
                "Coupling",oenv); 
    snew(leg,NJC); 
    for(i=0; (i<NKKKPHI); i++){
		leg[i] = strdup(kkkphi[i].name); 
    }
    for(i=0; (i<NKKKPSI); i++){
		leg[i+NKKKPHI]=strdup(kkkpsi[i].name); 
    }
    for(i=0; (i<NKKKCHI); i++){
      leg[i+NKKKPHI+NKKKPSI]=strdup(kkkchi1[i].name); 
    }      
    xvgr_legend(fp,NJC,(const char**)leg,oenv);
    fprintf(fp,"%5s ","#Res.");
    for(i=0; (i<NJC); i++)
      fprintf(fp,"%10s ",leg[i]); 
    fprintf(fp,"\n"); 
    for(i=0; (i<nlist); i++) {
      fprintf(fp,"%5d ",dlist[i].resnr);
      for(j=0; (j<NJC); j++)
	fprintf(fp,"  %8.3f",Jc[i][j]);
      fprintf(fp,"\n"); 
    }
    ffclose(fp);
    for(i=0; (i<NJC); i++)
      sfree(leg[i]); 
  }
  /* finished -jc stuff */ 

  snew(normhisto,nbin);
  for(i=0; (i<rt_size); i++) {
    for(Dih=0; (Dih<edMax); Dih++){
      /* First check whether something is in there */
      for(j=0; (j<nbin); j++)
	if (his_aa[Dih][i][j] != 0)
	  break;
      if ((j < nbin) &&
	  ((bPhi && (Dih==edPhi)) ||
	   (bPsi && (Dih==edPsi)) ||
	   (bOmega &&(Dih==edOmega)) ||
	   (bChi && (Dih>=edChi1)))) {
	if (bNormalize)
	  normalize_histo(nbin,his_aa[Dih][i],(360.0/nbin),normhisto);
	
	residue_name = gmx_residuetype_get_name(rt,i);
	switch (Dih) {
	case edPhi:
	  sprintf(hisfile,"histo-phi%s",residue_name);
	  sprintf(title,"\\xf\\f{} Distribution for %s",residue_name);
	  break;
	case edPsi:
	  sprintf(hisfile,"histo-psi%s",residue_name);
	  sprintf(title,"\\xy\\f{} Distribution for %s",residue_name);
	  break;
	case edOmega:
	  sprintf(hisfile,"histo-omega%s",residue_name);
	  sprintf(title,"\\xw\\f{} Distribution for %s",residue_name);
	  break;
	default:
	  sprintf(hisfile,"histo-chi%d%s",Dih-NONCHI+1,residue_name);
	  sprintf(title,"\\xc\\f{}\\s%d\\N Distribution for %s",
		  Dih-NONCHI+1,residue_name);
	}
	strcpy(hhisfile,hisfile);
	strcat(hhisfile,".xvg");
	fp=xvgropen(hhisfile,title,"Degrees","",oenv);
	fprintf(fp,"@ with g0\n");
	xvgr_world(fp,-180,0,180,0.1,oenv);
	fprintf(fp,"# this effort to set graph size fails unless you run with -autoscale none or -autoscale y flags\n"); 
	fprintf(fp,"@ xaxis tick on\n");
	fprintf(fp,"@ xaxis tick major 90\n");
	fprintf(fp,"@ xaxis tick minor 30\n");
	fprintf(fp,"@ xaxis ticklabel prec 0\n");
	fprintf(fp,"@ yaxis tick off\n");
	fprintf(fp,"@ yaxis ticklabel off\n");
	fprintf(fp,"@ type xy\n");
	if (bSSHisto) {
	  for(k=0; (k<3); k++) {
	    sprintf(sshisfile,"%s-%s.xvg",hisfile,sss[k]);
	    ssfp[k] = ffopen(sshisfile,"w");
	  }
	}
	for(j=0; (j<nbin); j++) {
	  angle = -180 + (360/nbin)*j ; 
	  if (bNormalize)
	    fprintf(fp,"%5d  %10g\n",angle,normhisto[j]);
	  else
	    fprintf(fp,"%5d  %10d\n",angle,his_aa[Dih][i][j]);
	  if (bSSHisto)
	    for(k=0; (k<3); k++) 
	      fprintf(ssfp[k],"%5d  %10d\n",angle,
		      his_aa_ss[k][i][Dih][j]);
	}
	fprintf(fp,"&\n");
	ffclose(fp);
	if (bSSHisto) {
	  for(k=0; (k<3); k++) {
	    fprintf(ssfp[k],"&\n");
	    ffclose(ssfp[k]);
	  }
	}
      }
    }
  }
  sfree(normhisto);
  
  if (bSSHisto) {
    /* Four dimensional array... Very cool */
    for(i=0; (i<3); i++) {
      for(j=0; (j<=rt_size); j++) {
	for(Dih=0; (Dih<edMax); Dih++)
	  sfree(his_aa_ss[i][j][Dih]);
	sfree(his_aa_ss[i][j]);
      }
      sfree(his_aa_ss[i]);
    }
    sfree(his_aa_ss);
    sfree(ss_str);
  }
}