diff --git a/modules/io/pymod/export_omf_io.cc b/modules/io/pymod/export_omf_io.cc
index ba10cfb6cafb7f43e7cd98502021dc530f3e7f00..b50392dc09ce99de19489f493d1908d681501cd8 100644
--- a/modules/io/pymod/export_omf_io.cc
+++ b/modules/io/pymod/export_omf_io.cc
@@ -26,6 +26,16 @@ using namespace ost::io;
 
 namespace{
 
+  template<typename T>
+  boost::python::list VecToList(const std::vector<T>& vec){
+    boost::python::list l;
+    for(typename std::vector<T>::const_iterator it=vec.begin();
+        it!=vec.end(); ++it){
+      l.append(*it);
+    }
+    return l;
+  }
+
   PyObject* wrap_to_bytes(OMFPtr omf) {
     String str = omf->ToString();
     return PyBytes_FromStringAndSize(str.c_str(), str.size());
@@ -36,6 +46,10 @@ namespace{
     return OMF::FromString(str);
   }
 
+  boost::python::list wrap_get_chain_names(OMFPtr omf) {
+    return VecToList<String>(omf->GetChainNames());
+  }
+
 }
 
 void export_omf_io() {
@@ -59,5 +73,9 @@ void export_omf_io() {
     .def("GetAU", &OMF::GetAU)
     .def("GetAUChain", &OMF::GetAUChain)
     .def("GetBU", &OMF::GetBU)
+    .def("GetChainNames", &wrap_get_chain_names)
+    .def("GetPositions", &OMF::GetPositions, return_value_policy<reference_existing_object>(),(arg("cname")))
+    .def("GetBFactors", &OMF::GetBFactors, return_value_policy<reference_existing_object>(),(arg("cname")))
+    .def("GetSequence", &OMF::GetSequence, (arg("cname")))
   ;
 }
diff --git a/modules/io/src/mol/omf.cc b/modules/io/src/mol/omf.cc
index 2ddda6b9da73cc42cc2f3b795caffb008d750984..f6a75c90e6516e6614556de6f2dc3f978e91a7ad 100644
--- a/modules/io/src/mol/omf.cc
+++ b/modules/io/src/mol/omf.cc
@@ -3653,6 +3653,43 @@ void OMF::FillChain(ost::mol::ChainHandle& chain, ost::mol::XCSEditor& ed,
       }
     }
   }
-} 
+}
+
+std::vector<String> OMF::GetChainNames() const{
+  std::vector<String> chain_names;
+  for(auto it = chain_data_.begin(); it != chain_data_.end(); ++it) {
+    chain_names.push_back(it->first);
+  }
+  return chain_names;
+}
+
+const geom::Vec3List& OMF::GetPositions(const String& cname) const {
+  auto it = chain_data_.find(cname);
+  if(it == chain_data_.end()) {
+    throw ost::Error("Provided chain name not in OMF structure");
+  }
+  return it->second->positions;
+}
+
+const std::vector<Real>& OMF::GetBFactors(const String& cname) const {
+  auto it = chain_data_.find(cname);
+  if(it == chain_data_.end()) {
+    throw ost::Error("Provided chain name not in OMF structure");
+  }
+  return it->second->bfactors;
+}
+
+String OMF::GetSequence(const String& cname) const {
+  auto it = chain_data_.find(cname);
+  if(it == chain_data_.end()) {
+    throw ost::Error("Provided chain name not in OMF structure");
+  }
+  const std::vector<int>& indices = it->second->res_def_indices;
+  String sequence(indices.size(), 'X');
+  for(size_t i = 0; i < indices.size(); ++i) {
+    sequence[i] = residue_definitions_[indices[i]].olc;
+  }
+  return sequence;
+}
 
 }} //ns
diff --git a/modules/io/src/mol/omf.hh b/modules/io/src/mol/omf.hh
index 151550ebbe055b65241edcdbef5bace24a1d3743..e049e53482d65124b85c26e8a1b3b969c767c858 100644
--- a/modules/io/src/mol/omf.hh
+++ b/modules/io/src/mol/omf.hh
@@ -188,6 +188,16 @@ public:
 
   static int GetCurrentOMFVersion() { return OMF_VERSION; }
 
+  // data access without requirement of generating a full
+  // OpenStructure entity
+  std::vector<String> GetChainNames() const;
+
+  const geom::Vec3List& GetPositions(const String& cname) const;
+
+  const std::vector<Real>& GetBFactors(const String& cname) const;
+
+  String GetSequence(const String& cname) const;
+
 private:
   // only construct with static functions
   OMF(): options_(0) { }