Index: src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.cpp
===================================================================
--- src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.cpp	(revision e0ae58d2284a52b479b4bafd7533855451f64a6c)
+++ src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.cpp	(revision 0588e9997198820786bc31f4c69ab48e55ac174a)
@@ -42,6 +42,8 @@
 
 #include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
 #include <boost/mpl/remove.hpp>
 
+#include <algorithm>
 #include <fstream>
 #include <iostream>
@@ -100,4 +102,24 @@
 }
 
+/** Print cycle correction from received results.
+ *
+ * @param results summed up results container
+ */
+void printReceivedCycleResults(
+    const FragmentationShortRangeResults &results)
+{
+  typedef boost::mpl::remove<
+        boost::mpl::remove<MPQCDataEnergyVector_t, MPQCDataFused::energy_eigenvalues>::type,
+      MPQCDataFused::energy_eigenhistogram>::type
+    MPQCDataEnergyVector_noeigenvalues_t;
+  const std::string energyresult =
+      writeTable<MPQCDataEnergyMap_t, MPQCDataEnergyVector_noeigenvalues_t >()(
+          results.Result_Energy_fused, results.getMaxLevel());
+  LOG(2, "DEBUG: Energy table is \n" << energyresult);
+  std::string filename;
+  filename += FRAGMENTPREFIX + std::string("_CycleEnergy.dat");
+  writeToFile(filename, energyresult);
+}
+
 /** Print (short range) energy, forces, and timings from received results.
  *
@@ -324,7 +346,36 @@
 }
 
+// this it taken from
+// http://stackoverflow.com/questions/2291802/is-there-a-c-iterator-that-can-iterate-over-a-file-line-by-line
+namespace detail
+{
+  /** Extend the string class by a friend function.
+   *
+   */
+  class Line : public std::string
+  {
+    friend std::istream & operator>>(std::istream & is, Line & line)
+    {
+      return std::getline(is, line);
+    }
+  };
+}
+
+/** Parse the given stream line-by-line, passing each to \a dest.
+ *
+ * \param is stream to parse line-wise
+ * \param dest output iterator
+ */
+template<class OutIt>
+void read_lines(std::istream& is, OutIt dest)
+{
+    typedef std::istream_iterator<detail::Line> InIt;
+    std::copy(InIt(is), InIt(), dest);
+}
+
+
 ActionState::ptr FragmentationAnalyseFragmentationResultsAction::performCall() {
 
-  // if file is given, parse from file into resultscontainer
+  /// if file is given, parse from file into ResultsContainer
   FragmentationResultContainer& container = FragmentationResultContainer::getInstance();
   if (!params.resultsfile.get().empty()) {
@@ -342,5 +393,5 @@
   }
 
-  // get data and keysets from ResultsContainer
+  /// get data and keysets from ResultsContainer
   const std::map<JobId_t, MPQCData> &shortrangedata = container.getShortRangeResults();
   const KeySetsContainer &keysets = container.getKeySets();
@@ -354,8 +405,115 @@
   }
 
+  /// calculate normal contributions with (if present) cycles coming at their
+  /// respective bond order.
   std::vector<bool> ValueMask(shortrangedata.size(), true);
   FragmentationShortRangeResults shortrangeresults(shortrangedata, keysets, forcekeysets, ValueMask);
   shortrangeresults(shortrangedata);
   printReceivedShortResults(shortrangeresults);
