Index: trunk/FACT++/src/Splitting.h
===================================================================
--- trunk/FACT++/src/Splitting.h	(revision 19802)
+++ trunk/FACT++/src/Splitting.h	(revision 19802)
@@ -0,0 +1,128 @@
+#ifndef FACT_Splitting
+#define FACT_Splitting
+
+#include <map>
+#include <vector>
+#include <random>
+#include <stdexcept>
+#include <algorithm>
+
+#include "Configuration.h"
+
+namespace Tools
+{
+    class Splitting
+    {
+        std::uniform_real_distribution<double> distribution;
+        std::mt19937_64 generator;
+        uint64_t seed;
+
+        std::vector<uint16_t> seq;
+        std::vector<double> quant;
+
+        size_t num;
+
+        std::map<size_t, size_t> lut;
+
+    public:
+        static const po::options_description &options()
+        {
+            static po::options_description split("Splitting options");
+            if (split.find_nothrow("seed", false))
+                return split;
+
+            split.add_options()
+                ("split-sequence,S", vars<uint16_t>(), "Split data sequentially into several trees/files (e.g. 1, 1, 2)")
+                ("split-quantile,Q", vars<double>(),   "Split data randomly into several trees/files (e.g. 0.5, 1)")
+                ("seed", var<uint64_t>(std::mt19937_64::default_seed), "Seed value in case of random split")
+                ;
+
+            return split;
+        }
+
+        static const char *usage()
+        {
+            return
+                "For several purposes, it might be convenient to split the output to several "
+                "different root-treess. This can be done using the --split-sequence (-S) "
+                "and the --split-quantile (-Q) options. If a split sequence is defined as "
+                "-S 1 -S 2 -S 1 the events are split by 1:2:1 in this sequence order. If "
+                "quantiles are given as -Q 0.5 -Q 0.6, the first tree will contain 50% of "
+                "the second one 10% and the third one 40%. The corresponding seed value can "
+                "be set with --seed.\n";
+        }
+
+        Splitting(Configuration &conf) : distribution(0, 1)
+        {
+            seq   = conf.Vec<uint16_t>("split-sequence");
+            quant = conf.Vec<double>("split-quantile");
+
+            if (!seq.empty() && !quant.empty())
+                throw std::runtime_error("Only splitting by --split-sequence or --split-quantile is allowed.");
+
+            num = seq.size()+quant.size()==0 ? 0 : std::max(seq.size(), quant.size()+1);
+
+            for (size_t i=0; i<seq.size(); i++)
+            {
+                const size_t sz = lut.size();
+                for (size_t j=0; j<seq[i]; j++)
+                    lut.emplace(j+sz, i);
+            }
+
+            for (size_t i=0; i<quant.size(); i++)
+                if (quant[i]<0 || quant[i]>=1)
+                    throw std::runtime_error("Splitting quantiles must be in the range [0;1)");
+
+            for (size_t i=1; i<quant.size(); i++)
+            {
+                if (quant[i]<=quant[i-1])
+                    throw std::runtime_error("Splitting quantiles must be in increasing order.");
+            }
+
+            seed = conf.Get<uint64_t>("seed");
+            generator.seed(seed);
+
+            //auto rndm = std::bind(distribution, generator);
+            //(bind(&StateMachineFTM::ResetConfig, this))
+        }
+
+        size_t index(const size_t &count) /*const*/
+        {
+            size_t index = 0;
+            if (!lut.empty())
+                index = lut.find(count % lut.size())->second;
+
+            if (quant.empty())
+                return index;
+
+            const double rndm = distribution(generator);
+            for (; rndm>=quant[index]; index++)
+                if (index==quant.size())
+                    return index;
+
+            return index;
+        }
+
+        void print()
+        {
+            if (!num)
+                return;
+
+            std::cout << "Splitting configured " << (seq.empty()?"randomly":"in sequence") << " into " << num << " branches.";
+            if (!quant.empty())
+                std::cout << "\nSeed value configured as " << seed << ".";
+            std::cout << std::endl;
+        }
+
+        const size_t &size() const
+        {
+            return num;
+        }
+
+        const bool empty() const
+        {
+            return num==0;
+        }
+    };
+};
+#endif
Index: trunk/FACT++/src/csv2root.cc
===================================================================
--- trunk/FACT++/src/csv2root.cc	(revision 19798)
+++ trunk/FACT++/src/csv2root.cc	(revision 19802)
@@ -1,4 +1,2 @@
-#include <random>
-
 #include <boost/regex.hpp>
 #include <boost/filesystem.hpp>
