diff --git a/modules/mol/alg/doc/molalg.rst b/modules/mol/alg/doc/molalg.rst
index 6efb2a18ded75633ea189dac734ecda7845730c3..d7d82b27cc435056a96463628bf30a130428ee31 100644
--- a/modules/mol/alg/doc/molalg.rst
+++ b/modules/mol/alg/doc/molalg.rst
@@ -1393,7 +1393,15 @@ Algorithms on Structures
   :param ent:           Entity of a transmembrane protein, you'll get weird 
                         results if this is not the case. The energy term
                         of the result is typically a good indicator whether
-                        *ent* is an actual transmembrane protein.
+                        *ent* is an actual transmembrane protein. The 
+                        following float properties will be set on the atoms:
+
+                        * 'asaAtom' on all atoms that are selected with 
+                          ent.Select('peptide=true and ele!=H') as a result
+                          of envoking :meth:`Accessibility`.
+                        * 'membrane_e' the contribution of the potentially 
+                          membrane facing atoms to the energy function. 
+                          
   :type ent:            :class:`ost.mol.EntityHandle` / :class:`ost.mol.EntityView`
 
   :param assign_membrane_representation: Whether to construct a membrane 
diff --git a/modules/mol/alg/src/find_membrane.cc b/modules/mol/alg/src/find_membrane.cc
index 2bf0d625a1db446d9519201bda1bdc97df44b7b4..a967bb3063a03606bcb61621b76dc5b8ba422f4d 100644
--- a/modules/mol/alg/src/find_membrane.cc
+++ b/modules/mol/alg/src/find_membrane.cc
@@ -400,11 +400,7 @@ void FloodLevel(char* data, int x_start, int y_start,
 
 
 void GetExposedAtoms(const std::vector<geom::Vec3>& atom_positions,
-                     const std::vector<Real>& transfer_energies,
-                     const std::vector<Real>& asas,
-                     std::vector<geom::Vec3>& exposed_atom_positions,
-                     std::vector<Real>& exposed_transfer_energies,
-                     std::vector<Real>& exposed_asas) {
+                     std::vector<int>& exposed_atoms) {
 
   // sum of approx. vdw radius of the present heavy atoms (1.8) 
   // plus 1.4 for water.
@@ -488,18 +484,14 @@ void GetExposedAtoms(const std::vector<geom::Vec3>& atom_positions,
   }
 
   // all positions that lie in a cube with value 3 are considered to be exposed...
-  exposed_atom_positions.clear();
-  exposed_transfer_energies.clear();
-  exposed_asas.clear();
+  exposed_atoms.clear();
   for(uint i = 0; i < atom_positions.size(); ++i) {
     const geom::Vec3& pos = atom_positions[i];
     int x_bin = (pos[0] - min_x) * one_over_radius;
     int y_bin = (pos[1] - min_y) * one_over_radius;
     int z_bin = (pos[2] - min_z) * one_over_radius;
     if(grid[z_bin*num_xbins*num_ybins + x_bin*num_ybins + y_bin] == 3) {
-      exposed_atom_positions.push_back(pos);
-      exposed_transfer_energies.push_back(transfer_energies[i]);
-      exposed_asas.push_back(asas[i]);
+      exposed_atoms.push_back(i);
     }
   }
 
@@ -582,6 +574,7 @@ struct LMInput {
   std::vector<geom::Vec3> exposed_atom_positions;
   std::vector<Real> exposed_transfer_energies;
   std::vector<Real> exposed_asas;
+  std::vector<int> exposed_indices;
 };
 
 
@@ -597,12 +590,26 @@ void SampleZ(const std::vector<geom::Vec3>& atom_pos,
     transformed_atom_pos[at_idx] = initial_transform.Apply(atom_pos[at_idx]);
   }
 
+  std::vector<int> exposed_atoms;
+  GetExposedAtoms(transformed_atom_pos, exposed_atoms);
+
   std::vector<geom::Vec3> exposed_atom_positions;
   std::vector<Real> exposed_transfer_energies;
   std::vector<Real> exposed_asas;
-  GetExposedAtoms(transformed_atom_pos, transfer_energies, asas,
-                  exposed_atom_positions, exposed_transfer_energies,
-                  exposed_asas);
+  std::vector<int> exposed_atoms_nonzero_energy;
+  exposed_atom_positions.reserve(exposed_atoms.size());
+  exposed_transfer_energies.reserve(exposed_atoms.size());
+  exposed_asas.reserve(exposed_atoms.size());
+  exposed_atoms_nonzero_energy.reserve(exposed_atoms.size());
+  for(uint i = 0; i < exposed_atoms.size(); ++i) {
+    if(transfer_energies[exposed_atoms[i]] != 0.0) {
+      exposed_atom_positions.push_back(transformed_atom_pos[exposed_atoms[i]]);
+      exposed_transfer_energies.push_back(transfer_energies[exposed_atoms[i]]);
+      exposed_asas.push_back(asas[exposed_atoms[i]]);
+      exposed_atoms_nonzero_energy.push_back(exposed_atoms[i]);
+    }
+  }
+  exposed_atoms = exposed_atoms_nonzero_energy;
 
   std::vector<Real> tilt_angles;
   std::vector<Real> rotation_angles;
@@ -654,6 +661,7 @@ void SampleZ(const std::vector<geom::Vec3>& atom_pos,
     lm_input.exposed_atom_positions = exposed_atom_positions;
     lm_input.exposed_transfer_energies = exposed_transfer_energies;
     lm_input.exposed_asas = exposed_asas;
+    lm_input.exposed_indices = exposed_atoms;
 
     if(top_solutions.empty()) {
       top_solutions.push_back(lm_input);
@@ -681,8 +689,7 @@ void SampleZ(const std::vector<geom::Vec3>& atom_pos,
 }
 
 
-ost::mol::alg::FindMemParam GetFinalSolution(const std::list<LMInput>& top_solutions, 
-                                             Real lambda) {
+LMInput GetFinalSolution(const std::list<LMInput>& top_solutions, Real lambda) {
 
   Real best_energy = std::numeric_limits<Real>::max();
   std::list<LMInput>::const_iterator best_sol_it = top_solutions.begin();
@@ -710,7 +717,7 @@ ost::mol::alg::FindMemParam GetFinalSolution(const std::list<LMInput>& top_solut
     lm_result = lm.minimize(&lm_parameters);
  
     Real minimized_energy = en_f(lm_parameters)(0, 0) - en_f.offset;
-    
+
     if(minimized_energy < best_energy) {
       best_energy = minimized_energy;
       best_sol_it = sol_it;
@@ -718,30 +725,29 @@ ost::mol::alg::FindMemParam GetFinalSolution(const std::list<LMInput>& top_solut
     }
   }
 
-  ost::mol::alg::FindMemParam mem_param = best_sol_it->mem_param;
-  mem_param.energy = best_energy;
-  mem_param.tilt = best_lm_parameters(0,0);
-  mem_param.angle = best_lm_parameters(1,0);
-  mem_param.width = best_lm_parameters(2,0);
-  mem_param.pos = best_lm_parameters(3,0);
+  LMInput sol = *best_sol_it;
+
+  // sol has still the initial parameters before optimization
+  sol.mem_param.energy = best_energy;
+  sol.mem_param.tilt = best_lm_parameters(0,0);
+  sol.mem_param.angle = best_lm_parameters(1,0);
+  sol.mem_param.width = best_lm_parameters(2,0);
+  sol.mem_param.pos = best_lm_parameters(3,0);
 
   // assign the membrane accessible surface
   // misuses the optimizer energy function and feeds in the 
   // exposed asa instead of the transfer energies
-  EnergyF en_f(best_sol_it->exposed_atom_positions, 
-               best_sol_it->exposed_asas, 
-               lambda, 0.0,
-               best_sol_it->mem_param.axis, 
-               best_sol_it->mem_param.tilt_axis);
-  mem_param.membrane_asa = en_f(best_lm_parameters)(0, 0);
+  EnergyF en_f(sol.exposed_atom_positions, sol.exposed_asas, lambda, 0.0,
+               sol.mem_param.axis, sol.mem_param.tilt_axis);
+  sol.mem_param.membrane_asa = en_f(best_lm_parameters)(0, 0);
 
   // the solution is still relative to the initial transform that has
   // been applied when calling the SampleZ funtion!
-  geom::Transform t = best_sol_it->initial_transform;
-  mem_param.tilt_axis = t.ApplyInverse(mem_param.tilt_axis);
-  mem_param.axis = t.ApplyInverse(mem_param.axis);
+  geom::Transform t = sol.initial_transform;
+  sol.mem_param.tilt_axis = t.ApplyInverse(sol.mem_param.tilt_axis);
+  sol.mem_param.axis = t.ApplyInverse(sol.mem_param.axis);
 
-  return mem_param;
+  return sol;
 }
 
 
@@ -926,6 +932,7 @@ FindMemParam FindMembrane(ost::mol::EntityView& ent,
   transfer_energies.reserve(peptide_view.GetAtomCount());
 
   ost::mol::AtomViewList atoms = peptide_view.GetAtomList();
+  ost::mol::AtomViewList processed_atoms;
   String stupid_string("S_N_O_C");
 
   for(ost::mol::AtomViewList::iterator it = atoms.begin(); 
@@ -940,6 +947,7 @@ FindMemParam FindMembrane(ost::mol::EntityView& ent,
       continue;
     }
 
+    processed_atoms.push_back(*it);
     Real asa = it->GetFloatProp("asaAtom");
     asas.push_back(asa);
     atom_pos.push_back(it->GetPos());
@@ -1014,23 +1022,28 @@ FindMemParam FindMembrane(ost::mol::EntityView& ent,
   }
 
   // Perform the final minimization and return the best solution.
-  // please note, that the returned solution is transformed back in order
-  // to match the initial atom positions
-  FindMemParam final_solution = GetFinalSolution(top_solutions, 0.9);
+  // The returned solution is transformed back in order to match the initial 
+  // atom positions
+  LMInput final_sol = GetFinalSolution(top_solutions, 0.9);
 
   if(assign_membrane_representation) {
-    final_solution.membrane_representation = CreateMembraneRepresentation(
-                                                                atom_pos,
-                                                                final_solution);
+    final_sol.mem_param.membrane_representation = CreateMembraneRepresentation(
+                                                          atom_pos,
+                                                          final_sol.mem_param);
+  }
+
+  // map transfer energies and membrane asas
+  for(uint i = 0; i < final_sol.exposed_indices.size(); ++i) {
+    ost::mol::AtomView at = processed_atoms[final_sol.exposed_indices[i]];
+    at.SetFloatProp("membrane_e", final_sol.exposed_transfer_energies[i]);
   }
 
-  return final_solution;
+  return final_sol.mem_param;
 }
 
 
 FindMemParam FindMembrane(ost::mol::EntityHandle& ent, 
-                          bool assign_membrane_representation,
-                          bool fast) {
+                          bool assign_membrane_representation, bool fast) {
 
   ost::mol::EntityView ent_view = ent.CreateFullView();
   return FindMembrane(ent_view, assign_membrane_representation, fast);