diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst
index 78e126def7cf2b67171435e5c2f9efe49ee43de2..bed692ff4bc7e137e71c0ee1a8e18dfe8a0d9419 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 447761e76bebe047f6fb1fdc674ca8f2cd6d38fa..dd90843e39fa7a32ed661975b208ea6325e7f7db 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 49cd8e16c9901a6d2132ca91c2b7d66f7e11f19d..0a00a838258de949f47c1796a9c70c93b284ef1e 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 abd02fe6e153746cc2df08c56cfdb60c698e8880..1c971ee2fa6ee08101d9303cd09e7bda21c1a9bc 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 55a195652092481182c644dd3f936e7b3593b2bc..3503223eb5e543088b93b44749cdd2edd508c494 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 83cba518f76fd002405e1a0f789fb43afc4b5f22..fb87382d106a3742a4ca3e0eee908da57cd4f394 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 68b2fbb5769c6e735ec7e30cb7311f002f9b3346..9bd8159d6215e3bf3c1dac4a6fae03f0c73c2375 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_