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_ter_db_c
= "$Id$";
44 /* use bonded types definitions in hackblock.h */
45 #define ekwRepl ebtsNR+1
46 #define ekwAdd ebtsNR+2
47 #define ekwDel ebtsNR+3
49 char *kw_names
[ekwNR
] = {
50 "replace", "add", "delete"
53 int find_kw(char *keyw
)
57 for(i
=0; i
<ebtsNR
; i
++)
58 if (strcasecmp(btsNames
[i
],keyw
) == 0)
60 for(i
=0; i
<ekwNR
; i
++)
61 if (strcasecmp(kw_names
[i
],keyw
) == 0)
62 return ebtsNR
+ 1 + i
;
67 #define FATAL() fatal_error(0,"Reading Termini Database: not enough items on line\n%s",line)
69 static void read_atom(char *line
, t_atom
*a
, t_atomtype
*atype
,
70 char nnew
[], int *cgnr
)
76 if ( (i
=sscanf(line
,"%s%s%lf%lf%n", nnew
, type
, &m
, &q
, &n
)) != 4 )
77 fatal_error(0,"Reading Termini Database: expected %d items of atom data in stead of %d on line\n%s", 4, i
, line
);
80 a
->type
=at2type(type
,atype
);
81 if ( sscanf(line
+n
,"%d", cgnr
) != 1 )
85 int read_ter_db(char *inf
,t_hackblock
**tbptr
,t_atomtype
*atype
)
88 char header
[STRLEN
],buf
[STRLEN
],line
[STRLEN
];
90 int i
,j
,n
,ni
,kwnr
,nb
,maxnb
,nh
;
94 fprintf(debug
,"Opened %s\n",inf
);
100 get_a_line(in
,line
,STRLEN
);
102 if (get_header(line
,header
)) {
103 /* this is a new block, or a new keyword */
104 kwnr
=find_kw(header
);
106 if (kwnr
== NOTSET
) {
108 /* here starts a new block */
113 clear_t_hackblock(&tb
[nb
]);
114 tb
[nb
].name
=strdup(header
);
118 fatal_error(0,"reading termini database: "
119 "directive expected before line:\n%s\n"
120 "This might be a file in an old format.",line
);
121 /* this is not a header, so it must be data */
122 if (kwnr
>= ebtsNR
) {
123 /* this is a hack: add/rename/delete atoms */
124 /* make space for hacks */
125 if (tb
[nb
].nhack
>= tb
[nb
].maxhack
) {
127 srenew(tb
[nb
].hack
, tb
[nb
].maxhack
);
130 clear_t_hack(&(tb
[nb
].hack
[nh
]));
132 tb
[nb
].hack
[nh
].a
[i
]=NULL
;
137 if ( kwnr
==ekwRepl
|| kwnr
==ekwDel
) {
138 if (sscanf(line
, "%s%n", buf
, &n
) != 1)
139 fatal_error(0,"Reading Termini Database: "
140 "expected atom name on line\n%s",line
);
141 tb
[nb
].hack
[nh
].oname
= strdup(buf
);
142 /* we only replace or delete one atom at a time */
143 tb
[nb
].hack
[nh
].nr
= 1;
144 } else if ( kwnr
==ekwAdd
) {
145 read_ab(line
, inf
, &(tb
[nb
].hack
[nh
]));
146 get_a_line(in
, line
, STRLEN
);
148 fatal_error(0,"unimplemented keyword number %d (%s:%d)",
149 kwnr
,__FILE__
,__LINE__
);
150 if ( kwnr
==ekwRepl
|| kwnr
==ekwAdd
) {
151 snew(tb
[nb
].hack
[nh
].atom
, 1);
152 read_atom(line
+n
, tb
[nb
].hack
[nh
].atom
, atype
,
153 buf
, &tb
[nb
].hack
[nh
].cgnr
);
154 tb
[nb
].hack
[nh
].nname
= strdup(buf
);
156 } else if (kwnr
>= 0 && kwnr
< ebtsNR
) {
157 /* this is bonded data: bonds, angles, dihedrals or impropers */
158 srenew(tb
[nb
].rb
[kwnr
].b
,tb
[nb
].rb
[kwnr
].nb
+1);
160 for(j
=0; j
<btsNiatoms
[kwnr
]; j
++) {
161 if ( sscanf(line
+n
, "%s%n", buf
, &ni
) == 1 )
162 tb
[nb
].rb
[kwnr
].b
[tb
[nb
].rb
[kwnr
].nb
].a
[j
] = strdup(buf
);
164 fatal_error(0,"Reading Termini Database: expected %d atom names (found %d) on line\n%s", btsNiatoms
[kwnr
], j
-1, line
);
167 for( ; j
<MAXATOMLIST
; j
++)
168 tb
[nb
].rb
[kwnr
].b
[tb
[nb
].rb
[kwnr
].nb
].a
[j
] = NULL
;
170 sscanf(line
+n
, "%s", buf
);
171 tb
[nb
].rb
[kwnr
].b
[tb
[nb
].rb
[kwnr
].nb
].s
= strdup(buf
);
172 tb
[nb
].rb
[kwnr
].nb
++;
174 fatal_error(0,"Reading Termini Database: Expecting a header at line\n"
177 get_a_line(in
,line
,STRLEN
);
184 if (debug
) print_ter_db(debug
, nb
, tb
, atype
);
190 t_hackblock
*choose_ter(int nb
,t_hackblock tb
[],char *title
)
197 printf("%s\n",title
);
198 for(i
=0; (i
<nb
); i
++)
199 printf("%2d: %s\n",i
,tb
[i
].name
);
201 fscanf(stdin
,"%d",&sel
);
202 } while ((sel
< 0) || (sel
>= nb
));
207 static void print_atom(FILE *out
,t_atom
*a
,t_atomtype
*atype
,char *newnm
)
209 fprintf(out
,"%s\t%s\t%g\t%g\n",
210 newnm
,type2nm(a
->type
,atype
),a
->m
,a
->q
);
213 void print_ter_db(FILE *out
,int nb
,t_hackblock tb
[],t_atomtype
*atype
)
215 int i
,j
,k
,bt
,nrepl
,nadd
,ndel
;
217 for(i
=0; (i
<nb
); i
++) {
218 fprintf(out
,"[ %s ]\n",tb
[i
].name
);
224 for(j
=0; j
<tb
[i
].nhack
; j
++)
225 if ( tb
[i
].hack
[j
].oname
!=NULL
&& tb
[i
].hack
[j
].nname
!=NULL
)
227 else if ( tb
[i
].hack
[j
].oname
==NULL
&& tb
[i
].hack
[j
].nname
!=NULL
)
229 else if ( tb
[i
].hack
[j
].oname
!=NULL
&& tb
[i
].hack
[j
].nname
==NULL
)
231 else if ( tb
[i
].hack
[j
].oname
==NULL
&& tb
[i
].hack
[j
].nname
==NULL
)
232 fatal_error(0,"invalid hack (%s) in termini database",tb
[i
].name
);
234 fprintf(out
,"[ %s ]\n",kw_names
[ekwRepl
-ebtsNR
-1]);
235 for(j
=0; j
<tb
[i
].nhack
; j
++)
236 if ( tb
[i
].hack
[j
].oname
!=NULL
&& tb
[i
].hack
[j
].nname
!=NULL
) {
237 fprintf(out
,"%s\t",tb
[i
].hack
[j
].oname
);
238 print_atom(out
,tb
[i
].hack
[j
].atom
,atype
,tb
[i
].hack
[j
].nname
);
242 fprintf(out
,"[ %s ]\n",kw_names
[ekwAdd
-ebtsNR
-1]);
243 for(j
=0; j
<tb
[i
].nhack
; j
++)
244 if ( tb
[i
].hack
[j
].oname
==NULL
&& tb
[i
].hack
[j
].nname
!=NULL
) {
245 print_ab(out
,&(tb
[i
].hack
[j
]));
247 print_atom(out
,tb
[i
].hack
[j
].atom
,atype
,tb
[i
].hack
[j
].nname
);
251 fprintf(out
,"[ %s ]\n",kw_names
[ekwDel
-ebtsNR
-1]);
252 for(j
=0; j
<tb
[i
].nhack
; j
++)
253 if ( tb
[i
].hack
[j
].oname
!=NULL
&& tb
[i
].hack
[j
].nname
==NULL
)
254 fprintf(out
,"%s\n",tb
[i
].hack
[j
].oname
);
256 for(bt
=0; bt
<ebtsNR
; bt
++)
257 if (tb
[i
].rb
[bt
].nb
) {
258 fprintf(out
,"[ %s ]\n", btsNames
[bt
]);
259 for(j
=0; j
<tb
[i
].rb
[bt
].nb
; j
++) {
260 for(k
=0; k
<btsNiatoms
[bt
]; k
++)
261 fprintf(out
,"%s%s",k
?"\t":"",tb
[i
].rb
[bt
].b
[j
].a
[k
]);
262 if ( tb
[i
].rb
[bt
].b
[j
].s
)
263 fprintf(out
,"\t%s",tb
[i
].rb
[bt
].b
[j
].s
);
272 int main(int argc
,char *argv
[])
276 t_hackblock
*tb
,*seltb
;
280 atype
=read_atype("ffgmx",&tab
);
281 nb
=read_ter_db("ffgmx-c.tdb",&tb
,atype
);
282 seltb
=choose_ter(nb
,tb
,"What do you want ?");
283 print_ter_db(stdout
,1,seltb
,atype
);