diff --git a/modules/mol/alg/pymod/CMakeLists.txt b/modules/mol/alg/pymod/CMakeLists.txt
index 7efbf88165105ae87c97d3b9aacd23e923e29060..045842de1152a5f5d655e2c90f614d41b1ddf574 100644
--- a/modules/mol/alg/pymod/CMakeLists.txt
+++ b/modules/mol/alg/pymod/CMakeLists.txt
@@ -5,6 +5,7 @@ set(OST_MOL_ALG_PYMOD_SOURCES
   export_trajectory_analysis.cc
   export_structure_analysis.cc
   export_contact_overlap.cc
+  export_accessibility.cc
 )
 
 set(OST_MOL_ALG_PYMOD_MODULES
diff --git a/modules/mol/alg/pymod/export_accessibility.cc b/modules/mol/alg/pymod/export_accessibility.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cecd75b551d9cfdecb6fc6b3b15b3cb7db928646
--- /dev/null
+++ b/modules/mol/alg/pymod/export_accessibility.cc
@@ -0,0 +1,85 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2017 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
+//------------------------------------------------------------------------------
+
+
+#include <boost/python.hpp>
+
+#include <ost/mol/alg/accessibility.hh>
+
+using namespace boost::python;
+
+namespace{
+
+Real WrapAccessibilityHandle(ost::mol::EntityHandle& ent, 
+                             Real probe_radius, 
+                             bool include_hydrogens, 
+                             bool include_hetatm,
+                             bool include_water,
+                             const String& selection,
+                             const String& asa_abs, 
+                             const String& asa_rel,
+                             const String& asa_atom) {
+                                 
+  return ost::mol::alg::Accessibility(ent, probe_radius, include_hydrogens, 
+                                      include_hetatm, include_water,
+                                      selection, asa_abs, asa_rel, asa_atom);
+}
+
+Real WrapAccessibilityView(ost::mol::EntityView& ent, 
+                           Real probe_radius, 
+                           bool include_hydrogens, 
+                           bool include_hetatm,
+                           bool include_water,
+                           const String& selection,
+                           const String& asa_abs, const String& asa_rel,
+                           const String& asa_atom) {
+
+  return ost::mol::alg::Accessibility(ent, probe_radius, include_hydrogens, 
+                                      include_hetatm, include_water, 
+                                      selection, asa_abs, asa_rel, asa_atom);
+}
+
+} // ns
+
+
+
+
+void export_accessibility() {
+
+    def("Accessibility", WrapAccessibilityHandle, (arg("ent"), 
+                                                   arg("probe_radius")=1.4,
+                                                   arg("include_hydrogens")=false,
+                                                   arg("include_hetatm")=false,
+                                                   arg("include_water")=false,
+                                                   arg("selection")="",
+                                                   arg("asa_abs")="asaAbs",
+                                                   arg("asa_rel")="asaRel",
+                                                   arg("asa_atom")="asaAtom"));
+
+    def("Accessibility", WrapAccessibilityView, (arg("ent"), 
+                                                 arg("probe_radius")=1.4,
+                                                 arg("include_hydrogens")=false,
+                                                 arg("include_hetatm")=false,
+                                                 arg("include_water")=false,
+                                                 arg("selection")="",
+                                                 arg("asa_abs")="asaAbs",
+                                                 arg("asa_rel")="asaRel",
+                                                 arg("asa_atom")="asaAtom"));
+}
+
diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc
index acd951f1a6413536d26ef05c08d957f75c953ab1..00eb51cb35657fba1826eea45525f42fbfe7800a 100644
--- a/modules/mol/alg/pymod/wrap_mol_alg.cc
+++ b/modules/mol/alg/pymod/wrap_mol_alg.cc
@@ -40,6 +40,7 @@ void export_TrajectoryAnalysis();
 void export_StructureAnalysis();
 void export_Clash();
 void export_contact_overlap();
+void export_accessibility();
 #if OST_IMG_ENABLED
 void export_entity_to_density();
 #endif
@@ -109,6 +110,7 @@ BOOST_PYTHON_MODULE(_ost_mol_alg)
   export_StructureAnalysis();
   export_Clash();
   export_contact_overlap();
+  export_accessibility();
   #if OST_IMG_ENABLED
   export_entity_to_density();
   #endif
diff --git a/modules/mol/alg/src/CMakeLists.txt b/modules/mol/alg/src/CMakeLists.txt
index 8f2038f96f4ab2dc03bcb9bd4624ca78a3f2003f..bd74affe8c31c2e1f246a3a1a88f34002f1208da 100644
--- a/modules/mol/alg/src/CMakeLists.txt
+++ b/modules/mol/alg/src/CMakeLists.txt
@@ -18,6 +18,7 @@ set(OST_MOL_ALG_HEADERS
   contact_overlap.hh
   domain_find.hh
   similarity_matrix.hh
+  accessibility.hh
 )
 
 set(OST_MOL_ALG_SOURCES
@@ -39,6 +40,7 @@ set(OST_MOL_ALG_SOURCES
   contact_overlap.cc
   domain_find.cc
   similarity_matrix.cc
+  accessibility.cc
 )
 
 set(MOL_ALG_DEPS ost_mol ost_seq)
diff --git a/modules/mol/alg/src/accessibility.cc b/modules/mol/alg/src/accessibility.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4d5e971eb48bad70465b650bee5a8838cfe68f94
--- /dev/null
+++ b/modules/mol/alg/src/accessibility.cc
@@ -0,0 +1,796 @@
+#include <ost/mol/alg/accessibility.hh>
+
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <cmath>
+#include <ost/mol/residue_view.hh>
+#include <ost/mol/atom_view.hh>
+
+namespace{
+
+struct Cube {
+  
+  Cube() {
+    particle_indices.reserve(20);
+  }
+
+  void AddIndex(int idx) { particle_indices.push_back(idx); }
+  const std::vector<int>& GetIndices() const { return particle_indices; };  
+
+  std::vector<int> particle_indices;
+};
+
+struct CubeGrid {
+  CubeGrid(Real cel, int x_cubes, int y_cubes, int z_cubes,
+           Real x_min, Real y_min, Real z_min): cube_edge_length(cel),
+                                                   x_cubes(x_cubes),
+                                                   y_cubes(y_cubes),
+                                                   z_cubes(z_cubes),
+                                                   x_min(x_min),
+                                                   y_min(y_min),
+                                                   z_min(z_min) {
+    int num_cubes = x_cubes * y_cubes * z_cubes;
+    cubes = new Cube*[num_cubes];
+    // assign NULL to each cube
+    for(int i = 0; i < num_cubes; ++i) {
+      cubes[i] = NULL;
+    }
+  }
+
+  ~CubeGrid() {
+    // cleanup cubes
+    int num_cubes = x_cubes * y_cubes * z_cubes;
+    for(int i = 0; i < num_cubes; ++i) {
+      if(cubes[i] != NULL) delete cubes[i];
+    }
+    delete [] cubes;
+  }
+
+  void AddIndex(Real x, Real y, Real z, int idx) {
+    int x_cube = (x - x_min) / cube_edge_length;
+    int y_cube = (y - y_min) / cube_edge_length;
+    int z_cube = (z - z_min) / cube_edge_length;
+    int cube_idx = x_cube * y_cubes * z_cubes + y_cube * z_cubes + z_cube;
+    if(cubes[cube_idx] == NULL) cubes[cube_idx] = new Cube; 
+    cubes[cube_idx]->AddIndex(idx);
+  }
+
+  void GetCubes(Real x, Real y, Real z,
+                std::vector<Cube*>& neighbouring_cubes,
+                Cube*& central_cube) {
+
+    int x_cube = (x - x_min) / cube_edge_length;
+    int y_cube = (y - y_min) / cube_edge_length;
+    int z_cube = (z - z_min) / cube_edge_length;
+
+    // set the central cube... we throw an error if this cube doesn't exist!
+    int cube_idx = x_cube * y_cubes * z_cubes + y_cube * z_cubes + z_cube;
+
+    if(cubes[cube_idx] == NULL){
+        throw ost::Error("This should not happen!");
+    }
+
+    central_cube = cubes[cube_idx];
+
+    // let's try all neighbours... only add if they actually exist!
+    int x_min = std::max(x_cube - 1, 0);
+    int x_max = std::min(x_cube + 1, x_cubes - 1);
+    int y_min = std::max(y_cube - 1, 0);
+    int y_max = std::min(y_cube + 1, y_cubes - 1);
+    int z_min = std::max(z_cube - 1, 0);
+    int z_max = std::min(z_cube + 1, z_cubes - 1);
+   
+    neighbouring_cubes.clear();
+    for(int i = x_min; i <= x_max; ++i) {
+      for(int j = y_min; j <= y_max; ++j) {
+        for(int k = z_min; k <= z_max; ++k){
+          if(!(i == x_cube && j == y_cube && k == z_cube)){
+            // its not the central cube, so lets add it if initialized
+            cube_idx = i * y_cubes * z_cubes + j * z_cubes + k;
+            if(cubes[cube_idx] != NULL) {
+              neighbouring_cubes.push_back(cubes[cube_idx]);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  Real cube_edge_length;
+  int x_cubes;
+  int y_cubes;
+  int z_cubes;
+  Real x_min;
+  Real y_min;
+  Real z_min;
+  Cube** cubes;
+};
+
+
+Real GetAtomAccessibility(Real x_pos, Real y_pos, Real z_pos,
+                           Real radius,
+                           const std::vector<Real>& dx, 
+                           const std::vector<Real>& dy, 
+                           const std::vector<Real>& d, 
+                           const std::vector<Real>& dsqr, 
+                           const std::vector<Real>& z, 
+                           const std::vector<Real>& radii) {
+
+  int num_close_atoms = dx.size();
+
+  if(num_close_atoms == 0) {
+    // return area of full sphere
+    return Real(4.0) * M_PI * radius * radius;
+  } 
+
+  Real area = 0.0;
+  int num_z_slices = 20;
+  Real z_res = Real(2.0) * radius / num_z_slices;
+  Real z_grid = z_pos - radius + Real(0.5) * z_res;
+  Real pi_two = Real(2.0) * M_PI;
+  std::vector<std::pair<Real, Real> > arcs;
+
+  for(int z_slice_idx = 0; z_slice_idx < num_z_slices; ++z_slice_idx) {
+    
+    arcs.clear();
+    Real dz = z_grid - z_pos;
+
+    // the radius of the circle given by the intersection of the sphere
+    // with the current z plane (remember: r*r = x*x + y*y)
+    Real z_slice_squared_r = radius*radius - dz*dz;
+
+    Real z_slice_r = std::sqrt(z_slice_squared_r);
+    bool fully_enclosed = false;
+
+    for(int idx = 0; idx < num_close_atoms; ++idx) {
+
+      Real close_atom_dz = z_grid - z[idx];
+      Real close_atom_radius = radii[idx];
+      
+
+      // the radius of the circle given by the intersection of the sphere
+      // around the close atom and the current z plane
+      Real close_atom_z_slice_squared_r = close_atom_radius*close_atom_radius - 
+                                           close_atom_dz*close_atom_dz;
+
+      if(close_atom_z_slice_squared_r < 0.0) {
+        continue;
+      }
+
+      Real close_atom_z_slice_r = std::sqrt(close_atom_z_slice_squared_r);
+
+      Real summed_r = close_atom_z_slice_r + z_slice_r;
+
+      if(d[idx] < summed_r) {
+        // the atoms are close!
+
+        Real r_diff = z_slice_r - close_atom_z_slice_r;
+
+        if(d[idx] < std::abs(r_diff)) {
+          // one circle is inside the other!
+          if(r_diff <= Real(0.0)) {
+            // the circle of the close atom fully encloses circle of currently
+            // processed atom!
+            fully_enclosed = true;
+            break;
+          } 
+          else {
+            // the circle of the currently processed atom encloses circle of the
+            // close atom => simply skip close atom...
+            continue;
+          }
+        }
+
+        // estimate alpha: the angle between l1 and l2.
+        // l1: line between the two circle centers
+        // l2: line between circle center of reference atom and intersection point
+        Real trig_test = (dsqr[idx] + z_slice_squared_r - 
+                           close_atom_z_slice_squared_r) / 
+                          (Real(2.0) * d[idx] * z_slice_r);
+    
+        if(trig_test >= 1.0) trig_test = Real(0.99999);
+        if(trig_test <=-1.0) trig_test = Real(-0.99999);
+        Real alpha = std::acos(trig_test);
+
+        // estimate beta: the angle between l and the x-axis
+        // l: line between the two circle centers
+        Real beta = std::atan2(dy[idx], dx[idx]) + M_PI;
+
+        // start and end of arc relative to x-axis
+        Real arc_start = beta - alpha;
+        Real arc_end = beta + alpha;
+    
+        // enforce range [0.0, 2*pi]
+        if(arc_start < 0.0) arc_start += pi_two;
+        if(arc_end > pi_two) arc_end -= pi_two;
+
+        if(arc_end >= arc_start) {
+          arcs.push_back(std::make_pair(arc_start, arc_end));
+        }
+        else {
+          arcs.push_back(std::make_pair(arc_start, pi_two));
+          arcs.push_back(std::make_pair(0.0, arc_end));
+        }
+      }
+    }
+
+    Real arc_sum = 0.0;
+
+    if(!fully_enclosed) {
+
+      if(arcs.empty()) {
+        arc_sum = pi_two;
+      }
+      else{
+        std::sort(arcs.begin(), arcs.end());
+        arc_sum = arcs[0].first;
+        Real end = arcs[0].second;
+        for(uint i = 1; i < arcs.size(); ++i) {
+          if(end < arcs[i].first) arc_sum += (arcs[i].first - end);
+          if(arcs[i].second > end) end = arcs[i].second;
+        }
+        arc_sum += (pi_two - end);
+      }
+    }
+
+    area += (arc_sum * z_res);
+    z_grid += z_res;
+  }
+
+  // scale to VdW shell
+  return area*radius;
+}
+
+void CalculateASA(std::vector<Real>& x, std::vector<Real>& y, 
+                  std::vector<Real>& z, std::vector<Real>& radii, 
+                  Real probe_radius, std::vector<Real>& asa) {
+
+  int num_atoms = x.size();
+  asa.resize(num_atoms);
+
+  std::vector<Real> full_radii;
+  full_radii.resize(num_atoms);
+  Real x_min = x[0];
+  Real x_max = x[0];
+  Real y_min = y[0];
+  Real y_max = y[0];
+  Real z_min = z[0];
+  Real z_max = z[0];
+  Real r_max = radii[0] + probe_radius;
+  full_radii[0] = r_max;
+
+  for(int i = 1; i < num_atoms; ++i){
+    full_radii[i] = radii[i] + probe_radius;
+    x_min = std::min(x_min, x[i]);
+    x_max = std::max(x_max, x[i]);
+    y_min = std::min(y_min, y[i]);
+    y_max = std::max(y_max, y[i]);
+    z_min = std::min(z_min, z[i]);
+    z_max = std::max(z_max, z[i]);
+    r_max = std::max(r_max, full_radii[i]);
+  }
+  
+  Real x_range = x_max - x_min;
+  Real y_range = y_max - y_min;
+  Real z_range = z_max - z_min;
+  Real cube_edge_length = 2 * (r_max);
+  int x_cubes = std::ceil(x_range / cube_edge_length);
+  int y_cubes = std::ceil(y_range / cube_edge_length);
+  int z_cubes = std::ceil(z_range / cube_edge_length);
+
+  CubeGrid cube_grid(cube_edge_length, x_cubes, y_cubes, z_cubes,
+                     x_min, y_min, z_min);
+
+  for(int i = 0; i < num_atoms; ++i) {
+    cube_grid.AddIndex(x[i], y[i], z[i], i);
+  }
+
+  //prepare some stuff
+  std::vector<Real> close_atom_dx, close_atom_dy, close_atom_d;
+  std::vector<Real> close_atom_dsqr, close_atom_z, close_atom_radii;
+  std::vector<Cube*> neighbouring_cubes;
+  Cube* central_cube;
+
+  // iterate over every atom
+  for(int atom_idx = 0; atom_idx < num_atoms; ++atom_idx) {
+
+    close_atom_dx.clear();
+    close_atom_dy.clear();
+    close_atom_d.clear();
+    close_atom_dsqr.clear();
+    close_atom_z.clear();
+    close_atom_radii.clear();
+
+    Real current_x = x[atom_idx];
+    Real current_y = y[atom_idx];
+    Real current_z = z[atom_idx];
+    Real current_radius = full_radii[atom_idx];
+
+    cube_grid.GetCubes(current_x, current_y, current_z, 
+                       neighbouring_cubes, central_cube);
+
+    // gather the stuff from all neighbouring cubes
+    for(std::vector<Cube*>::iterator cube_it = neighbouring_cubes.begin();
+        cube_it != neighbouring_cubes.end(); ++cube_it) {
+
+      const std::vector<int>& cube_indices = (*cube_it)->GetIndices();
+
+      for(std::vector<int>::const_iterator it = cube_indices.begin();
+          it != cube_indices.end(); ++it) {
+
+        int close_atom_idx = *it;
+        Real dx = current_x - x[close_atom_idx];
+        Real dy = current_y - y[close_atom_idx]; 
+        Real sqr_d = dx*dx + dy*dy;
+        Real d = std::sqrt(sqr_d);
+
+        close_atom_dx.push_back(dx);
+        close_atom_dy.push_back(dy);
+        close_atom_dsqr.push_back(sqr_d);
+        close_atom_d.push_back(d);
+        close_atom_z.push_back(z[close_atom_idx]);
+        close_atom_radii.push_back(full_radii[close_atom_idx]);
+      }
+    }
+
+    // gather stuff from central cube
+    const std::vector<int>& cube_indices = central_cube->GetIndices();
+    for(std::vector<int>::const_iterator it = cube_indices.begin();
+        it != cube_indices.end(); ++it) {
+
+      int close_atom_idx = *it;
+
+      if(atom_idx != close_atom_idx){
+        Real dx = current_x - x[close_atom_idx];
+        Real dy = current_y - y[close_atom_idx]; 
+        Real sqr_d = dx*dx + dy*dy;
+        Real d = std::sqrt(sqr_d);
+
+        close_atom_dx.push_back(dx);
+        close_atom_dy.push_back(dy);
+        close_atom_dsqr.push_back(sqr_d);
+        close_atom_d.push_back(d);
+        close_atom_z.push_back(z[close_atom_idx]);
+        close_atom_radii.push_back(full_radii[close_atom_idx]);
+      }
+    }
+
+    asa[atom_idx] = GetAtomAccessibility(current_x, current_y, current_z, 
+                                         current_radius, 
+                                         close_atom_dx, close_atom_dy, 
+                                         close_atom_d, close_atom_dsqr, 
+                                         close_atom_z, close_atom_radii);
+  }
+}
+
+
+} //ns
+
+
+
+
+
+
+
+namespace ost { namespace mol { namespace alg {
+
+NACCESSParam::NACCESSParam() {
+
+  std::map<String, Real> ala_map;
+  std::map<String, Real> arg_map;
+  std::map<String, Real> asp_map;
+  std::map<String, Real> asn_map;
+  std::map<String, Real> cys_map;
+  std::map<String, Real> glu_map;
+  std::map<String, Real> gln_map;
+  std::map<String, Real> gly_map;
+  std::map<String, Real> his_map;
+  std::map<String, Real> ile_map;
+  std::map<String, Real> leu_map;
+  std::map<String, Real> lys_map;
+  std::map<String, Real> met_map;
+  std::map<String, Real> phe_map;
+  std::map<String, Real> pro_map;
+  std::map<String, Real> ser_map;
+  std::map<String, Real> thr_map;
+  std::map<String, Real> trp_map;
+  std::map<String, Real> tyr_map;
+  std::map<String, Real> val_map;  
+ 
+  ala_map["N"]  = 1.65;  
+  ala_map["CA"] = 1.87;  
+  ala_map["C"]  = 1.76;  
+  ala_map["O"]  = 1.40;  
+  ala_map["CB"] = 1.87;
+
+  arg_map["N"]  = 1.65; 
+  arg_map["CA"] = 1.87; 
+  arg_map["C"]  = 1.76; 
+  arg_map["O"]  = 1.40; 
+  arg_map["CB"] = 1.87; 
+  arg_map["CG"] = 1.87; 
+  arg_map["CD"] = 1.87; 
+  arg_map["NE"] = 1.65; 
+  arg_map["CZ"] = 1.76; 
+  arg_map["NH1"]= 1.65; 
+  arg_map["NH2"]= 1.65; 
+
+  asp_map["N"]  = 1.65;
+  asp_map["CA"] = 1.87;
+  asp_map["C"]  = 1.76;
+  asp_map["O"]  = 1.40;
+  asp_map["CB"] = 1.87;
+  asp_map["CG"] = 1.76;
+  asp_map["OD1"]= 1.40;
+  asp_map["OD2"]= 1.40;
+
+  asn_map["N"]  = 1.65;  
+  asn_map["CA"] = 1.87;  
+  asn_map["C"]  = 1.76;  
+  asn_map["O"]  = 1.40;  
+  asn_map["CB"] = 1.87;  
+  asn_map["CG"] = 1.76;  
+  asn_map["OD1"]= 1.40;  
+  asn_map["ND2"]= 1.65;  
+         
+  cys_map["N"]  = 1.65;  
+  cys_map["CA"] = 1.87;  
+  cys_map["C"]  = 1.76;  
+  cys_map["O"]  = 1.40;  
+  cys_map["CB"] = 1.87;  
+  cys_map["SG"] = 1.85;  
+
+  glu_map["N"]  = 1.65; 
+  glu_map["CA"] = 1.87; 
+  glu_map["C"]  = 1.76; 
+  glu_map["O"]  = 1.40; 
+  glu_map["CB"] = 1.87; 
+  glu_map["CG"] = 1.87; 
+  glu_map["CD"] = 1.76; 
+  glu_map["OE1"]= 1.40; 
+  glu_map["OE2"]= 1.40;
+     
+  gln_map["N"]  = 1.65; 
+  gln_map["CA"] = 1.87; 
+  gln_map["C"]  = 1.76; 
+  gln_map["O"]  = 1.40; 
+  gln_map["CB"] = 1.87; 
+  gln_map["CG"] = 1.87; 
+  gln_map["CD"] = 1.76; 
+  gln_map["OE1"]= 1.40; 
+  gln_map["NE2"]= 1.65; 
+
+  gly_map["N"]  = 1.65;  
+  gly_map["CA"] = 1.87;  
+  gly_map["C"]  = 1.76;  
+  gly_map["O"]  = 1.40;  
+
+  his_map["N"]  = 1.65; 
+  his_map["CA"] = 1.87; 
+  his_map["C"]  = 1.76; 
+  his_map["O"]  = 1.40; 
+  his_map["CB"] = 1.87; 
+  his_map["CG"] = 1.76; 
+  his_map["ND1"]= 1.65; 
+  his_map["CD2"]= 1.76; 
+  his_map["CE1"]= 1.76; 
+  his_map["NE2"]= 1.65; 
+          
+  ile_map["N"]  = 1.65; 
+  ile_map["CA"] = 1.87; 
+  ile_map["C"]  = 1.76;
+  ile_map["O"]  = 1.40; 
+  ile_map["CB"] = 1.87;
+  ile_map["CG1"]= 1.87; 
+  ile_map["CG2"]= 1.87; 
+  ile_map["CD1"]= 1.87; 
+
+  leu_map["N"]  = 1.65;
+  leu_map["CA"] = 1.87; 
+  leu_map["C"]  = 1.76; 
+  leu_map["O"]  = 1.40; 
+  leu_map["CB"] = 1.87; 
+  leu_map["CG"] = 1.87; 
+  leu_map["CD1"]= 1.87; 
+  leu_map["CD2"]= 1.87; 
+
+  lys_map["N"]  = 1.65; 
+  lys_map["CA"] = 1.87; 
+  lys_map["C"]  = 1.76; 
+  lys_map["O"]  = 1.40; 
+  lys_map["CB"] = 1.87; 
+  lys_map["CG"] = 1.87; 
+  lys_map["CD"] = 1.87; 
+  lys_map["CE"] = 1.87; 
+  lys_map["NZ"] = 1.50; 
+           
+  met_map["N"]  = 1.65; 
+  met_map["CA"] = 1.87; 
+  met_map["C"]  = 1.76; 
+  met_map["O"]  = 1.40; 
+  met_map["CB"] = 1.87; 
+  met_map["CG"] = 1.87; 
+  met_map["SD"] = 1.85; 
+  met_map["CE"] = 1.87; 
+            
+  phe_map["N"]  = 1.65; 
+  phe_map["CA"] = 1.87;
+  phe_map["C"]  = 1.76; 
+  phe_map["O"]  = 1.40; 
+  phe_map["CB"] = 1.87; 
+  phe_map["CG"] = 1.76; 
+  phe_map["CD1"]= 1.76; 
+  phe_map["CD2"]= 1.76; 
+  phe_map["CE1"]= 1.76; 
+  phe_map["CE2"]= 1.76; 
+  phe_map["CZ"]= 1.76; 
+        
+  pro_map["N"]  = 1.65; 
+  pro_map["CA"] = 1.87; 
+  pro_map["C"]  = 1.76; 
+  pro_map["O"]  = 1.40; 
+  pro_map["CB"] = 1.87; 
+  pro_map["CG"] = 1.87; 
+  pro_map["CD"] = 1.87;
+
+  ser_map["N"]  = 1.65; 
+  ser_map["CA"] = 1.87; 
+  ser_map["C"]  = 1.76; 
+  ser_map["O"]  = 1.40; 
+  ser_map["CB"] = 1.87; 
+  ser_map["OG"] = 1.40; 
+
+  thr_map["N"]  = 1.65; 
+  thr_map["CA"] = 1.87; 
+  thr_map["C"]  = 1.76; 
+  thr_map["O"]  = 1.40; 
+  thr_map["CB"] = 1.87; 
+  thr_map["OG1"]= 1.40; 
+  thr_map["CG2"]= 1.87; 
+
+  trp_map["N"]  = 1.65; 
+  trp_map["CA"] = 1.87; 
+  trp_map["C"]  = 1.76; 
+  trp_map["O"]  = 1.40; 
+  trp_map["CB"] = 1.87; 
+  trp_map["CG"] = 1.76; 
+  trp_map["CD1"]= 1.76; 
+  trp_map["CD2"]= 1.76; 
+  trp_map["NE1"]= 1.65; 
+  trp_map["CE2"]= 1.76; 
+  trp_map["CE3"]= 1.76; 
+  trp_map["CZ2"]= 1.76; 
+  trp_map["CZ3"]= 1.76; 
+  trp_map["CH2"]= 1.76; 
+
+  tyr_map["N"]  = 1.65; 
+  tyr_map["CA"] = 1.87; 
+  tyr_map["C"]  = 1.76; 
+  tyr_map["O"]  = 1.40; 
+  tyr_map["CB"] = 1.87; 
+  tyr_map["CG"] = 1.76; 
+  tyr_map["CD1"]= 1.76; 
+  tyr_map["CD2"]= 1.76; 
+  tyr_map["CE1"]= 1.76; 
+  tyr_map["CE2"]= 1.76; 
+  tyr_map["CZ"]= 1.76; 
+  tyr_map["OH"]= 1.40; 
+
+  val_map["N"] = 1.65; 
+  val_map["CA"] = 1.87; 
+  val_map["C"] = 1.76; 
+  val_map["O"] = 1.40; 
+  val_map["CB"] = 1.87; 
+  val_map["CG1"] = 1.87; 
+  val_map["CG2"] = 1.87;
+
+  vdw_radii_["ALA"] = ala_map;
+  vdw_radii_["ARG"] = arg_map;
+  vdw_radii_["ASP"] = asp_map;
+  vdw_radii_["ASN"] = asn_map;
+  vdw_radii_["CYS"] = cys_map;
+  vdw_radii_["GLU"] = glu_map;
+  vdw_radii_["GLN"] = gln_map;
+  vdw_radii_["GLY"] = gly_map;
+  vdw_radii_["HIS"] = his_map;
+  vdw_radii_["ILE"] = ile_map;
+  vdw_radii_["LEU"] = leu_map;
+  vdw_radii_["LYS"] = lys_map;
+  vdw_radii_["MET"] = met_map;
+  vdw_radii_["PHE"] = phe_map;
+  vdw_radii_["PRO"] = pro_map;
+  vdw_radii_["SER"] = ser_map;
+  vdw_radii_["THR"] = thr_map;
+  vdw_radii_["TRP"] = trp_map;
+  vdw_radii_["TYR"] = tyr_map;
+  vdw_radii_["VAL"] = val_map;
+
+  accessibilities_["ALA"] = 107.95;
+  accessibilities_["CYS"] = 134.28;
+  accessibilities_["ASP"] = 140.39;
+  accessibilities_["GLU"] = 172.25;
+  accessibilities_["PHE"] = 199.48;
+  accessibilities_["GLY"] =  80.10;
+  accessibilities_["HIS"] = 182.88;
+  accessibilities_["ILE"] = 175.12;
+  accessibilities_["LYS"] = 200.81;
+  accessibilities_["LEU"] = 178.63;
+  accessibilities_["MET"] = 194.15;
+  accessibilities_["ASN"] = 143.94;
+  accessibilities_["PRO"] = 136.13;
+  accessibilities_["GLN"] = 178.50;
+  accessibilities_["ARG"] = 238.76;
+  accessibilities_["SER"] = 116.50;
+  accessibilities_["THR"] = 139.27;
+  accessibilities_["VAL"] = 151.44;
+  accessibilities_["TRP"] = 249.36;
+  accessibilities_["TYR"] = 212.76;
+}
+
+Real NACCESSParam::GuessRadius(const String& ele) const{
+  if(ele == "C") return 1.80;
+  if(ele == "N") return 1.60;
+  if(ele == "S") return 1.85;
+  if(ele == "O") return 1.40;
+  if(ele == "P") return 1.90;
+  if(ele == "CA") return 2.07;
+  if(ele == "FE") return 1.47;
+  if(ele == "CU") return 1.78;
+  if(ele == "ZN") return 1.39;
+  if(ele == "MG") return 1.73;
+  if(ele == "H") return 1.0;
+  if(ele == "D") return 1.0;
+  return 1.80;
+}
+
+Real NACCESSParam::GetVdWRadius(const String& rname, const String& aname, 
+                                const String& ele) const{
+  std::map<String, std::map<String, Real> >::const_iterator res_map_it =
+  vdw_radii_.find(rname);
+  if(res_map_it != vdw_radii_.end()) {
+    std::map<String, Real>::const_iterator at_it = 
+    res_map_it->second.find(aname);
+    if(at_it != res_map_it->second.end()) return at_it->second;
+  }
+  return GuessRadius(ele);
+}
+
+Real NACCESSParam::GetResidueAccessibility(const String& rname) const{
+  std::map<String, Real>::const_iterator it = accessibilities_.find(rname);
+  if(it != accessibilities_.end()) return it->second;
+  else return 0.0;
+}
+
+
+Real Accessibility(ost::mol::EntityView& ent, 
+                   Real probe_radius, bool include_hydrogens,
+                   bool include_hetatm, bool include_water,
+                   const String& selection, 
+                   const String& asa_abs, 
+                   const String& asa_rel,
+                   const String& asa_atom) {
+
+  String internal_selection = selection;
+
+  if(!include_hydrogens) {
+    if(internal_selection == "") {
+      internal_selection = "ele!=H,D";
+    }
+    else {
+      internal_selection += " and ele!=H,D";
+    }
+  }
+
+  if(!include_hetatm) {
+    if(internal_selection == "") {
+      internal_selection = "ishetatm=false";
+    }
+    else {
+      internal_selection += " and ishetatm=false";
+    }
+  }
+
+  if(!include_water) {
+    if(internal_selection == "") {
+      internal_selection = "water=false";
+    }
+    else {
+      internal_selection += " and water=false";
+    }
+  }
+
+  ost::mol::EntityView selected_ent;
+  if(internal_selection != "") { 
+    selected_ent = ent.Select(internal_selection);
+  }    
+  else{
+    selected_ent = ent;
+  }
+
+  // input for algorithm
+  std::vector<Real> x_pos;
+  std::vector<Real> y_pos;
+  std::vector<Real> z_pos;
+  std::vector<Real> radii;
+
+  x_pos.reserve(selected_ent.GetAtomCount());
+  y_pos.reserve(selected_ent.GetAtomCount());
+  z_pos.reserve(selected_ent.GetAtomCount());
+  radii.reserve(selected_ent.GetAtomCount());
+
+  // extract data from ent
+  String rname, aname, ele;
+
+  const NACCESSParam& param = NACCESSParam::GetInstance();
+
+  ost::mol::AtomViewList atom_list = selected_ent.GetAtomList();
+  for(ost::mol::AtomViewList::const_iterator at_it = atom_list.begin();
+      at_it != atom_list.end(); ++at_it) {
+    rname = at_it->GetResidue().GetName();
+    aname = at_it->GetName();
+    ele = at_it->GetElement();
+    geom::Vec3 at_pos = at_it->GetPos();
+    x_pos.push_back(at_pos[0]);
+    y_pos.push_back(at_pos[1]);
+    z_pos.push_back(at_pos[2]);
+    radii.push_back(param.GetVdWRadius(rname, aname, ele));
+  }  
+
+  // per atom accessibilities come in here
+  std::vector<Real> asa;
+
+  // do it! do it! do it!
+  CalculateASA(x_pos, y_pos, z_pos, radii, probe_radius, asa);
+
+  // assign 0.0 for per residue asaAbs
+  ost::mol::ResidueViewList res_list = selected_ent.GetResidueList();
+  for(uint res_idx = 0; res_idx < res_list.size(); ++res_idx) {
+    res_list[res_idx].SetFloatProp(asa_abs, 0.0);
+  }
+
+  // assign absolute accessibilities
+  Real summed_asa = 0.0;
+  for(uint idx = 0; idx < asa.size(); ++idx) {
+    Real val = asa[idx];
+    atom_list[idx].SetFloatProp(asa_atom, val);
+    ost::mol::ResidueView res = atom_list[idx].GetResidue();
+    Real current_asa = res.GetFloatProp(asa_abs);
+    res.SetFloatProp(asa_abs, current_asa + val);
+    summed_asa += val;
+  }
+
+  // go over residue and assign relative accessibilities
+  for(uint idx = 0; idx < res_list.size(); ++idx) {
+    rname = res_list[idx].GetName();
+    Real tot_acc = NACCESSParam::GetInstance().GetResidueAccessibility(rname);
+    if(tot_acc == 0.0) {
+      // no accessibility found... 
+      res_list[idx].SetFloatProp(asa_rel, 0.0);
+    }
+    else {
+      // the fraction gets multiplied by 100 (Thats how NACCESS does it...)
+      Real val = res_list[idx].GetFloatProp(asa_abs) / tot_acc * 100.0;
+      res_list[idx].SetFloatProp(asa_rel, val);
+    }
+  }
+
+  return summed_asa;
+}
+
+
+Real Accessibility(ost::mol::EntityHandle& ent, 
+                   Real probe_radius, bool include_hydrogens,
+                   bool include_hetatm, bool include_water,
+                   const String& selection,
+                   const String& asa_abs, 
+                   const String& asa_rel,
+                   const String& asa_atom) {
+
+  ost::mol::EntityView entity_view = ent.CreateFullView();
+  return Accessibility(entity_view, probe_radius, include_hydrogens,
+                       include_hetatm, include_water,
+                       selection, asa_abs, asa_rel, asa_atom);
+}
+
+}}} //ns
diff --git a/modules/mol/alg/src/accessibility.hh b/modules/mol/alg/src/accessibility.hh
new file mode 100644
index 0000000000000000000000000000000000000000..35a2811e6c97bc45e578801d4ac7e7b6fc91b91b
--- /dev/null
+++ b/modules/mol/alg/src/accessibility.hh
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2017 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_ACCESSIBILITY_HH
+#define OST_ACCESSIBILITY_HH
+
+#include <ost/mol/entity_view.hh>
+#include <ost/mol/entity_handle.hh>
+
+namespace ost { namespace mol { namespace alg {
+
+
+class NACCESSParam {
+
+public:
+  // Singleton access to one constant instance
+  static const NACCESSParam& GetInstance() {
+    static NACCESSParam instance;
+    return instance;
+  }
+  // Data access
+
+  Real GuessRadius(const String& ele) const;
+
+  Real GetVdWRadius(const String& rname, const String& aname, 
+                    const String& ele) const;
+
+  Real GetResidueAccessibility(const String& rname) const;
+
+private:
+
+  // construction only inside here
+  NACCESSParam();
+
+  std::map<String, std::map<String, Real> > vdw_radii_;
+  std::map<String, Real> accessibilities_;
+};
+
+Real Accessibility(ost::mol::EntityView& ent, 
+                   Real probe_radius = 1.4,
+                   bool include_hydrogens = false,  
+                   bool include_hetatm = false,
+                   bool include_water = false,
+                   const String& selection = "",
+                   const String& asa_abs = "asaAbs",
+                   const String& asa_rel = "asaRel",
+                   const String& asa_atom = "asaAtom");
+
+
+Real Accessibility(ost::mol::EntityHandle& ent, 
+                   Real probe_radius = 1.4,
+                   bool include_hydrogens = false,
+                   bool include_hetatm = false,
+                   bool include_water = false,
+                   const String& selection = "",
+                   const String& asa_abs = "asaAbs",
+                   const String& asa_rel = "asaRel",
+                   const String& asa_atom = "asaAtom");
+
+}}} //ns
+
+#endif