4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_g_mdmat_c
= "$Id$";
51 int *res_ndx(t_atoms
*atoms
)
59 r0
=atoms
->atom
[0].resnr
;
60 for(i
=0; (i
<atoms
->nr
); i
++)
61 rndx
[i
]=atoms
->atom
[i
].resnr
-r0
;
66 int *res_natm(t_atoms
*atoms
)
73 snew(natm
,atoms
->nres
);
74 r0
=atoms
->atom
[0].resnr
;
76 for(i
=0; (i
<atoms
->nres
); i
++) {
77 while ((atoms
->atom
[j
].resnr
)-r0
== i
) {
86 static void calc_mat(int nres
, int natoms
, int rndx
[],
87 rvec x
[], atom_id
*index
,
88 real trunc
, real
**mdmat
,int **nmat
)
94 for(resi
=0; (resi
<nres
); resi
++)
95 for(resj
=0; (resj
<nres
); resj
++)
96 mdmat
[resi
][resj
]=FARAWAY
;
97 for(i
=0; (i
<natoms
); i
++) {
99 for(j
=i
+1; (j
<natoms
); j
++) {
101 r2
=distance2(x
[index
[i
]],x
[index
[j
]]);
106 mdmat
[resi
][resj
]=min(r2
,mdmat
[resi
][resj
]);
110 for(resi
=0; (resi
<nres
); resi
++) {
112 for(resj
=resi
+1; (resj
<nres
); resj
++) {
113 r
=sqrt(mdmat
[resi
][resj
]);
120 static void tot_nmat(int nres
, int natoms
, int nframes
, int **nmat
,
121 int *tot_n
, real
*mean_n
)
125 for (i
=0; (i
<nres
); i
++) {
126 for (j
=0; (j
<natoms
); j
++)
127 if (nmat
[i
][j
] != 0) {
129 mean_n
[i
]+=nmat
[i
][j
];
135 int main(int argc
,char *argv
[])
137 static char *desc
[] = {
138 "g_mdmat makes distance matrices consisting of the smallest distance",
139 "between residue pairs. With -frames these distance matrices can be",
140 "stored as a function",
141 "of time, to be able to see differences in tertiary structure as a",
142 "funcion of time. If you choose your options unwise, this may generate",
143 "a large output file. Default only an averaged matrix over the whole",
144 "trajectory is output.",
145 "Also a count of the number of different atomic contacts between",
146 "residues over the whole trajectory can be made.",
147 "The output can be processed with xpm2ps to make a PostScript (tm) plot."
149 static real truncate
=1.5,dt
=0.0;
150 static bool bAtom
=FALSE
;
151 static int nlevels
=40;
153 { "-t", FALSE
, etREAL
, {&truncate
},
155 { "-nlevels", FALSE
, etINT
, {&nlevels
},
156 "Discretize distance in # levels" },
157 { "-dt", FALSE
, etREAL
, {&dt
},
158 "Only analyze a frame each dt picoseconds" }
161 { efTRX
, "-f", NULL
, ffREAD
},
162 { efTPS
, NULL
, NULL
, ffREAD
},
163 { efNDX
, NULL
, NULL
, ffOPTRD
},
164 { efXPM
, "-mean", "dm", ffWRITE
},
165 { efXPM
, "-frames", "dmf", ffOPTWR
},
166 { efXVG
, "-no", "num",ffOPTWR
},
168 #define NFILE asize(fnm)
178 int i
,j
,status
,nres
,natoms
,nframes
,it
,teller
,trxnat
;
182 char title
[256],label
[234];
185 real
**mdmat
,*resnr
,**totmdmat
;
186 int **nmat
,**totnmat
;
191 CopyRight(stdout
,argv
[0]);
193 parse_common_args(&argc
,argv
,PCA_CAN_TIME
,TRUE
,NFILE
,fnm
,
194 asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
196 fprintf(stderr
,"Will truncate at %f nm\n",truncate
);
197 bCalcN
= opt2bSet("-no",NFILE
,fnm
);
198 bFrames
= opt2bSet("-frames",NFILE
,fnm
);
200 fprintf(stderr
,"Will calculate number of different contacts\n");
201 fprintf(stderr
,"Time interval between frames is %g ps\n",dt
);
203 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title
,&top
,&x
,NULL
,box
,FALSE
);
205 fprintf(stderr
,"Select group for analysis\n");
206 get_index(&top
.atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),1,&isize
,&index
,&grpname
);
209 snew(useatoms
.atom
,natoms
);
210 snew(useatoms
.atomname
,natoms
);
213 useatoms
.resname
=top
.atoms
.resname
;
214 for(i
=0;(i
<isize
);i
++) {
215 useatoms
.atomname
[i
]=top
.atoms
.atomname
[index
[i
]];
216 useatoms
.atom
[i
].resnr
=top
.atoms
.atom
[index
[i
]].resnr
;
217 useatoms
.nres
=max(useatoms
.nres
,useatoms
.atom
[i
].resnr
+1);
221 rndx
=res_ndx(&(useatoms
));
222 natm
=res_natm(&(useatoms
));
224 fprintf(stderr
,"There are %d residues with %d atoms\n",nres
,natoms
);
232 for(i
=0; (i
<nres
); i
++) {
234 snew(nmat
[i
],natoms
);
235 snew(totnmat
[i
],natoms
);
239 for(i
=0; (i
<nres
); i
++)
240 snew(totmdmat
[i
],nres
);
242 trxnat
=read_first_x(&status
,ftp2fn(efTRX
,NFILE
,fnm
),&t
,&x
,box
);
247 rlo
.r
=1.0, rlo
.g
=1.0, rlo
.b
=1.0;
248 rhi
.r
=0.0, rhi
.g
=0.0, rhi
.b
=0.0;
250 out
=opt2FILE("-frames",NFILE
,fnm
,"w");
254 rm_pbc(&top
.idef
,trxnat
,box
,x
,x
);
257 calc_mat(nres
,natoms
,rndx
,x
,index
,truncate
,mdmat
,nmat
);
258 for (i
=0; (i
<nres
); i
++)
259 for (j
=0; (j
<natoms
); j
++)
262 for (i
=0; (i
<nres
); i
++)
263 for (j
=0; (j
<nres
); j
++)
264 totmdmat
[i
][j
] += mdmat
[i
][j
];
266 sprintf(label
,"t=%.0f ps",t
);
267 write_xpm(out
,label
,"Distance (nm)","Residue Index","Residue Index",
268 nres
,nres
,resnr
,resnr
,mdmat
,0,truncate
,rlo
,rhi
,&nlevels
);
272 } while (read_next_x(status
,&t
,trxnat
,x
,box
));
273 fprintf(stderr
,"\n");
278 fprintf(stderr
,"Processed %d frames out of %d\n",nframes
,teller
);
280 for (i
=0; (i
<nres
); i
++)
281 for (j
=0; (j
<nres
); j
++)
282 totmdmat
[i
][j
] /= nframes
;
283 write_xpm(opt2FILE("-mean",NFILE
,fnm
,"w"),"Mean smallest distance",
284 "Distance (nm)","Residue Index","Residue Index",
285 nres
,nres
,resnr
,resnr
,mdmat
,0,truncate
,rlo
,rhi
,&nlevels
);
288 tot_nmat(nres
,natoms
,nframes
,totnmat
,tot_n
,mean_n
);
289 fp
=xvgropen(ftp2fn(efXVG
,NFILE
,fnm
),
290 "Increase in number of contacts","Residue","Ratio");
291 fprintf(fp
,"@ legend on\n");
292 fprintf(fp
,"@ legend box on\n");
293 fprintf(fp
,"@ legend loctype view\n");
294 fprintf(fp
,"@ legend 0.75, 0.8\n");
295 fprintf(fp
,"@ legend string 0 \"Total/mean\"\n");
296 fprintf(fp
,"@ legend string 1 \"Total\"\n");
297 fprintf(fp
,"@ legend string 2 \"Mean\"\n");
298 fprintf(fp
,"@ legend string 3 \"# atoms\"\n");
299 fprintf(fp
,"@ legend string 4 \"Mean/# atoms\"\n");
300 fprintf(fp
,"#%3s %8s %3s %8s %3s %8s\n",
301 "res","ratio","tot","mean","natm","mean/atm");
302 for (i
=0; (i
<nres
); i
++) {
306 ratio
=tot_n
[i
]/mean_n
[i
];
307 fprintf(fp
,"%3d %8.3f %3d %8.3f %3d %8.3f\n",
308 i
+1,ratio
,tot_n
[i
],mean_n
[i
],natm
[i
],mean_n
[i
]/natm
[i
]);