From 00780ed46f29c5e7be028af883b91f8c0824c780 Mon Sep 17 00:00:00 2001 From: Gerardo Tauriello <gerardo.tauriello@unibas.ch> Date: Thu, 27 Jul 2017 18:55:34 +0200 Subject: [PATCH] SCHWED-2592: Extract rFree and rWork from mmCIF files --- modules/io/doc/mmcif.rst | 22 ++++++++++++++-- modules/io/pymod/export_mmcif_io.cc | 6 +++++ modules/io/src/mol/mmcif_info.hh | 24 ++++++++++++++++- modules/io/src/mol/mmcif_reader.cc | 26 ++++++++++++++----- modules/io/src/mol/mmcif_reader.hh | 4 ++- modules/io/tests/test_mmcif_reader.cc | 8 +++--- .../io/tests/testfiles/mmcif/atom_site.mmcif | 8 +++--- 7 files changed, 80 insertions(+), 18 deletions(-) diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index 78e126def..bed692ff4 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -25,7 +25,8 @@ The following categories of a mmCIF file are considered by the reader: * ``citation``: Goes into :class:`MMCifInfoCitation` * ``citation_author``: Goes into :class:`MMCifInfoCitation` * ``exptl``: Goes into :class:`MMCifInfo` as :attr:`~MMCifInfo.method`. -* ``refine``: Goes into :class:`MMCifInfo` as :attr:`~MMCifInfo.resolution`. +* ``refine``: Goes into :class:`MMCifInfo` as :attr:`~MMCifInfo.resolution`, + :attr:`~MMCifInfo.r_free` and :attr:`~MMCifInfo.r_work`. * ``pdbx_struct_assembly``: Used for :class:`MMCifInfoBioUnit`. * ``pdbx_struct_assembly_gen``: Used for :class:`MMCifInfoBioUnit`. * ``pdbx_struct_oper_list``: Used for :class:`MMCifInfoBioUnit`. @@ -93,11 +94,28 @@ of the annotation available. .. attribute:: resolution - Stores the resolution of the crystal structure. + Stores the resolution of the crystal structure. Set to 0 if no value in + loaded mmCIF file. Also available as :meth:`GetResolution`. May also be modified by :meth:`SetResolution`. + .. attribute:: r_free + + Stores the R-free value of the crystal structure. Set to 0 if no value in + loaded mmCIF file. + + Also available as :meth:`GetRFree`. May also be modified by + :meth:`SetRFree`. + + .. attribute:: r_work + + Stores the R-work value of the crystal structure. Set to 0 if no value in + loaded mmCIF file. + + Also available as :meth:`GetRWork`. May also be modified by + :meth:`SetRWork`. + .. attribute:: operations Stores the operations needed to transform a crystal structure into a diff --git a/modules/io/pymod/export_mmcif_io.cc b/modules/io/pymod/export_mmcif_io.cc index 447761e76..dd90843e3 100644 --- a/modules/io/pymod/export_mmcif_io.cc +++ b/modules/io/pymod/export_mmcif_io.cc @@ -310,6 +310,10 @@ void export_mmcif_io() .def("GetMethod", &MMCifInfo::GetMethod) .def("SetResolution", &MMCifInfo::SetResolution) .def("GetResolution", &MMCifInfo::GetResolution) + .def("SetRFree", &MMCifInfo::SetRFree) + .def("GetRFree", &MMCifInfo::GetRFree) + .def("SetRWork", &MMCifInfo::SetRWork) + .def("GetRWork", &MMCifInfo::GetRWork) .def("AddAuthorsToCitation", &MMCifInfo::AddAuthorsToCitation) .def("AddOperation", &MMCifInfo::AddOperation) .def("GetOperations", make_function(&MMCifInfo::GetOperations, @@ -334,6 +338,8 @@ void export_mmcif_io() .add_property("method", &MMCifInfo::GetMethod, &MMCifInfo::SetMethod) .add_property("resolution", &MMCifInfo::GetResolution, &MMCifInfo::SetResolution) + .add_property("r_free", &MMCifInfo::GetRFree, &MMCifInfo::SetRFree) + .add_property("r_work", &MMCifInfo::GetRWork, &MMCifInfo::SetRWork) .add_property("operations", make_function(&MMCifInfo::GetOperations, return_value_policy<copy_const_reference>())) .add_property("struct_details", &MMCifInfo::GetStructDetails, diff --git a/modules/io/src/mol/mmcif_info.hh b/modules/io/src/mol/mmcif_info.hh index 49cd8e16c..0a00a8382 100644 --- a/modules/io/src/mol/mmcif_info.hh +++ b/modules/io/src/mol/mmcif_info.hh @@ -869,7 +869,7 @@ private: class DLLEXPORT_OST_IO MMCifInfo { public: /// \brief Create an info object. - MMCifInfo(): exptl_method_(""), resolution_(0.0f) {}; + MMCifInfo(): exptl_method_(""), resolution_(0), r_free_(0), r_work_(0) { } /// \brief Add an item to the list of citations /// @@ -916,6 +916,26 @@ public: /// \return experiment resolution Real GetResolution() const { return resolution_; } + /// \brief Set R-free value. + /// + /// \param res experiment R-free value + void SetRFree(Real r_free) { r_free_ = r_free; } + + /// \brief Get R-free value. + /// + /// \return experiment R-free value + Real GetRFree() const { return r_free_; } + + /// \brief Set R-work value. + /// + /// \param r_work experiment R-work value + void SetRWork(Real r_work) { r_work_ = r_work; } + + /// \brief Get R-work value. + /// + /// \return experiment R-work value + Real GetRWork() const { return r_work_; } + /// \brief Add a new mmCIF/ PDB chain name tuple. /// /// \param cif chain name as used by the mmCIF file (label_asym_id) @@ -1049,6 +1069,8 @@ private: // members String exptl_method_; Real resolution_; + Real r_free_; + Real r_work_; MMCifInfoStructDetails struct_details_; ///< mmCIF struct category MMCifInfoObsolete obsolete_; ///< obsolete/ superseded entry MMCifInfoRevisions revisions_; ///< list of revisions diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index abd02fe6e..1c971ee2f 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -219,9 +219,12 @@ bool MMCifReader::OnBeginLoop(const StarLoopDesc& header) } else if (header.GetCategory() == "refine") { category_ = REFINE; // mandatory items - this->TryStoreIdx(REFINE_ENTRY_ID, "entry_id", header); - this->TryStoreIdx(LS_D_RES_HIGH, "ls_d_res_high", header); - this->TryStoreIdx(LS_D_RES_LOW, "ls_d_res_low", header); + this->TryStoreIdx(LS_D_RES_HIGH, "ls_d_res_high", header); + // optional items + indices_[REFINE_ENTRY_ID] = header.GetIndex("entry_id"); + indices_[LS_D_RES_LOW] = header.GetIndex("ls_d_res_low"); + indices_[LS_R_FACTOR_R_WORK] = header.GetIndex("ls_R_factor_R_work"); + indices_[LS_R_FACTOR_R_FREE] = header.GetIndex("ls_R_factor_R_free"); cat_available = true; } else if (header.GetCategory() == "pdbx_struct_assembly") { category_ = PDBX_STRUCT_ASSEMBLY; @@ -909,10 +912,21 @@ void MMCifReader::ParseExptl(const std::vector<StringRef>& columns) void MMCifReader::ParseRefine(const std::vector<StringRef>& columns) { - StringRef col=columns[indices_[LS_D_RES_HIGH]]; + StringRef col = columns[indices_[LS_D_RES_HIGH]]; if (col.size()!=1 || (col[0]!='?' && col[0]!='.')) { - info_.SetResolution(this->TryGetReal(columns[indices_[LS_D_RES_HIGH]], - "refine.ls_d_res_high")); + info_.SetResolution(this->TryGetReal(col, "refine.ls_d_res_high")); + } + if (indices_[LS_R_FACTOR_R_WORK] != -1) { + col = columns[indices_[LS_R_FACTOR_R_WORK]]; + if (col.size()!=1 || (col[0]!='?' && col[0]!='.')) { + info_.SetRWork(this->TryGetReal(col, "refine.ls_R_factor_R_work")); + } + } + if (indices_[LS_R_FACTOR_R_FREE] != -1) { + col = columns[indices_[LS_R_FACTOR_R_FREE]]; + if (col.size()!=1 || (col[0]!='?' && col[0]!='.')) { + info_.SetRFree(this->TryGetReal(col, "refine.ls_R_factor_R_free")); + } } } diff --git a/modules/io/src/mol/mmcif_reader.hh b/modules/io/src/mol/mmcif_reader.hh index 55a195652..3503223eb 100644 --- a/modules/io/src/mol/mmcif_reader.hh +++ b/modules/io/src/mol/mmcif_reader.hh @@ -427,7 +427,9 @@ private: typedef enum { REFINE_ENTRY_ID, ///< id LS_D_RES_HIGH, ///< crystal resolution - LS_D_RES_LOW + LS_D_RES_LOW, + LS_R_FACTOR_R_WORK, ///< R-work value + LS_R_FACTOR_R_FREE ///< R-free value } RefineItems; /// \enum items of the pdbx_struct_assembly category diff --git a/modules/io/tests/test_mmcif_reader.cc b/modules/io/tests/test_mmcif_reader.cc index 83cba518f..fb87382d1 100644 --- a/modules/io/tests/test_mmcif_reader.cc +++ b/modules/io/tests/test_mmcif_reader.cc @@ -678,11 +678,9 @@ BOOST_AUTO_TEST_CASE(mmcif_refine_tests) IOProfile profile; MMCifReader mmcif_p(s, eh, profile); BOOST_REQUIRE_NO_THROW(mmcif_p.Parse()); - #if OST_DOUBLE_PRECISION - BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetResolution(), 2.0, 0.001); - #else - BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetResolution(), 2.0f, 0.001f); - #endif + BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetResolution(), Real(2), Real(0.001)); + BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetRFree(), Real(0.229), Real(0.01)); + BOOST_CHECK_CLOSE(mmcif_p.GetInfo().GetRWork(), Real(0.200), Real(0.01)); } BOOST_TEST_MESSAGE(" done."); BOOST_TEST_MESSAGE(" capturing fishy data lines..."); diff --git a/modules/io/tests/testfiles/mmcif/atom_site.mmcif b/modules/io/tests/testfiles/mmcif/atom_site.mmcif index 68b2fbb57..9bd8159d6 100644 --- a/modules/io/tests/testfiles/mmcif/atom_site.mmcif +++ b/modules/io/tests/testfiles/mmcif/atom_site.mmcif @@ -51,9 +51,11 @@ _citation_author.name _exptl.entry_id experiment1 _exptl.method 'Deep-fry' -_refine.entry_id '1BAR' -_refine.ls_d_res_high 2.0 -_refine.ls_d_res_low 1.5 +_refine.entry_id '1BAR' +_refine.ls_d_res_high 2.0 +_refine.ls_d_res_low 1.5 +_refine.ls_R_factor_R_work 0.200 +_refine.ls_R_factor_R_free 0.229 # biounit begin loop_ -- GitLab