+
+  /// now do we need to calculate the cycle contribution
+  // check whether there are cycles in container or else in file
+  KeySetsContainer cycles = container.getCycles();
+  if (cycles.KeySets.empty()) {
+    // parse from file if cycles is empty
+    boost::filesystem::path filename(
+        params.prefix.get() + std::string(CYCLEKEYSETFILE));
+    if (boost::filesystem::exists(filename)) {
+      LOG(1, "INFO: Parsing cycles file " << filename.string() << ".");
+      // parse file line by line
+      std::ifstream File;
+      File.open(filename.string().c_str());
+      typedef std::istream_iterator<detail::Line> InIt;
+      for (InIt iter = InIt(File); iter != InIt(); ++iter) {
+        KeySetsContainer::IntVector cycle;
+        std::stringstream line(*iter);
+        while (line.good()) {
+          int id;
+          line >> id >> ws;
+          cycle.push_back(id);
+        }
+        if (!cycle.empty()) {
+          LOG(2, "DEBUG: Adding cycle " << cycle << ".");
+          cycles.insert( cycle, cycle.size());
+        }
+      }
+      File.close();
+    } else {
+      LOG(1, "INFO: Cycles file not found at " << filename.string() << ".");
+    }
+  }
+
+  // copy the shortrangeresults such that private MaxLevel is set in
+  // FragmentationShortRangeResults
+  FragmentationShortRangeResults cycleresults(shortrangeresults);
+  // calculate energy if cycles are calculated fully at each level already
+  if (!cycles.KeySets.empty()) {
+    // gather cycle sizes
+    std::vector<size_t> cyclesizes(cycles.KeySets.size());
+    std::transform(
+        cycles.KeySets.begin(), cycles.KeySets.end(),
+        cyclesizes.begin(),
+        boost::bind(&KeySetsContainer::IntVector::size, boost::lambda::_1)
+    );
+    // get maximum
+    std::vector<size_t>::const_iterator maximum_size =
+        std::max_element(cyclesizes.begin(), cyclesizes.end());
+
+    // loop from level 1 to max ring size and gather corrections
+    for (size_t level = 1; level <= *maximum_size; ++level) {
+      // create ValueMask for this level by stepping through each keyset and checking size
+      std::vector<bool> localValueMask(shortrangedata.size(), false);
+      size_t index=0;
+      KeySetsContainer::ArrayOfIntVectors::const_iterator keysetsiter = keysets.KeySets.begin();
+      KeySetsContainer::ArrayOfIntVectors::const_iterator cyclesiter = cycles.KeySets.begin();
+      for (; (keysetsiter != keysets.KeySets.end()) && (cyclesiter != cycles.KeySets.end());) {
+        if (cyclesiter->size() > keysetsiter->size()) {
+          // add if not greater than level in size
+          if ((*keysetsiter).size() <= level)
+            localValueMask[index] = true;
+          ++keysetsiter;
+          ++index;
+        } else if (cyclesiter->size() < keysetsiter->size()) {
+          ++cyclesiter;
+        } else { // both sets have same size
+          if (*cyclesiter > *keysetsiter) {
+            // add if not greater than level in size
+            if ((*keysetsiter).size() <= level)
+              localValueMask[index] = true;
+            ++keysetsiter;
+            ++index;
+          } else if (*cyclesiter < *keysetsiter) {
+            ++cyclesiter;
+          } else {
+            // also always add all cycles
+            localValueMask[index] = true;
+            ++cyclesiter;
+            ++keysetsiter;
+            ++index;
+          }
+        }
+      }
+      // activate rest if desired by level
+      for (; keysetsiter != keysets.KeySets.end(); ++keysetsiter) {
+        if ((*keysetsiter).size() <= level)
+          localValueMask[index] = true;
+        ++index;
+      }
+      LOG(2, "DEBUG: ValueMask for cycle correction at level " << level << " is "
+          << localValueMask << ".");
+      // create FragmentationShortRangeResults
+      FragmentationShortRangeResults localresults(shortrangedata, keysets, forcekeysets, localValueMask);
+      // and perform summation
+      localresults(shortrangedata);
+      // finally, extract the corrections
+      cycleresults.Result_Energy_fused[level-1] =
+          localresults.Result_Energy_fused.back();
+      cycleresults.Result_Time_fused[level-1] =
+          localresults.Result_Time_fused.back();
+      cycleresults.Result_Force_fused[level-1] =
+          localresults.Result_Force_fused.back();
+    }
+    printReceivedCycleResults(cycleresults);
+  }
 
   // adding obtained forces
Index: src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.def
===================================================================
--- src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.def	(revision e0ae58d2284a52b479b4bafd7533855451f64a6c)
+++ src/Actions/FragmentationAction/AnalyseFragmentationResultsAction.def	(revision 0588e9997198820786bc31f4c69ab48e55ac174a)
@@ -8,4 +8,5 @@
 // all includes and forward declarations necessary for non-integral types below
 #include <boost/filesystem/path.hpp>
+#include <string>
 
 #include "Parameters/Validators/DummyValidator.hpp"
@@ -14,12 +15,13 @@
 // ValueStorage by the token "Z" -> first column: int, Z, "Z"
 // "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value
-#define paramtypes (boost::filesystem::path)(bool)
-#define paramtokens ("fragment-resultfile")("store-grids")
-#define paramdescriptions ("parse fragment results from the given file")("whether to store sampled grids in homology files")
-#define paramdefaults (PARAM_DEFAULT(""))(PARAM_DEFAULT("0"))
-#define paramreferences (resultsfile)(DoStoreGrids)
+#define paramtypes (boost::filesystem::path)(bool)(std::string)
+#define paramtokens ("fragment-resultfile")("store-grids")("fragment-prefix")
+#define paramdescriptions ("parse fragment results from the given file")("whether to store sampled grids in homology files")("prefix of each fragment file")
+#define paramdefaults (PARAM_DEFAULT(""))(PARAM_DEFAULT("0"))(NOPARAM_DEFAULT)
+#define paramreferences (resultsfile)(DoStoreGrids)(prefix)
 #define paramvalids \
 (DummyValidator< boost::filesystem::path >()) \
-(DummyValidator< bool >())
+(DummyValidator< bool >()) \
+(DummyValidator< std::string >())
 
 #undef statetypes
