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 
343  for (i=0, atomptr=atomArray; i<atomCount; atomptr++, i++)
344  {
345  (*atomptr)->xcoor(pos[i].x);
346  (*atomptr)->ycoor(pos[i].y);
347  (*atomptr)->zcoor(pos[i].z);
348  }
349 #endif
350 }
351 
352 void PDB::get_position_for_atom(Vector *pos, int aid){
353 #ifdef MEM_OPT_VERSION
354  pos->x = atomArray[aid].coor[0];
355  pos->y = atomArray[aid].coor[1];
356  pos->z = atomArray[aid].coor[2];
357 #else
358  PDBAtomPtr *atomptr = &atomArray[aid];
359  pos->x = (*atomptr)->xcoor();
360  pos->y = (*atomptr)->ycoor();
361  pos->z = (*atomptr)->zcoor();
362 #endif
363 }
364 
365 // Get all the atom positions into a list of Vectors
367 {
368 #ifdef MEM_OPT_VERSION
369  for(int i=0; i<atomCount; i++){
370  pos[i].x = atomArray[i].coor[0];
371  pos[i].y = atomArray[i].coor[1];
372  pos[i].z = atomArray[i].coor[2];
373  }
374 #else
375  int i;
376  PDBAtomPtr *atomptr;
377 
378  for (i=0, atomptr=atomArray; i<atomCount; atomptr++, i++)
379  {
380  pos[i].x = (*atomptr)->xcoor();
381  pos[i].y = (*atomptr)->ycoor();
382  pos[i].z = (*atomptr)->zcoor();
383  }
384 #endif
385 }
386 
387 // given an index, return that atom
388 #ifdef MEM_OPT_VERSION
389 PDBCoreData *PDB::atom(int place){
390  if(place<0 || place>=atomCount) return NULL;
391  return &atomArray[place];
392 }
393 #else
394 PDBAtom *PDB::atom(int place)
395 {
396  if (place <0 || place >= atomCount)
397  return NULL;
398  return atomArray[place];
399 }
400 #endif
401 
402 
403 // find the lowest and highest bounds based on a fraction of the atoms
404 //void PDB::find_extremes(BigReal *min, BigReal *max, Vector rec, BigReal frac) const
405 void PDB::find_extremes_helper(
407  BigReal &min, BigReal &max, Vector rec, BigReal frac
408  )
409 {
411 #ifdef MEM_OPT_VERSION
412  PDBCoreData *atomptr = atomArray;
413  for(int i=0; i<atomCount; i++, atomptr++){
414  Vector pos(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
415  c_i[i] = rec*pos;
416  }
417 #else
418  PDBAtomPtr *atomptr = atomArray;
419  for (int i=0; i<atomCount; ++i, ++atomptr) {
420  PDBAtom *atom = *atomptr;
421  Vector pos(atom->xcoor(),atom->ycoor(),atom->zcoor());
422  c_i[i] = rec*pos;
423  }
424 #endif
425  coor.sort();
426  int ilow = (int)((1.0 - frac) * atomCount);
427  if ( ilow < 0 ) ilow = 0;
428  if ( ilow > atomCount/2 ) ilow = atomCount/2;
429  int ihigh = atomCount - ilow - 1;
430  BigReal span = coor[ihigh] - coor[ilow];
431  BigReal extension = (1.0 - frac) * span / (2.0 * frac - 1.0);
432  max = coor[ihigh] + extension;
433  min = coor[ilow] - extension;
434 }
435 
436 // Find the extreme edges of molecule in scaled coordinates,
437 // where "frac" sets bounds based on a fraction of the atoms.
438 void PDB::find_extremes(const Lattice &lattice, BigReal frac) {
439  if (atomCount == 0) {
440  smin = smax = 0;
441  }
442  else if (frac < 1.0) {
443  // for now use the previous "sort the array" approach
444  // for solving "frac"th largest and smallest selection problems
446  coor.resize(atomCount); // allocate array space once
447  find_extremes_helper(coor, smin.x, smax.x, lattice.a_r(), frac);
448  find_extremes_helper(coor, smin.y, smax.y, lattice.b_r(), frac);
449  find_extremes_helper(coor, smin.z, smax.z, lattice.c_r(), frac);
450  }
451  else {
452  // finding absolute min and max does not require sorting
453 #ifdef MEM_OPT_VERSION
454  PDBCoreData *atomptr = atomArray;
455  Vector p(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
456 #else
457  PDBAtomPtr *atomptr = atomArray;
458  PDBAtom *atom = *atomptr;
459  Vector p(atom->xcoor(),atom->ycoor(),atom->zcoor());
460 #endif
461  Vector s(lattice.a_r()*p, lattice.b_r()*p, lattice.c_r()*p);
462  smin = smax = s;
463  atomptr++;
464  for(int i=1; i<atomCount; i++, atomptr++){
465 #ifdef MEM_OPT_VERSION
466  p = Vector(atomptr->xcoor(),atomptr->ycoor(),atomptr->zcoor());
467 #else
468  atom = *atomptr;
469  p = Vector (atom->xcoor(),atom->ycoor(),atom->zcoor());
470 #endif
471  s = Vector(lattice.a_r()*p, lattice.b_r()*p, lattice.c_r()*p);
472  if (smin.x > s.x) smin.x = s.x;
473  else if (smax.x < s.x) smax.x = s.x;
474  if (smin.y > s.y) smin.y = s.y;
475  else if (smax.y < s.y) smax.y = s.y;
476  if (smin.z > s.z) smin.z = s.z;
477  else if (smax.z < s.z) smax.z = s.z;
478  }
479  }
480  // shift using the origin
481  BigReal origin_shift;
482  origin_shift = lattice.a_r() * lattice.origin();
483  smin.x -= origin_shift;
484  smax.x -= origin_shift;
485  origin_shift = lattice.b_r() * lattice.origin();
486  smin.y -= origin_shift;
487  smax.y -= origin_shift;
488  origin_shift = lattice.c_r() * lattice.origin();
489  smin.z -= origin_shift;
490  smax.z -= origin_shift;
491 }
492 
493 //#define TEST_PDB_CLASS
494 #ifdef TEST_PDB_CLASS
495 
496 main()
497 {
498  PDB *pdb = new PDB("pti.pdb");
499  if ( atomArray == NULL )
500  {
501  NAMD_die("memory allocation failed in main of test PDB class");
502  }
503  ilist = pdb->find_atom_name("CA");
504  if (!ilist)
505  printf("None found.\n");
506  else {
507  int i;
508  char s[200];
509  for (i=0; i<ilist->num(); i++) {
510  pdb->atom((*ilist)[i]) -> sprint(s);
511  printf("%s\n", s);
512  }
513  delete ilist;
514  } // if ilist
515 
516  printf("Now, search through space.\n");
517 
518  ilist = pdb->find_atoms_in_region(4.38, 19.5, 3.0,
519  4.40, 20.0, 3.2 );
520  if (!ilist)
521  printf("None found.\n");
522  else {
523  int i;
524  char s[200];
525  printf("%d found\n", ilist -> num());
526  for (i=0; i<ilist->num(); i++) {
527  pdb->atom((*ilist)[i]) -> sprint(s);
528  printf("%s\n", s);
529  }
530  delete ilist;
531  }
532 }
533 #endif // TEST_PDB_CLASS
534 
535 
536 
537 // This function was borrowed from VMD code in "ReadPARM.C".
538 // It skips to a new line.
539 static int readtoeoln(FILE *f) {
540  char c;
541 
542  /* skip to eoln */
543  while((c = getc(f)) != '\n') {
544  if (c == EOF)
545  return -1;
546  }
547 
548  return 0;
549 }
550 
551 
552 
553 // read in an AMBER coordinate file and populate the PDB structure
554 PDB::PDB( const char *filename, Ambertoppar *amber_data)
555 { int i,j,k;
556  BigReal coor[3];
557  char buf[13],resname[5],atomname[5];
558  FILE *infile;
559  PDBAtom *pdb;
560 
561  if ((infile=Fopen(filename, "r")) == NULL)
562  NAMD_err("Can't open AMBER coordinate file!");
563 
564  readtoeoln(infile); // Skip the first line (title)
565 
566  fscanf(infile,"%d",&atomCount); // Read in num of atoms
567  if (atomCount != amber_data->Natom)
568  NAMD_die("Num of atoms in coordinate file is different from that in parm file!");
569  readtoeoln(infile);
570 
571 #ifdef MEM_OPT_VERSION
572  altlocArray = 0;
573  atomArray = new PDBCoreData[atomCount];
574 #else
575  atomAlloc = 0;
576  atomArray = new PDBAtomPtr[atomCount];
577 #endif
578 
579  if ( atomArray == NULL )
580  {
581  NAMD_die("memory allocation failed in PDB::PDB");
582  }
583 
584  // Read in the coordinates, which are in the format of 6F12.7
585  // Other fields are copied from "amber_data"
586  for (i=0; i<atomCount; ++i)
587  { // Read x,y,z coordinates
588  for (j=0; j<3; ++j)
589  { for (k=0; k<12; ++k)
590  { buf[k]=getc(infile);
591  if (buf[k]=='\n' || buf[k]=='\0' || buf[k]==EOF)
592  NAMD_die("Error reading AMBER coordinate file!");
593  }
594  buf[12] = '\0';
595  coor[j] = atof(buf);
596  }
597  if (i%2 == 1)
598  readtoeoln(infile);
599 #ifdef MEM_OPT_VERSION
600  atomArray[i].coor[0] = coor[0];
601  atomArray[i].coor[1] = coor[1];
602  atomArray[i].coor[2] = coor[2];
603  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
604  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
605 #else
606  // Copy name, resname and resid from "amber_data"
607  for (j=0; j<4; ++j)
608  { resname[j] = amber_data->ResNames[amber_data->AtomRes[i]*4+j];
609  atomname[j] = amber_data->AtomNames[i*4+j];
610  }
611  resname[4] = atomname[4] = '\0';
612  // Create a new PDB record, and fill in its entries
613  pdb = new PDBAtomRecord("");
614  pdb->name(atomname);
615  pdb->residuename(resname);
616  pdb->serialnumber(i+1);
617  pdb->residueseq(amber_data->AtomRes[i]+1);
618  pdb->coordinates(coor);
619  atomArray[i] = pdb; // Include the new record into the array
620 #endif
621  }
622 }
623 
624 // read in an AMBER coordinate file and populate the PDB structure
625 PDB::PDB( const char *filename, AmberParm7Reader::Ambertoppar *amber_data)
626 { int i,j,k;
627  BigReal coor[3];
628  char buf[13],resname[5],atomname[5];
629  FILE *infile;
630  PDBAtom *pdb;
631 
632  if ((infile=Fopen(filename, "r")) == NULL)
633  NAMD_err("Can't open AMBER coordinate file!");
634 
635  readtoeoln(infile); // Skip the first line (title)
636 
637  fscanf(infile,"%d",&atomCount); // Read in num of atoms
638  if (atomCount != amber_data->Natom)
639  NAMD_die("Num of atoms in coordinate file is different from that in parm file!");
640  readtoeoln(infile);
641 
642 #ifdef MEM_OPT_VERSION
643  altlocArray = 0;
644  atomArray = new PDBCoreData[atomCount];
645 #else
646  atomAlloc = 0;
647  atomArray = new PDBAtomPtr[atomCount];
648 #endif
649 
650  if ( atomArray == NULL )
651  {
652  NAMD_die("memory allocation failed in PDB::PDB");
653  }
654 
655  // Read in the coordinates, which are in the format of 6F12.7
656  // Other fields are copied from "amber_data"
657  for (i=0; i<atomCount; ++i)
658  { // Read x,y,z coordinates
659  for (j=0; j<3; ++j)
660  { for (k=0; k<12; ++k)
661  { buf[k]=getc(infile);
662  if (buf[k]=='\n' || buf[k]=='\0' || buf[k]==EOF)
663  NAMD_die("Error reading AMBER coordinate file!");
664  }
665  buf[12] = '\0';
666  coor[j] = atof(buf);
667  }
668  if (i%2 == 1)
669  readtoeoln(infile);
670 #ifdef MEM_OPT_VERSION
671  atomArray[i].coor[0] = coor[0];
672  atomArray[i].coor[1] = coor[1];
673  atomArray[i].coor[2] = coor[2];
674  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
675  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
676 #else
677  // Copy name, resname and resid from "amber_data"
678  strncpy(resname, amber_data->ResNames[amber_data->AtomRes[i]].c_str(), 5);
679  strncpy(atomname, amber_data->AtomNames[i].c_str(), 5);
680  // Create a new PDB record, and fill in its entries
681  pdb = new PDBAtomRecord("");
682  pdb->name(atomname);
683  pdb->residuename(resname);
684  pdb->serialnumber(i+1);
685  pdb->residueseq(amber_data->AtomRes[i]+1);
686  pdb->coordinates(coor);
687  atomArray[i] = pdb; // Include the new record into the array
688 #endif
689  }
690 }
691 
692 #define LINESIZE 100
693 
694 /* This constructor initializes the PDB data using a Gromacs
695  coordinate file, generating an error message if the file
696  can't be parsed or if its contents don't jive with what is in
697  the topo file <topology>. */
698 PDB::PDB(const char *filename, const GromacsTopFile *topology) {
699  int i;
700  char buf[LINESIZE];
701  FILE *infile;
702 
703  /* open up the coordinate file */
704  infile=Fopen(filename, "r");
705  if (infile == NULL)
706  NAMD_err("Can't open GROMACS coordinate file!");
707 
708  fgets(buf,LINESIZE-1,infile); // get the title
709  // if(strcmp(buf,topology->getSystemName()) != 0)
710  // NAMD_die("System names in topology and coordinate files differ.");
711 
712  fgets(buf,LINESIZE-1,infile); // get the number of atoms
713  sscanf(buf,"%d",&atomCount);
714  if (atomCount != topology->getNumAtoms())
715  NAMD_die("Num of atoms in coordinate file is different from that in topology file!");
716 
717  /* read in the atoms */
718 #ifdef MEM_OPT_VERSION
719  altlocArray = 0;
720  atomArray = new PDBCoreData[atomCount];
721 #else
722  atomAlloc = 0;
723  atomArray = new PDBAtomPtr[atomCount];
724 #endif
725  if ( atomArray == NULL )
726  NAMD_die("memory allocation failed in PDB::PDB");
727 
728 #ifdef MEM_OPT_VERSION
729  for(i=0; i<atomCount; i++){
730  fgets(buf,LINESIZE-1,infile); // get a line
731  char *buf2 = buf+20; // skip three fields to get to the coordinates
732  BigReal coor[3];
733  if(3 != sscanf(buf2,"%lf%lf%lf", &coor[0],&coor[1],&coor[2]))
734  NAMD_die("Couldn't get three coordinates from file.");
735 
736  coor[0] *= 10; // convert to angstroms from nanometers
737  coor[1] *= 10;
738  coor[2] *= 10;
739 
740  atomArray[i].coor[0] = coor[0];
741  atomArray[i].coor[1] = coor[1];
742  atomArray[i].coor[2] = coor[2];
743  atomArray[i].myoccupancy = PDBAtom::default_occupancy;
744  atomArray[i].tempfactor = PDBAtom::default_temperaturefactor;
745  }
746 #else
747  for (i=0;i<atomCount;i++) {
748  char *buf2, resname[11], atomname[11], atmtype[11];
749  int resnum, typenum;
750  Real charge,mass;
751  BigReal coor[3];
752  PDBAtom *pdb = new PDBAtomRecord("");
753 
754  fgets(buf,LINESIZE-1,infile); // get a line
755  buf2 = buf+20; // skip three fields to get to the coordinates
756  if(3 != sscanf(buf2,"%lf%lf%lf",
757  &coor[0],&coor[1],&coor[2]))
758  NAMD_die("Couldn't get three coordinates from file.");
759  topology->getAtom(i,&resnum,resname,
760  atomname,atmtype,&typenum,&charge,&mass);
761  coor[0] *= 10; // convert to angstroms from nanometers
762  coor[1] *= 10;
763  coor[2] *= 10;
764 
765  pdb->name(atomname);
766  pdb->residuename(resname);
767  pdb->serialnumber(i+1);
768  pdb->residueseq(resnum+1);
769  pdb->coordinates(coor);
770 
771  atomArray[i] = pdb; // Include the new record into the array
772  }
773 #endif
774 }
775 
776 #ifdef MEM_OPT_VERSION
777 void PDBCoreData::sprint( char *outstr, PDBData::PDBFormatStyle usestyle){
778  if(usestyle == PDBData::COLUMNS){
779  //sprint_columns copied from PDBAtom::sprint_columns
780  for(int i=0; i<79; i++) outstr[i] = 32;
781  outstr[79] = 0;
787  }else{
788  //sprint_fields
789  char tmpstr[50];
790  if (xcoor() == PDBAtom::default_coor)
791  sprintf(tmpstr, " #");
792  else
793  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, xcoor());
794  strcat(outstr, tmpstr);
795  if (ycoor() == PDBAtom::default_coor)
796  sprintf(tmpstr, " #");
797  else
798  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, ycoor());
799  strcat(outstr, tmpstr);
800  if (zcoor() == PDBAtom::default_coor)
801  sprintf(tmpstr, " #");
802  else
803  sprintf(tmpstr, " %*.*f", PDBAtom::LCOOR, PDBAtom::LCOORPREC, zcoor());
804  strcat(outstr, tmpstr);
805 
806  sprintf(tmpstr, " %*.*f", PDBAtom::LOCC, PDBAtom::LOCCPREC, occupancy());
807  strcat(outstr, tmpstr);
808 
809  sprintf(tmpstr, " %*.*f", PDBAtom::LTEMPF, PDBAtom::LTEMPFPREC, temperaturefactor());
810  strcat(outstr, tmpstr);
811  }
812 }
813 #endif
814 
static const BigReal default_coor
Definition: PDBData.h:155
Definition: PDB.h:36
Vector a_r() const
Definition: Lattice.h:268
void NAMD_err(const char *err_msg)
Definition: common.C:106
int Natom
Definition: parm.h:17
static const BigReal default_temperaturefactor
Definition: PDBData.h:157
void get_position_for_atom(Vector *, int)
Definition: PDB.C:352
BigReal temperaturefactor(void)
Definition: PDBData.C:450
Definition: PDB.h:31
Definition: Vector.h:64
Vector c_r() const
Definition: Lattice.h:270
void write(const char *outfilename, const char *commentline=NULL)
Definition: PDB.C:261
float Real
Definition: common.h:109
#define LINESIZE
Definition: PDB.C:692
BigReal z
Definition: Vector.h:66
void set_all_positions(Vector *)
Definition: PDB.C:331
BigReal zcoor(void)
Definition: PDBData.C:433
int num_atoms(void)
Definition: PDB.C:323
Vector origin() const
Definition: Lattice.h:262
Vector b_r() const
Definition: Lattice.h:269
char * ResNames
Definition: parm.h:23
static int readtoeoln(FILE *f)
Definition: PDB.C:539
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:394
const BigReal * coordinates(void)
Definition: PDBData.C:438
BigReal ycoor(void)
Definition: PDBData.C:429
gridSize z
char * AtomNames
Definition: parm.h:23
int residueseq(void)
Definition: PDBData.C:411
FILE * Fopen(const char *filename, const char *mode)
Definition: common.C:273
int * AtomRes
Definition: parm.h:27
BigReal x
Definition: Vector.h:66
const char * alternatelocation(void)
Definition: PDBData.C:392
Definition: parm.h:15
void NAMD_die(const char *err_msg)
Definition: common.C:85
const char * name(void)
Definition: PDBData.C:386
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:438
int Fclose(FILE *fout)
Definition: common.C:367
void resize(int i)
Definition: ResizeArray.h:84
BigReal y
Definition: Vector.h:66
int main(int argc, char *argv[])
Definition: diffbinpdb.c:15
k< npairi;++k){TABENERGY(const int numtypes=simParams->tableNumTypes;const float table_spacing=simParams->tableSpacing;const int npertype=(int)(namdnearbyint(simParams->tableMaxDist/simParams->tableSpacing)+1);) int table_i=(r2iilist[2 *k] >> 14)+r2_delta_expc;const int j=pairlisti[k];#define p_j BigReal diffa=r2list[k]-r2_table[table_i];#define table_four_i TABENERGY(register const int tabtype=-1-(lj_pars->A< 0?lj_pars->A:0);) BigReal kqq=kq_i *p_j-> charge
gridSize y
int getNumAtoms() const
BigReal occupancy(void)
Definition: PDBData.C:444
PDBData * new_PDBData(const char *data)
Definition: PDBData.C:624
~PDB(void)
Definition: PDB.C:242
gridSize x
struct PAL PDBAtomList
int serialnumber(void)
Definition: PDBData.C:380
void get_all_positions(Vector *)
Definition: PDB.C:366
void sprint(char *s, PDBFormatStyle usestyle=COLUMNS)
Definition: PDBData.C:615
void getAtom(int num, int *residue_number, char *residue_name, char *atom_name, char *atom_type, int *atom_typenum, Real *charge, Real *mass) const
static const BigReal default_occupancy
Definition: PDBData.h:156
double BigReal
Definition: common.h:114
iterator begin(void)
Definition: ResizeArray.h:36