diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index da840874e29de801134a25a648a83eca6911499a..c5a0a164587a328253cf8a970a5bf557084daf38 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -34,6 +34,13 @@ of the annotation available. Also available as :meth:`GetCitations`. + .. attribute:: method + + Stores the experimental method used to create the structure. + + Also available as :meth:`GetMethod`. May also be modified by + :meth:`SetMethod`. + .. method:: AddCitation(citation) Add a citation to the citation list of an info object. @@ -54,6 +61,14 @@ of the annotation available. See :attr:`citations` + .. method:: SetMethod(method) + + See :attr:`method` + + .. method:: GetMethod() + + See :attr:`method` + .. class:: MMCifInfoCitation This stores citation information from an input file. diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc index 4e1a7e60af45d51fa8b03c2ab92c887eb5f42374..06cba8423ca595ae9c6e7f5889704eca888c33ab 100644 --- a/modules/io/pymod/export_mmcif_io.cc +++ b/modules/io/pymod/export_mmcif_io.cc @@ -106,8 +106,11 @@ void export_mmcif_io() .def("AddCitation", &MMCifInfo::AddCitation) .def("GetCitations", make_function(&MMCifInfo::GetCitations, return_value_policy<copy_const_reference>())) + .def("SetMethod", &MMCifInfo::SetMethod) + .def("GetMethod", &MMCifInfo::GetMethod) .def("AddAuthorsToCitation", &MMCifInfo::AddAuthorsToCitation) .add_property("citations", make_function(&MMCifInfo::GetCitations, return_value_policy<copy_const_reference>())) + .add_property("method", &MMCifInfo::GetMethod, &MMCifInfo::SetMethod) ; } diff --git a/modules/io/src/mol/mmcif_info.hh b/modules/io/src/mol/mmcif_info.hh index 70624d4f74eb0356f8f618cc2d496357451fa90e..37e8969754d1e31d6d6559669e8ea195cb562f3b 100644 --- a/modules/io/src/mol/mmcif_info.hh +++ b/modules/io/src/mol/mmcif_info.hh @@ -245,7 +245,7 @@ private: class DLLEXPORT_OST_IO MMCifInfo { public: /// \brief Create an info object. - MMCifInfo() {}; + MMCifInfo(): exptl_method_("") {}; /// \brief Add an item to the list of citations /// @@ -269,10 +269,24 @@ public: return citations_; } + /// \brief Set an experimental method. + /// + /// \param method Method description + void SetMethod(String method) { exptl_method_ = method; } + + /// \brief Get an experimental method. + /// + /// \return Method description + const StringRef GetMethod() const + { + return StringRef(exptl_method_.c_str(), exptl_method_.length()); + } + //protected: private: // members + String exptl_method_; std::vector<MMCifInfoCitation> citations_; ///< list of citations }; diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index 5b85c1340ec990377e9f66deea17ea5620f2ecfe..9f99c0b6e625fba1d24fb5a0b3ab58948aaff8b2 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -196,9 +196,13 @@ bool MMCifParser::OnBeginLoop(const StarLoopDesc& header) this->TryStoreIdx(AUTHOR_NAME, "name", header); this->TryStoreIdx(ORDINAL, "ordinal", header); cat_available = true; - } /* -else if (header.GetCategory()=="pdbx_struct_assembly") { - } else if (header.GetCategory()=="struct_conf") { + } else if (header.GetCategory() == "exptl") { + category_ = EXPTL; + // mandatory items + this->TryStoreIdx(CITATION_ID, "entry_id", header); + this->TryStoreIdx(METHOD, "method", header); + cat_available = true; + } /* else if (header.GetCategory()=="struct_conf") { }*/ category_counts_[category_]++; return cat_available; @@ -704,6 +708,11 @@ void MMCifParser::ParseCitationAuthor(const std::vector<StringRef>& columns) } } +void MMCifParser::ParseExptl(const std::vector<StringRef>& columns) +{ + info_.SetMethod(columns[indices_[METHOD]].str()); +} + void MMCifParser::OnDataRow(const StarLoopDesc& header, const std::vector<StringRef>& columns) { @@ -728,6 +737,10 @@ void MMCifParser::OnDataRow(const StarLoopDesc& header, LOG_TRACE("processing citation_author entry") this->ParseCitationAuthor(columns); break; + case EXPTL: + LOG_TRACE("processing exptl entry") + this->ParseExptl(columns); + break; default: throw IOException(this->FormatDiagnostic(STAR_DIAG_ERROR, "Uncatched category '"+ header.GetCategory() +"' found.", diff --git a/modules/io/src/mol/mmcif_reader.hh b/modules/io/src/mol/mmcif_reader.hh index ecd9f31a39a0982dc8d0f5f65f8001056bbce00f..1376abee23cfafc16e7eb0ad33685263a282fd36 100644 --- a/modules/io/src/mol/mmcif_reader.hh +++ b/modules/io/src/mol/mmcif_reader.hh @@ -226,6 +226,11 @@ protected: /// \param columns data row void ParseCitationAuthor(const std::vector<StringRef>& columns); + /// \brief Fetch MMCif exptl information + /// + /// \param columns data row + void ParseExptl(const std::vector<StringRef>& columns); + private: /// \enum magic numbers of this class typedef enum { @@ -293,6 +298,12 @@ private: ORDINAL ///< position in author list } CitationAuthorItems; + /// \enum items of the exptl category + typedef enum { + EXPTL_ENTRY_ID, ///< identifier + METHOD ///< method of the experiment + } ExptlItems; + /// \enum categories of the mmcif format typedef enum { ATOM_SITE, @@ -300,6 +311,7 @@ private: ENTITY_POLY, CITATION, CITATION_AUTHOR, + EXPTL, DONT_KNOW } MMCifCategory; diff --git a/modules/io/tests/test_io_mmcif.py b/modules/io/tests/test_io_mmcif.py index 47c52b7ece410092f5e4f46464680f143be3af1f..fd5671262c892b25029cbc49790d0f6977c7a93c 100644 --- a/modules/io/tests/test_io_mmcif.py +++ b/modules/io/tests/test_io_mmcif.py @@ -47,6 +47,7 @@ class TestPDB(unittest.TestCase): self.assertEquals(s2[0], 'Foo') i = io.MMCifInfo() + i.SetMethod('Deep-Fry') i.AddCitation(c) s.append('Bar') i.AddAuthorsToCitation('ID', s) @@ -58,6 +59,8 @@ class TestPDB(unittest.TestCase): self.assertEquals(al[0], 'Foo') self.assertEquals(al[1], 'Bar') + self.assertEquals(i.GetMethod(), 'Deep-Fry') + if __name__== '__main__': unittest.main() diff --git a/modules/io/tests/test_mmcif_info.cc b/modules/io/tests/test_mmcif_info.cc index 97346d7ff5ee6b6bbc090822497b3d391a634da9..d5e1aa3d4c5f405de7a98e8c6f0a9fbeb338d5de 100644 --- a/modules/io/tests/test_mmcif_info.cc +++ b/modules/io/tests/test_mmcif_info.cc @@ -79,4 +79,17 @@ BOOST_AUTO_TEST_CASE(mmcif_info_citation) BOOST_MESSAGE(" done."); } +BOOST_AUTO_TEST_CASE(mmcif_info) +{ + BOOST_MESSAGE(" Running mmcif_info tests..."); + + MMCifInfo info = MMCifInfo(); + + info.SetMethod("Cooking."); + BOOST_CHECK(info.GetMethod() == StringRef("Cooking.", 8)); + + BOOST_MESSAGE(" done."); +} + + BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/test_mmcif_reader.cc b/modules/io/tests/test_mmcif_reader.cc index d534e834a072416f086dc85cd5e8201483424d12..42b44d38ff547f45227e9218021fd97f3d59acae 100644 --- a/modules/io/tests/test_mmcif_reader.cc +++ b/modules/io/tests/test_mmcif_reader.cc @@ -664,6 +664,10 @@ BOOST_AUTO_TEST_CASE(mmcif_testreader) BOOST_MESSAGE(" done."); + BOOST_MESSAGE(" reading data fields which should not fail..."); + BOOST_CHECK(mmcif_p.GetInfo().GetMethod().str() == "Deep-fry"); + BOOST_MESSAGE(" done."); + BOOST_MESSAGE(" done."); } diff --git a/modules/io/tests/testfiles/mmcif/atom_site.mmcif b/modules/io/tests/testfiles/mmcif/atom_site.mmcif index 2d2322af617a75d450de0f054869b5dbe5d38830..6ada7db03d34b2131f5afc4e824780679235eb73 100644 --- a/modules/io/tests/testfiles/mmcif/atom_site.mmcif +++ b/modules/io/tests/testfiles/mmcif/atom_site.mmcif @@ -43,6 +43,9 @@ _citation_author.name primary 3 'Van Hummel, J.F.' primary 2 'McCheese, B.M.' +_exptl.entry_id experiment1 +_exptl.method 'Deep-fry' + loop_ _atom_site.group_PDB _atom_site.type_symbol