4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Gromacs Runs One Microsecond At Cannonball Speeds
53 void rm_gropbc(t_atoms
*atoms
,rvec x
[],matrix box
)
58 /* check periodic boundary */
60 for(n
=1; n
<atoms
->nr
; n
++) {
61 dist
= x
[n
][d
]-x
[n
-1][d
];
62 if ( fabs(dist
) > 0.9 * box
[d
][d
] ) {
71 int main (int argc
,char *argv
[])
73 static char *desc
[] = {
74 "g_confrms computes the root mean square deviation (RMSD) of two",
75 "structures after LSQ fitting the second structure on the first one.",
76 "The two structures do NOT need to have the same number of atoms,",
77 "only the two index groups used for the fit need to be identical.",
79 "The superimposed structures are written to file. In a [TT].pdb[tt] file",
80 "the two structures will be written as separate models",
81 "(use [TT]rasmol -nmrpdb[tt]).",
83 static bool bOne
=FALSE
,bRmpbc
=FALSE
,bFit
=TRUE
;
86 { "-one", FALSE
, etBOOL
, {&bOne
}, "Only write the fitted structure to file" },
87 { "-pbc", FALSE
, etBOOL
, {&bRmpbc
}, "Try to make molecules whole again" },
88 { "-fit", FALSE
, etBOOL
, {&bFit
},
89 "Do least squares superposition of the target structure to the reference" },
92 { efTPS
, "-f1", "conf1.gro", ffREAD
},
93 { efSTX
, "-f2", "conf2", ffREAD
},
94 { efSTO
, "-o", "fit.pdb", ffWRITE
},
95 { efNDX
, "-n1" , "fit1.ndx", ffOPTRD
},
96 { efNDX
, "-n2" , "fit2.ndx", ffOPTRD
}
98 #define NFILE asize(fnm)
100 /* the two structure files */
102 char title1
[STRLEN
],title2
[STRLEN
],*name1
,*name2
;
104 t_atoms atoms1
,atoms2
;
105 int natoms1
,natoms2
,warn
=0;
108 real
*w_rls
,mass
,totmass
;
109 rvec
*x1
,*v1
,*x2
,*v2
,*fit_x
;
115 /* center of mass calculation */
119 /* variables for fit */
120 char *groupnames1
,*groupnames2
;
122 atom_id
*index1
,*index2
;
125 CopyRight(stderr
,argv
[0]);
126 parse_common_args(&argc
,argv
,PCA_BE_NICE
,
127 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
129 /* reading reference structure from first structure file */
130 fprintf(stderr
,"\nReading first structure file\n");
131 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title1
,&top
,&x1
,&v1
,box
,TRUE
);
133 fprintf(stderr
,"%s\nContaining %d atoms in %d residues\n",
134 title1
,atoms1
.nr
,atoms1
.nres
);
135 srenew(atoms1
.resname
,atoms1
.nres
);
138 rm_gropbc(&atoms1
,x1
,box1
);
140 fprintf(stderr
,"Select group from first structure\n");
141 get_index(&atoms1
,opt2fn_null("-n1",NFILE
,fnm
),
142 1,&isize1
,&index1
,&groupnames1
);
144 if (bFit
&& (isize1
< 3))
145 fatal_error(0,"Need >= 3 points to fit!\n");
147 /* reading second structure file */
148 get_stx_coordnum(opt2fn("-f2",NFILE
,fnm
),&(atoms2
.nr
));
151 snew(atoms2
.resname
,atoms2
.nr
);
152 snew(atoms2
.atom
,atoms2
.nr
);
153 snew(atoms2
.atomname
,atoms2
.nr
);
154 fprintf(stderr
,"\nReading second structure file\n");
155 read_stx_conf(opt2fn("-f2",NFILE
,fnm
),title2
,&atoms2
,x2
,v2
,box2
);
156 fprintf(stderr
,"%s\nContaining %d atoms in %d residues\n",
157 title2
,atoms2
.nr
,atoms2
.nres
);
158 srenew(atoms2
.resname
,atoms2
.nres
);
161 rm_gropbc(&atoms2
,x2
,box2
);
163 fprintf(stderr
,"Select group from second structure\n");
164 get_index(&atoms2
,opt2fn_null("-n2",NFILE
,fnm
),
165 1,&isize2
,&index2
,&groupnames2
);
167 /* check isizes, must be equal */
168 if ( isize2
!= isize1
)
169 fatal_error(0,"You selected groups with differen number of atoms.\n");
171 for(i
=0; i
<isize1
; i
++) {
172 name1
=*atoms1
.atomname
[index1
[i
]];
173 name2
=*atoms2
.atomname
[index2
[i
]];
174 if (strcmp(name1
,name2
)) {
177 "Warning: atomnames at index %d don't match: %u %s, %u %s\n",
178 i
+1,index1
[i
]+1,name1
,index2
[i
]+1,name2
);
183 fprintf(stderr
,"%d atomname%s did not match\n",warn
,(warn
==1) ? "":"s");
186 /* calculate center of geometry of reference structure */
187 for(m
=0; m
<DIM
; m
++) {
189 for(i
=0; i
<isize1
; i
++)
190 xcm1
[m
]+=x1
[index1
[i
]][m
];
192 for(i
=0; i
<atoms1
.nr
; i
++)
196 /* calculate center of geometry of structure to be fitted */
197 for(m
=0; m
<DIM
; m
++) {
199 for(i
=0; i
<isize2
; i
++)
200 xcm2
[m
]+=x2
[index2
[i
]][m
];
202 for(i
=0; i
<atoms2
.nr
; i
++)
206 snew(w_rls
,atoms2
.nr
);
207 snew(fit_x
,atoms2
.nr
);
208 for(at
=0; at
<isize1
; at
++) {
209 w_rls
[index2
[at
]] = 1.0;
210 copy_rvec(x1
[index1
[at
]],fit_x
[index2
[at
]]);
213 /* do the least squares fit to the reference structure */
214 do_fit(atoms2
.nr
,w_rls
,fit_x
,x2
);
224 /* calculate the rms deviation */
226 for(at
=0; at
<isize1
; at
++) {
228 rms
+= sqr(x1
[index1
[at
]][m
] - x2
[index2
[at
]][m
]);
230 rms
= sqrt(rms
/isize1
);
232 fprintf(stderr
,"Root mean square deviation after lsq fit = %g\n",rms
);
235 /* reset coordinates of reference and fitted structure */
236 for(i
=0; i
<atoms1
.nr
; i
++)
239 for(i
=0; i
<atoms2
.nr
; i
++)
243 /* write gromos file of fitted structure(s) */
244 fp
=ffopen(opt2fn("-o",NFILE
,fnm
),"w");
245 if (fn2ftp(opt2fn("-o",NFILE
,fnm
))==efGRO
) {
247 write_hconf_p(fp
,title1
,&atoms1
,3,x1
,v1
,box1
);
248 write_hconf_p(fp
,title2
,&atoms2
,3,x2
,v2
,box2
);
251 write_pdbfile(fp
,title1
,&atoms1
,x1
,box1
,0,1);
252 write_pdbfile(fp
,title2
,&atoms2
,x2
,box2
,0,bOne
? -1 : 2);