diff --git a/modules/io/src/mol/omf.cc b/modules/io/src/mol/omf.cc
index f6a75c90e6516e6614556de6f2dc3f978e91a7ad..ddaf3d59114f1cd6157ef31ef0b0cfc294a276ab 100644
--- a/modules/io/src/mol/omf.cc
+++ b/modules/io/src/mol/omf.cc
@@ -174,10 +174,12 @@ namespace{
     int n = 0;
     int abs_min = std::abs(min);
     for(auto it = vec.begin(); it != vec.end(); ++it) {
-      if(*it > max) {
-        n += (*it/max + 1); 
-      } else if (*it < min) {
-        n += (std::abs(*it)/abs_min + 1);
+      if(*it >= max) {
+        n += *it/max;
+        ++n; 
+      } else if (*it <= min) {
+        n += std::abs(*it)/abs_min;
+        ++n;
       } else {
         ++n;
       }
@@ -186,10 +188,16 @@ namespace{
   }
 
   template<typename T>
-  void IntegerPacking(const std::vector<int>& in, std::vector<T>& out) {
+  void IntegerPacking(const std::vector<int>& in, std::vector<T>& out,
+                      int min, int max) {
+
+    if(min < std::numeric_limits<T>::min()) {
+      throw ost::Error("Invalid min val in IntegerPacking");
+    }
 
-    int min = std::numeric_limits<T>::min();
-    int max = std::numeric_limits<T>::max();
+    if(max > std::numeric_limits<T>::max()) {
+      throw ost::Error("Invalid max val in IntegerPacking");
+    }
 
     if(max <= min) {
       throw ost::Error("Min max error in IntegerPackingSize");
@@ -223,22 +231,29 @@ namespace{
   }
 
   template<typename T>
-  void IntegerUnpacking(const std::vector<T>& in, std::vector<int>& out) {
-    int min = std::numeric_limits<T>::min();
-    int max = std::numeric_limits<T>::max();
+  void IntegerUnpacking(const std::vector<T>& in, std::vector<int>& out,
+                        int min, int max) {
+
+    if(min < std::numeric_limits<T>::min()) {
+      throw ost::Error("Invalid min val in IntegerUnpacking");
+    }
+
+    if(max > std::numeric_limits<T>::max()) {
+      throw ost::Error("Invalid max val in IntegerUnpacking");
+    }
 
     if(max <= min) {
-      throw ost::Error("Min max error in IntegerPackingSize");
+      throw ost::Error("Min max error in IntegerUnpacking");
     }
 
     // We don't allow unsigned packing here => min must be negative,
     // max must be positive
     if(min >= 0) {
-      throw ost::Error("Min val in IntegerPacking must be negative");
+      throw ost::Error("Min val in IntegerUnpacking must be negative");
     }
 
     if(max <= 0) {
-      throw ost::Error("Max val in IntegerPacking must be positive");
+      throw ost::Error("Max val in IntegerUnpacking must be positive");
     }
 
     out.clear();
@@ -354,11 +369,13 @@ namespace{
     if(encoding == 8) {
       std::vector<int8_t> int8_vec;
       LoadIntVec(stream, int8_vec);
-      IntegerUnpacking(int8_vec, vec);
+      IntegerUnpacking(int8_vec, vec, std::numeric_limits<int8_t>::min(),
+                       std::numeric_limits<int8_t>::max());
     } else if(encoding == 16) {
       std::vector<int16_t> int16_vec;
       LoadIntVec(stream, int16_vec);
-      IntegerUnpacking(int16_vec, vec);
+      IntegerUnpacking(int16_vec, vec, std::numeric_limits<int16_t>::min(),
+                       std::numeric_limits<int16_t>::max());
     } else if(encoding == 32) {
       LoadIntVec(stream, vec);
     } else {
@@ -390,12 +407,16 @@ namespace{
       DumpIntVec(stream, vec);
     } else if(encoding == 16) {
       std::vector<int16_t> packed;
-      IntegerPacking(vec, packed);
+      IntegerPacking(vec, packed, std::numeric_limits<int16_t>::min(),
+                     std::numeric_limits<int16_t>::max());
       DumpIntVec(stream, packed);
     } else if(encoding == 8) {
       std::vector<int8_t> packed;
-      IntegerPacking(vec, packed);
+      IntegerPacking(vec, packed, std::numeric_limits<int8_t>::min(),
+                     std::numeric_limits<int8_t>::max());
       DumpIntVec(stream, packed);
+    } else {
+      throw ost::Error("AAAAAAAAaaaaaa!");
     }
   }
 
@@ -689,6 +710,104 @@ namespace{
   void DumpResDefIndices(std::ostream& stream, const std::vector<int>& indices) {
     Dump(stream, indices);
   }
+
+  void LoadSecStructures(std::istream& stream,
+                         std::vector<char>& sec_structures) {
+    std::vector<int> run_length_encoded;
+    Load(stream, run_length_encoded);
+    std::vector<int> transformed_sec_structures;
+    RunLengthDecoding(run_length_encoded, transformed_sec_structures);
+    sec_structures.clear();
+    sec_structures.reserve(transformed_sec_structures.size());
+    for(auto it = transformed_sec_structures.begin();
+        it != transformed_sec_structures.end(); ++it) {
+      switch(*it) {
+        case 0: {
+          sec_structures.push_back(ost::mol::SecStructure::ALPHA_HELIX);
+          break;
+        }
+        case 1: {
+          sec_structures.push_back(ost::mol::SecStructure::COIL);
+          break;
+        }
+        case 2: {
+          sec_structures.push_back(ost::mol::SecStructure::THREE_TEN_HELIX);
+          break;
+        }
+        case 3: {
+          sec_structures.push_back(ost::mol::SecStructure::TURN);
+          break;
+        }
+        case 4: {
+          sec_structures.push_back(ost::mol::SecStructure::EXTENDED);
+          break;
+        }
+        case 5: {
+          sec_structures.push_back(ost::mol::SecStructure::BETA_BRIDGE);
+          break;
+        }
+        case 6: {
+          sec_structures.push_back(ost::mol::SecStructure::BEND);
+          break;
+        }
+        case 7: {
+          sec_structures.push_back(ost::mol::SecStructure::PI_HELIX);
+          break;
+        }
+        default: {
+          throw ost::Error("Invalid sec structure observed");
+        }
+      }
+    }
+  }
+
+  void DumpSecStructures(std::ostream& stream,
+                         const std::vector<char>& sec_structures) {
+    std::vector<int> transformed_sec_structures;
+    transformed_sec_structures.reserve(sec_structures.size());
+    for(auto it = sec_structures.begin(); it != sec_structures.end(); ++it) {
+      switch(*it) {
+        case ost::mol::SecStructure::ALPHA_HELIX: {
+          transformed_sec_structures.push_back(0);
+          break;
+        }
+        case ost::mol::SecStructure::COIL: {
+          transformed_sec_structures.push_back(1);
+          break;
+        }
+        case ost::mol::SecStructure::THREE_TEN_HELIX: {
+          transformed_sec_structures.push_back(2);
+          break;
+        }
+        case ost::mol::SecStructure::TURN: {
+          transformed_sec_structures.push_back(3);
+          break;
+        }
+        case ost::mol::SecStructure::EXTENDED: {
+          transformed_sec_structures.push_back(4);
+          break;
+        }
+        case ost::mol::SecStructure::BETA_BRIDGE: {
+          transformed_sec_structures.push_back(5);
+          break;
+        }
+        case ost::mol::SecStructure::BEND: {
+          transformed_sec_structures.push_back(6);
+          break;
+        }
+        case ost::mol::SecStructure::PI_HELIX: {
+          transformed_sec_structures.push_back(7);
+          break;
+        }
+        default: {
+          throw ost::Error("Invalid sec structure observed");
+        }
+      }
+    }
+    std::vector<int> run_length_encoded;
+    RunLengthEncoding(transformed_sec_structures, run_length_encoded);
+    Dump(stream, run_length_encoded);
+  }
 }
 
 
@@ -922,7 +1041,7 @@ void ChainData::ToStream(std::ostream& stream,
   DumpBonds(stream, bonds);
   DumpBondOrders(stream, bond_orders);
   if(!skip_ss) {
-    DumpIntVec(stream, sec_structures);
+    DumpSecStructures(stream, sec_structures);
   }
 }
 
@@ -958,7 +1077,11 @@ void ChainData::FromStream(std::istream& stream,
   if(skip_ss) {
     sec_structures.assign(res_def_indices.size(), 'C');
   } else {
-    LoadIntVec(stream, sec_structures);
+    if(version >= 2) {
+      LoadSecStructures(stream, sec_structures);
+    } else {
+      LoadIntVec(stream, sec_structures);
+    }
   }
 }