NAMD
PDB.C
Go to the documentation of this file.
1 
7 /*
8  PDB Class
9  Code to implement the PDB class. This reads in a bunch of
10  PDBData records from a file, given the filename. See PDB.h
11  for a bit more information.
12 */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #ifndef WIN32
17 #include <strings.h>
18 #endif
19 #include "common.h"
20 #include "PDB.h"
21 #include "SortableResizeArray.h"
22 
23 
24 #ifdef MEM_OPT_VERSION
25 //read in PDB from a file and eliminate the temporary memory usage of pdb atom list
26 PDB::PDB(const char *pdbfilename, int expectedNumAtoms){
27  FILE *infile;
28  char buf[160];
29 
30  altlocArray = 0;
31  atomArray = new PDBCoreData[expectedNumAtoms];
32 
33  atomCount = 0;
34  atomListHead = atomListTail = NULL;
35  infile = Fopen(pdbfilename, "r");
36  if (! infile) {
37  char s[500];
38  sprintf(s, "Cannot open file '%s' for input in PDB::PDB.", pdbfilename);
39  NAMD_err(s);
40  }
41 
42  // loop through each line in the file and get a record
43  while ( fgets(buf, 150, infile) ) {
44  PDBData *newelement;
45  char *s;
46  for (s=buf; *s && *s!='\n'; s++) // chop off the '\n'
47  ;
48  *s = 0;
49  if ( s == (buf + 149) ) {
50  char s[500];
51  sprintf( s, "Line too long in pdbfile %s:\n%s\n", pdbfilename, buf);
52  NAMD_die(s);
53  }
54  *(s+1) = 0; // just to be on the safe side
55 
56  // I now have a string; make a PDBData element out of it
57  newelement = new_PDBData(buf);
58  if (!newelement) {
59  NAMD_die("Could not allocate PDBData.\n");
60  }
61  // I only know how to deal with ATOM and HETATM types; and
62  // I want to throw away the unknown data types; so
63  if (newelement -> type() != PDBData::ATOM &&
64  newelement -> type() != PDBData::HETATM) {
65  delete newelement;
66  } else {
67  PDBAtom *thisAtom = (PDBAtom *)newelement;
68  const BigReal *coor = thisAtom->coordinates();
69  atomArray[atomCount].coor[0] = coor[0];
70  atomArray[atomCount].coor[1] = coor[1];
71  atomArray[atomCount].coor[2] = coor[2];
72  atomArray[atomCount].myoccupancy = thisAtom->occupancy();
73  atomArray[atomCount].tempfactor = thisAtom->temperaturefactor();
74  atomCount++;
75  delete newelement;
76  if(atomCount > expectedNumAtoms) NAMD_die("Number of pdb and psf atoms are not the same!");
77  }
78  } // input while loop
79  Fclose(infile);
80 }
81 #endif
82 
83 PDB::PDB(molfile_plugin_t *pIOHdl, void *pIOFileHdl, int numAtoms, const float *occupancy, const float *bfactor){
84 #ifdef MEM_OPT_VERSION
85  NAMD_die("Sorry, plugin IO is not supported in the memory optimized version.");
86 #else
87  molfile_timestep_t ts;
88  float *atomcoords;
89  memset(&ts, 0, sizeof(molfile_timestep_t));
90 
91  /* set defaults for unit cell information */
92  ts.A = ts.B = ts.C = 0.0f;
93  ts.alpha = ts.beta = ts.gamma = 90.0f;
94 
95  atomCount = numAtoms;
96 
97  atomcoords = (float *) malloc(3*numAtoms*sizeof(float));
98  memset(atomcoords, 0, 3*numAtoms*sizeof(float));
99  ts.coords = atomcoords;
100 
101  if (pIOHdl->read_next_timestep(pIOFileHdl, numAtoms, &ts)) {
102  free(atomcoords);
103  pIOHdl->close_file_read(pIOFileHdl);
104  NAMD_die("ERROR: failed reading atom coordinates");
105  }
106 
107  //load coordinates to PDB object
108  //Note: the PDBAtom structure is very redundant in this case
109  PDBAtom *tmpAtoms = atomAlloc = new PDBAtom[numAtoms];
110  atomArray = new PDBAtomPtr[numAtoms];
111  BigReal tmpCoords[3];
112  for(int i=0; i<numAtoms; i++) {
113  PDBAtom *thisAtom = tmpAtoms+i;
114  atomArray[i] = thisAtom;
115 
116  tmpCoords[0] = atomcoords[0];
117  tmpCoords[1] = atomcoords[1];
118  tmpCoords[2] = atomcoords[2];
119  atomcoords += 3; //set to the next atom
120  thisAtom->coordinates(tmpCoords);
121  }
122  free(ts.coords);
123 
124  if(occupancy) {
125  for(int i=0; i<numAtoms; i++) {
126  PDBAtom *thisAtom = tmpAtoms+i;
127  thisAtom->occupancy((BigReal)occupancy[i]);
128  }
129  }
130  if(bfactor) {
131  for(int i=0; i<numAtoms; i++) {
132  PDBAtom *thisAtom = tmpAtoms+i;
133  thisAtom->temperaturefactor((BigReal)bfactor[i]);
134  }
135  }
136 #endif
137 }
138 
139 
140 // read in a file and stick all the elements on the appropriate list
141 PDB::PDB( const char *pdbfilename) {
142  FILE *infile;
143  char buf[160];
144 
145  atomCount = 0;
146  atomListHead = atomListTail = NULL;
147  infile = Fopen(pdbfilename, "r");
148  if (! infile) {
149  char s[500];
150  sprintf(s, "Cannot open file '%s' for input in PDB::PDB.", pdbfilename);
151  NAMD_err(s);
152  }
153 
154  // loop through each line in the file and get a record
155  while ( fgets(buf, 150, infile) ) {
156  PDBData *newelement;
157  char *s;
158  for (s=buf; *s && *s!='\n'; s++) // chop off the '\n'
159  ;
160  *s = 0;
161  if ( s == (buf + 149) ) {
162  char s[500];
163  sprintf( s, "Line too long in pdbfile %s:\n%s\n", pdbfilename, buf);
164  NAMD_die(s);
165  }
166  *(s+1) = 0; // just to be on the safe side
167 
168  // I now have a string; make a PDBData element out of it
169  newelement = new_PDBData(buf);
170  if (!newelement) {
171  NAMD_die("Could not allocate PDBData.\n");
172  }
173  // I only know how to deal with ATOM and HETATM types; and
174  // I want to throw away the unknown data types; so
175  if (newelement -> type() != PDBData::ATOM &&
176  newelement -> type() != PDBData::HETATM) {
177  delete newelement;
178  } else {
179  add_atom_element( (PDBAtom *) newelement);
180  }
181  } // input while loop
182  Fclose(infile);
183 
184  // now I have a linked list, and I know the size. However,
185  // that's got pretty slow access time for ramdom fetches, so
186  // I'll turn it into an array
187  {
188 
189 #ifdef MEM_OPT_VERSION
190 //pruning the PDBData structure into PDBCoreData by only leaving X/Y/Z, occupancy and temperaturefactor
191  altlocArray = new char[atomCount];
192  atomArray = new PDBCoreData[atomCount];
193  if(atomArray == NULL)
194  NAMD_die("memory allocation failed in PDB::PDB");
195 
196  PDBAtomList *tmp = atomListHead;
197  for(int i=0; tmp!=NULL; tmp=tmp->next, i++){
198  const BigReal *coor = tmp->data->coordinates();
199  atomArray[i].coor[0] = coor[0];
200  atomArray[i].coor[1] = coor[1];
201  atomArray[i].coor[2] = coor[2];
202  atomArray[i].myoccupancy = tmp->data->occupancy();
203  atomArray[i].tempfactor = tmp->data->temperaturefactor();
204  altlocArray[i] = tmp->data->alternatelocation()[0];
205  }
206 
207  //free the PDBAtomList
208  tmp = atomListHead;
209  while(tmp!=NULL){
210  PDBAtomList *nextTmp = tmp->next;
211  delete tmp->data;
212  delete tmp;
213  tmp = nextTmp;
214  }
215  atomListHead = atomListTail = NULL;
216 #else
217  atomAlloc = 0;
218  atomArray = new PDBAtomPtr[atomCount];
219  if ( atomArray == NULL )
220  {
221  NAMD_die("memory allocation failed in PDB::PDB");
222  }
223  PDBAtomList *tmp = atomListHead;
224  int i=0; // just need to copy the pointers
225  for (i=0, tmp = atomListHead; tmp != NULL; tmp = tmp -> next, i++) {
226  atomArray[i] = tmp -> data;
227  }
228  // now delete the linked list (w/o deleting the data)
229  PDBAtomList *tmp2;
230  for (tmp2 = tmp = atomListHead; tmp != NULL; tmp = tmp2) {
231  tmp2 = tmp->next;
232  delete tmp;
233  }
234  atomListHead = atomListTail = NULL;
235 #endif
236  } // everything converted
237 
238 }
239 
240 // Destructor - delete all the data pointed to by the array
241 // and then delete the array
242 PDB::~PDB( void )
243 {
244 #ifndef MEM_OPT_VERSION
245  int i;
246  if ( atomAlloc ) {
247  delete [] atomAlloc;
248  } else {
249  for (i=atomCount-1; i>=0; i--)
250  delete atomArray[i];
251  }
252 #else
253  delete [] altlocArray;
254 #endif
255  delete [] atomArray;
256  atomArray = NULL;
257  atomCount = 0;
258 }
259 
260 // print the PDB file out to a given file name
261 void PDB::write(const char *outfilename, const char *commentline)
262 {
263  int i;
264  char s[200];
265  FILE *outfile;
266  if ((outfile = fopen(outfilename, "w")) == NULL) {
267  sprintf(s, "Cannot open file '%s' in PDB::write.", outfilename);
268  NAMD_err(s);
269  }
270 
271  if (commentline != NULL)
272  {
273  sprintf(s, "REMARK %s\n", commentline);
274  if (fputs(s, outfile) == EOF)
275  {
276  NAMD_err("EOF in PDB::write writing the comment line - file system full?");
277  }
278  }
279 
280  for (i=0; i<atomCount; i++){ // I only contain ATOM/HETATM records
281 #ifdef MEM_OPT_VERSION
282  atomArray[i].sprint(s, PDBData::COLUMNS);
283 #else
284  atomArray[i]->sprint(s, PDBData::COLUMNS);
285 #endif
286  if ( (fputs(s, outfile) == EOF) ||
287  (fputs("\n", outfile) == EOF) ) {
288  sprintf(s, "EOF in PDB::write line %d - file system full?", i);
289  NAMD_err(s);
290  }
291  }
292  if (fputs("END\n", outfile) == EOF) {
293  NAMD_err("EOF in PDB::write while printing 'END' -- file system full?");
294  }
295  if (fclose(outfile) == EOF) {
296  NAMD_err("EOF in PDB::write while closing -- file system full?");
297  }
298 
299 }
300 
301 // store the info on the linked list
302 void PDB::add_atom_element( PDBAtom *newAtom)
303 {
304  PDBAtomList *tmp = new PDBAtomList;
305  if ( tmp == NULL )
306  {
307  NAMD_die("memory allocation failed in PDB::add_atom_element");
308  }
309  tmp -> data = newAtom;
310  tmp -> next = NULL;
311 
312  if (atomListHead == NULL) { // make the list
313  atomListHead = atomListTail = tmp;
314  } else {
315  atomListTail -> next = tmp; // add to the tail
316  atomListTail = tmp;
317  }
318  atomCount++;
319 }
320 
321 
322 // return the number of atoms found
323 int PDB::num_atoms( void)
324 {
325  return atomCount;
326 }
327 
328 
329 // Reset all the atom positions. This is used in preparation for
330 // output in cases like the restart files, etc.
332 {
333 #ifdef MEM_OPT_VERSION
334  for(int i=0; i<atomCount; i++){
335  atomArray[i].coor[0] = pos[i].x;
336  atomArray[i].coor[1] = pos[i].y;
337  atomArray[i].coor[2] = pos[i].z;
338  }
339 #else
340  int i;
341  PDBAtomPtr *atomptr;
342  for (i=0, atomptr=atomArray; i<atomCount; atomptr++, i++)
343  {
344  (*atomptr)->xcoor(pos[i].x);
345  (*atomptr)->ycoor(pos[i].y);
346  (*atomptr)->zcoor(pos[i].z);
347  }
348 #endif
349 }
350 
351 void PDB::get_position_for_atom(Vector *pos, int aid){
352 #ifdef MEM_OPT_VERSION
353  pos->x = atomArray[aid].coor[0];
354  pos->y = atomArray[aid].coor[1];
355  pos->z = atomArray[aid].coor[2];
356 #else
357  PDBAtomPtr *atomptr = &atomArray[aid];
358  pos->x = (*atomptr)->xcoor();
359  pos->y = (*atomptr)->ycoor();
360  pos->z = (*atomptr)->zcoor();
361 #endif
362 }
363 
364 // Get all the atom positions into a list of Vectors
366 {
367 #ifdef MEM_OPT_VERSION
368  for(int i=0; i<atomCount; i++){
369  pos[i].x = atomArray[i].coor[0];
370  pos[i].y = atomArray[i].coor[1];
371  pos[i].z = atomArray[i].coor[2];
372  }
373 #else
374  int i;
375  PDBAtomPtr *atomptr;
376 
377  for (i=0, atomptr=atomArray; i<atomCount; atomptr++, i++)
378  {
379  pos[i].x = (*atomptr)->xcoor();
380  pos[i].y = (*atomptr)->ycoor();
381  pos[i].z = (*atomptr)->zcoor();
382  }
383 #endif
384 }
385 
386 // given an index, return that atom
387 #ifdef MEM_OPT_VERSION
388 PDBCoreData *PDB::atom(int place){
389  if(place<0 || place>=atomCount) return NULL;
390  return &atomArray[place];
391 }
392 #else
393 PDBAtom *PDB::atom(int place)
394 {
395  if (place <0 || place >= atomCount)
396  return NULL;
397  return atomArray[place];
398 }
399 #endif
400 
401 
402 // find the lowest and highest bounds based on a fraction of the atoms
403 //void PDB::find_extremes(BigReal *min, BigReal *max, Vector rec, BigReal frac) const
404 void PDB::find_extremes_helper(
406  BigReal &min, BigReal &max, Vector rec, BigReal frac
407  )
408 {
410 #ifdef MEM_OPT_VERSION
411  PDBCoreData *atomptr = atomArray;
412  for(int i=0; i<atomCount; i++, atomptr++){
413  Vector pos(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
414  c_i[i] = rec*pos;
415  }
416 #else
417  PDBAtomPtr *atomptr = atomArray;
418  for (int i=0; i<atomCount; ++i, ++atomptr) {
419  PDBAtom *atom = *atomptr;
420  Vector pos(atom->xcoor(),atom->ycoor(),atom->zcoor());
421  c_i[i] = rec*pos;
422  }
423 #endif
424  coor.sort();
425  int ilow = (int)((1.0 - frac) * atomCount);
426  if ( ilow < 0 ) ilow = 0;
427  if ( ilow > atomCount/2 ) ilow = atomCount/2;
428  int ihigh = atomCount - ilow - 1;
429  BigReal span = coor[ihigh] - coor[ilow];
430  BigReal extension = (1.0 - frac) * span / (2.0 * frac - 1.0);
431  max = coor[ihigh] + extension;
432  min = coor[ilow] - extension;
433 }
434 
435 // Find the extreme edges of molecule in scaled coordinates,
436 // where "frac" sets bounds based on a fraction of the atoms.
437 void PDB::find_extremes(const Lattice &lattice, BigReal frac) {
438  if (atomCount == 0) {
439  smin = smax = 0;
440  }
441  else if (frac < 1.0) {
442  // for now use the previous "sort the array" approach
443  // for solving "frac"th largest and smallest selection problems
445  coor.resize(atomCount); // allocate array space once
446  find_extremes_helper(coor, smin.x, smax.x, lattice.a_r(), frac);
447  find_extremes_helper(coor, smin.y, smax.y, lattice.b_r(), frac);
448  find_extremes_helper(coor, smin.z, smax.z, lattice.c_r(), frac);
449  }
450  else {
451  // finding absolute min and max does not require sorting
452 #ifdef MEM_OPT_VERSION
453  PDBCoreData *atomptr = atomArray;
454  Vector p(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
455 #else
456  PDBAtomPtr *atomptr = atomArray;
457  PDBAtom *atom = *atomptr;
458  Vector p(atom->xcoor(),atom->ycoor(),atom->zcoor());
459 #endif
460  Vector s(lattice.a_r()*p, lattice.b_r()*p, lattice.c_r()*p);
461  smin = smax = s;
462  atomptr++;
463  for(int i=1; i<atomCount; i++, atomptr++){
464 #ifdef MEM_OPT_VERSION
465  p = Vector(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
466 #else
467  atom = *atomptr;
468  p = Vector (atom->xcoor(),atom->ycoor(),atom->zcoor());
469 #endif
470  s = Vector(lattice.a_r()*p, lattice.b_r()*p, lattice.c_r()*p);
471  if (smin.x > s.x) smin.x = s.x;
472  else if (smax.x < s.x) smax.x = s.x;
473  if (smin.y > s.y) smin.y = s.y;
474  else if (smax.y < s.y) smax.y = s.y;
475  if (smin.z > s.z) smin.z = s.z;
476  else if (smax.z < s.z) smax.z = s.z;
477  }
478  }
479  // shift using the origin
480  BigReal origin_shift;
481  origin_shift = lattice.a_r() * lattice.origin();
482  smin.x -= origin_shift;
483  smax.x -= origin_shift;
484  origin_shift = lattice.b_r() * lattice.origin();
485  smin.y -= origin_shift;
486  smax.y -= origin_shift;
487  origin_shift = lattice.c_r() * lattice.origin();
488  smin.z -= origin_shift;
489  smax.z -= origin_shift;
490 }
491 
492 //#define TEST_PDB_CLASS
493 #ifdef TEST_PDB_CLASS
494 
495 main()
496 {
497  PDB *pdb = new PDB("pti.pdb");
498  if ( atomArray == NULL )
499  {
500  NAMD_die("memory allocation failed in main of test PDB class");
501  }
502  ilist = pdb->find_atom_name("CA");
503  if (!ilist)
504  printf("None found.\n");
505  else {
506  int i;
507  char s[200];
508  for (i=0; i<ilist->num(); i++) {
509  pdb->atom((*ilist)[i]) -> sprint(s);
510  printf("%s\n", s);
511  }
512  delete ilist;
513  } // if ilist
514 
515  printf("Now, search through space.\n");
516 
517  ilist = pdb->find_atoms_in_region(4.38, 19.5, 3.0,
518  4.40, 20.0, 3.2 );
519  if (!ilist)
520  printf("None found.\n");
521  else {
522  int i;
523  char s[200];
524  printf("%d found\n", ilist -> num());
525  for (i=0; i<ilist->num(); i++) {
526  pdb->atom((*ilist)[i]) -> sprint(s);
527  printf("%s\n", s);
528  }
529  delete ilist;
530  }
531 }
532 #endif // TEST_PDB_CLASS
533 
534 
535 
536 // This function was borrowed from VMD code in "ReadPARM.C".
537 // It skips to a new line.
538 static int readtoeoln(FILE *f) {
539  char c;
540 
541  /* skip to eoln */
542  while((c = getc(f)) != '\n') {
543  if (c == EOF)
544  return -1;
545  }
546 
547  return 0;
548 }
549 
550 
551 
552 // read in an AMBER coordinate file and populate the PDB structure
553 PDB::PDB( const char *filename, Ambertoppar *amber_data)
554 { int i,j,k;
555  BigReal coor[3];
556  char buf[13],resname[5],atomname[5];
557  FILE *infile;
558  PDBAtom *pdb;
559 
560  if ((infile=Fopen(filename, "r")) == NULL)
561  NAMD_err("Can't open AMBER coordinate file!");
562 
563  readtoeoln(infile); // Skip the first line (title)
564 
565  fscanf(infile,"%d",&atomCount); // Read in num of atoms
566  if (atomCount != amber_data->Natom)
567  NAMD_die("Num of atoms in coordinate file is different from that in parm file!");
568  readtoeoln(infile);
569 
570 #ifdef MEM_OPT_VERSION
571  altlocArray = 0;
572  atomArray = new PDBCoreData[atomCount];
573 #else
574  atomAlloc = 0;
575  atomArray = new PDBAtomPtr[atomCount];
576 #endif
577 
578  if ( atomArray == NULL )
579  {
580  NAMD_die("memory allocation failed in PDB::PDB");
581  }
582 
583  // Read in the coordinates, which are in the format of 6F12.7
584  // Other fields are copied from "amber_data"
585  for (i=0; i<atomCount; ++i)
586  { // Read x,y,z coordinates
587  for (j=0; j<3; ++j)
588  { for (k=0; k<12; ++k)
589  { buf[k]=getc(infile);
590  if (buf[k]=='\n' || buf[k]=='\0' || buf[k]==EOF)
591  NAMD_die("Error reading AMBER coordinate file!");
592  }
593  buf[12] = '\0';
594  coor[j] = atof(buf);
595  }
596  if (i%2 == 1)
597  readtoeoln(infile);
598 #ifdef MEM_OPT_VERSION
599  atomArray[i].coor[0] = coor[0];
600  atomArray[i].coor[1] = coor[1];
601  atomArray[i].coor[2] = coor[2];
602  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
603  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
604 #else
605  // Copy name, resname and resid from "amber_data"
606  for (j=0; j<4; ++j)
607  { resname[j] = amber_data->ResNames[amber_data->AtomRes[i]*4+j];
608  atomname[j] = amber_data->AtomNames[i*4+j];
609  }
610  resname[4] = atomname[4] = '\0';
611  // Create a new PDB record, and fill in its entries
612  pdb = new PDBAtomRecord("");
613  pdb->name(atomname);
614  pdb->residuename(resname);
615  pdb->serialnumber(i+1);
616  pdb->residueseq(amber_data->AtomRes[i]+1);
617  pdb->coordinates(coor);
618  atomArray[i] = pdb; // Include the new record into the array
619 #endif
620  }
621 }
622 
623 // read in an AMBER coordinate file and populate the PDB structure
624 PDB::PDB( const char *filename, AmberParm7Reader::Ambertoppar *amber_data)
625 { int i,j,k;
626  BigReal coor[3];
627  char buf[13],resname[5],atomname[5];
628  FILE *infile;
629  PDBAtom *pdb;
630 
631  if ((infile=Fopen(filename, "r")) == NULL)
632  NAMD_err("Can't open AMBER coordinate file!");
633 
634  readtoeoln(infile); // Skip the first line (title)
635 
636  fscanf(infile,"%d",&atomCount); // Read in num of atoms
637  if (atomCount != amber_data->Natom)
638  NAMD_die("Num of atoms in coordinate file is different from that in parm file!");
639  readtoeoln(infile);
640 
641 #ifdef MEM_OPT_VERSION
642  altlocArray = 0;
643  atomArray = new PDBCoreData[atomCount];
644 #else
645  atomAlloc = 0;
646  atomArray = new PDBAtomPtr[atomCount];
647 #endif
648 
649  if ( atomArray == NULL )
650  {
651  NAMD_die("memory allocation failed in PDB::PDB");
652  }
653 
654  // Read in the coordinates, which are in the format of 6F12.7
655  // Other fields are copied from "amber_data"
656  for (i=0; i<atomCount; ++i)
657  { // Read x,y,z coordinates
658  for (j=0; j<3; ++j)
659  { for (k=0; k<12; ++k)
660  { buf[k]=getc(infile);
661  if (buf[k]=='\n' || buf[k]=='\0' || buf[k]==EOF)
662  NAMD_die("Error reading AMBER coordinate file!");
663  }
664  buf[12] = '\0';
665  coor[j] = atof(buf);
666  }
667  if (i%2 == 1)
668  readtoeoln(infile);
669 #ifdef MEM_OPT_VERSION
670  atomArray[i].coor[0] = coor[0];
671  atomArray[i].coor[1] = coor[1];
672  atomArray[i].coor[2] = coor[2];
673  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
674  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
675 #else
676  // Copy name, resname and resid from "amber_data"
677  strncpy(resname, amber_data->ResNames[amber_data->AtomRes[i]].c_str(), 5);
678  strncpy(atomname, amber_data->AtomNames[i].c_str(), 5);
679  // Create a new PDB record, and fill in its entries
680  pdb = new PDBAtomRecord("");
681  pdb->name(atomname);
682  pdb->residuename(resname);
683  pdb->serialnumber(i+1);
684  pdb->residueseq(amber_data->AtomRes[i]+1);
685  pdb->coordinates(coor);
686  atomArray[i] = pdb; // Include the new record into the array
687 #endif
688  }
689 }
690 
691 #define LINESIZE 100
692 
693 /* This constructor initializes the PDB data using a Gromacs
694  coordinate file, generating an error message if the file
695  can't be parsed or if its contents don't jive with what is in
696  the topo file <topology>. */
697 PDB::PDB(const char *filename, const GromacsTopFile *topology) {
698  int i;
699  char buf[LINESIZE];
700  FILE *infile;
701 
702  /* open up the coordinate file */
703  infile=Fopen(filename, "r");
704  if (infile == NULL)
705  NAMD_err("Can't open GROMACS coordinate file!");
706 
707  fgets(buf,LINESIZE-1,infile); // get the title
708  // if(strcmp(buf,topology->getSystemName()) != 0)
709  // NAMD_die("System names in topology and coordinate files differ.");
710 
711  fgets(buf,LINESIZE-1,infile); // get the number of atoms
712  sscanf(buf,"%d",&atomCount);
713  if (atomCount != topology->getNumAtoms())
714  NAMD_die("Num of atoms in coordinate file is different from that in topology file!");
715 
716  /* read in the atoms */
717 #ifdef MEM_OPT_VERSION
718  altlocArray = 0;
719  atomArray = new PDBCoreData[atomCount];
720 #else
721  atomAlloc = 0;
722  atomArray = new PDBAtomPtr[atomCount];
723 #endif
724  if ( atomArray == NULL )
725  NAMD_die("memory allocation failed in PDB::PDB");
726 
727 #ifdef MEM_OPT_VERSION
728  for(i=0; i<atomCount; i++){
729  fgets(buf,LINESIZE-1,infile); // get a line
730  char *buf2 = buf+20; // skip three fields to get to the coordinates
731  BigReal coor[3];
732  if(3 != sscanf(buf2,"%lf%lf%lf", &coor[0],&coor[1],&coor[2]))
733  NAMD_die("Couldn't get three coordinates from file.");
734 
735  coor[0] *= 10; // convert to angstroms from nanometers
736  coor[1] *= 10;
737  coor[2] *= 10;
738 
739  atomArray[i].coor[0] = coor[0];
740  atomArray[i].coor[1] = coor[1];
741  atomArray[i].coor[2] = coor[2];
742  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
743  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
744  }
745 #else
746  for (i=0;i<atomCount;i++) {
747  char *buf2, resname[11], atomname[11], atmtype[11];
748  int resnum, typenum;
749  Real charge,mass;
750  BigReal coor[3];
751  PDBAtom *pdb = new PDBAtomRecord("");
752 
753  fgets(buf,LINESIZE-1,infile); // get a line
754  buf2 = buf+20; // skip three fields to get to the coordinates
755  if(3 != sscanf(buf2,"%lf%lf%lf",
756  &coor[0],&coor[1],&coor[2]))
757  NAMD_die("Couldn't get three coordinates from file.");
758  topology->getAtom(i,&resnum,resname,
759  atomname,atmtype,&typenum,&charge,&mass);
760  coor[0] *= 10; // convert to angstroms from nanometers
761  coor[1] *= 10;
762  coor[2] *= 10;
763 
764  pdb->name(atomname);
765  pdb->residuename(resname);
766  pdb->serialnumber(i+1);
767  pdb->residueseq(resnum+1);
768  pdb->coordinates(coor);
769 
770  atomArray[i] = pdb; // Include the new record into the array
771  }
772 #endif
773 }
774 
775 #ifdef MEM_OPT_VERSION
776 void PDBCoreData::sprint( char *outstr, PDBData::PDBFormatStyle usestyle){
777  if(usestyle == PDBData::COLUMNS){
778  //sprint_columns copied from PDBAtom::sprint_columns
779  for(int i=0; i<79; i++) outstr[i] = 32;
780  outstr[79] = 0;
786  }else{
787  //sprint_fields
788  char tmpstr[50];
789  if (xcoor() == PDBAtom::default_coor)
790  sprintf(tmpstr, " #");
791  else
792  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, xcoor());
793  strcat(outstr, tmpstr);
794  if (ycoor() == PDBAtom::default_coor)
795  sprintf(tmpstr, " #");
796  else
797  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, ycoor());
798  strcat(outstr, tmpstr);
799  if (zcoor() == PDBAtom::default_coor)
800  sprintf(tmpstr, " #");
801  else
802  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, zcoor());
803  strcat(outstr, tmpstr);
804 
805  sprintf(tmpstr, " %*.*f", PDBAtom::LOCC, PDBAtom::LOCCPREC, occupancy());
806  strcat(outstr, tmpstr);
807 
808  sprintf(tmpstr, " %*.*f", PDBAtom::LTEMPF, PDBAtom::LTEMPFPREC, temperaturefactor());
809  strcat(outstr, tmpstr);
810  }
811 }
812 #endif
813 
static const BigReal default_coor
Definition: PDBData.h:155
Definition: PDB.h:36
void getAtom(int num, int *residue_number, char *residue_name, char *atom_name, char *atom_type, int *atom_typenum, Real *charge, Real *mass) const
void NAMD_err(const char *err_msg)
Definition: common.C:170
static const BigReal default_temperaturefactor
Definition: PDBData.h:157
void get_position_for_atom(Vector *, int)
Definition: PDB.C:351
BigReal temperaturefactor(void)
Definition: PDBData.C:450
Definition: PDB.h:31
Definition: Vector.h:72
void write(const char *outfilename, const char *commentline=NULL)
Definition: PDB.C:261
float Real
Definition: common.h:118
#define LINESIZE
Definition: PDB.C:691
BigReal z
Definition: Vector.h:74
void set_all_positions(Vector *)
Definition: PDB.C:331
BigReal zcoor(void)
Definition: PDBData.C:433
int num_atoms(void)
Definition: PDB.C:323
int getNumAtoms() const
static int readtoeoln(FILE *f)
Definition: PDB.C:538
void resize(int i)
Definition: ResizeArray.h:84
PDBAtom * data
Definition: PDB.h:32
const char * residuename(void)
Definition: PDBData.C:399
static Units next(Units u)
Definition: ParseOptions.C:48
static void sprintcol(char *s, int start, int len, const char *val)
Definition: PDBData.C:183
struct PAL * next
Definition: PDB.h:33
PDBAtom * atom(int place)
Definition: PDB.C:393
const BigReal * coordinates(void)
Definition: PDBData.C:438
BigReal ycoor(void)
Definition: PDBData.C:429
char * ResNames
Definition: parm.h:23
int residueseq(void)
Definition: PDBData.C:411
FILE * Fopen(const char *filename, const char *mode)
Definition: common.C:341
BigReal x
Definition: Vector.h:74
const char * alternatelocation(void)
Definition: PDBData.C:392
NAMD_HOST_DEVICE Vector a_r() const
Definition: Lattice.h:284
NAMD_HOST_DEVICE Vector b_r() const
Definition: Lattice.h:285
void NAMD_die(const char *err_msg)
Definition: common.C:147
const char * name(void)
Definition: PDBData.C:386
NAMD_HOST_DEVICE Vector c_r() const
Definition: Lattice.h:286
PDBFormatStyle
Definition: PDBData.h:48
BigReal xcoor(void)
Definition: PDBData.C:425
PDB(const char *pdbfilename)
Definition: PDB.C:141
void find_extremes(const Lattice &, BigReal frac=1.0)
Definition: PDB.C:437
int Fclose(FILE *fout)
Definition: common.C:435
int Natom
Definition: parm.h:17
iterator begin(void)
Definition: ResizeArray.h:36
BigReal y
Definition: Vector.h:74
int main(int argc, char *argv[])
Definition: diffbinpdb.c:15
char * AtomNames
Definition: parm.h:23
BigReal occupancy(void)
Definition: PDBData.C:444
PDBData * new_PDBData(const char *data)
Definition: PDBData.C:624
~PDB(void)
Definition: PDB.C:242
int * AtomRes
Definition: parm.h:27
struct PAL PDBAtomList
int serialnumber(void)
Definition: PDBData.C:380
void get_all_positions(Vector *)
Definition: PDB.C:365
void sprint(char *s, PDBFormatStyle usestyle=COLUMNS)
Definition: PDBData.C:615
NAMD_HOST_DEVICE Vector origin() const
Definition: Lattice.h:278
static const BigReal default_occupancy
Definition: PDBData.h:156
double BigReal
Definition: common.h:123