Exemple #1
0
/** Loop over all filenames in replica_filenames, set up TrajectoryIO. */
int TrajIOarray::SetupIOarray(ArgList& argIn, TrajFrameCounter& counter,
                              CoordinateInfo& cInfo, Topology* trajParm)
{
  // Sanity check
  if (!IOarray_.empty()) {
    mprinterr("Internal Error: SetupIOarray() has been called twice.\n");
    return 1;
  }
  // Save arguments that have not been processed so they can be passed
  // to each replica in turn. Only the lowest replica will use argIn.
  ArgList argCopy( argIn );
  bool lowestRep = true;
  int rep0Frames = TrajectoryIO::TRAJIN_UNK;  // Total frames in replica 0
  int totalFrames = TrajectoryIO::TRAJIN_UNK; // Total # frames to be read from ensemble
  TrajectoryFile::TrajFormatType lastRepFmt = TrajectoryFile::UNKNOWN_TRAJ;
  // Right now enforce that all replicas have the same metadata as lowest
  // replica, e.g. if replica 0 has temperature, replica 1 does too etc.
  for (File::NameArray::const_iterator repfile = replica_filenames_.begin();
                                       repfile != replica_filenames_.end(); ++repfile)
  {
    // Detect format
    TrajectoryFile::TrajFormatType repformat = TrajectoryFile::UNKNOWN_TRAJ;
    TrajectoryIO* replica0 = TrajectoryFile::DetectFormat( *repfile, repformat );
    if ( replica0 == 0 ) {
      mprinterr("Error: Could not set up replica file %s\n", repfile->full());
      return 1;
    }
    if (repformat != lastRepFmt)
      mprintf("\tReading '%s' as %s\n", repfile->full(), TrajectoryFile::FormatString(repformat));
    lastRepFmt = repformat;
    replica0->SetDebug( debug_ );
    // Pushing replica0 here allows the destructor to handle it on errors
    IOarray_.push_back( replica0 );
    // Process format-specific read args. Do not exit on error in case
    // replicas have different formats supporting different args.
    if (lowestRep) {
      replica0->processReadArgs( argIn );
    } else {
      ArgList argtmp( argCopy );
      replica0->processReadArgs( argtmp );
    }
    // Set up replica for reading and get the number of frames.
    int nframes = replica0->setupTrajin( *repfile, trajParm );
    if (nframes == TrajectoryIO::TRAJIN_ERR) {
      mprinterr("Error: Could not set up %s for reading.\n", repfile->full());
      return 1;
    }
    // TODO: Do not allow unknown number of frames?
    if (lowestRep) {
      cInfo = replica0->CoordInfo();
      rep0Frames = nframes;
      totalFrames = nframes;
      if (cInfo.ReplicaDimensions().Ndims() > 0) {
        mprintf("\tReplica dimensions:\n");
        for (int rd = 0; rd < cInfo.ReplicaDimensions().Ndims(); rd++)
          mprintf("\t\t%i: %s\n", rd+1, cInfo.ReplicaDimensions().Description(rd));
      }
    } else {
      // Check total frames in this replica against lowest rep.
      if (nframes != rep0Frames)
        mprintf("Warning: Replica %s frames (%i) does not match # frames in first replica (%i).\n",
                repfile->base(), nframes, rep0Frames);
      //if (repframes < 0) {
      //  mprinterr("Error: RemdTraj: Unknown # of frames in replica.\n");
      //  return 1;
      //}
      if (nframes < totalFrames) {
        totalFrames = nframes; 
        mprintf("Warning: Setting total # of frames to read from replica ensemble to %i\n",
                totalFrames);
      }
      // Check box info against lowest rep.
      if ( replica0->CoordInfo().HasBox() != cInfo.HasBox() ) {
        mprinterr("Error: Replica %s box info does not match first replica.\n",
                  repfile->full());
        return 1;
      }
      // TODO: Check specific box type
      // Check velocity info against lowest rep.
      if ( replica0->CoordInfo().HasVel() != cInfo.HasVel() ) {
        mprinterr("Error: Replica %s velocity info does not match first replica.\n",
                  repfile->full());
        return 1;
      }
      // Check # dimensions and types against lowest rep
      if ( replica0->CoordInfo().ReplicaDimensions() != cInfo.ReplicaDimensions() ) {
        mprinterr("Error: Replica %s dimension info does not match first replica.\n",
                  repfile->full());
        ReplicaDimArray const& thisRepDims = replica0->CoordInfo().ReplicaDimensions();
        for (int rd = 0; rd < thisRepDims.Ndims(); rd++)
          mprinterr("\t\t%i: %s\n", rd+1, thisRepDims.Description(rd)); 
        return 1;
      }
      // If temperature/time info does not match set to false.
      if (cInfo.HasTemp() != replica0->CoordInfo().HasTemp())
        cInfo.SetTemperature( false );
      if (cInfo.HasTime() != replica0->CoordInfo().HasTime())
        cInfo.SetTime( false );
    }
    lowestRep = false;
  }
  // Check how many frames will actually be read
  if (counter.CheckFrameArgs( totalFrames, argIn )) return 1;
  // Check for errors.
  if (IOarray_.empty()) {
    mprinterr("Error: No replica trajectories set up.\n");
    return 1;
  }
  if (IOarray_.size() != replica_filenames_.size()) { // SANITY CHECK
    mprinterr("Error: Not all replica files were set up.\n");
    return 1;
  }
  // Update ensemble size
  cInfo.SetEnsembleSize( (int)IOarray_.size() );
  if (debug_ > 0)
    cInfo.PrintCoordInfo( replica_filenames_[0].full(), trajParm->c_str() );

  return 0;
}
Exemple #2
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;
}