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_confrms_c
= "$Id$";
32 * fit coordinates of file 1 to coordinates of file 2
33 * fit is done on the atoms as indicated by the NDX- file
58 void rm_gropbc(t_atoms
*atoms
,rvec x
[],matrix box
)
63 /* check periodic boundary */
64 for(d
=0;(d
<DIM
);d
++) {
65 for(n
=1;(n
<atoms
->nr
);n
++) {
66 dist
= x
[n
][d
]-x
[n
-1][d
];
67 if ( fabs(dist
) > 0.9 * box
[d
][d
] ) {
77 int main (int argc
,char *argv
[])
79 static char *desc
[] = {
80 "g_confrms computes the root mean square deviation (RMSD) of two",
81 "structures after LSQ fitting the second structure on the first one.",
82 "The two structures do NOT need to have the same number of atoms,",
83 "only the two index groups used for the fit need to be identical.",
85 "The superimposed structures are written to file. In a [TT].pdb[tt] file",
86 "the two structures will have chain identifiers 'A' and 'B' respectively.",
87 "When the option [TT]-one[tt] is set, only the fitted structure is",
88 "written to file and the chain identifiers are not changed."
90 static bool bSecond
=FALSE
,bRmpbc
=FALSE
;
93 { "-one", FALSE
, etBOOL
, {&bSecond
}, "Only write the fitted structure to file" },
94 { "-pbc", FALSE
, etBOOL
, {&bRmpbc
}, "Try to make molecules whole again" }
97 { efTPS
, "-f1", "conf1.gro", ffREAD
},
98 { efSTX
, "-f2", "conf2", ffREAD
},
99 { efSTO
, "-o", "fit.pdb", ffWRITE
},
100 { efNDX
, "-n1" , "fit1.ndx", ffOPTRD
},
101 { efNDX
, "-n2" , "fit2.ndx", ffOPTRD
}
104 #define NFILE asize(fnm)
106 /* the two gromos files */
108 char title_1
[STRLEN
],title_2
[STRLEN
],*name1
,*name2
;
110 t_atoms atoms_1
,atoms_2
;
111 int natoms_1
,natoms_2
,warn
=0;
114 real
*w_rls
,mass
,totmass
;
115 rvec
*x_1
,*v_1
,*x_2
,*v_2
,*xf_1
,*xf_2
,*fit_x
;
121 /* center of mass calculation */
125 /* variables for fit */
126 char *groupnames_1
,*groupnames_2
;
128 atom_id
*index_1
,*index_2
;
131 CopyRight(stderr
,argv
[0]);
132 parse_common_args(&argc
,argv
,0,TRUE
,
133 NFILE
,fnm
,asize(pa
),pa
,asize(desc
),desc
,0,NULL
);
135 /* reading first structure file, nb this is going
136 * to be the reference structure*/
137 fprintf(stderr
,"\nReading first structure file\n");
138 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title_1
,&top
,&x_1
,&v_1
,box
,TRUE
);
140 fprintf(stderr
,"%s\nContaining %d atoms in %d residues\n",
141 title_1
,atoms_1
.nr
,atoms_1
.nres
);
142 srenew(atoms_1
.resname
,atoms_1
.nres
);
145 rm_gropbc(&atoms_1
,x_1
,box_1
);
148 /* check if we have an NDX file */
150 if ( opt2bSet("-n1",NFILE,fnm) ) {
151 fprintf(stderr,"\nSelect group for root least square fit\n");
152 rd_index(opt2fn("-n1",NFILE,fnm),1,&isize_1,&index_1,&groupnames_1);
154 isize_1 = atoms_1.nr;
155 snew(index_1,isize_1);
156 for(i=0;(i<isize_1);i++)
158 groupnames_1 = title_1;
161 get_index(&atoms_1
,opt2fn_null("-n1",NFILE
,fnm
),
162 1,&isize_1
,&index_1
,&groupnames_1
);
165 fatal_error(0,"Need >= 3 points to fit!\n");
168 /* reading second gromos file */
169 get_stx_coordnum(opt2fn("-f2",NFILE
,fnm
),&(atoms_2
.nr
));
170 snew(x_2
,atoms_2
.nr
);
171 snew(v_2
,atoms_2
.nr
);
172 snew(atoms_2
.resname
,atoms_2
.nr
);
173 snew(atoms_2
.atom
,atoms_2
.nr
);
174 snew(atoms_2
.atomname
,atoms_2
.nr
);
175 fprintf(stderr
,"\nReading second structure file\n");
176 read_stx_conf(opt2fn("-f2",NFILE
,fnm
),title_2
,&atoms_2
,x_2
,v_2
,box_2
);
177 fprintf(stderr
,"%s\nContaining %d atoms in %d residues\n",
178 title_2
,atoms_2
.nr
,atoms_2
.nres
);
179 srenew(atoms_2
.resname
,atoms_2
.nres
);
182 rm_gropbc(&atoms_2
,x_2
,box_2
);
184 get_index(&atoms_2
,opt2fn_null("-n2",NFILE
,fnm
),
185 1,&isize_2
,&index_2
,&groupnames_2
);
187 /* check isizes, must be equal */
188 if ( isize_2
!= isize_1
)
189 fatal_error(0,"isize_2 != isize_2\n");
192 fatal_error(0,"Need >= 3 points to fit!\n");
194 for(i
=0; (i
<isize_1
); i
++) {
195 name1
=*atoms_1
.atomname
[index_1
[i
]];
196 name2
=*atoms_2
.atomname
[index_2
[i
]];
197 if (strcmp(name1
,name2
)) {
200 "Warning: atomnames at index %d don't match: %u %s, %u %s\n",
201 i
+1,index_1
[i
]+1,name1
,index_2
[i
]+1,name2
);
206 fprintf(stderr
,"%d atomname%s did not match\n",warn
,(warn
==1) ? "":"s");
208 /* calculate center of mass of reference structure */
211 for(i
=0;(i
<isize_1
);i
++)
213 xcm_1
[m
]+=x_1
[index_1
[i
]][m
];
216 for(i
=0;(i
<atoms_1
.nr
);i
++)
220 /* calculate center of mass of structure to be fitted */
223 for(i
=0;(i
<isize_2
);i
++)
225 xcm_2
[m
]+=x_2
[index_2
[i
]][m
];
228 for(i
=0;(i
<atoms_2
.nr
);i
++)
232 snew(w_rls
,atoms_2
.nr
);
233 snew(fit_x
,atoms_2
.nr
);
234 for(at
=0; at
<isize_1
; at
++) {
235 w_rls
[index_2
[at
]] = 1.0;
236 copy_rvec(x_1
[index_1
[at
]],fit_x
[index_2
[at
]]);
239 /*do the least squares fit to the reference structure*/
241 rms = my_fit(isize_1,index_1,index_2,x_1,atoms_2.nr,x_2);
243 do_fit(atoms_2
.nr
,w_rls
,fit_x
,x_2
);
247 for(at
=0; at
<isize_1
; at
++) {
248 mass
= w_rls
[index_2
[at
]];
250 rms
+= sqr(x_1
[index_1
[at
]][m
] - x_2
[index_2
[at
]][m
])*mass
;
253 rms
= sqrt(rms
/totmass
);
255 fprintf(stderr
,"Root mean square deviation after lsq fit = %g\n",rms
);
257 /* reset coordinates of reference and fitted structure */
258 for(i
=0;(i
<atoms_1
.nr
);i
++) {
262 for(i
=0;(i
<atoms_2
.nr
);i
++) {
267 /* calculate the rms deviation */
271 /* write gromos file of fitted structure(s) */
272 fp
=ffopen(opt2fn("-o",NFILE
,fnm
),"w");
273 if (fn2ftp(opt2fn("-o",NFILE
,fnm
))==efGRO
) {
275 write_hconf(fp
,title_1
,&atoms_1
,x_1
,v_1
,box_1
);
276 write_hconf(fp
,title_2
,&atoms_2
,x_2
,v_2
,box_2
);
279 write_pdbfile(fp
,title_2
,&atoms_2
,x_2
,box_2
,0,TRUE
);
281 write_pdbfile(fp
,title_1
,&atoms_1
,x_1
,box_1
,'A',FALSE
);
282 write_pdbfile(fp
,title_2
,&atoms_2
,x_2
,box_2
,'B',TRUE
);