From 7101ae694c9cd77e1b228f11959e496005134cbd Mon Sep 17 00:00:00 2001 From: Marco Biasini <marco.biasini@unibas.ch> Date: Wed, 13 Oct 2010 18:34:24 +0200 Subject: [PATCH] SaveCHARMMTraj saves the PDB files in CHARMM format --- modules/io/pymod/__init__.py | 4 +- modules/io/pymod/export_pdb_io.cc | 1 + modules/io/src/mol/dcd_io.cc | 3 +- modules/io/src/mol/pdb_writer.cc | 71 ++++++++++++++++++++----------- modules/io/src/mol/pdb_writer.hh | 13 +++--- 5 files changed, 58 insertions(+), 34 deletions(-) diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index 5534c540d..b43415cb6 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -145,7 +145,7 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=False, PDB.PopFlags() raise -def SavePDB(models, filename): +def SavePDB(models, filename, dialect='PDB'): """ Save entity or list of entities to disk. If a list of entities is supplied the PDB file will be saved as a multi PDB file. Each of the entities is wrapped @@ -157,7 +157,7 @@ def SavePDB(models, filename): """ if not getattr(models, '__len__', None): models=[models] - writer=PDBWriter(filename) + writer=PDBWriter(filename, dialect=='CHARMM') try: if len(models)>1: PDB.PushFlags(PDB.Flags() |PDB.WRITE_MULTIPLE_MODELS) diff --git a/modules/io/pymod/export_pdb_io.cc b/modules/io/pymod/export_pdb_io.cc index 1275ea7a6..27e62dc1c 100644 --- a/modules/io/pymod/export_pdb_io.cc +++ b/modules/io/pymod/export_pdb_io.cc @@ -64,6 +64,7 @@ void export_pdb_io() ; class_<PDBWriter, boost::noncopyable>("PDBWriter", init<String>()) + .def(init<String, bool>()) .def("Write", write_a) .def("Write", write_b) ; diff --git a/modules/io/src/mol/dcd_io.cc b/modules/io/src/mol/dcd_io.cc index 86a59ed42..b7723de0a 100644 --- a/modules/io/src/mol/dcd_io.cc +++ b/modules/io/src/mol/dcd_io.cc @@ -242,6 +242,7 @@ public: mol::CoordSource(atoms), filename_(filename), stream_(filename.c_str(), std::ios::binary), loaded_(false), stride_(stride) { + frame_count_=0; this->SetMutable(false); frame_=mol::CoordFramePtr(new mol::CoordFrame(atoms.size())); } @@ -373,7 +374,7 @@ void SaveCHARMMTraj(const mol::CoordGroupHandle& coord_group, { if(stepsize==0) stepsize=1; if(!pdb_filename.empty()) { - PDBWriter writer(pdb_filename); + PDBWriter writer(pdb_filename, true); writer.Write(coord_group.GetAtomList()); } std::ofstream out(dcd_filename.c_str(), std::ios::binary); diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index 580c40752..8b16c2cce 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -61,7 +61,7 @@ bool shift_left(const String& atom_name, bool is_hetatm, void write_atom(std::ostream& ostr, FormattedLine& line, const mol::AtomHandle& atom, int atomnum, - bool is_pqr) + bool is_pqr, bool charmm_style) { mol::ResidueHandle res=atom.GetResidue(); char ins_code=res.GetNumber().GetInsCode(); @@ -83,20 +83,32 @@ void write_atom(std::ostream& ostr, FormattedLine& line, } else { line(13, 3)=fmt::RPadded(atom_name); } - if (res.GetKey().size()>3) { - throw IOException("Residue name '"+res.GetQualifiedName()+ - "' is too long for PDB output. At most 3 characters are " - "allowed"); + if (charmm_style) { + if (res.GetKey().size()>4) { + throw IOException("Residue name '"+res.GetName()+ + "' is too long for CHARMM-PDB output. At most 4 " + "characters are allowed"); + } + line(17, 4)=fmt::LPadded(res.GetKey()); + } else { + if (res.GetKey().size()>3) { + throw IOException("Residue name '"+res.GetName()+ + "' is too long for PDB output. At most 3 characters " + "are allowed"); + } + line(17, 3)=fmt::LPadded(res.GetKey()); } - line(17, 3)=fmt::LPadded(res.GetKey()); + String chain_name=res.GetChain().GetName(); - if (chain_name.size()>0) { - if (chain_name.size()==1) { - line[21]=chain_name[0]; - } else { - throw IOException("PDB format only support single-letter chain names"); - } + if (!charmm_style) { + if (chain_name.size()>0) { + if (chain_name.size()==1) { + line[21]=chain_name[0]; + } else { + throw IOException("PDB format only support single-letter chain names"); + } + } } line(22, 4)=fmt::LPaddedInt(res.GetNumber().GetNum()); if (ins_code!=0) { @@ -116,7 +128,9 @@ void write_atom(std::ostream& ostr, FormattedLine& line, line(54, 6)=fmt::LPaddedFloat(atom.GetOccupancy(), 2); line(60, 6)=fmt::LPaddedFloat(atom.GetBFactor(), 2); } - + if (charmm_style) { + line(72, 4)=fmt::RPadded(chain_name); + } line(76, 2)=fmt::LPadded(atom.GetElement()); ostr << line; } else { @@ -142,7 +156,9 @@ void write_atom(std::ostream& ostr, FormattedLine& line, line(54, 6)=fmt::LPaddedFloat(atom.GetOccupancy(), 2); line(60, 6)=fmt::LPaddedFloat(atom.GetBFactor(), 2); } - + if (charmm_style) { + line(72, 4)=fmt::RPadded(chain_name); + } line(76, 2)=fmt::LPadded(atom.GetElement()); ostr << line; } @@ -171,15 +187,16 @@ void write_conect(std::ostream& ostr, int atom_index, class PDBWriterImpl : public mol::EntityVisitor { public: PDBWriterImpl(std::ostream& ostream, FormattedLine& line, - std::map<long,int>& atom_indices) + std::map<long,int>& atom_indices, bool charmm_style) : ostr_(ostream), counter_(0), is_pqr_(false), - atom_indices_(atom_indices), line_(line), peptide_(false) { + atom_indices_(atom_indices), line_(line), peptide_(false), + charmm_style_(charmm_style) { } private: public: virtual bool VisitAtom(const mol::AtomHandle& atom) { counter_++; - write_atom(ostr_, line_, atom, counter_, is_pqr_); + write_atom(ostr_, line_, atom, counter_, is_pqr_, charmm_style_); if (atom.GetAtomProps().is_hetatm) { atom_indices_[atom.GetHashCode()]=counter_; } @@ -240,6 +257,7 @@ private: FormattedLine& line_; mol::ResidueHandle prev_; bool peptide_; + bool charmm_style_; }; class PDBConectWriterImpl : public mol::EntityVisitor { @@ -287,19 +305,21 @@ struct ForcePOSIX { } -PDBWriter::PDBWriter(std::ostream& stream): - outfile_(), outstream_(stream), mol_count_(0), line_(80) +PDBWriter::PDBWriter(std::ostream& stream, bool charmm_style): + outfile_(), outstream_(stream), mol_count_(0), line_(80), + charmm_style_(charmm_style) { } -PDBWriter::PDBWriter(const boost::filesystem::path& filename): +PDBWriter::PDBWriter(const boost::filesystem::path& filename, bool charmm_style): outfile_(filename.file_string().c_str()), outstream_(outfile_), - mol_count_(0), line_(80) + mol_count_(0), line_(80), charmm_style_(charmm_style) {} -PDBWriter::PDBWriter(const String& filename): - outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0), line_(80) +PDBWriter::PDBWriter(const String& filename, bool charmm_style): + outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0), line_(80), + charmm_style_(charmm_style) {} void PDBWriter::WriteModelLeader() @@ -325,7 +345,7 @@ void PDBWriter::WriteModel(H ent) { ForcePOSIX posix = ForcePOSIX(); this->WriteModelLeader(); - PDBWriterImpl writer(outstream_,line_, atom_indices_); + PDBWriterImpl writer(outstream_,line_, atom_indices_, charmm_style_); if (PDB::Flags() & PDB::PQR_FORMAT) { writer.SetIsPQR(true); } @@ -353,7 +373,8 @@ void PDBWriter::Write(const mol::AtomHandleList& atoms) mol::ChainHandle last_chain; for (mol::AtomHandleList::const_iterator i=atoms.begin(), e=atoms.end(); i!=e; ++i, ++counter) { - write_atom(outstream_, line_, *i, counter, (PDB::Flags() & PDB::PQR_FORMAT) != 0); + write_atom(outstream_, line_, *i, counter, + (PDB::Flags() & PDB::PQR_FORMAT) != 0, charmm_style_); } this->WriteModelTrailer(); } diff --git a/modules/io/src/mol/pdb_writer.hh b/modules/io/src/mol/pdb_writer.hh index 40ed1cbff..c89657215 100644 --- a/modules/io/src/mol/pdb_writer.hh +++ b/modules/io/src/mol/pdb_writer.hh @@ -40,9 +40,9 @@ namespace ost { namespace io { class DLLEXPORT_OST_IO PDBWriter { public: - PDBWriter(const String& filename); - PDBWriter(const boost::filesystem::path& filename); - PDBWriter(std::ostream& outstream); + PDBWriter(const String& filename, bool charmm_style=false); + PDBWriter(const boost::filesystem::path& filename, bool charmm_style=false); + PDBWriter(std::ostream& outstream, bool charmm_style=false); void Write(const mol::EntityView& ent); void Write(const mol::EntityHandle& ent); @@ -56,11 +56,12 @@ private: void WriteModelLeader(); void WriteModelTrailer(); - std::ofstream outfile_; - std::ostream& outstream_; - int mol_count_; + std::ofstream outfile_; + std::ostream& outstream_; + int mol_count_; std::map<long, int> atom_indices_; FormattedLine line_; + bool charmm_style_; }; }} -- GitLab