added Verlet scheme and NxN non-bonded functionality
[gromacs.git] / src / gmxlib / confio.c
blob886983a6d513dda269c8ad5b106ebaca6fd74ac5
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * GROningen Mixture of Alchemy and Childrens' Stories
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <math.h>
40 #include "sysstuff.h"
41 #include "typedefs.h"
42 #include "smalloc.h"
43 #include "sysstuff.h"
44 #include <errno.h>
45 #include "macros.h"
46 #include "string2.h"
47 #include "confio.h"
48 #include "vec.h"
49 #include "symtab.h"
50 #include "futil.h"
51 #include "xdrf.h"
52 #include "filenm.h"
53 #include "pdbio.h"
54 #include "tpxio.h"
55 #include "gmx_fatal.h"
56 #include "copyrite.h"
57 #include "filenm.h"
58 #include "statutil.h"
59 #include "pbc.h"
60 #include "mtop_util.h"
61 #include "gmxfio.h"
63 #define CHAR_SHIFT 24
65 static int read_g96_pos(char line[],t_symtab *symtab,
66 FILE *fp,const char *infile,
67 t_trxframe *fr)
69 t_atoms *atoms;
70 gmx_bool bEnd;
71 int nwanted,natoms,atnr,resnr=0,oldres,newres,shift;
72 char anm[STRLEN],resnm[STRLEN];
73 char c1,c2;
74 double db1,db2,db3;
76 nwanted = fr->natoms;
78 atoms = fr->atoms;
80 natoms = 0;
82 if (fr->bX) {
83 if (fr->bAtoms)
84 shift = CHAR_SHIFT;
85 else
86 shift = 0;
87 newres = -1;
88 oldres = -666; /* Unlikely number for the first residue! */
89 bEnd = FALSE;
90 while (!bEnd && fgets2(line,STRLEN,fp)) {
91 bEnd = (strncmp(line,"END",3) == 0);
92 if (!bEnd && (line[0] != '#')) {
93 if (sscanf(line+shift,"%15lf%15lf%15lf",&db1,&db2,&db3) != 3)
94 gmx_fatal(FARGS,"Did not find 3 coordinates for atom %d in %s\n",
95 natoms+1,infile);
96 if ((nwanted != -1) && (natoms >= nwanted))
97 gmx_fatal(FARGS,
98 "Found more coordinates (%d) in %s than expected %d\n",
99 natoms,infile,nwanted);
100 if (atoms) {
101 if (fr->bAtoms &&
102 (sscanf(line,"%5d%c%5s%c%5s%7d",&resnr,&c1,resnm,&c2,anm,&atnr)
103 != 6)) {
104 if (oldres>=0)
105 resnr = oldres;
106 else {
107 resnr = 1;
108 strncpy(resnm,"???",sizeof(resnm)-1);
110 strncpy(anm,"???",sizeof(anm)-1);
112 atoms->atomname[natoms]=put_symtab(symtab,anm);
113 if (resnr != oldres) {
114 oldres = resnr;
115 newres++;
116 if (newres >= atoms->nr)
117 gmx_fatal(FARGS,"More residues than atoms in %s (natoms = %d)",
118 infile,atoms->nr);
119 atoms->atom[natoms].resind = newres;
120 if (newres+1 > atoms->nres) {
121 atoms->nres = newres+1;
123 t_atoms_set_resinfo(atoms,natoms,symtab,resnm,resnr,' ',0,' ');
124 } else {
125 atoms->atom[natoms].resind = newres;
128 if (fr->x) {
129 fr->x[natoms][0] = db1;
130 fr->x[natoms][1] = db2;
131 fr->x[natoms][2] = db3;
133 natoms++;
136 if ((nwanted != -1) && natoms != nwanted)
137 fprintf(stderr,
138 "Warning: found less coordinates (%d) in %s than expected %d\n",
139 natoms,infile,nwanted);
142 fr->natoms = natoms;
144 return natoms;
147 static int read_g96_vel(char line[],FILE *fp,const char *infile,
148 t_trxframe *fr)
150 gmx_bool bEnd;
151 int nwanted,natoms=-1,shift;
152 double db1,db2,db3;
154 nwanted = fr->natoms;
156 if (fr->v && fr->bV) {
157 if (strcmp(line,"VELOCITYRED") == 0)
158 shift = 0;
159 else
160 shift = CHAR_SHIFT;
161 natoms = 0;
162 bEnd = FALSE;
163 while (!bEnd && fgets2(line,STRLEN,fp)) {
164 bEnd = (strncmp(line,"END",3) == 0);
165 if (!bEnd && (line[0] != '#')) {
166 if (sscanf(line+shift,"%15lf%15lf%15lf",&db1,&db2,&db3) != 3)
167 gmx_fatal(FARGS,"Did not find 3 velocities for atom %d in %s",
168 natoms+1,infile);
169 if ((nwanted != -1) && (natoms >= nwanted))
170 gmx_fatal(FARGS,"Found more velocities (%d) in %s than expected %d\n",
171 natoms,infile,nwanted);
172 if (fr->v) {
173 fr->v[natoms][0] = db1;
174 fr->v[natoms][1] = db2;
175 fr->v[natoms][2] = db3;
177 natoms++;
180 if ((nwanted != -1) && (natoms != nwanted))
181 fprintf(stderr,
182 "Warning: found less velocities (%d) in %s than expected %d\n",
183 natoms,infile,nwanted);
186 return natoms;
189 int read_g96_conf(FILE *fp,const char *infile,t_trxframe *fr, char *line)
191 t_symtab *symtab=NULL;
192 gmx_bool bAtStart,bTime,bAtoms,bPos,bVel,bBox,bEnd,bFinished;
193 int natoms,nbp;
194 double db1,db2,db3,db4,db5,db6,db7,db8,db9;
196 bAtStart = (ftell(fp) == 0);
198 clear_trxframe(fr,FALSE);
200 if (!symtab) {
201 snew(symtab,1);
202 open_symtab(symtab);
205 natoms=0;
207 if (bAtStart) {
208 while ( !fr->bTitle && fgets2(line,STRLEN,fp))
209 fr->bTitle = (strcmp(line,"TITLE") == 0);
210 if (fr->title == NULL) {
211 fgets2(line,STRLEN,fp);
212 fr->title = strdup(line);
214 bEnd = FALSE;
215 while (!bEnd && fgets2(line,STRLEN,fp))
216 bEnd = (strcmp(line,"END") == 0);
217 fgets2(line,STRLEN,fp);
220 /* Do not get a line if we are not at the start of the file, *
221 * because without a parameter file we don't know what is in *
222 * the trajectory and we have already read the line in the *
223 * previous call (VERY DIRTY). */
224 bFinished = FALSE;
225 do {
226 bTime = (strcmp(line,"TIMESTEP") == 0);
227 bAtoms = (strcmp(line,"POSITION") == 0);
228 bPos = (bAtoms || (strcmp(line,"POSITIONRED") == 0));
229 bVel = (strncmp(line,"VELOCITY",8) == 0);
230 bBox = (strcmp(line,"BOX") == 0);
231 if (bTime) {
232 if (!fr->bTime && !fr->bX) {
233 fr->bStep = bTime;
234 fr->bTime = bTime;
236 bFinished = (fgets2(line,STRLEN,fp) == NULL);
237 while (!bFinished && (line[0] == '#'));
238 sscanf(line,"%15d%15lf",&(fr->step),&db1);
239 fr->time = db1;
240 } else
241 bFinished = TRUE;
243 if (bPos) {
244 if (!fr->bX) {
245 fr->bAtoms = bAtoms;
246 fr->bX = bPos;
247 natoms = read_g96_pos(line,symtab,fp,infile,fr);
248 } else
249 bFinished = TRUE;
251 if (fr->v && bVel) {
252 fr->bV = bVel;
253 natoms = read_g96_vel(line,fp,infile,fr);
255 if (bBox) {
256 fr->bBox = bBox;
257 clear_mat(fr->box);
258 bEnd = FALSE;
259 while (!bEnd && fgets2(line,STRLEN,fp)) {
260 bEnd = (strncmp(line,"END",3) == 0);
261 if (!bEnd && (line[0] != '#')) {
262 nbp = sscanf(line,"%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf",
263 &db1,&db2,&db3,&db4,&db5,&db6,&db7,&db8,&db9);
264 if (nbp < 3)
265 gmx_fatal(FARGS,"Found a BOX line, but no box in %s",infile);
266 fr->box[XX][XX] = db1;
267 fr->box[YY][YY] = db2;
268 fr->box[ZZ][ZZ] = db3;
269 if (nbp == 9) {
270 fr->box[XX][YY] = db4;
271 fr->box[XX][ZZ] = db5;
272 fr->box[YY][XX] = db6;
273 fr->box[YY][ZZ] = db7;
274 fr->box[ZZ][XX] = db8;
275 fr->box[ZZ][YY] = db9;
279 bFinished = TRUE;
281 } while (!bFinished && fgets2(line,STRLEN,fp));
283 free_symtab(symtab);
285 fr->natoms = natoms;
287 return natoms;
290 void write_g96_conf(FILE *out,t_trxframe *fr,
291 int nindex,atom_id *index)
293 t_atoms *atoms;
294 int nout,i,a;
296 atoms = fr->atoms;
298 if (index)
299 nout = nindex;
300 else
301 nout = fr->natoms;
303 if (fr->bTitle)
304 fprintf(out,"TITLE\n%s\nEND\n",fr->title);
305 if (fr->bStep || fr->bTime)
306 /* Officially the time format is %15.9, which is not enough for 10 ns */
307 fprintf(out,"TIMESTEP\n%15d%15.6f\nEND\n",fr->step,fr->time);
308 if (fr->bX) {
309 if (fr->bAtoms) {
310 fprintf(out,"POSITION\n");
311 for(i=0; i<nout; i++) {
312 if (index) a = index[i]; else a = i;
313 fprintf(out,"%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
314 (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
315 *atoms->resinfo[atoms->atom[a].resind].name,
316 *atoms->atomname[a],(i+1) % 10000000,
317 fr->x[a][XX],fr->x[a][YY],fr->x[a][ZZ]);
319 } else {
320 fprintf(out,"POSITIONRED\n");
321 for(i=0; i<nout; i++) {
322 if (index) a = index[i]; else a = i;
323 fprintf(out,"%15.9f%15.9f%15.9f\n",
324 fr->x[a][XX],fr->x[a][YY],fr->x[a][ZZ]);
327 fprintf(out,"END\n");
329 if (fr->bV) {
330 if (fr->bAtoms) {
331 fprintf(out,"VELOCITY\n");
332 for(i=0; i<nout; i++) {
333 if (index) a = index[i]; else a = i;
334 fprintf(out,"%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n",
335 (atoms->resinfo[atoms->atom[a].resind].nr) % 100000,
336 *atoms->resinfo[atoms->atom[a].resind].name,
337 *atoms->atomname[a],(i+1) % 10000000,
338 fr->v[a][XX],fr->v[a][YY],fr->v[a][ZZ]);
340 } else {
341 fprintf(out,"VELOCITYRED\n");
342 for(i=0; i<nout; i++) {
343 if (index) a = index[i]; else a = i;
344 fprintf(out,"%15.9f%15.9f%15.9f\n",
345 fr->v[a][XX],fr->v[a][YY],fr->v[a][ZZ]);
348 fprintf(out,"END\n");
350 if (fr->bBox) {
351 fprintf(out,"BOX\n");
352 fprintf(out,"%15.9f%15.9f%15.9f",
353 fr->box[XX][XX],fr->box[YY][YY],fr->box[ZZ][ZZ]);
354 if (fr->box[XX][YY] || fr->box[XX][ZZ] || fr->box[YY][XX] ||
355 fr->box[YY][ZZ] || fr->box[ZZ][XX] ||fr->box[ZZ][YY])
356 fprintf(out,"%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f",
357 fr->box[XX][YY],fr->box[XX][ZZ],fr->box[YY][XX],
358 fr->box[YY][ZZ],fr->box[ZZ][XX],fr->box[ZZ][YY]);
359 fprintf(out,"\n");
360 fprintf(out,"END\n");
364 static int get_espresso_word(FILE *fp,char word[])
366 int ret,nc,i;
368 ret = 0;
369 nc = 0;
371 do {
372 i = fgetc(fp);
373 if (i != EOF) {
374 if (i == ' ' || i == '\n' || i == '\t') {
375 if (nc > 0)
376 ret = 1;
377 } else if (i == '{') {
378 if (nc == 0)
379 word[nc++] = '{';
380 ret = 2;
381 } else if (i == '}') {
382 if (nc == 0)
383 word[nc++] = '}';
384 ret = 3;
385 } else {
386 word[nc++] = (char)i;
389 } while (i != EOF && ret == 0);
391 word[nc] = '\0';
393 /* printf("'%s'\n",word); */
395 return ret;
398 static int check_open_parenthesis(FILE *fp,int r,
399 const char *infile,const char *keyword)
401 int level_inc;
402 char word[STRLEN];
404 level_inc = 0;
405 if (r == 2) {
406 level_inc++;
407 } else {
408 r = get_espresso_word(fp,word);
409 if (r == 2)
410 level_inc++;
411 else
412 gmx_fatal(FARGS,"Expected '{' after '%s' in file '%s'",
413 keyword,infile);
416 return level_inc;
419 static int check_close_parenthesis(FILE *fp,int r,
420 const char *infile,const char *keyword)
422 int level_inc;
423 char word[STRLEN];
425 level_inc = 0;
426 if (r == 3) {
427 level_inc--;
428 } else {
429 r = get_espresso_word(fp,word);
430 if (r == 3)
431 level_inc--;
432 else
433 gmx_fatal(FARGS,"Expected '}' after section '%s' in file '%s'",
434 keyword,infile);
437 return level_inc;
440 enum { espID, espPOS, espTYPE, espQ, espV, espF, espMOLECULE, espNR };
441 const char *esp_prop[espNR] = { "id", "pos", "type", "q", "v", "f",
442 "molecule" };
444 static void read_espresso_conf(const char *infile,
445 t_atoms *atoms,rvec x[],rvec *v,matrix box)
447 t_symtab *symtab=NULL;
448 FILE *fp;
449 char word[STRLEN],buf[STRLEN];
450 int natoms,level,npar,r,nprop,p,i,m,molnr;
451 int prop[32];
452 double d;
453 gmx_bool bFoundParticles,bFoundProp,bFoundVariable,bMol;
455 if (!symtab) {
456 snew(symtab,1);
457 open_symtab(symtab);
460 clear_mat(box);
462 fp = gmx_fio_fopen(infile,"r");
464 bFoundParticles = FALSE;
465 bFoundVariable = FALSE;
466 bMol = FALSE;
467 level = 0;
468 while ((r=get_espresso_word(fp,word))) {
469 if (level==1 && strcmp(word,"particles")==0 && !bFoundParticles) {
470 bFoundParticles = TRUE;
471 level += check_open_parenthesis(fp,r,infile,"particles");
472 nprop = 0;
473 while (level == 2 && (r=get_espresso_word(fp,word))) {
474 bFoundProp = FALSE;
475 for(p=0; p<espNR; p++) {
476 if (strcmp(word,esp_prop[p]) == 0) {
477 bFoundProp = TRUE;
478 prop[nprop++] = p;
479 /* printf(" prop[%d] = %s\n",nprop-1,esp_prop[prop[nprop-1]]); */
482 if (!bFoundProp && word[0] != '}') {
483 gmx_fatal(FARGS,"Can not read Espresso files with particle property '%s'",word);
485 if (bFoundProp && p == espMOLECULE)
486 bMol = TRUE;
487 if (r == 3)
488 level--;
491 i = 0;
492 while (level > 0 && (r=get_espresso_word(fp,word))) {
493 if (r == 2) {
494 level++;
495 } else if (r == 3) {
496 level--;
498 if (level == 2) {
499 for(p=0; p<nprop; p++) {
500 switch (prop[p]) {
501 case espID:
502 r = get_espresso_word(fp,word);
503 /* Not used */
504 break;
505 case espPOS:
506 for(m=0; m<3; m++) {
507 r = get_espresso_word(fp,word);
508 sscanf(word,"%lf",&d);
509 x[i][m] = d;
511 break;
512 case espTYPE:
513 r = get_espresso_word(fp,word);
514 atoms->atom[i].type = strtol(word, NULL, 10);
515 break;
516 case espQ:
517 r = get_espresso_word(fp,word);
518 sscanf(word,"%lf",&d);
519 atoms->atom[i].q = d;
520 break;
521 case espV:
522 for(m=0; m<3; m++) {
523 r = get_espresso_word(fp,word);
524 sscanf(word,"%lf",&d);
525 v[i][m] = d;
527 break;
528 case espF:
529 for(m=0; m<3; m++) {
530 r = get_espresso_word(fp,word);
531 /* not used */
533 break;
534 case espMOLECULE:
535 r = get_espresso_word(fp,word);
536 molnr = strtol(word, NULL, 10);
537 if (i == 0 ||
538 atoms->resinfo[atoms->atom[i-1].resind].nr != molnr) {
539 atoms->atom[i].resind =
540 (i == 0 ? 0 : atoms->atom[i-1].resind+1);
541 atoms->resinfo[atoms->atom[i].resind].nr = molnr;
542 atoms->resinfo[atoms->atom[i].resind].ic = ' ';
543 atoms->resinfo[atoms->atom[i].resind].chainid = ' ';
544 atoms->resinfo[atoms->atom[i].resind].chainnum = molnr; /* Not sure if this is right? */
545 } else {
546 atoms->atom[i].resind = atoms->atom[i-1].resind;
548 break;
551 /* Generate an atom name from the particle type */
552 sprintf(buf,"T%d",atoms->atom[i].type);
553 atoms->atomname[i] = put_symtab(symtab,buf);
554 if (bMol) {
555 if (i == 0 || atoms->atom[i].resind != atoms->atom[i-1].resind) {
556 atoms->resinfo[atoms->atom[i].resind].name =
557 put_symtab(symtab,"MOL");
559 } else {
560 /* Residue number is the atom number */
561 atoms->atom[i].resind = i;
562 /* Generate an residue name from the particle type */
563 if (atoms->atom[i].type < 26) {
564 sprintf(buf,"T%c",'A'+atoms->atom[i].type);
565 } else {
566 sprintf(buf,"T%c%c",
567 'A'+atoms->atom[i].type/26,'A'+atoms->atom[i].type%26);
569 t_atoms_set_resinfo(atoms,i,symtab,buf,i,' ',0,' ');
572 if (r == 3)
573 level--;
574 i++;
577 atoms->nres = atoms->nr;
579 if (i != atoms->nr) {
580 gmx_fatal(FARGS,"Internal inconsistency in Espresso routines, read %d atoms, expected %d atoms",i,atoms->nr);
582 } else if (level==1 && strcmp(word,"variable")==0 && !bFoundVariable) {
583 bFoundVariable = TRUE;
584 level += check_open_parenthesis(fp,r,infile,"variable");
585 while (level==2 && (r=get_espresso_word(fp,word))) {
586 if (level==2 && strcmp(word,"box_l") == 0) {
587 for(m=0; m<3; m++) {
588 r = get_espresso_word(fp,word);
589 sscanf(word,"%lf",&d);
590 box[m][m] = d;
592 level += check_close_parenthesis(fp,r,infile,"box_l");
595 } else if (r == 2) {
596 level++;
597 } else if (r == 3) {
598 level--;
602 if (!bFoundParticles) {
603 fprintf(stderr,"Did not find a particles section in Espresso file '%s'\n",
604 infile);
607 gmx_fio_fclose(fp);
610 static int get_espresso_coordnum(const char *infile)
612 FILE *fp;
613 char word[STRLEN];
614 int natoms,level,r;
615 gmx_bool bFoundParticles;
617 natoms = 0;
619 fp = gmx_fio_fopen(infile,"r");
621 bFoundParticles = FALSE;
622 level = 0;
623 while ((r=get_espresso_word(fp,word)) && !bFoundParticles) {
624 if (level==1 && strcmp(word,"particles")==0 && !bFoundParticles) {
625 bFoundParticles = TRUE;
626 level += check_open_parenthesis(fp,r,infile,"particles");
627 while (level > 0 && (r=get_espresso_word(fp,word))) {
628 if (r == 2) {
629 level++;
630 if (level == 2)
631 natoms++;
632 } else if (r == 3) {
633 level--;
636 } else if (r == 2) {
637 level++;
638 } else if (r == 3) {
639 level--;
642 if (!bFoundParticles) {
643 fprintf(stderr,"Did not find a particles section in Espresso file '%s'\n",
644 infile);
647 gmx_fio_fclose(fp);
649 return natoms;
652 static void write_espresso_conf_indexed(FILE *out,const char *title,
653 t_atoms *atoms,int nx,atom_id *index,
654 rvec *x,rvec *v,matrix box)
656 int i,j;
658 fprintf(out,"# %s\n",title);
659 if (TRICLINIC(box)) {
660 gmx_warning("The Espresso format does not support triclinic unit-cells");
662 fprintf(out,"{variable {box_l %f %f %f}}\n",box[0][0],box[1][1],box[2][2]);
664 fprintf(out,"{particles {id pos type q%s}\n",v ? " v" : "");
665 for(i=0; i<nx; i++) {
666 if (index)
667 j = index[i];
668 else
669 j = i;
670 fprintf(out,"\t{%d %f %f %f %d %g",
671 j,x[j][XX],x[j][YY],x[j][ZZ],
672 atoms->atom[j].type,atoms->atom[j].q);
673 if (v)
674 fprintf(out," %f %f %f",v[j][XX],v[j][YY],v[j][ZZ]);
675 fprintf(out,"}\n");
677 fprintf(out,"}\n");
680 static void get_coordnum_fp (FILE *in, char *title, int *natoms)
682 char line[STRLEN+1];
684 fgets2 (title,STRLEN,in);
685 fgets2 (line,STRLEN,in);
686 if (sscanf (line,"%d",natoms) != 1) {
687 gmx_fatal(FARGS,"gro file does not have the number of atoms on the second line");
691 static void get_coordnum (const char *infile,int *natoms)
693 FILE *in;
694 char title[STRLEN];
696 in=gmx_fio_fopen(infile,"r");
697 get_coordnum_fp(in,title,natoms);
698 gmx_fio_fclose (in);
701 static gmx_bool get_w_conf(FILE *in, const char *infile, char *title,
702 t_symtab *symtab, t_atoms *atoms, int *ndec,
703 rvec x[], rvec *v, matrix box)
705 char name[6];
706 char line[STRLEN+1],*ptr;
707 char buf[256];
708 double x1,y1,z1,x2,y2,z2;
709 rvec xmin,xmax;
710 int natoms,i,m,resnr,newres,oldres,ddist,c;
711 gmx_bool bFirst,bVel;
712 char *p1,*p2,*p3;
714 newres = -1;
715 oldres = NOTSET; /* Unlikely number for the first residue! */
716 ddist = 0;
718 /* Read the title and number of atoms */
719 get_coordnum_fp(in,title,&natoms);
721 if (natoms > atoms->nr)
722 gmx_fatal(FARGS,"gro file contains more atoms (%d) than expected (%d)",
723 natoms,atoms->nr);
724 else if (natoms < atoms->nr)
725 fprintf(stderr,"Warning: gro file contains less atoms (%d) than expected"
726 " (%d)\n",natoms,atoms->nr);
728 bFirst=TRUE;
730 bVel = FALSE;
732 /* just pray the arrays are big enough */
733 for (i=0; (i < natoms) ; i++) {
734 if ((fgets2 (line,STRLEN,in)) == NULL) {
735 unexpected_eof(infile,i+2);
737 if (strlen(line) < 39)
738 gmx_fatal(FARGS,"Invalid line in %s for atom %d:\n%s",infile,i+1,line);
740 /* determine read precision from distance between periods
741 (decimal points) */
742 if (bFirst) {
743 bFirst=FALSE;
744 p1=strchr(line,'.');
745 if (p1 == NULL)
746 gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile);
747 p2=strchr(&p1[1],'.');
748 if (p2 == NULL)
749 gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile);
750 ddist = p2 - p1;
751 *ndec = ddist - 5;
753 p3=strchr(&p2[1],'.');
754 if (p3 == NULL)
755 gmx_fatal(FARGS,"A coordinate in file %s does not contain a '.'",infile);
757 if (p3 - p2 != ddist)
758 gmx_fatal(FARGS,"The spacing of the decimal points in file %s is not consistent for x, y and z",infile);
761 /* residue number*/
762 memcpy(name,line,5);
763 name[5]='\0';
764 sscanf(name,"%d",&resnr);
765 memcpy(name,line+5,5);
766 name[5]='\0';
767 if (resnr != oldres) {
768 oldres = resnr;
769 newres++;
770 if (newres >= natoms)
771 gmx_fatal(FARGS,"More residues than atoms in %s (natoms = %d)",
772 infile,natoms);
773 atoms->atom[i].resind = newres;
774 t_atoms_set_resinfo(atoms,i,symtab,name,resnr,' ',0,' ');
775 } else {
776 atoms->atom[i].resind = newres;
779 /* atomname */
780 memcpy(name,line+10,5);
781 atoms->atomname[i]=put_symtab(symtab,name);
783 /* eventueel controle atomnumber met i+1 */
785 /* coordinates (start after residue shit) */
786 ptr = line + 20;
787 /* Read fixed format */
788 for(m=0; m<DIM; m++) {
789 for(c=0; (c<ddist && ptr[0]); c++) {
790 buf[c] = ptr[0];
791 ptr++;
793 buf[c] = '\0';
794 if (sscanf (buf,"%lf %lf",&x1,&x2) != 1) {
795 gmx_fatal(FARGS,"Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)",infile);
796 } else {
797 x[i][m] = x1;
801 /* velocities (start after residues and coordinates) */
802 if (v) {
803 /* Read fixed format */
804 for(m=0; m<DIM; m++) {
805 for(c=0; (c<ddist && ptr[0]); c++) {
806 buf[c] = ptr[0];
807 ptr++;
809 buf[c] = '\0';
810 if (sscanf (buf,"%lf",&x1) != 1) {
811 v[i][m] = 0;
812 } else {
813 v[i][m] = x1;
814 bVel = TRUE;
819 atoms->nres = newres + 1;
821 /* box */
822 fgets2 (line,STRLEN,in);
823 if (sscanf (line,"%lf%lf%lf",&x1,&y1,&z1) != 3) {
824 gmx_warning("Bad box in file %s",infile);
826 /* Generate a cubic box */
827 for(m=0; (m<DIM); m++)
828 xmin[m]=xmax[m]=x[0][m];
829 for(i=1; (i<atoms->nr); i++)
830 for(m=0; (m<DIM); m++) {
831 xmin[m]=min(xmin[m],x[i][m]);
832 xmax[m]=max(xmax[m],x[i][m]);
834 for (i=0; i<DIM; i++) for (m=0; m<DIM; m++) box[i][m]=0.0;
835 for(m=0; (m<DIM); m++)
836 box[m][m]=(xmax[m]-xmin[m]);
837 fprintf(stderr,"Generated a cubic box %8.3f x %8.3f x %8.3f\n",
838 box[XX][XX],box[YY][YY],box[ZZ][ZZ]);
840 else {
841 /* We found the first three values, the diagonal elements */
842 box[XX][XX]=x1;
843 box[YY][YY]=y1;
844 box[ZZ][ZZ]=z1;
845 if (sscanf (line,"%*f%*f%*f%lf%lf%lf%lf%lf%lf",
846 &x1,&y1,&z1,&x2,&y2,&z2) != 6)
847 x1=y1=z1=x2=y2=z2=0.0;
848 box[XX][YY] = x1;
849 box[XX][ZZ] = y1;
850 box[YY][XX] = z1;
851 box[YY][ZZ] = x2;
852 box[ZZ][XX] = y2;
853 box[ZZ][YY] = z2;
856 return bVel;
859 static void read_whole_conf(const char *infile,char *title,
860 t_atoms *atoms, rvec x[],rvec *v, matrix box)
862 FILE *in;
863 int ndec;
864 t_symtab symtab;
866 /* open file */
867 in=gmx_fio_fopen(infile,"r");
869 open_symtab(&symtab);
870 get_w_conf(in, infile, title, &symtab, atoms, &ndec, x, v, box);
871 /* We can't free the symbols, as they are still used in atoms, so
872 * the only choice is to leak them. */
873 free_symtab(&symtab);
875 gmx_fio_fclose(in);
878 gmx_bool gro_next_x_or_v(FILE *status,t_trxframe *fr)
880 t_atoms atoms;
881 t_symtab symtab;
882 char title[STRLEN],*p;
883 double tt;
884 int ndec=0,i;
886 if (gmx_eof(status))
887 return FALSE;
889 open_symtab(&symtab);
890 atoms.nr=fr->natoms;
891 snew(atoms.atom,fr->natoms);
892 atoms.nres=fr->natoms;
893 snew(atoms.resinfo,fr->natoms);
894 snew(atoms.atomname,fr->natoms);
896 fr->bV = get_w_conf(status,title,title,&symtab,&atoms,&ndec,fr->x,fr->v,fr->box);
897 fr->bPrec = TRUE;
898 fr->prec = 1;
899 /* prec = 10^ndec: */
900 for(i=0; i<ndec; i++)
901 fr->prec *= 10;
902 fr->title = title;
903 fr->bTitle = TRUE;
904 fr->bX = TRUE;
905 fr->bBox = TRUE;
907 sfree(atoms.atom);
908 sfree(atoms.resinfo);
909 sfree(atoms.atomname);
910 done_symtab(&symtab);
912 if ((p=strstr(title,"t=")) != NULL) {
913 p+=2;
914 if (sscanf(p,"%lf",&tt)==1) {
915 fr->time = tt;
916 fr->bTime = TRUE;
917 } else {
918 fr->time = 0;
919 fr->bTime = FALSE;
923 if (atoms.nr != fr->natoms)
924 gmx_fatal(FARGS,"Number of atoms in gro frame (%d) doesn't match the number in the previous frame (%d)",atoms.nr,fr->natoms);
926 return TRUE;
929 int gro_first_x_or_v(FILE *status,t_trxframe *fr)
931 char title[STRLEN];
933 frewind(status);
934 fprintf(stderr,"Reading frames from gro file");
935 get_coordnum_fp(status, title, &fr->natoms);
936 frewind(status);
937 fprintf(stderr," '%s', %d atoms.\n",title, fr->natoms);
938 fr->bTitle = TRUE;
939 fr->title = title;
940 if (fr->natoms==0)
941 gmx_file("No coordinates in gro file");
943 snew(fr->x,fr->natoms);
944 snew(fr->v,fr->natoms);
945 gro_next_x_or_v(status, fr);
947 return fr->natoms;
950 static void make_hconf_format(int pr,gmx_bool bVel,char format[])
952 int l,vpr;
954 /* build format string for printing,
955 something like "%8.3f" for x and "%8.4f" for v */
956 if (pr<0)
957 pr=0;
958 if (pr>30)
959 pr=30;
960 l=pr+5;
961 vpr=pr+1;
962 if (bVel)
963 sprintf(format,"%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
964 l,pr,l,pr,l,pr,l,vpr,l,vpr,l,vpr);
965 else
966 sprintf(format,"%%%d.%df%%%d.%df%%%d.%df\n",l,pr,l,pr,l,pr);
970 static void write_hconf_box(FILE *out,int pr,matrix box)
972 char format[100];
973 int l;
975 if (pr<5)
976 pr=5;
977 l=pr+5;
979 if (box[XX][YY] || box[XX][ZZ] || box[YY][XX] || box[YY][ZZ] ||
980 box[ZZ][XX] || box[ZZ][YY]) {
981 sprintf(format,"%%%d.%df%%%d.%df%%%d.%df"
982 "%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df%%%d.%df\n",
983 l,pr,l,pr,l,pr,l,pr,l,pr,l,pr,l,pr,l,pr,l,pr);
984 fprintf(out,format,
985 box[XX][XX],box[YY][YY],box[ZZ][ZZ],
986 box[XX][YY],box[XX][ZZ],box[YY][XX],
987 box[YY][ZZ],box[ZZ][XX],box[ZZ][YY]);
988 } else {
989 sprintf(format,"%%%d.%df%%%d.%df%%%d.%df\n",l,pr,l,pr,l,pr);
990 fprintf(out,format,
991 box[XX][XX],box[YY][YY],box[ZZ][ZZ]);
995 void write_hconf_indexed_p(FILE *out,const char *title,t_atoms *atoms,
996 int nx,atom_id index[], int pr,
997 rvec *x,rvec *v,matrix box)
999 char resnm[6],nm[6],format[100];
1000 int ai,i,resind,resnr;
1002 bromacs(format,99);
1003 fprintf (out,"%s\n",(title && title[0])?title:format);
1004 fprintf (out,"%5d\n",nx);
1006 make_hconf_format(pr,v!=NULL,format);
1008 for (i=0; (i<nx); i++) {
1009 ai=index[i];
1011 resind = atoms->atom[ai].resind;
1012 strncpy(resnm," ??? ",sizeof(resnm)-1);
1013 if (resind < atoms->nres) {
1014 strncpy(resnm,*atoms->resinfo[resind].name,sizeof(resnm)-1);
1015 resnr = atoms->resinfo[resind].nr;
1016 } else {
1017 strncpy(resnm," ??? ",sizeof(resnm)-1);
1018 resnr = resind + 1;
1021 if (atoms->atom)
1022 strncpy(nm,*atoms->atomname[ai],sizeof(nm)-1);
1023 else
1024 strncpy(nm," ??? ",sizeof(nm)-1);
1026 fprintf(out,"%5d%-5.5s%5.5s%5d",resnr%100000,resnm,nm,(ai+1)%100000);
1027 /* next fprintf uses built format string */
1028 if (v)
1029 fprintf(out,format,
1030 x[ai][XX], x[ai][YY], x[ai][ZZ], v[ai][XX],v[ai][YY],v[ai][ZZ]);
1031 else
1032 fprintf(out,format,
1033 x[ai][XX], x[ai][YY], x[ai][ZZ]);
1036 write_hconf_box(out,pr,box);
1038 fflush(out);
1041 static void write_hconf_mtop(FILE *out,const char *title,gmx_mtop_t *mtop,
1042 int pr,
1043 rvec *x,rvec *v,matrix box)
1045 char format[100];
1046 int i,resnr;
1047 gmx_mtop_atomloop_all_t aloop;
1048 t_atom *atom;
1049 char *atomname,*resname;
1051 bromacs(format,99);
1052 fprintf (out,"%s\n",(title && title[0])?title:format);
1053 fprintf (out,"%5d\n",mtop->natoms);
1055 make_hconf_format(pr,v!=NULL,format);
1057 aloop = gmx_mtop_atomloop_all_init(mtop);
1058 while (gmx_mtop_atomloop_all_next(aloop,&i,&atom)) {
1059 gmx_mtop_atomloop_all_names(aloop,&atomname,&resnr,&resname);
1061 fprintf(out,"%5d%-5.5s%5.5s%5d",
1062 resnr%100000,resname,atomname,(i+1)%100000);
1063 /* next fprintf uses built format string */
1064 if (v)
1065 fprintf(out,format,
1066 x[i][XX], x[i][YY], x[i][ZZ], v[i][XX],v[i][YY],v[i][ZZ]);
1067 else
1068 fprintf(out,format,
1069 x[i][XX], x[i][YY], x[i][ZZ]);
1072 write_hconf_box(out,pr,box);
1074 fflush(out);
1077 void write_hconf_p(FILE *out,const char *title,t_atoms *atoms, int pr,
1078 rvec *x,rvec *v,matrix box)
1080 atom_id *aa;
1081 int i;
1083 snew(aa,atoms->nr);
1084 for(i=0; (i<atoms->nr); i++)
1085 aa[i]=i;
1086 write_hconf_indexed_p(out,title,atoms,atoms->nr,aa,pr,x,v,box);
1087 sfree(aa);
1090 void write_conf_p(const char *outfile, const char *title,
1091 t_atoms *atoms, int pr,
1092 rvec *x, rvec *v,matrix box)
1094 FILE *out;
1096 out=gmx_fio_fopen(outfile,"w");
1097 write_hconf_p(out,title,atoms,pr,x,v,box);
1099 gmx_fio_fclose (out);
1102 static void write_conf(const char *outfile, const char *title, t_atoms *atoms,
1103 rvec *x, rvec *v,matrix box)
1105 write_conf_p(outfile, title, atoms, 3, x, v, box);
1108 void write_sto_conf_indexed(const char *outfile,const char *title,
1109 t_atoms *atoms,
1110 rvec x[],rvec *v,int ePBC,matrix box,
1111 atom_id nindex,atom_id index[])
1113 FILE *out;
1114 int ftp;
1115 t_trxframe fr;
1117 ftp=fn2ftp(outfile);
1118 switch (ftp) {
1119 case efGRO:
1120 out=gmx_fio_fopen(outfile,"w");
1121 write_hconf_indexed_p(out, title, atoms, nindex, index, 3, x, v, box);
1122 gmx_fio_fclose(out);
1123 break;
1124 case efG96:
1125 clear_trxframe(&fr,TRUE);
1126 fr.bTitle = TRUE;
1127 fr.title = title;
1128 fr.natoms = atoms->nr;
1129 fr.bAtoms = TRUE;
1130 fr.atoms = atoms;
1131 fr.bX = TRUE;
1132 fr.x = x;
1133 if (v) {
1134 fr.bV = TRUE;
1135 fr.v = v;
1137 fr.bBox = TRUE;
1138 copy_mat(box,fr.box);
1139 out=gmx_fio_fopen(outfile,"w");
1140 write_g96_conf(out, &fr, nindex, index);
1141 gmx_fio_fclose(out);
1142 break;
1143 case efPDB:
1144 case efBRK:
1145 case efENT:
1146 case efPQR:
1147 out=gmx_fio_fopen(outfile,"w");
1148 write_pdbfile_indexed(out,title,atoms,x,ePBC,box,' ',-1,nindex,index,NULL,TRUE);
1149 gmx_fio_fclose(out);
1150 break;
1151 case efESP:
1152 out=gmx_fio_fopen(outfile,"w");
1153 write_espresso_conf_indexed(out, title, atoms, nindex, index, x, v, box);
1154 gmx_fio_fclose(out);
1155 break;
1156 case efTPR:
1157 case efTPB:
1158 case efTPA:
1159 gmx_fatal(FARGS,"Sorry, can not write a topology to %s",outfile);
1160 break;
1161 default:
1162 gmx_incons("Not supported in write_sto_conf_indexed");
1166 static void write_xyz_conf(const char *outfile,const char *title,
1167 t_atoms *atoms,rvec *x)
1169 FILE *fp;
1170 int i,anr;
1171 real value;
1172 char *ptr,*name;
1173 gmx_atomprop_t aps=gmx_atomprop_init();
1175 fp = gmx_fio_fopen(outfile,"w");
1176 fprintf(fp,"%3d\n",atoms->nr);
1177 fprintf(fp,"%s\n",title);
1178 for(i=0; (i<atoms->nr); i++) {
1179 anr = atoms->atom[i].atomnumber;
1180 name = *atoms->atomname[i];
1181 if (anr == NOTSET) {
1182 if (gmx_atomprop_query(aps,epropElement,"???",name,&value))
1183 anr = gmx_nint(value);
1185 if ((ptr = gmx_atomprop_element(aps,anr)) == NULL)
1186 ptr = name;
1187 fprintf(fp,"%3s%10.5f%10.5f%10.5f\n",ptr,
1188 10*x[i][XX],10*x[i][YY],10*x[i][ZZ]);
1190 gmx_fio_fclose(fp);
1191 gmx_atomprop_destroy(aps);
1194 void write_sto_conf(const char *outfile,const char *title,t_atoms *atoms,
1195 rvec x[],rvec *v,int ePBC,matrix box)
1197 FILE *out;
1198 int ftp;
1199 t_trxframe fr;
1201 ftp=fn2ftp(outfile);
1202 switch (ftp) {
1203 case efGRO:
1204 write_conf(outfile, title, atoms, x, v, box);
1205 break;
1206 case efG96:
1207 clear_trxframe(&fr,TRUE);
1208 fr.bTitle = TRUE;
1209 fr.title = title;
1210 fr.natoms = atoms->nr;
1211 fr.bAtoms = TRUE;
1212 fr.atoms = atoms;
1213 fr.bX = TRUE;
1214 fr.x = x;
1215 if (v) {
1216 fr.bV = TRUE;
1217 fr.v = v;
1219 fr.bBox = TRUE;
1220 copy_mat(box,fr.box);
1221 out=gmx_fio_fopen(outfile,"w");
1222 write_g96_conf(out, &fr, -1, NULL);
1223 gmx_fio_fclose(out);
1224 break;
1225 case efXYZ:
1226 write_xyz_conf(outfile,(strlen(title) > 0) ? title : outfile,atoms,x);
1227 break;
1228 case efPDB:
1229 case efBRK:
1230 case efENT:
1231 out=gmx_fio_fopen(outfile,"w");
1232 write_pdbfile(out, title, atoms, x, ePBC, box, ' ', -1,NULL,TRUE);
1233 gmx_fio_fclose(out);
1234 break;
1235 case efESP:
1236 out=gmx_fio_fopen(outfile,"w");
1237 write_espresso_conf_indexed(out, title, atoms, atoms->nr, NULL, x, v, box);
1238 gmx_fio_fclose(out);
1239 break;
1240 case efTPR:
1241 case efTPB:
1242 case efTPA:
1243 gmx_fatal(FARGS,"Sorry, can not write a topology to %s",outfile);
1244 break;
1245 default:
1246 gmx_incons("Not supported in write_sto_conf");
1250 void write_sto_conf_mtop(const char *outfile,const char *title,
1251 gmx_mtop_t *mtop,
1252 rvec x[],rvec *v,int ePBC,matrix box)
1254 int ftp;
1255 FILE *out;
1256 t_atoms atoms;
1258 ftp=fn2ftp(outfile);
1259 switch (ftp) {
1260 case efGRO:
1261 out = gmx_fio_fopen(outfile,"w");
1262 write_hconf_mtop(out,title,mtop,3,x,v,box);
1263 gmx_fio_fclose(out);
1264 break;
1265 default:
1266 /* This is a brute force approach which requires a lot of memory.
1267 * We should implement mtop versions of all writing routines.
1269 atoms = gmx_mtop_global_atoms(mtop);
1271 write_sto_conf(outfile,title,&atoms,x,v,ePBC,box);
1273 done_atom(&atoms);
1274 break;
1278 static int get_xyz_coordnum(const char *infile)
1280 FILE *fp;
1281 int n;
1283 fp = gmx_fio_fopen(infile,"r");
1284 if (fscanf(fp,"%d",&n) != 1)
1285 gmx_fatal(FARGS,"Can not read number of atoms from %s",infile);
1286 gmx_fio_fclose(fp);
1288 return n;
1291 static void read_xyz_conf(const char *infile,char *title,
1292 t_atoms *atoms,rvec *x)
1294 FILE *fp;
1295 int i,n;
1296 double xx,yy,zz;
1297 t_symtab *tab;
1298 char atomnm[32],buf[STRLEN];
1300 snew(tab,1);
1301 fp = gmx_fio_fopen(infile,"r");
1302 fgets2(buf,STRLEN-1,fp);
1303 if (sscanf(buf,"%d",&n) != 1)
1304 gmx_fatal(FARGS,"Can not read number of atoms from %s",infile);
1305 fgets2(buf,STRLEN-1,fp);
1306 strcpy(title,buf);
1307 for(i=0; (i<n); i++) {
1308 fgets2(buf,STRLEN-1,fp);
1309 if (sscanf(buf,"%s%lf%lf%lf",atomnm,&xx,&yy,&zz) != 4)
1310 gmx_fatal(FARGS,"Can not read coordinates from %s",infile);
1311 atoms->atomname[i] = put_symtab(tab,atomnm);
1312 x[i][XX] = xx*0.1;
1313 x[i][YY] = yy*0.1;
1314 x[i][ZZ] = zz*0.1;
1316 gmx_fio_fclose(fp);
1319 void get_stx_coordnum(const char *infile,int *natoms)
1321 FILE *in;
1322 int ftp,tpxver,tpxgen;
1323 t_trxframe fr;
1324 char g96_line[STRLEN+1];
1326 ftp=fn2ftp(infile);
1327 range_check(ftp,0,efNR);
1328 switch (ftp) {
1329 case efGRO:
1330 get_coordnum(infile, natoms);
1331 break;
1332 case efG96:
1333 in=gmx_fio_fopen(infile,"r");
1334 fr.title = NULL;
1335 fr.natoms = -1;
1336 fr.atoms = NULL;
1337 fr.x = NULL;
1338 fr.v = NULL;
1339 fr.f = NULL;
1340 *natoms=read_g96_conf(in,infile,&fr,g96_line);
1341 gmx_fio_fclose(in);
1342 break;
1343 case efXYZ:
1344 *natoms = get_xyz_coordnum(infile);
1345 break;
1346 case efPDB:
1347 case efBRK:
1348 case efENT:
1349 in=gmx_fio_fopen(infile,"r");
1350 get_pdb_coordnum(in, natoms);
1351 gmx_fio_fclose(in);
1352 break;
1353 case efESP:
1354 *natoms = get_espresso_coordnum(infile);
1355 break;
1356 case efTPA:
1357 case efTPB:
1358 case efTPR: {
1359 t_tpxheader tpx;
1361 read_tpxheader(infile,&tpx,TRUE,&tpxver,&tpxgen);
1362 *natoms = tpx.natoms;
1363 break;
1365 default:
1366 gmx_fatal(FARGS,"File type %s not supported in get_stx_coordnum",
1367 ftp2ext(ftp));
1371 void read_stx_conf(const char *infile,char *title,t_atoms *atoms,
1372 rvec x[],rvec *v,int *ePBC,matrix box)
1374 FILE *in;
1375 char buf[256];
1376 gmx_mtop_t *mtop;
1377 t_topology top;
1378 t_trxframe fr;
1379 int i,ftp,natoms;
1380 real d;
1381 char g96_line[STRLEN+1];
1383 if (atoms->nr == 0)
1384 fprintf(stderr,"Warning: Number of atoms in %s is 0\n",infile);
1385 else if (atoms->atom == NULL)
1386 gmx_mem("Uninitialized array atom");
1388 if (ePBC)
1389 *ePBC = -1;
1391 ftp=fn2ftp(infile);
1392 switch (ftp) {
1393 case efGRO:
1394 read_whole_conf(infile, title, atoms, x, v, box);
1395 break;
1396 case efXYZ:
1397 read_xyz_conf(infile,title,atoms,x);
1398 break;
1399 case efG96:
1400 fr.title = title;
1401 fr.natoms = atoms->nr;
1402 fr.atoms = atoms;
1403 fr.x = x;
1404 fr.v = v;
1405 fr.f = NULL;
1406 in = gmx_fio_fopen(infile,"r");
1407 read_g96_conf(in, infile, &fr, g96_line);
1408 gmx_fio_fclose(in);
1409 copy_mat(fr.box,box);
1410 break;
1411 case efPDB:
1412 case efBRK:
1413 case efENT:
1414 read_pdb_conf(infile, title, atoms, x, ePBC, box, TRUE, NULL);
1415 break;
1416 case efESP:
1417 read_espresso_conf(infile,atoms,x,v,box);
1418 break;
1419 case efTPR:
1420 case efTPB:
1421 case efTPA:
1422 snew(mtop,1);
1423 i = read_tpx(infile,NULL,box,&natoms,x,v,NULL,mtop);
1424 if (ePBC)
1425 *ePBC = i;
1427 strcpy(title,*(mtop->name));
1429 /* Free possibly allocated memory */
1430 done_atom(atoms);
1432 *atoms = gmx_mtop_global_atoms(mtop);
1433 top = gmx_mtop_t_to_t_topology(mtop);
1434 tpx_make_chain_identifiers(atoms,&top.mols);
1436 sfree(mtop);
1437 /* The strings in the symtab are still in use in the returned t_atoms
1438 * structure, so we should not free them. But there is no place to put the
1439 * symbols; the only choice is to leak the memory...
1440 * So we clear the symbol table before freeing the topology structure. */
1441 free_symtab(&top.symtab);
1442 done_top(&top);
1444 break;
1445 default:
1446 gmx_incons("Not supported in read_stx_conf");