@@ -7,5 +5,5 @@
 #include "tools.h"
 #include "Time.h"
-#include "Configuration.h"
+#include "Splitting.h"
 
 #include <TROOT.h>
@@ -18,4 +16,7 @@
 using namespace std;
 namespace fs = boost::filesystem;
+
+// ------------------------------------------------------------------------
+
 
 // ------------------------------------------------------------------------
@@ -32,16 +33,6 @@
         ("compression,c",  var<uint16_t>(1),          "zlib compression level for the root file")
         ("no-header,n",    po_switch(),               "Use if the first line contains no header")
+        ("rename.*",       var<string>(),             "Can be used to rename a column")
         ("dry-run",        po_switch(),               "Do not create or manipulate any output file")
-        ;
-
-    po::options_description split("Splitting options");
-    split.add_options()
-        ("split-sequence,S", vars<uint16_t>(),            "Split data sequentially into several trees/files (e.g. 1, 1, 2)")
-        ("split-quantile,Q", vars<double>(),              "Split data randomly into several trees/files (e.g. 0.5, 1)")
-        ("seed", var<uint64_t>(mt19937_64::default_seed), "Seed value in case of random split")
-        ;
-
-    po::options_description debug("Debug options");
-    debug.add_options()
         ("verbose,v",      var<uint16_t>(1),          "Verbosity (0: quiet, 1: default, 2: more, 3, ...)")
         ;
@@ -53,6 +44,5 @@
 
     conf.AddOptions(control);
-    conf.AddOptions(split);
-    conf.AddOptions(debug);
+    conf.AddOptions(Tools::Splitting::options());
     conf.SetArgumentPositions(p);
 }
@@ -90,11 +80,7 @@
         "with --compression.\n"
         "\n"
-        "For several purposes, it might be convenient to split the output to several "
-        "different root-treess. This can be done using the --split-sequence (-S) "
-        "and the --split-quantile (-Q) options. If a split sequence is defined as "
-        "-S 1 -S 2 -S 1 the events are split by 1:2:1 in this sequence order. If "
-        "quantiles are given as -Q 0.5 -Q 0.6, the first tree will contain 50% of "
-        "the second one 10% and the third one 40%. The corresponding seed value can "
-        "be set with --seed.\n"
+        "Columns can be renamed with --rename.new=old\n"
+        "\n"
+        << Tools::Splitting::usage() <<
         "\n"
         "In case of success, 0 is returned, a value>0 otherwise.\n"
@@ -178,41 +164,7 @@
     }
 
-    // ----------------------------- Setup splitting ---------------------------
-
-    vector<uint16_t> split_seq   = conf.Vec<uint16_t>("split-sequence");
-    vector<double>   split_quant = conf.Vec<double>("split-quantile");
-
-    if (!split_seq.empty() && !split_quant.empty())
-        throw runtime_error("Only splitting by --split-sequence or --split-quantile is allowed.");
-
-    const size_t num_split = split_seq.size()+split_quant.size()==0 ? 0 :
-        ::max(split_seq.size(), split_quant.size()+1);
-
-    map<size_t, size_t> split_lut;
-    for (size_t i=0; i<split_seq.size(); i++)
-    {
-        const size_t sz = split_lut.size();
-        for (size_t j=0; j<split_seq[i]; j++)
-            split_lut.emplace(j+sz, i);
-    }
-
-    for (size_t i=0; i<split_quant.size(); i++)
-        if (split_quant[i]<0 || split_quant[i]>=1)
-            throw runtime_error("Splitting quantiles must be in the range [0;1)");
-
-    for (size_t i=1; i<split_quant.size(); i++)
-    {
-        if (split_quant[i]<=split_quant[i-1])
-            throw runtime_error("Splitting quantiles must be in increasing order.");
-    }
-
     // -------------------------------------------------------------------------
 
-    const uniform_real_distribution<double> distribution(0,1);
-    mt19937_64 generator;
-    generator.seed(conf.Get<uint64_t>("seed"));
-    auto rndm = bind(distribution, generator);
-
-    // -------------------------------------------------------------------------
+    /*const*/ Tools::Splitting split(conf);
 
     if (verbose>0)
@@ -300,4 +252,5 @@
         cout << "Opened root file '" << path << "'.\n";
         cout << "Writing to tree: " << tree << ".\n";
+        split.print();
     }
 
@@ -306,5 +259,5 @@
 
     size_t entries = 0;
