/** 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; }
/** 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; }
/* * 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(); }
/** 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; }
/** 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; }
// 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; }
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 }
// 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; }
/** Set up and read Amber restart file. Coordinate/velocities will be saved * here to avoid having to open the file again. Check that number of atoms * matches number of atoms in associated parmtop. Check for box/velocity info. */ int Traj_AmberRestart::setupTrajin(FileName const& fname, Topology* trajParm) { BufferedFrame infile; if (infile.SetupRead( fname, debug_ )) return TRAJIN_ERR; if (infile.OpenFile()) return TRAJIN_ERR; readAccess_ = true; // Read in title std::string title = infile.GetLine(); SetTitle( NoTrailingWhitespace(title) ); // Read in natoms, time, and Replica Temp if present std::string nextLine = infile.GetLine(); if (nextLine.empty()) { mprinterr("Error: Could not read restart atoms/time.\n"); return TRAJIN_ERR; } int restartAtoms = 0; bool hasTemp = false; bool hasTime = false; int nread = sscanf(nextLine.c_str(),"%i %lE %lE",&restartAtoms,&restartTime_,&restartTemp_); if (nread < 1) { mprinterr("Error: Unable to read restart atoms/time.\n"); return TRAJIN_ERR; } else if (nread == 1) { // # atoms only restartTime_ = 0.0; restartTemp_ = -1.0; } else if (nread == 2) { // # atoms and time hasTime = true; restartTemp_ = -1.0; } else { // # atoms, time, and temperature hasTime = true; hasTemp = true; } if (debug_ > 0) mprintf("\tAmber restart: Atoms=%i Time=%lf Temp=%lf\n",restartAtoms, restartTime_, restartTemp_); // Check that natoms matches parm natoms if (restartAtoms != trajParm->Natom()) { mprinterr("Error: Number of atoms in Amber Restart %s (%i) does not\n", infile.Filename().base(), restartAtoms); mprinterr(" match number in associated parmtop (%i)\n",trajParm->Natom()); return TRAJIN_ERR; } natom3_ = restartAtoms * 3; // Calculate the length of coordinate frame in bytes infile.SetupFrameBuffer( natom3_, 12, 6 ); // Read past restart coords if ( infile.ReadFrame() ) { mprinterr("Error: AmberRestart::setupTrajin(): Error reading coordinates.\n"); return TRAJIN_ERR; } // Save coordinates CRD_.resize( natom3_ ); infile.BufferBegin(); infile.BufferToDouble(&CRD_[0], natom3_); // Attempt a second read to get velocities or box coords bool hasVel = false; boxInfo_.SetNoBox(); nread = infile.AttemptReadFrame(); if ( nread < 0 ) { mprinterr("Error: Error attempting to read box line of Amber restart file.\n"); return TRAJIN_ERR; } size_t readSize = (size_t)nread; //mprintf("DEBUG: Restart readSize on second read = %i\n",readSize); // If 0 no box or velo if (readSize > 0) { if (readSize == infile.FrameSize()) { // If filled framebuffer again, has velocity info. hasVel = true; VEL_.resize( natom3_ ); infile.BufferBegin(); infile.BufferToDouble(&VEL_[0], natom3_); // If we can read 1 more line after velocity, should be box info. nextLine = infile.GetLine(); if (!nextLine.empty()) { if (getBoxAngles(nextLine, boxInfo_)) return TRAJIN_ERR; } } else if (readSize<82) { // If we read something but didnt fill framebuffer, should have box coords. nextLine.assign(infile.Buffer(), readSize); if (getBoxAngles(nextLine, boxInfo_)) return TRAJIN_ERR; } else { // Otherwise, who knows what was read? mprinterr("Error: AmberRestart::setupTrajin(): When attempting to read in\n" "Error: box coords/velocity info got %lu chars, expected 0, 37,\n" "Error: 73, or %lu.\n", readSize, infile.FrameSize()); mprinterr("Error: This usually indicates a malformed or corrupted restart file.\n"); return TRAJIN_ERR; } } if (useVelAsCoords_ && !hasVel) { mprinterr("Error: 'usevelascoords' specified but no velocities in this restart.\n"); return TRAJIN_ERR; } infile.CloseFile(); // Set coordinate info SetCoordInfo( CoordinateInfo(boxInfo_, hasVel, hasTemp, hasTime) ); // Only 1 frame in restart by definition return 1; }
// Traj_NcEnsemble::setupTrajin() int Traj_NcEnsemble::setupTrajin(FileName const& fname, Topology* trajParm) { # ifdef MPI if (NoPnetcdf()) return TRAJIN_ERR; # endif readAccess_ = true; filename_ = fname; //if (openTrajin()) return TRAJIN_ERR; // Open single thread for now if (NC_openRead( filename_.Full() )) return TRAJIN_ERR; // Sanity check - Make sure this is a Netcdf ensemble trajectory if ( GetNetcdfConventions() != NC_AMBERENSEMBLE ) { mprinterr("Error: Netcdf file %s conventions do not include \"AMBERENSEMBLE\"\n", filename_.base()); return TRAJIN_ERR; } // This will warn if conventions are not 1.0 CheckConventionsVersion(); // Get title SetTitle( GetNcTitle() ); // Get Frame info if ( SetupFrameDim()!=0 ) return TRAJIN_ERR; if ( Ncframe() < 1 ) { mprinterr("Error: Netcdf file is empty.\n"); return TRAJIN_ERR; } // Get ensemble info int ensembleSize = SetupEnsembleDim(); if (ensembleSize < 1) { mprinterr("Error: Could not get ensemble dimension info.\n"); return TRAJIN_ERR; } // Setup Coordinates/Velocities if ( SetupCoordsVelo( useVelAsCoords_, useFrcAsCoords_ )!=0 ) return TRAJIN_ERR; // Check that specified number of atoms matches expected number. if (Ncatom() != trajParm->Natom()) { mprinterr("Error: Number of atoms in NetCDF file %s (%i) does not\n" "Error: match number in associated parmtop (%i)!\n", filename_.base(), Ncatom(), trajParm->Natom()); return TRAJIN_ERR; } // Setup Time - FIXME: Allowed to fail silently SetupTime(); // Box info Box nc_box; if (SetupBox(nc_box, NC_AMBERENSEMBLE) == 1) // 1 indicates an error return TRAJIN_ERR; // Replica Temperatures - FIXME: Allowed to fail silently SetupTemperature(); // Replica Dimensions ReplicaDimArray remdDim; if ( SetupMultiD(remdDim) == -1 ) return TRAJIN_ERR; // Set traj info: FIXME - no forces yet SetCoordInfo( CoordinateInfo(ensembleSize, remdDim, nc_box, HasVelocities(), HasTemperatures(), HasTimes(), false) ); if (debug_>1) NetcdfDebug(); //closeTraj(); // Close single thread for now NC_close(); // Set up local ensemble parameters # ifdef MPI ensembleStart_ = Parallel::World().Rank(); ensembleEnd_ = Parallel::World().Rank() + 1; # else ensembleStart_ = 0; ensembleEnd_ = ensembleSize; # endif // DEBUG: Print info for all ranks WriteVIDs(); // Allocate float array if (Coord_ != 0) delete[] Coord_; Coord_ = new float[ Ncatom3() ]; return Ncframe(); }
int Traj_Gro::setupTrajin(FileName const& fnameIn, Topology* trajParm) { float fXYZ[9]; fname_ = fnameIn; // TODO SetupRead for BufferedLine // Open file for reading if (file_.OpenFileRead( fname_ )) return TRAJIN_ERR; // Read the title. May contain time value, 't= <time>' const char* ptr = file_.Line(); if (ptr == 0) { mprinterr("Error: Reading title.\n"); return TRAJIN_ERR; } std::string title( ptr ); RemoveTrailingWhitespace(title); mprintf("DBG: Title: %s\n", title.c_str()); bool hasTime = true; // TODO Is it OK to assume there will never be a negative time value? double timeVal = GetTimeValue( ptr ); if (timeVal < 0.0) hasTime = false; mprintf("DBG: Timeval= %g HasTime= %i\n", timeVal, (int)hasTime); // Read number of atoms ptr = file_.Line(); if (ptr == 0) return TRAJIN_ERR; natom_ = atoi(ptr); if (natom_ < 1) { mprinterr("Error: Reading number of atoms.\n"); return TRAJIN_ERR; } if (natom_ != trajParm->Natom()) { mprinterr("Error: Number of atoms %i does not match associated parm %s (%i)\n", natom_, trajParm->c_str(), trajParm->Natom()); return TRAJIN_ERR; } // Read first atom to see if there are velocities ptr = file_.Line(); int nread = sscanf(ptr, "%*5c%*5c%*5c%*5c%f %f %f %f %f %f", fXYZ, fXYZ+1, fXYZ+2, fXYZ+3, fXYZ+4, fXYZ+5); bool hasV = false; if (nread == 6) hasV = true; else if (nread != 3) { mprinterr("Error: Reading first atom, expected 3 or 6 coordinates, got %i\n", nread); return TRAJIN_ERR; } // Read past the rest of the atoms for (int i = 1; i != natom_; i++) if (file_.Line() == 0) { mprinterr("Error: Reading atom %i of first frame.\n", i+1); return TRAJIN_ERR; } // Attempt to read box line // v1(x) v2(y) v3(z) [v1(y) v1(z) v2(x) v2(z) v3(x) v3(y)] ptr = file_.Line(); Box groBox; if (ptr != 0) groBox = GetBox( ptr ); // Set trajectory information. No temperature info. SetCoordInfo( CoordinateInfo(groBox, hasV, false, hasTime) ); SetTitle( title ); // Check for multiple frames. If nothing was read above, 1 frame, no box. If // box info was read but nothing more can be read, 1 frame. Otherwise there // are more frames. bool hasMultipleFrames = false; if (ptr != 0) { if (groBox.Type() == Box::NOBOX) // Assume another title read. hasMultipleFrames = true; else { ptr = file_.Line(); // Read line after box info if (ptr != 0) hasMultipleFrames = true; } } // Set up some info for performing blank reads. linesToRead_ = natom_; if (groBox.Type() != Box::NOBOX) linesToRead_ += 1; int nframes = 1; if (hasMultipleFrames) { // Since there is no guarantee that each frame is the same size we cannot // just seek. Blank reads for as many times as possible. Should currently // be positioned at the title line of the next frame. while (ptr != 0 ) { ptr = file_.Line(); // Natoms int Nat = atoi(ptr); if (Nat != natom_) { mprinterr("Error: Frame %i # atoms (%i) does not match first frame (%i).\n" "Error: Only reading %i frames.\n", nframes+1, Nat, natom_, nframes); break; } for (int i = 0; i != linesToRead_; i++) ptr = file_.Line(); if (ptr == 0) break; nframes++; ptr = file_.Line(); // Next title or EOF } } file_.CloseFile(); return nframes; }
// Traj_AmberCoord::setupTrajin() int Traj_AmberCoord::setupTrajin(FileName const& fname, Topology* trajParm) { // Set up file for reading if (file_.SetupRead( fname, debug_ )) return TRAJIN_ERR; // Attempt to open the file. Read and set the title and titleSize if ( file_.OpenFile() ) return TRAJIN_ERR; std::string title = file_.GetLine(); // Allocate mem to read in frame (plus REMD header if present). REMD // header is checked for when file is IDd. Title size is used in seeking. natom3_ = trajParm->Natom() * 3; file_.SetupFrameBuffer( natom3_, 8, 10, headerSize_, title.size() ); if (debug_ > 0) { mprintf("Each frame is %zu bytes", file_.FrameSize()); if (headerSize_ != 0) mprintf(" (including REMD header)"); mprintf(".\n"); } // Read the first frame of coordinates if ( file_.ReadFrame() ) { mprinterr("Error: in read of Coords frame 1 of trajectory %s.\n", file_.Filename().base()); return TRAJIN_ERR; } // Check for box coordinates. If present, update the frame size and // reallocate the frame buffer. If less than 3 atoms there is no way // to tell if a line is a box line or coordinates, so skip. Box boxInfo; if ( trajParm->Natom() < 3 ) { mprintf("Warning: Less than 3 atoms, skipping box check.\n"); numBoxCoords_ = 0; } else { std::string nextLine = file_.GetLine(); if ( !nextLine.empty() ) { if (debug_>0) rprintf("DEBUG: Line after first frame: (%s)\n", nextLine.c_str()); if ( IsRemdHeader(nextLine.c_str()) || IsRxsgldHeader(nextLine.c_str()) ) { // REMD header - no box coords numBoxCoords_ = 0; } else { double box[8]; numBoxCoords_ = sscanf(nextLine.c_str(), "%8lf%8lf%8lf%8lf%8lf%8lf%8lf%8lf", box, box+1, box+2, box+3, box+4, box+5, box+6, box+7); if (numBoxCoords_ == -1) { mprinterr("Error: Could not read Box coord line of trajectory %s.\n", file_.Filename().base()); return TRAJIN_ERR; } else if (numBoxCoords_ == 8) { // Full line of coords was read, no box coords. numBoxCoords_ = 0; } else if (numBoxCoords_ == 3) { // Box lengths only, ortho. or truncated oct. Use default parm angles. if (trajParm->ParmBox().Type() == Box::NOBOX) mprintf("Warning: Trajectory only contains box lengths and topology has no box info.\n" "Warning: To set box angles for topology use the 'parmbox' command.\n"); box[3] = boxAngle_[0] = trajParm->ParmBox().Alpha(); box[4] = boxAngle_[1] = trajParm->ParmBox().Beta(); box[5] = boxAngle_[2] = trajParm->ParmBox().Gamma(); boxInfo.SetBox( box ); } else if (numBoxCoords_ == 6) { // General triclinic. Set lengths and angles. boxInfo.SetBox( box ); } else { mprinterr("Error: In %s, expect only 3 or 6 box coords, got %i\n" "Error: Box line=[%s]\n", file_.Filename().base(), numBoxCoords_, nextLine.c_str()); return TRAJIN_ERR; } } } // Reallocate frame buffer accordingly file_.ResizeBuffer( numBoxCoords_ ); } // Calculate Frames and determine seekable. If not possible and this is not a // compressed file the trajectory is probably corrupted. Frames will // be read until EOF. int Frames = 0; if (debug_>0) rprintf("Title offset=%lu FrameSize=%lu UncompressedFileSize=%lu\n", title.size(), file_.FrameSize(), file_.UncompressedSize()); off_t title_size = (off_t) title.size(); off_t frame_size = (off_t) file_.FrameSize(); off_t uncompressed_size = file_.UncompressedSize(); off_t file_size = uncompressed_size - title_size; bool seekable = false; if (file_.Compression() != CpptrajFile::NO_COMPRESSION) { // -----==== AMBER TRAJ COMPRESSED ====------ // If the uncompressed size of compressed file is reported as <= 0, // uncompressed size cannot be determined. Read coordinates until // EOF. if (uncompressed_size <= 0) { mprintf("Warning: %s: Uncompressed size of trajectory could not be determined.\n", file_.Filename().base()); if (file_.Compression() == CpptrajFile::BZIP2) mprintf(" (This is normal for bzipped files)\n"); mprintf(" Number of frames could not be calculated.\n"); mprintf(" Frames will be read until EOF.\n"); Frames = TRAJIN_UNK; seekable = false; } else { // Frame calculation for large gzip files if (file_.Compression() == CpptrajFile::GZIP) { // Since this is gzip compressed, if the file_size % frame size != 0, // it could be that the uncompressed filesize > 4GB. Since // ISIZE = uncompressed % 2^32, // try ((file_size + (2^32 * i)) % frame_size) and see if any are 0. if ( (file_size % frame_size) != 0) { // Determine the maximum number of iterations to try based on the // fact that Amber trajectories typically compress about 3x with // gzip. off_t tmpfsize = ((file_.FileSize() * 4) - uncompressed_size) / 4294967296LL; int maxi = (int) tmpfsize; ++maxi; if (debug_>1) mprintf("\tLooking for uncompressed gzip size > 4GB, %i iterations.\n",maxi); tmpfsize = 0; bool sizeFound = false; for (int i = 0; i < maxi; i++ ) { tmpfsize = (4294967296LL * i) + file_size; if ( (tmpfsize % frame_size) == 0) {sizeFound=true; break;} } if (sizeFound) file_size = tmpfsize; } } if ((file_size % frame_size) == 0) { Frames = (int) (file_size / frame_size); seekable = true; } else { mprintf("Warning: %s: Number of frames in compressed traj could not be determined.\n" "Warning: Frames will be read until EOF.\n", file_.Filename().base()); Frames = TRAJIN_UNK; seekable = false; } } } else { // ----==== AMBER TRAJ NOT COMPRESSED ====---- Frames = (int) (file_size / frame_size); if ( (file_size % frame_size) == 0 ) { seekable = true; } else { mprintf("Warning: %s: Could not accurately predict # frames. This usually\n" "Warning: indicates a corrupted trajectory or trajectory/topology\n" "Warning: mismatch. Will attempt to read %i frames.\n", file_.Filename().base(), Frames); seekable = false; } } if (debug_>0) rprintf("Atoms: %i FrameSize: %lu TitleSize: %lu NumBox: %i Seekable: %i Frames: %i\n\n", trajParm->Natom(), frame_size, title_size, numBoxCoords_, (int)seekable, Frames); // Close the file file_.CloseFile(); // Set trajectory info: no velocity, no time. SetCoordInfo( CoordinateInfo(boxInfo, false, (headerSize_ != 0), false) ); SetTitle( title ); return Frames; }