cd $AMBERHOME patch -p0 -N -r patch_rejects < ptraj_AT1.4_fixMaxFrames.patch Author: Daniel R. Roe Date: 2010-05-27 Description: Fixes bug where ptraj actions would attempt to allocate a negative number of bytes of memory when the number of frames to be read is unknown, i.e. file is compressed or corrupted. The number of frames for compressed files can now be calculated ahead of time. For gzip files this is simple, but for bzip2 and zip files this adds to the processing time since uncompressed file size cannot be determined for these file types without external programs. For corrupted files the trajectory filesize is used to predict the number of frames. After applying the patch ptraj should be completely recompiled (i.e. perform a make clean in the ptraj directory). ----------------------------------------------------------------------------- --- AmberTools/src/ptraj/trajectory.h 2010-03-30 23:05:16.000000000 -0400 +++ AmberTools/src/ptraj/trajectory.h 2010-05-27 11:16:27.928920475 -0400 @@ -168,6 +168,7 @@ char *filename; // File name int start; // Frame to start processing int stop; // Frame to end processing + int Nframes; // Total number of frames in the file. int offset; // # of frames to skip int append; // File will be appended to int isBox; // File has box information @@ -230,6 +231,7 @@ _p_->filename = NULL; \ _p_->start = 1; \ _p_->stop = -1; \ + _p_->Nframes = 0; \ _p_->offset = 1; \ _p_->append = 0; \ _p_->isBox = 0; \ --- AmberTools/src/ptraj/io.c 2010-03-30 23:05:16.000000000 -0400 +++ AmberTools/src/ptraj/io.c 2010-05-27 15:15:49.825241972 -0400 @@ -674,6 +674,91 @@ } /* DAN ROE: + * gzipFileSize() + * Return the uncompressed size in bytes of gzipped file by peeking at the + * last 4 bytes. + */ +int gzipFileSize(char *filename) { + FILE *infile; + int b1,b2,b3,b4,val; + + if (filename==NULL) return -1; + if ( (infile = fopen(filename,"rb"))==NULL ) { + fprintf(stdout,"Error: gzipFileSize: Could not open %s for reading.\n",filename); + return -1; + } + + // Place 4 bytes from the end + fseek(infile, -4, SEEK_END); + + b1=0; b2=0; b3=0; b4=0; + fread(&b4,1,1,infile); + fread(&b3,1,1,infile); + fread(&b2,1,1,infile); + fread(&b1,1,1,infile); + + val = (b1 << 24) | (b2 << 16) + (b3 << 8) + b4; + + fclose(infile); + + if (prnlev>0) fprintf(stdout,"gzipFileSize: Uncompressed size of %s: %i\n",filename,val); + + return val; +} +/* DAN ROE: + * bzip2FileSize() + * Return the uncompressed size of bzip2 file in bytes by counting all + * characters using bzcat and wc. + */ +int bzip2FileSize(char *filename) { + int val; + char *command; + FILE *pipe; + + if (filename==NULL) return -1; + // Use bzcat | wc -c to calc file size + command=(char*) malloc( (15 + strlen(filename)) * sizeof(char)); + sprintf(command,"bzcat %s | wc -c",filename); + if ((pipe=popen(command,"r"))==NULL) { + fprintf(stdout,"Error: bzip2FileSize: Could not open %s for reading.\n",filename); + fprintf(stdout," Check that bzcat and wc are present on your system.\n"); + return -1; + } + fscanf(pipe,"%i",&val); + pclose(pipe); + + if (prnlev>0) fprintf(stdout,"bzip2FileSize: Uncompressed size of %s: %i\n",filename,val); + + return val; +} +/* DAN ROE: + * zipFileSize() + * Return the uncompressed size of zip file in bytes by counting all + * characters using unzip and wc. + */ +int zipFileSize(char *filename) { + int val; + char *command; + FILE *pipe; + + if (filename==NULL) return -1; + // Use unzip -p | wc -c to calc file size + command=(char*) malloc( (18 + strlen(filename)) * sizeof(char)); + sprintf(command,"unzip -p %s | wc -c",filename); + if ((pipe=popen(command,"r"))==NULL) { + fprintf(stdout,"Error: zipFileSize: Could not open %s for reading.\n",filename); + fprintf(stdout," Check that unzip and wc are present on your system.\n"); + return -1; + } + fscanf(pipe,"%i",&val); + pclose(pipe); + + if (prnlev>0) fprintf(stdout,"zipFileSize: Uncompressed size of %s: %i\n",filename,val); + + return val; +} + +/* DAN ROE: * id_Filesig(): Attempt to identify the file type by first 3 hex vals. * A filename or an open stream should be supplied. * If a filename is supplied, the file is opened, checked, then closed. --- AmberTools/src/ptraj/io.h 2010-03-30 23:05:16.000000000 -0400 +++ AmberTools/src/ptraj/io.h 2010-05-27 15:16:16.839329069 -0400 @@ -76,6 +76,9 @@ extern void doSystem(char *); extern char * promptToOpenFile( FILE **, char *, char *, char *); +extern int gzipFileSize(char *); +extern int bzip2FileSize(char *); +extern int zipFileSize(char *); extern int id_Filesig(char *,FILE *); extern int openFile( FILE **, char *, char *); extern int promptUserResponse(FILE *, FILE *, char *, char *, int); @@ -94,6 +97,9 @@ extern void doSystem(); extern char * promptToOpenFile(); +extern int gzipFileSize(); +extern int bzip2FileSize(); +extern int zipFileSize(); extern int id_Filesig(); extern int openFile(); extern int promptUserResponse(); --- AmberTools/src/ptraj/ptraj.c 2010-04-23 10:17:17.000000000 -0400 +++ AmberTools/src/ptraj/ptraj.c 2010-05-27 15:16:27.913954807 -0400 @@ -2058,7 +2058,7 @@ int lines_per_set; int start = 1; int stop = 1; - int frame_lines, frame_size, title_size, seekable; + int frame_lines, frame_size, title_size, seekable, file_size; long int endoffset; float *binposScratch; FILE *fp; @@ -2414,12 +2414,25 @@ fprintf(stderr, "WARNING in %s: Could not find file status for %s\n", ROUTINE, filename); return NULL; } + + // Determine Uncompressed File Size for Nframes calculation + file_size=0; + if (trajInfo->compressType==1) // Gzip + file_size=gzipFileSize(filename); + else if (trajInfo->compressType==2) // Bzip2 + file_size=bzip2FileSize(filename); + else if (trajInfo->compressType==3) // Zip + file_size=zipFileSize(filename); + if (file_size<0) return NULL; + if (file_size==0) file_size=frame_stat.st_size; + if (prnlev>0) fprintf(stdout,"[%i] Title offset %u Frame Size %u File size %lu\n", - worldrank,trajInfo->titleSize,trajInfo->frameSize,frame_stat.st_size); - if (((frame_stat.st_size - trajInfo->titleSize) % (trajInfo->frameSize)) == 0) { + worldrank,trajInfo->titleSize,trajInfo->frameSize,file_size); + trajInfo->Nframes = (int) ((file_size - trajInfo->titleSize) / trajInfo->frameSize); + if (((file_size - trajInfo->titleSize) % (trajInfo->frameSize)) == 0) { seekable = 1; - stop = (int) ((frame_stat.st_size - trajInfo->titleSize) / trajInfo->frameSize); + stop = trajInfo->Nframes; } else { stop = -1; seekable = 0; @@ -2538,7 +2551,8 @@ printfone(" With this version of the code, this will likely lead to program failure!!!\n"); } - + // Set number of frames. Amber trajectory sets Nframes above + if (trajInfo->Nframes==0 && stop>0) trajInfo->Nframes=stop; trajInfo->start = start; trajInfo->stop = stop; trajInfo->offset = 1; @@ -4182,7 +4196,7 @@ fprintf(stderr,"Could not get replica temperature from file# %i\n",i); break; } - fprintf(stdout," Replica %i mytemp=%lf ",i,repTemp); //DEBUG + if (prnlev>0) fprintf(stdout," Replica %i mytemp=%lf ",i,repTemp); //DEBUG if (repTemp==currentCoordinateInfo->remdtrajtemp) { if (prnlev>0) fprintf(stdout, " REMD target temperature (%lf) found (%lf) at replica index %i\n", @@ -7078,6 +7092,7 @@ stackType *sp, *argumentStack; ptrajState *startingState, *currentState, **statep; char *continuation; + int totalFrames; int readCoordinates; int processCoordinates; @@ -7218,18 +7233,25 @@ */ startingState->maxFrames = 0; + totalFrames=0; for (sp = transformFileStack; sp != NULL; sp = sp->next) { currentCoordinateInfo = (coordinateInfo *) sp->entry; + fprintf(stdout," %s: %i frames.\n",currentCoordinateInfo->filename,currentCoordinateInfo->Nframes); + startingState->maxFrames += (currentCoordinateInfo->stop - currentCoordinateInfo->start) / currentCoordinateInfo->offset + 1; + // In case we dont know how many frames will be processed, use total number of frames + totalFrames += currentCoordinateInfo->Nframes; } printfone("\nPTRAJ: Successfully read the input file.\n"); - if (startingState->maxFrames == -1) + if (startingState->maxFrames == -1) { printfone(" Coordinate processing will occur until EOF (unknown number of frames).\n"); - else + // Use total frames for action memory alloc. + startingState->maxFrames = totalFrames; + } else printfone(" Coordinate processing will occur on %i frames.\n", startingState->maxFrames); printfone(" Summary of I/O and actions follows:\n\n");