// Traj_NcEnsemble::setupTrajin() int Traj_NcEnsemble::setupTrajin(FileName const& fname, Topology* trajParm) { # ifdef MPI if (NoPnetcdf()) return TRAJIN_ERR; # endif readAccess_ = true; filename_ = fname; // NOTE: Setup opens and closes single thread for now // Setup for Amber NetCDF ensemble if ( NC_setupRead(filename_.Full(), NC_AMBERENSEMBLE, trajParm->Natom(), useVelAsCoords_, useFrcAsCoords_, debug_) ) return TRAJIN_ERR; // Get title SetTitle( GetNcTitle() ); // Set coordinate info SetCoordInfo( NC_coordInfo() ); // Set up local ensemble parameters # ifdef MPI ensembleStart_ = Parallel::World().Rank(); ensembleEnd_ = Parallel::World().Rank() + 1; # else ensembleStart_ = 0; ensembleEnd_ = ensembleSize_; # endif // DEBUG: Print info for all ranks DebugVIDs(); // Allocate float array if (Coord_ != 0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; return Ncframe(); }
/* * Open the netcdf file, read all dimension and variable IDs, close. * Return the number of frames in the file. */ int Traj_AmberNetcdf::setupTrajin(FileName const& fname, Topology* trajParm) { filename_ = fname; if (openTrajin()) return TRAJIN_ERR; readAccess_ = true; // Sanity check - Make sure this is a Netcdf trajectory if ( GetNetcdfConventions() != NC_AMBERTRAJ ) { mprinterr("Error: Netcdf file %s conventions do not include \"AMBER\"\n",filename_.base()); return TRAJIN_ERR; } // Get global attributes std::string attrText = GetAttrText("ConventionVersion"); if ( attrText != "1.0") mprintf("Warning: Netcdf file %s has ConventionVersion that is not 1.0 (%s)\n", filename_.base(), attrText.c_str()); // Get title SetTitle( GetAttrText("title") ); // Get Frame info if ( SetupFrameDim()!=0 ) return TRAJIN_ERR; if ( Ncframe() < 1 ) { mprinterr("Error: Netcdf file is empty.\n"); return TRAJIN_ERR; } // Setup Coordinates/Velocities if ( SetupCoordsVelo( useVelAsCoords_ )!=0 ) return TRAJIN_ERR; // Check that specified number of atoms matches expected number. if (Ncatom() != trajParm->Natom()) { mprinterr("Error: Number of atoms in NetCDF file %s (%i) does not\n" "Error: match number in associated parmtop (%i)!\n", filename_.base(), Ncatom(), trajParm->Natom()); return TRAJIN_ERR; } // Setup Time - FIXME: Allowed to fail silently SetupTime(); // Box info double boxcrd[6]; if (SetupBox(boxcrd, NC_AMBERTRAJ) == 1) // 1 indicates an error return TRAJIN_ERR; // Replica Temperatures - FIXME: Allowed to fail silently SetupTemperature(); // Replica Dimensions ReplicaDimArray remdDim; if ( SetupMultiD(remdDim) == -1 ) return TRAJIN_ERR; // Set traj info: FIXME - no forces yet SetCoordInfo( CoordinateInfo(remdDim, Box(boxcrd), HasVelocities(), HasTemperatures(), HasTimes(), false) ); // NOTE: TO BE ADDED // labelDID; //int cell_spatialDID, cell_angularDID; //int spatialVID, cell_spatialVID, cell_angularVID; // Amber Netcdf coords are float. Allocate a float array for converting // float to/from double. if (Coord_ != 0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; if (debug_>1) NetcdfDebug(); closeTraj(); return Ncframe(); }
/** Set up trajectory for write. Calculate the length of each cooordinate * frame. Set the title and titleSize. Calculate the full output file * size, necessary only for seeking when MPI writing. Allocate memory for * the frame buffer. */ int Traj_AmberCoord::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { // Set Temperature Write // FIXME: Check for temperatures in input frames and when appending. SetCoordInfo( cInfoIn ); if (outputTemp_) { headerSize_ = REMD_HEADER_SIZE; if (!CoordInfo().HasTemp()) mprintf("Warning: No temperature information in input frames.\n"); } if (!append) { // Write the title if not appending if (file_.SetupWrite( fname, debug_ )) return 1; std::string title = Title(); if (title.empty()) { // Set up default title title.assign("Cpptraj Generated trajectory"); title.resize(80,' '); SetTitle( title ); } else { // Check title length if (title.size() > 80) { mprintf("Warning: Amber traj title for %s too long: truncating.\n[%s]\n", file_.Filename().base(), title.c_str()); title.resize(80); } } if (file_.OpenFile()) return 1; file_.Printf("%-s\n", title.c_str()); } else { // Just set up for append if (file_.SetupAppend( fname, debug_ )) return 1; if (file_.OpenFile()) return 1; } // Allocate buffer. Will not buffer REMD header or need to seek. // NOTE: This is done here since SetupFrameBuffer allocates based // on write mode, which is not known until now. natom3_ = trajParm->Natom() * 3; file_.SetupFrameBuffer( natom3_, 8, 10 ); // If box coords are present, allocate extra space for them switch (CoordInfo().TrajBox().Type()) { case Box::NOBOX : numBoxCoords_ = 0; break; case Box::ORTHO : case Box::TRUNCOCT: numBoxCoords_ = 3; break; default : numBoxCoords_ = 6; } file_.ResizeBuffer( numBoxCoords_ ); if (debug_>0) rprintf("(%s): Each frame has %lu bytes.\n", file_.Filename().base(), file_.FrameSize()); return 0; }
int Traj_GmxTrX::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { if (!append) { SetCoordInfo( cInfoIn ); natoms_ = trajParm->Natom(); natom3_ = natoms_ * 3; // Default to little endian, precision 4, TRR format_ = TRR; isBigEndian_ = false; precision_ = 4; // Set up title if (Title().empty()) SetTitle("Cpptraj generated TRR file."); // Set size defaults, box, velocity etc ir_size_ = 0; e_size_ = 0; if (CoordInfo().HasBox()) box_size_ = precision_ * 9; else box_size_ = 0; vir_size_ = 0; pres_size_ = 0; top_size_ = 0; sym_size_ = 0; x_size_ = natom3_ * precision_; if (CoordInfo().HasVel()) v_size_ = natom3_ * precision_; else v_size_ = 0; f_size_ = 0; step_ = 0; nre_ = 0; dt_ = 0.0; lambda_ = 0.0; // Allocate temp space for coords/velo AllocateCoords(); if (file_.SetupWrite( fname, debug_)) return 1; if (file_.OpenFile()) return 1; } else { int nframes = setupTrajin( fname, trajParm ); if ( format_ == TRJ ) { mprinterr("Error: Only writes to TRR files supported.\n"); return 1; } if ( nframes == TRAJIN_ERR ) return 1; mprintf("\tAppending to TRR file starting at frame %i\n", nframes); // Re-open for appending if (file_.SetupAppend( fname, debug_ )) return 1; if (file_.OpenFile()) return 1; } return 0; }
/** Allocate a character buffer based on number of coords and whether * velocities/box info is present. */ int Traj_AmberRestart::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { if (append) { mprinterr("Error: Append not supported for Amber Restart.\n"); return 1; } CoordinateInfo cInfo = cInfoIn; if (!cInfo.HasTemp() && outputTemp_) cInfo.SetTemperature(true); // If temperature requested write time as well or format will break. if (cInfo.HasTemp()) { outputTime_ = true; if (!cInfo.HasTime() && time0_ < 0.0) time0_ = 1.0; } if (cInfo.HasVel() && !outputVel_) cInfo.SetVelocity(false); if (outputTime_) { if (!cInfo.HasTime() && time0_ >= 0) cInfo.SetTime(true); } else cInfo.SetTime(false); SetCoordInfo( cInfo ); if (file_.SetupWrite( fname, debug_ )) return 1; readAccess_ = false; // Set trajectory info natom3_ = trajParm->Natom() * 3; // Calculate the length of coordinate frame in bytes file_.SetupFrameBuffer( natom3_, 12, 6 ); // Dont know ahead of time if velocities will be used, allocate space // just in case. Velocity will not be written if V input is null. file_.ResizeBuffer( natom3_ ); // If box coords are present, allocate extra space for them if (CoordInfo().HasBox()) { numBoxCoords_ = 6; file_.ResizeBuffer( numBoxCoords_ ); } // If number of frames to write == 1 set singleWrite so we dont append // frame # to filename. if (NframesToWrite==1) singleWrite_ = true; // Set up title std::string outTitle = Title(); if (outTitle.empty()) { outTitle.assign("Cpptraj Generated Restart"); outTitle.resize(80, ' '); } else { if ( outTitle.size() > 80) { mprintf("Warning: Amber restart title for %s too long: truncating.\n[%s]\n", file_.Filename().base(), outTitle.c_str()); outTitle.resize(80); } } SetTitle( outTitle ); return 0; }
/** Prepare trajectory for reading. Determine number of frames. */ int Traj_GmxTrX::setupTrajin(FileName const& fname, Topology* trajParm) { int nframes = 0; if (file_.SetupRead( fname, debug_ )) return TRAJIN_ERR; // Open and read in header if ( file_.OpenFile() ) return TRAJIN_ERR; ReadTrxHeader(); if (debug_ > 0) GmxInfo(); // DEBUG // Warn if # atoms in parm does not match if (trajParm->Natom() != natoms_) { mprinterr("Error: # atoms in TRX file (%i) does not match # atoms in parm %s (%i)\n", natoms_, trajParm->c_str(), trajParm->Natom()); return TRAJIN_ERR; } // If float precision, create temp array. Temp array not needed for double reads. if (precision_ == sizeof(float)) { if (farray_ != 0) delete[] farray_; farray_ = new float[ natom3_ ]; } // Attempt to determine # of frames in traj headerBytes_ = (size_t)file_.Tell(); frameSize_ = headerBytes_ + (size_t)box_size_ + (size_t)vir_size_ + (size_t)pres_size_ + (size_t)x_size_ + (size_t)v_size_ + (size_t)f_size_; //(size_t)ir_size_ + (size_t)e_size_ + (size_t)top_size_ + //(size_t)sym_size_; size_t file_size = (size_t)file_.UncompressedSize(); if (file_size > 0) { nframes = (int)(file_size / frameSize_); if ( (file_size % frameSize_) != 0 ) { mprintf("Warning: %s: Number of frames in TRX file could not be accurately determined.\n" "Warning: Will attempt to read %i frames.\n", file_.Filename().base(), nframes); } } else { mprintf("Warning: Uncompressed size could not be determined. This is normal for\n"); mprintf("Warning: bzip2 files. Cannot check # of frames. Frames will be read until EOF.\n"); nframes = TRAJIN_UNK; } // Load box info so that it can be checked. double box[6]; box[0]=0.0; box[1]=0.0; box[2]=0.0; box[3]=0.0; box[4]=0.0; box[5]=0.0; if ( box_size_ > 0 ) { if ( ReadBox( box ) ) return TRAJIN_ERR; } // Set traj info - No time or temperature SetCoordInfo( CoordinateInfo(Box(box), (v_size_ > 0), false, false) ); closeTraj(); return nframes; }
/** Create Netcdf file specified by filename and set up dimension and * variable IDs. */ int Traj_AmberNetcdf::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { readAccess_ = false; if (!append) { CoordinateInfo cInfo = cInfoIn; // Deal with output options // For backwards compatibility always write temperature if remdtraj is true. if (outputTemp_ && !cInfo.HasTemp()) cInfo.SetTemperature(true); // Explicitly write velocity - initial frames may not have velocity info. if (outputVel_ && !cInfo.HasVel()) cInfo.SetVelocity(true); if (outputFrc_ && !cInfo.HasForce()) cInfo.SetForce(true); SetCoordInfo( cInfo ); filename_ = fname; // Set up title if (Title().empty()) SetTitle("Cpptraj Generated trajectory"); // Create NetCDF file. if (NC_create( filename_.Full(), NC_AMBERTRAJ, trajParm->Natom(), CoordInfo(), Title() )) return 1; if (debug_>1) NetcdfDebug(); // Close Netcdf file. It will be reopened write. NC_close(); // Allocate memory if (Coord_!=0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; } else { // NOTE: File existence is checked for in Trajout // Call setupTrajin to set input parameters. This will also allocate // memory for coords. if (setupTrajin(fname, trajParm) == TRAJIN_ERR) return 1; // Check output options. if (outputTemp_ && !CoordInfo().HasTemp()) mprintf("Warning: Cannot append temperature data to NetCDF file '%s'; no temperature dimension.\n", filename_.base()); if (outputVel_ && !CoordInfo().HasVel()) mprintf("Warning: Cannot append velocity data to NetCDF file '%s'; no velocity dimension.\n", filename_.base()); if (outputFrc_ && !CoordInfo().HasForce()) mprintf("Warning: Cannot append force data to NetCDF file '%s'; no force dimension.\n", filename_.base()); if (debug_ > 0) mprintf("\tNetCDF: Appending %s starting at frame %i\n", filename_.base(), Ncframe()); } // Open file if ( NC_openWrite( filename_.Full() ) != 0 ) { mprinterr("Error: Opening Netcdf file %s for Write.\n", filename_.base()); return 1; } return 0; }
// Traj_SQM::setupTrajout() int Traj_SQM::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { if (trajParm==0) return 1; if (append) { mprinterr("Error: Append not supported for SQM.\n"); return 1; } SetCoordInfo( cInfoIn ); if (outfile_.SetupWrite( fname, debug_ )) return 1; sqmParm_ = trajParm; if (NframesToWrite==1) singleWrite_ = true; // Set up title std::string outTitle = Title(); if (outTitle.empty()) { outTitle.assign("Cpptraj generated SQM input"); } else { if ( outTitle.size() > 80) { mprintf("Warning: Amber SQM title for '%s' too long: truncating.\n[%s]\n", outfile_.Filename().base(), outTitle.c_str()); outTitle.resize(80); } } SetTitle( outTitle ); // If charge not set, try to determine charge. // TODO: Warn if not integer charge if (!chargeIsSet_) { mprintf("Warning: No charge specified; attempting to calculate charge.\n"); double qtotal = 0.0; for (int i = 0; i < sqmParm_->Natom(); i++) qtotal += (*sqmParm_)[i].Charge(); charge_ = (int)qtotal; } // Set up header header_.assign(" &qmmm\n" " qm_theory='AM1', qmcharge = "+integerToString(charge_)+", maxcyc = 0,\n" " tight_p_conv = 1, scfconv = 1.0e-10, pseudo_diag = 0, errconv = 1.0e-10\n" " /\n"); return 0; }
// Traj_NcEnsemble::setupTrajout() int Traj_NcEnsemble::setupTrajout(FileName const& fname, Topology* trajParm, CoordinateInfo const& cInfoIn, int NframesToWrite, bool append) { int err = 0; # ifdef MPI if (NoPnetcdf()) return 1; # endif readAccess_ = false; if (!append) { CoordinateInfo cInfo = cInfoIn; // TODO: File output modifications SetCoordInfo( cInfo ); # ifdef MPI ensembleStart_ = Parallel::World().Rank(); ensembleEnd_ = Parallel::World().Rank() + 1; # else ensembleStart_ = 0; ensembleEnd_ = cInfo.EnsembleSize();; # endif filename_ = fname; // Set up title if (Title().empty()) SetTitle("Cpptraj Generated trajectory"); # ifdef MPI if (Parallel::World().Master()) { // Only master creates file. # endif // Create NetCDF file. err = NC_create(filename_.Full(), NC_AMBERENSEMBLE, trajParm->Natom(), CoordInfo(), Title(), debug_); // Close Netcdf file. It will be reopened write. FIXME should NC_create leave it closed? NC_close(); # ifdef MPI } Parallel::World().MasterBcast(&err, 1, MPI_INT); # endif if (err != 0) return 1; # ifdef MPI // Synchronize netcdf info on non-master threads Sync(Parallel::World()); // DEBUG: Print info for all ranks DebugVIDs(); # endif // Allocate memory if (Coord_!=0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; } else { // NOTE: File existence is checked for in Trajout // Call setupTrajin to set input parameters. This will also allocate // memory for coords. if (setupTrajin(fname, trajParm) == TRAJIN_ERR) return 1; if (debug_ > 0) mprintf("\tNetCDF: Appending %s starting at frame %i\n", filename_.base(), Ncframe()); } // Open file # ifdef HAS_PNETCDF err = ncmpi_open(MPI_COMM_WORLD, filename_.full(), NC_WRITE, MPI_INFO_NULL, &ncid_); // TODO: Graceful error handling # else err = NC_openWrite( filename_.Full() ); # endif if ( err != 0 ) { mprinterr("Error: Opening Netcdf file %s for Write.\n", filename_.base()); return 1; } return 0; }
/** Set up and read Amber restart file. Coordinate/velocities will be saved * here to avoid having to open the file again. Check that number of atoms * matches number of atoms in associated parmtop. Check for box/velocity info. */ int Traj_AmberRestart::setupTrajin(FileName const& fname, Topology* trajParm) { BufferedFrame infile; if (infile.SetupRead( fname, debug_ )) return TRAJIN_ERR; if (infile.OpenFile()) return TRAJIN_ERR; readAccess_ = true; // Read in title std::string title = infile.GetLine(); SetTitle( NoTrailingWhitespace(title) ); // Read in natoms, time, and Replica Temp if present std::string nextLine = infile.GetLine(); if (nextLine.empty()) { mprinterr("Error: Could not read restart atoms/time.\n"); return TRAJIN_ERR; } int restartAtoms = 0; bool hasTemp = false; bool hasTime = false; int nread = sscanf(nextLine.c_str(),"%i %lE %lE",&restartAtoms,&restartTime_,&restartTemp_); if (nread < 1) { mprinterr("Error: Unable to read restart atoms/time.\n"); return TRAJIN_ERR; } else if (nread == 1) { // # atoms only restartTime_ = 0.0; restartTemp_ = -1.0; } else if (nread == 2) { // # atoms and time hasTime = true; restartTemp_ = -1.0; } else { // # atoms, time, and temperature hasTime = true; hasTemp = true; } if (debug_ > 0) mprintf("\tAmber restart: Atoms=%i Time=%lf Temp=%lf\n",restartAtoms, restartTime_, restartTemp_); // Check that natoms matches parm natoms if (restartAtoms != trajParm->Natom()) { mprinterr("Error: Number of atoms in Amber Restart %s (%i) does not\n", infile.Filename().base(), restartAtoms); mprinterr(" match number in associated parmtop (%i)\n",trajParm->Natom()); return TRAJIN_ERR; } natom3_ = restartAtoms * 3; // Calculate the length of coordinate frame in bytes infile.SetupFrameBuffer( natom3_, 12, 6 ); // Read past restart coords if ( infile.ReadFrame() ) { mprinterr("Error: AmberRestart::setupTrajin(): Error reading coordinates.\n"); return TRAJIN_ERR; } // Save coordinates CRD_.resize( natom3_ ); infile.BufferBegin(); infile.BufferToDouble(&CRD_[0], natom3_); // Attempt a second read to get velocities or box coords bool hasVel = false; boxInfo_.SetNoBox(); nread = infile.AttemptReadFrame(); if ( nread < 0 ) { mprinterr("Error: Error attempting to read box line of Amber restart file.\n"); return TRAJIN_ERR; } size_t readSize = (size_t)nread; //mprintf("DEBUG: Restart readSize on second read = %i\n",readSize); // If 0 no box or velo if (readSize > 0) { if (readSize == infile.FrameSize()) { // If filled framebuffer again, has velocity info. hasVel = true; VEL_.resize( natom3_ ); infile.BufferBegin(); infile.BufferToDouble(&VEL_[0], natom3_); // If we can read 1 more line after velocity, should be box info. nextLine = infile.GetLine(); if (!nextLine.empty()) { if (getBoxAngles(nextLine, boxInfo_)) return TRAJIN_ERR; } } else if (readSize<82) { // If we read something but didnt fill framebuffer, should have box coords. nextLine.assign(infile.Buffer(), readSize); if (getBoxAngles(nextLine, boxInfo_)) return TRAJIN_ERR; } else { // Otherwise, who knows what was read? mprinterr("Error: AmberRestart::setupTrajin(): When attempting to read in\n" "Error: box coords/velocity info got %lu chars, expected 0, 37,\n" "Error: 73, or %lu.\n", readSize, infile.FrameSize()); mprinterr("Error: This usually indicates a malformed or corrupted restart file.\n"); return TRAJIN_ERR; } } if (useVelAsCoords_ && !hasVel) { mprinterr("Error: 'usevelascoords' specified but no velocities in this restart.\n"); return TRAJIN_ERR; } infile.CloseFile(); // Set coordinate info SetCoordInfo( CoordinateInfo(boxInfo_, hasVel, hasTemp, hasTime) ); // Only 1 frame in restart by definition return 1; }
// Traj_NcEnsemble::setupTrajin() int Traj_NcEnsemble::setupTrajin(FileName const& fname, Topology* trajParm) { # ifdef MPI if (NoPnetcdf()) return TRAJIN_ERR; # endif readAccess_ = true; filename_ = fname; //if (openTrajin()) return TRAJIN_ERR; // Open single thread for now if (NC_openRead( filename_.Full() )) return TRAJIN_ERR; // Sanity check - Make sure this is a Netcdf ensemble trajectory if ( GetNetcdfConventions() != NC_AMBERENSEMBLE ) { mprinterr("Error: Netcdf file %s conventions do not include \"AMBERENSEMBLE\"\n", filename_.base()); return TRAJIN_ERR; } // This will warn if conventions are not 1.0 CheckConventionsVersion(); // Get title SetTitle( GetNcTitle() ); // Get Frame info if ( SetupFrameDim()!=0 ) return TRAJIN_ERR; if ( Ncframe() < 1 ) { mprinterr("Error: Netcdf file is empty.\n"); return TRAJIN_ERR; } // Get ensemble info int ensembleSize = SetupEnsembleDim(); if (ensembleSize < 1) { mprinterr("Error: Could not get ensemble dimension info.\n"); return TRAJIN_ERR; } // Setup Coordinates/Velocities if ( SetupCoordsVelo( useVelAsCoords_, useFrcAsCoords_ )!=0 ) return TRAJIN_ERR; // Check that specified number of atoms matches expected number. if (Ncatom() != trajParm->Natom()) { mprinterr("Error: Number of atoms in NetCDF file %s (%i) does not\n" "Error: match number in associated parmtop (%i)!\n", filename_.base(), Ncatom(), trajParm->Natom()); return TRAJIN_ERR; } // Setup Time - FIXME: Allowed to fail silently SetupTime(); // Box info Box nc_box; if (SetupBox(nc_box, NC_AMBERENSEMBLE) == 1) // 1 indicates an error return TRAJIN_ERR; // Replica Temperatures - FIXME: Allowed to fail silently SetupTemperature(); // Replica Dimensions ReplicaDimArray remdDim; if ( SetupMultiD(remdDim) == -1 ) return TRAJIN_ERR; // Set traj info: FIXME - no forces yet SetCoordInfo( CoordinateInfo(ensembleSize, remdDim, nc_box, HasVelocities(), HasTemperatures(), HasTimes(), false) ); if (debug_>1) NetcdfDebug(); //closeTraj(); // Close single thread for now NC_close(); // Set up local ensemble parameters # ifdef MPI ensembleStart_ = Parallel::World().Rank(); ensembleEnd_ = Parallel::World().Rank() + 1; # else ensembleStart_ = 0; ensembleEnd_ = ensembleSize; # endif // DEBUG: Print info for all ranks WriteVIDs(); // Allocate float array if (Coord_ != 0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; return Ncframe(); }
int Traj_Gro::setupTrajin(FileName const& fnameIn, Topology* trajParm) { float fXYZ[9]; fname_ = fnameIn; // TODO SetupRead for BufferedLine // Open file for reading if (file_.OpenFileRead( fname_ )) return TRAJIN_ERR; // Read the title. May contain time value, 't= <time>' const char* ptr = file_.Line(); if (ptr == 0) { mprinterr("Error: Reading title.\n"); return TRAJIN_ERR; } std::string title( ptr ); RemoveTrailingWhitespace(title); mprintf("DBG: Title: %s\n", title.c_str()); bool hasTime = true; // TODO Is it OK to assume there will never be a negative time value? double timeVal = GetTimeValue( ptr ); if (timeVal < 0.0) hasTime = false; mprintf("DBG: Timeval= %g HasTime= %i\n", timeVal, (int)hasTime); // Read number of atoms ptr = file_.Line(); if (ptr == 0) return TRAJIN_ERR; natom_ = atoi(ptr); if (natom_ < 1) { mprinterr("Error: Reading number of atoms.\n"); return TRAJIN_ERR; } if (natom_ != trajParm->Natom()) { mprinterr("Error: Number of atoms %i does not match associated parm %s (%i)\n", natom_, trajParm->c_str(), trajParm->Natom()); return TRAJIN_ERR; } // Read first atom to see if there are velocities ptr = file_.Line(); int nread = sscanf(ptr, "%*5c%*5c%*5c%*5c%f %f %f %f %f %f", fXYZ, fXYZ+1, fXYZ+2, fXYZ+3, fXYZ+4, fXYZ+5); bool hasV = false; if (nread == 6) hasV = true; else if (nread != 3) { mprinterr("Error: Reading first atom, expected 3 or 6 coordinates, got %i\n", nread); return TRAJIN_ERR; } // Read past the rest of the atoms for (int i = 1; i != natom_; i++) if (file_.Line() == 0) { mprinterr("Error: Reading atom %i of first frame.\n", i+1); return TRAJIN_ERR; } // Attempt to read box line // v1(x) v2(y) v3(z) [v1(y) v1(z) v2(x) v2(z) v3(x) v3(y)] ptr = file_.Line(); Box groBox; if (ptr != 0) groBox = GetBox( ptr ); // Set trajectory information. No temperature info. SetCoordInfo( CoordinateInfo(groBox, hasV, false, hasTime) ); SetTitle( title ); // Check for multiple frames. If nothing was read above, 1 frame, no box. If // box info was read but nothing more can be read, 1 frame. Otherwise there // are more frames. bool hasMultipleFrames = false; if (ptr != 0) { if (groBox.Type() == Box::NOBOX) // Assume another title read. hasMultipleFrames = true; else { ptr = file_.Line(); // Read line after box info if (ptr != 0) hasMultipleFrames = true; } } // Set up some info for performing blank reads. linesToRead_ = natom_; if (groBox.Type() != Box::NOBOX) linesToRead_ += 1; int nframes = 1; if (hasMultipleFrames) { // Since there is no guarantee that each frame is the same size we cannot // just seek. Blank reads for as many times as possible. Should currently // be positioned at the title line of the next frame. while (ptr != 0 ) { ptr = file_.Line(); // Natoms int Nat = atoi(ptr); if (Nat != natom_) { mprinterr("Error: Frame %i # atoms (%i) does not match first frame (%i).\n" "Error: Only reading %i frames.\n", nframes+1, Nat, natom_, nframes); break; } for (int i = 0; i != linesToRead_; i++) ptr = file_.Line(); if (ptr == 0) break; nframes++; ptr = file_.Line(); // Next title or EOF } } file_.CloseFile(); return nframes; }
// Traj_AmberCoord::setupTrajin() int Traj_AmberCoord::setupTrajin(FileName const& fname, Topology* trajParm) { // Set up file for reading if (file_.SetupRead( fname, debug_ )) return TRAJIN_ERR; // Attempt to open the file. Read and set the title and titleSize if ( file_.OpenFile() ) return TRAJIN_ERR; std::string title = file_.GetLine(); // Allocate mem to read in frame (plus REMD header if present). REMD // header is checked for when file is IDd. Title size is used in seeking. natom3_ = trajParm->Natom() * 3; file_.SetupFrameBuffer( natom3_, 8, 10, headerSize_, title.size() ); if (debug_ > 0) { mprintf("Each frame is %zu bytes", file_.FrameSize()); if (headerSize_ != 0) mprintf(" (including REMD header)"); mprintf(".\n"); } // Read the first frame of coordinates if ( file_.ReadFrame() ) { mprinterr("Error: in read of Coords frame 1 of trajectory %s.\n", file_.Filename().base()); return TRAJIN_ERR; } // Check for box coordinates. If present, update the frame size and // reallocate the frame buffer. If less than 3 atoms there is no way // to tell if a line is a box line or coordinates, so skip. Box boxInfo; if ( trajParm->Natom() < 3 ) { mprintf("Warning: Less than 3 atoms, skipping box check.\n"); numBoxCoords_ = 0; } else { std::string nextLine = file_.GetLine(); if ( !nextLine.empty() ) { if (debug_>0) rprintf("DEBUG: Line after first frame: (%s)\n", nextLine.c_str()); if ( IsRemdHeader(nextLine.c_str()) || IsRxsgldHeader(nextLine.c_str()) ) { // REMD header - no box coords numBoxCoords_ = 0; } else { double box[8]; numBoxCoords_ = sscanf(nextLine.c_str(), "%8lf%8lf%8lf%8lf%8lf%8lf%8lf%8lf", box, box+1, box+2, box+3, box+4, box+5, box+6, box+7); if (numBoxCoords_ == -1) { mprinterr("Error: Could not read Box coord line of trajectory %s.\n", file_.Filename().base()); return TRAJIN_ERR; } else if (numBoxCoords_ == 8) { // Full line of coords was read, no box coords. numBoxCoords_ = 0; } else if (numBoxCoords_ == 3) { // Box lengths only, ortho. or truncated oct. Use default parm angles. if (trajParm->ParmBox().Type() == Box::NOBOX) mprintf("Warning: Trajectory only contains box lengths and topology has no box info.\n" "Warning: To set box angles for topology use the 'parmbox' command.\n"); box[3] = boxAngle_[0] = trajParm->ParmBox().Alpha(); box[4] = boxAngle_[1] = trajParm->ParmBox().Beta(); box[5] = boxAngle_[2] = trajParm->ParmBox().Gamma(); boxInfo.SetBox( box ); } else if (numBoxCoords_ == 6) { // General triclinic. Set lengths and angles. boxInfo.SetBox( box ); } else { mprinterr("Error: In %s, expect only 3 or 6 box coords, got %i\n" "Error: Box line=[%s]\n", file_.Filename().base(), numBoxCoords_, nextLine.c_str()); return TRAJIN_ERR; } } } // Reallocate frame buffer accordingly file_.ResizeBuffer( numBoxCoords_ ); } // Calculate Frames and determine seekable. If not possible and this is not a // compressed file the trajectory is probably corrupted. Frames will // be read until EOF. int Frames = 0; if (debug_>0) rprintf("Title offset=%lu FrameSize=%lu UncompressedFileSize=%lu\n", title.size(), file_.FrameSize(), file_.UncompressedSize()); off_t title_size = (off_t) title.size(); off_t frame_size = (off_t) file_.FrameSize(); off_t uncompressed_size = file_.UncompressedSize(); off_t file_size = uncompressed_size - title_size; bool seekable = false; if (file_.Compression() != CpptrajFile::NO_COMPRESSION) { // -----==== AMBER TRAJ COMPRESSED ====------ // If the uncompressed size of compressed file is reported as <= 0, // uncompressed size cannot be determined. Read coordinates until // EOF. if (uncompressed_size <= 0) { mprintf("Warning: %s: Uncompressed size of trajectory could not be determined.\n", file_.Filename().base()); if (file_.Compression() == CpptrajFile::BZIP2) mprintf(" (This is normal for bzipped files)\n"); mprintf(" Number of frames could not be calculated.\n"); mprintf(" Frames will be read until EOF.\n"); Frames = TRAJIN_UNK; seekable = false; } else { // Frame calculation for large gzip files if (file_.Compression() == CpptrajFile::GZIP) { // Since this is gzip compressed, if the file_size % frame size != 0, // it could be that the uncompressed filesize > 4GB. Since // ISIZE = uncompressed % 2^32, // try ((file_size + (2^32 * i)) % frame_size) and see if any are 0. if ( (file_size % frame_size) != 0) { // Determine the maximum number of iterations to try based on the // fact that Amber trajectories typically compress about 3x with // gzip. off_t tmpfsize = ((file_.FileSize() * 4) - uncompressed_size) / 4294967296LL; int maxi = (int) tmpfsize; ++maxi; if (debug_>1) mprintf("\tLooking for uncompressed gzip size > 4GB, %i iterations.\n",maxi); tmpfsize = 0; bool sizeFound = false; for (int i = 0; i < maxi; i++ ) { tmpfsize = (4294967296LL * i) + file_size; if ( (tmpfsize % frame_size) == 0) {sizeFound=true; break;} } if (sizeFound) file_size = tmpfsize; } } if ((file_size % frame_size) == 0) { Frames = (int) (file_size / frame_size); seekable = true; } else { mprintf("Warning: %s: Number of frames in compressed traj could not be determined.\n" "Warning: Frames will be read until EOF.\n", file_.Filename().base()); Frames = TRAJIN_UNK; seekable = false; } } } else { // ----==== AMBER TRAJ NOT COMPRESSED ====---- Frames = (int) (file_size / frame_size); if ( (file_size % frame_size) == 0 ) { seekable = true; } else { mprintf("Warning: %s: Could not accurately predict # frames. This usually\n" "Warning: indicates a corrupted trajectory or trajectory/topology\n" "Warning: mismatch. Will attempt to read %i frames.\n", file_.Filename().base(), Frames); seekable = false; } } if (debug_>0) rprintf("Atoms: %i FrameSize: %lu TitleSize: %lu NumBox: %i Seekable: %i Frames: %i\n\n", trajParm->Natom(), frame_size, title_size, numBoxCoords_, (int)seekable, Frames); // Close the file file_.CloseFile(); // Set trajectory info: no velocity, no time. SetCoordInfo( CoordinateInfo(boxInfo, false, (headerSize_ != 0), false) ); SetTitle( title ); return Frames; }