-    if (num_split==0)
+    if (split.empty())
     {
         if (AddTree(ttree, tfile, tree, update, verbose))
@@ -318,5 +271,5 @@
     {
         bool found = false;
-        for (size_t i=0; i<num_split; i++)
+        for (size_t i=0; i<split.size(); i++)
             found |= AddTree(ttree, tfile, tree+"["+to_string(i)+"]", update, verbose);
 
@@ -328,4 +281,6 @@
     }
 
+    const auto rename = conf.GetWildcardOptions("rename.*");
+
     vector<float> vec(numcol);
     for (int i=0; i<numcol; i++)
@@ -333,9 +288,25 @@
         string col = noheader ? Tools::Form("col%d", i) : title->At(i)->GetName();
 
+        if (verbose>1)
+            cout << "Column: " << col;
+
         boost::regex rexpr(":");
         col = boost::regex_replace(col, rexpr, "");
 
         if (verbose>1)
-            cout << "Column: " << col << '\n';
+            cout << " -> " << col;
+
+        for (auto it=rename.cbegin(); it!=rename.cend(); it++)
+        {
+            if (col!=it->substr(7))
+                continue;
+
+            col = conf.Get<string>(*it);
+            if (verbose>1)
+                cout << " -> " << col;
+            break;
+        }
+        if (verbose>1)
+            cout << endl;
 
         for (auto it=ttree.begin(); it!=ttree.end(); it++)
@@ -361,6 +332,4 @@
         if (buf.IsNull() || buf[0]=='#')
             continue;
-
-        valid++;
 
         TObjArray *arr = buf.Tokenize(" ");
@@ -386,15 +355,5 @@
         delete arr;
 
-
-        size_t index = 0;
-        if (!split_lut.empty())
-            index = split_lut[line % split_lut.size()];
-        if (!split_quant.empty())
-        {
-            const float r = rndm();
-            for (; r>=split_quant[index]; index++)
-                if (index==split_quant.size())
-                    break;
-        }
+        const size_t index = split.index(valid++);
 
         // Fill only branches for which an adress was set
Index: trunk/FACT++/src/root2csv.cc
===================================================================
--- trunk/FACT++/src/root2csv.cc	(revision 19798)
+++ trunk/FACT++/src/root2csv.cc	(revision 19802)
@@ -1,4 +1,2 @@
-#include <random>
-
 #include <boost/regex.hpp>
 #include <boost/filesystem.hpp>
@@ -7,5 +5,5 @@
 #include "tools.h"
 #include "Time.h"
-#include "Configuration.h"
+#include "Splitting.h"
 
 #include <TROOT.h>
@@ -65,11 +63,4 @@
         ;
 
-    po::options_description split("Splitting options");
-    split.add_options()
-        ("split-sequence,S", vars<uint16_t>(),            "Split data sequentially into several trees/files (e.g. 1, 1, 2)")
-        ("split-quantile,Q", vars<double>(),              "Split data randomly into several trees/files (e.g. 0.5, 1)")
-        ("seed", var<uint64_t>(mt19937_64::default_seed), "Seed value in case of random split")
-        ;
-
     po::options_description debug("Debug options");
     debug.add_options()
@@ -84,5 +75,5 @@
 
     conf.AddOptions(control);
-    conf.AddOptions(split);
+    conf.AddOptions(Tools::Splitting::options());
     conf.AddOptions(debug);
     conf.SetArgumentPositions(p);
@@ -169,12 +160,5 @@
         "and all negative values are considered 'fales' (discard the entry).\n"
         "\n"
-        "For several purposes, it might be convenient to split the output to several "
-        "files. This can be achieved using the --split-sequence (-S) "
-        "and the --split-quantile (-Q) options. If a split sequence is defined as "
-        "-S 1 -S 2 -S 1 the events are split by 1:2:1 in this sequence order. If "
-        "quantiles are given as -Q 0.5 -Q 0.6, the first tree will contain 50% of "
-        "the second one 10% and the third one 40%. The corresponding seed value can "
-        "be set with --seed. Filenames are then created by adding an index after(!) "
-        "the extension, e.g. file.csv-0, file.csv-1, ...\n"
+        << Tools::Splitting::usage() <<
         "\n"
         "In case of success, 0 is returned, a value>0 otherwise.\n"
@@ -403,41 +387,7 @@
     const vector<Map> autoalias  = conf.Vec<Map>("auto-alias");
 
-    // ----------------------------- Setup splitting ---------------------------
-
-    vector<uint16_t> split_seq   = conf.Vec<uint16_t>("split-sequence");
-    vector<double>   split_quant = conf.Vec<double>("split-quantile");
-
-    if (!split_seq.empty() && !split_quant.empty())
-        throw runtime_error("Only splitting by --split-sequence or --split-quantile is allowed.");
-
-    const size_t num_split = split_seq.size()+split_quant.size()==0 ? 0 :
-        ::max(split_seq.size(), split_quant.size()+1);
-
-    map<size_t, size_t> split_lut;
-    for (size_t i=0; i<split_seq.size(); i++)
-    {
-        const size_t sz = split_lut.size();
-        for (size_t j=0; j<split_seq[i]; j++)
-            split_lut.emplace(j+sz, i);
-    }
-
-    for (size_t i=0; i<split_quant.size(); i++)
-        if (split_quant[i]<0 || split_quant[i]>=1)
-            throw runtime_error("Splitting quantiles must be in the range [0;1)");
-
-    for (size_t i=1; i<split_quant.size(); i++)
-    {
-        if (split_quant[i]<=split_quant[i-1])
-            throw runtime_error("Splitting quantiles must be in increasing order.");
-    }
-
     // -------------------------------------------------------------------------
 
-    const uniform_real_distribution<double> distribution(0,1);
-    mt19937_64 generator;
-    generator.seed(conf.Get<uint64_t>("seed"));
-    auto rndm = bind(distribution, generator);
-
-    // -------------------------------------------------------------------------
+    /*const*/ Tools::Splitting split(conf);
 
     if (verbose>0)
@@ -780,9 +730,8 @@
     // -------------------------------------------------------------------------
 
-    if (num_split)
-    {
-        cout << "\nSplitting configured " << (split_seq.empty()?"randomly":"in sequence") << " into " << num_split << " files." << endl;
-        if (!split_quant.empty())
-            cout << "Seed value configured as " << conf.Get<uint64_t>("seed") << "." << endl;
+    if (verbose>0)
+    {
+        cout << '\n';
+        split.print();
     }
 
@@ -798,5 +747,5 @@
     vector<ofstream> outfiles;
 
-    if (num_split==0)
+    if (split,empty())
     {
         TString path(out.c_str());
@@ -811,5 +760,5 @@
     else
     {
-        for (size_t i=0; i<num_split; i++)
+        for (size_t i=0; i<split.size(); i++)
         {
             TString path(out.c_str());
@@ -828,5 +777,5 @@
     // ---------------------------- Write Body --------------------------------
     size_t count = 0;
-    vector<size_t> ncount(num_split?num_split:1);
+    vector<size_t> ncount(split.empty()?1:split.size());
 
     auto itree = c.GetTreeNumber();
@@ -848,14 +797,6 @@
             continue;
 
-        size_t index = 0;
-        if (!split_lut.empty())
-            index = split_lut[count % split_lut.size()];
-        if (!split_quant.empty())
-        {
-            const float r = rndm();
-            for (; r>=split_quant[index]; index++)
-                if (index==split_quant.size())
-                    break;
-        }
+        const size_t index = split.index(count++);
+        ncount[index]++;
 
         vector<string> join;
@@ -875,7 +816,4 @@
 
         outfiles[index] << boost::join(join, " ") << "\n";
-
-        count ++;
-        ncount[index] ++;
     }
 
Index: trunk/FACT++/src/rootifysql.cc
===================================================================
--- trunk/FACT++/src/rootifysql.cc	(revision 19798)
+++ trunk/FACT++/src/rootifysql.cc	(revision 19802)
@@ -1,5 +1,3 @@
 #include "Database.h"
-
-#include <random>
 
 #include <boost/regex.hpp>
@@ -10,5 +8,5 @@
 #include "tools.h"
 #include "Time.h"
-#include "Configuration.h"
+#include "Splitting.h"
 
 #include <TROOT.h>
@@ -62,11 +60,4 @@
         ;
 
-    po::options_description split("Splitting options");
-    split.add_options()
-        ("split-sequence,S", vars<uint16_t>(),            "Split data sequentially into several trees/files (e.g. 1, 1, 2)")
-        ("split-quantile,Q", vars<double>(),              "Split data randomly into several trees/files (e.g. 0.5, 1)")
-        ("seed", var<uint64_t>(mt19937_64::default_seed), "Seed value in case of random split")
-        ;
-
     po::positional_options_description p;
     p.add("file", 1); // The 1st positional options (n=1)
@@ -76,5 +67,5 @@
     conf.AddOptions(ascii);
     conf.AddOptions(root);
-    conf.AddOptions(split);
+    conf.AddOptions(Tools::Splitting::options());
     conf.SetArgumentPositions(p);
 }
@@ -125,11 +116,5 @@
         "/*comment*/ or introduced with # (shell script style) or -- (SQL style).\n"
         "\n"
-        "For several purposes, it might be convenient to split the output to several "
-        "different root-trees or ascii files. This can be done using the --split-sequence (-S) "
-        "and the --split-quantile (-Q) options. If a split sequence is defined as "
-        "-S 1 -S 2 -S 1 the events are split by 1:2:1 in this sequence order. If "
-        "quantiled are given as -Q 0.5 -Q 0.6, the first tree will contain 50% of "
-        "the second one 10% and the third one 40%. The corresponding seed value can "
-        "be set with --seed.\n"
+        << Tools::Splitting::usage() <<
         "\n"
         "In case of success, 0 is returned, a value>0 otherwise.\n"
@@ -522,33 +507,4 @@
     // ----------------------- Setup splitting ---------------------------------
 
-    vector<uint16_t> split_seq   = conf.Vec<uint16_t>("split-sequence");
-    vector<double>   split_quant = conf.Vec<double>("split-quantile");
-
-    if (!split_seq.empty() && !split_quant.empty())
-        throw runtime_error("Only splitting by --split-sequence or --split-quantile is allowed.");
-
-    const size_t num_split = split_seq.size()+split_quant.size()==0 ? 0 :
-        ::max(split_seq.size(), split_quant.size()+1);
-
-    map<size_t, size_t> split_lut;
-    for (size_t i=0; i<split_seq.size(); i++)
-    {
-        const size_t sz = split_lut.size();
-        for (size_t j=0; j<split_seq[i]; j++)
-            split_lut.emplace(j+sz, i);
-    }
-
-    for (size_t i=0; i<split_quant.size(); i++)
-        if (split_quant[i]<0 || split_quant[i]>=1)
-            throw runtime_error("Splitting quantiles must be in the range [0;1)");
-
-    for (size_t i=1; i<split_quant.size(); i++)
-    {
-        if (split_quant[i]<=split_quant[i-1])
-            throw runtime_error("Splitting quantiles must be in increasing order.");
-    }
-
-    // -------------------------------------------------------------------------
-
     const auto vars = conf.GetWildcardOptions("var.*");
 
@@ -558,4 +514,6 @@
 
     // -------------------------------------------------------------------------
+
+    /*const*/ Tools::Splitting split(conf);
 
     if (verbose>0)
@@ -826,10 +784,5 @@
         cout << "Opening file '" << path << "' [compression=" << compression << "]...\n";
         cout << "Writing data to tree '" << tree << "'" << (nofill?" (--skipped--)":"") << endl;
-        if (num_split)
-        {
-            cout << "Splitting configured " << (split_seq.empty()?"randomly":"in sequence") << " into " << num_split << " branches." << endl;
-            if (!split_quant.empty())
-                cout << "Seed value configured as " << conf.Get<uint64_t>("seed") << "." << endl;
-        }
+        split.print();
     }
 
@@ -875,8 +828,8 @@
     vector<TTree*> ttree;
 
-    if (num_split==0)
+    if (split.empty())
         ttree.emplace_back(new TTree(tree.c_str(), query.c_str()));
     else
-        for (size_t i=0; i<num_split; i++)
+        for (size_t i=0; i<split.size(); i++)
             ttree.emplace_back(new TTree((tree+"["+to_string(i)+"]").c_str(), query.c_str()));
 
@@ -955,8 +908,8 @@
     {
         vector<string> names;
-        if (num_split==0)
+        if (split.empty())
             names.emplace_back(write);
         else
-            for (size_t i=0; i<num_split; i++)
+            for (size_t i=0; i<split.size(); i++)
                 names.emplace_back(write+"-"+to_string(i));
 
@@ -1017,25 +970,9 @@
     // ---------------------- Fill TTree with DB data --------------------------
 
-    const uniform_real_distribution<double> distribution(0,1);
-    mt19937_64 generator;
-    generator.seed(conf.Get<uint64_t>("seed"));
-    auto rndm = bind(distribution, generator);
-
     size_t count = 0;
     size_t skip  = 0;
     do
     {
-        size_t index = 0;
-        if (!split_lut.empty())
-            index = split_lut[count % split_lut.size()];
-        if (!split_quant.empty())
-        {
-            const float r = rndm();
-            for (; r>=split_quant[index]; index++)
-                if (index==split_quant.size())
-                    break;
-        }
-
-        count++;
+        size_t index = split.index(count++);
 
         ostringstream rtxt;
