diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index 82ab97c27b96400ea16d1bf5db285af1fea57c5b..996ff1ffcb76a3dddbd6b8b08bbee7e73b72fbe3 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -52,21 +52,27 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=False, flags|=PDB.NO_HETATMS if join_spread_atom_records: flags|=PDB.JOIN_SPREAD_ATOM_RECORDS - reader.SetFlags(flags) - if load_multi: - ent_list=[] - while reader.HasNext(): - ent=mol.CreateEntity() - reader.Import(ent, restrict_chains) - conop_inst.ConnectAll(builder, ent, 0) - ent_list.append(ent) - return ent_list - else: - ent=mol.CreateEntity() - if reader.HasNext(): - reader.Import(ent, restrict_chains) - conop_inst.ConnectAll(builder, ent, 0) - return ent + try: + PDB.PushFlags(PDB.Flags() | flags) + if load_multi: + ent_list=[] + while reader.HasNext(): + ent=mol.CreateEntity() + reader.Import(ent, restrict_chains) + conop_inst.ConnectAll(builder, ent, 0) + ent_list.append(ent) + PDB.PopFlags() + return ent_list + else: + ent=mol.CreateEntity() + if reader.HasNext(): + reader.Import(ent, restrict_chains) + conop_inst.ConnectAll(builder, ent, 0) + PDB.PopFlags() + return ent + except: + PDB.PopFlags() + raise def SavePDB(models, filename): """ diff --git a/modules/io/pymod/export_pdb_io.cc b/modules/io/pymod/export_pdb_io.cc index 6cc80b813ca1c95fca26604b91f93012684390e4..fe2a3a75f0635e36dbab85cc4157bacb696151d6 100644 --- a/modules/io/pymod/export_pdb_io.cc +++ b/modules/io/pymod/export_pdb_io.cc @@ -31,26 +31,38 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_PDB_ov, LoadPDB, 1, 2) void (PDBWriter::*write_a)(const mol::EntityHandle&)=&PDBWriter::Write; void (PDBWriter::*write_b)(const mol::EntityView&)=&PDBWriter::Write; + +namespace { + void push_flags(unsigned int x) {PDB::PushFlags(x);} + unsigned int flags() {return PDB::Flags();} + void pop_flags() {PDB::PopFlags();} +} + void export_pdb_io() { - enum_<PDB::Type>("PDB") - .value("NO_HETATMS", PDB::NO_HETATMS) - .value("SKIP_FAULTY_RECORDS", PDB::SKIP_FAULTY_RECORDS) - .value("WRITE_MULTIPLE_MODELS", PDB::WRITE_MULTIPLE_MODELS) - .value("JOIN_SPREAD_ATOM_RECORDS", PDB::JOIN_SPREAD_ATOM_RECORDS) - .value("SEQUENTIAL_ATOM_IMPORT", PDB::SEQUENTIAL_ATOM_IMPORT) - ; + { + scope pdb_scope=class_<PDB>("PDB",no_init) + .def("PushFlags",&PDB::PushFlags) + .staticmethod("PushFlags") + .def("Flags",&PDB::Flags) + .staticmethod("Flags") + .def("PopFlags",&PDB::PopFlags) + .staticmethod("PopFlags") + ; + pdb_scope.attr("NO_HETATMS")=PDB::NO_HETATMS; + pdb_scope.attr("SKIP_FAULTY_RECORDS")=PDB::SKIP_FAULTY_RECORDS; + pdb_scope.attr("WRITE_MULTIPLE_MODELS")=PDB::WRITE_MULTIPLE_MODELS; + pdb_scope.attr("JOIN_SPREAD_ATOM_RECORDS")=PDB::JOIN_SPREAD_ATOM_RECORDS; + } + class_<PDBReader, boost::noncopyable>("PDBReader", init<String>()) .def("HasNext", &PDBReader::HasNext) .def("Import", &PDBReader::Import, X_import(args("entity", "restrict_chains"))) - .def("SetFlags", &PDBReader::SetFlags) - .def("GetSequentialAtoms", &PDBReader::GetSequentialAtoms) ; class_<PDBWriter, boost::noncopyable>("PDBWriter", init<String>()) .def("Write", write_a) .def("Write", write_b) - .def("SetFlags", &PDBWriter::SetFlags) ; } diff --git a/modules/io/pymod/wrap_io.cc b/modules/io/pymod/wrap_io.cc index 79920189ef60ba1cb71c122bb566907291646bef..b04d3ac78ab729a8125fd258f9b7de89c2f15653 100644 --- a/modules/io/pymod/wrap_io.cc +++ b/modules/io/pymod/wrap_io.cc @@ -28,6 +28,7 @@ using namespace boost::python; #include <ost/io/seq/save.hh> #include <ost/io/mol/entity_io_pdb_handler.hh> #include <ost/io/mol/entity_io_crd_handler.hh> +#include <ost/io/mol/entity_io_mae_handler.hh> #include <ost/io/mol/entity_io_sdf_handler.hh> #include <ost/io/mol/pdb_reader.hh> #include <ost/io/mol/dcd_io.hh> @@ -120,6 +121,9 @@ BOOST_PYTHON_MODULE(_io) def("LoadCHARMMTraj",load_dcd3); def("LoadCHARMMTraj",load_dcd4); def("SaveCHARMMTraj",SaveCHARMMTraj,save_charmm_trj_ov()); + + def("LoadMAE", &LoadMAE); + export_pdb_io(); #if OST_IMG_ENABLED export_map_io(); diff --git a/modules/io/src/io_manager.cc b/modules/io/src/io_manager.cc index 23ab54bd29a2bc3efe72085ac9f9242b80c7a69f..b03169d8c84e49f80a7af74c23cf2780d20928b3 100644 --- a/modules/io/src/io_manager.cc +++ b/modules/io/src/io_manager.cc @@ -20,6 +20,7 @@ #include <ost/io/mol/entity_io_pdb_handler.hh> #include <ost/io/mol/entity_io_crd_handler.hh> #include <ost/io/mol/entity_io_sdf_handler.hh> +#include <ost/io/mol/entity_io_mae_handler.hh> #include <ost/io/seq/fasta_io_handler.hh> #include <ost/io/seq/promod_io_handler.hh> #include <ost/io/mol/surface_io_msms_handler.hh> @@ -43,6 +44,7 @@ IOManager::IOManager() RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOPDBHandlerFactory)); RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOCRDHandlerFactory)); RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOSDFHandlerFactory)); + RegisterFactory(EntityIOHandlerFactoryBaseP(new EntityIOMAEHandlerFactory)); RegisterFactory(SequenceIOHandlerFactoryBasePtr(new FastaIOHandlerFactory)); RegisterFactory(SequenceIOHandlerFactoryBasePtr(new ClustalIOHandlerFactory)); RegisterFactory(SequenceIOHandlerFactoryBasePtr(new PromodIOHandlerFactory)); diff --git a/modules/io/src/mol/CMakeLists.txt b/modules/io/src/mol/CMakeLists.txt index b3fd346b6e87552242a509f853a0eb5ff093fd38..772a0c89c5963a7efb97004895c9736dfd29d206 100644 --- a/modules/io/src/mol/CMakeLists.txt +++ b/modules/io/src/mol/CMakeLists.txt @@ -1,32 +1,35 @@ set(OST_IO_MOL_SOURCES +dcd_io.cc entity_io_crd_handler.cc -pdb_reader.cc +entity_io_mae_handler.cc entity_io_pdb_handler.cc -pdb_writer.cc entity_io_sdf_handler.cc -save_entity.cc load_entity.cc -surface_io_msms_handler.cc load_surface.cc -dcd_io.cc +pdb_io.cc +pdb_reader.cc +pdb_writer.cc +save_entity.cc star_parser.cc +surface_io_msms_handler.cc PARENT_SCOPE ) set(OST_IO_MOL_HEADERS -star_parser.hh dcd_io.hh +entity_io_handler.hh entity_io_crd_handler.hh +entity_io_mae_handler.hh +entity_io_pdb_handler.hh +entity_io_sdf_handler.hh +load_entity.hh +load_surface.hh pdb_io.hh -entity_io_handler.hh pdb_reader.hh -entity_io_pdb_handler.hh pdb_writer.hh -entity_io_sdf_handler.hh save_entity.hh -load_entity.hh surface_io_handler.hh -load_surface.hh +star_parser.hh surface_io_msms_handler.hh PARENT_SCOPE ) diff --git a/modules/io/src/mol/dcd_io.cc b/modules/io/src/mol/dcd_io.cc index efe9f1dfb368cc888c5785279af00ee8510a3fb7..6fd936c42fc15ac93d6c3c753a3f76fcc0aeaf70 100644 --- a/modules/io/src/mol/dcd_io.cc +++ b/modules/io/src/mol/dcd_io.cc @@ -22,6 +22,8 @@ */ #include <fstream> +#include <algorithm> + #include <boost/iostreams/filter/gzip.hpp> #include <boost/filesystem/convenience.hpp> @@ -58,12 +60,20 @@ struct DCDHeader { int t_atom_count,f_atom_count, atom_count; }; -mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist, +bool less_index(const mol::AtomHandle& a1, const mol::AtomHandle& a2) +{ + return a1.GetIndex()<a2.GetIndex(); +} + +mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist2, const String& trj_fn, unsigned int stride) { Profile profile_load("LoadCHARMMTraj"); + mol::AtomHandleList alist(alist2); + std::sort(alist.begin(),alist.end(),less_index); + bool gap_flag = true; boost::filesystem::path trj_f(trj_fn); @@ -121,7 +131,7 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist, header.f_atom_count=header.icntrl[8]; header.atom_count=header.t_atom_count-header.f_atom_count; - LOGN_MESSAGE("LoadCHARMMTraj: " << header.num << " trajectories with " + LOGN_DEBUG("LoadCHARMMTraj: " << header.num << " trajectories with " << header.atom_count << " atoms (" << header.f_atom_count << " fixed) each"); @@ -136,7 +146,8 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist, std::vector<geom::Vec3> clist(header.t_atom_count); std::vector<float> xlist(header.t_atom_count); - for(int i=0;i<header.num;++i) { + int i=0; + for(;i<header.num;++i) { if(skip_flag) ff.seekg(14*4,std::ios_base::cur); // read each frame if(!ff) { @@ -169,9 +180,9 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist, for(uint j=0;j<clist.size();++j) { clist[j].SetZ(xlist[j]); } - if(i%stride) { - cg.AddFrame(clist); - } + + cg.AddFrame(clist); + } ff.get(); @@ -179,6 +190,9 @@ mol::CoordGroupHandle load_dcd(const mol::AtomHandleList& alist, LOGN_VERBOSE("LoadCHARMMTraj: unexpected trailing file data, bytes read: " << ff.tellg()); } + + LOGN_VERBOSE("Loaded " << cg.GetFrameCount() << " frames with " << cg.GetAtomCount() << " atoms each"); + return cg; } @@ -188,6 +202,7 @@ mol::CoordGroupHandle LoadCHARMMTraj(const String& crd_fn, const String& trj_fn, unsigned int stride) { + if(stride==0) stride=1; boost::filesystem::path crd_f(crd_fn); // first the coordinate reference file @@ -197,21 +212,18 @@ mol::CoordGroupHandle LoadCHARMMTraj(const String& crd_fn, std::vector<mol::AtomHandle> alist; if(boost::filesystem::extension(crd_f)==".pdb") { PDBReader reader(crd_f); - reader.SetFlags(PDB::SEQUENTIAL_ATOM_IMPORT); LOGN_MESSAGE("importing coordinate data"); reader.Import(ent); - alist = reader.GetSequentialAtoms(); } else if (boost::filesystem::extension(crd_f)==".crd") { CRDReader reader(crd_f); LOGN_MESSAGE("importing coordinate data"); reader.Import(ent); - alist = reader.GetSequentialAtoms(); } else { throw(IOException("unsupported coordinate file format")); } conop::Conopology::Instance().ConnectAll(builder,ent); - return load_dcd(alist,trj_fn,stride); + return load_dcd(ent.GetAtomList(),trj_fn,stride); } diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc index ce4a1679b765cc8aa13fbddb873b82c33f427871..cfbb7efccbc7986a61b903409c90755b4fe17a1f 100644 --- a/modules/io/src/mol/entity_io_crd_handler.cc +++ b/modules/io/src/mol/entity_io_crd_handler.cc @@ -43,9 +43,6 @@ namespace ost { namespace io { using boost::format; -String FORMAT_NAME_STRING; -String FORMAT_DESCRIPTION_STRING; - CRDReader::CRDReader(const boost::filesystem::path& loc): sequential_atom_list_(), curr_chain_(), diff --git a/modules/io/src/mol/entity_io_mae_handler.cc b/modules/io/src/mol/entity_io_mae_handler.cc new file mode 100755 index 0000000000000000000000000000000000000000..e41fa029c98e38c157b2c729de228f71aa5e7bbf --- /dev/null +++ b/modules/io/src/mol/entity_io_mae_handler.cc @@ -0,0 +1,345 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +/* + Author: Ansgar Philippsen + */ +#include <iostream> +#include <sstream> +#include <iomanip> +#include <vector> +#include <string> + +#include <ctype.h> + +#include <boost/iostreams/filter/gzip.hpp> +#include <boost/filesystem/convenience.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/format.hpp> +#include <boost/regex.hpp> + +#include <ost/log.hh> +#include <ost/conop/conop.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/profile.hh> + +#include <ost/io/io_exception.hh> +#include <ost/io/swap_util.hh> + +#include "entity_io_mae_handler.hh" + +namespace ost { namespace io { + +using boost::format; + + namespace { + + std::vector<std::string> tokenize(const std::string& line) + { + std::vector<std::string> nrvo; + bool in_string=false; + int p0=0; + for(int p1=1;p1<line.size();++p1) { + if(in_string) { + if(line[p1]=='"') { + in_string=false; + nrvo.push_back(line.substr(p0,p1-p0)); + ++p1; + p0=p1; + while(isspace(line[p1]) and p1<line.size()) {++p0;++p1;} + --p0; --p1; + } + } else { + if(isspace(line[p1])) { + nrvo.push_back(line.substr(p0+1,p1-p0-1)); + ++p1; + p0=p1; + while(isspace(line[p1]) and p1<line.size()) {++p0;++p1;} + --p0; --p1; + } else if(line[p1]=='"') { + in_string=true; + p0=p1+1; + } + } + } + return nrvo; + } + + } + +MAEReader::MAEReader(const boost::filesystem::path& loc): + curr_chain_(), + curr_residue_(), + chain_count_(0), + residue_count_(0), + atom_count_(0), + infile_(loc), + in_() +{ + if (boost::iequals(".gz", boost::filesystem::extension(loc))) { + in_.push(boost::iostreams::gzip_decompressor()); + } + in_.push(infile_); + if(!infile_) throw IOException("could not open "+loc.string()); +} + +void MAEReader::Import(mol::EntityHandle& ent) +{ + Profile profile_import("MAEReader::Import"); + + static const boost::regex r_ct_block("f_m_ct +\\{"); + static const boost::regex r_atom_block("m_atom\\[.*\\] +\\{"); + static const boost::regex r_delim(":::"); + + String line; + bool in_ct_block=false; + bool in_atom_block=false; + bool parsing_atoms=false; + bool debug=true; + std::vector<std::string> prop_list; + int i_atom_name=-1; + int i_atom_xpos=-1; + int i_atom_ypos=-1; + int i_atom_zpos=-1; + int i_res_name=-1; + int i_res_num=-1; + int i_chain_name=-1; + + mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT); + + while(std::getline(in_,line)) { + line = boost::trim_copy(line); + if(in_ct_block) { + if(in_atom_block) { + if(parsing_atoms) { + if(boost::regex_match(line,r_delim)) { + std::cerr << "stopping atom parsing" << std::endl; + parsing_atoms=false; + } else { + // parsing atom line + std::vector<std::string> tokens=tokenize(line); + add_atom(ent,editor, + tokens[i_atom_name], + tokens[i_atom_xpos], + tokens[i_atom_ypos], + tokens[i_atom_zpos], + tokens[i_res_name], + tokens[i_res_num], + tokens[i_chain_name]); + } + } else { // not parsing atoms + if(boost::regex_match(line,r_delim)) { + if(i_atom_name==-1 || + i_atom_xpos==-1 || + i_atom_ypos==-1 || + i_atom_zpos==-1 || + i_res_name==-1 || + i_res_num==-1 || + i_chain_name==-1) { + throw IOException("missing atom prop"); + } + std::cerr << "starting atom parsing" << std::endl; + parsing_atoms=true; + } else if(line[0]=='}') { + std::cerr << "exiting atom block" << std::endl; + in_atom_block=false; + } else { + // parsing property line + int pid=prop_list.size(); + prop_list.push_back(line); + std::cerr << "found property '" << prop_list.back() << "'" << std::endl; + if(line=="s_m_pdb_atom_name") i_atom_name=pid; + else if(line=="r_m_x_coord") i_atom_xpos=pid; + else if(line=="r_m_y_coord") i_atom_ypos=pid; + else if(line=="r_m_z_coord") i_atom_zpos=pid; + else if(line=="s_m_pdb_residue_name") i_res_name=pid; + else if(line=="i_m_residue_number") i_res_num=pid; + else if(line=="s_m_pdb_segment_name") i_chain_name=pid; + } + } + } else { // not in atom block + if(boost::regex_match(line,r_atom_block)) { + std::cerr << "entering atom block" << std::endl; + in_atom_block=true; + } else if(line[0]=='}') { + std::cerr << "exiting ct block" << std::endl; + in_ct_block=false; + } + } + } else { // not in ct block + if(boost::regex_match(line,r_ct_block)) { + std::cerr << "entering ct block" << std::endl; + in_ct_block=true; + } + } + } + + LOGN_MESSAGE("imported " << chain_count_ << " chains, " << residue_count_ + << " residues, " << atom_count_ << " atoms"); +} + + +void MAEReader::add_atom(mol::EntityHandle ent, + mol::XCSEditor& editor, + const std::string& aname, + const std::string& s_axpos, + const std::string& s_aypos, + const std::string& s_azpos, + const std::string& rname, + const std::string& s_rnum, + const std::string& cname) +{ + std::string ele = aname.substr(0,1); + int irnum = boost::lexical_cast<int>(s_rnum); + geom::Vec3 apos(boost::lexical_cast<Real>(s_axpos), + boost::lexical_cast<Real>(s_aypos), + boost::lexical_cast<Real>(s_azpos)); + + mol::ResidueKey rkey(rname); + + // some postprocessing + LOGN_TRACE( "cname: [" << cname << "]" ); + + mol::ResNum rnum(irnum); + + // determine chain and residue update + bool update_chain=false; + bool update_residue=false; + if(!curr_chain_) { + update_chain=true; + update_residue=true; + } else if(curr_chain_.GetName()!=cname) { + update_chain=true; + update_residue=true; + } + + if(!curr_residue_) { + update_residue=true; + } else if(curr_residue_.GetNumber()!=rnum) { + update_residue=true; + } + + if(update_chain) { + if (!(curr_chain_=ent.FindChain(cname))) { + LOGN_DUMP("new chain " << cname); + curr_chain_=editor.InsertChain(cname); + ++chain_count_; + } + } + + if(update_residue) { + if (!(curr_residue_=curr_chain_.FindResidue(rnum))) { + LOGN_DUMP("new residue " << rkey << " " << rnum); + curr_residue_=editor.AppendResidue(curr_chain_, rkey, rnum); + assert(curr_residue_.IsValid()); + ++residue_count_; + } + } + + // finally add atom + LOGN_DUMP("adding atom " << aname << " (" << ele << ") @" << apos); + mol::AtomProp aprop; + aprop.element=ele; + aprop.radius=conop::Conopology::Instance().GetDefaultAtomRadius(ele); + aprop.is_hetatm=false; + aprop.b_factor=0.0; + aprop.occupancy=1.0; + mol::AtomHandle ah = editor.InsertAtom(curr_residue_, aname, apos, aprop); +} + + + + +bool EntityIOMAEHandler::RequiresBuilder() const +{ + return true; +} + +void EntityIOMAEHandler::Import(mol::EntityHandle& ent, + const boost::filesystem::path& loc) +{ + MAEReader reader(loc); + reader.Import(ent); +} + +void EntityIOMAEHandler::Export(const mol::EntityView& ent, + const boost::filesystem::path& loc) const +{ +} + +namespace { + +bool mae_handler_is_responsible_for(const boost::filesystem::path& loc, + const String& type) { + if(type=="auto") { + String match_suf_string=loc.string(); + std::transform(match_suf_string.begin(),match_suf_string.end(),match_suf_string.begin(),tolower); + if( detail::FilenameEndsWith(match_suf_string,".mae") || detail::FilenameEndsWith(match_suf_string,".mae.gz") ) { + return true; + } + } else if(type=="mae") { + return true; + } + + return false; +} + +} + +bool EntityIOMAEHandler::ProvidesImport(const boost::filesystem::path& loc, + const String& type) +{ + return mae_handler_is_responsible_for(loc, type); +} + +bool EntityIOMAEHandler::ProvidesExport(const boost::filesystem::path& loc, + const String& type) +{ + return false; +} + +mol::EntityHandle LoadMAE(const String& file_name) +{ + Profile profile_load("LoadMAE"); + conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); + MAEReader reader(file_name); + mol::EntityHandle ent=mol::CreateEntity(); + mol::XCSEditor editor=ent.RequestXCSEditor(mol::BUFFERED_EDIT); + reader.Import(ent); + conop::Conopology::Instance().ConnectAll(builder,ent); + return ent; +} + + +void EntityIOMAEHandler::Import(mol::EntityHandle& ent, + std::istream& stream) +{ + throw IOException("MAE format does not support import from stream"); +} + + +void EntityIOMAEHandler::Export(const mol::EntityView& ent, + std::ostream& stream) const +{ + throw IOException("MAE format does not support export to stream"); +} + +}} // ns + + diff --git a/modules/io/src/mol/entity_io_mae_handler.hh b/modules/io/src/mol/entity_io_mae_handler.hh new file mode 100755 index 0000000000000000000000000000000000000000..3924bd143a8930774276bbc2cb256df3821a51c5 --- /dev/null +++ b/modules/io/src/mol/entity_io_mae_handler.hh @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_IO_ENTITY_IO_PLUGIN_MAE_H +#define OST_IO_ENTITY_IO_PLUGIN_MAE_H + +#include <ost/io/mol/entity_io_handler.hh> + +#include <boost/iostreams/filtering_stream.hpp> +#include <boost/filesystem/fstream.hpp> + +namespace ost { namespace io { + +class DLLEXPORT_OST_IO MAEReader { +public: + MAEReader(const boost::filesystem::path& loc); + + void Import(mol::EntityHandle& ent); + +private: + + void add_atom(mol::EntityHandle ent, + mol::XCSEditor& editor,const std::string& s_aname, + const std::string& s_axpos, + const std::string& s_aypos, + const std::string& s_azpos, + const std::string& s_rname, + const std::string& s_rnum, + const std::string& s_cname); + + mol::ChainHandle curr_chain_; + mol::ResidueHandle curr_residue_; + int chain_count_; + int residue_count_; + int atom_count_; + boost::filesystem::ifstream infile_; + boost::iostreams::filtering_stream<boost::iostreams::input> in_; +}; + +class DLLEXPORT_OST_IO EntityIOMAEHandler: public EntityIOHandler { +public: + virtual void Import(mol::EntityHandle& ent, const boost::filesystem::path& loc); + + virtual void Export(const mol::EntityView& ent, + const boost::filesystem::path& loc) const; + + virtual void Import(mol::EntityHandle& ent, std::istream& stream); + + virtual void Export(const mol::EntityView& ent, std::ostream& stream) const; + + static bool ProvidesImport(const boost::filesystem::path& loc, + const String& format="auto"); + static bool ProvidesExport(const boost::filesystem::path& loc, + const String& format="auto"); + virtual bool RequiresBuilder() const; + + static String GetFormatName() { return String("Mae"); } + static String GetFormatDescription() { return String("MAEstro coordinate file format"); } +}; + + +typedef EntityIOHandlerFactory<EntityIOMAEHandler> EntityIOMAEHandlerFactory; + +mol::EntityHandle DLLEXPORT_OST_IO LoadMAE(const String& file_name); + +}} // ns + +#endif diff --git a/modules/io/src/mol/entity_io_pdb_handler.cc b/modules/io/src/mol/entity_io_pdb_handler.cc index ca64835e7372b51d8b7089d0197ce47cb04c6f96..99b8ea49560a7dbe9ef2ca79ab9dbbc855c94dbe 100644 --- a/modules/io/src/mol/entity_io_pdb_handler.cc +++ b/modules/io/src/mol/entity_io_pdb_handler.cc @@ -50,9 +50,12 @@ void EntityIOPDBHandler::Export(const mol::EntityView& ent, { PDBWriter writer(loc); if (boost::iequals(boost::filesystem::extension(loc), ".pqr")) { - writer.SetFlags(PDB::PQR_FORMAT); + PDB::PushFlags(PDB::Flags() | PDB::PQR_FORMAT); + writer.Write(ent); + PDB::PopFlags(); + } else { + writer.Write(ent); } - writer.Write(ent); } void EntityIOPDBHandler::Import(mol::EntityHandle& ent, diff --git a/modules/io/src/mol/pdb_io.hh b/modules/io/src/mol/pdb_io.hh index 140db87e3648055a3bff689f18657da8cceb820e..d9f3bc78ee50813cff776e1efa76452ae7a071be 100644 --- a/modules/io/src/mol/pdb_io.hh +++ b/modules/io/src/mol/pdb_io.hh @@ -19,22 +19,32 @@ #ifndef OST_IO_PDB_IO_HH #define OST_IO_PDB_IO_HH +#include <stack> + namespace ost { namespace io { /// \brief flags that incluence the behaviour of the PDBReader and PDBWriter struct PDB { - typedef enum { + + struct S { + static S& I(); + std::stack<unsigned int> fstack; + }; + /// \brief skip faulty records - /// /// This flag tells the PDB loader to ignore faulty records. By default, /// faulty records abort import. - SKIP_FAULTY_RECORDS=1, + static const unsigned int SKIP_FAULTY_RECORDS; + /// \brief do not import HETATM records - NO_HETATMS=2, + static const unsigned int NO_HETATMS; + /// \brief enable writing of multiple models - WRITE_MULTIPLE_MODELS=4, + static const unsigned int WRITE_MULTIPLE_MODELS; + /// \brief enable for PQR - PQR_FORMAT=8, + static const unsigned int PQR_FORMAT; + /// \brief Join atom records into one residue, even if the atom records /// are not sequential. /// @@ -57,20 +67,15 @@ struct PDB { /// /// By default, the atom 550 will start a new residue instead of being /// joined with atoms 43-48 into one residue. - JOIN_SPREAD_ATOM_RECORDS=16, - //// \brief keep track of the order of atom records - /// - /// This option is mostly useful in combination with - /// PDB::JOIN_SPREAD_ATOM_RECORDS and CoordGroups. - /// - /// The atoms are accessible via PDBReader::GetSequentialAtoms() - SEQUENTIAL_ATOM_IMPORT=32, + static const unsigned int JOIN_SPREAD_ATOM_RECORDS; + /// \brief only import C-alpha atoms - CALPHA_ONLY=64 - } Type; -}; + static const unsigned int CALPHA_ONLY; -typedef unsigned int PDBFlags; + static void PushFlags(unsigned int flags); + static unsigned int Flags(); + static void PopFlags(); +}; }} diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc index ec0dbaccb37e140bd8227659455beee97f516ad3..1ea6f6da8e0c2456f6e4503cfe851e15bf17740d 100644 --- a/modules/io/src/mol/pdb_reader.cc +++ b/modules/io/src/mol/pdb_reader.cc @@ -62,19 +62,19 @@ mol::ResNum to_res_num(int num, char ins_code) } PDBReader::PDBReader(std::istream& instream): - infile_(), instream_(instream), flags_(0) + infile_(), instream_(instream) { this->Init(boost::filesystem::path("")); } PDBReader::PDBReader(const String& filename) - : infile_(filename), instream_(infile_), flags_(0) + : infile_(filename), instream_(infile_) { this->Init(boost::filesystem::path(filename)); } PDBReader::PDBReader(const boost::filesystem::path& loc): - infile_(loc), instream_(infile_), flags_(0) + infile_(loc), instream_(infile_) { this->Init(loc); } @@ -106,7 +106,7 @@ bool PDBReader::HasNext() while (std::getline(in_, curr_line_) && ++line_num_) { StringRef curr_line(curr_line_.c_str(), curr_line_.length()); if (IEquals(curr_line.substr(0, 6), StringRef("ATOM ", 6)) || - (!(flags_ & PDB::NO_HETATMS) && + (!(PDB::Flags() & PDB::NO_HETATMS) && IEquals(curr_line.substr(0, 6),StringRef("HETATM ", 6))) || IEquals(curr_line.substr(0, 6),StringRef("ANISOU ", 6)) || IEquals(curr_line.substr(0, 6), StringRef("SHEET ", 6)) || @@ -123,6 +123,8 @@ bool PDBReader::HasNext() void PDBReader::Import(mol::EntityHandle& ent, const String& restrict_chains) { + LOGN_DEBUG("PDBReader: current flags: " << PDB::Flags()); + Profile profile_import("PDBReader::Import"); this->ClearState(); // first read curr_line and then read next... @@ -171,7 +173,7 @@ void PDBReader::Import(mol::EntityHandle& ent, continue; } if (IEquals(curr_line.substr(0, 6), StringRef("HETATM", 6))) { - if (flags_ & PDB::NO_HETATMS) + if (PDB::Flags() & PDB::NO_HETATMS) continue; LOGN_TRACE("processing HETATM entry"); this->ParseAndAddAtom(curr_line, line_num_, ent, @@ -250,17 +252,6 @@ void PDBReader::ClearState() hard_end_=false; helix_list_.clear(); strand_list_.clear(); - sequential_atom_list_.clear(); -} - -std::vector<mol::AtomHandle> PDBReader::GetSequentialAtoms() const -{ - return sequential_atom_list_; -} - -void PDBReader::SetFlags(PDBFlags flags) -{ - flags_=flags; } bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num, @@ -276,7 +267,7 @@ bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num, std::pair<bool, int> a_num=line.substr(6, 5).ltrim().to_int(); if (!a_num.first) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return false; } throw IOException(str(format("invalid atom number on line %d") %line_num)); @@ -286,7 +277,7 @@ bool PDBReader::ParseAtomIdent(const StringRef& line, int line_num, res_name=line.substr(17, 3).trim(); std::pair<bool, int> res_num=line.substr(22, 4).ltrim().to_int();; if (!res_num.first) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return false; } throw IOException(str(format("invalid res number on line %d") % line_num)); @@ -311,7 +302,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num, for (int i=0;i<6; ++i) { std::pair<bool, int> result=line.substr(29+i*7, 6).to_int(); if (!result.first) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return; } throw IOException(str(format("invalid ANISOU record on line %d")%line_num)); @@ -320,7 +311,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num, } String aname(atom_name.str()); if (!curr_residue_.IsValid()) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return; } const char* fmt_str="invalid ANISOU record for inexistent atom on line %d"; @@ -328,7 +319,7 @@ void PDBReader::ParseAnisou(const StringRef& line, int line_num, } mol::AtomHandle atom=curr_residue_.FindAtom(aname); if (!atom.IsValid()) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return; } const char* fmt_str="invalid ANISOU record for inexistent atom on line %d"; @@ -367,7 +358,7 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num, for (int i=0;i<3; ++i) { std::pair<bool, float> result=line.substr(30+i*8, 8).ltrim().to_float(); if (!result.first) { - if (flags_ & PDB::SKIP_FAULTY_RECORDS) { + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { return; } throw IOException(str(format("invalid coordinate on line %d")%line_num)); @@ -432,24 +423,31 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num, } if(update_chain) { - if (!(curr_chain_=ent.FindChain(s_chain))) { + curr_chain_=mol::ChainHandle(); +#if 0 + // TODO: should this depend on JOIN_SPREAD as well? + if (PDB::Flags() & PDB::JOIN_SPREAD_ATOM_RECORDS) { + curr_chain_=ent.FindChain(s_chain); + } +#else + curr_chain_=ent.FindChain(s_chain); +#endif + if(!curr_chain_.IsValid()) { LOGN_DUMP("new chain " << s_chain); curr_chain_=editor.InsertChain(s_chain); ++chain_count_; } + assert(curr_chain_.IsValid()); } if(update_residue) { - if (flags_ & PDB::JOIN_SPREAD_ATOM_RECORDS) { + curr_residue_=mol::ResidueHandle(); + if (PDB::Flags() & PDB::JOIN_SPREAD_ATOM_RECORDS) { curr_residue_=curr_chain_.FindResidue(res_num); - if (!curr_residue_.IsValid()) { - LOGN_DUMP("new residue " << res_name << " " << res_num); - curr_residue_=editor.AppendResidue(curr_chain_, res_name.str(), res_num); - ++residue_count_; - } - } else { + } + if (!curr_residue_.IsValid()) { LOGN_DUMP("new residue " << res_name << " " << res_num); curr_residue_=editor.AppendResidue(curr_chain_, res_name.str(), res_num); - ++residue_count_; + ++residue_count_; } assert(curr_residue_.IsValid()); } @@ -493,16 +491,22 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num, } else { mol::AtomHandle ah=editor.InsertAltAtom(curr_residue_, aname, String(1, alt_loc), apos, aprop); - if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) { + /* + for now, this is not needed - the cg will use an global atom id sorted + list insteadx + if (PDB::Flags() & PDB::SEQUENTIAL_ATOM_IMPORT) { sequential_atom_list_.push_back(ah); } + */ ++atom_count_; } } else { mol::AtomHandle ah = editor.InsertAtom(curr_residue_, aname, apos, aprop); - if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) { + /* + if (PDB::Flags() & PDB::SEQUENTIAL_ATOM_IMPORT) { sequential_atom_list_.push_back(ah); } + */ ++atom_count_; } } diff --git a/modules/io/src/mol/pdb_reader.hh b/modules/io/src/mol/pdb_reader.hh index 5c85e23a14a88e80d6229f728171914b9deaa6b9..6d9f715c6cd9071a471d33427464533bb6b29294 100644 --- a/modules/io/src/mol/pdb_reader.hh +++ b/modules/io/src/mol/pdb_reader.hh @@ -47,17 +47,7 @@ public: bool HasNext(); void Import(mol::EntityHandle& ent, - const String& restrict_chains=""); - void SetFlags(PDBFlags flags); - - /// \brief get list of atoms - /// - /// The atom handles reflect the order of atom records in the PDb files. This - /// is used to synchronize PDB and coordgroup io. - /// - /// By default, the atom list is empty, The PDB::SEQUENTIAL_ATOM_IMPORT flag - /// must be set. - std::vector<mol::AtomHandle> GetSequentialAtoms() const; + const String& restrict_chains=""); private: void ClearState(); @@ -90,8 +80,7 @@ private: std::istream& instream_; boost::iostreams::filtering_stream<boost::iostreams::input> in_; String curr_line_; - std::vector<mol::AtomHandle> sequential_atom_list_; - PDBFlags flags_; + // this needs to be set to true for reading pqr // file (i.e. pdb formatted file with charges in occupacy // column, and radii in b-factor column) diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index 9251f42b227ae6d8667724689f0b3a68d8dc81bd..a6b32d39636d278386fada049323629d4346bbf1 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -123,27 +123,20 @@ private: PDBWriter::PDBWriter(std::ostream& stream): outfile_(), outstream_(stream) -{ - -} +{} PDBWriter::PDBWriter(const boost::filesystem::path& filename): - outfile_(filename.file_string().c_str()), outstream_(outfile_), mol_count_(0), - flags_(0) -{ - -} + outfile_(filename.file_string().c_str()), outstream_(outfile_), mol_count_(0) +{} PDBWriter::PDBWriter(const String& filename): - outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0), flags_(0) -{ - -} + outfile_(filename.c_str()), outstream_(outfile_), mol_count_(0) +{} void PDBWriter::WriteModelLeader() { ++mol_count_; - if (flags_ & PDB::WRITE_MULTIPLE_MODELS) { + if (PDB::Flags() & PDB::WRITE_MULTIPLE_MODELS) { outstream_ << "MODEL " << mol_count_ << std::endl; } else if (mol_count_>1) { throw IOException("Please enable the PDB::WRITE_MULTIPLE_MODELS flag to " @@ -153,7 +146,7 @@ void PDBWriter::WriteModelLeader() void PDBWriter::WriteModelTrailer() { - if (flags_ & PDB::WRITE_MULTIPLE_MODELS) { + if (PDB::Flags() & PDB::WRITE_MULTIPLE_MODELS) { outstream_ << "ENDMDL" << std::endl; } } @@ -163,18 +156,13 @@ void PDBWriter::WriteModel(H ent) { this->WriteModelLeader(); PDBWriterImpl writer(outstream_); - if (flags_ & PDB::PQR_FORMAT) { + if (PDB::Flags() & PDB::PQR_FORMAT) { writer.SetIsPQR(true); } ent.Apply(writer); this->WriteModelTrailer(); } -void PDBWriter::SetFlags(PDBFlags flags) -{ - flags_=flags; -} - void PDBWriter::Write(const mol::EntityView& ent) { this->WriteModel(ent); @@ -199,7 +187,7 @@ void PDBWriter::Write(const mol::AtomHandleList& atoms) } last_chain=(*i).GetResidue().GetChain(); } - write_atom(outstream_, *i, counter, flags_ & PDB::PQR_FORMAT); + write_atom(outstream_, *i, counter, PDB::Flags() & PDB::PQR_FORMAT); } this->WriteModelTrailer(); } diff --git a/modules/io/src/mol/pdb_writer.hh b/modules/io/src/mol/pdb_writer.hh index 83f2f923e38ede6435bda01ab860a1421d907ec4..971890eeb66d75cba69453e1782a185b84a51d24 100644 --- a/modules/io/src/mol/pdb_writer.hh +++ b/modules/io/src/mol/pdb_writer.hh @@ -42,8 +42,6 @@ public: PDBWriter(const boost::filesystem::path& filename); PDBWriter(std::ostream& outstream); - void SetFlags(PDBFlags flags); - void Write(const mol::EntityView& ent); void Write(const mol::EntityHandle& ent); @@ -59,7 +57,6 @@ private: std::ofstream outfile_; std::ostream& outstream_; int mol_count_; - PDBFlags flags_; }; }} diff --git a/modules/mol/base/pymod/export_atom.cc b/modules/mol/base/pymod/export_atom.cc index 52983f3ae26775d4014f16028925230a4cc31420..ccebbfb0adf0f9b7eb3aba0f10ba914ef68e987c 100644 --- a/modules/mol/base/pymod/export_atom.cc +++ b/modules/mol/base/pymod/export_atom.cc @@ -46,6 +46,7 @@ void export_Atom() .def("GetProp", &AtomBase::GetProp, return_value_policy<copy_const_reference>()) .def("SetProp", &AtomBase::SetProp, args("prop")) + .def("GetIndex", &AtomBase::GetIndex) .add_property("prop", make_function(&AtomBase::GetProp, return_value_policy<copy_const_reference>())) @@ -56,6 +57,7 @@ void export_Atom() make_function(&AtomBase::GetName, return_value_policy<copy_const_reference>()), &AtomBase::SetName) + .add_property("index",&AtomBase::GetIndex) ; generic_prop_def<AtomBase>(atom_base); diff --git a/modules/mol/base/src/atom_base.cc b/modules/mol/base/src/atom_base.cc index 95141733ff27a4ab798e67d9aa814b1d7201aa58..9a8cfb1fc0ce1438612555e2909c7be900fc7558 100644 --- a/modules/mol/base/src/atom_base.cc +++ b/modules/mol/base/src/atom_base.cc @@ -156,5 +156,11 @@ int AtomBase::GetIntProperty(Prop::ID prop_id) const return Impl()->GetIntProperty(prop_id); } +unsigned long AtomBase::GetIndex() const +{ + this->CheckValidity(); + return Impl()->GetIndex(); +} + }} // ns diff --git a/modules/mol/base/src/atom_base.hh b/modules/mol/base/src/atom_base.hh index 0a17ce2508b7a904e92e738de0fe72fbf4a7249b..3b10fb8ca241ff4aa5c452d0b86a63c2bb848127 100644 --- a/modules/mol/base/src/atom_base.hh +++ b/modules/mol/base/src/atom_base.hh @@ -116,7 +116,10 @@ public: /// \brief Get int property by id int GetIntProperty(Prop::ID prop_id) const; -public: + + /// \brief Get the internal index + unsigned long GetIndex() const; + /// \brief get atom implementation. /// /// Intended for internal use. diff --git a/modules/mol/base/src/coord_frame.hh b/modules/mol/base/src/coord_frame.hh index 4a04ca4e45ef0be5a7785e72c6198f046a960e42..017a58865a239a10bc7869ab4a2380047a528c85 100644 --- a/modules/mol/base/src/coord_frame.hh +++ b/modules/mol/base/src/coord_frame.hh @@ -29,17 +29,10 @@ namespace ost { namespace mol { -class CoordFrame; - +typedef std::vector<geom::Vec3> CoordFrame; typedef boost::shared_ptr<CoordFrame> CoordFramePtr; typedef std::vector<CoordFramePtr> CoordFrameList; -class DLLEXPORT_OST_MOL CoordFrame : public std::vector<geom::Vec3> { -public: - CoordFrame() {} - CoordFrame(Real ts) {} -}; - }} #endif diff --git a/modules/mol/base/src/coord_source.cc b/modules/mol/base/src/coord_source.cc index a8d95ff1a9828a56663539407aa7df11ccf7b546..b25a91755d461be23870de214a5e592c038ece6a 100644 --- a/modules/mol/base/src/coord_source.cc +++ b/modules/mol/base/src/coord_source.cc @@ -20,6 +20,7 @@ /* Author: Marco Biasini */ +#include <ost/log.hh> #include <ost/mol/atom_handle.hh> #include <ost/mol/xcs_editor.hh> #include <ost/mol/in_mem_coord_source.hh> @@ -53,10 +54,12 @@ CoordSource::~CoordSource() void CoordSource::CopyFrame(uint frame_id) { if (atoms_.empty()) { + LOGN_DEBUG("atom list empty, ignored"); return; } CoordFramePtr frame=this->GetFrame(frame_id); if (!frame) { + LOGN_DEBUG("invalid frame given, ignored"); return; } assert(frame->size()==atoms_.size()); @@ -64,7 +67,7 @@ void CoordSource::CopyFrame(uint frame_id) CoordFrame::const_iterator c=frame->begin(); for (AtomHandleList::iterator i=atoms_.begin(), e=atoms_.end(); i!=e; ++i, ++c) { - edi.SetAtomPos(*i, *c); + edi.SetAtomPos(*i, *c); } } diff --git a/modules/mol/base/src/impl/atom_impl.cc b/modules/mol/base/src/impl/atom_impl.cc index d8e37b25c38fd459f6e9d1c41d940f9247dd5852..cb3ecf87a290166e78a14329655b9ff7a733698c 100644 --- a/modules/mol/base/src/impl/atom_impl.cc +++ b/modules/mol/base/src/impl/atom_impl.cc @@ -40,7 +40,8 @@ AtomImpl::AtomImpl(const EntityImplPtr& e, const ResidueImplPtr& r, const String& n, const geom::Vec3& p, - const AtomProp& prop): + const AtomProp& prop, + unsigned long index): res_(r), name_(n), pos_(p), @@ -48,7 +49,8 @@ AtomImpl::AtomImpl(const EntityImplPtr& e, prim_connector_(), connector_list_(), fragment_(), - state_(0) + state_(0), + index_(index) { EntityHandle ent = this->GetEntity(); geom::Mat4 transf_matrix = ent.GetTransformationMatrix(); diff --git a/modules/mol/base/src/impl/atom_impl.hh b/modules/mol/base/src/impl/atom_impl.hh index 3db9ff520d4cf7ce0bb03f540e8fa8687fc14339..f3c2cc1c03db42b317b49606c326979e5b473d46 100644 --- a/modules/mol/base/src/impl/atom_impl.hh +++ b/modules/mol/base/src/impl/atom_impl.hh @@ -50,7 +50,8 @@ class AtomImpl: public GenericPropertyContainerImpl, public boost::enable_shared_from_this<AtomImpl> { public: AtomImpl(const EntityImplPtr& ent, const ResidueImplPtr& res, - const String& name, const geom::Vec3& pos, const AtomProp& prop); + const String& name, const geom::Vec3& pos, const AtomProp& prop, + unsigned long index); ~AtomImpl(); void Apply(EntityVisitor& h); @@ -137,6 +138,9 @@ public: Real GetFloatProperty(Prop::ID prop_id) const; int GetIntProperty(Prop::ID prop_id) const; + + unsigned long GetIndex() const {return index_;} + void SetIndex(unsigned long index) {index_=index;} private: ResidueImplW res_; @@ -171,6 +175,8 @@ private: unsigned int mask = 0x1<<bit; return (state_ & mask)!=0; } + + unsigned long index_; }; /// \internal diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc index e17a5a76dbcd2b23047cd34df54ed6ac3a5dff61..4806c7cbd382511d9ffaea3fa0adb0c43a332208 100644 --- a/modules/mol/base/src/impl/entity_impl.cc +++ b/modules/mol/base/src/impl/entity_impl.cc @@ -76,7 +76,8 @@ EntityImpl::EntityImpl(): xcs_editor_count_(0), ics_editor_count_(0), dirty_flags_(DisableICS), - name_("") + name_(""), + next_index_(0L) { } @@ -350,9 +351,9 @@ AtomImplPtr EntityImpl::CreateAtom(const ResidueImplPtr& rp, { #if MAKE_SHARED_AVAILABLE AtomImplPtr ap=boost::make_shared<AtomImpl>(shared_from_this(), rp, name, - pos, prop); + pos, prop,next_index_++); #else - AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos, prop)); + AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos, prop,next_index_++)); #endif if (identity_transf_ == false) { geom::Vec3 transformed_pos = geom::Vec3(transformation_matrix_*geom::Vec4(pos)); diff --git a/modules/mol/base/src/impl/entity_impl.hh b/modules/mol/base/src/impl/entity_impl.hh index 4042e92975df4ad29d2b8c327d6f113aa0d8b0aa..ebe32704b8309441f87898b52d37bbbaf7fbbe43 100644 --- a/modules/mol/base/src/impl/entity_impl.hh +++ b/modules/mol/base/src/impl/entity_impl.hh @@ -268,6 +268,9 @@ private: int ics_editor_count_; int dirty_flags_; String name_; + + unsigned long next_index_; + template <bool always_true> EntityView do_selection(const EntityHandle&, const Query&, QueryFlags) const; }; diff --git a/modules/mol/base/src/in_mem_coord_source.cc b/modules/mol/base/src/in_mem_coord_source.cc index 98417d1594aa55ba4f26a0a9cfaa208c1fe2ad3f..089c667bd1971f1a7ea6ee7c77d807deaeeb3d8e 100644 --- a/modules/mol/base/src/in_mem_coord_source.cc +++ b/modules/mol/base/src/in_mem_coord_source.cc @@ -27,8 +27,8 @@ void InMemCoordSource::AddFrame(const CoordFramePtr& frame) void InMemCoordSource::AddFrame(const std::vector<geom::Vec3>& coords) { - frames_.push_back(CoordFramePtr(new CoordFrame(0.0))); - frames_.back()->insert(frames_.back()->end(), coords.begin(), coords.end()); + CoordFramePtr fp(new CoordFrame(coords)); + frames_.push_back(fp); } }} diff --git a/modules/mol/base/tests/test_entity.cc b/modules/mol/base/tests/test_entity.cc index 8deba9b01bad9b3a814daee98736ef1e8d0b465f..0504422946e34546f0c3dee532bb05de4fbd232a 100644 --- a/modules/mol/base/tests/test_entity.cc +++ b/modules/mol/base/tests/test_entity.cc @@ -95,10 +95,12 @@ BOOST_AUTO_TEST_CASE(entity_creator) AtomHandle atom1 = e.InsertAtom(res, "X1",geom::Vec3()); BOOST_CHECK(res==atom1.GetResidue()); BOOST_CHECK(atom1.GetName()=="X1"); + BOOST_CHECK(atom1.GetIndex()==0); AtomHandle atom2 = e.InsertAtom(res, "X2",geom::Vec3()); BOOST_CHECK(res==atom2.GetResidue()); BOOST_CHECK(atom2.GetName()=="X2"); + BOOST_CHECK(atom2.GetIndex()==1); BondHandle bond = e.Connect(atom1, atom2);