// TODO: Use Box class int NetcdfFile::SetupBox(double* boxIn, NCTYPE typeIn) { boxIn[0] = 0.0; boxIn[1] = 0.0; boxIn[2] = 0.0; boxIn[3] = 0.0; boxIn[4] = 0.0; boxIn[5] = 0.0; if ( nc_inq_varid(ncid_,NCCELL_LENGTHS,&cellLengthVID_)==NC_NOERR ) { if (checkNCerr(nc_inq_varid(ncid_,NCCELL_ANGLES,&cellAngleVID_)) ) { mprinterr("Error: Getting cell angles.\n"); return 1; } if (ncdebug_>0) mprintf(" Netcdf Box information found.\n"); // If present, get box angles. These will be used to determine the box // type in TrajectoryFile. start_[0]=0; start_[1]=0; start_[2]=0; start_[3]=0; switch (typeIn) { case NC_AMBERRESTART: count_[0]=3; count_[1]=0; count_[2]=0; break; case NC_AMBERTRAJ: count_[0]=1; count_[1]=3; count_[2]=0; break; case NC_AMBERENSEMBLE: count_[0]=1; // NOTE: All ensemble members must have same box type count_[1]=1; // TODO: Check all members? count_[2]=3; break; case NC_UNKNOWN: return 1; // Sanity check } count_[3]=0; if ( checkNCerr(nc_get_vara_double(ncid_, cellLengthVID_, start_, count_, boxIn )) ) { mprinterr("Error: Getting cell lengths.\n"); return 1; } if ( checkNCerr(nc_get_vara_double(ncid_, cellAngleVID_, start_, count_, boxIn+3)) ) { mprinterr("Error: Getting cell angles.\n"); return 1; } if (ncdebug_ > 0) mprintf("\tNetcdf Box: XYZ={%f %f %f} ABG={%f %f %f}\n", boxIn[0], boxIn[1], boxIn[2], boxIn[3], boxIn[4], boxIn[5]); return 0; } // No box information return -1; }
// NetcdfFile::NC_defineTemperature() int NetcdfFile::NC_defineTemperature(int* dimensionID, int NDIM) { if (checkNCerr(nc_def_var(ncid_,NCTEMPERATURE,NC_DOUBLE,NDIM,dimensionID,&TempVID_))) { mprinterr("NetCDF error on defining temperature.\n"); return 1; } if (checkNCerr(nc_put_att_text(ncid_,TempVID_,"units",6,"kelvin"))) { mprinterr("NetCDF error on defining temperature units.\n"); return 1; } return 0; }
/** Get the specified frame from amber netcdf file * Coords are a 1 dimensional array of format X1,Y1,Z1,X2,Y2,Z2,... */ int Traj_AmberNetcdf::readFrame(int set,double *X, double *V,double *box, double *T) { // Get temperature if (TempVID_!=-1) { start_[0] = set; count_[0] = 1; if ( checkNCerr(nc_get_vara_double(ncid_, TempVID_, start_, count_, T)) ) { mprinterr("Error: Getting replica temperature.\n"); return 1; } //fprintf(stderr,"DEBUG: Replica Temperature %lf\n",F->T); } // Read Coords start_[0] = set; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; if ( checkNCerr(nc_get_vara_float(ncid_, coordVID_, start_, count_, Coord_)) ) { mprinterr("Error: Getting frame %i\n", set); return 1; } FloatToDouble(X, Coord_); // Read Velocities if (velocityVID_ != -1) { if ( checkNCerr(nc_get_vara_float(ncid_, velocityVID_, start_, count_, Veloc_)) ) { mprinterr("Error: Getting velocities for frame %i\n", set); return 1; } FloatToDouble(V, Veloc_); } // Read box info if (cellLengthVID_ != -1) { count_[1] = 3; count_[2] = 0; if ( checkNCerr(nc_get_vara_double(ncid_, cellLengthVID_, start_, count_, box)) ) { mprinterr("Getting cell lengths.\n"); return 1; } if ( checkNCerr(nc_get_vara_double(ncid_, cellAngleVID_, start_, count_, box+3)) ) { mprinterr("Getting cell angles.\n"); return 1; } } return 0; }
// NetcdfFile::NC_close() void NetcdfFile::NC_close() { if (ncid_ == -1) return; bool err = checkNCerr( nc_close(ncid_) ); if (ncdebug_ > 0 && !err) mprintf("Successfully closed ncid %i\n",ncid_); ncid_ = -1; }
/** Determine if Netcdf file contains time; set up timeVID and check units. */ int NetcdfFile::SetupTime() { if ( nc_inq_varid(ncid_, NCTIME, &timeVID_) == NC_NOERR ) { std::string attrText = GetAttrText(timeVID_, "units"); if (attrText!="picosecond") mprintf("Warning: NetCDF file has time units of %s - expected picosecond.\n", attrText.c_str()); // Check for time values which have NOT been filled, which was possible // with netcdf trajectories created by older versions of ptraj/cpptraj. if (ncframe_ > 0 && GetNetcdfConventions() == NC_AMBERTRAJ) { float time; start_[0] = 0; count_[0] = 1; if (checkNCerr(nc_get_vara_float(ncid_, timeVID_, start_, count_, &time))) { mprinterr("Error: Getting time value for NetCDF file.\n"); return -1; } if (time == NC_FILL_FLOAT) { mprintf("Warning: NetCDF file time variable defined but empty. Disabling.\n"); timeVID_ = -1; } } return 0; } timeVID_=-1; return 1; }
/** Determine if Netcdf file contains multi-D REMD info. If so set the * number of replica dimensions (remd_dimension_) and figure out * the dimension types (remdDim) */ int NetcdfFile::SetupMultiD(ReplicaDimArray& remdDim) { int dimensionDID; if ( nc_inq_dimid(ncid_, NCREMD_DIMENSION, &dimensionDID) != NC_NOERR) return 1; // Although this is a second call to dimid, makes for easier code if ( (dimensionDID = GetDimInfo(NCREMD_DIMENSION, &remd_dimension_))==-1 ) return -1; if (ncdebug_ > 0) mprintf("\tNetcdf file has multi-D REMD info, %i dimensions.\n",remd_dimension_); // Ensure valid # dimensions if (remd_dimension_ < 1) { mprinterr("Error: Number of REMD dimensions is less than 1!\n"); return -1; } // Start and count for groupnum and dimtype, allocate mem start_[0]=0; start_[1]=0; start_[2]=0; count_[0]=remd_dimension_; count_[1]=0; count_[2]=0; int* remd_dimtype = new int[ remd_dimension_ ]; // Get dimension types int dimtypeVID; if ( checkNCerr(nc_inq_varid(ncid_, NCREMD_DIMTYPE, &dimtypeVID)) ) { mprinterr("Error: Getting dimension type variable ID for each dimension.\n"); return -1; } if ( checkNCerr(nc_get_vara_int(ncid_, dimtypeVID, start_, count_, remd_dimtype)) ) { mprinterr("Error: Getting dimension type in each dimension.\n"); return -1; } // Get VID for replica indices if ( checkNCerr(nc_inq_varid(ncid_, NCREMD_INDICES, &indicesVID_)) ) { mprinterr("Error: Getting replica indices variable ID.\n"); return -1; } // Print info for each dimension for (int dim = 0; dim < remd_dimension_; ++dim) remdDim.AddRemdDimension( remd_dimtype[dim] ); delete[] remd_dimtype; return 0; }
/** Return the dimension ID of a given attribute in netcdf file ncid. * Also set dimension length. */ int NetcdfFile::GetDimInfo(const char *attribute, int *length) { int dimID; size_t slength = 0; *length = 0; // Get dimid if ( checkNCerr(nc_inq_dimid(ncid_, attribute, &dimID)) ) { mprinterr("Error: Getting dimID for attribute %s\n",attribute); return -1; } // get Dim length if ( checkNCerr(nc_inq_dimlen(ncid_, dimID, &slength)) ) { mprinterr("Error: Getting length for attribute %s\n",attribute); return -1; } *length = (int) slength; return dimID; }
// Traj_AmberNetcdf::writeFrame() int Traj_AmberNetcdf::writeFrame(int set, double *X, double *V, double *box, double T) { DoubleToFloat(Coord_, X); // Write coords start_[0] = ncframe_; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; if (checkNCerr(nc_put_vara_float(ncid_,coordVID_,start_,count_,Coord_)) ) { mprinterr("Error: Netcdf Writing frame %i\n",set); return 1; } // Write box if (cellLengthVID_ != -1) { count_[1] = 3; count_[2] = 0; if (checkNCerr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,box)) ) { mprinterr("Error: Writing cell lengths.\n"); return 1; } if (checkNCerr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_, box+3)) ) { mprinterr("Error: Writing cell angles.\n"); return 1; } } // Write temperature if (TempVID_!=-1) { if ( checkNCerr( nc_put_vara_double(ncid_,TempVID_,start_,count_,&T)) ) { mprinterr("Error: Writing temperature.\n"); return 1; } } nc_sync(ncid_); // Necessary after every write?? ++ncframe_; return 0; }
/** Get the specified frame from amber netcdf file * Coords are a 1 dimensional array of format X1,Y1,Z1,X2,Y2,Z2,... */ int Traj_AmberRestartNC::readFrame(int set,double *X, double *V,double *box, double *T) { // Get temperature if (TempVID_!=-1) { if ( checkNCerr(nc_get_var_double(ncid_, TempVID_, T)) ) { mprinterr("Error: Getting replica temperature.\n"); return 1; } if (debug_>1) mprintf("DEBUG: %s: Replica Temperature %lf\n",filename_.base(), T); } // Read Coords start_[0] = 0; start_[1] = 0; count_[0] = Ncatom(); count_[1] = 3; if ( checkNCerr(nc_get_vara_double(ncid_, coordVID_, start_, count_, X)) ) { mprinterr("Error: Getting Coords\n"); return 1; } // Read Velocity if (velocityVID_!=-1 && V!=0) { if ( checkNCerr(nc_get_vara_double(ncid_, velocityVID_, start_, count_, V)) ) { mprinterr("Error: Getting velocities\n"); return 1; } } // Read box info if (cellLengthVID_ != -1) { count_[0] = 3; count_[1] = 0; if ( checkNCerr(nc_get_vara_double(ncid_, cellLengthVID_, start_, count_, box)) ) { mprinterr("Error: Getting cell lengths.\n"); return 1; } if ( checkNCerr(nc_get_vara_double(ncid_, cellAngleVID_, start_, count_, box+3)) ) { mprinterr("Error: Getting cell angles.\n"); return 1; } } return 0; }
int Traj_AmberRestartNC::readIndices(int set, int* remd_indices) { if (indicesVID_!=-1) { start_[0] = 0; count_[1] = remd_dimension_; if ( checkNCerr(nc_get_vara_int(ncid_, indicesVID_, start_, count_, remd_indices)) ) { mprinterr("Error: Getting replica indices.\n"); return 1; } //mprintf("DEBUG:\tReplica Rst indices:"); //for (int dim=0; dim < remd_dimension_; dim++) mprintf(" %i",remd_indices[dim]); //mprintf("\n"); } return 0; }
/** Get the information about a netcdf attribute with given vid and * attribute text. * Since there is no guarantee that null char at the end of retrieved string * append one. */ std::string NetcdfFile::GetAttrText(int vid, const char *attribute) { size_t attlen; std::string attrOut; // Get attr length if ( checkNCerr(nc_inq_attlen(ncid_, vid, attribute, &attlen)) ) { mprintf("Warning: Getting length for attribute '%s'\n",attribute); return attrOut; } // Allocate space for attr text, plus one for null char char *attrText = new char[ (attlen + 1) ]; // Get attr text if ( checkNCerr(nc_get_att_text(ncid_, vid, attribute, attrText)) ) { mprintf("Warning: Getting attribute text for '%s'\n",attribute); delete[] attrText; return attrOut; } // Append null char - NECESSARY? attrText[attlen]='\0'; attrOut.assign( attrText ); delete[] attrText; return attrOut; }
// Traj_AmberNetcdf::readVelocity() int Traj_AmberNetcdf::readVelocity(int set, Frame& frameIn) { start_[0] = set; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; // Read Velocities if (velocityVID_ != -1) { if ( checkNCerr(nc_get_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) { mprinterr("Error: Getting velocities for frame %i\n", set+1); return 1; } FloatToDouble(frameIn.vAddress(), Coord_); } return 0; }
// Traj_AmberNetcdf::writeReservoir() TODO: Make Frame const& int Traj_AmberNetcdf::writeReservoir(int set, Frame const& frame, double energy, int bin) { start_[0] = ncframe_; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; // Coords DoubleToFloat(Coord_, frame.xAddress()); if (checkNCerr(nc_put_vara_float(ncid_,coordVID_,start_,count_,Coord_)) ) { mprinterr("Error: Netcdf writing reservoir coords %i\n",set); return 1; } // Velo if (velocityVID_ != -1) { if (frame.vAddress() == 0) { // TODO: Make it so this can NEVER happen. mprinterr("Error: Reservoir expects velocities, but no velocities in frame.\n"); return 1; } DoubleToFloat(Coord_, frame.vAddress()); if (checkNCerr(nc_put_vara_float(ncid_,velocityVID_,start_,count_,Coord_)) ) { mprinterr("Error: Netcdf writing reservoir velocities %i\n",set); return 1; } } // Eptot, bins if ( checkNCerr( nc_put_vara_double(ncid_,eptotVID_,start_,count_,&energy)) ) { mprinterr("Error: Writing eptot.\n"); return 1; } if (binsVID_ != -1) { if ( checkNCerr( nc_put_vara_int(ncid_,binsVID_,start_,count_,&bin)) ) { mprinterr("Error: Writing bins.\n"); return 1; } } // Write box if (cellLengthVID_ != -1) { count_[1] = 3; count_[2] = 0; if (checkNCerr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,frame.bAddress())) ) { mprinterr("Error: Writing cell lengths.\n"); return 1; } if (checkNCerr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_, frame.bAddress()+3)) ) { mprinterr("Error: Writing cell angles.\n"); return 1; } } nc_sync(ncid_); // Necessary after every write?? ++ncframe_; return 0; }
// NetcdfFile::NC_createReservoir() int NetcdfFile::NC_createReservoir(bool hasBins, double reservoirT, int iseed, int& eptotVID, int& binsVID) { int dimensionID[1]; dimensionID[0] = frameDID_; if (ncid_ == -1 || dimensionID[0] == -1) return 1; // Place file back in define mode if ( checkNCerr( nc_redef( ncid_ ) ) ) return 1; // Define eptot, bins, temp0 if ( checkNCerr( nc_def_var(ncid_, NCEPTOT, NC_DOUBLE, 1, dimensionID, &eptotVID)) ) { mprinterr("Error: defining eptot variable ID.\n"); return 1; } if (hasBins) { if ( checkNCerr( nc_def_var(ncid_, NCBINS, NC_INT, 1, dimensionID, &binsVID)) ) { mprinterr("Error: defining bins variable ID.\n"); return 1; } } else binsVID = -1; if (NC_defineTemperature(dimensionID, 0)) return 1; // Random seed, make global if ( checkNCerr( nc_put_att_int(ncid_, NC_GLOBAL, "iseed", NC_INT, 1, &iseed) ) ) { mprinterr("Error: setting random seed attribute.\n"); return 1; } // End definitions if (checkNCerr(nc_enddef(ncid_))) { mprinterr("NetCDF error on ending definitions."); return 1; } // Write temperature if (checkNCerr(nc_put_var_double(ncid_,TempVID_,&reservoirT)) ) { mprinterr("Error: Writing reservoir temperature.\n"); return 1; } return 0; }
// NetcdfFile::NC_create() int NetcdfFile::NC_create(std::string const& Name, NCTYPE type, int natomIn, CoordinateInfo const& coordInfo, std::string const& title) { if (Name.empty()) return 1; int dimensionID[NC_MAX_VAR_DIMS]; int NDIM; nc_type dataType; if (ncdebug_>1) mprintf("DEBUG: NC_create: %s natom=%i V=%i F=%i box=%i temp=%i time=%i\n", Name.c_str(),natomIn,(int)coordInfo.HasVel(), (int)coordInfo.HasForce(),(int)coordInfo.HasBox(), (int)coordInfo.HasTemp(),(int)coordInfo.HasTime()); if ( checkNCerr( nc_create( Name.c_str(), NC_64BIT_OFFSET, &ncid_) ) ) return 1; ncatom_ = natomIn; ncatom3_ = ncatom_ * 3; // Set number of dimensions based on file type switch (type) { case NC_AMBERENSEMBLE: NDIM = 4; dataType = NC_FLOAT; break; case NC_AMBERTRAJ: NDIM = 3; dataType = NC_FLOAT; break; case NC_AMBERRESTART: NDIM = 2; dataType = NC_DOUBLE; break; default: mprinterr("Error: NC_create (%s): Unrecognized type (%i)\n",Name.c_str(),(int)type); return 1; } if (type == NC_AMBERENSEMBLE) { // Ensemble dimension for ensemble if (coordInfo.EnsembleSize() < 1) { mprinterr("Internal Error: NetcdfFile: ensembleSize < 1\n"); return 1; } if ( checkNCerr(nc_def_dim(ncid_, NCENSEMBLE, coordInfo.EnsembleSize(), &ensembleDID_)) ) { mprinterr("Error: Defining ensemble dimension.\n"); return 1; } dimensionID[1] = ensembleDID_; } ncframe_ = 0; if (type == NC_AMBERTRAJ || type == NC_AMBERENSEMBLE) { // Frame dimension for traj if ( checkNCerr( nc_def_dim( ncid_, NCFRAME, NC_UNLIMITED, &frameDID_)) ) { mprinterr("Error: Defining frame dimension.\n"); return 1; } // Since frame is UNLIMITED, it must be lowest dim. dimensionID[0] = frameDID_; } // Time variable and units if (coordInfo.HasTime()) { if ( checkNCerr( nc_def_var(ncid_, NCTIME, dataType, NDIM-2, dimensionID, &timeVID_)) ) { mprinterr("Error: Defining time variable.\n"); return 1; } if ( checkNCerr( nc_put_att_text(ncid_, timeVID_, "units", 10, "picosecond")) ) { mprinterr("Error: Writing time VID units.\n"); return 1; } } // Spatial dimension and variable if ( checkNCerr( nc_def_dim( ncid_, NCSPATIAL, 3, &spatialDID_)) ) { mprinterr("Error: Defining spatial dimension.\n"); return 1; } dimensionID[0] = spatialDID_; if ( checkNCerr( nc_def_var( ncid_, NCSPATIAL, NC_CHAR, 1, dimensionID, &spatialVID_)) ) { mprinterr("Error: Defining spatial variable.\n"); return 1; } // Atom dimension if ( checkNCerr( nc_def_dim( ncid_, NCATOM, ncatom_, &atomDID_)) ) { mprinterr("Error: Defining atom dimension.\n"); return 1; } // Setup dimensions for Coords/Velocity // NOTE: THIS MUST BE MODIFIED IF NEW TYPES ADDED if (type == NC_AMBERENSEMBLE) { dimensionID[0] = frameDID_; dimensionID[1] = ensembleDID_; dimensionID[2] = atomDID_; dimensionID[3] = spatialDID_; } else if (type == NC_AMBERTRAJ) { dimensionID[0] = frameDID_; dimensionID[1] = atomDID_; dimensionID[2] = spatialDID_; } else { dimensionID[0] = atomDID_; dimensionID[1] = spatialDID_; } // Coord variable if ( checkNCerr( nc_def_var( ncid_, NCCOORDS, dataType, NDIM, dimensionID, &coordVID_)) ) { mprinterr("Error: Defining coordinates variable.\n"); return 1; } if ( checkNCerr( nc_put_att_text( ncid_, coordVID_, "units", 8, "angstrom")) ) { mprinterr("Error: Writing coordinates variable units.\n"); return 1; } // Velocity variable if (coordInfo.HasVel()) { if ( checkNCerr( nc_def_var( ncid_, NCVELO, dataType, NDIM, dimensionID, &velocityVID_)) ) { mprinterr("Error: Defining velocities variable.\n"); return 1; } if ( checkNCerr( nc_put_att_text( ncid_, velocityVID_, "units", 19, "angstrom/picosecond")) ) { mprinterr("Error: Writing velocities variable units.\n"); return 1; } if ( checkNCerr( nc_put_att_double( ncid_, velocityVID_, "scale_factor", NC_DOUBLE, 1, &Constants::AMBERTIME_TO_PS)) ) { mprinterr("Error: Writing velocities scale factor.\n"); return 1; } } // Force variable if (coordInfo.HasForce()) { if ( checkNCerr( nc_def_var( ncid_, NCFRC, dataType, NDIM, dimensionID, &frcVID_)) ) { mprinterr("Error: Defining forces variable\n"); return 1; } if ( checkNCerr( nc_put_att_text( ncid_, frcVID_, "units", 25, "kilocalorie/mole/angstrom")) ) { mprinterr("Error: Writing forces variable units.\n"); return 1; } } // Replica Temperature if (coordInfo.HasTemp()) { // NOTE: Setting dimensionID should be OK for Restart, will not be used. dimensionID[0] = frameDID_; if ( NC_defineTemperature( dimensionID, NDIM-2 ) ) return 1; } // Replica indices int remDimTypeVID = -1; if (coordInfo.HasReplicaDims()) { // Define number of replica dimensions remd_dimension_ = coordInfo.ReplicaDimensions().Ndims(); int remDimDID = -1; if ( checkNCerr(nc_def_dim(ncid_, NCREMD_DIMENSION, remd_dimension_, &remDimDID)) ) { mprinterr("Error: Defining replica indices dimension.\n"); return 1; } dimensionID[0] = remDimDID; // For each dimension, store the type if ( checkNCerr(nc_def_var(ncid_, NCREMD_DIMTYPE, NC_INT, 1, dimensionID, &remDimTypeVID)) ) { mprinterr("Error: Defining replica dimension type variable.\n"); return 1; } // Need to store the indices of replica in each dimension each frame // NOTE: THIS MUST BE MODIFIED IF NEW TYPES ADDED if (type == NC_AMBERENSEMBLE) { dimensionID[0] = frameDID_; dimensionID[1] = ensembleDID_; dimensionID[2] = remDimDID; } else if (type == NC_AMBERTRAJ) { dimensionID[0] = frameDID_; dimensionID[1] = remDimDID; } else { dimensionID[0] = remDimDID; } if (checkNCerr(nc_def_var(ncid_, NCREMD_INDICES, NC_INT, NDIM-1, dimensionID, &indicesVID_))) { mprinterr("Error: Defining replica indices variable ID.\n"); return 1; } // TODO: Determine if groups are really necessary for restarts. If not, // remove from AmberNetcdf.F90. } // Box Info if (coordInfo.HasBox()) { // Cell Spatial if ( checkNCerr( nc_def_dim( ncid_, NCCELL_SPATIAL, 3, &cell_spatialDID_)) ) { mprinterr("Error: Defining cell spatial dimension.\n"); return 1; } dimensionID[0] = cell_spatialDID_; if ( checkNCerr( nc_def_var(ncid_, NCCELL_SPATIAL, NC_CHAR, 1, dimensionID, &cell_spatialVID_))) { mprinterr("Error: Defining cell spatial variable.\n"); return 1; } // Cell angular if ( checkNCerr( nc_def_dim( ncid_, NCLABEL, NCLABELLEN, &labelDID_)) ) { mprinterr("Error: Defining label dimension.\n"); return 1; } if ( checkNCerr( nc_def_dim( ncid_, NCCELL_ANGULAR, 3, &cell_angularDID_)) ) { mprinterr("Error: Defining cell angular dimension.\n"); return 1; } dimensionID[0] = cell_angularDID_; dimensionID[1] = labelDID_; if ( checkNCerr( nc_def_var( ncid_, NCCELL_ANGULAR, NC_CHAR, 2, dimensionID, &cell_angularVID_)) ) { mprinterr("Error: Defining cell angular variable.\n"); return 1; } // Setup dimensions for Box // NOTE: This must be modified if more types added int boxdim; if (type == NC_AMBERENSEMBLE) { dimensionID[0] = frameDID_; dimensionID[1] = ensembleDID_; boxdim = 2; } else if (type == NC_AMBERTRAJ) { dimensionID[0] = frameDID_; boxdim = 1; } else { boxdim = 0; } dimensionID[boxdim] = cell_spatialDID_; if ( checkNCerr( nc_def_var( ncid_, NCCELL_LENGTHS, NC_DOUBLE, NDIM-1, dimensionID, &cellLengthVID_)) ) { mprinterr("Error: Defining cell length variable.\n"); return 1; } if ( checkNCerr( nc_put_att_text( ncid_, cellLengthVID_, "units", 8, "angstrom")) ) { mprinterr("Error: Writing cell length variable units.\n"); return 1; } dimensionID[boxdim] = cell_angularDID_; if ( checkNCerr( nc_def_var( ncid_, NCCELL_ANGLES, NC_DOUBLE, NDIM-1, dimensionID, &cellAngleVID_)) ) { mprinterr("Error: Defining cell angle variable.\n"); return 1; } if ( checkNCerr( nc_put_att_text( ncid_, cellAngleVID_, "units", 6, "degree")) ) { mprinterr("Error: Writing cell angle variable units.\n"); return 1; } } // Attributes if (checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"title",title.size(),title.c_str())) ) { mprinterr("Error: Writing title.\n"); return 1; } if (checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"application",5,"AMBER")) ) { mprinterr("Error: Writing application.\n"); return 1; } if (checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"program",7,"cpptraj")) ) { mprinterr("Error: Writing program.\n"); return 1; } if (checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"programVersion", NETCDF_VERSION_STRLEN, NETCDF_VERSION_STRING)) ) { mprinterr("Error: Writing program version.\n"); return 1; } // TODO: Make conventions a static string bool errOccurred = false; if ( type == NC_AMBERENSEMBLE ) errOccurred = checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"Conventions",13,"AMBERENSEMBLE")); else if ( type == NC_AMBERTRAJ ) errOccurred = checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"Conventions",5,"AMBER")); else errOccurred = checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"Conventions",12,"AMBERRESTART")); if (errOccurred) { mprinterr("Error: Writing conventions.\n"); return 1; } if (checkNCerr(nc_put_att_text(ncid_,NC_GLOBAL,"ConventionVersion",3,"1.0")) ) { mprinterr("Error: Writing conventions version.\n"); return 1; } // Set fill mode if (checkNCerr(nc_set_fill(ncid_, NC_NOFILL, dimensionID))) { mprinterr("Error: NetCDF setting fill value.\n"); return 1; } // End netcdf definitions if (checkNCerr(nc_enddef(ncid_))) { mprinterr("NetCDF error on ending definitions."); return 1; } // Specify spatial dimension labels start_[0] = 0; count_[0] = 3; char xyz[3]; xyz[0] = 'x'; xyz[1] = 'y'; xyz[2] = 'z'; if (checkNCerr(nc_put_vara_text(ncid_, spatialVID_, start_, count_, xyz))) { mprinterr("Error on NetCDF output of spatial VID 'x', 'y' and 'z'"); return 1; } if ( coordInfo.HasBox() ) { xyz[0] = 'a'; xyz[1] = 'b'; xyz[2] = 'c'; if (checkNCerr(nc_put_vara_text(ncid_, cell_spatialVID_, start_, count_, xyz))) { mprinterr("Error on NetCDF output of cell spatial VID 'a', 'b' and 'c'"); return 1; } char abc[15] = { 'a', 'l', 'p', 'h', 'a', 'b', 'e', 't', 'a', ' ', 'g', 'a', 'm', 'm', 'a' }; start_[0] = 0; start_[1] = 0; count_[0] = 3; count_[1] = NCLABELLEN; if (checkNCerr(nc_put_vara_text(ncid_, cell_angularVID_, start_, count_, abc))) { mprinterr("Error on NetCDF output of cell angular VID 'alpha', 'beta ' and 'gamma'"); return 1; } } // Store the type of each replica dimension. if (coordInfo.HasReplicaDims()) { ReplicaDimArray const& remdDim = coordInfo.ReplicaDimensions(); start_[0] = 0; count_[0] = remd_dimension_; int* tempDims = new int[ remd_dimension_ ]; for (int i = 0; i < remd_dimension_; ++i) tempDims[i] = remdDim[i]; if (checkNCerr(nc_put_vara_int(ncid_, remDimTypeVID, start_, count_, tempDims))) { mprinterr("Error: writing replica dimension types.\n"); delete[] tempDims; return 1; } delete[] tempDims; } return 0; }
// Traj_AmberRestartNC::writeFrame() int Traj_AmberRestartNC::writeFrame(int set, double *X, double *V,double *box, double T) { // Set up file for this set bool V_present = (HasV() && V != 0); std::string fname; // Create filename for this set // If just writing 1 frame dont modify output filename if (singleWrite_) fname = filename_.Full(); else fname = NumberFilename(filename_.Full(), set+1); if ( NC_create( fname.c_str(), NC_AMBERRESTART, Ncatom(), V_present, HasBox(), HasT(), (time0_ >= 0), Title() ) ) return 1; // write coords start_[0] = 0; start_[1] = 0; count_[0] = Ncatom(); count_[1] = 3; if (checkNCerr(nc_put_vara_double(ncid_,coordVID_,start_,count_,X)) ) { mprinterr("Error: Netcdf restart Writing coordinates %i\n",set); return 1; } // write velocity if (V_present) { mprintf("DEBUG: Writing V, VID=%i\n",velocityVID_); if (checkNCerr(nc_put_vara_double(ncid_,velocityVID_,start_,count_,V)) ) { mprinterr("Error: Netcdf restart writing velocity %i\n",set); return 1; } } // write box if (cellLengthVID_ != -1) { count_[0] = 3; count_[1] = 0; if (checkNCerr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,box)) ) { mprinterr("Error: Writing cell lengths.\n"); return 1; } if (checkNCerr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_, box+3)) ) { mprinterr("Error: Writing cell angles.\n"); return 1; } } // write time if (timeVID_ != -1) { restartTime_ = (time0_ + (double)set) * dt_; if (checkNCerr(nc_put_var_double(ncid_,timeVID_,&restartTime_)) ) { mprinterr("Error: Writing restart time.\n"); return 1; } } // write temperature if (TempVID_ != -1) { if (checkNCerr(nc_put_var_double(ncid_,TempVID_,&T)) ) { mprinterr("Error: Writing restart temperature.\n"); return 1; } } //nc_sync(ncid_); // Necessary? File about to close anyway... // Close file for this set closeTraj(); return 0; }
// NetcdfFile::NC_openWrite() int NetcdfFile::NC_openWrite(std::string const& Name) { if (Name.empty()) return 1; if ( checkNCerr( nc_open( Name.c_str(), NC_WRITE, &ncid_ ) ) ) return 1; return 0; }
// Traj_NcEnsemble::readArray() int Traj_NcEnsemble::readArray(int set, FrameArray& f_ensemble) { # ifdef HAS_PNETCDF MPI_Offset pstart_[4]; MPI_Offset pcount_[4]; # define start_ pstart_ # define count_ pcount_ # endif start_[0] = set; // Frame start_[2] = 0; // Atoms start_[3] = 0; // XYZ count_[0] = 1; // Frame count_[1] = 1; // Ensemble count_[3] = 3; // XYZ //rprintf("DEBUG: Reading frame %i\n", set+1); for (int member = ensembleStart_; member != ensembleEnd_; member++) { # ifdef MPI Frame& frm = f_ensemble[0]; # else Frame& frm = f_ensemble[member]; # endif start_[1] = member; // Ensemble count_[2] = Ncatom(); // Atoms // Read Coords # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_float_all(ncid_, coordVID_, start_, count_, Coord_))) # else if (checkNCerr(nc_get_vara_float(ncid_, coordVID_, start_, count_, Coord_))) # endif { rprinterr("Error: Getting coordinates for frame %i\n", set+1); return 1; } FloatToDouble(frm.xAddress(), Coord_); //mprintf("Frm=%8i Rep=%8i ", set+1, member+1); // DEBUG //frm.printAtomCoord(0); // DEBUG // Read Velocities if (velocityVID_ != -1) { # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_float_all(ncid_, velocityVID_, start_, count_, Coord_))) # else if (checkNCerr(nc_get_vara_float(ncid_, velocityVID_, start_, count_, Coord_))) # endif { rprinterr("Error: Getting velocities for frame %i\n", set+1); return 1; } FloatToDouble(frm.vAddress(), Coord_); } // Read Box if (cellLengthVID_ != -1) { count_[2] = 3; # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_double_all(ncid_, cellLengthVID_, start_, count_, frm.bAddress()))) # else if (checkNCerr(nc_get_vara_double(ncid_, cellLengthVID_, start_, count_, frm.bAddress()))) # endif { rprinterr("Error: Getting cell lengths for frame %i.\n", set+1); return 1; } # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_double_all(ncid_, cellAngleVID_, start_, count_, frm.bAddress()+3))) # else if (checkNCerr(nc_get_vara_double(ncid_, cellAngleVID_, start_, count_, frm.bAddress()+3))) # endif { rprinterr("Error: Getting cell angles for frame %i.\n", set+1); return 1; } } // Read Temperature if (TempVID_!=-1) { # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_double_all(ncid_, TempVID_, start_, count_, frm.tAddress()))) # else if (checkNCerr(nc_get_vara_double(ncid_, TempVID_, start_, count_, frm.tAddress()))) # endif { rprinterr("Error: Getting replica temperature for frame %i.\n", set+1); return 1; } //fprintf(stderr,"DEBUG: Replica Temperature %lf\n",F->T); } // Read indices if (indicesVID_!=-1) { count_[2] = remd_dimension_; # ifdef HAS_PNETCDF if (checkPNCerr(ncmpi_get_vara_int_all(ncid_, indicesVID_, start_, count_, frm.iAddress()))) # else if (checkNCerr(nc_get_vara_int(ncid_, indicesVID_, start_, count_, frm.iAddress()))) # endif { rprinterr("Error: Getting replica indices for frame %i.\n", set+1); return 1; } // DEBUG //char buffer[128]; //char* ptr = buffer; //ptr += sprintf(buffer,"DEBUG:\tReplica indices:"); //for (int dim=0; dim < remd_dimension_; dim++) ptr += sprintf(ptr, " %i", frm.RemdIndices()[dim]); //sprintf(ptr,"\n"); //rprintf("%s", buffer); } } # ifdef HAS_PNETCDF // DEBUG # undef start_ # undef count_ # endif return 0; }
// Traj_NcEnsemble::writeArray() int Traj_NcEnsemble::writeArray(int set, FramePtrArray const& Farray) { # ifdef HAS_PNETCDF MPI_Offset pstart_[4]; MPI_Offset pcount_[4]; # define start_ pstart_ # define count_ pcount_ # endif start_[0] = ncframe_; // Frame start_[2] = 0; // Atoms start_[3] = 0; // XYZ count_[0] = 1; // Frame count_[1] = 1; // Ensemble count_[3] = 3; // XYZ for (int member = ensembleStart_; member != ensembleEnd_; member++) { //rprintf("DEBUG: Writing set %i, member %i\n", set+1, member); # ifdef MPI Frame* frm = Farray[0]; # else Frame* frm = Farray[member]; # endif start_[1] = member; // Ensemble count_[2] = Ncatom(); // Atoms // Write Coords //WriteIndices(); // DEBUG DoubleToFloat(Coord_, frm->xAddress()); # ifdef HAS_PNETCDF if (ncmpi_put_vara_float_all(ncid_, coordVID_, start_, count_, Coord_)) # else if (checkNCerr(nc_put_vara_float(ncid_, coordVID_, start_, count_, Coord_))) # endif { mprinterr("Error: Netcdf Writing coords frame %i\n", set+1); return 1; } // Write velocity. if (CoordInfo().HasVel() && frm->HasVelocity()) { // TODO: Determine V beforehand DoubleToFloat(Coord_, frm->vAddress()); # ifdef HAS_PNETCDF if (ncmpi_put_vara_float_all(ncid_, velocityVID_, start_, count_, Coord_)) # else if (checkNCerr(nc_put_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) # endif { mprinterr("Error: Netcdf writing velocity frame %i\n", set+1); return 1; } } // Write box if (cellLengthVID_ != -1) { count_[2] = 3; # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,cellLengthVID_,start_,count_,frm->bAddress())) # else if (checkNCerr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,frm->bAddress())) ) # endif { mprinterr("Error: Writing cell lengths frame %i.\n", set+1); return 1; } # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,cellAngleVID_,start_,count_,frm->bAddress()+3)) # else if (checkNCerr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_,frm->bAddress()+3))) # endif { mprinterr("Error: Writing cell angles frame %i.\n", set+1); return 1; } } // Write temperature if (TempVID_!=-1) { # ifdef HAS_PNETCDF if (ncmpi_put_vara_double_all(ncid_,TempVID_,start_,count_,frm->tAddress())) # else if (checkNCerr(nc_put_vara_double(ncid_,TempVID_,start_,count_,frm->tAddress()))) # endif { mprinterr("Error: Writing temperature frame %i.\n", set+1); return 1; } } // Write indices if (indicesVID_ != -1) { count_[2] = remd_dimension_; # ifdef HAS_PNETCDF if (ncmpi_put_vara_int_all(ncid_,indicesVID_,start_,count_,frm->iAddress())) # else if (checkNCerr(nc_put_vara_int(ncid_,indicesVID_,start_,count_,frm->iAddress()))) # endif { mprinterr("Error: Writing indices frame %i.\n", set+1); return 1; } } } # ifdef HAS_PNETCDF //ncmpi_sync(ncid_); # else nc_sync(ncid_); // Necessary after every write?? # endif ++ncframe_; # ifdef HAS_PNETCDF // DEBUG # undef start_ # undef count_ # endif return 0; }
/** Get the specified frame from amber netcdf file * Coords are a 1 dimensional array of format X1,Y1,Z1,X2,Y2,Z2,... */ int Traj_AmberNetcdf::readFrame(int set, Frame& frameIn) { start_[0] = set; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; // Get temperature if (TempVID_!=-1) { if ( checkNCerr(nc_get_vara_double(ncid_, TempVID_, start_, count_, frameIn.tAddress())) ) { mprinterr("Error: Getting replica temperature for frame %i.\n", set+1); return 1; } //fprintf(stderr,"DEBUG: Replica Temperature %lf\n",F->T); } // Get time if (timeVID_!=-1) { float time; if (checkNCerr(nc_get_vara_float(ncid_, timeVID_, start_, count_, &time))) { mprinterr("Error: Getting time for frame %i.\n", set + 1); return 1; } frameIn.SetTime( (double)time ); } // Read Coords if ( checkNCerr(nc_get_vara_float(ncid_, coordVID_, start_, count_, Coord_)) ) { mprinterr("Error: Getting coordinates for frame %i\n", set+1); return 1; } FloatToDouble(frameIn.xAddress(), Coord_); // Read Velocities if (velocityVID_ != -1) { if ( checkNCerr(nc_get_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) { mprinterr("Error: Getting velocities for frame %i\n", set+1); return 1; } FloatToDouble(frameIn.vAddress(), Coord_); } // Read indices. Input array must be allocated to be size remd_dimension. if (indicesVID_!=-1) { count_[1] = remd_dimension_; if ( checkNCerr(nc_get_vara_int(ncid_, indicesVID_, start_, count_, frameIn.iAddress())) ) { mprinterr("Error: Getting replica indices for frame %i.\n", set+1); return 1; } //mprintf("DEBUG:\tReplica indices:"); //for (int dim=0; dim < remd_dimension_; dim++) mprintf(" %i",remd_indices[dim]); //mprintf("\n"); } // Read box info if (cellLengthVID_ != -1) { count_[1] = 3; count_[2] = 0; if (checkNCerr(nc_get_vara_double(ncid_, cellLengthVID_, start_, count_, frameIn.bAddress()))) { mprinterr("Error: Getting cell lengths for frame %i.\n", set+1); return 1; } if (checkNCerr(nc_get_vara_double(ncid_, cellAngleVID_, start_, count_, frameIn.bAddress()+3))) { mprinterr("Error: Getting cell angles for frame %i.\n", set+1); return 1; } } return 0; }
/** Setup ncatom, ncatom3, atomDID, coordVID, spatialDID, spatialVID, * velocityVID, frcVID. Check units and spatial dimensions. */ int NetcdfFile::SetupCoordsVelo(bool useVelAsCoords) { int spatial; atomDID_ = GetDimInfo(NCATOM, &ncatom_); if (atomDID_==-1) return 1; ncatom3_ = ncatom_ * 3; // Get coord info coordVID_ = -1; if ( nc_inq_varid(ncid_, NCCOORDS, &coordVID_) == NC_NOERR ) { if (ncdebug_ > 0) mprintf("\tNetcdf file has coordinates.\n"); std::string attrText = GetAttrText(coordVID_, "units"); if (attrText!="angstrom") mprintf("Warning: Netcdf file has length units of %s - expected angstrom.\n", attrText.c_str()); } // Get spatial info spatialDID_ = GetDimInfo(NCSPATIAL, &spatial); if (spatialDID_==-1) return 1; if (spatial!=3) { mprinterr("Error: Expected 3 spatial dimensions, got %i\n",spatial); return 1; } if ( checkNCerr(nc_inq_varid(ncid_, NCSPATIAL, &spatialVID_)) ) { mprintf("Warning: Could not get spatial VID. File may not be Amber NetCDF compliant.\n"); mprintf("Warning: Assuming spatial variables are 'x', 'y', 'z'\n"); } else { start_[0] = 0; count_[0] = 3; char xyz[3]; if (checkNCerr(nc_get_vara_text(ncid_, spatialVID_, start_, count_, xyz))) { mprinterr("Error: Getting spatial variables.\n"); return 1; } if (xyz[0] != 'x' || xyz[1] != 'y' || xyz[2] != 'z') { mprinterr("Error: NetCDF spatial variables are '%c', '%c', '%c', not 'x', 'y', 'z'\n", xyz[0], xyz[1], xyz[2]); return 1; } } // Get velocity info velocityVID_ = -1; if ( nc_inq_varid(ncid_, NCVELO, &velocityVID_) == NC_NOERR ) { if (ncdebug_>0) mprintf("\tNetcdf file has velocities.\n"); } // Return a error if no coords and no velocity if ( coordVID_ == -1 && velocityVID_ == -1 ) { mprinterr("Error: NetCDF file has no coords and no velocities.\n"); return 1; } // If using velocities as coordinates, swap them now. if (useVelAsCoords) { if (velocityVID_ == -1) { mprinterr("Error: Cannot use velocities as coordinates; no velocities present.\n"); return 1; } mprintf("\tUsing velocities as coordinates.\n"); coordVID_ = velocityVID_; velocityVID_ = -1; } // Get force info frcVID_ = -1; if ( nc_inq_varid(ncid_, NCFRC, &frcVID_) == NC_NOERR ) { if (ncdebug_>0) mprintf("\tNetcdf file has forces.\n"); } // Get overall replica and coordinate indices crdidxVID_ = -1; if ( nc_inq_varid(ncid_, NCREMD_REPIDX, &repidxVID_) == NC_NOERR ) { //if (ncdebug_ > 0) mprintf(" Netcdf file has overall replica indices.\n"); if ( checkNCerr(nc_inq_varid(ncid_, NCREMD_CRDIDX, &crdidxVID_)) ) { mprinterr("Error: Getting overall coordinate index variable ID.\n"); return 1; } } else repidxVID_ = -1; return 0; }
// Traj_AmberNetcdf::writeFrame() int Traj_AmberNetcdf::writeFrame(int set, Frame const& frameOut) { DoubleToFloat(Coord_, frameOut.xAddress()); // Write coords start_[0] = ncframe_; start_[1] = 0; start_[2] = 0; count_[0] = 1; count_[1] = Ncatom(); count_[2] = 3; if (checkNCerr(nc_put_vara_float(ncid_,coordVID_,start_,count_,Coord_)) ) { mprinterr("Error: Netcdf Writing coords frame %i\n", set+1); return 1; } // Write velocity. FIXME: Should check in setup if (CoordInfo().HasVel() && frameOut.HasVelocity()) { DoubleToFloat(Coord_, frameOut.vAddress()); if (checkNCerr(nc_put_vara_float(ncid_, velocityVID_, start_, count_, Coord_)) ) { mprinterr("Error: Netcdf writing velocity frame %i\n", set+1); return 1; } } // Write box if (cellLengthVID_ != -1) { count_[1] = 3; count_[2] = 0; if (checkNCerr(nc_put_vara_double(ncid_,cellLengthVID_,start_,count_,frameOut.bAddress())) ) { mprinterr("Error: Writing cell lengths frame %i.\n", set+1); return 1; } if (checkNCerr(nc_put_vara_double(ncid_,cellAngleVID_,start_,count_, frameOut.bAddress()+3)) ) { mprinterr("Error: Writing cell angles frame %i.\n", set+1); return 1; } } // Write temperature if (TempVID_!=-1) { if ( checkNCerr( nc_put_vara_double(ncid_,TempVID_,start_,count_,frameOut.tAddress())) ) { mprinterr("Error: Writing temperature frame %i.\n", set+1); return 1; } } // Write time if (timeVID_ != -1) { float tVal = (float)frameOut.Time(); if ( checkNCerr( nc_put_vara_float(ncid_,timeVID_,start_,count_,&tVal)) ) { mprinterr("Error: Writing time frame %i.\n", set+1); return 1; } } // Write indices if (indicesVID_ != -1) { count_[1] = remd_dimension_; if ( checkNCerr(nc_put_vara_int(ncid_,indicesVID_,start_,count_,frameOut.iAddress())) ) { mprinterr("Error: Writing indices frame %i.\n", set+1); return 1; } } nc_sync(ncid_); // Necessary after every write?? ++ncframe_; return 0; }