2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
47 #include "gmx_fatal.h"
67 static gmx_bool bAllowed(real phi, real psi)
69 static const char *map[] = {
70 "1100000000000000001111111000000000001111111111111111111111111",
71 "1100000000000000001111110000000000011111111111111111111111111",
72 "1100000000000000001111110000000000011111111111111111111111111",
73 "1100000000000000001111100000000000111111111111111111111111111",
74 "1100000000000000001111100000000000111111111111111111111111111",
75 "1100000000000000001111100000000001111111111111111111111111111",
76 "1100000000000000001111100000000001111111111111111111111111111",
77 "1100000000000000001111100000000011111111111111111111111111111",
78 "1110000000000000001111110000000111111111111111111111111111111",
79 "1110000000000000001111110000001111111111111111111111111111111",
80 "1110000000000000001111111000011111111111111111111111111111111",
81 "1110000000000000001111111100111111111111111111111111111111111",
82 "1110000000000000001111111111111111111111111111111111111111111",
83 "1110000000000000001111111111111111111111111111111111111111111",
84 "1110000000000000001111111111111111111111111111111111111111111",
85 "1110000000000000001111111111111111111111111111111111111111111",
86 "1110000000000000001111111111111110011111111111111111111111111",
87 "1110000000000000001111111111111100000111111111111111111111111",
88 "1110000000000000001111111111111000000000001111111111111111111",
89 "1100000000000000001111111111110000000000000011111111111111111",
90 "1100000000000000001111111111100000000000000011111111111111111",
91 "1000000000000000001111111111000000000000000001111111111111110",
92 "0000000000000000001111111110000000000000000000111111111111100",
93 "0000000000000000000000000000000000000000000000000000000000000",
94 "0000000000000000000000000000000000000000000000000000000000000",
95 "0000000000000000000000000000000000000000000000000000000000000",
96 "0000000000000000000000000000000000000000000000000000000000000",
97 "0000000000000000000000000000000000000000000000000000000000000",
98 "0000000000000000000000000000000000000000000000000000000000000",
99 "0000000000000000000000000000000000000000000000000000000000000",
100 "0000000000000000000000000000000000000000000000000000000000000",
101 "0000000000000000000000000000000000000000000000000000000000000",
102 "0000000000000000000000000000000000000000000000000000000000000",
103 "0000000000000000000000000000000000000000000000000000000000000",
104 "0000000000000000000000000000000000000000000000000000000000000",
105 "0000000000000000000000000000000000000000000000000000000000000",
106 "0000000000000000000000000000000000000000000000000000000000000",
107 "0000000000000000000000000000000000000000000000000000000000000",
108 "0000000000000000000000000000000000111111111111000000000000000",
109 "1100000000000000000000000000000001111111111111100000000000111",
110 "1100000000000000000000000000000001111111111111110000000000111",
111 "0000000000000000000000000000000000000000000000000000000000000",
112 "0000000000000000000000000000000000000000000000000000000000000",
113 "0000000000000000000000000000000000000000000000000000000000000",
114 "0000000000000000000000000000000000000000000000000000000000000",
115 "0000000000000000000000000000000000000000000000000000000000000",
116 "0000000000000000000000000000000000000000000000000000000000000",
117 "0000000000000000000000000000000000000000000000000000000000000",
118 "0000000000000000000000000000000000000000000000000000000000000",
119 "0000000000000000000000000000000000000000000000000000000000000",
120 "0000000000000000000000000000000000000000000000000000000000000",
121 "0000000000000000000000000000000000000000000000000000000000000",
122 "0000000000000000000000000000000000000000000000000000000000000",
123 "0000000000000000000000000000000000000000000000000000000000000",
124 "0000000000000000000000000000000000000000000000000000000000000",
125 "0000000000000000000000000000000000000000000000000000000000000",
126 "0000000000000000000000000000000000000000000000000000000000000",
127 "0000000000000000000000000000000000000000000000000000000000000",
128 "0000000000000000000000000000000000000000000000000000000000000",
129 "0000000000000000000000000000000000000000000000000000000000000",
130 "0000000000000000000000000000000000000000000000000000000000000"
132 #define NPP asize(map)
135 #define INDEX(ppp) ((((int) (360+ppp*RAD2DEG)) % 360)/6)
139 return (gmx_bool) map[x][y];
142 atom_id *make_chi_ind(int nl, t_dlist dl[], int *ndih)
147 /* There are nl residues with max edMax dihedrals with 4 atoms each */
148 snew(id, nl*edMax*4);
151 for (i = 0; (i < nl); i++)
153 /* Phi, fake the first one */
154 dl[i].j0[edPhi] = n/4;
155 if (dl[i].atm.minC >= 0)
157 id[n++] = dl[i].atm.minC;
161 id[n++] = dl[i].atm.H;
163 id[n++] = dl[i].atm.N;
164 id[n++] = dl[i].atm.Cn[1];
165 id[n++] = dl[i].atm.C;
167 for (i = 0; (i < nl); i++)
169 /* Psi, fake the last one */
170 dl[i].j0[edPsi] = n/4;
171 id[n++] = dl[i].atm.N;
172 id[n++] = dl[i].atm.Cn[1];
173 id[n++] = dl[i].atm.C;
176 id[n++] = dl[i+1].atm.N;
180 id[n++] = dl[i].atm.O;
183 for (i = 1; (i < nl); i++)
186 if (has_dihedral(edOmega, &(dl[i])))
188 dl[i].j0[edOmega] = n/4;
189 id[n++] = dl[i].atm.minCalpha;
190 id[n++] = dl[i].atm.minC;
191 id[n++] = dl[i].atm.N;
192 id[n++] = dl[i].atm.Cn[1];
195 for (Xi = 0; (Xi < MAXCHI); Xi++)
198 for (i = 0; (i < nl); i++)
200 if (dl[i].atm.Cn[Xi+3] != -1)
202 dl[i].j0[edChi1+Xi] = n/4;
203 id[n++] = dl[i].atm.Cn[Xi];
204 id[n++] = dl[i].atm.Cn[Xi+1];
205 id[n++] = dl[i].atm.Cn[Xi+2];
206 id[n++] = dl[i].atm.Cn[Xi+3];
215 int bin(real chi, int mult)
219 return (int) (chi*mult/360.0);
223 static void do_dihcorr(const char *fn, int nf, int ndih, real **dih, real dt,
224 int nlist, t_dlist dlist[], real time[], int maxchi,
225 gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega,
226 const output_env_t oenv)
228 char name1[256], name2[256];
231 do_autocorr(fn, oenv, "Dihedral Autocorrelation Function",
232 nf, ndih, dih, dt, eacCos, FALSE);
235 for (i = 0; (i < nlist); i++)
239 print_one(oenv, "corrphi", dlist[i].name, "Phi ACF for", "C(t)", nf/2, time,
244 for (i = 0; (i < nlist); i++)
248 print_one(oenv, "corrpsi", dlist[i].name, "Psi ACF for", "C(t)", nf/2, time,
253 for (i = 0; (i < nlist); i++)
255 if (has_dihedral(edOmega, &dlist[i]))
259 print_one(oenv, "corromega", dlist[i].name, "Omega ACF for", "C(t)",
265 for (Xi = 0; (Xi < maxchi); Xi++)
267 sprintf(name1, "corrchi%d", Xi+1);
268 sprintf(name2, "Chi%d ACF for", Xi+1);
269 for (i = 0; (i < nlist); i++)
271 if (dlist[i].atm.Cn[Xi+3] != -1)
275 print_one(oenv, name1, dlist[i].name, name2, "C(t)", nf/2, time, dih[j]);
281 fprintf(stderr, "\n");
284 static void copy_dih_data(real in[], real out[], int nf, gmx_bool bLEAVE)
286 /* if bLEAVE, do nothing to data in copying to out
287 * otherwise multiply by 180/pi to convert rad to deg */
298 for (i = 0; (i < nf); i++)
304 static void dump_em_all(int nlist, t_dlist dlist[], int nf, real time[],
305 real **dih, int maxchi,
306 gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega, gmx_bool bRAD,
307 const output_env_t oenv)
309 char name[256], titlestr[256], ystr[256];
316 strcpy(ystr, "Angle (rad)");
320 strcpy(ystr, "Angle (degrees)");
325 for (i = 0; (i < nlist); i++)
327 /* grs debug printf("OK i %d j %d\n", i, j) ; */
330 copy_dih_data(dih[j], data, nf, bRAD);
331 print_one(oenv, "phi", dlist[i].name, "\\xf\\f{}", ystr, nf, time, data);
335 for (i = 0; (i < nlist); i++)
339 copy_dih_data(dih[j], data, nf, bRAD);
340 print_one(oenv, "psi", dlist[i].name, "\\xy\\f{}", ystr, nf, time, data);
344 for (i = 0; (i < nlist); i++)
346 if (has_dihedral(edOmega, &(dlist[i])))
350 copy_dih_data(dih[j], data, nf, bRAD);
351 print_one(oenv, "omega", dlist[i].name, "\\xw\\f{}", ystr, nf, time, data);
357 for (Xi = 0; (Xi < maxchi); Xi++)
359 for (i = 0; (i < nlist); i++)
361 if (dlist[i].atm.Cn[Xi+3] != -1)
365 sprintf(name, "chi%d", Xi+1);
366 sprintf(titlestr, "\\xc\\f{}\\s%d\\N", Xi+1);
367 copy_dih_data(dih[j], data, nf, bRAD);
368 print_one(oenv, name, dlist[i].name, titlestr, ystr, nf, time, data);
374 fprintf(stderr, "\n");
377 static void reset_one(real dih[], int nf, real phase)
381 for (j = 0; (j < nf); j++)
384 while (dih[j] < -M_PI)
388 while (dih[j] >= M_PI)
395 static int reset_em_all(int nlist, t_dlist dlist[], int nf,
396 real **dih, int maxchi)
403 for (i = 0; (i < nlist); i++)
405 if (dlist[i].atm.minC == -1)
407 reset_one(dih[j++], nf, M_PI);
411 reset_one(dih[j++], nf, 0);
415 for (i = 0; (i < nlist-1); i++)
417 reset_one(dih[j++], nf, 0);
419 /* last Psi is faked from O */
420 reset_one(dih[j++], nf, M_PI);
423 for (i = 0; (i < nlist); i++)
425 if (has_dihedral(edOmega, &dlist[i]))
427 reset_one(dih[j++], nf, 0);
430 /* Chi 1 thru maxchi */
431 for (Xi = 0; (Xi < maxchi); Xi++)
433 for (i = 0; (i < nlist); i++)
435 if (dlist[i].atm.Cn[Xi+3] != -1)
437 reset_one(dih[j], nf, 0);
442 fprintf(stderr, "j after resetting (nr. active dihedrals) = %d\n", j);
446 static void histogramming(FILE *log, int nbin, gmx_residuetype_t rt,
447 int nf, int maxchi, real **dih,
448 int nlist, t_dlist dlist[],
450 gmx_bool bPhi, gmx_bool bPsi, gmx_bool bOmega, gmx_bool bChi,
451 gmx_bool bNormalize, gmx_bool bSSHisto, const char *ssdump,
452 real bfac_max, t_atoms *atoms,
453 gmx_bool bDo_jc, const char *fn,
454 const output_env_t oenv)
456 /* also gets 3J couplings and order parameters S2 */
457 t_karplus kkkphi[] = {
458 { "J_NHa1", 6.51, -1.76, 1.6, -M_PI/3, 0.0, 0.0 },
459 { "J_NHa2", 6.51, -1.76, 1.6, M_PI/3, 0.0, 0.0 },
460 { "J_HaC'", 4.0, 1.1, 0.1, 0.0, 0.0, 0.0 },
461 { "J_NHCb", 4.7, -1.5, -0.2, M_PI/3, 0.0, 0.0 },
462 { "J_Ci-1Hai", 4.5, -1.3, -1.2, 2*M_PI/3, 0.0, 0.0 }
464 t_karplus kkkpsi[] = {
465 { "J_HaN", -0.88, -0.61, -0.27, M_PI/3, 0.0, 0.0 }
467 t_karplus kkkchi1[] = {
468 { "JHaHb2", 9.5, -1.6, 1.8, -M_PI/3, 0, 0.0 },
469 { "JHaHb3", 9.5, -1.6, 1.8, 0, 0, 0.0 }
471 #define NKKKPHI asize(kkkphi)
472 #define NKKKPSI asize(kkkpsi)
473 #define NKKKCHI asize(kkkchi1)
474 #define NJC (NKKKPHI+NKKKPSI+NKKKCHI)
476 FILE *fp, *ssfp[3] = {NULL, NULL, NULL};
477 const char *sss[3] = { "sheet", "helix", "coil" };
481 int ****his_aa_ss = NULL;
482 int ***his_aa, **his_aa1, *histmp;
483 int i, j, k, m, n, nn, Dih, nres, hindex, angle;
484 gmx_bool bBfac, bOccup;
485 char hisfile[256], hhisfile[256], sshisfile[256], title[256], *ss_str = NULL;
487 const char *residue_name;
490 rt_size = gmx_residuetype_get_size(rt);
493 fp = ffopen(ssdump, "r");
494 if (1 != fscanf(fp, "%d", &nres))
496 gmx_fatal(FARGS, "Error reading from file %s", ssdump);
499 snew(ss_str, nres+1);
500 if (1 != fscanf(fp, "%s", ss_str))
502 gmx_fatal(FARGS, "Error reading from file %s", ssdump);
506 /* Four dimensional array... Very cool */
508 for (i = 0; (i < 3); i++)
510 snew(his_aa_ss[i], rt_size+1);
511 for (j = 0; (j <= rt_size); j++)
513 snew(his_aa_ss[i][j], edMax);
514 for (Dih = 0; (Dih < edMax); Dih++)
516 snew(his_aa_ss[i][j][Dih], nbin+1);
522 for (Dih = 0; (Dih < edMax); Dih++)
524 snew(his_aa[Dih], rt_size+1);
525 for (i = 0; (i <= rt_size); i++)
527 snew(his_aa[Dih][i], nbin+1);
534 for (i = 0; (i < nlist); i++)
542 for (Dih = 0; (Dih < NONCHI+maxchi); Dih++)
544 for (i = 0; (i < nlist); i++)
546 if (((Dih < edOmega) ) ||
547 ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) ||
548 ((Dih > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1)))
550 make_histo(log, nf, dih[j], nbin, histmp, -M_PI, M_PI);
554 /* Assume there is only one structure, the first.
555 * Compute index in histogram.
557 /* Check the atoms to see whether their B-factors are low enough
558 * Check atoms to see their occupancy is 1.
560 bBfac = bOccup = TRUE;
561 for (nn = 0; (nn < 4); nn++, n++)
563 bBfac = bBfac && (atoms->pdbinfo[index[n]].bfac <= bfac_max);
564 bOccup = bOccup && (atoms->pdbinfo[index[n]].occup == 1);
566 if (bOccup && ((bfac_max <= 0) || ((bfac_max > 0) && bBfac)))
568 hindex = ((dih[j][0]+M_PI)*nbin)/(2*M_PI);
569 range_check(hindex, 0, nbin);
571 /* Assign dihedral to either of the structure determined
574 switch (ss_str[dlist[i].resnr])
577 his_aa_ss[0][dlist[i].index][Dih][hindex]++;
580 his_aa_ss[1][dlist[i].index][Dih][hindex]++;
583 his_aa_ss[2][dlist[i].index][Dih][hindex]++;
589 fprintf(debug, "Res. %d has imcomplete occupancy or bfacs > %g\n",
590 dlist[i].resnr, bfac_max);
601 calc_distribution_props(nbin, histmp, -M_PI, NKKKPHI, kkkphi, &S2);
603 for (m = 0; (m < NKKKPHI); m++)
605 Jc[i][m] = kkkphi[m].Jc;
606 Jcsig[i][m] = kkkphi[m].Jcsig;
610 calc_distribution_props(nbin, histmp, -M_PI, NKKKPSI, kkkpsi, &S2);
612 for (m = 0; (m < NKKKPSI); m++)
614 Jc[i][NKKKPHI+m] = kkkpsi[m].Jc;
615 Jcsig[i][NKKKPHI+m] = kkkpsi[m].Jcsig;
619 calc_distribution_props(nbin, histmp, -M_PI, NKKKCHI, kkkchi1, &S2);
620 for (m = 0; (m < NKKKCHI); m++)
622 Jc[i][NKKKPHI+NKKKPSI+m] = kkkchi1[m].Jc;
623 Jcsig[i][NKKKPHI+NKKKPSI+m] = kkkchi1[m].Jcsig;
626 default: /* covers edOmega and higher Chis than Chi1 */
627 calc_distribution_props(nbin, histmp, -M_PI, 0, NULL, &S2);
630 dlist[i].S2[Dih] = S2;
632 /* Sum distribution per amino acid type as well */
633 for (k = 0; (k < nbin); k++)
635 his_aa[Dih][dlist[i].index][k] += histmp[k];
640 else /* dihed not defined */
642 dlist[i].S2[Dih] = 0.0;
648 /* Print out Jcouplings */
649 fprintf(log, "\n *** J-Couplings from simulation (plus std. dev.) ***\n\n");
650 fprintf(log, "Residue ");
651 for (i = 0; (i < NKKKPHI); i++)
653 fprintf(log, "%7s SD", kkkphi[i].name);
655 for (i = 0; (i < NKKKPSI); i++)
657 fprintf(log, "%7s SD", kkkpsi[i].name);
659 for (i = 0; (i < NKKKCHI); i++)
661 fprintf(log, "%7s SD", kkkchi1[i].name);
664 for (i = 0; (i < NJC+1); i++)
666 fprintf(log, "------------");
669 for (i = 0; (i < nlist); i++)
671 fprintf(log, "%-10s", dlist[i].name);
672 for (j = 0; (j < NJC); j++)
674 fprintf(log, " %5.2f %4.2f", Jc[i][j], Jcsig[i][j]);
680 /* and to -jc file... */
683 fp = xvgropen(fn, "\\S3\\NJ-Couplings from Karplus Equation", "Residue",
686 for (i = 0; (i < NKKKPHI); i++)
688 leg[i] = strdup(kkkphi[i].name);
690 for (i = 0; (i < NKKKPSI); i++)
692 leg[i+NKKKPHI] = strdup(kkkpsi[i].name);
694 for (i = 0; (i < NKKKCHI); i++)
696 leg[i+NKKKPHI+NKKKPSI] = strdup(kkkchi1[i].name);
698 xvgr_legend(fp, NJC, (const char**)leg, oenv);
699 fprintf(fp, "%5s ", "#Res.");
700 for (i = 0; (i < NJC); i++)
702 fprintf(fp, "%10s ", leg[i]);
705 for (i = 0; (i < nlist); i++)
707 fprintf(fp, "%5d ", dlist[i].resnr);
708 for (j = 0; (j < NJC); j++)
710 fprintf(fp, " %8.3f", Jc[i][j]);
715 for (i = 0; (i < NJC); i++)
720 /* finished -jc stuff */
722 snew(normhisto, nbin);
723 for (i = 0; (i < rt_size); i++)
725 for (Dih = 0; (Dih < edMax); Dih++)
727 /* First check whether something is in there */
728 for (j = 0; (j < nbin); j++)
730 if (his_aa[Dih][i][j] != 0)
736 ((bPhi && (Dih == edPhi)) ||
737 (bPsi && (Dih == edPsi)) ||
738 (bOmega && (Dih == edOmega)) ||
739 (bChi && (Dih >= edChi1))))
743 normalize_histo(nbin, his_aa[Dih][i], (360.0/nbin), normhisto);
746 residue_name = gmx_residuetype_get_name(rt, i);
750 sprintf(hisfile, "histo-phi%s", residue_name);
751 sprintf(title, "\\xf\\f{} Distribution for %s", residue_name);
754 sprintf(hisfile, "histo-psi%s", residue_name);
755 sprintf(title, "\\xy\\f{} Distribution for %s", residue_name);
758 sprintf(hisfile, "histo-omega%s", residue_name);
759 sprintf(title, "\\xw\\f{} Distribution for %s", residue_name);
762 sprintf(hisfile, "histo-chi%d%s", Dih-NONCHI+1, residue_name);
763 sprintf(title, "\\xc\\f{}\\s%d\\N Distribution for %s",
764 Dih-NONCHI+1, residue_name);
766 strcpy(hhisfile, hisfile);
767 strcat(hhisfile, ".xvg");
768 fp = xvgropen(hhisfile, title, "Degrees", "", oenv);
769 if (output_env_get_print_xvgr_codes(oenv))
771 fprintf(fp, "@ with g0\n");
773 xvgr_world(fp, -180, 0, 180, 0.1, oenv);
774 if (output_env_get_print_xvgr_codes(oenv))
776 fprintf(fp, "# this effort to set graph size fails unless you run with -autoscale none or -autoscale y flags\n");
777 fprintf(fp, "@ xaxis tick on\n");
778 fprintf(fp, "@ xaxis tick major 90\n");
779 fprintf(fp, "@ xaxis tick minor 30\n");
780 fprintf(fp, "@ xaxis ticklabel prec 0\n");
781 fprintf(fp, "@ yaxis tick off\n");
782 fprintf(fp, "@ yaxis ticklabel off\n");
783 fprintf(fp, "@ type xy\n");
787 for (k = 0; (k < 3); k++)
789 sprintf(sshisfile, "%s-%s.xvg", hisfile, sss[k]);
790 ssfp[k] = ffopen(sshisfile, "w");
793 for (j = 0; (j < nbin); j++)
795 angle = -180 + (360/nbin)*j;
798 fprintf(fp, "%5d %10g\n", angle, normhisto[j]);
802 fprintf(fp, "%5d %10d\n", angle, his_aa[Dih][i][j]);
806 for (k = 0; (k < 3); k++)
808 fprintf(ssfp[k], "%5d %10d\n", angle,
809 his_aa_ss[k][i][Dih][j]);
813 fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : "");
817 for (k = 0; (k < 3); k++)
819 fprintf(ssfp[k], "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : "");
830 /* Four dimensional array... Very cool */
831 for (i = 0; (i < 3); i++)
833 for (j = 0; (j <= rt_size); j++)
835 for (Dih = 0; (Dih < edMax); Dih++)
837 sfree(his_aa_ss[i][j][Dih]);
839 sfree(his_aa_ss[i][j]);
848 static FILE *rama_file(const char *fn, const char *title, const char *xaxis,
849 const char *yaxis, const output_env_t oenv)
853 fp = xvgropen(fn, title, xaxis, yaxis, oenv);
854 if (output_env_get_print_xvgr_codes(oenv))
856 fprintf(fp, "@ with g0\n");
858 xvgr_world(fp, -180, -180, 180, 180, oenv);
859 if (output_env_get_print_xvgr_codes(oenv))
861 fprintf(fp, "@ xaxis tick on\n");
862 fprintf(fp, "@ xaxis tick major 90\n");
863 fprintf(fp, "@ xaxis tick minor 30\n");
864 fprintf(fp, "@ xaxis ticklabel prec 0\n");
865 fprintf(fp, "@ yaxis tick on\n");
866 fprintf(fp, "@ yaxis tick major 90\n");
867 fprintf(fp, "@ yaxis tick minor 30\n");
868 fprintf(fp, "@ yaxis ticklabel prec 0\n");
869 fprintf(fp, "@ s0 type xy\n");
870 fprintf(fp, "@ s0 symbol 2\n");
871 fprintf(fp, "@ s0 symbol size 0.410000\n");
872 fprintf(fp, "@ s0 symbol fill 1\n");
873 fprintf(fp, "@ s0 symbol color 1\n");
874 fprintf(fp, "@ s0 symbol linewidth 1\n");
875 fprintf(fp, "@ s0 symbol linestyle 1\n");
876 fprintf(fp, "@ s0 symbol center false\n");
877 fprintf(fp, "@ s0 symbol char 0\n");
878 fprintf(fp, "@ s0 skip 0\n");
879 fprintf(fp, "@ s0 linestyle 0\n");
880 fprintf(fp, "@ s0 linewidth 1\n");
881 fprintf(fp, "@ type xy\n");
886 static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih,
887 gmx_bool bViol, gmx_bool bRamOmega, const output_env_t oenv)
889 FILE *fp, *gp = NULL;
892 int i, j, k, Xi1, Xi2, Phi, Psi, Om = 0, nlevels;
894 real **mat = NULL, phi, psi, omega, axis[NMAT], lo, hi;
895 t_rgb rlo = { 1.0, 0.0, 0.0 };
896 t_rgb rmid = { 1.0, 1.0, 1.0 };
897 t_rgb rhi = { 0.0, 0.0, 1.0 };
899 for (i = 0; (i < nlist); i++)
901 if ((has_dihedral(edPhi, &(dlist[i]))) &&
902 (has_dihedral(edPsi, &(dlist[i]))))
904 sprintf(fn, "ramaPhiPsi%s.xvg", dlist[i].name);
905 fp = rama_file(fn, "Ramachandran Plot",
906 "\\8f\\4 (deg)", "\\8y\\4 (deg)", oenv);
907 bOm = bRamOmega && has_dihedral(edOmega, &(dlist[i]));
910 Om = dlist[i].j0[edOmega];
912 for (j = 0; (j < NMAT); j++)
915 axis[j] = -180+(360*j)/NMAT;
920 sprintf(fn, "violPhiPsi%s.xvg", dlist[i].name);
921 gp = ffopen(fn, "w");
923 Phi = dlist[i].j0[edPhi];
924 Psi = dlist[i].j0[edPsi];
925 for (j = 0; (j < nf); j++)
927 phi = RAD2DEG*dih[Phi][j];
928 psi = RAD2DEG*dih[Psi][j];
929 fprintf(fp, "%10g %10g\n", phi, psi);
932 fprintf(gp, "%d\n", !bAllowed(dih[Phi][j], RAD2DEG*dih[Psi][j]));
936 omega = RAD2DEG*dih[Om][j];
937 mat[(int)((phi*NMAT)/360)+NMAT/2][(int)((psi*NMAT)/360)+NMAT/2]
948 sprintf(fn, "ramomega%s.xpm", dlist[i].name);
949 fp = ffopen(fn, "w");
951 for (j = 0; (j < NMAT); j++)
953 for (k = 0; (k < NMAT); k++)
956 lo = min(mat[j][k], lo);
957 hi = max(mat[j][k], hi);
961 if (fabs(lo) > fabs(hi))
970 for (j = 0; (j < NMAT); j++)
972 for (k = 0; (k < NMAT); k++)
980 write_xpm3(fp, 0, "Omega/Ramachandran Plot", "Deg", "Phi", "Psi",
981 NMAT, NMAT, axis, axis, mat, lo, 180.0, hi, rlo, rmid, rhi, &nlevels);
983 for (j = 0; (j < NMAT); j++)
990 if ((has_dihedral(edChi1, &(dlist[i]))) &&
991 (has_dihedral(edChi2, &(dlist[i]))))
993 sprintf(fn, "ramaX1X2%s.xvg", dlist[i].name);
994 fp = rama_file(fn, "\\8c\\4\\s1\\N-\\8c\\4\\s2\\N Ramachandran Plot",
995 "\\8c\\4\\s1\\N (deg)", "\\8c\\4\\s2\\N (deg)", oenv);
996 Xi1 = dlist[i].j0[edChi1];
997 Xi2 = dlist[i].j0[edChi2];
998 for (j = 0; (j < nf); j++)
1000 fprintf(fp, "%10g %10g\n", RAD2DEG*dih[Xi1][j], RAD2DEG*dih[Xi2][j]);
1006 fprintf(stderr, "No chi1 & chi2 angle for %s\n", dlist[i].name);
1012 static void print_transitions(const char *fn, int maxchi, int nlist,
1013 t_dlist dlist[], t_atoms *atoms, rvec x[],
1014 matrix box, gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, real dt,
1015 const output_env_t oenv)
1017 /* based on order_params below */
1022 /* must correspond with enum in pp2shift.h:38 */
1024 #define NLEG asize(leg)
1026 leg[0] = strdup("Phi");
1027 leg[1] = strdup("Psi");
1028 leg[2] = strdup("Omega");
1029 leg[3] = strdup("Chi1");
1030 leg[4] = strdup("Chi2");
1031 leg[5] = strdup("Chi3");
1032 leg[6] = strdup("Chi4");
1033 leg[7] = strdup("Chi5");
1034 leg[8] = strdup("Chi6");
1036 /* Print order parameters */
1037 fp = xvgropen(fn, "Dihedral Rotamer Transitions", "Residue", "Transitions/ns",
1039 xvgr_legend(fp, NONCHI+maxchi, (const char**)leg, oenv);
1041 for (Dih = 0; (Dih < edMax); Dih++)
1046 fprintf(fp, "%5s ", "#Res.");
1047 fprintf(fp, "%10s %10s %10s ", leg[edPhi], leg[edPsi], leg[edOmega]);
1048 for (Xi = 0; Xi < maxchi; Xi++)
1050 fprintf(fp, "%10s ", leg[NONCHI+Xi]);
1054 for (i = 0; (i < nlist); i++)
1056 fprintf(fp, "%5d ", dlist[i].resnr);
1057 for (Dih = 0; (Dih < NONCHI+maxchi); Dih++)
1059 fprintf(fp, "%10.3f ", dlist[i].ntr[Dih]/dt);
1061 /* fprintf(fp,"%12s\n",dlist[i].name); this confuses xmgrace */
1067 static void order_params(FILE *log,
1068 const char *fn, int maxchi, int nlist, t_dlist dlist[],
1069 const char *pdbfn, real bfac_init,
1070 t_atoms *atoms, rvec x[], int ePBC, matrix box,
1071 gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, const output_env_t oenv)
1079 /* except for S2Min/Max, must correspond with enum in pp2shift.h:38 */
1080 const char *const_leg[2+edMax] = {
1081 "S2Min", "S2Max", "Phi", "Psi", "Omega",
1082 "Chi1", "Chi2", "Chi3", "Chi4", "Chi5",
1085 #define NLEG asize(leg)
1089 for (i = 0; i < NLEG; i++)
1091 leg[i] = strdup(const_leg[i]);
1094 /* Print order parameters */
1095 fp = xvgropen(fn, "Dihedral Order Parameters", "Residue", "S2", oenv);
1096 xvgr_legend(fp, 2+NONCHI+maxchi, const_leg, oenv);
1098 for (Dih = 0; (Dih < edMax); Dih++)
1103 fprintf(fp, "%5s ", "#Res.");
1104 fprintf(fp, "%10s %10s ", leg[0], leg[1]);
1105 fprintf(fp, "%10s %10s %10s ", leg[2+edPhi], leg[2+edPsi], leg[2+edOmega]);
1106 for (Xi = 0; Xi < maxchi; Xi++)
1108 fprintf(fp, "%10s ", leg[2+NONCHI+Xi]);
1112 for (i = 0; (i < nlist); i++)
1116 for (Dih = 0; (Dih < NONCHI+maxchi); Dih++)
1118 if (dlist[i].S2[Dih] != 0)
1120 if (dlist[i].S2[Dih] > S2Max)
1122 S2Max = dlist[i].S2[Dih];
1124 if (dlist[i].S2[Dih] < S2Min)
1126 S2Min = dlist[i].S2[Dih];
1129 if (dlist[i].S2[Dih] > 0.8)
1134 fprintf(fp, "%5d ", dlist[i].resnr);
1135 fprintf(fp, "%10.3f %10.3f ", S2Min, S2Max);
1136 for (Dih = 0; (Dih < NONCHI+maxchi); Dih++)
1138 fprintf(fp, "%10.3f ", dlist[i].S2[Dih]);
1141 /* fprintf(fp,"%12s\n",dlist[i].name); this confuses xmgrace */
1149 if (NULL == atoms->pdbinfo)
1151 snew(atoms->pdbinfo, atoms->nr);
1153 for (i = 0; (i < atoms->nr); i++)
1155 atoms->pdbinfo[i].bfac = bfac_init;
1158 for (i = 0; (i < nlist); i++)
1160 atoms->pdbinfo[dlist[i].atm.N].bfac = -dlist[i].S2[0]; /* Phi */
1161 atoms->pdbinfo[dlist[i].atm.H].bfac = -dlist[i].S2[0]; /* Phi */
1162 atoms->pdbinfo[dlist[i].atm.C].bfac = -dlist[i].S2[1]; /* Psi */
1163 atoms->pdbinfo[dlist[i].atm.O].bfac = -dlist[i].S2[1]; /* Psi */
1164 for (Xi = 0; (Xi < maxchi); Xi++) /* Chi's */
1166 if (dlist[i].atm.Cn[Xi+3] != -1)
1168 atoms->pdbinfo[dlist[i].atm.Cn[Xi+1]].bfac = -dlist[i].S2[NONCHI+Xi];
1173 fp = ffopen(pdbfn, "w");
1174 fprintf(fp, "REMARK generated by g_chi\n");
1175 fprintf(fp, "REMARK "
1176 "B-factor field contains negative of dihedral order parameters\n");
1177 write_pdbfile(fp, NULL, atoms, x, ePBC, box, ' ', 0, NULL, TRUE);
1178 x0 = y0 = z0 = 1000.0;
1179 for (i = 0; (i < atoms->nr); i++)
1181 x0 = min(x0, x[i][XX]);
1182 y0 = min(y0, x[i][YY]);
1183 z0 = min(z0, x[i][ZZ]);
1185 x0 *= 10.0; /* nm -> angstrom */
1186 y0 *= 10.0; /* nm -> angstrom */
1187 z0 *= 10.0; /* nm -> angstrom */
1188 sprintf(buf, "%s%%6.f%%6.2f\n", pdbformat);
1189 for (i = 0; (i < 10); i++)
1191 fprintf(fp, buf, "ATOM ", atoms->nr+1+i, "CA", "LEG", ' ',
1192 atoms->nres+1, ' ', x0, y0, z0+(1.2*i), 0.0, -0.1*i);
1197 fprintf(log, "Dihedrals with S2 > 0.8\n");
1198 fprintf(log, "Dihedral: ");
1201 fprintf(log, " Phi ");
1205 fprintf(log, " Psi ");
1209 for (Xi = 0; (Xi < maxchi); Xi++)
1211 fprintf(log, " %s ", leg[2+NONCHI+Xi]);
1214 fprintf(log, "\nNumber: ");
1217 fprintf(log, "%4d ", nh[0]);
1221 fprintf(log, "%4d ", nh[1]);
1225 for (Xi = 0; (Xi < maxchi); Xi++)
1227 fprintf(log, "%4d ", nh[NONCHI+Xi]);
1232 for (i = 0; i < NLEG; i++)
1239 int gmx_chi(int argc, char *argv[])
1241 const char *desc[] = {
1242 "[TT]g_chi[tt] computes [GRK]phi[grk], [GRK]psi[grk], [GRK]omega[grk], and [GRK]chi[grk] dihedrals for all your ",
1243 "amino acid backbone and sidechains.",
1244 "It can compute dihedral angle as a function of time, and as",
1245 "histogram distributions.",
1246 "The distributions [TT](histo-(dihedral)(RESIDUE).xvg[tt]) are cumulative over all residues of each type.[PAR]",
1247 "If option [TT]-corr[tt] is given, the program will",
1248 "calculate dihedral autocorrelation functions. The function used",
1249 "is C(t) = [CHEVRON][COS][GRK]chi[grk]([GRK]tau[grk])[cos] [COS][GRK]chi[grk]([GRK]tau[grk]+t)[cos][chevron]. The use of cosines",
1250 "rather than angles themselves, resolves the problem of periodicity.",
1251 "(Van der Spoel & Berendsen (1997), Biophys. J. 72, 2032-2041).",
1252 "Separate files for each dihedral of each residue",
1253 "[TT](corr(dihedral)(RESIDUE)(nresnr).xvg[tt]) are output, as well as a",
1254 "file containing the information for all residues (argument of [TT]-corr[tt]).[PAR]",
1255 "With option [TT]-all[tt], the angles themselves as a function of time for",
1256 "each residue are printed to separate files [TT](dihedral)(RESIDUE)(nresnr).xvg[tt].",
1257 "These can be in radians or degrees.[PAR]",
1258 "A log file (argument [TT]-g[tt]) is also written. This contains [BR]",
1259 "(a) information about the number of residues of each type.[BR]",
1260 "(b) The NMR ^3J coupling constants from the Karplus equation.[BR]",
1261 "(c) a table for each residue of the number of transitions between ",
1262 "rotamers per nanosecond, and the order parameter S^2 of each dihedral.[BR]",
1263 "(d) a table for each residue of the rotamer occupancy.[PAR]",
1264 "All rotamers are taken as 3-fold, except for [GRK]omega[grk] and [GRK]chi[grk] dihedrals",
1265 "to planar groups (i.e. [GRK]chi[grk][SUB]2[sub] of aromatics, Asp and Asn; [GRK]chi[grk][SUB]3[sub] of Glu",
1266 "and Gln; and [GRK]chi[grk][SUB]4[sub] of Arg), which are 2-fold. \"rotamer 0\" means ",
1267 "that the dihedral was not in the core region of each rotamer. ",
1268 "The width of the core region can be set with [TT]-core_rotamer[tt][PAR]",
1270 "The S^2 order parameters are also output to an [TT].xvg[tt] file",
1271 "(argument [TT]-o[tt] ) and optionally as a [TT].pdb[tt] file with",
1272 "the S^2 values as B-factor (argument [TT]-p[tt]). ",
1273 "The total number of rotamer transitions per timestep",
1274 "(argument [TT]-ot[tt]), the number of transitions per rotamer",
1275 "(argument [TT]-rt[tt]), and the ^3J couplings (argument [TT]-jc[tt]), ",
1276 "can also be written to [TT].xvg[tt] files. Note that the analysis",
1277 "of rotamer transitions assumes that the supplied trajectory frames",
1278 "are equally spaced in time.[PAR]",
1280 "If [TT]-chi_prod[tt] is set (and [TT]-maxchi[tt] > 0), cumulative rotamers, e.g.",
1281 "1+9([GRK]chi[grk][SUB]1[sub]-1)+3([GRK]chi[grk][SUB]2[sub]-1)+([GRK]chi[grk][SUB]3[sub]-1) (if the residue has three 3-fold ",
1282 "dihedrals and [TT]-maxchi[tt] >= 3)",
1283 "are calculated. As before, if any dihedral is not in the core region,",
1284 "the rotamer is taken to be 0. The occupancies of these cumulative ",
1285 "rotamers (starting with rotamer 0) are written to the file",
1286 "that is the argument of [TT]-cp[tt], and if the [TT]-all[tt] flag",
1287 "is given, the rotamers as functions of time",
1288 "are written to [TT]chiproduct(RESIDUE)(nresnr).xvg[tt] ",
1289 "and their occupancies to [TT]histo-chiproduct(RESIDUE)(nresnr).xvg[tt].[PAR]",
1291 "The option [TT]-r[tt] generates a contour plot of the average [GRK]omega[grk] angle",
1292 "as a function of the [GRK]phi[grk] and [GRK]psi[grk] angles, that is, in a Ramachandran plot",
1293 "the average [GRK]omega[grk] angle is plotted using color coding.",
1297 const char *bugs[] = {
1298 "Produces MANY output files (up to about 4 times the number of residues in the protein, twice that if autocorrelation functions are calculated). Typically several hundred files are output.",
1299 "[GRK]phi[grk] and [GRK]psi[grk] dihedrals are calculated in a non-standard way, using H-N-CA-C for [GRK]phi[grk] instead of C(-)-N-CA-C, and N-CA-C-O for [GRK]psi[grk] instead of N-CA-C-N(+). This causes (usually small) discrepancies with the output of other tools like [TT]g_rama[tt].",
1300 "[TT]-r0[tt] option does not work properly",
1301 "Rotamers with multiplicity 2 are printed in [TT]chi.log[tt] as if they had multiplicity 3, with the 3rd (g(+)) always having probability 0"
1305 static int r0 = 1, ndeg = 1, maxchi = 2;
1306 static gmx_bool bAll = FALSE;
1307 static gmx_bool bPhi = FALSE, bPsi = FALSE, bOmega = FALSE;
1308 static real bfac_init = -1.0, bfac_max = 0;
1309 static const char *maxchistr[] = { NULL, "0", "1", "2", "3", "4", "5", "6", NULL };
1310 static gmx_bool bRama = FALSE, bShift = FALSE, bViol = FALSE, bRamOmega = FALSE;
1311 static gmx_bool bNormHisto = TRUE, bChiProduct = FALSE, bHChi = FALSE, bRAD = FALSE, bPBC = TRUE;
1312 static real core_frac = 0.5;
1314 { "-r0", FALSE, etINT, {&r0},
1315 "starting residue" },
1316 { "-phi", FALSE, etBOOL, {&bPhi},
1317 "Output for [GRK]phi[grk] dihedral angles" },
1318 { "-psi", FALSE, etBOOL, {&bPsi},
1319 "Output for [GRK]psi[grk] dihedral angles" },
1320 { "-omega", FALSE, etBOOL, {&bOmega},
1321 "Output for [GRK]omega[grk] dihedrals (peptide bonds)" },
1322 { "-rama", FALSE, etBOOL, {&bRama},
1323 "Generate [GRK]phi[grk]/[GRK]psi[grk] and [GRK]chi[grk][SUB]1[sub]/[GRK]chi[grk][SUB]2[sub] Ramachandran plots" },
1324 { "-viol", FALSE, etBOOL, {&bViol},
1325 "Write a file that gives 0 or 1 for violated Ramachandran angles" },
1326 { "-periodic", FALSE, etBOOL, {&bPBC},
1327 "Print dihedral angles modulo 360 degrees" },
1328 { "-all", FALSE, etBOOL, {&bAll},
1329 "Output separate files for every dihedral." },
1330 { "-rad", FALSE, etBOOL, {&bRAD},
1331 "in angle vs time files, use radians rather than degrees."},
1332 { "-shift", FALSE, etBOOL, {&bShift},
1333 "Compute chemical shifts from [GRK]phi[grk]/[GRK]psi[grk] angles" },
1334 { "-binwidth", FALSE, etINT, {&ndeg},
1335 "bin width for histograms (degrees)" },
1336 { "-core_rotamer", FALSE, etREAL, {&core_frac},
1337 "only the central [TT]-core_rotamer[tt]*(360/multiplicity) belongs to each rotamer (the rest is assigned to rotamer 0)" },
1338 { "-maxchi", FALSE, etENUM, {maxchistr},
1339 "calculate first ndih [GRK]chi[grk] dihedrals" },
1340 { "-normhisto", FALSE, etBOOL, {&bNormHisto},
1341 "Normalize histograms" },
1342 { "-ramomega", FALSE, etBOOL, {&bRamOmega},
1343 "compute average omega as a function of [GRK]phi[grk]/[GRK]psi[grk] and plot it in an [TT].xpm[tt] plot" },
1344 { "-bfact", FALSE, etREAL, {&bfac_init},
1345 "B-factor value for [TT].pdb[tt] file for atoms with no calculated dihedral order parameter"},
1346 { "-chi_prod", FALSE, etBOOL, {&bChiProduct},
1347 "compute a single cumulative rotamer for each residue"},
1348 { "-HChi", FALSE, etBOOL, {&bHChi},
1349 "Include dihedrals to sidechain hydrogens"},
1350 { "-bmax", FALSE, etREAL, {&bfac_max},
1351 "Maximum B-factor on any of the atoms that make up a dihedral, for the dihedral angle to be considere in the statistics. Applies to database work where a number of X-Ray structures is analyzed. [TT]-bmax[tt] <= 0 means no limit." }
1355 int natoms, nlist, idum, nbin;
1360 char title[256], grpname[256];
1362 gmx_bool bChi, bCorr, bSSHisto;
1363 gmx_bool bDo_rt, bDo_oh, bDo_ot, bDo_jc;
1364 real dt = 0, traj_t_ns;
1366 gmx_residuetype_t rt;
1368 atom_id isize, *index;
1369 int ndih, nactdih, nf;
1370 real **dih, *trans_frac, *aver_angle, *time;
1371 int i, j, **chi_lookup, *multiplicity;
1374 { efSTX, "-s", NULL, ffREAD },
1375 { efTRX, "-f", NULL, ffREAD },
1376 { efXVG, "-o", "order", ffWRITE },
1377 { efPDB, "-p", "order", ffOPTWR },
1378 { efDAT, "-ss", "ssdump", ffOPTRD },
1379 { efXVG, "-jc", "Jcoupling", ffWRITE },
1380 { efXVG, "-corr", "dihcorr", ffOPTWR },
1381 { efLOG, "-g", "chi", ffWRITE },
1382 /* add two more arguments copying from g_angle */
1383 { efXVG, "-ot", "dihtrans", ffOPTWR },
1384 { efXVG, "-oh", "trhisto", ffOPTWR },
1385 { efXVG, "-rt", "restrans", ffOPTWR },
1386 { efXVG, "-cp", "chiprodhisto", ffOPTWR }
1388 #define NFILE asize(fnm)
1392 CopyRight(stderr, argv[0]);
1394 ppa = add_acf_pargs(&npargs, pa);
1395 parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE,
1396 NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs,
1399 /* Handle result from enumerated type */
1400 sscanf(maxchistr[0], "%d", &maxchi);
1401 bChi = (maxchi > 0);
1403 log = ffopen(ftp2fn(efLOG, NFILE, fnm), "w");
1412 /* set some options */
1413 bDo_rt = (opt2bSet("-rt", NFILE, fnm));
1414 bDo_oh = (opt2bSet("-oh", NFILE, fnm));
1415 bDo_ot = (opt2bSet("-ot", NFILE, fnm));
1416 bDo_jc = (opt2bSet("-jc", NFILE, fnm));
1417 bCorr = (opt2bSet("-corr", NFILE, fnm));
1420 fprintf(stderr, "Will calculate autocorrelation\n");
1423 if (core_frac > 1.0)
1425 fprintf(stderr, "core_rotamer fraction > 1.0 ; will use 1.0\n");
1428 if (core_frac < 0.0)
1430 fprintf(stderr, "core_rotamer fraction < 0.0 ; will use 0.0\n");
1434 if (maxchi > MAXCHI)
1437 "Will only calculate first %d Chi dihedrals in stead of %d.\n",
1441 bSSHisto = ftp2bSet(efDAT, NFILE, fnm);
1444 /* Find the chi angles using atoms struct and a list of amino acids */
1445 get_stx_coordnum(ftp2fn(efSTX, NFILE, fnm), &natoms);
1446 init_t_atoms(&atoms, natoms, TRUE);
1448 read_stx_conf(ftp2fn(efSTX, NFILE, fnm), title, &atoms, x, NULL, &ePBC, box);
1449 fprintf(log, "Title: %s\n", title);
1451 gmx_residuetype_init(&rt);
1452 dlist = mk_dlist(log, &atoms, &nlist, bPhi, bPsi, bChi, bHChi, maxchi, r0, rt);
1453 fprintf(stderr, "%d residues with dihedrals found\n", nlist);
1457 gmx_fatal(FARGS, "No dihedrals in your structure!\n");
1460 /* Make a linear index for reading all. */
1461 index = make_chi_ind(nlist, dlist, &ndih);
1463 fprintf(stderr, "%d dihedrals found\n", ndih);
1467 /* COMPUTE ALL DIHEDRALS! */
1468 read_ang_dih(ftp2fn(efTRX, NFILE, fnm), FALSE, TRUE, FALSE, bPBC, 1, &idum,
1469 &nf, &time, isize, index, &trans_frac, &aver_angle, dih, oenv);
1471 dt = (time[nf-1]-time[0])/(nf-1); /* might want this for corr or n. transit*/
1476 gmx_fatal(FARGS, "Need at least 2 frames for correlation");
1480 /* put angles in -M_PI to M_PI ! and correct phase factor for phi and psi
1481 * pass nactdih instead of ndih to low_ana_dih_trans and get_chi_product_traj
1482 * to prevent accessing off end of arrays when maxchi < 5 or 6. */
1483 nactdih = reset_em_all(nlist, dlist, nf, dih, maxchi);
1487 dump_em_all(nlist, dlist, nf, time, dih, maxchi, bPhi, bPsi, bChi, bOmega, bRAD, oenv);
1490 /* Histogramming & J coupling constants & calc of S2 order params */
1491 histogramming(log, nbin, rt, nf, maxchi, dih, nlist, dlist, index,
1492 bPhi, bPsi, bOmega, bChi,
1493 bNormHisto, bSSHisto, ftp2fn(efDAT, NFILE, fnm), bfac_max, &atoms,
1494 bDo_jc, opt2fn("-jc", NFILE, fnm), oenv);
1498 * added multiplicity */
1500 snew(multiplicity, ndih);
1501 mk_multiplicity_lookup(multiplicity, maxchi, dih, nlist, dlist, ndih);
1503 strcpy(grpname, "All residues, ");
1506 strcat(grpname, "Phi ");
1510 strcat(grpname, "Psi ");
1514 strcat(grpname, "Omega ");
1518 strcat(grpname, "Chi 1-");
1519 sprintf(grpname + strlen(grpname), "%i", maxchi);
1523 low_ana_dih_trans(bDo_ot, opt2fn("-ot", NFILE, fnm),
1524 bDo_oh, opt2fn("-oh", NFILE, fnm), maxchi,
1525 dih, nlist, dlist, nf, nactdih, grpname, multiplicity,
1526 time, FALSE, core_frac, oenv);
1528 /* Order parameters */
1529 order_params(log, opt2fn("-o", NFILE, fnm), maxchi, nlist, dlist,
1530 ftp2fn_null(efPDB, NFILE, fnm), bfac_init,
1531 &atoms, x, ePBC, box, bPhi, bPsi, bChi, oenv);
1533 /* Print ramachandran maps! */
1536 do_rama(nf, nlist, dlist, dih, bViol, bRamOmega, oenv);
1541 do_pp2shifts(log, nf, nlist, dlist, dih);
1544 /* rprint S^2, transitions, and rotamer occupancies to log */
1545 traj_t_ns = 0.001 * (time[nf-1]-time[0]);
1546 pr_dlist(log, nlist, dlist, traj_t_ns, edPrintST, bPhi, bPsi, bChi, bOmega, maxchi);
1547 pr_dlist(log, nlist, dlist, traj_t_ns, edPrintRO, bPhi, bPsi, bChi, bOmega, maxchi);
1549 /* transitions to xvg */
1552 print_transitions(opt2fn("-rt", NFILE, fnm), maxchi, nlist, dlist,
1553 &atoms, x, box, bPhi, bPsi, bChi, traj_t_ns, oenv);
1556 /* chi_product trajectories (ie one "rotamer number" for each residue) */
1557 if (bChiProduct && bChi)
1559 snew(chi_lookup, nlist);
1560 for (i = 0; i < nlist; i++)
1562 snew(chi_lookup[i], maxchi);
1564 mk_chi_lookup(chi_lookup, maxchi, dih, nlist, dlist);
1566 get_chi_product_traj(dih, nf, nactdih, nlist,
1567 maxchi, dlist, time, chi_lookup, multiplicity,
1568 FALSE, bNormHisto, core_frac, bAll,
1569 opt2fn("-cp", NFILE, fnm), oenv);
1571 for (i = 0; i < nlist; i++)
1573 sfree(chi_lookup[i]);
1577 /* Correlation comes last because it fucks up the angles */
1580 do_dihcorr(opt2fn("-corr", NFILE, fnm), nf, ndih, dih, dt, nlist, dlist, time,
1581 maxchi, bPhi, bPsi, bChi, bOmega, oenv);
1585 do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy");
1586 do_view(oenv, opt2fn("-jc", NFILE, fnm), "-nxy");
1589 do_view(oenv, opt2fn("-corr", NFILE, fnm), "-nxy");
1592 gmx_residuetype_destroy(rt);