Example #1
0
/** Determine what atoms each mask pertains to for the current parm file.
  */
Action::RetType Action_ReplicateCell::Setup(ActionSetup& setup) {
  if (setup.Top().SetupIntegerMask( Mask1_ )) return Action::ERR;
  mprintf("\t%s (%i atoms)\n",Mask1_.MaskString(), Mask1_.Nselected());
  if (Mask1_.None()) {
    mprintf("Warning: One or both masks have no atoms.\n");
    return Action::SKIP;
  }
  // Set up imaging info for this parm
  image_.SetupImaging( setup.CoordInfo().TrajBox().Type() );
  if (!image_.ImagingEnabled()) {
    mprintf("Warning: Imaging cannot be performed for topology %s\n", setup.Top().c_str());
    return Action::SKIP;
  }
  // Create combined topology.
  if (combinedTop_.Natom() > 0) {
    // Topology already set up. Check that # atoms matches.
    if (Mask1_.Nselected() * ncopies_ != combinedTop_.Natom()) {
      mprintf("Warning: Unit cell can currently only be replicated for"
              " topologies with same # atoms.\n");
      return Action::SKIP;
    }
    // Otherwise assume top does not change.
  } else {
    // Set up topology and frame.
    Topology* stripParm = setup.Top().modifyStateByMask( Mask1_ );
    if (stripParm == 0) return Action::ERR;
    for (int cell = 0; cell != ncopies_; cell++)
      combinedTop_.AppendTop( *stripParm );
    combinedTop_.Brief("Combined parm:");
    delete stripParm;
    if (!parmfilename_.empty()) {
      ParmFile pfile;
      if (pfile.WriteTopology(combinedTop_, parmfilename_, ParmFile::UNKNOWN_PARM, 0)) {
        mprinterr("Error: Topology file %s not written.\n", parmfilename_.c_str());
        return Action::ERR;
      }
    }
    // Only coordinates for now. FIXME
    combinedFrame_.SetupFrameM(combinedTop_.Atoms());
    // Set up COORDS / output traj if necessary.
    if (coords_ != 0)
      coords_->CoordsSetup( combinedTop_, CoordinateInfo() );
    if (!trajfilename_.empty()) {
      if ( outtraj_.PrepareEnsembleTrajWrite(trajfilename_, trajArgs_,
                                             &combinedTop_, CoordinateInfo(),
                                             setup.Nframes(), TrajectoryFile::UNKNOWN_TRAJ,
                                             ensembleNum_) )
        return Action::ERR;
    }
  }

  return Action::OK;
}
Example #2
0
/** Write file containing only cut atoms and energies as charges. */
int Action_Pairwise::WriteCutFrame(int frameNum, Topology const& Parm, AtomMask const& CutMask, 
                                   Darray const& CutCharges,
                                   Frame const& frame, std::string const& outfilename) 
{
  if (CutMask.Nselected() != (int)CutCharges.size()) {
    mprinterr("Error: WriteCutFrame: # of charges (%u) != # mask atoms (%i)\n",
              CutCharges.size(), CutMask.Nselected());
    return 1;
  }
  Frame CutFrame(frame, CutMask);
  Topology* CutParm = Parm.modifyStateByMask( CutMask );
  if (CutParm == 0) return 1;
  // Set new charges
  for (int i = 0; i != CutParm->Natom(); i++)
    CutParm->SetAtom(i).SetCharge( CutCharges[i] );
  int err = 0;
  Trajout_Single tout;
  if (tout.PrepareTrajWrite(outfilename, "multi", CutParm, CoordinateInfo(), 1,
                            TrajectoryFile::MOL2FILE))
  {
    mprinterr("Error: Could not set up cut mol2 file %s\n", outfilename.c_str());
    err = 1;
  } else {
    tout.WriteSingle(frameNum, CutFrame);
    tout.EndTraj();
  }
  delete CutParm;
  return err;
}
Example #3
0
/* * 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();
}
Example #4
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;
}
Example #5
0
/** Project average coords along eigenvectors */
int Analysis_Modes::ProjectCoords(DataSet_Modes const& modes) {
  double scale = factor_;
  int max_it = (int)(pcmax_ - pcmin_);
  // Check that size of eigenvectors match # coords
  int ncoord = tOutParm_->Natom() * 3;
  if (ncoord != modes.NavgCrd()) {
    mprinterr("Error: # selected coords (%i) != eigenvector size (%i)\n",
               ncoord, modes.NavgCrd());
    return 1;
  }
  // Check that mode is valid.
  if (tMode_ < 1 || tMode_ > modes.Nmodes() ) {
    mprinterr("Error: mode %i is out of bounds.\n", tMode_);
    return Analysis::ERR;
  }
  // Setup frame to hold output coords, initalized to avg coords.
  Frame outframe;
  outframe.SetupFrameXM( modes.AvgCrd(), modes.Mass() );
  // Point to correct eigenvector
  const double* Vec = modes.Eigenvector(tMode_-1);
  // Initialize coords to pcmin
  for (int idx = 0; idx < ncoord; idx++)
    outframe[idx] += pcmin_ * Vec[idx];
  if (debug_>0) CalculateProjection(0, outframe, tMode_-1);
  if (trajout_.SetupTrajWrite( tOutParm_, CoordinateInfo(), max_it )) {
    mprinterr("Error: Could not open output modes traj '%s'\n", trajout_.Traj().Filename().full());
    return 1;
  }
  // Write first frame with coords at pcmin.
  int set = 0;
  trajout_.WriteSingle(set++, outframe);
  // Main loop
  for (int it = 0; it < max_it; it++) {
    double* crd = outframe.xAddress();
    // Move coordinates along eigenvector.
    for (int idx = 0; idx < ncoord; ++idx)
      crd[idx] += scale * Vec[idx];
    if (debug_>0) CalculateProjection(set, outframe, tMode_-1);
    // DEBUG: calc PC projection for first 3 modes
    //for (int m = 0; m < 3; m++)
    //  CalculateProjection(set, outframe, m);
    // Write frame
    trajout_.WriteSingle(set++, outframe);
  }
  trajout_.EndTraj();
  return 0;
}
Example #6
0
// Analysis_Hist::Analyze()
Analysis::RetType Analysis_Hist::Analyze() {
  // Set up dimensions
  // Size of histdata and dimensionArgs should be the same
  size_t total_bins = 0UL;
  for (unsigned int hd = 0; hd < N_dimensions_; hd++) {
    if ( setupDimension(dimensionArgs_[hd], *(histdata_[hd]), total_bins) ) 
      return Analysis::ERR;
  }
  // dimensionArgs no longer needed
  dimensionArgs_.clear();

  // Check that the number of data points in each dimension are equal
  std::vector<DataSet_1D*>::iterator ds = histdata_.begin();
  size_t Ndata = (*ds)->Size();
  ++ds;
  for (; ds != histdata_.end(); ++ds)
  {
    //mprintf("DEBUG: DS %s size %i\n",histdata[hd]->Name(),histdata[hd]->Xmax()+1);
    if (Ndata != (*ds)->Size()) {
      mprinterr("Error: Hist: Dataset %s has inconsistent # data points (%zu), expected %zu.\n",
                (*ds)->legend(), (*ds)->Size(), Ndata);
      return Analysis::ERR;
    }
  }
  mprintf("\tHist: %zu data points in each dimension.\n", Ndata);
  if (calcAMD_ && Ndata != amddata_->Size()) {
    mprinterr("Error: Hist: AMD data set size (%zu) does not match # expected data points (%zu).\n",
              amddata_->Size(), Ndata);
    return Analysis::ERR;
  }

  // Allocate bins
  mprintf("\tHist: Allocating histogram, total bins = %zu\n", total_bins);
  Bins_.resize( total_bins, 0.0 );

  // Bin data
  for (size_t n = 0; n < Ndata; n++) {
    long int index = 0;
    HdimType::const_iterator dim = dimensions_.begin();
    OffType::const_iterator bOff = binOffsets_.begin();
    for (std::vector<DataSet_1D*>::iterator ds = histdata_.begin();
                                            ds != histdata_.end(); ++ds, ++dim, ++bOff)
    {
      double dval = (*ds)->Dval( n );
      // Check if data is out of bounds for this dimension.
      if (dval > dim->Max() || dval < dim->Min()) {
        index = -1L;
        break;
      }
      // Calculate index for this particular dimension (idx)
      long int idx = (long int)((dval - dim->Min()) / dim->Step());
      if (debug_>1) mprintf(" [%s:%f (%li)],", dim->label(), dval, idx);
      // Calculate overall index in Bins, offset has already been calcd.
      index += (idx * (*bOff));
    }
    // If index was successfully calculated, populate bin
    if (index > -1L && index < (long int)Bins_.size()) {
      if (debug_ > 1) mprintf(" |index=%li",index);
      if (calcAMD_)
        Bins_[index] += exp( amddata_->Dval(n) );
      else
        Bins_[index]++;
    } else {
      mprintf("\tWarning: Frame %zu Coordinates out of bounds (%li)\n", n+1, index);
    }
    if (debug_>1) mprintf("}\n");
  }
  // Calc free energy if requested
  if (calcFreeE_) CalcFreeE();

  // Normalize if requested
  if (normalize_ != NO_NORM) Normalize();

  if (nativeOut_) {
    // Use Histogram built-in output
    PrintBins();
  } else {
    // Using DataFileList framework, set-up labels etc.
    if (N_dimensions_ == 1) {
      DataSet_double& dds = static_cast<DataSet_double&>( *hist_ );
      // Since Allocate1D only reserves data, use assignment op.
      dds = Bins_;
      hist_->SetDim(Dimension::X, dimensions_[0]);
    } else if (N_dimensions_ == 2) {
      DataSet_MatrixDbl& mds = static_cast<DataSet_MatrixDbl&>( *hist_ );
      mds.Allocate2D( dimensions_[0].Bins(), dimensions_[1].Bins() );
      std::copy( Bins_.begin(), Bins_.end(), mds.begin() );
      hist_->SetDim(Dimension::X, dimensions_[0]);
      hist_->SetDim(Dimension::Y, dimensions_[1]);
      outfile_->ProcessArgs("noxcol usemap nolabels");
    } else if (N_dimensions_ == 3) {
      DataSet_GridFlt& gds = static_cast<DataSet_GridFlt&>( *hist_ );
      //gds.Allocate3D( dimensions_[0].Bins(), dimensions_[1].Bins(), dimensions_[2].Bins() );
      gds.Allocate_N_O_D( dimensions_[0].Bins(), dimensions_[1].Bins(), dimensions_[2].Bins(),
                          Vec3(dimensions_[0].Min(), dimensions_[1].Min(), dimensions_[2].Min()),
                          Vec3(dimensions_[0].Step(), dimensions_[1].Step(), dimensions_[2].Step())
                        );
      //std::copy( Bins_.begin(), Bins_.end(), gds.begin() );
      // FIXME: Copy will not work since in grids data is ordered with Z
      // changing fastest. Should the ordering in grid be changed?
      size_t idx = 0;
      for (size_t z = 0; z < gds.NZ(); z++)
        for (size_t y = 0; y < gds.NY(); y++)
          for (size_t x = 0; x < gds.NX(); x++)
            gds.SetElement( x, y, z, (float)Bins_[idx++] );
      hist_->SetDim(Dimension::X, dimensions_[0]);
      hist_->SetDim(Dimension::Y, dimensions_[1]);
      hist_->SetDim(Dimension::Z, dimensions_[2]);
      outfile_->ProcessArgs("noxcol usemap nolabels");
      // Create pseudo-topology/trajectory
      if (!traj3dName_.empty()) {
        Topology pseudo;
        pseudo.AddTopAtom(Atom("H3D", 0), Residue("H3D", 1, ' ', ' '));
        pseudo.CommonSetup();
        if (!parmoutName_.empty()) {
          ParmFile pfile;
          if (pfile.WriteTopology( pseudo, parmoutName_, ParmFile::UNKNOWN_PARM, 0 ))
            mprinterr("Error: Could not write pseudo topology to '%s'\n", parmoutName_.c_str());
        }
        Trajout_Single out;
        if (out.PrepareTrajWrite(traj3dName_, ArgList(), &pseudo, CoordinateInfo(),
                                 Ndata, traj3dFmt_) == 0)
        {
          Frame outFrame(1);
          for (size_t i = 0; i < Ndata; ++i) {
            outFrame.ClearAtoms();
            outFrame.AddVec3( Vec3(histdata_[0]->Dval(i), 
                                   histdata_[1]->Dval(i), 
                                   histdata_[2]->Dval(i)) );
            out.WriteSingle(i, outFrame);
          }
          out.EndTraj();
        } else
          mprinterr("Error: Could not set up '%s' for write.\n", traj3dName_.c_str());
      }
    }
  }

  return Analysis::OK;
}
Example #7
0
int SequenceAlign(CpptrajState& State, ArgList& argIn) {
  std::string blastfile = argIn.GetStringKey("blastfile");
  if (blastfile.empty()) {
    mprinterr("Error: 'blastfile' must be specified.\n");
    return 1;
  }
  ReferenceFrame qref = State.DSL()->GetReferenceFrame(argIn);
  if (qref.error() || qref.empty()) {
    mprinterr("Error: Must specify reference structure for query.\n");
    return 1;
  }
  std::string outfilename = argIn.GetStringKey("out");
  if (outfilename.empty()) {
    mprinterr("Error: Must specify output file.\n");
    return 1;
  }
  TrajectoryFile::TrajFormatType fmt = TrajectoryFile::GetFormatFromArg(argIn);
  if (fmt != TrajectoryFile::PDBFILE && fmt != TrajectoryFile::MOL2FILE)
    fmt = TrajectoryFile::PDBFILE; // Default to PDB
  int smaskoffset = argIn.getKeyInt("smaskoffset", 0) + 1;
  int qmaskoffset = argIn.getKeyInt("qmaskoffset", 0) + 1;

  // Load blast file
  mprintf("\tReading BLAST alignment from '%s'\n", blastfile.c_str());
  BufferedLine infile;
  if (infile.OpenFileRead( blastfile )) return 1;
  // Seek down to first Query line.
  const char* ptr = infile.Line();
  bool atFirstQuery = false;
  while (ptr != 0) {
    if (*ptr == 'Q') {
      if ( strncmp(ptr, "Query", 5) == 0 ) {
        atFirstQuery = true;
        break;
      }
    }
    ptr = infile.Line();
  }
  if (!atFirstQuery) {
    mprinterr("Error: 'Query' not found.\n");
    return 1;
  }

  // Read alignment. Replacing query with subject.
  typedef std::vector<char> Carray;
  typedef std::vector<int> Iarray;
  Carray Query; // Query residues
  Carray Sbjct; // Sbjct residues
  Iarray Smap;  // Smap[Sbjct index] = Query index
  while (ptr != 0) {
    const char* qline = ptr;           // query line
    const char* aline = infile.Line(); // alignment line
    const char* sline = infile.Line(); // subject line
    if (aline == 0 || sline == 0) {
      mprinterr("Error: Missing alignment line or subject line after Query:\n");
      mprinterr("Error:  %s", qline);
      return 1;
    }
    for (int idx = 12; qline[idx] != ' '; idx++) {
      if (qline[idx] == '-') {
        // Sbjct does not have corresponding res in Query
        Smap.push_back(-1);
        Sbjct.push_back( sline[idx] );
      } else if (sline[idx] == '-') {
        // Query does not have a corresponding res in Sbjct
        Query.push_back( qline[idx] );
      } else {
        // Direct Query to Sbjct map
        Smap.push_back( Query.size() );
        Sbjct.push_back( sline[idx] );
        Query.push_back( qline[idx] );
      }
    }
    // Scan to next Query 
    ptr = infile.Line();
    while (ptr != 0) {
      if (*ptr == 'Q') {
        if ( strncmp(ptr, "Query", 5) == 0 ) break;
      }
      ptr = infile.Line();
    }
  }
  // DEBUG
  std::string SmaskExp, QmaskExp;
  if (State.Debug() > 0) mprintf("  Map of Sbjct to Query:\n");
  for (int sres = 0; sres != (int)Sbjct.size(); sres++) {
    if (State.Debug() > 0)
      mprintf("%-i %3s %i", sres+smaskoffset, Residue::ConvertResName(Sbjct[sres]),
              Smap[sres]+qmaskoffset);
    const char* qres = "";
    if (Smap[sres] != -1) {
      qres = Residue::ConvertResName(Query[Smap[sres]]);
      if (SmaskExp.empty())
        SmaskExp.assign( integerToString(sres+smaskoffset) );
      else
        SmaskExp.append( "," + integerToString(sres+smaskoffset) );
      if (QmaskExp.empty())
        QmaskExp.assign( integerToString(Smap[sres]+qmaskoffset) );
      else
        QmaskExp.append( "," + integerToString(Smap[sres]+qmaskoffset) );

    }
    if (State.Debug() > 0) mprintf(" %3s\n", qres);
  }
  mprintf("Smask: %s\n", SmaskExp.c_str());
  mprintf("Qmask: %s\n", QmaskExp.c_str());
  // Check that query residues match reference.
  for (unsigned int sres = 0; sres != Sbjct.size(); sres++) {
    int qres = Smap[sres];
    if (qres != -1) {
      if (Query[qres] != qref.Parm().Res(qres).SingleCharName()) {
        mprintf("Warning: Potential residue mismatch: Query %s reference %s\n",
                Residue::ConvertResName(Query[qres]), qref.Parm().Res(qres).c_str());
      }
    }
  }
  // Build subject using coordinate from reference.
  //AtomMask sMask; // Contain atoms that should be in sTop
  Topology sTop;
  Frame sFrame;
  Iarray placeHolder; // Atom indices of placeholder residues.
  for (unsigned int sres = 0; sres != Sbjct.size(); sres++) {
    int qres = Smap[sres];
    NameType SresName( Residue::ConvertResName(Sbjct[sres]) );
    if (qres != -1) {
      Residue const& QR = qref.Parm().Res(qres);
      Residue SR(SresName, sres+1, ' ', QR.ChainID());
      if (Query[qres] == Sbjct[sres]) { // Exact match. All non-H atoms.
        for (int qat = QR.FirstAtom(); qat != QR.LastAtom(); qat++)
        {
          if (qref.Parm()[qat].Element() != Atom::HYDROGEN)
            sTop.AddTopAtom( qref.Parm()[qat], SR );
            sFrame.AddXYZ( qref.Coord().XYZ(qat) );
            //sMask.AddAtom(qat);
        }
      } else { // Partial match. Copy only backbone and CB.
        for (int qat = QR.FirstAtom(); qat != QR.LastAtom(); qat++)
        {
          if ( qref.Parm()[qat].Name().Match("N" ) ||
               qref.Parm()[qat].Name().Match("CA") ||
               qref.Parm()[qat].Name().Match("CB") ||
               qref.Parm()[qat].Name().Match("C" ) ||
               qref.Parm()[qat].Name().Match("O" ) )
          {
            sTop.AddTopAtom( qref.Parm()[qat], SR );
            sFrame.AddXYZ( qref.Coord().XYZ(qat) );
          }
        }
      }
    } else {
      // Residue in query does not exist for subject. Just put placeholder CA for now.
      Vec3 Zero(0.0);
      placeHolder.push_back( sTop.Natom() );
      sTop.AddTopAtom( Atom("CA", "C "), Residue(SresName, sres+1, ' ', ' ') );
      sFrame.AddXYZ( Zero.Dptr() );
    }
  }
  //sTop.PrintAtomInfo("*");
  mprintf("\tPlaceholder residue indices:");
  for (Iarray::const_iterator p = placeHolder.begin(); p != placeHolder.end(); ++p)
    mprintf(" %i", *p + 1);
  mprintf("\n");
  // Try to give placeholders more reasonable coordinates.
  if (!placeHolder.empty()) {
    Iarray current_indices;
    unsigned int pidx = 0;
    while (pidx < placeHolder.size()) {
      if (current_indices.empty()) {
        current_indices.push_back( placeHolder[pidx++] );
        // Search for the end of this segment
        for (; pidx != placeHolder.size(); pidx++) {
          if (placeHolder[pidx] - current_indices.back() > 1) break;
          current_indices.push_back( placeHolder[pidx] );
        }
        // DEBUG
        mprintf("\tSegment:");
        for (Iarray::const_iterator it = current_indices.begin();
                                    it != current_indices.end(); ++it)
          mprintf(" %i", *it + 1);
        // Get coordinates of residues bordering segment.
        int prev_res = sTop[current_indices.front()].ResNum() - 1;
        int next_res = sTop[current_indices.back() ].ResNum() + 1;
        mprintf(" (prev_res=%i, next_res=%i)\n", prev_res+1, next_res+1);
        Vec3 prev_crd(sFrame.XYZ(current_indices.front() - 1));
        Vec3 next_crd(sFrame.XYZ(current_indices.back()  + 1));
        prev_crd.Print("prev_crd");
        next_crd.Print("next_crd");
        Vec3 crd_step = (next_crd - prev_crd) / (double)(current_indices.size()+1);
        crd_step.Print("crd_step");
        double* xyz = sFrame.xAddress() + (current_indices.front() * 3);
        for (unsigned int i = 0; i != current_indices.size(); i++, xyz += 3) {
          prev_crd += crd_step;
          xyz[0] = prev_crd[0];
          xyz[1] = prev_crd[1];
          xyz[2] = prev_crd[2];
        }
        current_indices.clear();
      }
    }
  }
  //Topology* sTop = qref.Parm().partialModifyStateByMask( sMask );
  //if (sTop == 0) return 1;
  //Frame sFrame(qref.Coord(), sMask);
  // Write output traj
  Trajout_Single trajout;
  if (trajout.PrepareTrajWrite(outfilename, argIn, &sTop, CoordinateInfo(), 1, fmt)) return 1;
  if (trajout.WriteSingle(0, sFrame)) return 1;
  trajout.EndTraj();
  return 0;
}
// Exec_PermuteDihedrals::RandomizeAngles()
void Exec_PermuteDihedrals::RandomizeAngles(Frame& currentFrame, Topology const& topIn) {
  Matrix_3x3 rotationMatrix;
# ifdef DEBUG_PERMUTEDIHEDRALS
  // DEBUG
  int debugframenum=0;
  Trajout_Single DebugTraj;
  DebugTraj.PrepareTrajWrite("debugtraj.nc",ArgList(),(Topology*)&topIn,
                             CoordinateInfo(), BB_dihedrals_.size()*max_factor_,
                             TrajectoryFile::AMBERNETCDF);
  DebugTraj.WriteSingle(debugframenum++,currentFrame);
# endif
  int next_resnum;
  int bestLoop = 0;
  int number_of_rotations = 0;
  // Set max number of rotations to try.
  int max_rotations = (int)BB_dihedrals_.size();
  max_rotations *= max_factor_;

  // Loop over all dihedrals
  std::vector<PermuteDihedralsType>::const_iterator next_dih = BB_dihedrals_.begin();
  next_dih++;
  for (std::vector<PermuteDihedralsType>::const_iterator dih = BB_dihedrals_.begin();
                                                     dih != BB_dihedrals_.end(); 
                                                     ++dih, ++next_dih)
  {
    ++number_of_rotations;
    // Get the residue atom of the next dihedral. Residues up to and
    // including this residue will be checked for bad clashes 
    if (next_dih != BB_dihedrals_.end()) 
      next_resnum = next_dih->resnum;
    else
      next_resnum = dih->resnum - 1;
    // Set axis of rotation
    Vec3 axisOfRotation = currentFrame.SetAxisOfRotation(dih->atom1, dih->atom2);
    // Generate random value to rotate by in radians
    // Guaranteed to rotate by at least 1 degree.
    // NOTE: could potentially rotate 360 - prevent?
    // FIXME: Just use 2PI and rn_gen, get everything in radians
    double theta_in_degrees = ((int)(RN_.rn_gen()*100000) % 360) + 1;
    double theta_in_radians = theta_in_degrees * Constants::DEGRAD;
    // Calculate rotation matrix for random theta
    rotationMatrix.CalcRotationMatrix(axisOfRotation, theta_in_radians);
    int loop_count = 0;
    double clash = 0;
    double bestClash = 0;
    if (debug_>0) mprintf("DEBUG: Rotating dihedral %zu res %8i:\n", dih - BB_dihedrals_.begin(),
                          dih->resnum+1);
    bool rotate_dihedral = true;
    while (rotate_dihedral) {
      if (debug_>0) {
        mprintf("\t%8i %12s %12s, +%.2lf degrees (%i).\n",dih->resnum+1,
                topIn.AtomMaskName(dih->atom1).c_str(),
                topIn.AtomMaskName(dih->atom2).c_str(),
                theta_in_degrees,loop_count);
      }
      // Rotate around axis
      currentFrame.Rotate(rotationMatrix, dih->Rmask);
#     ifdef DEBUG_PERMUTEDIHEDRALS
      // DEBUG
      DebugTraj.WriteSingle(debugframenum++,currentFrame);
#     endif
      // If we dont care about sterics exit here
      if (!check_for_clashes_) break;
      // Check resulting structure for issues
      int checkresidue;
      if (!checkAllResidues_)
        checkresidue = CheckResidue(currentFrame, topIn, *dih, next_resnum, clash);
      else
        checkresidue = CheckResidue(currentFrame, topIn, *dih, topIn.Nres(), clash);
      if (checkresidue==0)
        rotate_dihedral = false;
      else if (checkresidue==-1) {
        if (dih - BB_dihedrals_.begin() < 2) {
          mprinterr("Error: Cannot backtrack; initial structure already has clashes.\n");
          number_of_rotations = max_rotations + 1;
        } else {
          dih--; //  0
          dih--; // -1
          next_dih = dih;
          next_dih++;
          if (debug_>0)
            mprintf("\tCannot resolve clash with further rotations, trying previous again.\n");
        }
        break;
      }
      if (clash > bestClash) {bestClash = clash; bestLoop = loop_count;}
      //n_problems = CheckResidues( currentFrame, second_atom );
      //if (n_problems > -1) {
      //  mprintf("%i\tCheckResidues: %i problems.\n",frameNum,n_problems);
      //  rotate_dihedral = false;
      //} else if (loop_count==0) {
      if (loop_count==0 && rotate_dihedral) {
        if (debug_>0)
          mprintf("\tTrying dihedral increments of +%i\n",increment_);
        // Instead of a new random dihedral, try increments
        theta_in_degrees = (double)increment_;
        theta_in_radians = theta_in_degrees * Constants::DEGRAD;
        // Calculate rotation matrix for new theta
        rotationMatrix.CalcRotationMatrix(axisOfRotation, theta_in_radians);
      }
      ++loop_count;
      if (loop_count == max_increment_) {
        if (debug_>0)
          mprintf("%i iterations! Best clash= %.3lf at %i\n",max_increment_,
                  sqrt(bestClash),bestLoop);
        if (dih - BB_dihedrals_.begin() < backtrack_) {
          mprinterr("Error: Cannot backtrack; initial structure already has clashes.\n");
          number_of_rotations = max_rotations + 1;
        } else { 
          for (int bt = 0; bt < backtrack_; bt++)
            dih--;
          next_dih = dih;
          next_dih++;
          if (debug_>0)
            mprintf("\tCannot resolve clash with further rotations, trying previous %i again.\n",
                    backtrack_ - 1);
        }
        break;
        // Calculate how much to rotate back in order to get to best clash
        /*int num_back = bestLoop - 359;
        theta_in_degrees = (double) num_back;
        theta_in_radians = theta_in_degrees * Constants::DEGRAD;
        // Calculate rotation matrix for theta
        calcRotationMatrix(rotationMatrix, axisOfRotation, theta_in_radians);
        // Rotate back to best clash
        frm.Frm().RotateAroundAxis(rotationMatrix, theta_in_radians, dih->Rmask);
        // DEBUG
        DebugTraj.WriteFrame(debugframenum++,currentParm,*currentFrame);
        // Sanity check
        CheckResidue(currentFrame, *dih, second_atom, &clash);
        rotate_dihedral=false;*/
        //DebugTraj.EndTraj();
        //return 1;
      }
    } // End dihedral rotation loop
    // Safety valve - number of defined dihedrals times * maxfactor
    if (number_of_rotations > max_rotations) {
      mprinterr("Error: # of rotations (%i) exceeds max rotations (%i), exiting.\n",
                number_of_rotations, max_rotations);
//#     ifdef DEBUG_PERMUTEDIHEDRALS
//      DebugTraj.EndTraj();
//#     endif
      // Return gracefully for now
      break;
      //return 1;
    }
  } // End loop over dihedrals
# ifdef DEBUG_PERMUTEDIHEDRALS
  DebugTraj.EndTraj();
  mprintf("\tNumber of rotations %i, expected %u\n",number_of_rotations,BB_dihedrals_.size());
# endif
}
Example #9
0
// Action_LESsplit::Setup()
Action::RetType Action_LESsplit::Setup(ActionSetup& setup) {
  if ( !setup.Top().LES().HasLES() ) {
    mprintf("Warning: No LES parameters in '%s', skipping.\n", setup.Top().c_str());
    return Action::SKIP;
  }
  if (lesParm_ == 0) { // First time setup
    // Set up masks for all copies
    lesMasks_.clear();
    lesMasks_.resize( setup.Top().LES().Ncopies() );
    unsigned int atom = 0;
    for (LES_Array::const_iterator les = setup.Top().LES().Array().begin();
                                   les != setup.Top().LES().Array().end(); ++les, ++atom)
    {
      // Copy 0 is in all copies
      if ( les->Copy() == 0 ) {
        for (MaskArray::iterator mask = lesMasks_.begin(); mask != lesMasks_.end(); ++mask)
          mask->AddAtom( atom );
      } else
        lesMasks_[ les->Copy() - 1 ].AddAtom( atom );
    }
    for (unsigned int i = 0; i < lesMasks_.size(); i++) {
      mprintf("\t%i atoms in LES copy %u\n", lesMasks_[i].Nselected(), i+1);
      if ( lesMasks_[i].Nselected() != lesMasks_[0].Nselected() ) {
        mprinterr("Error: Currently all LES copies MUST have same # atoms.\n");
        return Action::ERR;
      }
    }
    // Create topology for first copy
    lesParm_ = setup.Top().modifyStateByMask( lesMasks_[0] );
    if (lesParm_ == 0) return Action::ERR;
    // Set up frames to hold individual copies
    lesFrames_.resize( lesMasks_.size() );
    lesFrames_.SetupFrames(lesParm_->Atoms(), setup.CoordInfo());
    lesPtrs_.resize( lesMasks_.size() );
    for (unsigned int i = 0; i != lesMasks_.size(); i++)
      lesPtrs_[i] = &lesFrames_[i];
    if (lesSplit_) {
      // Set up output ensemble FIXME check overwrites TODO combine init/setup?
      if (lesTraj_.InitEnsembleWrite(trajfilename_, trajArgs_, lesMasks_.size(),
                                     TrajectoryFile::UNKNOWN_TRAJ))
        return Action::ERR;
      if (lesTraj_.SetupEnsembleWrite(lesParm_, setup.CoordInfo(), setup.Nframes()))
         return Action::ERR;
      lesTraj_.PrintInfo(0);
    }
    if (lesAverage_) {
      // For average only care about coords.
      avgFrame_.SetupFrame( lesParm_->Natom() );
      if (avgTraj_.PrepareTrajWrite( avgfilename_, trajArgs_, lesParm_,
                                     CoordinateInfo(), setup.Nframes(),
                                     TrajectoryFile::UNKNOWN_TRAJ ))
        return Action::ERR;
      avgTraj_.PrintInfo(0);
    }
  } else {
    if (lesParm_->Pindex() != setup.Top().Pindex()) {
      mprintf("Warning: Already set up for LES parm '%s'. Skipping '%s'\n",
              lesParm_->c_str(), setup.Top().c_str());
      return Action::SKIP;
    }
  }

  return Action::OK;
}
Example #10
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;
}
Example #11
0
// 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();
}
Example #12
0
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;
}
Example #13
0
// 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;
}