diff --git a/FastNLO/include/FastNLOxFitter.h b/FastNLO/include/FastNLOxFitter.h
index 3ab450a619ae506be8cf011bf87863f6ee668ac0..89f8e33dfe3e0b4a632481e3dfc4e096555ab495 100644
--- a/FastNLO/include/FastNLOxFitter.h
+++ b/FastNLO/include/FastNLOxFitter.h
@@ -26,12 +26,12 @@
 class FastNLOxFitter : public fastNLOReader {
 
 public:
-   FastNLOxFitter(string name);
+   FastNLOxFitter(std::string name);
 
 protected:
    // inherited functions
    double EvolveAlphas(double Q ) const ;
    bool InitPDF();
-   vector<double> GetXFX(double xp, double muf) const ;
+   std::vector<double> GetXFX(double xp, double muf) const ;
 };
 #endif
diff --git a/FastNLO/include/fastnlotk/HoppetInterface.h b/FastNLO/include/fastnlotk/HoppetInterface.h
deleted file mode 100644
index ce929dfe619cecdcbb5adc38449fafdde547019a..0000000000000000000000000000000000000000
--- a/FastNLO/include/fastnlotk/HoppetInterface.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <vector>
-
-class fastNLOReader;
-
-extern "C" void evolvepdf_(const double& x, const double& Q, double* xf);
-
-class HoppetInterface {
-   public:
-      static void InitHoppet(fastNLOReader&) {};
-      static std::vector<double> GetSpl(double, double) {return std::vector<double>();};
-      static std::vector<double> GetXFX(double, double) {return std::vector<double>();};
-      static double EvolveAlphas(double) {return 0;};
-      static bool IsInitialized;
-      // ---- Alphas vars ---- //
-      static double fAlphasMz;
-      static double fMz;
-      static int fnFlavor;
-      static int fnLoop;
-      static double QMass[6];
-      // ____ //
-   private:
-      static void StartHoppet(){};
-      static void LHAsub(const double &, const double &, double*){};
-      static fastNLOReader *fnlo;
-};
diff --git a/FastNLO/include/fastnlotk/Makefile.am b/FastNLO/include/fastnlotk/Makefile.am
index b23c08cb83266ac7f4b67a2c00fb37b873be6b57..2337210b3d5574bd99030b6f82eb93bd562a019b 100644
--- a/FastNLO/include/fastnlotk/Makefile.am
+++ b/FastNLO/include/fastnlotk/Makefile.am
@@ -1,6 +1,6 @@
 AUTOMAKE_OPTIONS = foreign
 
 dist_noinst_HEADERS = \
-fastNLOBase.h          fastNLOCoeffAddFlex.h  fastNLOCoefficients.h  fastNLOPDFLinearCombinations.h  fastNLOTools.h \
-fastNLOCoeffAddBase.h  fastNLOCoeffBase.h     fastNLOCoeffMult.h     fastNLOReader.h                 HoppetInterface.h \
+fastNLOCoeffAddFlex.h  fastNLOCoefficients.h  fastNLOPDFLinearCombinations.h  fastNLOTools.h \
+fastNLOCoeffAddBase.h  fastNLOCoeffBase.h     fastNLOCoeffMult.h     fastNLOReader.h \
 fastNLOCoeffAddFix.h   fastNLOCoeffData.h     fastNLOConstants.h     fastNLOTable.h                  speaker.h
diff --git a/FastNLO/include/fastnlotk/fastNLOBase.h b/FastNLO/include/fastnlotk/fastNLOBase.h
deleted file mode 100644
index 79b2335c94354d6b940e97aa765a28555594a2a7..0000000000000000000000000000000000000000
--- a/FastNLO/include/fastnlotk/fastNLOBase.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef __fastNLOBase__
-#define __fastNLOBase__
-
-#include <fstream>
-#include <iostream>
-#include <istream>
-#include <string>
-#include "speaker.h"
-
-using namespace std;
-
-class fastNLOBase {
-
-public:
-   fastNLOBase();
-   fastNLOBase(string name);
-   fastNLOBase(const fastNLOBase&);
-   virtual ~fastNLOBase();
-
-   // i/o
-   virtual void ReadTable();                                                    //!< read table
-   virtual void WriteTable();                                                   //!< write full table to disk
-   virtual void Print() const;
-   // header
-   void PrintHeader() const;                                            //!< Print header variables (BlockA1) to screen
-   void SetHeaderDefaults();                                            //!< Set some default values
-   void ResetHeader();                                                  //!< Reset variables to default values
-   void SetContributionHeader();                                        //
-   bool IsCompatibleHeader(const fastNLOBase& other) const;             //!< Compare header with header of another table
-
-   // getter/setters
-   string GetFilename() const {return ffilename;}
-   void   SetFilename(string name){ffilename=name;}
-
-   int  GetItabversion() const {return Itabversion;}
-   void SetItabversion(int version){Itabversion = version;}
-
-   string GetScenName() const {return ScenName;}
-   void   SetScenName(string name){ScenName = name;}
-
-   int  GetNmult() const {return Nmult;}
-   void SetNmult(int n){Nmult = n;}
-
-   int  GetNuserString() const {return NuserString;}
-   void SetNuserString(int n){NuserString = n;}
-
-   int  GetNuserFloat() const {return NuserFloat;}
-   void SetNuserFloat(int n){NuserFloat = n;}
-
-   int  GetNcontrib() const {return Ncontrib;}
-   void SetNcontrib(int n){Ncontrib = n;}
-
-   int  GetNdata() const {return Ndata;}
-   void SetNdata(int n){Ndata = n;}
-
-   int  GetNuserInt() const {return NuserInt;}
-   void SetNuserInt(int n){NuserInt = n;}
-
-   int  GetImachine() const {return Imachine;}
-   void SetImachine(int n){Imachine = n;}
-
-   int  GetOutputPrecision() const {return fPrecision;}
-   void SetOutputPrecision(int precision) {fPrecision = precision;}
-
-
-protected:
-   void PrintWelcomeMessage();                                          //!< Say hello to fastNLO user
-   ofstream* OpenFileWrite();                                           //!< open ofstream for writing tables to ffilename
-   ifstream* OpenFileRead();                                            //!< open ifstream for reading table
-   //ofstream *OpenFileRewrite();
-   void WriteHeader(ostream& table);                                    //!< write (or cout) hader using ostream
-   void ReadHeader(istream& table);                                     //!< read header of table (BlockA1)
-   void CloseFileWrite(ofstream& table);
-   void CloseFileRead(ifstream& table);
-   //void CloseStream();
-
-   string ffilename;
-   //ifstream *ifilestream;
-   //ofstream *ofilestream;
-   int fPrecision;
-   // header
-   int Itabversion;
-   string ScenName;
-   int Ncontrib;
-   int Nmult;
-   int Ndata;
-   int NuserString;
-   int NuserInt;
-   int NuserFloat;
-   int Imachine;
-
-   PrimalScream logger;
-   static bool fWelcomeOnce;
-
-};
-#endif
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffAddBase.h b/FastNLO/include/fastnlotk/fastNLOCoeffAddBase.h
index 514e275e50f6d3b45e7bc652f8ceb94af7c18da5..7fd03443b5f10c84f3a09d046a1e5f8893e60457 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffAddBase.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffAddBase.h
@@ -5,7 +5,95 @@
 #include "fastNLOCoeffBase.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
+namespace fastNLO {
+   struct WgtStat {
+      double WgtNevt = 0; //!< 'number of events', i.e. normalisation as suggested by generator (identical to previously use 'Nevt')
+      int NumTable = 1; //!< Number of tables merged into this table
+      unsigned long long WgtNumEv = 0; //!< number of entries
+      double WgtSumW2 = 0; //!< Sum of all weight**2
+      double SigSumW2 = 0; //!< Sum of all sigma**2 (i.e. (wgt*alpha*pdf)**2 )
+      double SigSum = 0; //!< Sum of all sigma (i.e. (wgt*alpha*pdf)**2 )
+      fastNLO::v2d WgtObsSumW2; //!< sumw2[proc][obs]
+      fastNLO::v2d SigObsSumW2; //!< sumw2[proc][obs]
+      fastNLO::v2d SigObsSum;   //!< sum[proc][obs]
+      std::vector < std::vector < unsigned long long > > WgtObsNumEv; //!< Nentries[proc][obs]
+      //fastNLO::v2d SigObsUser;   //!< sum[proc][obs]
+
+      void Erase() {
+         WgtNevt=0;
+         NumTable=1;
+         WgtNumEv=0;
+         WgtSumW2=0;
+         SigSumW2=0;
+         SigSum=0;
+         for ( auto& i : WgtObsSumW2 ) for ( auto& j : i ) j=0;
+         for ( auto& i : SigObsSumW2 ) for ( auto& j : i ) j=0;
+         for ( auto& i : SigObsSum   ) for ( auto& j : i ) j=0;
+         for ( auto& i : WgtObsNumEv ) for ( auto& j : i ) j=0;
+         //for ( auto& i : SigObsUser  ) for ( auto& j : i ) j=0;
+      };
+
+      void Add(const WgtStat& other ) {
+         this->WgtNevt  += other.WgtNevt;
+         this->NumTable += other.NumTable;
+         this->WgtNumEv += other.WgtNumEv;
+         this->WgtSumW2 += other.WgtSumW2;
+         this->SigSumW2 += other.SigSumW2;
+         this->SigSum   += other.SigSum;
+         if ( this->WgtObsNumEv.size() != other.WgtObsNumEv.size() ) exit(8);
+         for ( unsigned int i = 0 ; i<WgtObsNumEv.size() ; i++ ) {
+            if ( this->WgtObsNumEv[i].size() != other.WgtObsNumEv[i].size() ) exit(8);
+            for ( unsigned int j = 0 ; j<WgtObsNumEv[i].size() ; j++ ) {
+               this->WgtObsSumW2[i][j] += other.WgtObsSumW2[i][j];
+               this->SigObsSumW2[i][j] += other.SigObsSumW2[i][j];
+               this->SigObsSum[i][j]   += other.SigObsSum[i][j];
+               this->WgtObsNumEv[i][j] += other.WgtObsNumEv[i][j];
+               //this->SigObsUser[i][j]  += other.SigObsUser[i][j];
+            }
+         }
+      };
+      WgtStat& operator+=(const WgtStat& other) { this->Add(other); return *this;}
+      
+      void SetWgtUser( const fastNLO::v2d& wgtUser ) {
+	 //! Set user weights
+	 //! wgtUser[proc][obs]
+	 if ( wgtUser.size()!=WgtObsNumEv.size() ) {
+	    std::cerr<<"Error [fastNLO::WgtStat::SetWgtUser()] Array with wrong size (wrong number of subprocesses. Must be "
+		     <<WgtObsNumEv.size()<<", but is "<< wgtUser.size()<<std::endl;
+	    exit(8);
+	 }
+	 if ( wgtUser[0].size()!=WgtObsNumEv[0].size() ) {
+	    std::cerr<<"Error [fastNLO::WgtStat::SetWgtUser()] Array with wrong size (wrong number of obs bins. Must be "
+		     <<WgtObsNumEv[0].size()<<", but is "<< wgtUser[0].size()<<std::endl;
+	    exit(8);
+	 }
+	 SigObsSum = wgtUser;
+	 //SigObsUser = wgtUser;
+      };
+
+      void SetWgtUser( double wgtUser ) {
+	 //! Set user weight valid for all entries
+	 SigSum = wgtUser;
+	 for ( auto& proc : SigObsSum ) {
+	    for ( auto& w : proc ) w=wgtUser;
+	 }
+      };
+      
+      void SetWgtUser( const std::vector<double>& wgtUserObs ) {
+	 //! Set user weights
+	 //! wgtUserObs[obs]
+	 if ( wgtUserObs.size()!=WgtObsNumEv[0].size() ) {
+	    std::cerr<<"Error [fastNLO::WgtStat::SetWgtUser()] Array with wrong size (wrong number of obs bins. Must be "
+		     <<WgtObsNumEv[0].size()<<", but is "<< wgtUserObs.size()<<std::endl;
+	    exit(8);
+	 }
+	 for ( std::vector<double>& proc : SigObsSum ) {
+	    proc = wgtUserObs;
+	 }
+      };
+   };
+
+}
 
 class fastNLOCoeffAddBase : public fastNLOCoeffBase {
 
@@ -13,23 +101,34 @@ class fastNLOCoeffAddBase : public fastNLOCoeffBase {
    friend class fastNLOCreate;
 
 public:
+   fastNLOCoeffAddBase() = delete;
    fastNLOCoeffAddBase(int NObsBin);
-   fastNLOCoeffAddBase(const fastNLOCoeffBase& base);
-   virtual ~fastNLOCoeffAddBase() {;}
-   virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
+   explicit fastNLOCoeffAddBase(const fastNLOCoeffBase& base);
+   virtual ~fastNLOCoeffAddBase() {}
+   virtual fastNLOCoeffAddBase* Clone() const;                                     //!< returns 'new' copy of this instance.
    static bool CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet = false);
-   void Read(istream& table);
-   virtual void Write(ostream& table);
-   virtual void Add(const fastNLOCoeffAddBase& other);
-   virtual void Print() const;
-   virtual void Clear();                                                        //!< Clear all coefficients and event counters
-   virtual void NormalizeCoefficients();                                        //!< Set number of events to 1 and normalize coefficients accordingly.
+   void Read(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption=fastNLO::kMerge);
+   virtual void Print(int iprint) const;
+
+   // Manipulate coefficient bins
+   virtual void Clear();//!< Clear all coefficients and event counters
+   virtual void NormalizeCoefficients(double wgt=1); //!< Set number of events to unity and normalize coefficients accordingly
+   virtual void NormalizeCoefficients(const std::vector<std::vector<double> >& wgtProcBin) {};
+   virtual void MultiplyCoefficientsByConstant(double fact) {};//!< Multiply all coefficients of all bins by a constant factor
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact) {};  //!< Multiply coefficients of one observable bin a factor
+   virtual void MultiplyBinProc(unsigned int iObsIdx, unsigned int iProc, double fact) {}; //!< Multiply coefficients of one observable bin a factor (idx starting from 0)
+   virtual void EraseBin(unsigned int iObsIdx);//!< Erase observable bin from table
+   virtual void CatBin(const fastNLOCoeffAddBase& other, unsigned int iObsIdx); //!< Catenate observable to table
 
    int GetIRef() const {return IRef;}
+   void SetIRef(int iref=1) {IRef=iref;}
    double GetNevt() const { return Nevt; }
    double GetNevt(int NObsBin, int NSubproc) const {
+      //return fWgt.WgtObsSumW2[NSubproc][NObsBin];
       if (Nevt > 0) return Nevt;
-      else {cout<<"Todo. Preparation for v2.3."<<endl; return Nevt;}
+      else {std::cout<<"Todo. Preparation for v2.3."<< std::endl; return Nevt;}
    }
    void SetNevt(double nevt) { Nevt = nevt;}                                    //!< Set number of events
    int GetNxmax(int Obsbin) const ;
@@ -45,50 +144,81 @@ public:
    int GetNpow() const {return Npow;}
    int GetNScales() const {return NScales;}
    int GetNScaleDim() const {return NScaleDim;}
-   //vector<string > GetScaleDescript(int iScale=0) const { return ScaleDescript[iScale]; };
-   string GetScaleDescription(int iScale=0) const { return ScaleDescript[0][iScale]; };         // getter for scale description of scale iScale
-   vector<vector<string > > GetScaleDescr() const { return ScaleDescript; }
+   //std::vector<std::string > GetScaleDescript(int iScale=0) const { return ScaleDescript[iScale]; };
+   std::string GetScaleDescription(int iScale=0) const { return ScaleDescript[0][iScale]; };         // getter for scale description of scale iScale
+   std::vector<std::vector<std::string > > GetScaleDescr() const { return ScaleDescript; }
    int GetNxtot1(int iBin) const { return XNode1[iBin].size(); }
    int GetNxtot2(int iBin) const { return XNode2.size() > 0 ? XNode2[iBin].size() : -1; }
 
    double GetXNode1(int iObsBin, int iNode) const { return XNode1[iObsBin][iNode]; }
    double GetXNode2(int iObsBin, int iNode) const { return XNode2[iObsBin][iNode]; }
+   double GetX1(int iObsBin, int iXnode) const; //! return x value of pdf1 for x-node 1
+   double GetX2(int iObsBin, int iXnode) const; //! return x value of pdf1 for x-node 1
+
+   std::vector < double > GetXNodes1(int iObsBin) const { return XNode1[iObsBin]; }
+   std::vector < double > GetXNodes2(int iObsBin) const { return XNode2[iObsBin]; }
 
    bool IsReference() const {return IRef>0;};
    bool IsCompatible(const fastNLOCoeffAddBase& other) const;
+   bool IsCatenable(const fastNLOCoeffAddBase& other) const;
 
-   const vector<vector<pair<int,int> > >& GetPDFCoeff() const { return fPDFCoeff;}
+   const std::vector<std::vector<std::pair<int,int> > >& GetPDFCoeff() const { return fPDFCoeff;}
+
+   bool SubIsEnabled(int index) const { 
+      if ( index >= (int)sub_enabled.size() ) error["SubIsEnabled"]<<"index too large: "<<index<<"\tsub.size="<<sub_enabled.size();
+      return index < NSubproc && sub_enabled[index]; 
+   }  //!< Returns true if a single subcontribution is enabled in this contribution
+   void SubEnable(int index, bool on = true) { if ( index < NSubproc ) sub_enabled[index] = on; } //!< Enables/Disables a single subcontribution
+   void SubEnableAll( bool on = true ) { sub_enabled.assign(sub_enabled.size(), on); } //!< Enables/Disables all subcontributions
+   bool SubSelect( std::vector< std::pair<int,int> > processes, bool on = true); //!< checks if the given subprocess list is compatible with the subcontribution list and enables/disables the corresponding subcontributions. Returns true on sucess and false on failure.
+
+   const fastNLO::WgtStat& GetWgtStat() const { return fWgt;} //!< Get weight and event counts
+   fastNLO::WgtStat& AccessWgtStat() { return fWgt;} //!< Get weight and event counts
+   double GetMergeWeight(fastNLO::EMerge moption, int proc, int bin) const ; //!< Get merge weight for a given bin and subprocess
 
 protected:
-   fastNLOCoeffAddBase();
-   void ReadCoeffAddBase(istream& table);
+   void ReadCoeffAddBase(std::istream& table);
    int GetScaledimfromvar(int scalevar) const;
 
-   int IRef;
-   int IScaleDep;
-   double Nevt;
-   int Npow;
-   vector < int > NPDFPDG;
-   int NPDFDim;
-   vector < int > NFFPDG;
-   int NFFDim;
-   int NSubproc;
-   int IPDFdef1;
-   int IPDFdef2;
-   int IPDFdef3;
-   vector<vector<pair<int,int> > > fPDFCoeff;                                                   //! fPDFCoeff[iSubProc][iPartonPair][pair]
+   int IRef = 0;
+   int IScaleDep = 0;
+   double Nevt = 0;
+   int Npow = 0;
+   std::vector < int > NPDFPDG;
+   int NPDFDim = 0;
+   std::vector < int > NFFPDG;
+   int NFFDim = 0;
+   int NSubproc = 0;
+   int IPDFdef1 = 0;
+   int IPDFdef2 = 0;
+   int IPDFdef3 = 0;
+   std::vector<std::vector<std::pair<int,int> > > fPDFCoeff;                                                   //! fPDFCoeff[iSubProc][iPartonPair][pair]
    // Missing: linear PDF combinations for IPDFdef1=0
-   vector < double > Hxlim1;
-   v2d XNode1;
-   vector < double > Hxlim2;
-   v2d XNode2;
-   vector < int > Nztot;
-   vector < double > Hzlim;
-   v2d ZNode;
-   int NScales;
-   int NScaleDim;
-   vector < int > Iscale;                                                                       // not used
-   vector < vector < string > > ScaleDescript;
+   std::vector < double > Hxlim1;
+   fastNLO::v2d XNode1;
+   std::vector < double > Hxlim2;
+   fastNLO::v2d XNode2;
+   std::vector < int > Nztot;
+   std::vector < double > Hzlim;
+   fastNLO::v2d ZNode;
+   int NScales = 0;
+   int NScaleDim = 0;
+   std::vector < int > Iscale;                                                                       // not used
+   std::vector < std::vector < std::string > > ScaleDescript;
+
+   std::vector < bool > sub_enabled;
+
+   fastNLO::WgtStat fWgt; //!< event and weight counts
+   // double fWgtNevt = 0; //!< 'number of events', i.e. normalisation as suggested by generator (identical to previously use 'Nevt')
+   // unsigned long long fWgtNumEv = 0; //!< number of entries
+   // double fWgtSumW2 = 0; //!< Sum of all weight**2
+   // double fSigSumW2 = 0; //!< Sum of all sigma**2 (i.e. (wgt*alpha*pdf)**2 )
+   // double fSigSum = 0; //!< Sum of all sigma (i.e. (wgt*alpha*pdf)**2 )
+   // fastNLO::v2d fWgtObsSumW2; //!< sumw2[proc][obs]
+   // fastNLO::v2d fSigObsSumW2; //!< sumw2[proc][obs]
+   // fastNLO::v2d fSigObsSum;   //!< sum[proc][obs]
+   // std::vector < std::vector < unsigned long long > > fWgtObsNumEv; //!< Nentries[proc][obs]
+
 
 };
 
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffAddFix.h b/FastNLO/include/fastnlotk/fastNLOCoeffAddFix.h
index 5dabffd1c67c4bdc835a70d45b39084f8150cb1d..abb14a854b48d1d08cf5e12680f64f697f665b13 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffAddFix.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffAddFix.h
@@ -4,62 +4,73 @@
 #include "fastNLOCoeffAddBase.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
 
 class fastNLOCoeffAddFix : public fastNLOCoeffAddBase {
 
+   friend class fastNLOTable;
    friend class fastNLOReader;
    friend class fastNLOCreate;
 
 public:
+   fastNLOCoeffAddFix() = delete;
    fastNLOCoeffAddFix(int NObsBin);
-   fastNLOCoeffAddFix(const fastNLOCoeffBase&);
+   explicit fastNLOCoeffAddFix(const fastNLOCoeffBase&);
    virtual ~fastNLOCoeffAddFix(){;}
-   virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
+   virtual fastNLOCoeffAddFix* Clone() const;                                     //!< returns 'new' copy of this instance.
    static bool CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet = false);
-   virtual void Read(istream&table);
-   void ReadRest(istream& table);
-   virtual void Write(ostream& table);
-   virtual void Add(const fastNLOCoeffAddBase& other);
-   virtual void Print() const;
-   virtual void Clear();                                                        //!< Clear all coefficients and event counters
-   virtual void NormalizeCoefficients();                                        //!< Set number of events to 1 and normalize coefficients accordingly.
-   virtual void MultiplyCoefficientsByConstant(double coef);                    //!< Multiply all coefficients by constant coef
+   virtual void Read(std::istream&table);
+   void ReadRest(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption = fastNLO::kMerge);
+   virtual void Print(int iprint) const;
+
+   // Manipulate coefficient bins
+   virtual void Clear();//!< Clear all coefficients and event counters
+   virtual void NormalizeCoefficients(double wgt=1);//!<a Set number of events to wgt and re-normalize coefficients accordingly
+   virtual void NormalizeCoefficients(const std::vector<std::vector<double> >& wgtProcBin);
+   virtual void MultiplyCoefficientsByConstant(double fact);//!< Multiply all coefficients of all bins by a constant factor
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact); //!< Multiply coefficients of one bin a factor
+   virtual void MultiplyBinProc(unsigned int iObsIdx, unsigned int iProc, double fact); //!< Multiply coefficients of one bin and subprocess by a factor
+   // Erase observable bin from table
+   virtual void EraseBin(unsigned int iObsIdx);
+   // Catenate observable to table
+   virtual void CatBin(const fastNLOCoeffAddFix& other, unsigned int iObsIdx);
 
    int GetTotalScalevars() const ;
    int GetTotalScalenodes() const ;
    int GetNScaleNode() const { return GetTotalScalenodes(); }
    int GetNScalevar() const { return Nscalevar[0];}
-   v1d GetAvailableScaleFactors() const { return ScaleFac[0]; }
+   fastNLO::v1d GetAvailableScaleFactors() const { return ScaleFac[0]; }
    double GetScaleFactor(int iVar) const {
       if ( iVar >= (int)ScaleFac[0].size() )
-         this->error["GetScaleFactor"]<<"Scalevariation no. "<<iVar<<" not available. There are only "<<GetNScalevar()<<" available in this table."<<endl;
+         this->error["GetScaleFactor"]<<"Scalevariation no. "<<iVar<<" not available. There are only "<<GetNScalevar()<<" available in this table."<< std::endl;
       return ScaleFac[0][iVar];
    }
 
    double GetSigmaTilde(int iObs, int iSvar, int ix, int is, int iN ) const { return SigmaTilde[iObs][iSvar][ix][is][iN];}
-   double GetScaleNode(int iObs, int iSvar, int iNode ) const { return ScaleNode[iObs][0][iSvar][iNode];}
+   double GetScaleNode(int iObs, int iSvar, int iNode ) const { return ScaleNode[iObs][0][iSvar][iNode]; }
+   std::vector < double > GetScaleNodes(int iObs, int iSvar) const { return ScaleNode[iObs][0][iSvar]; }
 
    void ResizePdfLC();
    void ResizePdfSplLC();
    void ResizeSigmaTilde();
    bool IsCompatible(const fastNLOCoeffAddFix& other) const;                   //!< Check for compatibility of two contributions for merging/adding
+   bool IsCatenable(const fastNLOCoeffAddFix& other) const;        //!< Check for compatibility of two contributions for merging/adding
 
 protected:
-   fastNLOCoeffAddFix();
-   void ReadCoeffAddFix(istream& table);
+   void ReadCoeffAddFix(std::istream& table);
 
-   vector < int > Nscalevar;
-   //vector < int > Nscalenode;
-   v2d ScaleFac;
-   v4d ScaleNode;
-   v5d SigmaTilde; // units are (p)barn * Nevt / BinSize
+   std::vector < int > Nscalevar;
+   //std::vector < int > Nscalenode;
+   fastNLO::v2d ScaleFac;
+   fastNLO::v4d ScaleNode;
+   fastNLO::v5d SigmaTilde; // units are (p)barn * Nevt / BinSize
 
 public:
-   v2d AlphasTwoPi_v20;
-   v4d PdfLc;
-   v4d PdfSplLc1;
-   v4d PdfSplLc2;
+   fastNLO::v2d AlphasTwoPi_v20;
+   fastNLO::v4d PdfLc;
+   fastNLO::v4d PdfSplLc1;
+   fastNLO::v4d PdfSplLc2;
 };
 
 #endif
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffAddFlex.h b/FastNLO/include/fastnlotk/fastNLOCoeffAddFlex.h
index 413b6bb522d11d136df3e77488f9db6e4360b63d..3f5f32ebb040f88dafb5bdf8be600e6c3752033f 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffAddFlex.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffAddFlex.h
@@ -4,8 +4,6 @@
 #include "fastNLOCoeffAddBase.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
-using namespace fastNLO;
 
 class fastNLOCoeffAddFlex : public fastNLOCoeffAddBase {
 
@@ -14,53 +12,71 @@ class fastNLOCoeffAddFlex : public fastNLOCoeffAddBase {
    friend class fastNLOCreate;
 
 public:
+   fastNLOCoeffAddFlex() = delete;
    fastNLOCoeffAddFlex(int NObsBin, int iLOord);
-   fastNLOCoeffAddFlex(const fastNLOCoeffBase& base , int iLOord);
+   explicit fastNLOCoeffAddFlex(const fastNLOCoeffBase& base , int iLOord);
    virtual ~fastNLOCoeffAddFlex(){;}
-   virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
+   virtual fastNLOCoeffAddFlex* Clone() const;                                     //!< returns 'new' copy of this instance.
    static bool CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet = false) ;
-   virtual void Read(istream& table);
-   void ReadRest(istream& table);
-   virtual void Write(ostream& table);
-   virtual void Print() const;
-   virtual void Add(const fastNLOCoeffAddBase& other);
-   virtual void Clear();                                                        //!< Clear all coefficients and event counters
-   virtual void NormalizeCoefficients();                                        //!< Set number of events to 1 and normalize coefficients accordingly.
-   virtual void MultiplyCoefficientsByConstant(double coef);                    //!< Multiply all coefficients by constant coef
+   virtual void Read(std::istream& table);
+   void ReadRest(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Print(int iprint) const;
+   virtual void Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption = fastNLO::kMerge);
+
+   // Manipulate coefficient bins
+   virtual void Clear(); //!< Clear all coefficients and event counters
+   virtual void NormalizeCoefficients(double wgt=1); //!< Set number of events to given wgt and re-normalize coefficients accordingly
+   virtual void NormalizeCoefficients(const std::vector<std::vector<double> >& wgtProcBin);
+   virtual void MultiplyCoefficientsByConstant(double fact); //!< Multiply all coefficients of all bins by a constant factor
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact); //!< Multiply coefficients of one bin a factor (iObsIdx starting with index 0)
+   virtual void MultiplyBinProc(unsigned int iObsIdx, unsigned int iProc, double fact); //!< Multiply coefficients of one bin and subprocess a factor
+   virtual void EraseBin(unsigned int iObsIdx); //!< Erase observable bin from table
+   virtual void CatBin(const fastNLOCoeffAddFlex& other, unsigned int iObsIdx); //!< Catenate observable to table
 
    unsigned int GetNScaleNode1(int iObsBin) const { return ScaleNode1[iObsBin].size(); };
    unsigned int GetNScaleNode2(int iObsBin) const { return ScaleNode2[iObsBin].size(); };
    double GetScaleNode1(int iObsBin, int iNode) const { return ScaleNode1[iObsBin][iNode]; };
    double GetScaleNode2(int iObsBin, int iNode) const { return ScaleNode2[iObsBin][iNode]; };
+   std::vector < double > GetScaleNodes1(int iObsBin) const { return ScaleNode1[iObsBin]; };
+   std::vector < double > GetScaleNodes2(int iObsBin) const { return ScaleNode2[iObsBin]; };
    bool IsCompatible(const fastNLOCoeffAddFlex& other) const;                   //!< check for compatibilty for adding/merging of two tables
+   bool IsCatenable(const fastNLOCoeffAddFlex& other) const;        //!< Check for compatibility of two contributions for merging/adding
+   std::vector<fastNLO::v5d*>  AccessSigmaTildes() {
+      return {&SigmaTildeMuIndep,&SigmaTildeMuRDep,&SigmaTildeMuFDep,&SigmaTildeMuRRDep,&SigmaTildeMuFFDep,&SigmaTildeMuRFDep};
+   };//!< Get access to sigma tilde
+   std::vector<const fastNLO::v5d*> GetSigmaTildes() const {
+      return {&SigmaTildeMuIndep,&SigmaTildeMuRDep,&SigmaTildeMuFDep,&SigmaTildeMuRRDep,&SigmaTildeMuFFDep,&SigmaTildeMuRFDep};
+   };//!< Get access to sigma tilde
 
 protected:
 
-   fastNLOCoeffAddFlex();
-   void ReadCoeffAddFlex(istream& table);
+   void ReadCoeffAddFlex(std::istream& table);
 
    int fILOord;   // obtained from Scenario
+   int fSTildeDISFormat = 1; // format of sigma-tilde coefficients (0: log(mu2/q2), 1: log(mu2))
 
    // SigmaTilde [NObsBins] ['n' x-nodes] [n s1-Nodes] [n s2-Nodes] [nsubproc]
-   v5d SigmaTildeMuIndep; // units are (p)barn * Nevt / BinSize
-   v5d SigmaTildeMuFDep;
-   v5d SigmaTildeMuRDep;
-   v5d SigmaTildeMuRRDep;
-   v5d SigmaTildeMuFFDep;
-   v5d SigmaTildeMuRFDep;
+   fastNLO::v5d SigmaTildeMuIndep; // units are (p)barn * Nevt / BinSize
+   fastNLO::v5d SigmaTildeMuFDep;
+   fastNLO::v5d SigmaTildeMuRDep;
+   fastNLO::v5d SigmaTildeMuRRDep;
+   fastNLO::v5d SigmaTildeMuFFDep;
+   fastNLO::v5d SigmaTildeMuRFDep;
    // SigmaRef [NObsBins] [nsubproc]
-   v2d SigmaRefMixed;  // units are (p)barn * Nevt / BinSize
-   v2d SigmaRef_s1;
-   v2d SigmaRef_s2;
+   fastNLO::v2d SigmaRefMixed;  // units are (p)barn * Nevt / BinSize
+   fastNLO::v2d SigmaRef_s1;
+   fastNLO::v2d SigmaRef_s2;
    //int NscalenodeScale1;
    //int NscalenodeScale2;
    // ScaleNodeXY [ObsBin] [NscalenodeScaleX]
-   v2d ScaleNode1;
-   v2d ScaleNode2;
+   fastNLO::v2d ScaleNode1;
+   fastNLO::v2d ScaleNode2;
 
 public:
-   v3d AlphasTwoPi;
-   v5d PdfLcMuVar;
+   fastNLO::v3d AlphasTwoPi;
+   fastNLO::v5d PdfLcMuVar;
+   fastNLO::v5d PdfXfx;
 
 };
 
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffBase.h b/FastNLO/include/fastnlotk/fastNLOCoeffBase.h
index 2c9c912a8edd7a12d31d3ef949fcacad8c07449e..bf863f96f2eac3023a519baef8269138f64dfe1a 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffBase.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffBase.h
@@ -11,23 +11,30 @@
 #include "fastNLOConstants.h"
 #include "speaker.h"
 
-using namespace std;
-using namespace fastNLO;
 
 class fastNLOCoeffBase : public PrimalScream {
 
    friend class fastNLOTable;
 
 public:
+   fastNLOCoeffBase() = delete;
    fastNLOCoeffBase(int NObsBin);                                               //! Use this constructor
-   virtual ~fastNLOCoeffBase(){;};                                              //! destructor
-   //fastNLOCoeffBase(const fastNLOCoeffBase& coeff);                           //! Use compiler-default
+   // deletes instance of derived classes through pointer to base class
+   virtual ~fastNLOCoeffBase(){};                                              //! destructor
    virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
 
-   virtual void Read(istream& table);
-   virtual void Write(ostream& table);
-   //void Add(fastNLOCoeffBase* other);
-   virtual void Print() const;
+   virtual void Read(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Print(int iprint) const;
+
+   // Erase or multiply observable bin; iObsIdx is the C++ array index to be removed and
+   // not the observable bin no. running from 1 to fNObsBins
+   virtual void EraseBin(unsigned int iObsIdx);
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact);
+   // Catenate observable to table
+   virtual void CatBin(const fastNLOCoeffBase& other, unsigned int iObsIdx);
+
+   bool IsCatenable(const fastNLOCoeffBase& other) const;
 
    void SetCoeffAddDefaults();
 
@@ -50,26 +57,26 @@ public:
    void SetIXsectUnits(int n){IXsectUnits = n;}
 
    int GetNObsBin() const { return fNObsBins;}
+   void SetNObsBin(unsigned int nObs) { fNObsBins = nObs;}
 
    bool GetIsFlexibleScale() const { return (NScaleDep>=3) && (IAddMultFlag==0); }
 
-   vector<string > GetContributionDescription() const { return CtrbDescript; }
-   void SetContributionDescription(vector<string > descr ) { CtrbDescript = descr; };           //! Set contribution description
-   vector<string > GetCodeDescription() const { return CodeDescript; }
-
+   std::vector<std::string > GetContributionDescription() const { return CtrbDescript; }
+   void SetContributionDescription(std::vector<std::string > descr ) { CtrbDescript = descr; };           //! Set contribution description
+   std::vector<std::string > GetCodeDescription() const { return CodeDescript; }
 
    bool IsLO() const {return IContrFlag1==1 && IContrFlag2==1;}
    bool IsNLO() const {return IContrFlag1==1 && IContrFlag2==2;}
    bool IsNNLO() const {return IContrFlag1==1 && IContrFlag2==3;}
-
    bool IsCompatible(const fastNLOCoeffBase& other) const;
-   //bool operator==(const fastNLOCoeffBase& other) const { return IsCompatible(other); }
 
+   bool IsEnabled() const {return enabled;}
+   void Enable() {enabled = true;}
+   void Enable(bool on) {enabled = on;}
 
 protected:
-   fastNLOCoeffBase();
-   void ReadBase(istream& table);
-   void EndReadCoeff(istream& table);
+   void ReadBase(std::istream& table);
+   void EndReadCoeff(std::istream& table);
 
    int fNObsBins; // obtained from Scenario
 
@@ -79,9 +86,11 @@ protected:
    int IContrFlag1;
    int IContrFlag2;
    int NScaleDep;
-   vector < string > CtrbDescript;
-   vector < string > CodeDescript;
+   int fVersionRead = 23000;
+   std::vector < std::string > CtrbDescript;
+   std::vector < std::string > CodeDescript;
 
+   bool enabled = false;
 };
 
 
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffData.h b/FastNLO/include/fastnlotk/fastNLOCoeffData.h
index a269ba2fdaae9ebbf3b201a3cbfee6e7c4c14479..9be1b89892656c6bfb1180cec668d0b3956d22b7 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffData.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffData.h
@@ -4,39 +4,54 @@
 #include "fastNLOCoeffBase.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
 
 class fastNLOCoeffData : public fastNLOCoeffBase {
 
    friend class fastNLOTable;
 
 public:
+   fastNLOCoeffData() = delete;
    fastNLOCoeffData(int NObsBin);
-   fastNLOCoeffData(const fastNLOCoeffBase&);
+   explicit fastNLOCoeffData(const fastNLOCoeffBase&);
    virtual ~fastNLOCoeffData(){;};
-   virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
-   virtual void Read(istream& table);
-   virtual void Write(ostream& table);
-   virtual void Print() const;
+   virtual fastNLOCoeffData* Clone() const;                                     //!< returns 'new' copy of this instance.
+   virtual void Read(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Print(int iprint) const;
    static bool CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet = false);
 
+   // Erase observable bin; iObsIdx is the C++ array index to be removed and
+   // not the observable bin no. running from 1 to fNObsBins
+   virtual void EraseBin(unsigned int iObsIdx);
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact);
+   // Catenate observable to table
+   virtual void CatBin(const fastNLOCoeffData& other, unsigned int iObsIdx);
+   bool IsCatenable(const fastNLOCoeffData& other) const;
+
+   // getter/setter
+   int  GetNuncorrel() const {return Nuncorrel;}
+   void SetNuncorrel(int n){Nuncorrel = n;}
+   int  GetNcorrel() const {return Ncorrel;}
+   void SetNcorrel(int n){Ncorrel = n;}
+   int  GetNErrMatrix() const {return NErrMatrix;}
+   void SetNErrMatrix(int n){NErrMatrix = n;}
+
 protected:
-   fastNLOCoeffData();
-   void ReadCoeffData(istream& table);
-   void ReadRest(istream& table);
+   void ReadCoeffData(std::istream& table);
+   void ReadRest(std::istream& table);
 
    int Nuncorrel;
-   vector<string > UncDescr;
+   std::vector<std::string > UncDescr;
    int Ncorrel;
-   vector<string > CorDescr;
-   vector<double > Xcenter;
-   vector<double > Value;
-   v2d UncorLo;
-   v2d UncorHi;
-   v2d CorrLo;
-   v2d CorrHi;
+   std::vector<std::string > CorDescr;
+   std::vector<double > Xcenter;
+   std::vector<double > Value;
+   fastNLO::v2d UncorLo;
+   fastNLO::v2d UncorHi;
+   fastNLO::v2d CorrLo;
+   fastNLO::v2d CorrHi;
    int NErrMatrix;
-   v2d matrixelement;
+   fastNLO::v2d matrixelement;
 
 };
 
diff --git a/FastNLO/include/fastnlotk/fastNLOCoeffMult.h b/FastNLO/include/fastnlotk/fastNLOCoeffMult.h
index 5679b290f35bf504680ae7b0b36049fc406f21ab..902d130b47758834c6f6da8745d780c117f8606d 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoeffMult.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoeffMult.h
@@ -4,7 +4,6 @@
 #include "fastNLOCoeffBase.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
 
 class fastNLOCoeffMult : public fastNLOCoeffBase {
 
@@ -12,38 +11,52 @@ class fastNLOCoeffMult : public fastNLOCoeffBase {
    friend class fastNLOCreate;
 
 public:
-   fastNLOCoeffMult();
+   fastNLOCoeffMult() = delete;
    fastNLOCoeffMult(int NObsBin);
-   fastNLOCoeffMult(const fastNLOCoeffBase&);
+   explicit fastNLOCoeffMult(const fastNLOCoeffBase&);
    virtual ~fastNLOCoeffMult(){;};
-   virtual fastNLOCoeffBase* Clone() const;                                     //!< returns 'new' copy of this instance.
+   virtual fastNLOCoeffMult* Clone() const;                                     //!< returns 'new' copy of this instance.
    static bool CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet = false);
-   virtual void Read(istream& table);
-   virtual void Write(ostream& table);
-   virtual void Print() const;
+   virtual void Read(std::istream& table);
+   virtual void Write(std::ostream& table, int ITabVersionWrite);
+   virtual void Print(int iprint) const;
 
    double GetMultFactor(int iObs) const { return fact[iObs]; }
-   vector<double > GetMultFactor() const { return fact; }
-   vector<string> GetUncDescription() const { return UncDescr; }
-   vector<string> GetCorDescription() const { return CorDescr; }
-   v2d GetUncorLo() const { return UncorHi; };
-   v2d GetUncorHi() const { return UncorLo; };
-   v2d GetCorrLo()  const { return CorrLo; };
-   v2d GetCorrHi()  const { return CorrHi; };
+   std::vector<double > GetMultFactor() const { return fact; }
+   std::vector<std::string> GetUncDescription() const { return UncDescr; }
+   std::vector<std::string> GetCorDescription() const { return CorDescr; }
+   fastNLO::v2d GetUncorLo() const { return UncorHi; };
+   fastNLO::v2d GetUncorHi() const { return UncorLo; };
+   fastNLO::v2d GetCorrLo()  const { return CorrLo; };
+   fastNLO::v2d GetCorrHi()  const { return CorrHi; };
+
+   // Erase observable bin; iObsIdx is the C++ array index to be removed and
+   // not the observable bin no. running from 1 to fNObsBins
+   virtual void EraseBin(unsigned int iObsIdx);
+   virtual void MultiplyBin(unsigned int iObsIdx, double fact);
+   bool IsCatenable(const fastNLOCoeffMult& other) const;
+   // Catenate observable to table
+   virtual void CatBin(const fastNLOCoeffMult& other, unsigned int iObsIdx);
+
+   // getter/setter
+   int  GetNuncorrel() const {return Nuncorrel;}
+   void SetNuncorrel(int n){Nuncorrel = n;}
+   int  GetNcorrel() const {return Ncorrel;}
+   void SetNcorrel(int n){Ncorrel = n;}
 
 protected:
-   void ReadCoeffMult(istream& table);
-   void ReadRest(istream& table);
+   void ReadCoeffMult(std::istream& table);
+   void ReadRest(std::istream& table);
 
    int Nuncorrel;
-   vector < string > UncDescr;
+   std::vector < std::string > UncDescr;
    int Ncorrel;
-   vector < string > CorDescr;
-   v2d UncorLo;
-   v2d UncorHi;
-   v2d CorrLo;
-   v2d CorrHi;
-   v1d fact;
+   std::vector < std::string > CorDescr;
+   fastNLO::v2d UncorLo;
+   fastNLO::v2d UncorHi;
+   fastNLO::v2d CorrLo;
+   fastNLO::v2d CorrHi;
+   fastNLO::v1d fact;
 
 };
 
diff --git a/FastNLO/include/fastnlotk/fastNLOCoefficients.h b/FastNLO/include/fastnlotk/fastNLOCoefficients.h
index 0f1f8f25021ce7469fae146f5c335577b94ce8dc..4dd756dcaaccfd3cc4462061a955f5d27a08f714 100644
--- a/FastNLO/include/fastnlotk/fastNLOCoefficients.h
+++ b/FastNLO/include/fastnlotk/fastNLOCoefficients.h
@@ -10,7 +10,6 @@
 
 #include "fastNLOConstants.h"
 
-using namespace std;
 
 class fastNLOCoefficients {
 
@@ -20,59 +19,59 @@ class fastNLOCoefficients {
 public:
    fastNLOCoefficients();
    fastNLOCoefficients(int NObsBin, int iLOord);
-   int Read(istream *table);
-   int Write(ostream *table, int option = 0);
+   int Read(std::istream *table);
+   int Write(std::ostream *table, int option = 0);
    int Copy(fastNLOCoefficients* other);
 
-   void StripWhitespace(string& s) const;
-
-   //    template<typename T> void ResizeFlexibleVector(vector<T>* v, vector<T>* nom);
-   //    void ResizeFlexibleVector(vector<double >* v, vector<double >*nom ){ v->resize(nom->size());};
-
-   void ResizeTable( vector<double >* v, int dim0 );
-   void ResizeTable( vector<vector<double > >*  v, int dim0 , int dim1 );
-   void ResizeTable( vector<vector<double > >*  v, int dim0 , int* dim1GetNxmaxFromDimI );
-   void ResizeTable( vector<vector<vector<double > > >* v, int dim0 , int* dim1GetNxmaxFromDimI, int dim2 );
-   void ResizeTable( vector<vector<vector<double > > >* v, int dim0 , int dim1, int dim2 );
-   void ResizeTable( vector<vector<vector<vector<double > > > >* v, int dim0 , int dim1, int dim2, int dim3 );
-   void ResizeTable( vector<vector<vector<vector<double > > > >* v, int dim0 , int dim1, int* dim2GetNxmaxFromDimI, int dim3 );
-   void ResizeTable( vector<vector<vector<vector<vector<double > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4 );
-   void ResizeTable( vector<vector<vector<vector<vector<double > > > > >* v, int dim0 , int dim1, int dim2, int* dim3GetNxmaxFromDimI, int dim4 );
-   void ResizeTable( vector<vector<vector<vector<vector<double > > > > >* v, int dim0 , int* dim1GetNxmaxFromDimI, int dim2, int dim3, int dim4 );
-   void ResizeTable( vector<vector<vector<vector<vector<vector<double > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5 );
-   void ResizeTable( vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5, int dim6 );
-   void ResizeTable( vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int* dim5GetNxmaxFromDimI , int dim6 );
-
-
-   template<typename T> int ReadTable( vector<T>* v, istream *table );
-   int ReadTable( vector<double>* v, istream *table );
-
-   template<typename T>  int ReadFlexibleVector(vector<T>* v, istream* table, bool nProcLast=false);
-   int ReadFlexibleVector( vector<double >* v, istream *table , bool nProcLast = false );
-
-   int WriteTable( vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* v, ostream *table , bool DivByNevt=false , int Nevt=1 );
-   int WriteTable( vector<vector<vector<vector<vector<vector<double > > > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-   int WriteTable( vector<vector<vector<vector<vector<double > > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-   int WriteTable( vector<vector<vector<vector<double > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-   int WriteTable( vector<vector<vector<double > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-   int WriteTable( vector<vector<double > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-   int WriteTable( vector<double >* v, ostream *table , bool DivByNevt=false, int Nevt=1 );
-
-   int WriteFlexibleTable( vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* v, ostream *table , bool DivByNevt=false , int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<vector<vector<vector<vector<vector<double > > > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<vector<vector<vector<vector<double > > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<vector<vector<vector<double > > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<vector<vector<double > > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<vector<double > >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-   int WriteFlexibleTable( vector<double >* v, ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
-
-   void AddTableToAnotherTable( vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* vSum, vector<vector<vector<vector<vector<vector<vector<double > > > > > > >* vAdd, double w1 = 0, double w2 = 0 );
-   void AddTableToAnotherTable( vector<vector<vector<vector<vector<vector<double > > > > > >* vSum, vector<vector<vector<vector<vector<vector<double > > > > > >* vAdd, double w1 = 1, double w2 = 1 );
-   void AddTableToAnotherTable( vector<vector<vector<vector<vector<double > > > > >* vSum, vector<vector<vector<vector<vector<double > > > > >* vAdd, double w1 = 1, double w2 = 1 );
-   void AddTableToAnotherTable( vector<vector<vector<vector<double > > > >* vSum, vector<vector<vector<vector<double > > > >* vAdd, double w1 = 1, double w2 = 1 );
-   void AddTableToAnotherTable( vector<vector<vector<double > > >* vSum, vector<vector<vector<double > > >* vAdd, double w1 = 1, double w2 = 1 );
-   void AddTableToAnotherTable( vector<vector<double > >* vSum, vector<vector<double > >* vAdd, double w1 = 1, double w2 = 1 );
-   void AddTableToAnotherTable( vector<double >* vSum, vector<double >* vAdd, double w1 = 1, double w2 = 1 );
+   void StripWhitespace(std::string& s) const;
+
+   //    template<typename T> void ResizeFlexibleVector(std::vector<T>* v, std::vector<T>* nom);
+   //    void ResizeFlexibleVector(std::vector<double >* v, std::vector<double >*nom ){ v->resize(nom->size());};
+
+   void ResizeTable( std::vector<double >* v, int dim0 );
+   void ResizeTable( std::vector<std::vector<double > >*  v, int dim0 , int dim1 );
+   void ResizeTable( std::vector<std::vector<double > >*  v, int dim0 , int* dim1GetNxmaxFromDimI );
+   void ResizeTable( std::vector<std::vector<std::vector<double > > >* v, int dim0 , int* dim1GetNxmaxFromDimI, int dim2 );
+   void ResizeTable( std::vector<std::vector<std::vector<double > > >* v, int dim0 , int dim1, int dim2 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<double > > > >* v, int dim0 , int dim1, int dim2, int dim3 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<double > > > >* v, int dim0 , int dim1, int* dim2GetNxmaxFromDimI, int dim3 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* v, int dim0 , int dim1, int dim2, int* dim3GetNxmaxFromDimI, int dim4 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* v, int dim0 , int* dim1GetNxmaxFromDimI, int dim2, int dim3, int dim4 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5, int dim6 );
+   void ResizeTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* v, int dim0 , int dim1, int dim2, int dim3, int dim4, int* dim5GetNxmaxFromDimI , int dim6 );
+
+
+   template<typename T> int ReadTable( std::vector<T>* v, std::istream *table );
+   int ReadTable( std::vector<double>* v, std::istream *table );
+
+   template<typename T>  int ReadFlexibleVector(std::vector<T>* v, std::istream* table, bool nProcLast=false);
+   int ReadFlexibleVector( std::vector<double >* v, std::istream *table , bool nProcLast = false );
+
+   int WriteTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* v, std::ostream *table , bool DivByNevt=false , int Nevt=1 );
+   int WriteTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+   int WriteTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+   int WriteTable( std::vector<std::vector<std::vector<std::vector<double > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+   int WriteTable( std::vector<std::vector<std::vector<double > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+   int WriteTable( std::vector<std::vector<double > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+   int WriteTable( std::vector<double >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 );
+
+   int WriteFlexibleTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* v, std::ostream *table , bool DivByNevt=false , int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<std::vector<std::vector<std::vector<double > > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<std::vector<std::vector<double > > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<std::vector<double > >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+   int WriteFlexibleTable( std::vector<double >* v, std::ostream *table , bool DivByNevt=false, int Nevt=1 , bool nProcLast = false );
+
+   void AddTableToAnotherTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* vSum, std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > >* vAdd, double w1 = 0, double w2 = 0 );
+   void AddTableToAnotherTable( std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > >* vSum, std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > >* vAdd, double w1 = 1, double w2 = 1 );
+   void AddTableToAnotherTable( std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* vSum, std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > >* vAdd, double w1 = 1, double w2 = 1 );
+   void AddTableToAnotherTable( std::vector<std::vector<std::vector<std::vector<double > > > >* vSum, std::vector<std::vector<std::vector<std::vector<double > > > >* vAdd, double w1 = 1, double w2 = 1 );
+   void AddTableToAnotherTable( std::vector<std::vector<std::vector<double > > >* vSum, std::vector<std::vector<std::vector<double > > >* vAdd, double w1 = 1, double w2 = 1 );
+   void AddTableToAnotherTable( std::vector<std::vector<double > >* vSum, std::vector<std::vector<double > >* vAdd, double w1 = 1, double w2 = 1 );
+   void AddTableToAnotherTable( std::vector<double >* vSum, std::vector<double >* vAdd, double w1 = 1, double w2 = 1 );
 
    void Print() const;
 
@@ -126,84 +125,84 @@ protected:
    int IContrFlag2;
    int NScaleDep;
    // obsolete int NContrDescr;
-   vector < string > CtrbDescript;
+   std::vector < std::string > CtrbDescript;
    // obsolete   int NCodeDescr;
-   vector < string > CodeDescript;
+   std::vector < std::string > CodeDescript;
    int Nuncorrel;
-   vector < string > UncDescr;
+   std::vector < std::string > UncDescr;
    int Ncorrel;
-   vector < string > CorDescr;
-   vector < double > Xcenter;
-   vector < double > Value;
-   vector < vector < double > > UncorLo;
-   vector < vector < double > > UncorHi;
-   vector < vector < double > > CorrLo;
-   vector < vector < double > > CorrHi;
+   std::vector < std::string > CorDescr;
+   std::vector < double > Xcenter;
+   std::vector < double > Value;
+   std::vector < std::vector < double > > UncorLo;
+   std::vector < std::vector < double > > UncorHi;
+   std::vector < std::vector < double > > CorrLo;
+   std::vector < std::vector < double > > CorrHi;
    int NErrMatrix;
-   vector < vector < double > > matrixelement;
-   vector < double > fact;
+   std::vector < std::vector < double > > matrixelement;
+   std::vector < double > fact;
    int IRef;
    int IScaleDep;
    unsigned long long int Nevt;
    int Npow;
    int NPDF;
-   vector < int > NPDFPDG;
+   std::vector < int > NPDFPDG;
    int NPDFDim;
    int NFragFunc;
-   vector < int > NFFPDG;
+   std::vector < int > NFFPDG;
    int NFFDim;
    int NSubproc;
    int IPDFdef1;
    int IPDFdef2;
    int IPDFdef3;
    // Missing: linear PDF combinations for IPDFdef1=0
-   //vector < int > Nxtot1;
-   vector < double > Hxlim1;
-   vector < vector < double > > XNode1;
-   //vector < int >  Nxtot2;
-   vector < double > Hxlim2;
-   vector < vector < double > > XNode2;
-   vector < int > Nztot;
-   vector < double > Hzlim;
-   vector < vector < double > > ZNode;
+   //std::vector < int > Nxtot1;
+   std::vector < double > Hxlim1;
+   std::vector < std::vector < double > > XNode1;
+   //std::vector < int >  Nxtot2;
+   std::vector < double > Hxlim2;
+   std::vector < std::vector < double > > XNode2;
+   std::vector < int > Nztot;
+   std::vector < double > Hzlim;
+   std::vector < std::vector < double > > ZNode;
    int NScales;
    int NScaleDim;
-   vector < int > Iscale;
-   // obsolete vector < int > NscaleDescript;
-   vector < vector < string > > ScaleDescript;
+   std::vector < int > Iscale;
+   // obsolete std::vector < int > NscaleDescript;
+   std::vector < std::vector < std::string > > ScaleDescript;
 
 
    // ------------------------ not flexible scale --------------------------- //
-   vector < int > Nscalevar;
-   vector < int > Nscalenode;
-   vector < vector < double > > ScaleFac;
-   vector < vector < vector < vector < double > > > > ScaleNode;
-   //vector < vector < vector < vector < double > > > > HScaleNode;
-   vector < vector < vector < vector < vector < double > > > > > SigmaTilde;
+   std::vector < int > Nscalevar;
+   std::vector < int > Nscalenode;
+   std::vector < std::vector < double > > ScaleFac;
+   std::vector < std::vector < std::vector < std::vector < double > > > > ScaleNode;
+   //std::vector < std::vector < std::vector < std::vector < double > > > > HScaleNode;
+   std::vector < std::vector < std::vector < std::vector < std::vector < double > > > > > SigmaTilde;
 
    // --------------------------- flexible scale --------------------------- //
    // ---- members to write to disc ---- //
    // SigmaTilde [NObsBins] ['n' x-nodes] [n s1-Nodes] [n s2-Nodes] [nsubproc]
-   vector < vector < vector < vector < vector < double > > > > > SigmaTildeMuIndep; 
-   vector < vector < vector < vector < vector < double > > > > > SigmaTildeMuFDep; 
-   vector < vector < vector < vector < vector < double > > > > > SigmaTildeMuRDep; 
+   std::vector < std::vector < std::vector < std::vector < std::vector < double > > > > > SigmaTildeMuIndep; 
+   std::vector < std::vector < std::vector < std::vector < std::vector < double > > > > > SigmaTildeMuFDep; 
+   std::vector < std::vector < std::vector < std::vector < std::vector < double > > > > > SigmaTildeMuRDep; 
    // SigmaRef [NObsBins] [nsubproc]
-   vector < vector < double > > SigmaRefMixed; 
-   vector < vector < double > > SigmaRef_s1; 
-   vector < vector < double > > SigmaRef_s2; 
+   std::vector < std::vector < double > > SigmaRefMixed; 
+   std::vector < std::vector < double > > SigmaRef_s1; 
+   std::vector < std::vector < double > > SigmaRef_s2; 
    int NscalenodeScale1;
    int NscalenodeScale2;
    // ScaleNodeXY [ObsBin] [NscalenodeScaleX]  
-   vector < vector < double > > ScaleNode1;
-   vector < vector < double > > ScaleNode2;
-   //    vector < vector < double > > HScaleNode1;
-   //    vector < vector < double > > HScaleNode2;
+   std::vector < std::vector < double > > ScaleNode1;
+   std::vector < std::vector < double > > ScaleNode2;
+   //    std::vector < std::vector < double > > HScaleNode1;
+   //    std::vector < std::vector < double > > HScaleNode2;
 
 };
 
 
 template<typename T>
-int fastNLOCoefficients::ReadFlexibleVector(vector<T>* v, istream* table, bool nProcLast){
+int fastNLOCoefficients::ReadFlexibleVector(std::vector<T>* v, std::istream* table, bool nProcLast){
    int nn = 0;
    int size = 0;
    *table >> size; nn++;
@@ -216,14 +215,14 @@ int fastNLOCoefficients::ReadFlexibleVector(vector<T>* v, istream* table, bool n
 
 
 // template<typename T>
-// void fastNLOCoefficients::ResizeFlexibleVector(vector<T>* v, vector<T>* nom){
+// void fastNLOCoefficients::ResizeFlexibleVector(std::vector<T>* v, std::vector<T>* nom){
 //    v->resize(nom->size());
 //    for ( unsigned int i = 0 ; i<v->size() ; i++ ){
 //       ResizeFlexibleVector(&((*v)[i]),&((*nom)[i]));
 //    }
 // };
 
-template<typename T> int fastNLOCoefficients::ReadTable( vector<T>* v, istream *table ){
+template<typename T> int fastNLOCoefficients::ReadTable( std::vector<T>* v, std::istream *table ){
    int nn = 0;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn+= ReadTable(&(*v)[i0],table);
diff --git a/FastNLO/include/fastnlotk/fastNLOConstants.h b/FastNLO/include/fastnlotk/fastNLOConstants.h
index dd8a9e2c30c756e538f9ef21b45159e931b37249..0f87ad1e7b3b6ad4d9c5181da5c350bfa176b689 100644
--- a/FastNLO/include/fastnlotk/fastNLOConstants.h
+++ b/FastNLO/include/fastnlotk/fastNLOConstants.h
@@ -3,26 +3,27 @@
 
 #include <string>
 #include <vector>
+#include <set>
 
 #ifndef FNLO_NAME
 #define FNLO_NAME       "fastNLO_toolkit"
 #define FNLO_SUBPROJECT "toolkit"
 #define FNLO_VERSION    "2.3.1pre"
-#define FNLO_SVNREV     "2163"
+#define FNLO_SVNREV     "@SVNREV@"
 #define FNLO_AUTHORS    "D. Britzger, T. Kluge, K. Rabbertz, F. Stober, G. Sieber, M. Wobisch"
 #define FNLO_WEBPAGE    "http://projects.hepforge.org/fastnlo"
 #define FNLO_AUTHORSv14 "T. Kluge, K. Rabbertz, M. Wobisch"
 #define FNLO_QUOTEv14   "hep-ph/0609285"
 #define FNLO_AUTHORSv2  "D. Britzger, T. Kluge, K. Rabbertz, F. Stober, M. Wobisch"
 #define FNLO_QUOTEv2    "arXiv:1109.1310"
-#define FNLO_YEARS      "2005-2015"
+#define FNLO_YEARS      "2005-2018"
 #endif
 
 // Define variables fixed by precompiler for optional parts.
 // Compilers like gcc usually drop unreachable statements
 // anyway such that unnecessary if-else-endif calls or
 // "unresolved symbol" errors are avoided.
-#define FNLO_HOPPET     ""
+//#define FNLO_HOPPET     ""
 #define FNLO_QCDNUM     ""
 #define FNLO_ROOT       "@ROOT@"
 
@@ -32,15 +33,15 @@ const double TWOPISQR = 39.47841760435743447533796;
 const double TOCL90   =  1.64485362695147271486385; // SQRT(2.D0)*InvERF(0.9D0)
 //#define TWOPI (2.*M_PI)
 //#define TWOPISQR (4.*M_PI*M_PI)
-// PDG values 2012/2013
-#define PDG_MU   (0.0023)
-#define PDG_MD   (0.0048)
-#define PDG_MS   (0.095)
-#define PDG_MC   (1.275)
+// PDG values 2017, MSbar except MT
+#define PDG_MU   (0.0022)
+#define PDG_MD   (0.0047)
+#define PDG_MS   (0.096)
+#define PDG_MC   (1.28)
 #define PDG_MB   (4.18)
-#define PDG_MT   (173.07)
+#define PDG_MT   (173.1)
 #define PDG_MZ   (91.1876)
-#define PDG_ASMZ (0.1184)
+#define PDG_ASMZ (0.1182)
 
 namespace fastNLO {
 
@@ -54,8 +55,11 @@ namespace fastNLO {
    typedef std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<double > > > > > > > v7d;
 
    // ---- constants ---- //
-   const int tabversion   = 20000;
+   static const std::set<int> CompatibleVersions{20000,21000,22000,23000,23500,23600,24000};
+   const int tabversion   = 23600;
    const int tablemagicno = 1234567890;
+   // separating character between entries in table
+   const char sep[] = "\n";
    //   const double TWOPI = 6.28318530717958647692528;
 
 
@@ -76,8 +80,13 @@ namespace fastNLO {
       kScaleMax                 = 7,    // e.g. mu^2 = max( Q^2, pt^2)
       kScaleMin                 = 8,    // e.g. mu^2 = min( Q^2, pt^2)
       kProd                     = 9,    // e.g. mu^2 = (scale1 * scale2) ^2
-      kExpProd2                 = 10,   // e.g. mu^2 = (scale1 * exp(0.3 * scale2)) ^2
-      kExtern                   = 11    // define an external function for your scale
+      kS2plusS1half             = 10,   // e.g. mu^2 = (scale1^1/2 + scale2^2)
+      kPow4Sum                  = 11,   // e.g. mu^2 = sqrt((scale1^4 + scale2^4))
+      kWgtAvg                   = 12,   // e.g. mu^2 = sqrt( (scale1^4 + scale2^4)/(scale1^2 + scale2^2)) [weighted average]
+      kS2plusS1fourth           = 13,   // e.g. mu^2 = (scale1^1/4 + scale2^2)
+      kExpProd2                 = 14,   // e.g. mu^2 = (scale1 * exp(0.3 * scale2)) ^2
+      kExtern                   = 15,   // define an external function for your scale
+      kConst                    = 16,   // e.g. mu^2 = c, while c is a constant and could be for instance the top-mass
    };
 
    enum ESMCalculation {
@@ -117,6 +126,25 @@ namespace fastNLO {
       kHeraPDF10                = 7     // HERAPDF 1.0 uncertainties
    };
 
+   enum EAsUncertaintyStyle {
+      kAsNone                   = 0,    // no a_s uncertainty
+      kAsGRV                    = 1,    // a_s(M_Z) uncertainty with GRV evolution
+   };
+
+   enum EMerge {  //!< mergeing options.
+      kMerge, //!< Calculate weighted average (default. Nevt usually set externally by generator code).
+      kAdd, //!< Add (Append)! Do not merge, but add two tables together (fully unweighted) (1+1=2).
+      kUnweighted, //!< Calculated unweighted average (usually better: take kNumEvent).
+      kAttach, //!< Add (Append)! Same functionality as 'add' but subprocesses are attached and file size increases.
+      kNumEvent, kNumEventBinProc, //!< Calculate weighted average, using w = num entries
+      kSumW2,    kSumW2BinProc, //!< Calculate weighted average , using w = sum(weight**2)
+      kSumSig2,  kSumSig2BinProc, //!< Calculate weighted average, using w = sum(sig**2) [sig ~ wgt*as*pdf]
+      kSumUser,  kSumUserBinProc, //!< Calculate weighted average, using w = sum(sig) [sig ~ wgt*as*pdf], or 'user-specified' weights
+      kMedian, kMean, //!< build median or median value of many tables (option not applicable to member function, because many tables are needed as input).
+      kUndefined //!< Error
+   };
+
+
    // ---- some names for nice output ---- //
    const std::string _ContrName[20] = {
       "Fixed order calculation", "Threshold corrections", "Electroweak corrections", "Non-perturbative corrections",
@@ -136,12 +164,18 @@ namespace fastNLO {
    // ---- Some shapes for nice output ---- //
    //
 #ifndef SWIG
-   const std::string _CSEP40("########################################");
-   const std::string _DSEP40("========================================");
-   const std::string _SSEP40("----------------------------------------");
-   const std::string _CSEP40C(" ##########################################");
-   const std::string _DSEP40C(" #=========================================");
-   const std::string _SSEP40C(" #-----------------------------------------");
+   const std::string _CSEP20("####################");
+   const std::string _DSEP20("====================");
+   const std::string _SSEP20("--------------------");
+   const std::string _CSEP20C(" ######################");
+   const std::string _DSEP20C(" #=====================");
+   const std::string _SSEP20C(" #---------------------");
+   const std::string _CSEP40  = _CSEP20  + _CSEP20;
+   const std::string _DSEP40  = _DSEP20  + _DSEP20;
+   const std::string _SSEP40  = _SSEP20  + _SSEP20;
+   const std::string _CSEP40C = _CSEP20C + _CSEP20;
+   const std::string _DSEP40C = _DSEP20C + _DSEP20;
+   const std::string _SSEP40C = _SSEP20C + _SSEP20;
    const std::string _CSEPS  = _CSEP40  + _CSEP40;
    const std::string _DSEPS  = _DSEP40  + _DSEP40;
    const std::string _SSEPS  = _SSEP40  + _SSEP40;
diff --git a/FastNLO/include/fastnlotk/fastNLOPDFLinearCombinations.h b/FastNLO/include/fastnlotk/fastNLOPDFLinearCombinations.h
index 37019ea425d55c6380ad12e9e72fdd303dc5d753..0a924ae9b146e9c18b3d83e94ecc10f34b14d9ab 100644
--- a/FastNLO/include/fastnlotk/fastNLOPDFLinearCombinations.h
+++ b/FastNLO/include/fastnlotk/fastNLOPDFLinearCombinations.h
@@ -1,11 +1,9 @@
 #ifndef __fastNLOLinearCombinations__
 #define __fastNLOLinearCombinations__
 
-#include <string>
 #include "speaker.h"
 #include "fastNLOCoeffAddBase.h"
 
-using namespace std;
 
 class fastNLOPDFLinearCombinations {
 
@@ -13,20 +11,21 @@ public:
    fastNLOPDFLinearCombinations();
    ~fastNLOPDFLinearCombinations();
 
-   vector<double > CalcPDFLinearCombination(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 = vector<double>(), const vector<double>& pdfx2 = vector<double>() , bool pdf2IsAntiParticle = false) const;
+   std::vector<double > CalcPDFLinearCombination(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 = std::vector<double>(), const std::vector<double>& pdfx2 = std::vector<double>() , bool pdf2IsAntiParticle = false) const;
 
 protected:
-   vector<double > MakeAntiHadron(const vector<double >& hadron) const;
+   std::vector<double > MakeAntiHadron(const std::vector<double >& hadron) const;
 
 private: 
-   vector<double > CalcPDFLCTwoHadrons(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1, const vector<double>& pdfx2 ) const ;
-   vector<double > CalcPDFLCOneHadron(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 ) const;
-
-   vector<double> CalcPDFDIS(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1) const;
-   vector<double> CalcPDFHHCFromTable(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const ; // hh collisions. PDFLiCos are stored in table
-   vector<double> CalcPDFHHC(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const ; // jets in hh
-   vector<double> CalcDefaultPDFLiCos(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const ; // jets in hh
-   vector<double> CalcPDFttbar(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const ; // ttbar
-   vector<double> CalcPDFThreshold(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const ; // pp->2jets 
+   std::vector<double > CalcPDFLCTwoHadrons(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1, const std::vector<double>& pdfx2 ) const ;
+   std::vector<double > CalcPDFLCOneHadron(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 ) const;
+
+   std::vector<double> CalcPDFDIS(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1) const;
+   std::vector<double> CalcPDFDISFromTable(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1) const ; // DIS. PDFLiCos are stored in table
+   std::vector<double> CalcPDFHHCFromTable(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 , const std::vector<double>& pdfx2) const ; // hh collisions. PDFLiCos are stored in table
+   std::vector<double> CalcPDFHHC(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 , const std::vector<double>& pdfx2) const ; // jets in hh
+   std::vector<double> CalcDefaultPDFLiCos(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 , const std::vector<double>& pdfx2) const ; // jets in hh
+   std::vector<double> CalcPDFttbar(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 , const std::vector<double>& pdfx2) const ; // ttbar
+   std::vector<double> CalcPDFThreshold(const fastNLOCoeffAddBase* c, const std::vector<double>& pdfx1 , const std::vector<double>& pdfx2) const ; // pp->2jets 
 };
 #endif
diff --git a/FastNLO/include/fastnlotk/fastNLOReader.h b/FastNLO/include/fastnlotk/fastNLOReader.h
index f1c851f37bded5655fda1e1fa6a6d93446d5f745..f76c394f373058a98377bf8ac3112c1d6095ba1d 100644
--- a/FastNLO/include/fastnlotk/fastNLOReader.h
+++ b/FastNLO/include/fastnlotk/fastNLOReader.h
@@ -4,29 +4,56 @@
 #include "fastNLOTable.h"
 #include "fastNLOPDFLinearCombinations.h"
 
- using namespace std;
+// ---- Getters for results---- //
+struct XsUncertainty {
+   //! Struct for returning vectors with cross section and relative uncertainty
+   // keep definition of this class outside of fastNLOReader, beacause of python wrapper
+   std::vector < double > xs;
+   std::vector < double > dxsl;
+   std::vector < double > dxsu;
+};
+
 
 class fastNLOReader : public fastNLOTable , public fastNLOPDFLinearCombinations {
-   //
-   // fastNLOReader.
-   //
+   //!
+   //! fastNLOReader.
+   //! Abstract base class for evaluation of fastNLO tables.
+   //! Instantiatians must implement functions for PDF and alpha_s access.
+   //!
 
 public:
    typedef double(*mu_func)(double,double);
 
-   fastNLOReader(string filename);
+   fastNLOReader(std::string filename);
+   fastNLOReader(const fastNLOTable&);
    fastNLOReader(const fastNLOReader&);
    virtual ~fastNLOReader();
-   void SetFilename(string filename) ;
+   void SetFilename(std::string filename) ;
    void InitScalevariation();
    void SetUnits(fastNLO::EUnits Unit);
-   bool SetContributionON(fastNLO::ESMCalculation eCalc , unsigned int Id , bool SetOn = true);  //!< Set contribution On/Off. Look for Id of this contribution during initialization.
+   /// Set contribution Id On/Off. Check for Id of a particular contribution with ContrId(...) or use ActivateContribution(...).
+   bool SetContributionON(fastNLO::ESMCalculation eCalc , unsigned int Id , bool SetOn = true);
+   /// Activate first found contribution of type eCalc and order eOrd
+   bool ActivateContribution(fastNLO::ESMCalculation eCalc , fastNLO::ESMOrder eOrd , bool SetOn = true);
+   /// Find Id in table of contribution of type eCalc and order eOrd
    int ContrId(const fastNLO::ESMCalculation eCalc, const fastNLO::ESMOrder eOrder) const;
-   bool GetIsFlexibleScaleTable(fastNLOCoeffAddBase* ctest=NULL) const { //! Get, if this table is a 'flexible scale' table or not.
+   /// Switch on LO and NLO contributions, deactivate other contributions.
+   void SetCoefficientUsageDefault();
+   /// Get, if this table is a 'flexible-scale' table or not.
+   inline bool GetIsFlexibleScaleTable(fastNLOCoeffAddBase* ctest=NULL) const {
       if ( ctest ) return  ctest->GetNScaleDep() >= 3;
-      else return B_LO()->GetIsFlexibleScale();
+      else if ( B_LO() ) return B_LO()->GetIsFlexibleScale();
+      else if ( B_NLO() ) return B_NLO()->GetIsFlexibleScale();
+      else if ( B_NNLO() ) return B_NNLO()->GetIsFlexibleScale();
+      else return false;
    }
-   void SetCoefficientUsageDefault();                                                   //!< Switch on LO and NLO contributions, deactivate other contributions.
+   void SelectProcesses( const std::vector< std::pair<int,int> >& proclist );   //!< tries to select the specified subprocesses for calculation. Prints a warning on failure.
+   void SelectProcesses( const std::string& processes );                      //!< tries to select the specified subprocesses for calculation. Prints a warning on failure.
+
+   // ---- setters for specific options ---- //
+   void SetCalculateSingleSubprocessOnly(int iSub);					//!< only use one subprocess for calculation
+   void SetCalculateSubprocesses( const std::vector< int >& iSub );			//!< use several but not all subprocesses in calculation
+   void SetNewSqrtS(double NewSqrtS, double OldSqrtS=0 );
 
    // ---- setters for scales of MuVar tables ---- //
    void SetMuRFunctionalForm(fastNLO::EScaleFunctionalForm func);                       //!< Set the functional form of Mu_R
@@ -35,37 +62,47 @@ public:
    bool SetScaleFactorsMuRMuF(double xmur, double xmuf);                                //!< Set scale factors for MuR and MuF
    void SetExternalFuncForMuR(mu_func);                                                 //!< Set external function for scale calculation (optional)
    void SetExternalFuncForMuF(mu_func);                                                 //!< Set external function for scale calculation (optional)
+   void SetExternalConstantForMuR(double MuR);                                          //!< Set value for mu_r if mu_r is chosen to be a constant value (i.e. m_t, or m_Z)
+   void SetExternalConstantForMuF(double MuF);                                          //!< Set value for mu_f if mu_f is chosen to be a constant value (i.e. m_t, or m_Z)
 
    void UseHoppetScaleVariations(bool);
+
    // ---- Pdf interface ---- //
-   void FillPDFCache(double chksum=0.);                                                 //!< Prepare for recalculation of cross section with 'new'/updated pdf.
-   virtual vector<double> GetXFX(double x, double muf) const = 0;
+   void FillPDFCache(double chksum=0., bool lForce=false);                              //!< Prepare for recalculation of cross section with 'new'/updated pdf.
+   std::vector<double> GetXFXSqrtS(double x, double muf);                               //!< Interface to GetXFX, but for 'reweighted' sqrt(s)
+   virtual std::vector<double> GetXFX(double x, double muf) const = 0;
+
+   // virtual functions for the user interface
+   virtual bool InitPDF() = 0;
+   virtual double EvolveAlphas(double Q) const = 0;
 
    // ---- alphas cache ---- //
-   void FillAlphasCache();                                                              //!< prepare for recalculation of cross section with new alpha_s value.
+   void FillAlphasCache(bool lForce=false);                                             //!< prepare for recalculation of cross section with new alpha_s value.
+
+   // --- cache ---- //
+   void ResetCache() { fPDFCached=0; fAlphasCached=0;}
 
    // ---- Do the cross section calculation ---- //
    void CalcCrossSection();
    double RescaleCrossSectionUnits(double binsize, int xunits);                         // Rescale according to kAbsoluteUnits and Ipublunits settings
 
-   // ---- Getters for results---- //
-   struct XsUncertainty {                                                               //! Struct for returning vectors with cross section and relative uncertainty
-      vector < double > xs;
-      vector < double > dxsl;
-      vector < double > dxsu;
-   };
+   std::vector < double > GetCrossSection();                //!< Return vector with all cross section values
+   std::vector < double > GetCrossSection(bool lNorm);      //!< Return vector with all cross section values, normalize on request
+   std::vector < double > GetNormCrossSection();            //!< Return vector with all normalized cross section values
+   std::vector < std::map< double, double > > GetCrossSection_vs_x1(); //! Cross section vs. x1 ( XSection_vsX1[bin][<x,xs>] )
+   std::vector < std::map< double, double > > GetCrossSection_vs_x2(); //! Cross section vs. x2 ( XSection_vsX1[bin][<x,xs>] )
 
-   vector < double > GetCrossSection();                                                 //! Return vector with all cross section values
+   std::vector < double > GetReferenceCrossSection();
+   std::vector < double > GetKFactors();  ///< DEPRECATED
+   std::vector < double > GetQScales();   //!< Order (power of alpha_s) rel. to LO: 0 --> LO, 1 --> NLO
+   std::vector < std::vector < double > > GetCrossSection2Dim();
 
-   //! Return struct with vectors containing the cross section values and the selected scale uncertainty
-   XsUncertainty GetScaleUncertainty( const EScaleUncertaintyStyle eScaleUnc );
-   // Deprecated: Replaced by struct as return object: Return vector of pairs with all cross section values first and pairs of scale uncertainties second
-   //   vector < pair < double, pair <double, double> > > GetScaleUncertainty( const EScaleUncertaintyStyle eScaleUnc );
 
-   vector < double > GetReferenceCrossSection();
-   vector < double > GetKFactors();
-   vector < double > GetQScales(int irelord);                                           //!< Order (power of alpha_s) rel. to LO: 0 --> LO, 1 --> NLO
-   vector < vector < double > > GetCrossSection2Dim();
+   //! Return struct with vectors containing the cross section values and the selected scale uncertainty
+   XsUncertainty GetScaleUncertainty( const fastNLO::EScaleUncertaintyStyle eScaleUnc );
+   XsUncertainty GetScaleUncertainty( const fastNLO::EScaleUncertaintyStyle eScaleUnc, bool lNorm );
+   //! Function for use with pyext (TODO: Clean this up)
+   std::vector< std::vector<double> > GetScaleUncertaintyVec( const fastNLO::EScaleUncertaintyStyle eScaleUnc );
 
    // ---- Getters for fastNLOReader member variables ---- //
    fastNLO::EScaleFunctionalForm GetMuRFunctionalForm() const { return fMuRFunc; };
@@ -73,24 +110,34 @@ public:
    fastNLO::EUnits GetUnits() const { return fUnits; };
    mu_func GetExternalFuncForMuR() { return Fct_MuR; };
    mu_func GetExternalFuncForMuF() { return Fct_MuF; };
+   double fConst_MuR; //!< Constant _value_ for the renormalization scale. Used only for flexible-scale tables and if requested.
+   double fConst_MuF; //!< Constant _value_ for the factorization scale. Used only for flexible-scale tables and if requested.
+
    double GetScaleFactorMuR() const { return fScaleFacMuR; };
    double GetScaleFactorMuF() const { return fScaleFacMuF; };
    int GetScaleVariation() const { return fScalevar; };
-   string GetScaleDescription(const ESMOrder eOrder, int iScale=0) const;
-   double GetNevt(const ESMOrder eOrder) const;
+   std::string GetScaleDescription(const fastNLO::ESMOrder eOrder, int iScale=0) const;
+   double GetNevt(const fastNLO::ESMOrder eOrder) const;		//!< Get number of events in contribution
+   int GetNSubproc(const fastNLO::ESMOrder eOrder) const;		//!< Get number of subprocesses in this contribution
+   std::vector < std::vector < std::pair < int,int > > > GetSubprocIndices(const fastNLO::ESMOrder eOrder) const; //!< Get information on the members of each subprocess. Each member of the [iSubproc][iPartonPair] pair is a pair of PDGIds indicating the particles involved in the subprocess.
 
    int GetNScaleVariations() const;                                                     //!< Get number of available scale variations
-   vector < double > GetScaleFactors() const;                                           //!< Get list of available scale factors
+   std::vector < double > GetScaleFactors() const;                                           //!< Get list of available scale factors
 
    // ---- Print outs ---- //
-   void PrintTableInfo(const int iprint = 0) const;                                     //!<  Print basic info about fastNLO table and its contributions
-   void PrintFastNLOTableConstants(const int iprint = 2) const;                         //!<  Print (technical) constants of fastNLO table (use iprint) for level of details.
-   void PrintCrossSections() const;                                                     //!<  Print cross sections (optimized for double-differential tables)
-   void PrintCrossSectionsDefault(vector<double> kthc = vector<double>()) const;        //!<  Print cross sections in the same format as in the fortran version.
+   ///  Print basic info about fastNLO table and its contributions
+   void Print(int iprint) const;
+   void PrintContributionSummary(int iprint) const;
+   void PrintCrossSections() const; //!<  Print cross sections (optimized for double-differential tables)
    void PrintCrossSectionsWithReference();
-   //void PrintCrossSectionsData() const;                                                 //!<  Print data table. (if available)
 
-   void RunFastNLODemo();                                                               //!<  Run an example of fastNLO for educational purposes, i.e. calculate and print cross sections for several scale variations
+   // DEPRECATED
+   void PrintTableInfo(const int iprint = 0) const; // DEPRECATED, use PrintContributionSummary instead
+   void PrintFastNLOTableConstants(const int iprint = 2) const; // DEPRECATED, use Print instead
+   void PrintCrossSectionsData() const; ///< DEPRECATED
+   void PrintCrossSectionsDefault(std::vector<double> kthc = std::vector<double>()) const; ///< DEPRECATED
+   void RunFastNLODemo(); ///< DEPRECATED
+
    // ---- Test virtual functions for reasonable values. ---- //
    bool TestXFX();                                                                      //!< Test if XFX reasonable values
    bool TestAlphas();                                                                   //!< Test if EvolvaAlphas returns a reasonable value
@@ -100,11 +147,11 @@ protected:
    fastNLOReader();
    void OrderCoefficients() ;
    //void ReadTable();
-   void StripWhitespace(string* s);
+   void StripWhitespace(std::string* s);
 
-   void PrintScaleSettings(fastNLO::EMuX kMuX=kMuR);
+   void PrintScaleSettings(fastNLO::EMuX kMuX=fastNLO::kMuR);
    void FillBlockBPDFLCsDISv20(fastNLOCoeffAddFix* B);
-   void FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* B);
+   void FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* B, fastNLOCoeffAddFlex* B0=NULL);
    void FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* B);
    void FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* B);
    void CalcAposterioriScaleVariationMuR();
@@ -123,6 +170,10 @@ protected:
    double FuncMixedOver1(double scale1 , double scale2) ;
    double FuncMixedOver2(double scale1 , double scale2) ;
    double FuncMixedOver4(double scale1 , double scale2) ;
+   double FuncMixed2s2Ov2(double scale1 , double scale2) ;
+   double FuncMixed2s2Ov4(double scale1 , double scale2) ;
+   double FuncPow4Sum(double scale1 , double scale2) ;
+   double FuncWgtAvg(double scale1 , double scale2) ;
    double FuncLinearMean(double scale1 , double scale2) ;
    double FuncLinearSum(double scale1 , double scale2) ;
    double FuncMax(double scale1 , double scale2) ;
@@ -130,36 +181,50 @@ protected:
    double FuncProd(double scale1 , double scale2) ;
    double FuncExpProd2(double scale1 , double scale2) ;
 
-   void CalcCrossSectionv21(fastNLOCoeffAddFlex* B , bool IsLO = false);
-   void CalcCrossSectionv20(fastNLOCoeffAddFix*  B , bool IsLO = false);
+   void CalcCrossSectionv20(fastNLOCoeffAddFix*  B);
+   void CalcCrossSectionv21(fastNLOCoeffAddFlex* B);
 
-   fastNLOCoeffAddBase* B_NLO() const {
-      if ( BBlocksSMCalc[fastNLO::kFixedOrder].size() < 2 ) return NULL;
-      else return (fastNLOCoeffAddBase*) BBlocksSMCalc[fastNLO::kFixedOrder][fastNLO::kNextToLeading];
-   };
    fastNLOCoeffAddBase* B_LO() const {
+      //if ( BBlocksSMCalc[fastNLO::kFixedOrder][fastNLO::kLeading] !=0 ) 
       return (fastNLOCoeffAddBase*) BBlocksSMCalc[fastNLO::kFixedOrder][fastNLO::kLeading];
+      // else if ( B_NLO()!= NULL ) return B_NLO();
+      // else if ( B_NNLO()!= NULL ) return B_NNLO();
+   };
+   fastNLOCoeffAddBase* B_NLO() const {
+      return (fastNLOCoeffAddBase*) BBlocksSMCalc[fastNLO::kFixedOrder][fastNLO::kNextToLeading];
+   };
+   fastNLOCoeffAddBase* B_NNLO() const {
+      return (fastNLOCoeffAddBase*) BBlocksSMCalc[fastNLO::kFixedOrder][fastNLO::kNextToNextToLeading];
    };
    fastNLOCoeffBase* B_ThC(int n=0) {
       if (BBlocksSMCalc[fastNLO::kThresholdCorrection].empty()) return NULL;
       else return BBlocksSMCalc[fastNLO::kThresholdCorrection][n];
    };
-
-   // virtual functions for the user interface
-   virtual bool InitPDF() = 0;
-   virtual double EvolveAlphas(double Q) const = 0;
+   fastNLOCoeffAddBase* B_Any() const {
+      if (B_LO() != NULL ) return B_LO();
+      else if ( B_NLO()!= NULL ) return B_NLO();
+      else if ( B_NNLO()!= NULL ) return B_NNLO();
+      // else if ( B_ThC(0)!= NULL ) return B_ThC(0);
+      // else if ( B_ThC(1)!= NULL ) return B_ThC(1);
+      else {
+	 std::cerr<<"Error. Cannot get any additive contribution, but requested."<<std::endl;
+	 exit(3);
+	 return NULL;
+      }
+   };
 
    // ---- setters for scale variation in v2.0 tables  ---- //
    bool SetScaleVariation(int scalevar);                       //!< Choose the MuF scale variation table
 
    // ---- human readable strings ---- //
-   //static const string fContrName[20];
-   //static const string fOrdName[4][4];
-   //static const string fNSDep[6];
+   //static const std::string fContrName[20];
+   //static const std::string fOrdName[4][4];
+   //static const std::string fNSDep[6];
 
+   bool UpdateProcesses(); //!< Checks if the choosen processes in fselect_processes are compatible to all selected contributions and activate them. Returns true on success false on failure.
 
 protected:
-   string ffilename;
+   std::string ffilename;
    int fScalevar;
    double fScaleFacMuR;
    double fScaleFacMuF;
@@ -171,27 +236,32 @@ protected:
    double fAlphasCached;
    mu_func Fct_MuR;                                                                     //!< Function, if you define your functional form for your scale external
    mu_func Fct_MuF;                                                                     //!< Function, if you define your functional form for your scale external
-   vector < vector < bool > > bUseSMCalc;                                               //!< switch calculations ON/OFF
 
    bool fUseHoppet;
+   double fSqrtSovSP = 1;  //!< Center-of-mass 'reweighting'
+
+   std::vector < std::pair<int,int> >* fselected_processes = NULL;   //!< selected processes. When NULL, all processes are used in the calculation
 
    // ---- pointers to coefftables in fCoeff ---- //
-   //    vector< vector < fastNLOCoeffAddBase* > > fCoAdd;
-   //    vector< vector < fastNLOCoeffMult* > > fCoMult;
-   vector < vector < fastNLOCoeffBase* > > BBlocksSMCalc;                               //!< BlockB's for SM corrections
+   //    std::vector< std::vector < fastNLOCoeffAddBase* > > fCoAdd;
+   //    std::vector< std::vector < fastNLOCoeffMult* > > fCoMult;
+   std::vector < std::vector < fastNLOCoeffBase* > > BBlocksSMCalc;                               //!< BlockB's for SM corrections
 
    // ---- Cross sections ---- //
-   vector < double > XSection_LO;
-   vector < double > XSection;
-   vector < double > kFactor;
-   vector < double > QScale_LO;
-   vector < double > QScale;
+   std::vector < double > XSection_LO;
+   std::vector < double > XSection;
+   std::vector < double > kFactor;
+   std::vector < double > QScale_LO;
+   std::vector < double > QScale;
+   std::vector < std::map< double, double > > fXSection_vsX1; //! Cross section vs. x ( XSection_vsX1[bin][<x,xs>] )
+   std::vector < std::map< double, double > > fXSection_vsX2;
 
    // ----  reference tables ---- //
-   vector < double > XSectionRef;
-   vector < double > XSectionRefMixed;
-   vector < double > XSectionRef_s1;
-   vector < double > XSectionRef_s2;
+   std::vector < double > XSectionRef;
+   std::vector < double > XSectionRefMixed;
+   std::vector < double > XSectionRef_s1;
+   std::vector < double > XSectionRef_s2;
+
 
 };
 #endif
diff --git a/FastNLO/include/fastnlotk/fastNLOTable.h b/FastNLO/include/fastnlotk/fastNLOTable.h
index 97c9b2f3003a91a553ab6f9ac2ec97074afa89f3..0aa2879f7d5819ac090ac4472f282676d937a0be 100644
--- a/FastNLO/include/fastnlotk/fastNLOTable.h
+++ b/FastNLO/include/fastnlotk/fastNLOTable.h
@@ -2,13 +2,12 @@
 // DESY, 08.08.2013
 #ifndef __fastNLOTable__
 #define __fastNLOTable__
-#include <cmath>
 #include <fstream>
+#include <istream>
 #include <string>
-#include <utility>
 #include <vector>
+#include "speaker.h"
 
-#include "fastNLOBase.h"
 #include "fastNLOCoeffBase.h"
 #include "fastNLOCoeffAddFix.h"
 #include "fastNLOCoeffAddFlex.h"
@@ -16,175 +15,291 @@
 #include "fastNLOCoeffMult.h"
 #include "fastNLOConstants.h"
 
-using namespace std;
 
-class fastNLOTable : public fastNLOBase {
+
+class fastNLOTable {
 
  public:
    fastNLOTable();
-   fastNLOTable(string filename);
-   ~fastNLOTable();
+   fastNLOTable(std::string filename);
+   virtual ~fastNLOTable();
    fastNLOTable(const fastNLOTable&);
 
    virtual void ReadTable();
    virtual void WriteTable();
-   virtual void WriteTable(string filename);
+   virtual void WriteTable(std::string filename);
    bool IsCompatible(const fastNLOTable& other) const;
+   bool IsCompatibleScenario(const fastNLOTable& other) const;
+   bool IsCatenable(const fastNLOTable& other) const;
+   bool IsCatenableScenario(const fastNLOTable& other) const;
 
-   // ___________________________________________________________________________________________________
-   // Getters for binning structure
-   // ___________________________________________________________________________________________________
-   // Getters for linear array of "ObsBin"'s running from 0->(NObsBin-1))
-   // Returns no. of observable bins
-   unsigned int GetNObsBin() const {return NObsBin;}
-   // Return lower bin bound for obs. bin iObs in dim. iDim
+   // --- function previously included in fastNLOBase
+   // header
+   void PrintHeader(int iprint) const;                                  //!< Print header variables (BlockA1) to screen
+   bool IsCompatibleHeader(const fastNLOTable& other) const;             //!< Compare header with header of another table
+   bool IsCatenableHeader(const fastNLOTable& other) const;              //!< Compare header with header of another table
+
+   // getter/setters
+   std::string GetFilename() const {return ffilename;}
+   void   SetFilename(std::string name){ffilename=name;}
+
+   int  GetItabversion() const {return Itabversion;}
+   void SetItabversion(int version){Itabversion = version;}
+
+   std::string GetScenName() const {return ScenName;}
+   void   SetScenName(std::string name){ScenName = name;}
+
+   int  GetNmult() const;
+   int  GetNcontrib() const;
+   int  GetNdata() const;
+
+   int  GetOutputPrecision() const {return fPrecision;}
+   void SetOutputPrecision(int precision) {fPrecision = precision;}
+
+   /// _____________________________________________________________________________________________
+   /// Getters for binning structure
+   /// _____________________________________________________________________________________________
+
+   /// Get dimensionality of calculation: single-, double-, or triple-differential
+   unsigned int GetNumDiffBin() const {return NDim;}
+
+   /// Getters for linear array of observable bins "ObsBin" running from 0->(NObsBin-1)
+
+   /// Return lower bin bound for obs. bin iObs in dim. iDim
    double GetObsBinLoBound(unsigned int iObs, unsigned int iDim) const;
-   // Return upper bin bound for obs. bin iObs in dim. iDim
+   /// Return upper bin bound for obs. bin iObs in dim. iDim
    double GetObsBinUpBound(unsigned int iObs, unsigned int iDim) const;
-   // Return vector of lower bin bounds in dim. iDim for all obs. bins
-   vector < double > GetObsBinsLoBounds(unsigned int iDim) const;
-   // Return vector of upper bin bounds in dim. iDim for all obs. bins
-   vector < double > GetObsBinsUpBounds(unsigned int iDim) const;
-   // Return minimum value of all lower bin bounds for dim. iDim
+   /// Return std::vector of lower bin bounds in dim. iDim for all obs. bins
+   std::vector < double > GetObsBinsLoBounds(unsigned int iDim) const;
+   /// Return std::vector of upper bin bounds in dim. iDim for all obs. bins
+   std::vector < double > GetObsBinsUpBounds(unsigned int iDim) const;
+   /// Return minimum value of all lower bin bounds for dim. iDim
    double GetObsBinsLoBoundsMin(unsigned int iDim) const;
-   // Return maximum value of all upper bin bounds for dim. iDim
+   /// Return maximum value of all upper bin bounds for dim. iDim
    double GetObsBinsUpBoundsMax(unsigned int iDim) const;
-   // Return vector of pairs with lower and upper bin bounds in dim. iDim for all obs. bins
-   vector < pair < double, double > > GetObsBinsBounds(unsigned int iDim) const;
-   // Return observable bin no. for vector of values obs0=var0,obs1=var1,...; -1 if outside range
-   int GetObsBinNumber(const vector < double >& vobs) const ;
-   // Return observable bin no. for obs0=var0 in 1D binning; -1 if outside range
+   /// Return std::vector of pairs with lower and upper bin bounds in dim. iDim for all obs. bins
+   std::vector < std::pair < double, double > > GetObsBinsBounds(unsigned int iDim) const;
+   /// Return observable bin no. for std::vector of values obs0=var0,obs1=var1,...; -1 if outside range
+   int GetObsBinNumber(const std::vector < double >& vobs) const ;
+   /// Return observable bin no. for obs0=var0 in 1D binning; -1 if outside range
    int GetObsBinNumber(double var0) const ;
-   // Return observable bin no. for obs0=var0,obs1=var1 in 2D binning; -1 if outside range
+   /// Return observable bin no. for obs0=var0,obs1=var1 in 2D binning; -1 if outside range
    int GetObsBinNumber(double var0, double var1) const ;
-   // Return observable bin no. for obs0=var0,obs1=var1,obs2=var2 in 3D binning; -1 if outside range
+   /// Return observable bin no. for obs0=var0,obs1=var1,obs2=var2 in 3D binning; -1 if outside range
    int GetObsBinNumber(double var0, double var1, double var2) const ;
 
-   // Getters for multidimensional binning, here called Dim<I>Bins
-   // Return vector of pairs with unique bin bounds of 1st dim.
-   vector < pair < double, double > > GetDim0BinBounds() const;
-   // Return vector of pairs with unique bin bounds of 2nd dim. for 'iDim0Bin' of 1st dim.
-   vector < pair < double, double > > GetDim1BinBounds(unsigned int iDim0Bin) const;
-   // Return vector of pairs with unique bin bounds of 3rd dim. for 'iDim0Bin' and 'iDim1Bin' of 1st two dim.
-   vector < pair < double, double > > GetDim2BinBounds(unsigned int iDim0Bin, unsigned int iDim1Bin) const;
-   // Return vector of pairs with lower and upper bin bounds for all dimensions for a given obs. bin
-   vector < pair < double, double > > GetObsBinDimBounds(unsigned int iObs) const;
-   // Return pair with lower and upper bin bounds for given obs. bin and dim. iDim
-   pair < double, double > GetObsBinDimBounds(unsigned int iObs, unsigned int iDim) const;
-   // Return bin no. in 1st dim. for obs. bin iObs
+   /// Getters for multidimensional binning, here called Dim<I>Bins
+
+   /// Return std::vector of pairs with unique bin bounds of 1st dim.
+   std::vector < std::pair < double, double > > GetDim0BinBounds() const;
+   /// Return std::vector of pairs with unique bin bounds of 2nd dim. for 'iDim0Bin' of 1st dim.
+   std::vector < std::pair < double, double > > GetDim1BinBounds(unsigned int iDim0Bin) const;
+   /// Return std::vector of pairs with unique bin bounds of 3rd dim. for 'iDim0Bin' and 'iDim1Bin' of 1st two dim.
+   std::vector < std::pair < double, double > > GetDim2BinBounds(unsigned int iDim0Bin, unsigned int iDim1Bin) const;
+   /// Return std::vector of pairs with lower and upper bin bounds for all dimensions for a given obs. bin
+   std::vector < std::pair < double, double > > GetObsBinDimBounds(unsigned int iObs) const;
+   /// Return pair with lower and upper bin bounds for given obs. bin and dim. iDim
+   std::pair < double, double > GetObsBinDimBounds(unsigned int iObs, unsigned int iDim) const;
+   /// Return bin no. in 1st dim. for obs. bin iObs
    unsigned int GetIDim0Bin(unsigned int iObs) const;
-   // Return bin no. in 2nd dim. for obs. bin iObs
+   /// Return bin no. in 2nd dim. for obs. bin iObs
    unsigned int GetIDim1Bin(unsigned int iObs) const;
-   // Return bin no. in 3rd dim. for obs. bin iObs
+   /// Return bin no. in 3rd dim. for obs. bin iObs
    unsigned int GetIDim2Bin(unsigned int iObs) const;
-   // Return no. of bins in 1st dimension
+   /// Return no. of bins in 1st dimension
    unsigned int GetNDim0Bins() const;
-   // Return no. of bins in 2nd dimension for given bin in 1st dim.
+   /// Return no. of bins in 2nd dimension for given bin in 1st dim.
    unsigned int GetNDim1Bins(unsigned int iDim0Bin) const;
-   // Return no. of bins in 3rd dimension for given bins in 1st and 2nd dim.
+   /// Return no. of bins in 3rd dimension for given bins in 1st and 2nd dim.
    unsigned int GetNDim2Bins(unsigned int iDim0Bin, unsigned int iDim1Bin) const;
-   // Return bin no. in 1st dim. for obs0=var0; -1 if outside range
+   /// Return bin no. in 1st dim. for obs0=var0; -1 if outside range
    int GetODim0Bin(double var0) const;
-   // Return bin no. in 2nd dim. for obs0=var0,obs1=var1; -1 if outside range
+   /// Return bin no. in 2nd dim. for obs0=var0,obs1=var1; -1 if outside range
    int GetODim1Bin(double var0, double var1) const;
-   // Return bin no. in 3rd dim. for obs0=var0,obs1=var1,obs2=var2; -1 if outside range
+   /// Return bin no. in 3rd dim. for obs0=var0,obs1=var1,obs2=var2; -1 if outside range
    int GetODim2Bin(double var0, double var1, double var2) const;
-   // DO NOT USE! DOES NOT WORK YET!
-   unsigned int GetIDimBin(unsigned int iObs, unsigned int iDim) const;
-   vector < pair < double, double > > GetBinBoundaries(int iDim0Bin, int iDim1Bin = -1, int iDim2Bin = -1);
+   // DO NOT USE! DOES NOT WORK!
+   //   unsigned int GetIDimBin(unsigned int iObs, unsigned int iDim) const;
+   //   std::vector < std::pair < double, double > > GetBinBoundaries(int iDim0Bin, int iDim1Bin = -1, int iDim2Bin = -1);
 
+   /// ___________________________________________________________________________________________________
+   /// Some more info getters with respect to observable dimensions
+   /// ___________________________________________________________________________________________________
 
-   // ___________________________________________________________________________________________________
-   // Some other info getters
-   // ___________________________________________________________________________________________________
-   vector < double > GetBinSize() const {return BinSize;};                                      //!< Get Binsize = BinSizeDim1 < * BinSizeDim2 >
-   double GetBinSize(int bin) const {return BinSize[bin];};                                     //!< Get Binsize = BinSizeDim1 < * BinSizeDim2 >
-   void SetNumDiffBin(int iDiff ) { NDim=iDiff; DimLabel.resize(NDim); IDiffBin.resize(NDim);}  //!< Set dimension of calculation. (Single-differential, double-differential, etc...)
-   unsigned int GetNumDiffBin() const { return NDim; }                                                   //!< Get dimension of calculation. (Single-differential, double-differential, etc...)
+   /// Get if dimension is 'truly differential' or bin-integrated (divided by bin width or not)
+   int GetIDiffBin(int bin) const {return IDiffBin[bin];}
+   /// Get BinSize for bin = BinSizeDim1 < * BinSizeDim2 >
+   double GetBinSize(int bin) const {return BinSize[bin];};
+   /// Get vector of dimensions labels
+   std::vector < std::string > GetDimLabels() const {return DimLabel;};
+   /// Get dimension label for dimension iDim
+   std::string GetDimLabel(int iDim) const {return DimLabel[iDim];};
 
-   int GetIDiffBin(int bin) const { return IDiffBin[bin]; }                                     //!< Get if dimension is 'truly differential' or bin-integrated (divided by bin-width or not)
+   /// ___________________________________________________________________________________________________
+   /// Some info getters with respect to normalization
+   /// ___________________________________________________________________________________________________
 
-   void SetDimLabel( string label, unsigned int iDim , bool IsDiff = true );
-   string GetDimLabel( int iDim  ) const {return DimLabel[iDim];};                              //!< Get label (name) of observable in dimension iDim
-   vector<string > GetDimLabels() const {return DimLabel;};                                     //!< Get label (name) of all observables
+   /// Get normalization flag:
+   ///    def=0        -> no norm.
+   ///     1, 2, 3,... -> normalize to slice in NDim of same table
+   ///    -1,-2,-3,... -> normalize to slice in NDim of other table
+   int GetINormFlag() const {return INormFlag;};
+   /// Get normalization logical (def=false)
+   bool IsNorm() const {return INormFlag == 0 ? false : true;}
+   /// Get filename of normalization table for INormFlag<0
+   std::string GetDenomTable() const {return DenomTable;}
 
-   void SetIpublunits(int unit){Ipublunits = unit;}
+   /// ___________________________________________________________________________________________________
+   /// Some info getters & setters for table modifications
+   /// ___________________________________________________________________________________________________
+
+   /// get/set scenario description
+   std::vector <std::string> GetScDescr() const;
+   void SetScDescr(std::vector <std::string> ScDescr);
+
+   /// get/set cross section units of published results (pb = 12, fb = 15, ...)
    int GetIpublunits() const {return Ipublunits;}
+   void SetIpublunits(int unit){Ipublunits = unit;}
 
+   /// get/set center-of-mass energy in units of GeV
    double GetEcms() const {return Ecms;}
    void SetEcms(double E) {Ecms = E;}
 
+   /// get/set power of alpha_s for LO process
    int GetLoOrder() const {return ILOord;}
    void SetLoOrder(int LOOrd);
 
-   bool IsNorm() const { return INormFlag == 0 ? false : true;}
-   string GetDenomTable() const {return DenomTable;}
+   /// get/set no. of observable bins
+   unsigned int GetNObsBin() const {return NObsBin;}
+   void SetNObsBin(int NObs);
+
+   /// get/set Bin vector
+   std::vector < std::vector <std::pair<double,double> > > GetBins() const {return Bin;};
+   void SetBins(std::vector < std::vector <std::pair<double,double> > >);
+
+   /// get/set BinSize vector
+   std::vector < double > GetBinSize() const {return BinSize;};
+   void SetBinSize(std::vector < double >);
+
+   // Erase observable bin; iObsIdx is the C++ array index to be removed and
+   // not the observable bin no. running from 1 to NObsBin
+   void EraseBinFromTable(unsigned int iObsIdx);
+   template<typename T> void EraseBin(std::vector<T>& v, unsigned int idx);
+
+   // Multiply observable bin; iObsIdx is the C++ array index to be multiplied and
+   // not the observable bin no. running from 1 to NObsBin
+   void MultiplyBinInTable(unsigned int iObsIdx, double fact);
+   void MultiplyBinSize(unsigned int iObsIdx, double fact);
+   template<typename T> void MultiplyBin(std::vector<T>& v, unsigned int idx, double fact);
+
+   void CatBinToTable(const fastNLOTable& other, unsigned int iObsIdx, unsigned int table_count);
+   void CatBin(const fastNLOTable& other, unsigned int iObsIdx, unsigned int table_count);
+
+   /// ???
+   /// Get Rivet ID of analysis
+   std::string GetRivetId() const;
+   /// Get cross section from analysis description
+   std::string GetXSDescr() const;
+   void SetDimLabel(std::string label, unsigned int iDim, bool IsDiff = true);
+   void SetNumDiffBin(int iDiff) {NDim=iDiff; DimLabel.resize(NDim); IDiffBin.resize(NDim);}
 
-   string GetRivetId() const;
+   //void Cat(const fastNLOCoeffBase& other);
 
 
-   // ___________________________________________________________________________________________________
-   // Info print out functionality
-   // ___________________________________________________________________________________________________
-   //  Print basic info about fastNLO table and its contributions
-   void PrintTableInfo(const int iprint = 0) const;
-   //  Print (technical) constants of fastNLO table (use iprint) for level of details.
-   void PrintFastNLOTableConstants(const int iprint = 0) const;
-   void PrintScenario() const;
-   virtual void Print() const;
+   /// ___________________________________________________________________________________________________
+   /// Info print out functionality
+   /// ___________________________________________________________________________________________________
 
+   ///  Print basic info about fastNLO table and its contributions
+   void PrintTableInfo(const int iprint = 0) const; // DEPRECATED, use PrintContributionSummary instead
+   void PrintContributionSummary(int iprint) const;
+   ///  Print (technical) constants of fastNLO table (use iprint) for level of details.
+   void PrintFastNLOTableConstants(const int iprint = 0) const;  // DEPRECATED, use PrintContributionSummary instead
+   void PrintScenario(int iprint) const;
+   virtual void Print(int iprint) const;
 
-   // ___________________________________________________________________________________________________
-   // Other useful functions
-   // ___________________________________________________________________________________________________
-   // handle coefficient tables
+   /// ___________________________________________________________________________________________________
+   /// Other useful functions
+   /// ___________________________________________________________________________________________________
+   void MergeTable(const fastNLOTable& rhs, fastNLO::EMerge option=fastNLO::kMerge ); //!< 'merge' 
+   void MergeTables(const std::vector<fastNLOTable*>& tables, fastNLO::EMerge option=fastNLO::kMerge, double cutRMS=0 ); //!< 'merge' (also supports 'median' and 'mean')
+   void AddTable(const fastNLOTable& rhs, fastNLO::EMerge option=fastNLO::kMerge); //!< 'merge'
+   void SetUserWeights(double wgt); //!< Set user weights for subsequent mergeing wgt
+   void SetUserWeights(std::vector<double> wgtsObs); //!< Set user weights for subsequent mergeing wgt[obs]
+   void SetUserWeights(std::vector<std::vector<double> > wgtsBinProc); //!< Set user weights for subsequent mergeing wgt[proc][obs]
+
+   /// Handle coefficient tables
    //int WriteCoeffTable(int no);
    //int WriteCoeffTable(int no,ofstream* outstream );
    //int WriteCoeffTableDividebyN(int no);
    void DeleteAllCoeffTable();
    //int CreateCoeffBase(int no);
    int CreateCoeffTable(int no,fastNLOCoeffBase *newcoeff);
-   void AddTable(const fastNLOTable& rhs);
+   void CatenateTable(const fastNLOTable& other);
    fastNLOCoeffBase* GetCoeffTable(int no) const;
-   fastNLOCoeffData* GetDataTable() const;                                                      //!< returns pointer to data table if available, else returns NULL pointer
-   fastNLOCoeffAddBase* GetReferenceTable(ESMOrder eOrder) const;                               //!< returns pointer to reference table if available, else returns NULL pointer
+   /// Returns pointer to data table if available, else returns NULL pointer
+   fastNLOCoeffData* GetDataTable() const;
+   /// Returns pointer to reference table if available, else returns NULL pointer
+   fastNLOCoeffAddBase* GetReferenceTable(fastNLO::ESMOrder eOrder) const;
+
 
 
 private:
    bool cmp(const double x1, const double x2) const;
-   bool cmp(const vector<double>& x1, const vector<double >& x2) const;
-   bool cmp(const vector<vector<double> >& x1,const vector<vector<double > >& x2) const;
-   bool cmp(const vector<vector<pair<double,double> > >&  x1,const vector<vector<pair<double,double> > >& x2) const;
-
+   bool cmp(const std::vector<double>& x1, const std::vector<double >& x2) const;
+   bool cmp(const std::vector<std::vector<double> >& x1,const std::vector<std::vector<double > >& x2) const;
+   bool cmp(const std::vector<std::vector<std::pair<double,double> > >&  x1,const std::vector<std::vector<std::pair<double,double> > >& x2) const;
 
 protected:
-   void WriteScenario(ostream& table);
-   void ReadScenario(istream& table);
-   void ReadCoeffTables(istream& table);
-   fastNLOCoeffBase* ReadRestOfCoeffTable(const fastNLOCoeffBase& cB, istream& table);
+   // --- functions previously included in fastNLOBase
+   void PrintWelcomeMessage();                         //!< Say hello to fastNLO user
+   std::ostream* OpenFileWrite(bool compress=false); //!< open std::ofstream for writing tables to ffilename
+   std::istream* OpenFileRead();                     //!< open std::ifstream for reading table
+   //std::ofstream *OpenFileRewrite();
+   void WriteHeader(std::ostream& table);          //!< write (or cout) hader using std::ostream
+   int ReadHeader(std::istream& table);           //!< read header of table (BlockA1)
+   void CloseFileWrite(std::ostream& table);
+   void CloseFileRead(std::istream& table);
+   //void CloseStream();
+
+   std::string ffilename;
+   int fPrecision;
+   int Itabversion;
+   std::string ScenName;
+
+   PrimalScream logger;
+   static bool fWelcomeOnce;
+   // ---- fastNLOBase end
+
+
+   void WriteScenario(std::ostream& table);
+   void ReadScenario(std::istream& table);
+   void ReadCoeffTables(std::istream& table, int nCoeff);
+   fastNLOCoeffBase* ReadRestOfCoeffTable(const fastNLOCoeffBase& cB, std::istream& table);
 
-   vector < fastNLOCoeffBase* > fCoeff;
+   std::vector < fastNLOCoeffBase* > fCoeff;
    //fastNLOCoeffData* fData;
 
    double Ecms;
    int ILOord;
    int Ipublunits;
-   vector <string> ScDescript;
+   std::vector <std::string> ScDescript;
 
-   // CKR: Changed to unsigned int
+   // Unsigned int
    unsigned int NObsBin;
    unsigned int NDim;
 
-   vector <string> DimLabel;
-   vector <int> IDiffBin;
-   vector < vector <pair<double,double> > > Bin; // every bin has a lower and upper bin boundary and belongs to a 'dimension'. If a truely differential measurment, then upper bin boundary is equal lower one
-   vector <double> BinSize;
+   std::vector <std::string> DimLabel;
+   std::vector <int> IDiffBin;
+   // Every bin has a lower and upper bin boundary and belongs to a 'dimension'. In a point-wise differential measurement, the upper bin boundary is equal to the lower one.
+   std::vector < std::vector <std::pair<double,double> > > Bin;
+   std::vector <double> BinSize;
 
-   // contributions for normalization
+   // Contributions for normalization
    int INormFlag;
-   string DenomTable;
-   vector <int> IDivLoPointer;
-   vector <int> IDivUpPointer;
+   std::string DenomTable;
+   std::vector <int> IDivLoPointer;
+   std::vector <int> IDivUpPointer;
 
 };
 #endif
diff --git a/FastNLO/include/fastnlotk/fastNLOTools.h b/FastNLO/include/fastnlotk/fastNLOTools.h
index e8cb13bd11b3421db017e8460eeb7e1712dafb4b..69351ae84993fb4919ad907c0a59a0b6f0b39e6f 100644
--- a/FastNLO/include/fastnlotk/fastNLOTools.h
+++ b/FastNLO/include/fastnlotk/fastNLOTools.h
@@ -8,71 +8,75 @@
 
 namespace fastNLOTools {
 
-   using namespace std;
-   using namespace say;
-   using namespace fastNLO;
 
-   //! - Reading vectors from disk
-   template<typename T> int ReadVector( vector<T>& v, istream& table , double nevts = 1);
-   int ReadVector( vector<double>& v, istream& table , double nevts = 1);
+   //! - Reading std::vectors from disk
+   template<typename T> int ReadVector( std::vector<T>& v, std::istream& table , double nevts = 1);
+   int ReadVector( std::vector<double>& v, std::istream& table , double nevts = 1);
 
-   template<typename T>  int ReadFlexibleVector(vector<T>& v, istream& table, int nProcLast=0 , double nevts = 1);
-   int ReadFlexibleVector( vector<double >& v, istream& table , int nProcLast = 0 , double nevts = 1 );
+   template<typename T>  int ReadFlexibleVector(std::vector<T>& v, std::istream& table, int nProcLast=0 , double nevts = 1);
+   int ReadFlexibleVector( std::vector<std::string >& v, std::istream& table , int nProcLast = 0 , double nevts = 1 );
+   int ReadFlexibleVector( std::vector<double >& v, std::istream& table , int nProcLast = 0 , double nevts = 1 );
+   int ReadFlexibleVector( std::vector<int >& v, std::istream& table , int nProcLast = 0 , double nevts = 1 );
+   int ReadFlexibleVector( std::vector<unsigned long long >& v, std::istream& table , int nProcLast = 0 , double nevts = 1 );
+   int ReadUnused( std::istream& table );
 
    //! - Resizing tools
-   template<typename T> void ResizeFlexibleVector(vector<T>& v, const vector<T>& nom);
-   void ResizeFlexibleVector( vector<double >& v, const vector<double >& nom);
+   template<typename T> void ResizeFlexibleVector(std::vector<T>& v, const std::vector<T>& nom);
+   void ResizeFlexibleVector( std::vector<double >& v, const std::vector<double >& nom);
+   void ResizeFlexibleVector( std::vector<unsigned long long >& v, const std::vector<double >& nom);
 
    //! - Clearing tools
-   template<typename T> void ClearVector(vector<vector<T > >& v);
-   template<typename T> void ClearVector(vector<T>& v);
+   template<typename T> void ClearVector(std::vector<std::vector<T > >& v);
+   template<typename T> void ClearVector(std::vector<T>& v);
 
    // there are nicer  options in c++11
-   void ResizeVector( v1d& v, int dim0 );
-   void ResizeVector( v2d& v, int dim0 , int dim1 );
-   void ResizeVector( v3d& v, int dim0 , int dim1, int dim2 );
-   void ResizeVector( v4d& v, int dim0 , int dim1, int dim2, int dim3 );
-   void ResizeVector( v5d& v, int dim0 , int dim1, int dim2, int dim3, int dim4 );
-   void ResizeVector( v6d& v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5 );
-   void ResizeVector( v7d& v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5, int dim6 );
-
-   //! - Check if vector is empty
-   template<typename T> bool IsEmptyVector(const vector<vector<T > >& v);
-   template<typename T> bool IsEmptyVector(const vector<T>& v);
+   void ResizeVector( fastNLO::v1d& v, int dim0 );
+   void ResizeVector( fastNLO::v2d& v, int dim0 , int dim1 );
+   void ResizeVector( fastNLO::v3d& v, int dim0 , int dim1, int dim2 );
+   void ResizeVector( fastNLO::v4d& v, int dim0 , int dim1, int dim2, int dim3 );
+   void ResizeVector( fastNLO::v5d& v, int dim0 , int dim1, int dim2, int dim3, int dim4 );
+   void ResizeVector( fastNLO::v6d& v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5 );
+   void ResizeVector( fastNLO::v7d& v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5, int dim6 );
+
+   //! - Check if std::vector is empty
+   template<typename T> bool IsEmptyVector(const std::vector<std::vector<T > >& v);
+   template<typename T> bool IsEmptyVector(const std::vector<T>& v);
 
    //! - Writing tables to disk
-   //! use 'fastNLO::WriteVector(vector..., *table, nevts=1) to write fastNLO table in v2.0 format to disk
-   //! use 'fastNLO::WriteFlexibleVector(vector..., *table, int nProcLast=0, nevts=1) to write 'flexible' table
-   template<typename T> int WriteVector( const vector<T>& v, ostream& table , double nevts=1 );
-   template<typename T> int _Write1DVectorByN( const vector<T>& v, ostream& table , double nevts );
-   template<typename T> int _Write1DVector( const vector<T>& v, ostream& table);
-   int WriteVector( const vector<double >& v, ostream& table , double nevts=1 );
-   int WriteVector( const vector<string >& v, ostream& table , double nevts=1 );
-   int WriteVector( const vector<int >& v, ostream& table , double nevts=1 ) ;
-   int WriteVector( const vector<unsigned long long >& v, ostream& table , double nevts=1 );
-   
-   template<typename T> int WriteFlexibleVector( const vector<T>& v, ostream& table, int nProcLast = 0, double nevts=1 );
-   int WriteFlexibleVector( const vector<double >& v, ostream& table, int nProcLast = 0 , double nevts=1 );
-   int WriteFlexibleVector( const vector<string >& v, ostream& table, int nProcLast = 0 , double nevts=1 );
-   int WriteFlexibleVector( const vector<int >& v, ostream& table, int nProcLast = 0 , double nevts=1 );
-   int WriteFlexibleVector( const vector<unsigned long long >& v, ostream& table, int nProcLast = 0 , double nevts=1 );
-   
-   //! - adding vectors
-   template<typename T> void AddVectors( vector<T>& vSum, const vector<T>& vAdd, double w1 = 1, double w2 = 1 );
-   template<typename T> void _DoAddVectors( vector<T>& vSum, const vector<T>& vAdd, double w1 = 1, double w2 = 1 );
-   void AddVectors( vector<double >& vSum, const vector<double >& vAdd, double w1 = 1, double w2 = 1 ) ;
-   void AddVectors( vector<int >& vSum, const vector<int >& vAdd, double w1 = 1, double w2 = 1 ) ;
-   void AddVectors( vector<unsigned long long >& vSum, const vector<unsigned long long >& vAdd, double w1=1, double w2=1  ) ;
-
-   //! - String modifications
-   void StripWhitespace(string& s);
-
-   //! - Printout of vectors
-   template<typename T> void PrintVector( const vector<T>& v, string name, string prefix="");
+   //! use 'fastNLO::WriteVector(std::vector..., *table, nevts=1) to write fastNLO table in v2.0 format to disk
+   //! use 'fastNLO::WriteFlexibleVector(std::vector..., *table, int nProcLast=0, nevts=1) to write 'flexible' table
+   template<typename T> int WriteVector( const std::vector<T>& v, std::ostream& table , double nevts=1 );
+   template<typename T> int _Write1DVectorByN( const std::vector<T>& v, std::ostream& table , double nevts );
+   template<typename T> int _Write1DVector( const std::vector<T>& v, std::ostream& table);
+   int WriteVector( const std::vector<double >& v, std::ostream& table , double nevts=1 );
+   int WriteVector( const std::vector<std::string >& v, std::ostream& table , double nevts=1 );
+   int WriteVector( const std::vector<int >& v, std::ostream& table , double nevts=1 ) ;
+   int WriteVector( const std::vector<unsigned long long >& v, std::ostream& table , double nevts=1 );
+
+   template<typename T> int WriteFlexibleVector( const std::vector<T>& v, std::ostream& table, int nProcLast = 0, double nevts=1 );
+   int WriteFlexibleVector( const std::vector<double >& v, std::ostream& table, int nProcLast = 0 , double nevts=1 );
+   int WriteFlexibleVector( const std::vector<std::string >& v, std::ostream& table, int nProcLast = 0 , double nevts=1 );
+   int WriteFlexibleVector( const std::vector<int >& v, std::ostream& table, int nProcLast = 0 , double nevts=1 );
+   int WriteFlexibleVector( const std::vector<unsigned long long >& v, std::ostream& table, int nProcLast = 0 , double nevts=1 );
+
+   //! - adding std::vectors
+   template<typename T> void AddVectors( std::vector<T>& vSum, const std::vector<T>& vAdd, double w1 = 1, double w2 = 1 );
+   template<typename T> void _DoAddVectors( std::vector<T>& vSum, const std::vector<T>& vAdd, double w1 = 1, double w2 = 1 );
+   void AddVectors( std::vector<double >& vSum, const std::vector<double >& vAdd, double w1 = 1, double w2 = 1 ) ;
+   void AddVectors( std::vector<int >& vSum, const std::vector<int >& vAdd, double w1 = 1, double w2 = 1 ) ;
+   void AddVectors( std::vector<unsigned long long >& vSum, const std::vector<unsigned long long >& vAdd, double w1=1, double w2=1  ) ;
+
+   //! - std::string modifications
+   void StripWhitespace(std::string& s);
+
+   //! - Printout of std::vectors
+   template<typename T> void PrintVector( const std::vector<T>& v, std::string name, std::string prefix="");
 
    //! - useful i/o
-   bool ReadMagicNo(istream& table);					//!< Read and check magic number from table.	
-   void PutBackMagicNo(istream& table);					//!< Reset magic number, such that it can be recognized by other reading routines
+   bool CheckVersion(int version); //!< check version and exit if failed.
+   //bool CheckVersion(const std::string& version) {return CheckVersion((int)std::stoi(version));} ; //!< check version and exit if failed.
+   bool ReadMagicNo(std::istream& table);                                       //!< Read and check magic number from table.
+   void PutBackMagicNo(std::istream& table);                                    //!< Reset magic number, such that it can be recognized by other reading routines
 
 };
 
@@ -81,8 +85,8 @@ namespace fastNLOTools {
 //________________________________________________________________________________________________________________
 // Reading functions
 template<typename T>
-int fastNLOTools::ReadVector( vector<T>& v, istream& table , double nevts){
-   //! Read values according to the size() of the given vector
+int fastNLOTools::ReadVector( std::vector<T>& v, std::istream& table , double nevts){
+   //! Read values according to the size() of the given std::vector
    //! from table (v2.0 format).
    int nn = 0;
    for( unsigned int i=0 ; i<v.size() ; i++ ){
@@ -93,7 +97,7 @@ int fastNLOTools::ReadVector( vector<T>& v, istream& table , double nevts){
 
 
 template<typename T>
-int fastNLOTools::ReadFlexibleVector(vector<T>& v, istream& table, int nProcLast, double nevts ){
+int fastNLOTools::ReadFlexibleVector(std::vector<T>& v, std::istream& table, int nProcLast, double nevts ){
    int nn = 0;
    int size = 0;
    table >> size; nn++;
@@ -107,7 +111,7 @@ int fastNLOTools::ReadFlexibleVector(vector<T>& v, istream& table, int nProcLast
 //________________________________________________________________________________________________________________
 // Resizing functions
 template<typename T>
-void fastNLOTools::ResizeFlexibleVector(vector<T>& v, const vector<T>& nom) {
+void fastNLOTools::ResizeFlexibleVector(std::vector<T>& v, const std::vector<T>& nom) {
    v.resize(nom.size());
    for (unsigned int i = 0 ; i<v.size() ; i++) {
       ResizeFlexibleVector(v[i],nom[i]);
@@ -116,16 +120,16 @@ void fastNLOTools::ResizeFlexibleVector(vector<T>& v, const vector<T>& nom) {
 
 
 //________________________________________________________________________________________________________________
-// Clearing 
+// Clearing
 template<typename T>
-void fastNLOTools::ClearVector(vector<vector<T > >& v) {
+void fastNLOTools::ClearVector(std::vector<std::vector<T > >& v) {
    for (unsigned int i = 0 ; i<v.size() ; i++) {
       ClearVector(v[i]);
    }
 };
 
 template<typename T>
-void fastNLOTools::ClearVector(vector<T >& v) {
+void fastNLOTools::ClearVector(std::vector<T >& v) {
    for (unsigned int i = 0 ; i<v.size() ; i++) {
       v[i]=0;
    }
@@ -133,10 +137,10 @@ void fastNLOTools::ClearVector(vector<T >& v) {
 
 
 //________________________________________________________________________________________________________________
-// Check if vector is empty
-template<typename T> 
-bool fastNLOTools::IsEmptyVector(const vector<vector<T > >& v){
-   //! check if vector is 'empty', or if sum of all elements is 0.
+// Check if std::vector is empty
+template<typename T>
+bool fastNLOTools::IsEmptyVector(const std::vector<std::vector<T > >& v){
+   //! check if std::vector is 'empty', or if sum of all elements is 0.
    if ( v.empty() ) return true;
    for (unsigned int i = 0 ; i<v.size() ; i++) {
       if ( !IsEmptyVector(v[i]) ) return false;
@@ -144,9 +148,9 @@ bool fastNLOTools::IsEmptyVector(const vector<vector<T > >& v){
    return true;
 }
 
-template<typename T> 
-bool fastNLOTools::IsEmptyVector(const vector<T>& v){
-   //! check if vector is 'empty', or if sum of all elements is 0.
+template<typename T>
+bool fastNLOTools::IsEmptyVector(const std::vector<T>& v){
+   //! check if std::vector is 'empty', or if sum of all elements is 0.
    if ( v.empty() ) return true;
    for (unsigned int i = 0 ; i<v.size() ; i++) {
       if ( v[i] != 0 ) return false;
@@ -158,8 +162,8 @@ bool fastNLOTools::IsEmptyVector(const vector<T>& v){
 //________________________________________________________________________________________________________________
 // Writing functions
 template<typename T>
-int fastNLOTools::WriteVector( const vector<T>& v, ostream& table , double nevts) {
-   //! Write values of vector v to table (v2.0 format) .
+int fastNLOTools::WriteVector( const std::vector<T>& v, std::ostream& table , double nevts) {
+   //! Write values of std::vector v to table (v2.0 format) .
    int nn = 0;
    for(unsigned int i=0;i<v.size();i++)
       nn += WriteVector( v[i] , table , nevts );
@@ -167,29 +171,29 @@ int fastNLOTools::WriteVector( const vector<T>& v, ostream& table , double nevts
 }
 
 template<typename T>
-int fastNLOTools::_Write1DVectorByN( const vector<T>& v, ostream& table , double nevts) {
+int fastNLOTools::_Write1DVectorByN( const std::vector<T>& v, std::ostream& table , double nevts) {
    if( nevts == 0) return -1000;
    for(unsigned int i0=0;i0<v.size();i0++)
-      table << v[i0] / nevts << endl;
+      table << v[i0] / nevts << fastNLO::sep;
    return v.size();
 }
 
 template<typename T>
-int fastNLOTools::_Write1DVector( const vector<T>& v, ostream& table ) {
+int fastNLOTools::_Write1DVector( const std::vector<T>& v, std::ostream& table ) {
    for(unsigned int i0=0;i0<v.size();i0++)
-      table << v[i0] << endl;
+      table << v[i0] << fastNLO::sep;
    return v.size();
 }
 
 
 template<typename T>
-int fastNLOTools::WriteFlexibleVector( const vector<T>& v, ostream& table, int nProcLast , double nevts ) {
+int fastNLOTools::WriteFlexibleVector( const std::vector<T>& v, std::ostream& table, int nProcLast , double nevts ) {
    if ( nevts == 0 ) {
-      error["fastNLOTools::WriteFlexibleVector"]<<"Cannot divide by zero."<<endl;
+      say::error["fastNLOTools::WriteFlexibleVector"]<<"Cannot divide by zero."<<std::endl;
       return -1000;
    }
    int nn = 1;
-   table << v.size() << endl;
+   table << v.size() << fastNLO::sep;
    for(unsigned int i0=0;i0<v.size();i0++){
       nn += WriteFlexibleVector( v[i0] , table , nProcLast , nevts );
    }
@@ -200,14 +204,14 @@ int fastNLOTools::WriteFlexibleVector( const vector<T>& v, ostream& table, int n
 //________________________________________________________________________________________________________________
 // Adding functions
 template<typename T>
-void fastNLOTools::AddVectors( vector<T>& vSum, const vector<T>& vAdd, double w1, double w2 ) {
-   //! Add the values of the vector vAdd to the vector vSum
+void fastNLOTools::AddVectors( std::vector<T>& vSum, const std::vector<T>& vAdd, double w1, double w2 ) {
+   //! Add the values of the std::vector vAdd to the std::vector vSum
    //! if weights w1 and w1 are specified, the values are weighted accordingly
    //! i.e.: vSum[i] = w1*vSum[i] + w2*vAdd[i];
    if ( vSum.size() != vAdd.size() ) {
-      error["fastNLOTools::AddVectors"]
-	 <<"Cannot add tables with different size. s1="
-	 <<vSum.size()<<", s2="<<vAdd.size()<<endl;
+      say::error["fastNLOTools::AddVectors"]
+      <<"Cannot add tables with different size. s1="
+      <<vSum.size()<<", s2="<<vAdd.size()<<std::endl;
       return;
    }
    for ( unsigned int i = 0 ; i<vSum.size() ; i++ )
@@ -215,27 +219,27 @@ void fastNLOTools::AddVectors( vector<T>& vSum, const vector<T>& vAdd, double w1
 }
 
 template<typename T>
-void fastNLOTools::_DoAddVectors( vector<T>& vSum, const vector<T>& vAdd, double w1, double w2 ) {
+void fastNLOTools::_DoAddVectors( std::vector<T>& vSum, const std::vector<T>& vAdd, double w1, double w2 ) {
    //! This function infact does the addition
    if ( vSum.size() != vAdd.size() ) {
-      error["fastNLOTools::_DoAddVectors"]
-	 <<"Cannot add tables with different size. s1="
-	 <<vSum.size()<<", s2="<<vAdd.size()<<endl;
+      say::error["fastNLOTools::_DoAddVectors"]
+      <<"Cannot add tables with different size. s1="
+      <<vSum.size()<<", s2="<<vAdd.size()<<std::endl;
       return;
    }
-   if ( w1==1. && w2==1. ) 
+   if ( w1==1. && w2==1. )
       for ( unsigned int i = 0 ; i<vSum.size() ; i++ )
-	 vSum[i] += vAdd[i];
+         vSum[i] += vAdd[i];
    else
       for ( unsigned int i = 0 ; i<vSum.size() ; i++ )
-	 vSum[i] =  w1*vSum[i] + w2*vAdd[i];
+         vSum[i] =  w1*vSum[i] + w2*vAdd[i];
 }
 
 template<typename T>
-void fastNLOTools::PrintVector( const vector<T>& v, string name, string prefix){
-   cout<<" "<<prefix<<"   "<<name<<endl;
+void fastNLOTools::PrintVector( const std::vector<T>& v, std::string name, std::string prefix){
+   std::cout<<" "<<prefix<<" "<<name<<std::endl;
    for(unsigned int i=0;i<v.size();i++){
-      cout<<" "<<prefix<<"     "<<i<<"\t"<<v[i]<<endl;
+      std::cout<<" "<<prefix<<"   "<<i<<"\t"<<v[i]<<std::endl;
    }
 }
 
diff --git a/FastNLO/include/fastnlotk/speaker.h b/FastNLO/include/fastnlotk/speaker.h
index d6d5ad015859cea7196401773583dcfbfa2faf3b..8671927ddb6ec66eb84ffaf0101523da036981cc 100644
--- a/FastNLO/include/fastnlotk/speaker.h
+++ b/FastNLO/include/fastnlotk/speaker.h
@@ -9,7 +9,7 @@
 #include <map>
 
 namespace say {
-enum Verbosity {DEBUG=-1000, MANUAL=-1, INFO=0, WARNING=1, ERROR=2, SILENT=1000};
+   enum Verbosity {DEBUG=-1000, MANUAL=2, INFO=0, WARNING=1, ERROR=2, SILENT=1000};
 }
 
 class speaker {
@@ -82,13 +82,14 @@ protected:
 };
 
 namespace say {
-extern speaker debug;
-extern speaker man;
-extern speaker info;
-extern speaker warn;
-extern speaker error;
-extern speaker shout; // same as error but streamed to cout
-extern int SetGlobalVerbosity(Verbosity verbosity);
+   extern speaker debug;
+   extern speaker man;   //
+   extern speaker info;
+   extern speaker warn;
+   extern speaker error;
+   extern speaker shout; // same as error but streamed to cout
+   extern speaker yell;  // same as error but streamed to cout without prefix
+   extern int SetGlobalVerbosity(Verbosity verbosity);
 }
 
 
@@ -103,6 +104,7 @@ public:
    speaker warn;
    speaker error;
    speaker shout;
+   speaker yell;
 private:
    std::string ___cn;
 };
diff --git a/FastNLO/src/Makefile.am b/FastNLO/src/Makefile.am
index e90cbccea4f84fc767c8994b25aa8963fd2463bd..52a432dd19ecc59625dbb6cb51ff98079443392f 100644
--- a/FastNLO/src/Makefile.am
+++ b/FastNLO/src/Makefile.am
@@ -11,7 +11,7 @@ AUTOMAKE_OPTIONS = foreign
 
 # shared library for 'theory reacton interface'
 lib_LTLIBRARIES = libxffnlo.la # libxfrtfnlo.la
-libxffnlo_la_SOURCES= speaker.cc fastNLOTools.cc fastNLOBase.cc fastNLOTable.cc fastNLOCoefficients.cc fastNLOCoeffBase.cc fastNLOCoeffData.cc fastNLOCoeffMult.cc fastNLOCoeffAddBase.cc fastNLOCoeffAddFix.cc fastNLOCoeffAddFlex.cc fastNLOReader.cc fastNLOPDFLinearCombinations.cc FastNLOInterface.cc FastNLOxFitter.cc #LHAPDF.cc Alphas.cc $(libFastNLO_a_SOURCES)
+libxffnlo_la_SOURCES= speaker.cc fastNLOTools.cc fastNLOTable.cc fastNLOCoefficients.cc fastNLOCoeffBase.cc fastNLOCoeffData.cc fastNLOCoeffMult.cc fastNLOCoeffAddBase.cc fastNLOCoeffAddFix.cc fastNLOCoeffAddFlex.cc fastNLOReader.cc fastNLOPDFLinearCombinations.cc FastNLOInterface.cc FastNLOxFitter.cc #LHAPDF.cc Alphas.cc $(libFastNLO_a_SOURCES)
 libxffnlo_la_CFLAGS=
 libxffnlo_la_CPPFLAGS=
 libxffnlo_la_CXXFLAGS=-I$(srcdir)/../include -I$(srcdir)/../include/fastnlotk -I$(srcdir)/../../interfaces/include -Wall #$(AM_CXXFLAGS)
diff --git a/FastNLO/src/fastNLOBase.cc b/FastNLO/src/fastNLOBase.cc
deleted file mode 100644
index e83f5afe2f4fc0f43b85532599ac63f907011213..0000000000000000000000000000000000000000
--- a/FastNLO/src/fastNLOBase.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-#include <cstdlib>
-#include <unistd.h>
-#include <string>
-#include <fstream>
-#include <iostream>
-#include <cmath>
-#include "fastnlotk/fastNLOConstants.h"
-#include "fastnlotk/fastNLOBase.h"
-#include "fastnlotk/fastNLOTools.h"
-
-using namespace std;
-
-//______________________________________________________________________________
-bool fastNLOBase::fWelcomeOnce = false;
-
-
-//______________________________________________________________________________
-fastNLOBase::fastNLOBase() : fPrecision(8), logger("fastNLOBase") {
-   if (!fWelcomeOnce) PrintWelcomeMessage();
-}
-
-
-//______________________________________________________________________________
-fastNLOBase::fastNLOBase(string name) : ffilename(name), fPrecision(8), logger("fastNLOBase") {
-   if (!fWelcomeOnce) PrintWelcomeMessage();
-}
-
-
-//______________________________________________________________________________
-fastNLOBase::fastNLOBase(const fastNLOBase& other) :
-   ffilename(other.ffilename), fPrecision(other.fPrecision),
-   Itabversion(other.Itabversion), ScenName(other.ScenName),
-   Ncontrib(other.Ncontrib), Nmult(other.Nmult),
-   Ndata(other.Ndata), NuserString(other.NuserString),
-   NuserInt(other.NuserInt), NuserFloat(other.NuserFloat),
-   Imachine(other.Imachine),
-   logger("fastNLOBase") {
-   //! copy constructor
-}
-
-
-//______________________________________________________________________________
-fastNLOBase::~fastNLOBase() {
-}
-
-
-//______________________________________________________________________________
-ifstream* fastNLOBase::OpenFileRead() {
-   //! Open file-stream for reading table
-   // does file exist?
-   if (access(ffilename.c_str(), R_OK) != 0) {
-      logger.error["OpenFileRead"]<<"File does not exist! Was looking for: "<<ffilename<<". Exiting."<<endl;
-      exit(1);
-   }
-   ifstream* strm = new ifstream(ffilename.c_str(),ios::in);
-   return strm;
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::CloseFileRead(ifstream& strm) {
-   //! Close file-stream
-   strm.close();
-   delete &strm;
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::ReadTable() {
-   // does file exist?
-   // open file
-   ifstream* strm = OpenFileRead();
-   // read header
-   ReadHeader(*strm);
-   // close stream
-   CloseFileRead(*strm);
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::ReadHeader(istream& table) {
-   table.peek();
-   if (table.eof()) {
-      logger.error["ReadHeader"]<<"Cannot read from stream."<<endl;
-   }
-
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      logger.error["ReadHeader"]<<"Did not find initial magic number, aborting!"<<endl;
-      logger.error["ReadHeader"]<<"Please check compatibility of tables and program version!"<<endl;
-      exit(1);
-   }
-   table >> Itabversion;
-   table >> ScenName;
-   table >> Ncontrib;
-   table >> Nmult;
-   table >> Ndata;
-   table >> NuserString;
-   table >> NuserInt;
-   for (int i = 0 ; i<NuserInt ; i++) {
-      int IUserLines;
-      table >> IUserLines;
-      // future code if 'user-blocks' are used ...
-      // int NUserFlag;
-      // string NUserBlockDescr;
-      // table >> NUserFlag;
-      // table >> NUserBlockDescr;;
-      // if ( known-user-block ) { read-known-userblock... }
-      // else { // skip meaningful reading
-      //    for ( int i = 2 ; i<NuserInt ; i++ ) {
-      //       double devnull;
-      //       table >> devnull;
-      //    }
-      // }
-      // ...sofar skip reading
-      for (int i = 0 ; i<NuserInt ; i++) {
-         double devnull;
-         table >> devnull;
-      }
-   }
-   table >> NuserFloat;
-   table >> Imachine;
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      logger.error["ReadHeader"]<<"Did not find final magic number, aborting!"<<endl;
-      logger.error["ReadHeader"]<<"Please check compatibility of tables and program version!"<<endl;
-      exit(1);
-   }
-   fastNLOTools::PutBackMagicNo(table);
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::WriteTable() {
-   //!
-   //! WriteTable(). writes the full FastNLO table to
-   //! the previously defined ffilename on disk.
-   //!
-   //! this function is overwritten by
-   //! fastNLOTable::WriteTable();
-   //!
-   ofstream* table = OpenFileWrite();
-   WriteHeader(*table);
-   CloseFileWrite(*table);
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::WriteHeader(ostream& table) {
-   table << fastNLO::tablemagicno << endl;
-   table << Itabversion << endl;
-   table << ScenName << endl;
-   table << Ncontrib << endl;
-   table << Nmult << endl;
-   table << Ndata << endl;
-   table << NuserString << endl;
-   table << NuserInt << endl;
-   table << NuserFloat << endl;
-   table << Imachine << endl;
-}
-
-
-//______________________________________________________________________________
-ofstream* fastNLOBase::OpenFileWrite() {
-   //! open ofstream for writing tables
-   //! do overwrite existing table
-   if (access(ffilename.c_str(), F_OK) == 0) {
-      logger.info["OpenFileWrite"]<<"Overwriting the already existing table file: " << ffilename << endl;
-   }
-   ofstream* stream = new ofstream(ffilename.c_str(),ios::out);
-   if (!stream->good()) {
-      logger.error["OpenFileWrite"]<<"Cannot open file '"<<ffilename<<"' for writing. Aborting."<<endl;
-      exit(2);
-   }
-   stream->precision(fPrecision);
-   return stream;
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::CloseFileWrite(ofstream& table) {
-   //! close stream and delete object;
-   table << fastNLO::tablemagicno << endl;
-   table << fastNLO::tablemagicno << endl;
-   table.close();
-   delete &table;
-}
-
-
-//______________________________________________________________________________
-bool fastNLOBase::IsCompatibleHeader(const fastNLOBase& other) const {
-   if (Itabversion!= other.GetItabversion()) {
-      logger.warn["IsCompatibleHeader"]<<"Differing versions of table format: "<<Itabversion<<" and "<< other.GetItabversion()<<endl;
-      return false;
-   }
-   if (Ndata + other.GetNdata() > 1) {
-      logger.warn["IsCompatibleHeader"]<<"Two tables containing both experimental data are incompatible"<<endl;
-      return false;
-   }
-   if (ScenName!= other.GetScenName()) {
-      logger.warn["IsCompatibleHeader"]<<"Differing names of scenarios: "<<ScenName.c_str()<<" and "<<other.ScenName.c_str()<<endl;
-      // continue...
-   }
-   return true;
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::SetHeaderDefaults() {
-   // TableMagicNo and ITabVersion are defined as constant in fastNLOConstants.h
-   SetScenName("tns2000");
-   SetContributionHeader();
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::SetContributionHeader() {
-   SetNcontrib(1);
-   SetNmult(0);
-   SetNdata(0);
-   SetNuserString(0);
-   SetNuserInt(0);
-   SetNuserFloat(0);
-   SetImachine(0);
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::ResetHeader() {
-   logger.debug["ResetHeader"]<<endl;
-   SetNcontrib(0);
-   SetNmult(0);
-   SetNdata(0);
-   SetNuserString(0);
-   SetNuserInt(0);
-   SetNuserFloat(0);
-   SetImachine(0);
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::Print() const {
-   PrintHeader();
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::PrintHeader() const {
-   printf("\n **************** FastNLO Table Header ******************\n\n");
-   printf("   tablemagicno                  %d\n",fastNLO::tablemagicno);
-   printf("   Itabversion                   %d\n",Itabversion);
-   printf("   ScenName                      %s\n",ScenName.data());
-   printf("   Ncontrib                      %d\n",Ncontrib);
-   printf("   Nmult                         %d\n",Nmult);
-   printf("   Ndata                         %d\n",Ndata);
-   printf("   NuserString                   %d\n",NuserString);
-   printf("   NuserInt                      %d\n",NuserInt);
-   printf("   NuserFloat                    %d\n",NuserFloat);
-   printf("   Imachine                      %d\n",Imachine);
-   printf("\n ********************************************************\n\n");
-}
-
-
-//______________________________________________________________________________
-void fastNLOBase::PrintWelcomeMessage() {
-
-   char fnlo[100];
-   sprintf(fnlo,"%c[%d;%dmfast%c[%d;%dmNLO\033[0m",27,0,31,27,0,34);
-   char subproject[100]      = FNLO_SUBPROJECT;
-   char package_version[100] = FNLO_VERSION;
-   char svnrev[100]          = FNLO_SVNREV;
-   char authors[500]         = FNLO_AUTHORS;
-   char webpage[500]         = FNLO_WEBPAGE;
-   char authorsv14[200]      = FNLO_AUTHORSv14;
-   char quotev14[200]        = FNLO_QUOTEv14;
-   char authorsv2[200]       = FNLO_AUTHORSv2;
-   char quotev2[200]         = FNLO_QUOTEv2;
-   char years[100]           = FNLO_YEARS;
-
-   cout  << endl;
-   cout  << fastNLO::_CSEPSC << endl;
-   speaker &shout = logger.shout;
-   shout << "" << endl;
-   shout << fnlo << "_" << subproject << endl;
-   shout << "Version " << package_version << "_" << svnrev << endl;
-   shout << "" << endl;
-   shout << "C++ program and toolkit to read and create fastNLO v2 tables and" << endl;
-   shout << "derive QCD cross sections using PDFs, e.g. from LHAPDF" << endl;
-   shout << "" << endl;
-   cout  << fastNLO::_SSEPSC << endl;
-   shout << "" << endl;
-   shout << "Copyright © " << years << " " << fnlo << " Collaboration" << endl;
-   shout << authors << endl;
-   shout << "" << endl;
-   shout << "This program is free software: you can redistribute it and/or modify" << endl;
-   shout << "it under the terms of the GNU General Public License as published by" << endl;
-   shout << "the Free Software Foundation, either version 3 of the License, or" << endl;
-   shout << "(at your option) any later version." << endl;
-   shout << "" << endl;
-   shout << "This program is distributed in the hope that it will be useful," << endl;
-   shout << "but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl;
-   shout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << endl;
-   shout << "GNU General Public License for more details." << endl;
-   shout << "" << endl;
-   shout << "You should have received a copy of the GNU General Public License" << endl;
-   shout << "along with this program. If not, see <http://www.gnu.org/licenses/>." << endl;
-   shout << "" << endl;
-   cout  << fastNLO::_SSEPSC << endl;
-   shout << "" << endl;
-   shout << "The projects web page can be found at:" << endl;
-   shout << "  " << webpage << endl;
-   shout << "" << endl;
-   shout << "If you use this code, please cite:" << endl;
-   shout << "  " << authorsv14 << ", " << quotev14 << endl;
-   shout << "  " << authorsv2 << ", " << quotev2 << endl;
-   shout << "" << endl;
-   cout  << fastNLO::_CSEPSC << endl;
-   fWelcomeOnce = true;
-}
diff --git a/FastNLO/src/fastNLOCoeffAddBase.cc b/FastNLO/src/fastNLOCoeffAddBase.cc
index ad180e768f1b693625770a3dd6021e772055d1f5..8aac5393af22ff4ec3ff443ad7b638cd059e0c8d 100644
--- a/FastNLO/src/fastNLOCoeffAddBase.cc
+++ b/FastNLO/src/fastNLOCoeffAddBase.cc
@@ -8,6 +8,21 @@
 using namespace std;
 using namespace fastNLO;
 
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffAddBase::fastNLOCoeffAddBase(int NObsBin)
+   : fastNLOCoeffBase(NObsBin), IRef(), IScaleDep(), Nevt(), Npow(), NPDFPDG(),
+     NPDFDim(), NFFPDG(), NFFDim(), NSubproc(), IPDFdef1(), IPDFdef2(), IPDFdef3(),
+     fPDFCoeff(), Hxlim1(), XNode1(), Hxlim2(), XNode2(), Nztot(), Hzlim(), ZNode(),
+     NScales(), NScaleDim(), Iscale(), ScaleDescript() {
+
+}
+
+
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffAddBase::fastNLOCoeffAddBase(const fastNLOCoeffBase& base ) : fastNLOCoeffBase(base) {
+}
+
+
 //________________________________________________________________________________________________________________ //
 bool fastNLOCoeffAddBase::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet) {
    if ( c->GetIAddMultFlag()==0 && c->GetIDataFlag()==0 ) {
@@ -29,27 +44,10 @@ bool fastNLOCoeffAddBase::CheckCoeffConstants(const fastNLOCoeffBase* c, bool qu
    }
 }
 
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffAddBase::fastNLOCoeffAddBase(){
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffAddBase::fastNLOCoeffAddBase(int NObsBin) : fastNLOCoeffBase(NObsBin) {
-   NScaleDep = 0;
-}
-
-
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffAddBase::fastNLOCoeffAddBase(const fastNLOCoeffBase& base ) : fastNLOCoeffBase(base) {
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffBase* fastNLOCoeffAddBase::Clone() const {
+fastNLOCoeffAddBase* fastNLOCoeffAddBase::Clone() const {
    //! Use has to take care to delete this object later
-   return static_cast<fastNLOCoeffBase*>(new fastNLOCoeffAddBase(*this));
+   return new fastNLOCoeffAddBase(*this);
 }
 
 
@@ -66,9 +64,41 @@ void fastNLOCoeffAddBase::Read(istream& table){
 void fastNLOCoeffAddBase::ReadCoeffAddBase(istream& table){
    CheckCoeffConstants(this);
    char buffer[5257];
+   string stest;
+   if ( fVersionRead>=24000 ) table >> stest; //"fastNLO_CoeffAddBase"
+   if ( fVersionRead>=24000 ) fastNLOTools::ReadUnused(table);
    table >> IRef;
    table >> IScaleDep;
-   table >> Nevt;
+   if ( fVersionRead >= 24000 ) {
+      table >> Nevt;
+      table >> fWgt.WgtNevt;
+      table >> fWgt.NumTable;
+      table >> fWgt.WgtNumEv;
+      table >> fWgt.WgtSumW2;
+      table >> fWgt.SigSumW2;
+      table >> fWgt.SigSum;
+      fastNLOTools::ReadFlexibleVector ( fWgt.WgtObsSumW2, table );
+      fastNLOTools::ReadFlexibleVector ( fWgt.SigObsSumW2, table );
+      fastNLOTools::ReadFlexibleVector ( fWgt.SigObsSum, table );
+      fastNLOTools::ReadFlexibleVector ( fWgt.WgtObsNumEv, table );
+   }
+   else {
+      table >> Nevt;
+      double readNevt = Nevt;
+      if ( Nevt <= 0 ) { // v2300
+         table >> Nevt;
+         table >> fWgt.WgtNevt;
+         if ( readNevt<=-2 ) table >> fWgt.NumTable;
+         table >> fWgt.WgtNumEv;
+         table >> fWgt.WgtSumW2;
+         table >> fWgt.SigSumW2;
+         table >> fWgt.SigSum;
+         fastNLOTools::ReadFlexibleVector ( fWgt.WgtObsSumW2, table );
+         fastNLOTools::ReadFlexibleVector ( fWgt.SigObsSumW2, table );
+         fastNLOTools::ReadFlexibleVector ( fWgt.SigObsSum, table );
+         fastNLOTools::ReadFlexibleVector ( fWgt.WgtObsNumEv, table );
+      }
+   }
    table >> Npow;
    int NPDF;
    table >> NPDF;
@@ -92,7 +122,9 @@ void fastNLOCoeffAddBase::ReadCoeffAddBase(istream& table){
    table >> IPDFdef1;
    table >> IPDFdef2;
    table >> IPDFdef3;
-   //printf("  *  fastNLOCoeffAddBase::Read(). IRef : %d, IScaleDep: %d, Nevt: %d, Npow: %d, NPDF: %d, NPDFDim: %d\n", IRef ,IScaleDep  ,Nevt  , Npow ,NPDF , NPDFDim  );
+
+   sub_enabled.clear();
+   sub_enabled.resize(NSubproc, true); // enable all subprocesses by default
 
    if(IPDFdef2==0){ // PDF linear combinations are stored herewith
       if ( IPDFdef3 != NSubproc ){
@@ -112,7 +144,7 @@ void fastNLOCoeffAddBase::ReadCoeffAddBase(istream& table){
                   table >> PDF1Flavor;
                   table >> PDF2Flavor;
                }
-               else if ( IPDFdef1>=3 ) {
+               else if ( IPDFdef1==2 ) {
                   table >> PDF1Flavor;
                   PDF2Flavor = PDF1Flavor;
                }
@@ -132,7 +164,7 @@ void fastNLOCoeffAddBase::ReadCoeffAddBase(istream& table){
          }else{
             if(NPDF==2){
             }
-         }
+        }
       }
    }
    //Nxtot1.resize(fNObsBins);
@@ -188,55 +220,92 @@ void fastNLOCoeffAddBase::ReadCoeffAddBase(istream& table){
       for(int j=0;j<NscaleDescript;j++){
          table.getline(buffer,256);
          ScaleDescript[i][j] = buffer;
-         //            StripWhitespace(ScaleDescript[i][j]);
+      //            StripWhitespace(ScaleDescript[i][j]);
       }
    }
+
+   if ( fVersionRead>=24000 ) fastNLOTools::ReadUnused(table);
+   if ( fVersionRead>=24000 ) fastNLOTools::ReadUnused(table);
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddBase::Write(ostream& table) {
+void fastNLOCoeffAddBase::Write(ostream& table, int itabversion) {
    debug["Write"]<<"Calling fastNLOCoeffBase::Write()"<<endl;
-   fastNLOCoeffBase::Write(table);
+   fastNLOCoeffBase::Write(table,itabversion);
    CheckCoeffConstants(this);
-   table << IRef << endl;
-   table << IScaleDep << endl;
-   table << Nevt << endl;
-   table << Npow << endl;
-   table << NPDFPDG.size() << endl;
+   if ( itabversion >= 24000 ) table << "fastNLO_CoeffAddBase" << sep;
+   if ( itabversion >= 24000 ) table << 0 << sep; // v2.4, but yet unused
+   table << IRef << sep;
+   table << IScaleDep << sep;
+   // table << Nevt << sep;
+   if ( itabversion==23000 || itabversion==23500 || itabversion==23600 ) { // detailed storage of weights
+      if ( itabversion==23000 || itabversion==23500 ) table << -1 << sep; // -1: read the values below
+      else table << -2 << sep; // -1: read the values below
+      table << Nevt << sep;
+      table << fWgt.WgtNevt << sep;
+      if ( itabversion >= 23600 ) table << fWgt.NumTable << sep;
+      table << fWgt.WgtNumEv << sep;
+      table << fWgt.WgtSumW2 << sep;
+      table << fWgt.SigSumW2 << sep;
+      table << fWgt.SigSum << sep;
+      fastNLOTools::WriteFlexibleVector ( fWgt.WgtObsSumW2, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.SigObsSumW2, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.SigObsSum, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.WgtObsNumEv, table );
+   }
+   else if ( itabversion>=24000 ) { // detailed storage of weights
+      table << Nevt << sep;
+      table << fWgt.WgtNevt << sep;
+      table << fWgt.NumTable << sep;
+      table << fWgt.WgtNumEv << sep;
+      table << fWgt.WgtSumW2 << sep;
+      table << fWgt.SigSumW2 << sep;
+      table << fWgt.SigSum << sep;
+      fastNLOTools::WriteFlexibleVector ( fWgt.WgtObsSumW2, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.SigObsSumW2, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.SigObsSum, table );
+      fastNLOTools::WriteFlexibleVector ( fWgt.WgtObsNumEv, table );
+   }
+   else {
+      table << Nevt << sep;
+   }
+   table << Npow << sep;
+   table << NPDFPDG.size() << sep;
    for(unsigned int i=0;i<NPDFPDG.size();i++){
-      table <<  NPDFPDG[i] << endl;
+      table <<  NPDFPDG[i] << sep;
    }
-   table << NPDFDim << endl;
+   table << NPDFDim << sep;
    int NFragFunc = NFFPDG.size();
-   table << NFragFunc << endl;
+   table << NFragFunc << sep;
    if(NFragFunc>0){
       for(int i=0;i<NFragFunc;i++){
-         table <<  NFFPDG[i] << endl;
+         table <<  NFFPDG[i] << sep;
       }
    }
-   table << NFFDim << endl;
-   table << NSubproc << endl;
-   table << IPDFdef1 << endl;
-   table << IPDFdef2 << endl;
-   table << IPDFdef3 << endl;
+   table << NFFDim << sep;
+   table << NSubproc << sep;
+   table << IPDFdef1 << sep;
+   table << IPDFdef2 << sep;
+   table << IPDFdef3 << sep;
 
    if(IPDFdef2==0){ // PDF linear combinations are stored herewith
+      cout<<"Writing PDF coefficients into table."<<endl;
       if ( IPDFdef3 != NSubproc ){
          error["Write"]<<"IPDFdef3 must be equal to NSubproc. (IPDFdef3="<<IPDFdef3<<", NSubproc="<<NSubproc<<"). Exiting."<<endl;
          exit(1);
       }
       int IPDFCoeffFormat = 0 ; // this is format style 0
-      table <<  IPDFCoeffFormat << endl;
+      table <<  IPDFCoeffFormat << sep;
       for(int k=0;k<NSubproc;k++){
-         table << fPDFCoeff[k].size() <<endl; // NPartonParis
+         table << fPDFCoeff[k].size() <<sep; // NPartonParis
          for( unsigned int n=0;n<fPDFCoeff[k].size();n++){
             if ( IPDFdef1>=3 ) {
-               table << fPDFCoeff[k][n].first << endl;
-               table << fPDFCoeff[k][n].second << endl;
+               table << fPDFCoeff[k][n].first << sep;
+               table << fPDFCoeff[k][n].second << sep;
             }
-            else if ( IPDFdef1>=3 ) {
-               table << fPDFCoeff[k][n].first << endl;
+            else if ( IPDFdef1==2 ) {
+               table << fPDFCoeff[k][n].first << sep;
             }
          }
       }
@@ -253,47 +322,116 @@ void fastNLOCoeffAddBase::Write(ostream& table) {
       }
    }
    for(int i=0;i<fNObsBins;i++){
-      table << XNode1[i].size() << endl;
+      table << XNode1[i].size() << sep;
       for(unsigned int j=0;j<XNode1[i].size();j++){
-         table << XNode1[i][j] << endl;
+         table << XNode1[i][j] << sep;
       }
    }
    if(NPDFDim==2){
       for(int i=0;i<fNObsBins;i++){
-         table << XNode2[i].size() << endl;
+         table << XNode2[i].size() << sep;
          for(unsigned int j=0;j<XNode2[i].size();j++){
-            table << XNode2[i][j] << endl;
+            table << XNode2[i][j] << sep;
          }
       }
    }
    if(NFragFunc>0){
       for(int i=0;i<fNObsBins;i++){
-         table << Nztot[i] << endl;
+         table << Nztot[i] << sep;
          for(int j=0;j<Nztot[i];j++){
-            table << ZNode[i][j] << endl;
+            table << ZNode[i][j] << sep;
          }
       }
    }
    int NScales = Iscale.size();
-   table << NScales << endl;
-   table << NScaleDim << endl;
+   table << NScales << sep;
+   table << NScaleDim << sep;
    for(int i=0;i<NScales;i++){
-      table << Iscale[i] << endl;
+      table << Iscale[i] << sep;
    }
    for(int i=0;i<NScaleDim;i++){
-      table << ScaleDescript[i].size() << endl;
+      table << ScaleDescript[i].size() << sep;
       for(unsigned int j=0;j<ScaleDescript[i].size();j++){
-         table << ScaleDescript[i][j] << endl;
+         table << ScaleDescript[i][j] << sep;
       }
    }
+   if ( itabversion>=24000 ) table << 0 << sep; // v2.4, but yet unused
+   if ( itabversion>=24000 ) table << 0 << sep; // v2.4, but yet unused
+
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddBase::Add(const fastNLOCoeffAddBase& other){
+void fastNLOCoeffAddBase::Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption){
    //    double w1 = (double)Nevt / (Nevt+other.Nevt);
    //    double w2 = (double)other.Nevt / (Nevt+other.Nevt);
-   Nevt += other.Nevt;
+   if ( Nevt==1 || other.GetNevt()==1 ) {
+      if ( moption != fastNLO::kAdd && moption != fastNLO::kUnweighted && moption != fastNLO::kAttach ) {
+         error["Add"]<<"Table has weight 1, which is invalid for mergeing purposes."<<endl;
+         error["Add"]<<"Possibly, the table is a result from a previous 'append' or 'unweighted' mergeing."<<endl;
+         exit(4);
+      }
+   }
+
+
+   if ( moption==fastNLO::kAttach ) {
+      //Nevt = Nevt;// stays!
+      fWgt.WgtNevt  = 1;
+      fWgt.NumTable += other.fWgt.NumTable;
+      fWgt.WgtNumEv += other.fWgt.WgtNumEv;
+      fWgt.WgtSumW2 += other.fWgt.WgtSumW2;
+      fWgt.SigSumW2 += other.fWgt.SigSumW2;
+      fWgt.SigSum   += other.fWgt.SigSum;
+      for ( unsigned int iAddProc = 0 ; iAddProc<other.fWgt.WgtObsSumW2.size() ; iAddProc++ ) {
+         fWgt.WgtObsSumW2.push_back(other.fWgt.WgtObsSumW2[iAddProc]);
+         fWgt.SigObsSumW2.push_back(other.fWgt.SigObsSumW2[iAddProc]);
+         fWgt.SigObsSum.  push_back(other.fWgt.SigObsSum[iAddProc]);
+         fWgt.WgtObsNumEv.push_back(other.fWgt.WgtObsNumEv[iAddProc]);
+      }
+      if ( other.GetPDFCoeff().size() ==0  || this->GetPDFCoeff().size()==0 ) {
+         error["Add"]<<"Mergeing option 'kAttach' requires that PDF coefficients are stored in table.!"<<endl;
+      }
+      for ( unsigned int iAddProc = 0 ; iAddProc<other.GetPDFCoeff().size() ;iAddProc++ ) {
+         fPDFCoeff.push_back(other.GetPDFCoeff()[iAddProc]);
+      }
+      NSubproc += other.GetNSubproc();
+      IPDFdef3 += other.GetIPDFdef3();
+   }
+   else {
+      Nevt += other.Nevt;
+      fWgt.WgtNevt  += other.fWgt.WgtNevt;
+      fWgt.NumTable += other.fWgt.NumTable;
+      fWgt.WgtNumEv += other.fWgt.WgtNumEv;
+      fWgt.WgtSumW2 += other.fWgt.WgtSumW2;
+      fWgt.SigSumW2 += other.fWgt.SigSumW2;
+      fWgt.SigSum   += other.fWgt.SigSum;
+      fastNLOTools::AddVectors( fWgt.WgtObsSumW2, other.fWgt.WgtObsSumW2 );
+      fastNLOTools::AddVectors( fWgt.SigObsSumW2, other.fWgt.SigObsSumW2 );
+      fastNLOTools::AddVectors( fWgt.SigObsSum,   other.fWgt.SigObsSum );
+      fastNLOTools::AddVectors( fWgt.WgtObsNumEv, other.fWgt.WgtObsNumEv );
+   }
+
+}
+
+
+//________________________________________________________________________________________________________________ //
+double fastNLOCoeffAddBase::GetMergeWeight(fastNLO::EMerge moption, int proc, int bin) const {
+
+   //!< Get a bin and subprocess dependent weight for merging puprposes.
+   if      ( moption == kMerge    )   return fWgt.WgtNevt; // Nevt
+   else if ( moption == kUnweighted ) return fWgt.NumTable;
+   else if ( moption == kAdd )     return 1;
+   else if ( moption == kNumEvent )   return double(fWgt.WgtNumEv);
+   else if ( moption == kSumW2    )   return fWgt.WgtSumW2;
+   else if ( moption == kSumSig2  )   return fWgt.SigSumW2;
+   else if ( moption == kSumUser  )   return fWgt.SigSum;
+   else if ( moption == kNumEventBinProc ) return double(fWgt.WgtObsNumEv[proc][bin]);
+   else if ( moption == kSumW2BinProc    ) return fWgt.WgtObsSumW2[proc][bin];
+   else if ( moption == kSumSig2BinProc  ) return fWgt.SigObsSumW2[proc][bin];
+   else if ( moption == kSumUserBinProc  ) return fWgt.SigObsSum[proc][bin];
+   error["GetMergeWeight"]<<"Weighting option not recognized: "<<moption<<endl;
+   exit(4);
+   return 0;
 }
 
 
@@ -301,72 +439,183 @@ void fastNLOCoeffAddBase::Add(const fastNLOCoeffAddBase& other){
 bool fastNLOCoeffAddBase::IsCompatible(const fastNLOCoeffAddBase& other) const {
    // chek CoeffBase variables
    if ( ! ((fastNLOCoeffBase*)this)->IsCompatible(other)) {
-      say::debug["fastNLOCoeffAddBase::IsCompatible"]<<"fastNLOCoeffBase not compatible."<<endl;
+      debug["IsCompatible"]<<"fastNLOCoeffBase not compatible."<<endl;
       return false;
    }
    if ( IRef != other.GetIRef() ) {
       //warn["IsCompatible"]<<""<<endl;
-      say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of IRef detected."<<endl;
+      warn["IsCompatible"]<<"Different number of IRef detected."<<endl;
+      return false;
+   }
+   if ( Nevt * other.Nevt < 0 ) {
+      // skip, if the two tables store the event weights in different formats
+      // If this is needed, simple solutions are thinkable
+      warn["IsCompatible"]<<"Tables use different format for normalisation."<<endl;
       return false;
    }
    if ( IScaleDep != other.GetIScaleDep() ) {
-      say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of IScaleDep detected."<<endl;
+      warn["IsCompatible"]<<"Different number of IScaleDep detected."<<endl;
       return false;
    }
    if ( Npow != other.GetNpow() ) {
-      say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of NPow detected."<<endl;
-      //warn["IsCompatible"]<<""<<endl;
+      warn["IsCompatible"]<<"Different number of NPow detected."<<endl;
       return false;
    }
    if ( GetNPDF() != other.GetNPDF() ) {
-      say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of NPDF detected."<<endl;
-      //warn["IsCompatible"]<<""<<endl;
+      warn["IsCompatible"]<<"Different number of NPDF detected."<<endl;
       return false;
    }
    if ( NSubproc != other.GetNSubproc() ) {
-      say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different numbers for NSubproc detected."<<endl;
-      //warn["IsCompatible"]<<""<<endl;
-      return false;
+      warn["IsCompatible"]<<"Different numbers for NSubproc detected."<<endl;
+      //return false;
+      warn["IsCompatible"]<<"Continuing! (experimental: This is needed for kAttach, but may causes bugs otherwise. Please report!)"<<endl;
    }
    // check x-nodes briefly
    if ( fNObsBins != other.GetNObsBin() ){
-      say::warn["IsCompatible"]<<"Different number of bins detected."<<endl;
+      warn["IsCompatible"]<<"Different number of bins detected."<<endl;
       return false;
    }
    // check x-nodes briefly
    for ( int i = 0 ; i< fNObsBins ;i++ ){
       if ( GetNxmax(i) != other.GetNxmax(i) ){
-	 say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of x-nodes detected."<<endl;
-	 return false;
+         error["IsCompatible"]<<"Different number of x-nodes detected: "<<GetNxmax(i)<<" <-> "<<other.GetNxmax(i)<<endl;
+         return false;
       }
       if ( GetNxtot1(i) != other.GetNxtot1(i) ){
-	 say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different number of x-nodes detected."<<endl;
-	 return false;
+         error["IsCompatible"]<<"Different number of x-nodes detected: "<<GetNxtot1(i)<<" <-> "<<other.GetNxtot1(i)<<endl;
+         return false;
       }
       if ( GetXNode1(i,0) != other.GetXNode1(i,0) ){
-	 say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different values for x-nodes detected."<<endl;
-	 return false;
-      }
-      if ( GetXNode1(i,1) != other.GetXNode1(i,1) ){
-	 say::warn["fastNLOCoeffAddBase::IsCompatible"]<<"Different values for x-nodes detected."<<endl;
-	 return false;
+         warn["IsCompatible"]<<"Different values for x-nodes detected. Lowest x-node: "<<GetXNode1(i,0)<<" <-> "<<other.GetXNode1(i,0)<<endl;
+         return false;
       }
+      // if ( GetXNode1(i,1) != other.GetXNode1(i,1) ){
+      //    warn["IsCompatible"]<<"Different values for x-nodes detected."<<endl;
+      //    return false;
+      // }
    }
    // succesful!
    return true;
 }
 
 
+//________________________________________________________________________________________________________________ //
+bool fastNLOCoeffAddBase::IsCatenable(const fastNLOCoeffAddBase& other) const {
+   // check CoeffBase variables
+   if ( ! ((fastNLOCoeffBase*)this)->IsCatenable(other)) {
+      debug["IsCatenable"]<<"fastNLOCoeffBase not compatible. Skipped."<<endl;
+      return false;
+   }
+   if ( Nevt * other.Nevt < 0 ) {
+      // skip, if the two tables store the event weights in different formats
+      // If this is needed, simple solutions are thinkable
+      debug["IsCatenable"]<<"Tables use different format for table normalisation. Skipped."<<endl;
+      return false;
+   }
+   if ( IRef != other.GetIRef() ) {
+      debug["IsCatenable"]<<"Different number of IRef detected. Skipped."<<endl;
+      return false;
+   }
+   if ( IScaleDep != other.GetIScaleDep() ) {
+      debug["IsCatenable"]<<"Different number of IScaleDep detected. Skipped."<<endl;
+      return false;
+   }
+   if ( Npow != other.GetNpow() ) {
+      debug["IsCatenable"]<<"Different number of NPow detected. Skipped."<<endl;
+      return false;
+   }
+   if ( GetNPDF() != other.GetNPDF() ) {
+      debug["IsCatenable"]<<"Different number of NPDF detected. Skipped."<<endl;
+      return false;
+   }
+   if ( NSubproc != other.GetNSubproc() ) {
+      debug["IsCatenable"]<<"Different numbers for NSubproc detected. Skipped."<<endl;
+      return false;
+   }
+   // check x-nodes briefly
+   // for ( int i = 0 ; i< fNObsBins ;i++ ){
+   //    if ( GetNxmax(i) != other.GetNxmax(i) ){
+   //       debug["IsCatenable"]<<"Different number of x-nodes detected."<<endl;
+   //       return false;
+   //    }
+   //    if ( GetNxtot1(i) != other.GetNxtot1(i) ){
+   //       debug["IsCatenable"]<<"Different number of x-nodes detected."<<endl;
+   //       return false;
+   //    }
+   //    if ( GetXNode1(i,0) != other.GetXNode1(i,0) ){
+   //       debug["IsCatenable"]<<"Different values for x-nodes detected."<<endl;
+   //       return false;
+   //    }
+   //    if ( GetXNode1(i,1) != other.GetXNode1(i,1) ){
+   //       debug["IsCatenable"]<<"Different values for x-nodes detected."<<endl;
+   //       return false;
+   //    }
+   // }
+   info["IsCatenable"]<<"Base parameters of additive contribution allow catenation"<<endl;
+   return true;
+}
+
+//________________________________________________________________________________________________________________
+bool fastNLOCoeffAddBase::SubSelect( vector< pair<int,int> > processes, bool on ) {
+   vector<int> s;
+   s.clear();
+   for ( unsigned int k=0; k<processes.size(); k++ ) {
+      pair<int,int> p = processes[k];
+      // search for selected process in fPDFCoeff
+      bool fff = false;
+      for ( unsigned int i = 0; i<fPDFCoeff.size(); i++ ) {
+         for ( unsigned int j = 0; j<fPDFCoeff[i].size(); j++ ) {
+	    if ( p == fPDFCoeff[i][j] ) {
+	       // found! now check if the other proesses in this subcontribution are also to be selected
+	       vector< pair<int,int> > p_list = fPDFCoeff[i];
+	       bool f = true;
+	       for ( unsigned int n = 0; n<p_list.size(); n++ ) {
+		  bool ff = false;
+		  for ( unsigned int m = 0; m<processes.size(); m++ )
+		     if ( p_list[n] == processes[m] )
+			ff = true;
+	       	  f &= ff;
+	       }	       
+	       if (!f)
+		  return false;
+	       s.push_back(i);
+	       fff = true;
+	    }
+	 }
+      }
+      if (!fff)
+	 return false;
+   }
+   // now activate the selected subcontributions and return succes (true)
+   for ( unsigned int k = 0; k<s.size(); k++ )
+      SubEnable(s[k], on);
+
+   return true;
+}
+	          
+
+
 //________________________________________________________________________________________________________________ //
 void fastNLOCoeffAddBase::Clear() {
    //! Clear all coefficients and event counts
    Nevt = 0;
+   fWgt.WgtNevt = 0;
+   fWgt.NumTable = 1;
+   fWgt.WgtNumEv = 0;
+   fWgt.WgtSumW2 = 0;
+   fWgt.SigSumW2 = 0;
+   fWgt.SigSum   = 0;
+   fastNLOTools::ClearVector(fWgt.WgtObsSumW2);
+   fastNLOTools::ClearVector(fWgt.SigObsSumW2);
+   fastNLOTools::ClearVector(fWgt.SigObsSum);
+   fastNLOTools::ClearVector(fWgt.WgtObsNumEv);
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddBase::NormalizeCoefficients() {
-   Nevt = 1;
+void fastNLOCoeffAddBase::NormalizeCoefficients(double wgt) {
+   Nevt = wgt;
+   // Don't touch other weights.
 }
 
 
@@ -404,54 +653,164 @@ int fastNLOCoeffAddBase::GetXIndex(int Obsbin,int x1bin,int x2bin) const {
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddBase::Print() const {
-   fastNLOCoeffBase::Print();
-   printf(" **************** FastNLO Table: fastNLOCoeffAddBase ****************\n");
-   printf(" B   IRef                          %d\n",IRef);
-   printf(" B   NScaleDep                     %d\n",NScaleDep);
-   printf(" B   IScaleDep                     %d\n",IScaleDep);
-   printf(" B   Nevt                          %f\n",Nevt);
-   printf(" B   Npow                          %d\n",Npow);
-   printf(" B   NPDF                          %lu\n",NPDFPDG.size());
-   for(unsigned int i=0;i<NPDFPDG.size();i++){
-      printf(" B    - NPDFPDG[%d]                 %d\n",i,NPDFPDG[i]);
-   }
-   printf(" B   NPDFDim                       %d\n",NPDFDim);
-   printf(" B   NFragFunc                     %lu\n",NFFPDG.size());
-   for(unsigned int i=0;i<NFFPDG.size();i++){
-      printf(" B    - NFFPDG[%d]               %d\n",i,NFFPDG[i]);
-   }
-   printf(" B   NFFDim                        %d\n",NFFDim);
-   printf(" B   NSubproc                      %d\n",NSubproc);
-   printf(" B   IPDFdef1                      %d\n",IPDFdef1);
-   printf(" B   IPDFdef2                      %d\n",IPDFdef2);
-   printf(" B   IPDFdef3                      %d\n",IPDFdef3);
-   printf(" B   Nxtot1[0-%d]             ",fNObsBins);
-   for(int i=0;i<fNObsBins;i++){
-      printf("%lu ,",XNode1[i].size());
-   }
-   printf("\n");
-   //     for(int i=0;i<fNObsBins;i++){
-   //       printf(" B    XNode1[%d]             ",i);
-   //       for(int j=0;j<Nxtot1[i];j++){
-   //   printf(" B   %8.4f ,",XNode1[i][j]);
-   //       }
-   //       printf(" B   \n");
-   //     }
-   printf(" B   if (NPDFDim==2), you could print xnodes2 here. (NPDFDim = %d)\n",NPDFDim);
-   printf(" B   if (NFragFunc>0), you could print xnodes2 here. (NFragFunc = %lu)\n",NFFPDG.size());
-   printf(" B   NScales                       %lu\n",Iscale.size());
-   for(unsigned int i=0;i<Iscale.size();i++){
-      printf(" B    - Iscale[%d]                  %d\n",i,Iscale[i]);
-   }
-   printf(" B   NScaleDim                     %d\n",NScaleDim);
+double fastNLOCoeffAddBase::GetX1(int iObsBin, int iXnode) const {
+   // return x-value of PDF1 at node iXnode
+   switch (NPDFDim) {
+   case 0:
+      return GetXNode1(iObsBin,iXnode);
+   case 1:
+      //
+      // cout<<"GetX1 not implemented for half-matrix notation!"<<endl;
+      //
+      return 1;
+   case 2:
+      return GetXNode1(iObsBin, iXnode % GetNxtot1(iObsBin) );
+   default: return 1;
+   }
+   return 1;
+}
+
+//________________________________________________________________________________________________________________ //
+double fastNLOCoeffAddBase::GetX2(int iObsBin, int iXnode) const {
+   // return x-value of PDF1 at node iXnode
+   switch (NPDFDim) {
+   case 0:
+      return 1;
+   case 1:
+      //
+      //cout<<"GetX2 not implemented for half-matrix notation!"<<endl;
+      //
+      return 1;
+   case 2:
+      return GetXNode2(iObsBin, iXnode / GetNxtot1(iObsBin) );
+   default: return 1;
+   }
+   return 1;
+}
+
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddBase::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      fastNLOCoeffBase::Print(iprint);
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffAddBase " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffAddBase " << fastNLO::_CSEP20 << endl;
+   }
+   printf(" # No. of events (Nevt)                %f\n",Nevt);
+   if ( fWgt.WgtNevt!= 0 || fWgt.WgtSumW2!= 0 ) {
+      printf(" # Weight of table [=Nevt] (fWgtNevt)  %f\n",fWgt.WgtNevt);
+      printf(" # Number of tables merged together    %d\n",fWgt.NumTable);
+      printf(" # No. of filled events (WgtNumEv)     %llu\n",fWgt.WgtNumEv);
+      printf(" # Sum of weights squared (WgtSumW2)   %f\n",fWgt.WgtSumW2);
+      printf(" # Sum of sigma squared (SigSumW2)     %f\n",fWgt.SigSumW2);
+      printf(" # Sum of sigma (SigSum)               %f\n",fWgt.SigSum);
+      printf(" # Sigma / Nevt (SigSum/WgtNevt)       %f\n",fWgt.SigSum/fWgt.WgtNevt);
+   }
+
+   printf(" # Abs. order in a_s (Npow)            %d\n",Npow);
+   printf(" # No. of hadrons involved (NPDF)      %lu\n",NPDFPDG.size());
+   fastNLOTools::PrintVector(NPDFPDG,"Type(s) of hadrons (NPDFPDG)","#");
+
+   printf(" # PDF storage format (NPDFDim)        %d\n",NPDFDim);
+   if ( NPDFDim == 0 ) {
+      printf(" #   --> x-interpolation storage format: Linear\n");
+   } else if ( NPDFDim == 1 ) {
+      printf(" #   --> x-interpolation storage format: Half-Matrix\n");
+   } else if ( NPDFDim == 2 ) {
+      printf(" #   --> x-interpolation storage format: Full-Matrix\n");
+   } else {
+      error["Print"] << "Unknown interpolation storage structure, aborting! "
+                                          << " NPDFDim = " << NPDFDim << endl;
+   }
+
+   for (int i=0; i<fNObsBins; i++) {
+      // Print only for first and last observable bin
+      if (i==0 || i==fNObsBins-1) {
+         printf(" # Observable bin no. %d\n",i+1);
+         printf(" #   No. of X1 nodes (XNode1[i].size())          %d\n",(int)GetXNodes1(i).size());
+      }
+   }
+   printf(" # No. of scales involved (NScales)    %lu\n",Iscale.size());
    for(int i=0;i<NScaleDim;i++){
-      for(unsigned int j=0;j<ScaleDescript[i].size();j++){
-         printf(" B    -  - ScaleDescript[%d][%d]     %s\n",i,j,ScaleDescript[i][j].data());
+      fastNLOTools::PrintVector(ScaleDescript[i],"Scale descriptions (ScaleDescript)","#");
+   }
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      if ( NScales > 0 ) {fastNLOTools::PrintVector(Iscale,"Iscale (Unused, always 0) (Iscale)","#  ");}
+      printf(" #   IRef                              %d\n",IRef);
+      printf(" #   IScaleDep (Unused, always 0)      %d\n",IScaleDep);
+      printf(" #   NFragFunc                         %lu\n",NFFPDG.size());
+      if ( NFFPDG.size() > 0 ) {fastNLOTools::PrintVector(NFFPDG,"Type(s) of hadrons (NFFPDG)","#");}
+      printf(" #   NFFDim                            %d\n",NFFDim);
+      printf(" #   NScaleDim                         %d\n",NScaleDim);
+      printf(" #   NSubproc                          %d\n",NSubproc);
+      printf(" #   IPDFdef1                          %d\n",IPDFdef1);
+      printf(" #   IPDFdef2                          %d\n",IPDFdef2);
+      printf(" #   IPDFdef3                          %d\n",IPDFdef3);
+      char buffer[1024];
+      for (int i=0; i<fNObsBins; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==fNObsBins-1) {
+            printf(" #   Observable bin no. %d\n",i+1);
+            snprintf(buffer, sizeof(buffer), "X1 nodes (XNode1[%d][])",i);
+            fastNLOTools::PrintVector(GetXNodes1(i),buffer,"#    ");
+            if ( NPDFDim == 2 ) {
+               snprintf(buffer, sizeof(buffer), "X2 nodes (XNode2[%d][])",i);
+               fastNLOTools::PrintVector(GetXNodes2(i),buffer,"#    ");
+            }
+         }
       }
    }
-   printf(" *******************************************************\n");
+   if ( iprint < 0 ) {
+      cout << fastNLO::_CSEPSC << endl;
+   } else {
+      //      cout << fastNLO::_DSEPSC << endl;
+   }
 }
 
 
 //________________________________________________________________________________________________________________ //
+
+// Erase observable bin
+void fastNLOCoeffAddBase::EraseBin(unsigned int iObsIdx) {
+   debug["EraseBin"]<<"Erasing table entries in CoeffAddBase for bin index " << iObsIdx << endl;
+   if ( XNode1.size() == 0 ) {
+      error["EraseBin"]<<"All additive contribution bins deleted already. Aborted!" << endl;
+      exit(1);
+   }
+   if ( XNode1.size() != 0 ) XNode1.erase(XNode1.begin()+iObsIdx);
+   if ( NPDFDim==2 && XNode2.size() != 0 ) XNode2.erase(XNode2.begin()+iObsIdx);
+   for ( unsigned int ip = 0 ; ip<fWgt.WgtObsSumW2.size() ; ip++ ) {
+      fWgt.WgtObsSumW2[ip].erase(fWgt.WgtObsSumW2[ip].begin()+iObsIdx);
+      fWgt.SigObsSumW2[ip].erase(fWgt.SigObsSumW2[ip].begin()+iObsIdx);
+      fWgt.SigObsSum[ip].  erase(fWgt.SigObsSum  [ip].begin()+iObsIdx);
+      fWgt.WgtObsNumEv[ip].erase(fWgt.WgtObsNumEv[ip].begin()+iObsIdx);
+   }
+   fastNLOCoeffBase::EraseBin(iObsIdx);
+}
+
+// Catenate observable bin
+void fastNLOCoeffAddBase::CatBin(const fastNLOCoeffAddBase& other, unsigned int iObsIdx) {
+   debug["CatBin"]<<"Catenating observable bin in CoeffAddBase corresponding to bin index " << iObsIdx << endl;
+   if ( XNode1.size() == 0 ) {
+      error["CatBin"]<<"Initial additive table is empty. Aborted!" << endl;
+      exit(1);
+   }
+   //unsigned int nold = XNode1.size();
+   if ( XNode1.size() != 0 ) {
+      XNode1.push_back(other.XNode1[iObsIdx]);
+      // XNode1.resize(nold+1);
+      // XNode1[nold] = other.XNode1[iObsIdx];
+   }
+   if ( NPDFDim==2 &&  XNode2.size() != 0 ) {
+      XNode2.push_back(other.XNode2[iObsIdx]);
+   }
+   for ( unsigned int ip = 0 ; ip<fWgt.WgtObsSumW2.size() ; ip++ ) {
+      fWgt.WgtObsSumW2[ip].push_back(other.fWgt.WgtObsSumW2[ip][iObsIdx]);
+      fWgt.SigObsSumW2[ip].push_back(other.fWgt.SigObsSumW2[ip][iObsIdx]);
+      fWgt.SigObsSum[ip].  push_back(other.fWgt.SigObsSum  [ip][iObsIdx]);
+      fWgt.WgtObsNumEv[ip].push_back(other.fWgt.WgtObsNumEv[ip][iObsIdx]);
+   }
+   fastNLOCoeffBase::CatBin(other, iObsIdx);
+}
diff --git a/FastNLO/src/fastNLOCoeffAddFix.cc b/FastNLO/src/fastNLOCoeffAddFix.cc
index 4d141d8e0af013ee4888f863dec44ce1b85e3727..169419eb5a7e698351d166b55c2830bbd71ca23c 100644
--- a/FastNLO/src/fastNLOCoeffAddFix.cc
+++ b/FastNLO/src/fastNLOCoeffAddFix.cc
@@ -2,11 +2,26 @@
 #include <iostream>
 #include <cmath>
 
-#include "fastnlotk/fastNLOTools.h"
 #include "fastnlotk/fastNLOCoeffAddFix.h"
+#include "fastnlotk/fastNLOTools.h"
 #include "fastnlotk/speaker.h"
 
 using namespace std;
+using namespace fastNLO;
+
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffAddFix::fastNLOCoeffAddFix(int NObsBin)
+   : fastNLOCoeffAddBase(NObsBin), Nscalevar(), ScaleFac(), ScaleNode(), SigmaTilde(),
+     AlphasTwoPi_v20(), PdfLc(), PdfSplLc1(), PdfSplLc2() {
+   SetClassName("fastNLOCoeffAddFix");
+}
+
+
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffAddFix::fastNLOCoeffAddFix(const fastNLOCoeffBase& base) : fastNLOCoeffAddBase(base) {
+   SetClassName("fastNLOCoeffAddFix");
+}
+
 
 
 //________________________________________________________________________________________________________________ //
@@ -25,27 +40,9 @@ bool fastNLOCoeffAddFix::CheckCoeffConstants(const fastNLOCoeffBase* c, bool qui
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFix::fastNLOCoeffAddFix(){
-   SetClassName("fastNLOCoeffAddFix");
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFix::fastNLOCoeffAddFix(int NObsBin) : fastNLOCoeffAddBase(NObsBin) {
-   SetClassName("fastNLOCoeffAddFix");
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFix::fastNLOCoeffAddFix(const fastNLOCoeffBase& base) : fastNLOCoeffAddBase(base) {
-   SetClassName("fastNLOCoeffAddFix");
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffBase* fastNLOCoeffAddFix::Clone() const {
+fastNLOCoeffAddFix* fastNLOCoeffAddFix::Clone() const {
    //! Use has to take care to delete this object later
-   return static_cast<fastNLOCoeffBase*>(new fastNLOCoeffAddFix(*this));
+   return new fastNLOCoeffAddFix(*this);
 }
 
 
@@ -68,15 +65,14 @@ void fastNLOCoeffAddFix::ReadRest(istream& table){
 //________________________________________________________________________________________________________________ //
 void fastNLOCoeffAddFix::ReadCoeffAddFix(istream& table){
    CheckCoeffConstants(this);
-
    Nscalevar.resize(NScaleDim);
    vector<int> Nscalenode(NScaleDim);
    for(int i=0;i<NScaleDim;i++){
       table >> Nscalevar[i];
       table >> Nscalenode[i];
    }
-   //    printf("  *  fastNLOCoeffAddFix::Read().bins %d, NScalevar[0] %d, Nscalenode[0] %d,  NScaleDim %d  \n",
-   //    fNObsBins, Nscalevar[0] , Nscalenode[0] , NScaleDim );
+   // printf("  *  fastNLOCoeffAddFix::Read().bins %d, NScalevar[0] %d, Nscalenode[0] %d,  NScaleDim %d  \n",
+   // 	  fNObsBins, Nscalevar[0] , Nscalenode[0] , NScaleDim );
    ScaleFac.resize(NScaleDim);
    for(int i=0;i<NScaleDim;i++){
       ScaleFac[i].resize(Nscalevar[i]);
@@ -84,9 +80,9 @@ void fastNLOCoeffAddFix::ReadCoeffAddFix(istream& table){
          table >> ScaleFac[i][j];
       }
    }
-   //printf("  *  fastNLOCoeffAddFix::Read().bins %d, NScalevar[0] %d, Nscalenode[0] %d, ScaleFac[0][0] %d,  NScaleDim %d  \n",
-   //fNObsBins, Nscalevar[0] , Nscalenode[0] , ScaleFac[0][0], NScaleDim );
-   fastNLOTools::ResizeVector( ScaleNode , fNObsBins, 1 , Nscalevar[0] , Nscalenode[0] ); // should work, since NScaleDim==1, but is not yet tested for 100%
+   // printf("  *  fastNLOCoeffAddFix::Read().bins %d, NScalevar[0] %d, Nscalenode[0] %d, ScaleFac[0][0] %d,  NScaleDim %d  \n",
+   // 	  fNObsBins, Nscalevar[0] , Nscalenode[0] , ScaleFac[0][0], NScaleDim );
+   fastNLOTools::ResizeVector( ScaleNode , fNObsBins, 1 , Nscalevar[0] , Nscalenode[0] );
    int nsn = fastNLOTools::ReadVector( ScaleNode , table );
    debug["fastNLOCoeffAddFix::Read()"]<<"Read "<<nsn<<" lines of ScaleNode."<<endl;
 
@@ -159,14 +155,14 @@ void fastNLOCoeffAddFix::ResizePdfSplLC(){
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFix::Write(ostream& table){
+void fastNLOCoeffAddFix::Write(ostream& table, int itabversion){
    //! Write coefficient table to disk (ostream)
    CheckCoeffConstants(this);
-   fastNLOCoeffAddBase::Write(table);
+   fastNLOCoeffAddBase::Write(table,itabversion);
 
    for(int i=0;i<NScaleDim;i++){
-      table << Nscalevar[i] << endl;
-      table << GetNScaleNode() << endl;
+      table << Nscalevar[i] << sep;
+      table << GetNScaleNode() << sep;
    }
    fastNLOTools::WriteVector( ScaleFac , table );
    int nsn = fastNLOTools::WriteVector( ScaleNode , table );
@@ -176,7 +172,7 @@ void fastNLOCoeffAddFix::Write(ostream& table){
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFix::Add(const fastNLOCoeffAddBase& other){
+void fastNLOCoeffAddFix::Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption){
    //! Add another coefficient table to this table
    bool ok = CheckCoeffConstants(this);
    if ( !ok ) {
@@ -184,12 +180,63 @@ void fastNLOCoeffAddFix::Add(const fastNLOCoeffAddBase& other){
       return;
    }
    const fastNLOCoeffAddFix& othfix = (const fastNLOCoeffAddFix&)other;
-   Nevt += othfix.Nevt;
-   fastNLOTools::AddVectors( SigmaTilde , othfix.SigmaTilde);
+   if ( moption==fastNLO::kMerge )  fastNLOTools::AddVectors( SigmaTilde , othfix.SigmaTilde);
+   else if ( moption==fastNLO::kAttach ) {
+      for( int i=0 ; i<fNObsBins ; i++ ){
+	 int nxmax = GetNxmax(i);
+	 for( int k=0 ; k<GetTotalScalevars() ; k++ ){
+	    for( int l=0 ; l<GetTotalScalenodes() ; l++ ){
+	       for( int m=0 ; m<nxmax ; m++ ){
+		  for( int n=0 ; n<other.GetNSubproc() ; n++ ){ // attach all other subprocesses
+		     double s2  = othfix.SigmaTilde[i][k][l][m][n];
+		     s2 *= this->Nevt/other.GetNevt();
+		     this->SigmaTilde[i][k][l][m].push_back(s2);
+		  }
+	       }
+	    }
+	 }
+      }
+   }
+   else {
+      for( int i=0 ; i<fNObsBins ; i++ ){
+	 int nxmax = GetNxmax(i);
+	 for( int k=0 ; k<GetTotalScalevars() ; k++ ){
+	    for( int l=0 ; l<GetTotalScalenodes() ; l++ ){
+	       for( int m=0 ; m<nxmax ; m++ ){
+		  for( int n=0 ; n<NSubproc ; n++ ){
+		     double w1  = this->GetMergeWeight(moption,n,i);
+		     double w2  = other.GetMergeWeight(moption,n,i);
+		     double& s1 = this->SigmaTilde[i][k][l][m][n];
+		     double s2  = othfix.SigmaTilde[i][k][l][m][n];
+		     if ( s1!=0 || s2!=0 ) {
+			if ( w1==0 || w2==0 ) {
+			   error["fastNLOCoeffAddFix"]<<"Mergeing weight is 0, but sigma tilde is non-zero. Cannot proceed!"<<endl;
+			   exit(3);
+			}
+			s1 = ( w1*s1/Nevt + w2*s2/other.GetNevt() ) / (w1 + w2 ) * ( Nevt + other.GetNevt() ) ;
+		     }
+		  }
+	       }
+	    }
+	 }
+      }
+   }
+   //Nevt += othfix.Nevt;
+   fastNLOCoeffAddBase::Add(other,moption);
+   if ( moption==fastNLO::kAdd ) {
+      NormalizeCoefficients(2);
+      Nevt = 1;
+      fWgt.WgtNevt = 1;
+   }
+   else if ( moption==fastNLO::kUnweighted ) {
+      NormalizeCoefficients(1);
+   }
+   else if ( moption==fastNLO::kAttach ) {
+      NormalizeCoefficients(1);
+   }
 }
 
 
-
 //________________________________________________________________________________________________________________ //
 int fastNLOCoeffAddFix::GetTotalScalevars() const {
    //! Get nuber of scale-variations
@@ -221,26 +268,47 @@ bool  fastNLOCoeffAddFix::IsCompatible(const fastNLOCoeffAddFix& other) const {
    //! Check for compatibility for merging/adding of two contributions
    if ( ! ((fastNLOCoeffAddBase*)this)->IsCompatible(other)) return false;
    if ( GetNScaleNode() != other.GetNScaleNode() ) {
-      say::warn["IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;                                                                                     
+      say::warn["IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;
       return false;
    }
    if ( GetNScalevar() != other.GetNScalevar() ) {
-      say::warn["IsCompatible"]<<"Incompatible number of scale variations found."<<endl;                                                                                     
+      say::warn["IsCompatible"]<<"Incompatible number of scale variations found."<<endl;
       return false;
    }
    if ( GetAvailableScaleFactors()[GetNScalevar()-1] != other.GetAvailableScaleFactors()[GetNScalevar()-1] ) {
-      say::warn["IsCompatible"]<<"Incompatible scale variations found."<<endl;                                                                                     
+      say::warn["IsCompatible"]<<"Incompatible scale variations found."<<endl;
       return false;
    }
    for ( int i=0 ; i<fNObsBins ; i++ ){
       for ( int is=0 ; is<GetNScaleNode() ; is++ ){
-	 if ( GetScaleNode(i,0,is) != other.GetScaleNode(i,0,is) ) {
-	    say::warn["IsCompatible"]<<"Incompatible scale node found."<<endl;                                                                                     
-	    return false;
-	 }
+         if ( GetScaleNode(i,0,is) != other.GetScaleNode(i,0,is) ) {
+            say::warn["IsCompatible"]<<"Incompatible scale node found."<<endl;
+            return false;
+         }
       }
    }
-   return true; 
+   return true;
+}
+
+
+//________________________________________________________________________________________________________________ //
+bool  fastNLOCoeffAddFix::IsCatenable(const fastNLOCoeffAddFix& other) const {
+   //! Check for compatibility of catenating observable bins
+   if ( ! ((fastNLOCoeffAddBase*)this)->IsCatenable(other)) return false;
+   if ( GetNScaleNode() != other.GetNScaleNode() ) {
+      debug["IsCatenable"]<<"Incompatible number of scale nodes found. Skipped."<<endl;
+      return false;
+   }
+   if ( GetNScalevar() != other.GetNScalevar() ) {
+      debug["IsCatenable"]<<"Incompatible number of scale variations found. Skipped."<<endl;
+      return false;
+   }
+   if ( GetAvailableScaleFactors()[GetNScalevar()-1] != other.GetAvailableScaleFactors()[GetNScalevar()-1] ) {
+      debug["IsCatenable"]<<"Incompatible scale variations found. Skipped."<<endl;
+      return false;
+   }
+   info["IsCatenable"]<<"Fix-scale contributions are catenable"<<endl;
+   return true;
 }
 
 
@@ -253,46 +321,127 @@ void fastNLOCoeffAddFix::Clear() {
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFix::NormalizeCoefficients(){
-   //!< Set number of events to 1 and normalize coefficients accordingly.
+void fastNLOCoeffAddFix::NormalizeCoefficients(double wgt){
+   //!< Set number of events to wgt (default=1) and normalize coefficients accordingly.
    //! This means, that the information about the
    //! number of events is essentially lost
-   MultiplyCoefficientsByConstant(1./Nevt);
-   Nevt = 1;
+   if ( wgt == Nevt ) return;
+   MultiplyCoefficientsByConstant(wgt/Nevt);
+   fastNLOCoeffAddBase::NormalizeCoefficients(wgt); //Nevt = wgt;
 }
 
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFix::NormalizeCoefficients(const std::vector<std::vector<double> >& wgtProcBin){
+   //!< Set number of events to wgtProcBin for each subprocess and bin
+   //!< and normalize coefficients accordingly.
+   if ( int(wgtProcBin.size()) != GetNSubproc() ) {//NObs
+      error["NormalizeCoefficients"]<<"Dimension of weights (iObs) incompatible with table (wgtProcBin must have dimension [iProc][iBin])."<<endl;
+      exit(4);
+   }
+
+   for ( int iProc = 0 ; iProc<GetNSubproc(); iProc++ ) {
+      if ( int(wgtProcBin[iProc].size()) != GetNObsBin() ) {
+         error["NormalizeCoefficients"]<<"Dimension of weights (iProc) incompatible with table (wgtProcBin must have dimension [iProc][iBin])."<<endl;
+	 exit(4);
+      }
+      for ( int iObs = 0 ; iObs<GetNObsBin(); iObs++ ) {
+         MultiplyBinProc(iObs, iProc, wgtProcBin[iProc][iObs]/Nevt);
+      }
+   }
+   fastNLOCoeffAddBase::NormalizeCoefficients(wgtProcBin);
+   //Nevt = 1;
+}
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFix::MultiplyCoefficientsByConstant(double coef) {
+void fastNLOCoeffAddFix::MultiplyCoefficientsByConstant(double fact) {
    for (unsigned int i=0; i<SigmaTilde.size(); i++) {
-      for (unsigned int s=0 ; s<SigmaTilde[i].size() ; s++) {
-         for (unsigned int x=0 ; x<SigmaTilde[i][s].size() ; x++) {
-            for (unsigned int l=0 ; l<SigmaTilde[i][s][x].size() ; l++) {
-               for (unsigned int m=0 ; m<SigmaTilde[i][s][x][m].size() ; m++) {
-                  SigmaTilde[i][s][x][l][m] *= coef;
-               }
-            }
-         }
+      MultiplyBin(i,fact);
+   }
+}
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFix::MultiplyBin(unsigned int iObsIdx, double fact) {
+   //! Multiply observable bin
+   for (int m=0 ; m<GetNSubproc() ; m++)
+      MultiplyBinProc(iObsIdx,m,fact);
+}
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFix::MultiplyBinProc(unsigned int iObsIdx, unsigned int iProc, double fact) {
+   //! Multiply observable bin for a single subprocess
+   debug["fastNLOCoeffAddFix::MultiplyBin"]<<"Multiplying table entries in CoeffAddFix for bin index " << iObsIdx << " by factor " << fact << endl;
+   for (unsigned int s=0 ; s<SigmaTilde[iObsIdx].size() ; s++) {
+      for (unsigned int x=0 ; x<SigmaTilde[iObsIdx][s].size() ; x++) {
+         for (unsigned int l=0 ; l<SigmaTilde[iObsIdx][s][x].size() ; l++) {
+	    SigmaTilde[iObsIdx][s][x][l][iProc] *= fact;
+	 }
       }
    }
+   fastNLOCoeffAddBase::MultiplyBinProc(iObsIdx, iProc, fact);
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFix::Print() const {
-   fastNLOCoeffAddBase::Print();
-   printf(" **************** FastNLO Table: fastNLOCoeffAddFix ****************\n");
-   for(int i=0;i<NScaleDim;i++){
-      printf(" B    - Nscalenode[%d]              %d\n",i,GetNScaleNode());
-      printf(" B    - Nscalevar[%d]               %d\n",i,Nscalevar[i]);
-      for(int j=0;j<Nscalevar[i];j++){
-         printf(" B    -  - ScaleFac[%d][%d]          %6.4f\n",i,j,ScaleFac[i][j]);
+void fastNLOCoeffAddFix::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      fastNLOCoeffAddBase::Print(iprint);
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffAddFix " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffAddFix " << fastNLO::_CSEP20 << endl;
+   }
+   for (int i=0; i<NScaleDim; i++) {
+      printf(" # No. of scale variations (Nscalevar) %d\n",GetNScalevar());
+      fastNLOTools::PrintVector(GetAvailableScaleFactors(),"Scale factors (ScaleFac[0][])","#");
+      printf(" # No. of scale nodes (Nscalenode)     %d\n",GetNScaleNode());
+   }
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      char buffer[1024];
+      for (int i=0; i<fNObsBins; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==fNObsBins-1) {
+            printf(" #   Observable bin no. %d\n",i+1);
+            snprintf(buffer, sizeof(buffer), "Scale nodes (ScaleNode[%d][0][0][])",i);
+            fastNLOTools::PrintVector(GetScaleNodes(i,0),buffer,"#  ");
+         }
       }
    }
-   printf(" B   No printing of ScaleNode implemented yet.\n");
-   printf(" B   No printing of SigmaTilde implemented yet.\n");
-   printf(" *******************************************************\n");
+   if ( abs(iprint) > 1 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 1) " << fastNLO::_SSEP20 << endl;
+      printf(" #   Printing of SigmaTilde not yet implemented.\n");
+   }
+   cout << fastNLO::_CSEPSC << endl;
 }
 
 
 //________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFix::EraseBin(unsigned int iObsIdx) {
+   //! Erase observable bin
+   debug["fastNLOCoeffAddFix::EraseBin"]<<"Erasing table entries in CoeffAddFix for bin index " << iObsIdx << endl;
+   if ( ScaleNode.size() == 0 ) {
+      say::error["EraseBin"]<<"All fix-scale bins deleted already. Aborted!" << endl;
+      exit(1);
+   }
+   if ( ScaleNode.size() != 0 ) ScaleNode.erase(ScaleNode.begin()+iObsIdx);
+   if ( SigmaTilde.size() != 0 ) SigmaTilde.erase(SigmaTilde.begin()+iObsIdx);
+   fastNLOCoeffAddBase::EraseBin(iObsIdx);
+}
+
+// Catenate observable bin
+void fastNLOCoeffAddFix::CatBin(const fastNLOCoeffAddFix& other, unsigned int iObsIdx) {
+   debug["fastNLOCoeffAddFix::CatBin"]<<"Catenating observable bin in CoeffAddFix corresponding to bin index " << iObsIdx << endl;
+   if ( ScaleNode.size() == 0 ) {
+      say::error["CatBin"]<<"Initial fix-scale table is empty. Aborted!" << endl;
+      exit(1);
+   }
+   unsigned int nold = ScaleNode.size();
+   if ( ScaleNode.size() != 0 ) {
+      ScaleNode.resize(nold+1);
+      ScaleNode[nold] = other.ScaleNode[iObsIdx];
+   }
+   if ( SigmaTilde.size() != 0 ) {
+      SigmaTilde.resize(nold+1);
+      SigmaTilde[nold] = other.SigmaTilde[iObsIdx];
+   }
+   fastNLOCoeffAddBase::CatBin(other, iObsIdx);
+}
diff --git a/FastNLO/src/fastNLOCoeffAddFlex.cc b/FastNLO/src/fastNLOCoeffAddFlex.cc
index 7c026d7491e11d7e9149d1890544d7f2e2ce2f4e..8a16da0b0e730ee741eb5f774d1d2d2b43bf0ad5 100644
--- a/FastNLO/src/fastNLOCoeffAddFlex.cc
+++ b/FastNLO/src/fastNLOCoeffAddFlex.cc
@@ -9,43 +9,39 @@ using namespace std;
 
 
 //________________________________________________________________________________________________________________ //
-bool fastNLOCoeffAddFlex::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet ) {
-   bool ret = fastNLOCoeffAddBase::CheckCoeffConstants(c,quiet);
-   if ( ret &&  c->GetNScaleDep() >= 3) return true;
-   else if ( c->GetNScaleDep() < 3 ) {
-      if ( !quiet )
-         say::error["CheckCoeffConstants"]<<"This is not a flexible scale table. NScaleDep must be >= 3 but is NScaleDep="
-                                          <<c->GetNScaleDep()<<endl;
-      return false;
-   }
-   else return false;
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFlex::fastNLOCoeffAddFlex(){
+fastNLOCoeffAddFlex::fastNLOCoeffAddFlex(int NObsBin, int iLOord)
+   : fastNLOCoeffAddBase(NObsBin), fILOord(iLOord), SigmaTildeMuIndep(), SigmaTildeMuFDep(),
+     SigmaTildeMuRDep(), SigmaTildeMuRRDep(), SigmaTildeMuFFDep(), SigmaTildeMuRFDep(),
+     SigmaRefMixed(), SigmaRef_s1(), SigmaRef_s2(), ScaleNode1(), ScaleNode2(), AlphasTwoPi(), PdfLcMuVar() {
    SetClassName("fastNLOCoeffAddFlex");
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFlex::fastNLOCoeffAddFlex(int NObsBin, int iLOord) : fastNLOCoeffAddBase(NObsBin){
+fastNLOCoeffAddFlex::fastNLOCoeffAddFlex(const fastNLOCoeffBase& base , int iLOord ) : fastNLOCoeffAddBase(base)  {
    SetClassName("fastNLOCoeffAddFlex");
-   fILOord = iLOord; // only necessary for fixing NScaleDep 3 -> 4,5
+   fILOord = iLOord;
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffAddFlex::fastNLOCoeffAddFlex(const fastNLOCoeffBase& base , int iLOord ) : fastNLOCoeffAddBase(base)  {
-   SetClassName("fastNLOCoeffAddFlex");
-   fILOord = iLOord;
+bool fastNLOCoeffAddFlex::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet ) {
+   bool ret = fastNLOCoeffAddBase::CheckCoeffConstants(c,quiet);
+   if ( ret &&  c->GetNScaleDep() >= 3) return true;
+   else if ( c->GetNScaleDep() < 3 ) {
+      if ( !quiet )
+         say::error["CheckCoeffConstants"]<<"This is not a flexible scale table. NScaleDep must be >= 3 but is NScaleDep="
+                                          <<c->GetNScaleDep()<<endl;
+      return false;
+   }
+   else return false;
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffBase* fastNLOCoeffAddFlex::Clone() const {
+fastNLOCoeffAddFlex* fastNLOCoeffAddFlex::Clone() const {
    //! User has to take care to delete this object later
-   return static_cast<fastNLOCoeffBase*>(new fastNLOCoeffAddFlex(*this));
+   return new fastNLOCoeffAddFlex(*this);
 }
 
 
@@ -83,6 +79,8 @@ void fastNLOCoeffAddFlex::ReadCoeffAddFlex(istream& table){
    // ------------------------------ //
    int nn3 = 0;
 
+   if ( fWgt.WgtSumW2==0 ) fSTildeDISFormat=0;
+
    nn3 += fastNLOTools::ReadFlexibleVector  ( ScaleNode1 , table );
    nn3 += fastNLOTools::ReadFlexibleVector  ( ScaleNode2 , table );
    //NscalenodeScale1 = ScaleNode1[0].size();
@@ -125,7 +123,7 @@ void fastNLOCoeffAddFlex::ReadCoeffAddFlex(istream& table){
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFlex::Write(ostream& table) {
+void fastNLOCoeffAddFlex::Write(ostream& table, int itabversion) {
    CheckCoeffConstants(this);
    // update to latest version
    if ( NScaleDep==3 ) {
@@ -145,10 +143,10 @@ void fastNLOCoeffAddFlex::Write(ostream& table) {
       }
       else if ( Npow==fILOord+2 ) {
          debug["Write"]<<" * Increase NScaleDep from 3 to 6 because NNLO!"<<endl;
-          NScaleDep=7;
+         NScaleDep=7;
       }
    }
-   fastNLOCoeffAddBase::Write(table);
+   fastNLOCoeffAddBase::Write(table,itabversion);
 
    int nn3 = 0;
    nn3 += fastNLOTools::WriteFlexibleVector( ScaleNode1 , table );
@@ -167,33 +165,33 @@ void fastNLOCoeffAddFlex::Write(ostream& table) {
          nn3 += fastNLOTools::WriteFlexibleVector( SigmaTildeMuRFDep , table , NSubproc, Nevt);
       }
    }
+
    if ( SigmaRefMixed.empty() ) fastNLOTools::ResizeVector(SigmaRefMixed,fNObsBins,NSubproc);
    if ( SigmaRef_s1.empty() )   fastNLOTools::ResizeVector(SigmaRef_s1,fNObsBins,NSubproc);
    if ( SigmaRef_s2.empty() )   fastNLOTools::ResizeVector(SigmaRef_s2,fNObsBins,NSubproc);
    nn3 += fastNLOTools::WriteFlexibleVector( SigmaRefMixed      , table , NSubproc, Nevt);
    nn3 += fastNLOTools::WriteFlexibleVector( SigmaRef_s1        , table , NSubproc, Nevt);
    nn3 += fastNLOTools::WriteFlexibleVector( SigmaRef_s2        , table , NSubproc, Nevt);
-
    /*
-   nn3 += WriteFlexibleTable( &SigmaTildeMuIndep, table , (bool)(option & DividebyNevt) , Nevt , true );
-
-   //if ( NScaleDep==3 || Npow!=fScen->ILOord || NScaleDep==5) {
-   if ( NScaleDep==3 || NScaleDep>=5) {
-      //cout<<"Write NLO FlexTable. NScaleDep="<<NScaleDep<<"\tNpow="<<Npow<<"\tfScen->ILOord="<<fScen->ILOord<<endl;
-      nn3 += WriteFlexibleTable( &SigmaTildeMuFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
-      nn3 += WriteFlexibleTable( &SigmaTildeMuRDep , table , (bool)(option & DividebyNevt) , Nevt , true );
-      if ( NScaleDep>=6) {
-         nn3 += WriteFlexibleTable( &SigmaTildeMuRRDep , table , (bool)(option & DividebyNevt) , Nevt , true );
-         nn3 += WriteFlexibleTable( &SigmaTildeMuFFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
-         nn3 += WriteFlexibleTable( &SigmaTildeMuRFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
-      }
-   }
-   if ( SigmaRefMixed.empty() ) fastNLOCoeffBase::ResizeTable(&SigmaRefMixed,fNObsBins,NSubproc);
-   if ( SigmaRef_s1.empty() )   fastNLOCoeffBase::ResizeTable(&SigmaRef_s1,fNObsBins,NSubproc);
-   if ( SigmaRef_s2.empty() )   fastNLOCoeffBase::ResizeTable(&SigmaRef_s2,fNObsBins,NSubproc);
-   nn3 += WriteFlexibleTable( &SigmaRefMixed    , table , (bool)(option & DividebyNevt) , Nevt , true );
-   nn3 += WriteFlexibleTable( &SigmaRef_s1      , table , (bool)(option & DividebyNevt) , Nevt , true );
-   nn3 += WriteFlexibleTable( &SigmaRef_s2      , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaTildeMuIndep, table , (bool)(option & DividebyNevt) , Nevt , true );
+
+     //if ( NScaleDep==3 || Npow!=fScen->ILOord || NScaleDep==5) {
+     if ( NScaleDep==3 || NScaleDep>=5) {
+     //cout<<"Write NLO FlexTable. NScaleDep="<<NScaleDep<<"\tNpow="<<Npow<<"\tfScen->ILOord="<<fScen->ILOord<<endl;
+     nn3 += WriteFlexibleTable( &SigmaTildeMuFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaTildeMuRDep , table , (bool)(option & DividebyNevt) , Nevt , true );
+     if ( NScaleDep>=6) {
+     nn3 += WriteFlexibleTable( &SigmaTildeMuRRDep , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaTildeMuFFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaTildeMuRFDep , table , (bool)(option & DividebyNevt) , Nevt , true );
+     }
+     }
+     if ( SigmaRefMixed.empty() ) fastNLOCoeffBase::ResizeTable(&SigmaRefMixed,fNObsBins,NSubproc);
+     if ( SigmaRef_s1.empty() )   fastNLOCoeffBase::ResizeTable(&SigmaRef_s1,fNObsBins,NSubproc);
+     if ( SigmaRef_s2.empty() )   fastNLOCoeffBase::ResizeTable(&SigmaRef_s2,fNObsBins,NSubproc);
+     nn3 += WriteFlexibleTable( &SigmaRefMixed    , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaRef_s1      , table , (bool)(option & DividebyNevt) , Nevt , true );
+     nn3 += WriteFlexibleTable( &SigmaRef_s2      , table , (bool)(option & DividebyNevt) , Nevt , true );
    */
    //printf("  *  fastNLOCoeffAddFlex::Write(). Wrote %d lines of v2.1 Tables.\n",nn3);
    debug["Write"]<<"Wrote "<<nn3<<" lines of v2.1 Tables."<<endl;
@@ -201,36 +199,145 @@ void fastNLOCoeffAddFlex::Write(ostream& table) {
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFlex::Add(const fastNLOCoeffAddBase& other){
+void fastNLOCoeffAddFlex::Add(const fastNLOCoeffAddBase& other, fastNLO::EMerge moption){
    bool ok = CheckCoeffConstants(this);
    if ( !ok ) {
       error["Add"]<<"Incompatible table."<<endl;
    }
    const fastNLOCoeffAddFlex& othflex = (const fastNLOCoeffAddFlex&) other;
-   Nevt += othflex.Nevt;
-   fastNLOTools::AddVectors( SigmaTildeMuIndep , othflex.SigmaTildeMuIndep );
-   if ( NScaleDep==3 || NScaleDep>=5 ) {
-      fastNLOTools::AddVectors( SigmaTildeMuFDep , othflex.SigmaTildeMuFDep );
-      fastNLOTools::AddVectors( SigmaTildeMuRDep , othflex.SigmaTildeMuRDep );
-      if (( NScaleDep>=6 || !SigmaTildeMuRRDep.empty())  // both tables contain log^2 contributions (default case)
-          && (othflex.NScaleDep>=6 || !othflex.SigmaTildeMuRRDep.empty()) ) {
-         fastNLOTools::AddVectors( SigmaTildeMuRRDep , othflex.SigmaTildeMuRRDep );
+   if ( moption==fastNLO::kMerge ) {
+      fastNLOTools::AddVectors( SigmaTildeMuIndep , othflex.SigmaTildeMuIndep );
+      if ( NScaleDep==3 || NScaleDep>=5 ) {
+         fastNLOTools::AddVectors( SigmaTildeMuFDep , othflex.SigmaTildeMuFDep );
+         fastNLOTools::AddVectors( SigmaTildeMuRDep , othflex.SigmaTildeMuRDep );
+         if (( NScaleDep>=6 || !SigmaTildeMuRRDep.empty())  // both tables contain log^2 contributions (default case)
+             && (othflex.NScaleDep>=6 || !othflex.SigmaTildeMuRRDep.empty()) ) {
+            fastNLOTools::AddVectors( SigmaTildeMuRRDep , othflex.SigmaTildeMuRRDep );
+         }
+         else if ( NScaleDep==6 && othflex.NScaleDep==5 ) { // this tables contains log^2 contributions, but the other does not
+            // nothing todo.
+         }
+         else if ( NScaleDep==5 && othflex.NScaleDep==6 ) { // this tables does not contain log^2 contributions, but the other does !
+            SigmaTildeMuRRDep = othflex.SigmaTildeMuRRDep;
+            NScaleDep = 6;
+         }
+         if ( NScaleDep>=7 || !SigmaTildeMuFFDep.empty()) {
+            fastNLOTools::AddVectors( SigmaTildeMuFFDep , othflex.SigmaTildeMuFFDep );
+            fastNLOTools::AddVectors( SigmaTildeMuRFDep , othflex.SigmaTildeMuRFDep );
+         }
       }
-      else if ( NScaleDep==6 && othflex.NScaleDep==5 ) { // this tables contains log^2 contributions, but the other does not
-         // nothing todo.
+      fastNLOTools::AddVectors( SigmaRefMixed , othflex.SigmaRefMixed );
+      fastNLOTools::AddVectors( SigmaRef_s1 , othflex.SigmaRef_s1 );
+      fastNLOTools::AddVectors( SigmaRef_s2 , othflex.SigmaRef_s2 );
+   }
+   else if ( moption==fastNLO::kAttach ) {
+      vector<fastNLO::v5d*> st1 = this->AccessSigmaTildes();
+      vector<const fastNLO::v5d*> st2 = othflex.GetSigmaTildes();
+      int cMax = st1.size();
+      for ( int ii = cMax-1 ; ii>= 0 ; ii-- ) {
+         if ( st1[ii]->size()==0 ) cMax--;
+         if ( st1[ii]->size() != st2[ii]->size() ) {
+            error["Add"]<<"Scale dependent weights are not identically initialized"<<endl;
+            exit(1);
+         }
       }
-      else if ( NScaleDep==5 && othflex.NScaleDep==6 ) { // this tables does not contain log^2 contributions, but the other does !
-         SigmaTildeMuRRDep = othflex.SigmaTildeMuRRDep;
-         NScaleDep = 6;
+      for ( int iObs = 0 ; iObs<GetNObsBin(); iObs++ ) {
+         for (unsigned int jS1=0; jS1<GetNScaleNode1(iObs); jS1++) {
+            for (unsigned int kS2=0; kS2<GetNScaleNode2(iObs); kS2++) {
+               int nxmax = GetNxmax(iObs);
+               for (int x=0; x<nxmax; x++) {
+                  for (int n=0; n<other.GetNSubproc(); n++) {
+                     for ( int im = 0 ; im<cMax ; im++ ) { // mu-indep, mur, muf, ...
+                        double s2  = (*st2[im])[iObs][x][jS1][kS2][n];
+                        s2 *= this->Nevt/other.GetNevt();
+                        (*st1[im])[iObs][x][jS1][kS2].push_back(s2);
+                     }
+                  }
+               }
+            }
+         }
+         for (int n=0; n<other.GetNSubproc(); n++) {
+            SigmaRefMixed[iObs].push_back(othflex.SigmaRefMixed[iObs][n]);
+            SigmaRef_s1[iObs].push_back(othflex.SigmaRef_s1[iObs][n]);
+            SigmaRef_s2[iObs].push_back(othflex.SigmaRef_s2[iObs][n]);
+         }
+      }
+   }
+   else {
+      vector<fastNLO::v5d*> st1 = this->AccessSigmaTildes();
+      vector<const fastNLO::v5d*> st2 = othflex.GetSigmaTildes();
+      int cMax = st1.size();
+      for ( int ii = cMax-1 ; ii>= 0 ; ii-- ) {
+         if ( st1[ii]->size()==0 && st2[ii]->size()==0) cMax--;
+         if ( st1[ii]->size() != st2[ii]->size() ) {
+            warn["Add"]<<"Scale dependent weights are not identically initialized... (NScaleDep="<<NScaleDep<<", other.NScaleDep="<<other.GetNScaleDep()<<")"<<endl;
+            //exit(1);
+            if ( st1[ii]->size() == 0 ) {
+               /*
+               // error["Add"]<<"...and calling table has less entries. Please try to call with opposite order of input arguments."<<endl;
+               // exit(1);
+               if ( ii==0 ) { error["Add"]<<"... no scale-independent contributions detected! exiting."<<endl; exit(3); }
+               else {
+                  (*st1[ii]) = *st2[ii]; // hard copy of coefficients
+                  cMax--; // no need for second copy
+               }
+               info["add"]<<"Copied coefficients from other table."<<endl;
+               */
+               fastNLOTools::ResizeFlexibleVector(*st1[ii],*st2[ii]);
+            }
+            else if ( st2[ii]->size() == 0  ) {
+               warn["Add"]<<"... 'other' table has empty coefficients (ii="<<ii<<"). Ignoring it (NScaleDep="<<NScaleDep<<", other.NScaleDep="<<other.GetNScaleDep()<<")"<<endl;
+               cMax--;
+            }
+            else {
+               error["Add"]<<"... don't know how to merge these two tables (Different number of bins detected)."<<endl;
+               exit(2);
+            }
+         }
       }
-      if ( NScaleDep>=7 || !SigmaTildeMuFFDep.empty()) {
-         fastNLOTools::AddVectors( SigmaTildeMuFFDep , othflex.SigmaTildeMuFFDep );
-         fastNLOTools::AddVectors( SigmaTildeMuRFDep , othflex.SigmaTildeMuRFDep );
+      for ( int iObs = 0 ; iObs<GetNObsBin(); iObs++ ) {
+         for (unsigned int jS1=0; jS1<GetNScaleNode1(iObs); jS1++) {
+            for (unsigned int kS2=0; kS2<GetNScaleNode2(iObs); kS2++) {
+               int nxmax = GetNxmax(iObs);
+               for (int x=0; x<nxmax; x++) {
+                  for (int n=0; n<GetNSubproc(); n++) {
+                     for ( int im = 0 ; im<cMax ; im++ ) { // mu-indep, mur, muf, ...
+                        double w1  = this->GetMergeWeight(moption,n,iObs);
+                        double w2  = other.GetMergeWeight(moption,n,iObs);
+                        double& s1 = (*st1[im])[iObs][x][jS1][kS2][n];
+                        double s2  = st2[im]->size() ? (*st2[im])[iObs][x][jS1][kS2][n] : 0;
+                        if ( s1!=0 || s2!=0 ) {
+                           if ( w1==0 || w2==0 ) {
+                              error["fastNLOCoeffAddFix"]<<"Mergeing weight is 0, but sigma tilde is non-zero. Cannot proceed!"<<endl;
+                              exit(3);
+                           }
+                           s1 = ( w1*s1/Nevt + w2*s2/other.GetNevt() ) / (w1 + w2 ) * ( Nevt + other.GetNevt() ) ;
+                        }
+                     }
+                  }
+               }
+            }
+         }
       }
+      fastNLOTools::AddVectors( SigmaRefMixed , othflex.SigmaRefMixed );
+      fastNLOTools::AddVectors( SigmaRef_s1 , othflex.SigmaRef_s1 );
+      fastNLOTools::AddVectors( SigmaRef_s2 , othflex.SigmaRef_s2 );
+   }
+
+   fastNLOCoeffAddBase::Add(other,moption);
+
+   //Nevt += othflex.Nevt;
+   if ( moption==fastNLO::kAdd ) {
+      NormalizeCoefficients(2);
+      Nevt = 1;
+      fWgt.WgtNevt = 1;
+   }
+   else if ( moption==fastNLO::kUnweighted ) {
+      NormalizeCoefficients(1);
+   }
+   else if ( moption==fastNLO::kAttach ) {
+      NormalizeCoefficients(1);
    }
-   fastNLOTools::AddVectors( SigmaRefMixed , othflex.SigmaRefMixed );
-   fastNLOTools::AddVectors( SigmaRef_s1 , othflex.SigmaRef_s1 );
-   fastNLOTools::AddVectors( SigmaRef_s2 , othflex.SigmaRef_s2 );
 }
 
 
@@ -249,85 +356,212 @@ void fastNLOCoeffAddFlex::Clear() {
    fastNLOTools::ClearVector(SigmaRef_s2);
 }
 
-//________________________________________________________________________________________________________________ // 
+
+//________________________________________________________________________________________________________________ //
 bool  fastNLOCoeffAddFlex::IsCompatible(const fastNLOCoeffAddFlex& other) const {
-   //! Check for compatibility for merging/adding of two contributions 
+   //! Check for compatibility for merging/adding of two contributions
    if ( ! ((fastNLOCoeffAddBase*)this)->IsCompatible(other)) return false;
-   for ( int i=0 ; i<fNObsBins ; i++ ){ 
+   for ( int i=0 ; i<fNObsBins ; i++ ){
       if ( GetNScaleNode1(i) != other.GetNScaleNode1(i) ) {
-	 say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;
-	 return false;
+         say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;
+         return false;
       }
       if ( GetNScaleNode2(i) != other.GetNScaleNode2(i) ) {
-	 say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;
-	 return false;
+         say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible number of scale nodes found."<<endl;
+         return false;
       }
       for ( unsigned int is1 = 0 ; is1<GetNScaleNode1(i) ; is1++ ) {
-	 if ( GetScaleNode1(i,is1) != other.GetScaleNode1(i,is1) ) {
-	    say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible scale1 node found."<<endl;
-	    return false;
-	 }
+         if ( GetScaleNode1(i,is1) != other.GetScaleNode1(i,is1) ) {
+            say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible scale1 node found."<<endl;
+            return false;
+         }
       }
       for ( unsigned int is2 = 0 ; is2<GetNScaleNode2(i) ; is2++ ) {
-	 if ( GetScaleNode2(i,is2) != other.GetScaleNode2(i,is2) ) {
-	    say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible scale2 node found."<<endl;
-	    return false;
-	 }
+         if ( GetScaleNode2(i,is2) != other.GetScaleNode2(i,is2) ) {
+            say::warn["fastNLOCoeffAddFlex::IsCompatible"]<<"Incompatible scale2 node found."<<endl;
+            return false;
+         }
       }
    }
    return true;
 }
 
+
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFlex::NormalizeCoefficients(){
-   //!< Set number of events to 1 and normalize coefficients accordingly.
-   //! This means, that the information about the
-   //! number of events is essentially lost
-   MultiplyCoefficientsByConstant(1./Nevt);
-   Nevt = 1;
+bool  fastNLOCoeffAddFlex::IsCatenable(const fastNLOCoeffAddFlex& other) const {
+   //! Check for compatibility of catenating observable bins
+   if ( ! ((fastNLOCoeffAddBase*)this)->IsCatenable(other)) return false;
+   // TODO: More checks
+   info["IsCatenable"]<<"Flex-scale contributions are catenable"<<endl;
+   return true;
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFlex::MultiplyCoefficientsByConstant(double coef) {
-   const bool WithMuR = !SigmaTildeMuFDep.empty();
-   const bool WithMuRR = !SigmaTildeMuRRDep.empty();
-   const bool WithMuFF = !SigmaTildeMuFFDep.empty();
-   for (unsigned int i=0; i<SigmaTildeMuIndep.size(); i++) {
-      int nxmax = GetNxmax(i);
-      for (unsigned int jS1=0; jS1<GetNScaleNode1(i); jS1++) {
-         for (unsigned int kS2=0; kS2<GetNScaleNode2(i); kS2++) {
-            for (int x=0; x<nxmax; x++) {
-               for (int n=0; n<GetNSubproc(); n++) {
-                  SigmaTildeMuIndep[i][x][jS1][kS2][n] *= coef;
-                  //if ( GetNScaleDep() >= 5 ) {
-                  if (WithMuR) {
-                     SigmaTildeMuFDep [i][x][jS1][kS2][n] *= coef;
-                     SigmaTildeMuRDep [i][x][jS1][kS2][n] *= coef;
-                     //if ( GetNScaleDep() >= 6 ) {
-                     if (WithMuRR) {
-                        SigmaTildeMuRRDep [i][x][jS1][kS2][n] *= coef;
-                     }
-                     if (WithMuFF) {
-                        SigmaTildeMuFFDep [i][x][jS1][kS2][n] *= coef;
-                        SigmaTildeMuRFDep [i][x][jS1][kS2][n] *= coef;
-                     }
-                  }
-               }
+void fastNLOCoeffAddFlex::NormalizeCoefficients(double wgt){
+   //!< Set number of events to wgt (default=1) and normalize coefficients accordingly.
+   if ( wgt==Nevt ) return;
+   MultiplyCoefficientsByConstant(wgt/Nevt);
+   fastNLOCoeffAddBase::NormalizeCoefficients(wgt); // Nevt=wgt
+}
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFlex::NormalizeCoefficients(const std::vector<std::vector<double> >& wgtProcBin){
+   //!< Change cross sections!!!
+   //!< Warning! This function is only sensible if called by 'MergeTable'!
+   if ( int(wgtProcBin.size()) != GetNSubproc() ) {//NObs
+      error["NormalizeCoefficients"]<<"Dimension of weights (iObs) incompatible with table (wgtProcBin must have dimension [iProc][iBin])."<<endl; exit(4);
+   }
+
+   for ( int iProc = 0 ; iProc<GetNSubproc(); iProc++ ) {
+      if ( int(wgtProcBin[iProc].size()) != GetNObsBin() ) {//
+         error["NormalizeCoefficients"]<<"Dimension of weights (iProc) incompatible with table (wgtProcBin must have dimension [iProc][iBin])."<<endl; exit(4);
+      }
+      for ( int iObs = 0 ; iObs<GetNObsBin(); iObs++ ) {
+         MultiplyBinProc(iObs, iProc, wgtProcBin[iProc][iObs]/Nevt);
+      }
+   }
+   //fastNLOCoeffAddBase::NormalizeCoefficients(wgtProcBin);
+   //Nevt = 1;
+   // MultiplyCoefficientsByConstant(wgt/Nevt);
+   // Nevt = 0;
+}
+
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFlex::MultiplyCoefficientsByConstant(double fact) {
+   for (unsigned int i=0; i<SigmaTildeMuIndep.size(); i++) { // NObsBin
+      MultiplyBin(i,fact);
+   }
+}
+
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFlex::MultiplyBin(unsigned int iObsIdx, double fact) {
+   //! Multiply observable bin
+   for (int n=0; n<GetNSubproc(); n++) {
+      MultiplyBinProc(iObsIdx,n,fact);
+   }
+}
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffAddFlex::MultiplyBinProc(unsigned int iObsIdx, unsigned int iProc, double fact) {
+   //! Multiply observable bin
+   debug["fastNLOCoeffAddFlex::MultiplyBinProc"]<<"Multiplying table entries in CoeffAddFlex for bin index "
+                                                << iObsIdx << " and proc index "<<iProc<<" by factor " << fact << endl;
+   int nxmax = GetNxmax(iObsIdx);
+   for (unsigned int jS1=0; jS1<GetNScaleNode1(iObsIdx); jS1++) {
+      for (unsigned int kS2=0; kS2<GetNScaleNode2(iObsIdx); kS2++) {
+         for (int x=0; x<nxmax; x++) {
+            int n=iProc;
+            if ( fact==0 && SigmaTildeMuIndep[iObsIdx][x][jS1][kS2][n]!=0 ) {
+               // prevent to calculate unreasonable cross sections.
+               error["MultiplyBinProc"]<<"Multiplying non-zero coefficient with weight 0. "<<endl;
+               exit(4);
+            }
+            else {
+               if ( SigmaTildeMuIndep.size() != 0 ) SigmaTildeMuIndep[iObsIdx][x][jS1][kS2][n] *= fact;
+               if ( SigmaTildeMuRDep.size()  != 0 ) SigmaTildeMuRDep[iObsIdx][x][jS1][kS2][n]  *= fact;
+               if ( SigmaTildeMuFDep.size()  != 0 ) SigmaTildeMuFDep[iObsIdx][x][jS1][kS2][n]  *= fact;
+               if ( SigmaTildeMuRRDep.size() != 0 ) SigmaTildeMuRRDep[iObsIdx][x][jS1][kS2][n] *= fact;
+               if ( SigmaTildeMuFFDep.size() != 0 ) SigmaTildeMuFFDep[iObsIdx][x][jS1][kS2][n] *= fact;
+               if ( SigmaTildeMuRFDep.size() != 0 ) SigmaTildeMuRFDep[iObsIdx][x][jS1][kS2][n] *= fact;
             }
          }
       }
    }
+   fastNLOCoeffAddBase::MultiplyBinProc(iObsIdx, iProc, fact);
 }
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffAddFlex::Print() const {
-   fastNLOCoeffAddBase::Print();
-   printf(" **************** FastNLO Table: fastNLOCoeffAddFlex ****************\n");
-   printf(" B   NscalenodeScale1              %lu\n",ScaleNode1[0].size());
-   printf(" B   NscalenodeScale2              %lu\n",ScaleNode2[0].size());
-   printf(" *******************************************************\n");
+void fastNLOCoeffAddFlex::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      fastNLOCoeffAddBase::Print(iprint);
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffAddFlex " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffAddFlex " << fastNLO::_CSEP20 << endl;
+   }
+   printf(" # No. of scale1 nodes (Nscalenode1)   %d\n",(int)ScaleNode1[0].size());
+   printf(" # No. of scale2 nodes (Nscalenode2)   %d\n",(int)ScaleNode2[0].size());
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      char buffer[1024];
+      for (int i=0; i<fNObsBins; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==fNObsBins-1) {
+            printf(" #   Observable bin no. %d\n",i+1);
+            snprintf(buffer, sizeof(buffer), "Scale nodes 1 (ScaleNode1[%d][])",i);
+            fastNLOTools::PrintVector(GetScaleNodes1(i),buffer,"#  ");
+            if ( ScaleNode2.size() != 0 ) {
+               snprintf(buffer, sizeof(buffer), "Scale nodes 2 (ScaleNode2[%d][])",i);
+               fastNLOTools::PrintVector(GetScaleNodes2(i),buffer,"#  ");
+            }
+         }
+      }
+   }
+   cout << fastNLO::_CSEPSC << endl;
 }
 
 
 //________________________________________________________________________________________________________________ //
+
+// Erase observable bin
+void fastNLOCoeffAddFlex::EraseBin(unsigned int iObsIdx) {
+   debug["fastNLOCoeffAddFlex::EraseBin"]<<"Erasing table entries in CoeffAddFlex for bin index " << iObsIdx << endl;
+   if ( ScaleNode1.size() == 0 ) {
+      say::error["EraseBin"]<<"All bins deleted already. Aborted!" << endl;
+      exit(1);
+   }
+   if ( ScaleNode1.size() != 0 ) ScaleNode1.erase(ScaleNode1.begin()+iObsIdx);
+   if ( ScaleNode2.size() != 0 ) ScaleNode2.erase(ScaleNode2.begin()+iObsIdx);
+   if ( SigmaTildeMuIndep.size() != 0 ) SigmaTildeMuIndep.erase(SigmaTildeMuIndep.begin()+iObsIdx);
+   if ( SigmaTildeMuFDep.size()  != 0 ) SigmaTildeMuFDep.erase(SigmaTildeMuFDep.begin()+iObsIdx);
+   if ( SigmaTildeMuRDep.size()  != 0 ) SigmaTildeMuRDep.erase(SigmaTildeMuRDep.begin()+iObsIdx);
+   if ( SigmaTildeMuRRDep.size() != 0 ) SigmaTildeMuRRDep.erase(SigmaTildeMuRRDep.begin()+iObsIdx);
+   if ( SigmaTildeMuFFDep.size() != 0 ) SigmaTildeMuFFDep.erase(SigmaTildeMuFFDep.begin()+iObsIdx);
+   if ( SigmaTildeMuRFDep.size() != 0 ) SigmaTildeMuRFDep.erase(SigmaTildeMuRFDep.begin()+iObsIdx);
+   fastNLOCoeffAddBase::EraseBin(iObsIdx);
+}
+
+// Catenate observable bin
+void fastNLOCoeffAddFlex::CatBin(const fastNLOCoeffAddFlex& other, unsigned int iObsIdx) {
+   debug["fastNLOCoeffAddFlex::CatBin"]<<"Catenating observable bin in CoeffAddFlex corresponding to bin index " << iObsIdx << endl;
+   if ( ScaleNode1.size() == 0 ) {
+      say::error["CatBin"]<<"Initial flex-scale table is empty. Aborted!" << endl;
+      exit(1);
+   }
+   unsigned int nold = ScaleNode1.size();
+   if ( ScaleNode1.size() != 0 ) {
+      ScaleNode1.resize(nold+1);
+      ScaleNode1[nold] = other.ScaleNode1[iObsIdx];
+   }
+   if ( ScaleNode2.size() != 0 ) {
+      ScaleNode2.resize(nold+1);
+      ScaleNode2[nold] = other.ScaleNode2[iObsIdx];
+   }
+   if ( SigmaTildeMuIndep.size() != 0 ) {
+      SigmaTildeMuIndep.resize(nold+1);
+      SigmaTildeMuIndep[nold] = other.SigmaTildeMuIndep[iObsIdx];
+   }
+   if ( SigmaTildeMuFDep.size() != 0 ) {
+      SigmaTildeMuFDep.resize(nold+1);
+      SigmaTildeMuFDep[nold] = other.SigmaTildeMuFDep[iObsIdx];
+   }
+   if ( SigmaTildeMuRDep.size() != 0 ) {
+      SigmaTildeMuRDep.resize(nold+1);
+      SigmaTildeMuRDep[nold] = other.SigmaTildeMuRDep[iObsIdx];
+   }
+   if ( SigmaTildeMuRRDep.size() != 0 ) {
+      SigmaTildeMuRRDep.resize(nold+1);
+      SigmaTildeMuRRDep[nold] = other.SigmaTildeMuRRDep[iObsIdx];
+   }
+   if ( SigmaTildeMuFFDep.size() != 0 ) {
+      SigmaTildeMuFFDep.resize(nold+1);
+      SigmaTildeMuFFDep[nold] = other.SigmaTildeMuFFDep[iObsIdx];
+   }
+   if ( SigmaTildeMuRFDep.size() != 0 ) {
+      SigmaTildeMuRFDep.resize(nold+1);
+      SigmaTildeMuRFDep[nold] = other.SigmaTildeMuRFDep[iObsIdx];
+   }
+   fastNLOCoeffAddBase::CatBin(other, iObsIdx);
+}
diff --git a/FastNLO/src/fastNLOCoeffBase.cc b/FastNLO/src/fastNLOCoeffBase.cc
index 2b42e1c8be8759d0384893338ff913a0e3d1c6f7..1b9a34685e55fd84eff7f6241de812691f141af6 100644
--- a/FastNLO/src/fastNLOCoeffBase.cc
+++ b/FastNLO/src/fastNLOCoeffBase.cc
@@ -3,23 +3,21 @@
 #include <cmath>
 
 #include "fastnlotk/fastNLOCoeffBase.h"
+#include "fastnlotk/fastNLOConstants.h"
 #include "fastnlotk/fastNLOTools.h"
 
 using namespace std;
+using namespace fastNLO;
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffBase::fastNLOCoeffBase() : PrimalScream("fastNLOCoeffBase"){
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffBase::fastNLOCoeffBase(int NObsBin) : PrimalScream("fastNLOCoeffBase") {
-   fNObsBins = NObsBin;
-}
+fastNLOCoeffBase::fastNLOCoeffBase(int NObsBin)
+   : PrimalScream("fastNLOCoeffBase"), fNObsBins(NObsBin), IXsectUnits(),
+     IDataFlag(), IAddMultFlag(), IContrFlag1(), IContrFlag2(), NScaleDep(),
+     CtrbDescript(), CodeDescript() {}
 
 //________________________________________________________________________________________________________________ //
 fastNLOCoeffBase* fastNLOCoeffBase::Clone() const {
-   //! Use has to take care to delete this object later
+   //! User has to take care to delete this object later
    return new fastNLOCoeffBase(*this);
 }
 
@@ -37,17 +35,15 @@ void fastNLOCoeffBase::Read(istream& table){
 //________________________________________________________________________________________________________________ //
 void fastNLOCoeffBase::ReadBase(istream& table){
    debug["ReadBase"]<<endl;
-   table.peek();
-   if (table.eof()){
-      //printf("fastNLOCoeffBase::Read: Cannot read from file.\n");
-      error["ReadBase"]<<"Cannot read from file."<<endl;
-   }
+   //table.peek();
 
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      say::error["ReadBase"]<<"Did not find initial magic number, aborting!"<<endl;
-      say::error["ReadBase"]<<"Please check compatibility of tables and program version!"<<endl;
-      exit(1);
-   }
+   table >> fVersionRead;
+   if ( fVersionRead == fastNLO::tablemagicno )
+      fVersionRead = 22000 ;
+   //fastNLOTools::ReadMagicNo(table);
+   std::string stest;
+   if ( fVersionRead>=24000 ) table >> stest; //"fastNLO_CoeffAddBase"
+   if ( fVersionRead>=24000 ) fastNLOTools::ReadUnused(table);
 
    table >> IXsectUnits;
    table >> IDataFlag;
@@ -55,61 +51,63 @@ void fastNLOCoeffBase::ReadBase(istream& table){
    table >> IContrFlag1;
    table >> IContrFlag2;
    table >> NScaleDep;
-   int NContrDescr;
-   table >> NContrDescr;
-   //   printf("  *  fastNLOCoeffBase::Read().  IDataFlag: %d, IAddMultFlag: %d, IContrFlag1: %d, IContrFlag2: %d,, NScaleDep: %d\n",IDataFlag,IAddMultFlag,IContrFlag1,IContrFlag2,NScaleDep );
-   CtrbDescript.resize(NContrDescr);
-   char buffer[5257];
-   table.getline(buffer,5256);
-   for(int i=0;i<NContrDescr;i++){
-      table.getline(buffer,256);
-      CtrbDescript[i] = buffer;
-      //      StripWhitespace(CtrbDescript[i]);
-   }
-   int NCodeDescr;
-   table >> NCodeDescr;
-   CodeDescript.resize(NCodeDescr);
-   table.getline(buffer,256);
-   for(int i=0;i<NCodeDescr;i++){
-      table.getline(buffer,256);
-      CodeDescript[i] = buffer;
-      //      StripWhitespace(CodeDescript[i]);
-   }
+   fastNLOTools::ReadFlexibleVector(CtrbDescript,table);
+   fastNLOTools::ReadFlexibleVector(CodeDescript,table);
+   //printf("  *  fastNLOCoeffBase::Read().  IDataFlag: %d, IAddMultFlag: %d, IContrFlag1: %d, IContrFlag2: %d,, NScaleDep: %d\n",IDataFlag,IAddMultFlag,IContrFlag1,IContrFlag2,NScaleDep );
+   // int NContrDescr;
+   // table >> NContrDescr;
+   // CtrbDescript.resize(NContrDescr);
+   // char buffer[5257];
+   // table.getline(buffer,5256);
+   // for(int i=0;i<NContrDescr;i++){
+   //    table.getline(buffer,256);
+   //    CtrbDescript[i] = buffer;
+   //    //      StripWhitespace(CtrbDescript[i]);
+   // }
+   // int NCodeDescr;
+   // table >> NCodeDescr;
+   // CodeDescript.resize(NCodeDescr);
+   // table.getline(buffer,256);
+   // for(int i=0;i<NCodeDescr;i++){
+   //    table.getline(buffer,256);
+   //    CodeDescript[i] = buffer;
+   //    //      StripWhitespace(CodeDescript[i]);
+   // }
+   if ( fVersionRead>=24000 ) fastNLOTools::ReadUnused(table);
 }
 
 
 //________________________________________________________________________________________________________________ //
 void fastNLOCoeffBase::EndReadCoeff(istream& table){
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      say::error["ReadBase"]<<"Did not find final magic number, aborting!"<<endl;
-      say::error["ReadBase"]<<"Please check compatibility of tables and program version!"<<endl;
-      say::error["ReadBase"]<<"This might also be provoked by lines with unexpected non-numeric content like 'inf' or 'nan'!"<<endl;
-      exit(1);
-   }
+   fastNLOTools::ReadMagicNo(table);
+   // if (!fastNLOTools::ReadMagicNo(table)) {
+   //    say::error["ReadBase"]<<"Did not find final magic number, aborting!"<<endl;
+   //    say::error["ReadBase"]<<"Please check compatibility of tables and program version!"<<endl;
+   //    say::error["ReadBase"]<<"This might also be provoked by lines with unexpected non-numeric content like 'inf' or 'nan'!"<<endl;
+   //    exit(1);
+   // }
    fastNLOTools::PutBackMagicNo(table);
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffBase::Write(ostream& table) {
-   say::debug["Write"]<<"Writing fastNLOCoeffBase."<<endl;
-   table << tablemagicno << endl;
-   table << IXsectUnits << endl;
-   table << IDataFlag << endl;
-   table << IAddMultFlag << endl;
-   table << IContrFlag1 << endl;
-   table << IContrFlag2 << endl;
-   table << NScaleDep << endl;
-   table << CtrbDescript.size() << endl;
+void fastNLOCoeffBase::Write(ostream& table, int itabversion) {
+   say::debug["Write"]<<"Writing fastNLOCoeffBase for table version " << itabversion << "." << endl;
+   table << fastNLO::tablemagicno << sep;
+   if ( itabversion >= 24000 ) table << fastNLO::tabversion << sep;
+   if ( itabversion >= 24000 ) table << "fastNLO_CoeffAddBase" << sep;
+   if ( itabversion >= 24000 ) table << 0 << sep; // v2.4, but yet unused
+   table << IXsectUnits << sep;
+   table << IDataFlag << sep;
+   table << IAddMultFlag << sep;
+   table << IContrFlag1 << sep;
+   table << IContrFlag2 << sep;
+   table << NScaleDep << sep;
    //printf("  *  fastNLOCoeffBase::Write().  IDataFlag: %d, IAddMultFlag: %d, IContrFlag1: %d, IContrFlag2: %d, NScaleDep: %d\n",
    //IDataFlag,IAddMultFlag,IContrFlag1,IContrFlag2,NScaleDep);
-   for(unsigned int i=0;i<CtrbDescript.size();i++){
-      table << CtrbDescript[i] << endl;
-   }
-   table << CodeDescript.size() << endl;
-   for(unsigned int i=0;i<CodeDescript.size();i++){
-      table << CodeDescript[i] << endl;
-   }
+   fastNLOTools::WriteFlexibleVector(CtrbDescript,table);
+   fastNLOTools::WriteFlexibleVector(CodeDescript,table);
+   if ( itabversion >= 24000 ) table << 0 << sep; // v2.4, but yet unuse
 }
 
 
@@ -146,8 +144,8 @@ bool fastNLOCoeffBase::IsCompatible(const fastNLOCoeffBase& other) const {
          // continue;
       }
       else {
-	 warn["IsCompatible"]<<"Incompatible NScaleDep found!()"<<endl;
-	 return false;
+         warn["IsCompatible"]<<"Incompatible NScaleDep found!()"<<endl;
+         return false;
       }
    }
    debug["IsCompatible"]<<"Both tables are compatible"<<endl;
@@ -159,6 +157,40 @@ bool fastNLOCoeffBase::IsCompatible(const fastNLOCoeffBase& other) const {
 }
 
 
+//________________________________________________________________________________________________________________ //
+bool fastNLOCoeffBase::IsCatenable(const fastNLOCoeffBase& other) const {
+   if( IXsectUnits != other.GetIXsectUnits() ){
+      debug["IsCatenable"]<<"IXsectUnits != other.GetIXsectUnits(). Skipped."<<endl;
+      return false;
+   }
+   if( IDataFlag != other.GetIDataFlag() ){
+      debug["IsCatenable"]<<"IDataFlag != other.GetIDataFlag(). Skipped."<<endl;
+      return false;
+   }
+   if( IAddMultFlag != other.GetIAddMultFlag() ){
+      debug["IsCatenable"]<<"IAddMultFlag != other.GetIAddMultFlag(). Skipped."<<endl;
+      return false;
+   }
+   if( IContrFlag1 != other.GetIContrFlag1() ){
+      debug["IsCatenable"]<<"IContrFlag1 != other.GetIContrFlag1(). Skipped."<<endl;
+      return false;
+   }
+   if( IContrFlag2 != other.GetIContrFlag2() ){
+      debug["IsCatenable"]<<"IContrFlag2 != other.GetIContrFlag2(). Skipped."<<endl;
+      return false;
+   }
+   if( NScaleDep != other.GetNScaleDep() ){
+      debug["IsCatenable"]<<"NScaleDep != other.GetNScaleDep(). Skipped."<<endl;
+      return false;
+   }
+   info["IsCatenable"]<<"Base parameters of contribution allow catenation"<<endl;
+   // check descripts here ?!
+   //bool potentialcompatible = true;
+   //vector < string > CtrbDescript;
+   //vector < string > CodeDescript;
+   return true;
+}
+
 //________________________________________________________________________________________________________________ //
 
 
@@ -172,22 +204,46 @@ void fastNLOCoeffBase::SetCoeffAddDefaults(){
 };
 
 //________________________________________________________________________________________________________________ //
+void fastNLOCoeffBase::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffBase " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffBase " << fastNLO::_CSEP20 << endl;
+   }
+   fastNLOTools::PrintVector(CtrbDescript,"Contribution description (CtrbDescript)","#");
+   fastNLOTools::PrintVector(CodeDescript,"Code description (CodeDescript)","#");
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      printf(" #   IXsectUnits                       %d\n",IXsectUnits);
+      printf(" #   IDataFlag                         %d\n",IDataFlag);
+      printf(" #   IAddMultFlag                      %d\n",IAddMultFlag);
+      printf(" #   IContrFlag1                       %d\n",IContrFlag1);
+      printf(" #   IContrFlag2                       %d\n",IContrFlag2);
+      printf(" #   NScaleDep                         %d\n",NScaleDep);
+   }
+   if ( iprint < 0 ) {
+      cout << fastNLO::_CSEPSC << endl;
+   } else {
+      //      cout << fastNLO::_DSEPSC << endl;
+   }
+}
 
 
-void fastNLOCoeffBase::Print() const {
-  printf("\n **************** FastNLO Table: CoeffBase ****************\n");
-  printf(" B   Scenario::GetNObsBin()        %d\n",fNObsBins);
-  printf(" B   IXsectUnits                   %d\n",IXsectUnits);
-  printf(" B   IDataFlag                     %d\n",IDataFlag);
-  printf(" B   IAddMultFlag                  %d\n",IAddMultFlag);
-  printf(" B   IContrFlag1                   %d\n",IContrFlag1);
-  printf(" B   IContrFlag2                   %d\n",IContrFlag2);
-  printf(" B   NScaleDep                     %d\n",NScaleDep);
-  fastNLOTools::PrintVector(CtrbDescript,"CtrbDescript","B");
-  fastNLOTools::PrintVector(CodeDescript,"CodeDescript","B");
-  printf(" *******************************************************\n");
+//________________________________________________________________________________________________________________ //
 
+// Erase observable bin
+void fastNLOCoeffBase::EraseBin(unsigned int iObsIdx) {
+   debug["fastNLOCoeffBase::EraseBin"]<<"Erasing table entries in CoeffBase for bin index " << iObsIdx << endl;
+   SetNObsBin(GetNObsBin()-1);
 }
 
+// Catenate observable bin
+void fastNLOCoeffBase::CatBin(const fastNLOCoeffBase& other, unsigned int iObsIdx) {
+   debug["fastNLOCoeffBase::CatBin"]<<"Catenating observable bin in CoeffBase corresponding to bin index " << iObsIdx << endl;
+   SetNObsBin(GetNObsBin()+1);
+}
 
-//________________________________________________________________________________________________________________ //
+// Multiply observable bin
+void fastNLOCoeffBase::MultiplyBin(unsigned int iObsIdx, double nfact) {
+   debug["fastNLOCoeffBase::MultiplyBin"]<<"Multiplying table entries. Nothing to be done in CoeffBase." << endl;
+}
diff --git a/FastNLO/src/fastNLOCoeffData.cc b/FastNLO/src/fastNLOCoeffData.cc
index f0ed82fa6168065f6489fd264e187cbc5f5731aa..d52363e9c50cadd976cb47b4063ba390cf4c94ca 100644
--- a/FastNLO/src/fastNLOCoeffData.cc
+++ b/FastNLO/src/fastNLOCoeffData.cc
@@ -3,44 +3,41 @@
 #include <cmath>
 
 #include "fastnlotk/fastNLOCoeffData.h"
+#include "fastnlotk/fastNLOTools.h"
 
 using namespace std;
 using namespace fastNLO;
 
 
 //________________________________________________________________________________________________________________ //
-bool fastNLOCoeffData::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet) {
-   if ( c->GetIDataFlag() == 1 ) return true;
-   else {
-      if ( !quiet )
-	 say::error["fastNLOCoeffData::CheckCoeffConstants"]<<"This is not a data table! IDataFlag="<<c->GetIDataFlag()<<", but must be 1."<<endl;
-      return false;
-   }
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffData::fastNLOCoeffData(){
+fastNLOCoeffData::fastNLOCoeffData(int NObsBin)
+   : fastNLOCoeffBase(NObsBin), Nuncorrel(), UncDescr(), Ncorrel(), CorDescr(), Xcenter(), Value(),
+     UncorLo(), UncorHi(), CorrLo(), CorrHi(), NErrMatrix(), matrixelement() {
    SetClassName("fastNLOCoeffData");
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffData::fastNLOCoeffData(int NObsBin) : fastNLOCoeffBase(NObsBin) {
+fastNLOCoeffData::fastNLOCoeffData(const fastNLOCoeffBase& base) : fastNLOCoeffBase(base) {
    SetClassName("fastNLOCoeffData");
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffData::fastNLOCoeffData(const fastNLOCoeffBase& base) : fastNLOCoeffBase(base) {
-   SetClassName("fastNLOCoeffData");
+bool fastNLOCoeffData::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet) {
+   if ( c->GetIDataFlag() == 1 ) return true;
+   else {
+      if ( !quiet )
+         say::info["fastNLOCoeffData::CheckCoeffConstants"]<<"This is not a data table! IDataFlag="<<c->GetIDataFlag()<<", but must be 1."<<endl;
+      return false;
+   }
 }
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffBase* fastNLOCoeffData::Clone() const {
+fastNLOCoeffData* fastNLOCoeffData::Clone() const {
    //! Use has to take care to delete this object later
-   return static_cast<fastNLOCoeffBase*>(new fastNLOCoeffData(*this));
+   return new fastNLOCoeffData(*this);
 }
 
 
@@ -91,14 +88,14 @@ void fastNLOCoeffData::ReadCoeffData(istream& table){
       UncorLo[i].resize(Nuncorrel);
       UncorHi[i].resize(Nuncorrel);
       for(int j=0;j<Nuncorrel;j++){
-	 table >> UncorLo[i][j];
-	 table >> UncorHi[i][j];
+         table >> UncorLo[i][j];
+         table >> UncorHi[i][j];
       }
       CorrLo[i].resize(Ncorrel);
       CorrHi[i].resize(Ncorrel);
       for(int j=0;j<Ncorrel;j++){
-	 table >> CorrLo[i][j];
-	 table >> CorrHi[i][j];
+         table >> CorrLo[i][j];
+         table >> CorrHi[i][j];
       }
    }
    table >> NErrMatrix;
@@ -106,57 +103,161 @@ void fastNLOCoeffData::ReadCoeffData(istream& table){
    for(int i=0;i<NErrMatrix;i++){
       matrixelement[i].resize((int)pow((double)fNObsBins,2));
       for(int j=0;j<(int)pow((double)fNObsBins,2);j++){
-	 table >> matrixelement[i][j];
+         table >> matrixelement[i][j];
       }
    }
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffData::Write(ostream& table) {
-   fastNLOCoeffBase::Write(table);
+void fastNLOCoeffData::Write(ostream& table, int itabversion) {
+   fastNLOCoeffBase::Write(table,itabversion);
    CheckCoeffConstants(this);
 
    //if(IDataFlag==1){
-   table << Nuncorrel << endl;
+   table << Nuncorrel << sep;
    for(int i=0;i<Nuncorrel;i++){
-      table << UncDescr[i] << endl;
+      table << UncDescr[i] << sep;
    }
-   table << Ncorrel << endl;
+   table << Ncorrel << sep;
    for(int i=0;i<Ncorrel;i++){
-      table << CorDescr[i]  << endl;
+      table << CorDescr[i]  << sep;
    }
    for(int i=0;i<fNObsBins;i++){
-      table << Xcenter[i] << endl;
-      table << Value[i] << endl;
+      table << Xcenter[i] << sep;
+      table << Value[i] << sep;
       for(int j=0;j<Nuncorrel;j++){
-	 table << UncorLo[i][j] << endl;
-	 table << UncorHi[i][j] << endl;
+         table << UncorLo[i][j] << sep;
+         table << UncorHi[i][j] << sep;
       }
       for(int j=0;j<Ncorrel;j++){
-	 table << CorrLo[i][j] << endl;
-	 table << CorrHi[i][j] << endl;
+         table << CorrLo[i][j] << sep;
+         table << CorrHi[i][j] << sep;
       }
    }
-   table << NErrMatrix << endl;
+   table << NErrMatrix << sep;
    for(int i=0;i<NErrMatrix;i++){
       for(int j=0;j<(int)pow((double)fNObsBins,2);j++){
-	 table << matrixelement[i][j] << endl;
+         table << matrixelement[i][j] << sep;
+      }
+   }
+}
+
+
+//________________________________________________________________________________________________________________ //
+void fastNLOCoeffData::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      fastNLOCoeffBase::Print(iprint);
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffData " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffData " << fastNLO::_CSEP20 << endl;
+   }
+   printf(" # No. of uncorr. unc. (Nuncorrel)     %d\n",Nuncorrel);
+   if (Nuncorrel > 0) {fastNLOTools::PrintVector(UncDescr,"Uncorr. uncertainties (UncDescr)","#");}
+   printf(" # No. of corr. unc. (Ncorrel)         %d\n",Ncorrel);
+   if (Ncorrel > 0) {fastNLOTools::PrintVector(CorDescr,"Corr. uncertainties (CorDescr)","#");}
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      fastNLOTools::PrintVector(Xcenter,"Data bin centers (Xcenter)","#  ");
+      fastNLOTools::PrintVector(Value,"Data values (Value)","#  ");
+   }
+   if ( abs(iprint) > 1 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 1) " << fastNLO::_SSEP20 << endl;
+      for (int i=0; i<fNObsBins; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==fNObsBins-1) {
+            printf(" #     Observable bin no. %d\n",i+1);
+            if (Nuncorrel > 0) {
+               fastNLOTools::PrintVector(UncorLo[i],"Lower uncorr. uncertainties (UncorLo)","#    ");
+               fastNLOTools::PrintVector(UncorHi[i],"Upper uncorr. uncertainties (UncorHi)","#    ");
+            }
+            if (Ncorrel > 0) {
+               fastNLOTools::PrintVector(CorrLo[i],"Lower corr. uncertainties (CorrLo)","#    ");
+               fastNLOTools::PrintVector(CorrHi[i],"Upper corr. uncertainties (CorrHi)","#    ");
+            }
+         }
       }
    }
+   cout << fastNLO::_CSEPSC << endl;
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffData::Print() const {
-   fastNLOCoeffBase::Print();
-   printf("\n **************** FastNLO Table: CoeffData ****************\n\n");
-   printf(" B   Nuncorrel                     %d\n",Nuncorrel);
-   printf(" B   Ncorrel                       %d\n",Ncorrel);
-   printf(" B   NErrMatrix                    %d\n",NErrMatrix);
-   printf(" B   fastNLOCoeffData::Print(). some more output could be printed here (IDataFlag==1).\n");
-   printf("\n *******************************************************\n\n");
+
+// Erase observable bin
+void fastNLOCoeffData::EraseBin(unsigned int iObsIdx) {
+   debug["fastNLOCoeffData::EraseBin"]<<"Erasing table entries in CoeffData for bin index " << iObsIdx << endl;
+   if ( Value.size() == 0 ) {
+      say::error["EraseBin"]<<"All data bins deleted already. Aborted!" << endl;
+      exit(1);
+   }
+   if ( Xcenter.size() != 0 ) Xcenter.erase(Xcenter.begin()+iObsIdx);
+   if ( Value.size() != 0 ) Value.erase(Value.begin()+iObsIdx);
+   if ( UncorLo.size() != 0 ) UncorLo.erase(UncorLo.begin()+iObsIdx);
+   if ( UncorHi.size() != 0 ) UncorHi.erase(UncorHi.begin()+iObsIdx);
+   if ( CorrLo.size() != 0 ) CorrLo.erase(CorrLo.begin()+iObsIdx);
+   if ( CorrHi.size() != 0 ) CorrHi.erase(CorrHi.begin()+iObsIdx);
+   fastNLOCoeffBase::EraseBin(iObsIdx);
 }
 
+// Catenate observable bin
+void fastNLOCoeffData::CatBin(const fastNLOCoeffData& other, unsigned int iObsIdx) {
+   debug["fastNLOCoeffData::CatBin"]<<"Catenating observable bin in CoeffData corresponding to bin index " << iObsIdx << endl;
+   if ( Value.size() == 0 ) {
+      say::error["CatBin"]<<"Initial data table is empty. Aborted!" << endl;
+      exit(1);
+   }
+   unsigned int nold = Value.size();
+   if ( Xcenter.size() != 0 ) {
+      Xcenter.resize(nold+1);
+      Xcenter[nold] = other.Xcenter[iObsIdx];
+   }
+   if ( Value.size() != 0 ) {
+      Value.resize(nold+1);
+      Value[nold] = other.Value[iObsIdx];
+   }
+   if ( UncorLo.size() != 0 ) {
+      UncorLo.resize(nold+1);
+      UncorLo[nold] = other.UncorLo[iObsIdx];
+   }
+   if ( UncorHi.size() != 0 ) {
+      UncorHi.resize(nold+1);
+      UncorHi[nold] = other.UncorHi[iObsIdx];
+   }
+   if ( CorrLo.size() != 0 ) {
+      CorrLo.resize(nold+1);
+      CorrLo[nold] = other.CorrLo[iObsIdx];
+   }
+   if ( CorrHi.size() != 0 ) {
+      CorrHi.resize(nold+1);
+      CorrHi[nold] = other.CorrHi[iObsIdx];
+   }
+   fastNLOCoeffBase::CatBin(other, iObsIdx);
+}
+
+// Multiply observable bin
+void fastNLOCoeffData::MultiplyBin(unsigned int iObsIdx, double fact) {
+   debug["fastNLOCoeffData::MultiplyBin"]<<"Multiplying table entries in CoeffData for bin index " << iObsIdx << " by factor " << fact << endl;
+   Value[iObsIdx] *= fact;
+   fastNLOCoeffBase::MultiplyBin(iObsIdx, fact);
+}
 
 //________________________________________________________________________________________________________________ //
+bool fastNLOCoeffData::IsCatenable(const fastNLOCoeffData& other) const {
+   //! Check for compatibility of catenating observable bins
+   if ( ! ((fastNLOCoeffBase*)this)->IsCatenable(other)) return false;
+   if( Nuncorrel != other.GetNuncorrel() ){
+      debug["IsCatenable"]<<"Nuncorrel != other.GetNuncorrel(). Skipped."<<endl;
+      return false;
+   }
+   if( Ncorrel != other.GetNcorrel() ){
+      debug["IsCatenable"]<<"Ncorrel != other.GetNcorrel(). Skipped."<<endl;
+      return false;
+   }
+   if( NErrMatrix != other.GetNErrMatrix() ){
+      debug["IsCatenable"]<<"NErrMatrix != other.GetNErrMatrix(). Skipped."<<endl;
+      return false;
+   }
+   info["IsCatenable"]<<"Data contributions are catenable"<<endl;
+   return true;
+}
diff --git a/FastNLO/src/fastNLOCoeffMult.cc b/FastNLO/src/fastNLOCoeffMult.cc
index 2db5d014270ae96729c5394a1d31a02be28bf7d5..65fff484735c09aae12dfd9ab97eb92d5602850e 100644
--- a/FastNLO/src/fastNLOCoeffMult.cc
+++ b/FastNLO/src/fastNLOCoeffMult.cc
@@ -1,13 +1,29 @@
+#include <algorithm>
 #include <cstdlib>
 #include <iostream>
 #include <cmath>
 
 #include "fastnlotk/fastNLOCoeffMult.h"
+#include "fastnlotk/fastNLOTools.h"
 
 using namespace std;
 using namespace fastNLO;
 
 
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffMult::fastNLOCoeffMult(int NObsBin)
+   : fastNLOCoeffBase(NObsBin), Nuncorrel(), UncDescr(), Ncorrel(), CorDescr(),
+     UncorLo(), UncorHi(), CorrLo(), CorrHi(), fact() {
+   SetClassName("fastNLOCoeffMult");
+}
+
+
+//________________________________________________________________________________________________________________ //
+fastNLOCoeffMult::fastNLOCoeffMult(const fastNLOCoeffBase& base) : fastNLOCoeffBase(base) {
+   SetClassName("fastNLOCoeffMult");
+}
+
+
 //________________________________________________________________________________________________________________ //
 bool fastNLOCoeffMult::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet)  {
    if ( c->GetIAddMultFlag()==0 && c->GetIDataFlag()==0 ) {
@@ -31,28 +47,9 @@ bool fastNLOCoeffMult::CheckCoeffConstants(const fastNLOCoeffBase* c, bool quiet
 
 
 //________________________________________________________________________________________________________________ //
-fastNLOCoeffMult::fastNLOCoeffMult(){
-   SetClassName("fastNLOCoeffMult");
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffMult::fastNLOCoeffMult(int NObsBin) : fastNLOCoeffBase(NObsBin){
-   SetClassName("fastNLOCoeffMult");
-   fNObsBins = NObsBin;
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffMult::fastNLOCoeffMult(const fastNLOCoeffBase& base) : fastNLOCoeffBase(base) {
-   SetClassName("fastNLOCoeffMult");
-}
-
-
-//________________________________________________________________________________________________________________ //
-fastNLOCoeffBase* fastNLOCoeffMult::Clone() const {
+fastNLOCoeffMult* fastNLOCoeffMult::Clone() const {
    //! Use has to take care to delete this object later
-   return static_cast<fastNLOCoeffBase*>(new fastNLOCoeffMult(*this));
+   return new fastNLOCoeffMult(*this);
 }
 
 
@@ -115,40 +112,136 @@ void fastNLOCoeffMult::ReadCoeffMult(istream& table){
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffMult::Write(ostream& table) {
-   fastNLOCoeffBase::Write(table);
+void fastNLOCoeffMult::Write(ostream& table, int itabversion) {
+   fastNLOCoeffBase::Write(table,itabversion);
    CheckCoeffConstants(this);
-   table << Nuncorrel << endl;
+   table << Nuncorrel << sep;
    for(int i=0;i<Nuncorrel;i++){
-      table << UncDescr[i]  << endl;
+      table << UncDescr[i]  << sep;
    }
-   table << Ncorrel << endl;
+   table << Ncorrel << sep;
    for(int i=0;i<Ncorrel;i++){
-      table << CorDescr[i]  << endl;
+      table << CorDescr[i]  << sep;
    }
    for(int i=0;i<fNObsBins;i++){
-      table << fact[i] << endl;
+      table << fact[i] << sep;
       for(int j=0;j<Nuncorrel;j++){
-         table << UncorLo[i][j] << endl;
-         table << UncorHi[i][j] << endl;
+         table << UncorLo[i][j] << sep;
+         table << UncorHi[i][j] << sep;
       }
       for(int j=0;j<Ncorrel;j++){
-         table << CorrLo[i][j] << endl;
-         table << CorrHi[i][j] << endl;
+         table << CorrLo[i][j] << sep;
+         table << CorrHi[i][j] << sep;
       }
    }
 }
 
 
 //________________________________________________________________________________________________________________ //
-void fastNLOCoeffMult::Print() const {
-  printf(" **************** FastNLO Table: CoeffMult ****************\n");
-  fastNLOCoeffBase::Print();
-  if(IAddMultFlag==1){
-    printf(" B   fastNLOCoeffMult::Print(). Printing of multiplicative factors not yet implemented (IAddMultFlag==1).\n");
-  }
-  printf(" *******************************************************\n");
+void fastNLOCoeffMult::Print(int iprint) const {
+   if ( !(iprint < 0) ) {
+      fastNLOCoeffBase::Print(iprint);
+      cout << fastNLO::_DSEP20C << " fastNLO Table: CoeffMult " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: CoeffMult " << fastNLO::_CSEP20 << endl;
+   }
+   double minfact = *min_element(fact.begin(),fact.end());
+   double maxfact = *max_element(fact.begin(),fact.end());
+   printf(" # Minimal correction factor (fact[])  %f\n",minfact);
+   printf(" # Maximal correction factor (fact[])  %f\n",maxfact);
+   printf(" # No. of uncorr. unc. (Nuncorrel)     %d\n",Nuncorrel);
+   if (Nuncorrel > 0) {fastNLOTools::PrintVector(UncDescr,"Uncorr. uncertainties (UncDescr)","#");}
+   printf(" # No. of corr. unc. (Ncorrel)         %d\n",Ncorrel);
+   if (Ncorrel > 0) {fastNLOTools::PrintVector(CorDescr,"Corr. uncertainties (CorDescr)","#");}
+   if ( abs(iprint) > 1 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 1) " << fastNLO::_SSEP20 << endl;
+      fastNLOTools::PrintVector(fact,"Correction factors (fact)","#    ");
+   }
+   if ( abs(iprint) > 2 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 2) " << fastNLO::_SSEP20 << endl;
+      for (int i=0; i<fNObsBins; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==fNObsBins-1) {
+            printf(" #       Observable bin no. %d\n",i+1);
+            if (Nuncorrel > 0) {
+               fastNLOTools::PrintVector(UncorLo[i],"Lower uncorr. uncertainties (UncorLo)","#      ");
+               fastNLOTools::PrintVector(UncorHi[i],"Upper uncorr. uncertainties (UncorHi)","#      ");
+            }
+            if (Ncorrel > 0) {
+               fastNLOTools::PrintVector(CorrLo[i],"Lower corr. uncertainties (CorrLo)","#      ");
+               fastNLOTools::PrintVector(CorrHi[i],"Upper corr. uncertainties (CorrHi)","#      ");
+            }
+         }
+      }
+   }
+   cout << fastNLO::_CSEPSC << endl;
+}
+
+
+//________________________________________________________________________________________________________________ //
+// Erase observable bin
+void fastNLOCoeffMult::EraseBin(unsigned int iObsIdx) {
+   debug["fastNLOCoeffMult::EraseBin"]<<"Erasing table entries in CoeffMult for bin index " << iObsIdx << endl;
+   if ( fact.size() == 0 ) {
+      say::error["EraseBin"]<<"All multiplicative bins deleted already. Aborted!" << endl;
+      exit(1);
+   }
+   if ( fact.size() != 0 ) fact.erase(fact.begin()+iObsIdx);
+   if ( UncorLo.size() != 0 ) UncorLo.erase(UncorLo.begin()+iObsIdx);
+   if ( UncorHi.size() != 0 ) UncorHi.erase(UncorHi.begin()+iObsIdx);
+   if ( CorrLo.size() != 0 ) CorrLo.erase(CorrLo.begin()+iObsIdx);
+   if ( CorrHi.size() != 0 ) CorrHi.erase(CorrHi.begin()+iObsIdx);
+   fastNLOCoeffBase::EraseBin(iObsIdx);
+}
+
+// Catenate observable bin
+void fastNLOCoeffMult::CatBin(const fastNLOCoeffMult& other, unsigned int iObsIdx) {
+   debug["fastNLOCoeffMult::CatBin"]<<"Catenating observable bin in CoeffMult corresponding to bin index " << iObsIdx << endl;
+   if ( fact.size() == 0 ) {
+      say::error["CatBin"]<<"Initial multiplicative table is empty. Aborted!" << endl;
+      exit(1);
+   }
+   unsigned int nold = fact.size();
+   if ( fact.size() != 0 ) {
+      fact.resize(nold+1);
+      fact[nold] = other.fact[iObsIdx];
+   }
+   if ( UncorLo.size() != 0 ) {
+      UncorLo.resize(nold+1);
+      UncorLo[nold] = other.UncorLo[iObsIdx];
+   }
+   if ( UncorHi.size() != 0 ) {
+      UncorHi.resize(nold+1);
+      UncorHi[nold] = other.UncorHi[iObsIdx];
+   }
+   if ( CorrLo.size() != 0 ) {
+      CorrLo.resize(nold+1);
+      CorrLo[nold] = other.CorrLo[iObsIdx];
+   }
+   if ( CorrHi.size() != 0 ) {
+      CorrHi.resize(nold+1);
+      CorrHi[nold] = other.CorrHi[iObsIdx];
+   }
+   fastNLOCoeffBase::CatBin(other, iObsIdx);
 }
 
+// Multiply observable bin
+void fastNLOCoeffMult::MultiplyBin(unsigned int iObsIdx, double nfact) {
+   debug["fastNLOCoeffMult::MultiplyBin"]<<"Multiplying table entries. Nothing to be done in CoeffMult." << endl;
+}
 
 //________________________________________________________________________________________________________________ //
+bool fastNLOCoeffMult::IsCatenable(const fastNLOCoeffMult& other) const {
+   //! Check for compatibility of catenating observable bins
+   if ( ! ((fastNLOCoeffBase*)this)->IsCatenable(other)) return false;
+   if( Nuncorrel != other.GetNuncorrel() ){
+      debug["IsCatenable"]<<"Nuncorrel != other.GetNuncorrel(). Skipped."<<endl;
+      return false;
+   }
+   if( Ncorrel != other.GetNcorrel() ){
+      debug["IsCatenable"]<<"Ncorrel != other.GetNcorrel(). Skipped."<<endl;
+      return false;
+   }
+   info["IsCatenable"]<<"Multiplicable contributions are catenable"<<endl;
+   return true;
+}
diff --git a/FastNLO/src/fastNLOCoefficients.cc b/FastNLO/src/fastNLOCoefficients.cc
index 15f3bce25e1bc337dcce3624441552261c51adcf..b9f74320d45997a495d43d349d17f46c11dbc4f3 100644
--- a/FastNLO/src/fastNLOCoefficients.cc
+++ b/FastNLO/src/fastNLOCoefficients.cc
@@ -367,14 +367,14 @@ int fastNLOCoefficients::Read(istream *table){
 }
 
 int fastNLOCoefficients::Write(ostream *table, int option){
-   *table << tablemagicno << endl;
-   *table << IXsectUnits << endl;
-   *table << IDataFlag << endl;
-   *table << IAddMultFlag << endl;
-   *table << IContrFlag1 << endl;
-   *table << IContrFlag2 << endl;
+   *table << tablemagicno << sep;
+   *table << IXsectUnits << sep;
+   *table << IDataFlag << sep;
+   *table << IAddMultFlag << sep;
+   *table << IContrFlag1 << sep;
+   *table << IContrFlag2 << sep;
    //KR: IContrFlag3 replaced by NScaleDep
-   //*table << IContrFlag3 << endl;     // v2.0+. for v2.1 write IContrFlag3 here, but NScaleDep only later
+   //*table << IContrFlag3 << sep;     // v2.0+. for v2.1 write IContrFlag3 here, but NScaleDep only later
    if ( NScaleDep==3 ) {
       if ( Npow==fILOord) {
          cout<<" * Increase NScaleDep from 3 to 4, because LO!"<<endl;
@@ -385,93 +385,93 @@ int fastNLOCoefficients::Write(ostream *table, int option){
          NScaleDep=5;
       }
    }
-   *table << NScaleDep << endl;
-   *table << CtrbDescript.size() << endl;
+   *table << NScaleDep << sep;
+   *table << CtrbDescript.size() << sep;
    //printf("  *  fastNLOCoefficients::Write().  IDataFlag: %d, IAddMultFlag: %d, IContrFlag1: %d, IContrFlag2: %d, NScaleDep: %d\n",
    //IDataFlag,IAddMultFlag,IContrFlag1,IContrFlag2,NScaleDep);
    for(unsigned int i=0;i<CtrbDescript.size();i++){
-      *table << CtrbDescript[i] << endl;
+      *table << CtrbDescript[i] << sep;
    }
-   *table << CodeDescript.size() << endl;
+   *table << CodeDescript.size() << sep;
    for(unsigned int i=0;i<CodeDescript.size();i++){
-      *table << CodeDescript[i] << endl;
+      *table << CodeDescript[i] << sep;
    }
 
    if(IDataFlag==1){
-      *table << Nuncorrel << endl;
+      *table << Nuncorrel << sep;
       for(int i=0;i<Nuncorrel;i++){
-         *table << UncDescr[i] << endl;
+         *table << UncDescr[i] << sep;
       }
-      *table << Ncorrel << endl;
+      *table << Ncorrel << sep;
       for(int i=0;i<Ncorrel;i++){
-         *table << CorDescr[i]  << endl;
+         *table << CorDescr[i]  << sep;
       }
       for(int i=0;i<fNObsBins;i++){
-         *table << Xcenter[i] << endl;
-         *table << Value[i] << endl;
+         *table << Xcenter[i] << sep;
+         *table << Value[i] << sep;
          for(int j=0;j<Nuncorrel;j++){
-            *table << UncorLo[i][j] << endl;
-            *table << UncorHi[i][j] << endl;
+            *table << UncorLo[i][j] << sep;
+            *table << UncorHi[i][j] << sep;
          }
          for(int j=0;j<Ncorrel;j++){
-            *table << CorrLo[i][j] << endl;
-            *table << CorrHi[i][j] << endl;
+            *table << CorrLo[i][j] << sep;
+            *table << CorrHi[i][j] << sep;
          }
       }
-      *table << NErrMatrix << endl;
+      *table << NErrMatrix << sep;
       for(int i=0;i<NErrMatrix;i++){
          for(int j=0;j<(int)pow((double)fNObsBins,2);j++){
-            *table << matrixelement[i][j] << endl;
+            *table << matrixelement[i][j] << sep;
          }
       }
    }// end of IDataFlag==1
 
    cout<<" 3"<<endl;
    if(IAddMultFlag==1){
-      *table << Nuncorrel << endl;
+      *table << Nuncorrel << sep;
       for(int i=0;i<Nuncorrel;i++){
-         *table << UncDescr[i]  << endl;
+         *table << UncDescr[i]  << sep;
       }
-      *table << Ncorrel << endl;
+      *table << Ncorrel << sep;
       for(int i=0;i<Ncorrel;i++){
-         *table << CorDescr[i]  << endl;
+         *table << CorDescr[i]  << sep;
       }
       for(int i=0;i<fNObsBins;i++){
-         *table << fact[i] << endl;
+         *table << fact[i] << sep;
          for(int j=0;j<Nuncorrel;j++){
-            *table << UncorLo[i][j] << endl;
-            *table << UncorHi[i][j] << endl;
+            *table << UncorLo[i][j] << sep;
+            *table << UncorHi[i][j] << sep;
          }
          for(int j=0;j<Ncorrel;j++){
-            *table << CorrLo[i][j] << endl;
-            *table << CorrHi[i][j] << endl;
+            *table << CorrLo[i][j] << sep;
+            *table << CorrHi[i][j] << sep;
          }
       }
    }// end of IAddMultFlag==1
 
    if(!(IDataFlag==1) && !(IAddMultFlag==1)){
-      *table << IRef << endl;
-      *table << IScaleDep << endl;
-      *table << Nevt << endl;
-      *table << Npow << endl;
-      *table << NPDF << endl;
+      *table << IRef << sep;
+      *table << IScaleDep << sep;
+      *table << Nevt << sep;
+      *table << Npow << sep;
+      *table << NPDF << sep;
       if(NPDF>0){
          for(int i=0;i<NPDF;i++){
-            *table <<  NPDFPDG[i] << endl;
+            *table <<  NPDFPDG[i] << sep;
          }
       }
-      *table << NPDFDim << endl;
-      *table << NFragFunc << endl;
+      *table << NPDFDim << sep;
+      *table << NFragFunc << sep;
     if(NFragFunc>0){
          for(int i=0;i<NFragFunc;i++){
-            *table <<  NFFPDG[i] << endl;
+            *table <<  NFFPDG[i] << sep;
          }
       }
-      *table << NFFDim << endl;
-      *table << NSubproc << endl;
-      *table << IPDFdef1 << endl;
-      *table << IPDFdef2 << endl;
-      *table << IPDFdef3 << endl;
+      *table << NFFDim << sep;
+      *table << NSubproc << sep;
+      *table << IPDFdef1 << sep;
+      *table << IPDFdef2 << sep;
+      *table << IPDFdef3 << sep;
      if(IPDFdef1==0){
          for(int i=0;i<NSubproc;i++){
             // Missing: linear PDF combinations for IPDFdef1=0
@@ -483,52 +483,52 @@ int fastNLOCoefficients::Write(ostream *table, int option){
          }
       }
       for(int i=0;i<fNObsBins;i++){
-         *table << XNode1[i].size() << endl;
+         *table << XNode1[i].size() << sep;
          for(unsigned int j=0;j<XNode1[i].size();j++){
-            *table << XNode1[i][j] << endl;
+            *table << XNode1[i][j] << sep;
          }
       }
       if(NPDFDim==2){
          for(int i=0;i<fNObsBins;i++){
-            *table << XNode2[i].size() << endl;
+            *table << XNode2[i].size() << sep;
             for(unsigned int j=0;j<XNode2[i].size();j++){
-               *table << XNode2[i][j] << endl;
+               *table << XNode2[i][j] << sep;
             }
          }
       }
       cout<<" 10"<<endl;
      if(NFragFunc>0){
          for(int i=0;i<fNObsBins;i++){
-            *table << Nztot[i] << endl;
+            *table << Nztot[i] << sep;
             for(int j=0;j<Nztot[i];j++){
-               *table << ZNode[i][j] << endl;
+               *table << ZNode[i][j] << sep;
             }
          }
       }
-      *table << NScales << endl;
-      *table << NScaleDim << endl;
+      *table << NScales << sep;
+      *table << NScaleDim << sep;
       for(int i=0;i<NScales;i++){
-         *table << Iscale[i] << endl;
+         *table << Iscale[i] << sep;
       }
      for(int i=0;i<NScaleDim;i++){
-         *table << ScaleDescript[i].size() << endl;
+         *table << ScaleDescript[i].size() << sep;
          for(unsigned int j=0;j<ScaleDescript[i].size();j++){
-            *table << ScaleDescript[i][j] << endl;
+            *table << ScaleDescript[i][j] << sep;
          }
       }
 
       //! v2.1 store NScaleDep here
-      //! *table << NScaleDep << endl;
+      //! *table << NScaleDep << sep;
       cout<<"fastNLOCoefficients. Writing coefficients."<<endl;
 
       if ( NScaleDep<3 ){
          for(int i=0;i<NScaleDim;i++){
-            *table << Nscalevar[i] << endl;
-            *table << Nscalenode[i] << endl;
+            *table << Nscalevar[i] << sep;
+            *table << Nscalenode[i] << sep;
          }
          for(int i=0;i<NScaleDim;i++){
             for(int j=0;j<Nscalevar[i];j++){
-               *table << ScaleFac[i][j] << endl;
+               *table << ScaleFac[i][j] << sep;
             }
          }
 
@@ -557,10 +557,10 @@ int fastNLOCoefficients::Write(ostream *table, int option){
          nn3 += WriteFlexibleTable( &SigmaRef_s1        , table , (bool)(option & DividebyNevt) , Nevt , true );
          nn3 += WriteFlexibleTable( &SigmaRef_s2        , table , (bool)(option & DividebyNevt) , Nevt , true );
 
-//       *table << NscalenodeScale1 << endl;
+//       *table << NscalenodeScale1 << sep;
 //       nn3 += WriteTable( &ScaleNode1 , table );
 
-//       *table << NscalenodeScale2 << endl;
+//       *table << NscalenodeScale2 << sep;
 //       nn3 += WriteTable( &ScaleNode2 , table );
 
 //       nn3 += WriteTable( &SigmaTildeMuIndep, table , (bool)(option & DividebyNevt) , Nevt );
@@ -917,9 +917,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<vector<vector<vector<vector<ve
             for(unsigned int i5=0;i5<v->at(i0)[i1][i2][i3][i4].size();i5++){
               for(unsigned int i6=0;i6<v->at(i0)[i1][i2][i3][i4][i5].size();i6++){
                 if( DivByNevt && Nevt>0){
-                  *table << v->at(i0)[i1][i2][i3][i4][i5][i6] / Nevt << endl;
+                  *table << v->at(i0)[i1][i2][i3][i4][i5][i6] / Nevt << sep;
                 }else{
-                  *table << v->at(i0)[i1][i2][i3][i4][i5][i6] << endl;
+                  *table << v->at(i0)[i1][i2][i3][i4][i5][i6] << sep;
                 }
                 nn++;
               }
@@ -942,9 +942,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<vector<vector<vector<vector<do
           for(unsigned int i4=0;i4<v->at(i0)[i1][i2][i3].size();i4++){
             for(unsigned int i5=0;i5<v->at(i0)[i1][i2][i3][i4].size();i5++){
               if( DivByNevt && Nevt>0){
-                *table << v->at(i0)[i1][i2][i3][i4][i5] / Nevt << endl;
+                *table << v->at(i0)[i1][i2][i3][i4][i5] / Nevt << sep;
               }else{
-                *table << v->at(i0)[i1][i2][i3][i4][i5] << endl;
+                *table << v->at(i0)[i1][i2][i3][i4][i5] << sep;
               }
               nn++;
             }
@@ -965,9 +965,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<vector<vector<vector<double >
         for(unsigned int i3=0;i3<v->at(i0)[i1][i2].size();i3++){
           for(unsigned int i4=0;i4<v->at(i0)[i1][i2][i3].size();i4++){
             if( DivByNevt && Nevt>0){
-              *table << v->at(i0)[i1][i2][i3][i4] / Nevt << endl;
+              *table << v->at(i0)[i1][i2][i3][i4] / Nevt << sep;
                 }else{
-              *table << v->at(i0)[i1][i2][i3][i4] << endl;
+              *table << v->at(i0)[i1][i2][i3][i4] << sep;
             }
             nn++;
           }
@@ -986,9 +986,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<vector<vector<double > > > >*
       for(unsigned int i2=0;i2<v->at(i0)[i1].size();i2++){
         for(unsigned int i3=0;i3<v->at(i0)[i1][i2].size();i3++){
           if( DivByNevt && Nevt>0){
-            *table << v->at(i0)[i1][i2][i3] / Nevt << endl;
+            *table << v->at(i0)[i1][i2][i3] / Nevt << sep;
           }else{
-            *table << v->at(i0)[i1][i2][i3] << endl;
+            *table << v->at(i0)[i1][i2][i3] << sep;
           }
           nn++;
         }
@@ -1005,9 +1005,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<vector<double > > >* v, ostrea
     for(unsigned int i1=0;i1<v->at(i0).size();i1++){
       for(unsigned int i2=0;i2<v->at(i0)[i1].size();i2++){
         if( DivByNevt && Nevt>0){
-          *table << v->at(i0)[i1][i2] / Nevt << endl;
+          *table << v->at(i0)[i1][i2] / Nevt << sep;
         }else{
-          *table << v->at(i0)[i1][i2] << endl;
+          *table << v->at(i0)[i1][i2] << sep;
         }
         nn++;
       }
@@ -1022,9 +1022,9 @@ int fastNLOCoefficients::WriteTable(vector<vector<double > >* v, ostream *table
   for(unsigned int i0=0;i0<v->size();i0++){
     for(unsigned int i1=0;i1<v->at(i0).size();i1++){
       if( DivByNevt && Nevt>0){
-        *table << v->at(i0)[i1] / Nevt << endl;
+        *table << v->at(i0)[i1] / Nevt << sep;
       }else{
-        *table << v->at(i0)[i1] << endl;
+        *table << v->at(i0)[i1] << sep;
       }
       nn++;
     }
@@ -1039,9 +1039,9 @@ int fastNLOCoefficients::WriteTable(vector<double >* v, ostream *table , bool Di
   int nn = 0;
   for(unsigned int i0=0;i0<v->size();i0++){
     if( DivByNevt && Nevt>0){
-      *table << v->at(i0) / Nevt << endl;
+      *table << v->at(i0) / Nevt << sep;
     }else{
-      *table << v->at(i0) << endl;
+      *table << v->at(i0) << sep;
     }
     nn++;
   }
@@ -1052,7 +1052,7 @@ int fastNLOCoefficients::WriteTable(vector<double >* v, ostream *table , bool Di
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<vector<vector< double > > > > > > >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1061,7 +1061,7 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<v
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<vector<double > > > > > >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1070,7 +1070,7 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<v
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<double > > > >  >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1079,7 +1079,7 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<vector<d
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<double > >  > >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1088,7 +1088,7 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<vector<double >
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<double > > >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1097,7 +1097,7 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<vector<double > > >* v
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<vector<double > >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   *table << v->size() << endl;
+   *table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
       nn += WriteFlexibleTable( &(v->at(i0)) , table , DivByNevt, Nevt , nProcLast );
    }
@@ -1107,10 +1107,10 @@ int fastNLOCoefficients::WriteFlexibleTable(vector<vector<double > >* v, ostream
 //________________________________________________________________________________________________________________ //
 int fastNLOCoefficients::WriteFlexibleTable(vector<double >* v, ostream *table , bool DivByNevt , int Nevt , bool nProcLast ){
    int nn = 1;
-   if ( !nProcLast )*table << v->size() << endl;
+   if ( !nProcLast )*table << v->size() << sep;
    for(unsigned int i0=0;i0<v->size();i0++){
-      if( DivByNevt && Nevt>0)  *table << v->at(i0) / Nevt << endl;
-      else                      *table << v->at(i0) << endl;
+      if( DivByNevt && Nevt>0)  *table << v->at(i0) / Nevt << sep;
+      else                      *table << v->at(i0) << sep;
       nn++;
    }
    return nn;
diff --git a/FastNLO/src/fastNLOPDFLinearCombinations.cc b/FastNLO/src/fastNLOPDFLinearCombinations.cc
index b32a79a28e598d858990446c846f7cff393bd054..4fd1945d140d4576e899f256872705cd284c7c6b 100644
--- a/FastNLO/src/fastNLOPDFLinearCombinations.cc
+++ b/FastNLO/src/fastNLOPDFLinearCombinations.cc
@@ -63,12 +63,13 @@ vector<double > fastNLOPDFLinearCombinations::CalcPDFLCOneHadron(const fastNLOCo
    bool IsDIS    = ( c->GetIPDFdef1() == 2 );
    bool IsNCDIS  = ( c->GetIPDFdef2() == 1 );
    bool IsProton = ( c->GetPDFPDG(0) == 2212 );
-   if ( IsDIS && IsONEPDF && IsNCDIS && IsProton ) return CalcPDFDIS(c,pdfx1);
+   if ( IsDIS && c->GetIPDFdef2()==0 ) return CalcPDFDISFromTable(c,pdfx1);
+   else if ( IsDIS && IsONEPDF && IsNCDIS && IsProton ) return CalcPDFDIS(c,pdfx1);
    // ---- unknown process ---- //
    else {
       //error["CalcPDFLCDIS"]<<"Could not identify process. Printing and exiting"<<endl;
       say::error<<"Error. Could not identify process. Printing and exiting"<<endl;
-      c->Print();
+      c->Print(-1);
       exit(1);
       return vector<double >();
    }
@@ -117,7 +118,7 @@ vector<double > fastNLOPDFLinearCombinations::CalcPDFLCTwoHadrons(const fastNLOC
       say::error<<"PDFFlag1="<<c->GetIPDFdef1()<<endl;
       say::error<<"PDFFlag2="<<c->GetIPDFdef2()<<endl;
       say::error<<"PDFFlag3="<<c->GetIPDFdef3()<<endl;
-      c->Print();
+      c->Print(-1);
       exit(1);
       return vector<double >();
    }
@@ -205,8 +206,6 @@ vector<double> fastNLOPDFLinearCombinations::CalcDefaultPDFLiCos(const fastNLOCo
 
 
 //______________________________________________________________________________
-
-
 vector<double> fastNLOPDFLinearCombinations::CalcPDFHHCFromTable(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 , const vector<double>& pdfx2) const {
    // calculate PDF linear combinations as stored in table
    if ( c->GetNSubproc() != c->GetIPDFdef3() || c->GetIPDFdef3() != (int)c->GetPDFCoeff().size()) {
@@ -225,6 +224,25 @@ vector<double> fastNLOPDFLinearCombinations::CalcPDFHHCFromTable(const fastNLOCo
 }
 
 
+//______________________________________________________________________________
+vector<double> fastNLOPDFLinearCombinations::CalcPDFDISFromTable(const fastNLOCoeffAddBase* c, const vector<double>& pdfx1 ) const {
+   // calculate PDF linear combinations as stored in table
+   if ( c->GetNSubproc() != c->GetIPDFdef3() || c->GetIPDFdef3() != (int)c->GetPDFCoeff().size()) {
+      say::error["fastNLOPDFLinearCombinations::CalcPDFDISFromTable"]
+         <<"IPDFdef3 must be equal to NSubproc. (IPDFdef3="<<c->GetIPDFdef3()<<", NSubproc="<<c->GetNSubproc()<<"). Exiting."<<endl;
+      exit(1);
+   }
+   const vector<vector<pair<int,int> > >& PDFCoeff = c->GetPDFCoeff();
+   vector < double > pdflc(PDFCoeff.size());
+   for ( unsigned int k = 0 ; k<PDFCoeff.size() ; k++ ){
+      for ( unsigned int i = 0 ; i<PDFCoeff[k].size() ; i++ ){
+         pdflc[k] += pdfx1[PDFCoeff[k][i].first+6];
+      }
+   }
+   return pdflc;
+}
+
+
 //______________________________________________________________________________
 
 
diff --git a/FastNLO/src/fastNLOReader.cc b/FastNLO/src/fastNLOReader.cc
index afe8f1d13d0afff13a4522b2a42359ffec3e7782..689e36fbcd098e9fcfaa7d31fd24a14407013615 100644
--- a/FastNLO/src/fastNLOReader.cc
+++ b/FastNLO/src/fastNLOReader.cc
@@ -6,7 +6,7 @@
 //______________________________________________________________________________
 /**
     --- fastNLO user: Hello!
-        If you use fastNLO for the first time, please read through the
+        When using fastNLO for the first time, please read through the
         documentation and comments carefully in order to calculate
         a reasonable cross section.
         All comments that start with '--- fastNLO user:' are intended as a
@@ -128,7 +128,7 @@
     ---- Table information ---- //
     --- fastNLO user: For a comprehensive insight into the fastNLO variables
         you can use:
-                fnlo.PrintFastNLOTableConstants(0);
+                fnlo.Print(0);
 
 
 
@@ -207,7 +207,7 @@
           - kNonPerturbativeCorrections  -> Non-perturbative corrections|Hadronisation corrections
         plus one must know the 'Id' of this contribution, which can be printed e.g.
         by calling
-           fnlo.PrintTableInfo();
+           fnlo.PrintContributionSummary();
 
         To switch a contribution on/off please use:
                bool SetOn = fnlo.SetContributionON( contrib, Id, on/off )
@@ -315,9 +315,6 @@
         you might use the following print methods:
                 fnlo.PrintCrossSections();
 
-        Or print it like the Fortran reader code:
-                fnlo.PrintCrossSectionsDefault();
-
 
     12.
     ------- Set fastNLOReader verbosity ------- //
@@ -429,7 +426,6 @@
     ---- Example of a cross section calculation with some nice standardized output
     fastNLOLHAPDF fnlo(tablename,"cteq6m.LHpdf",0);
     fnlo.CalcCrossSection();
-    fnlo.PrintCrossSectionsDefault();
 
 */
 //______________________________________________________________________________
@@ -443,6 +439,7 @@
 #include "fastnlotk/fastNLOTools.h"
 #include "fastnlotk/fastNLOCoeffAddFix.h"
 #include "fastnlotk/fastNLOCoeffAddFlex.h"
+//#include "fastnlotk/fastNLOLHAPDF.h"
 #ifdef FNLO_HOPPET
 #include "fastnlotk/HoppetInterface.h"
 #endif
@@ -469,7 +466,7 @@ fastNLOReader::fastNLOReader() : fastNLOTable() {
 fastNLOReader::fastNLOReader(string filename) : fastNLOTable(filename) {
    //SetGlobalVerbosity(DEBUG); // Temporary for debugging
    logger.SetClassName("fastNLOReader");
-   debug["fastNLOReader"]<<"New fastNLOReader reading filename="<<filename<<endl;
+   logger.debug["fastNLOReader"]<<"New fastNLOReader reading filename="<<filename<<endl;
    //fCoeffData           = NULL;
    //    Coeff_LO_Ref         = NULL;
    //    Coeff_NLO_Ref        = NULL;
@@ -483,7 +480,23 @@ fastNLOReader::fastNLOReader(string filename) : fastNLOTable(filename) {
    SetFilename(filename);
 }
 
+//______________________________________________________________________________
 
+fastNLOReader::fastNLOReader(const fastNLOTable& table) : fastNLOTable(table) {
+   //SetGlobalVerbosity(DEBUG); // Temporary for debugging
+   logger.SetClassName("fastNLOReader");
+   //fCoeffData           = NULL;
+   //    Coeff_LO_Ref         = NULL;
+   //    Coeff_NLO_Ref        = NULL;
+   fUnits               = fastNLO::kPublicationUnits;
+   fMuRFunc             = fastNLO::kScale1;
+   fMuFFunc             = fastNLO::kScale1;
+   fPDFSuccess          = false;
+   fAlphasCached        = 0.;
+   fPDFCached           = 0.;
+   fUseHoppet            = false;
+   SetFilename("null");
+}
 //______________________________________________________________________________
 fastNLOReader::~fastNLOReader(void) {
 }
@@ -496,11 +509,13 @@ fastNLOReader::fastNLOReader(const fastNLOReader& other) :
    ffilename(other.ffilename), fScalevar(other.fScalevar), fScaleFacMuR(other.fScaleFacMuR),
    fUnits(other.fUnits), fPDFSuccess(other.fPDFSuccess), fPDFCached(other.fPDFCached),
    fAlphasCached(other.fAlphasCached), Fct_MuR(other.Fct_MuR), Fct_MuF(other.Fct_MuF),
-   bUseSMCalc(other.bUseSMCalc),
-   XSection_LO(other.XSection_LO), XSection(other.XSection), kFactor(other.kFactor),
-   QScale_LO(other.QScale_LO), QScale(other.QScale), XSectionRef(other.XSectionRef),
+   XSection(other.XSection), QScale(other.QScale), XSectionRef(other.XSectionRef),
    XSectionRefMixed(other.XSectionRefMixed), XSectionRef_s1(other.XSectionRef_s1),
    XSectionRef_s2(other.XSectionRef_s2)
+   // XSection_LO(other.XSection_LO), XSection(other.XSection), kFactor(other.kFactor),
+   // QScale_LO(other.QScale_LO), QScale(other.QScale), XSectionRef(other.XSectionRef),
+   // XSectionRefMixed(other.XSectionRefMixed), XSectionRef_s1(other.XSectionRef_s1),
+   // XSectionRef_s2(other.XSectionRef_s2)
 {
    //! Copy constructor
    OrderCoefficients(); // initialize pointers to fCoeff's
@@ -510,7 +525,7 @@ fastNLOReader::fastNLOReader(const fastNLOReader& other) :
 
 //______________________________________________________________________________
 void fastNLOReader::SetFilename(string filename) {
-   debug["SetFilename"]<<"New filename="<<filename<<endl;
+   logger.debug["SetFilename"]<<"New filename="<<filename<<endl;
    ffilename    = filename;
    OrderCoefficients();
    SetCoefficientUsageDefault();
@@ -520,18 +535,18 @@ void fastNLOReader::SetFilename(string filename) {
 
 //______________________________________________________________________________
 void fastNLOReader::OrderCoefficients() {
-   debug["OrderCoefficients"]<<endl;
+   logger.debug["OrderCoefficients"]<<endl;
 
    // Initialize Coeff's
-   fastNLOCoeffBase* Coeff_LO   = NULL;
-   fastNLOCoeffBase* Coeff_NLO  = NULL;
-   fastNLOCoeffBase* Coeff_NNLO = NULL;
-   fastNLOCoeffBase* Coeff_THC1 = NULL;
-   fastNLOCoeffBase* Coeff_THC2 = NULL;
-   fastNLOCoeffBase* Coeff_NPC1 = NULL;
+   fastNLOCoeffBase* Coeff_LO    = NULL;
+   fastNLOCoeffBase* Coeff_NLO   = NULL;
+   fastNLOCoeffBase* Coeff_NNLO  = NULL;
+   fastNLOCoeffBase* Coeff_THC1  = NULL;
+   fastNLOCoeffBase* Coeff_THC2  = NULL;
+   fastNLOCoeffBase* Coeff_NPC1  = NULL;
 
    // run over all coefficient tables, identify and sort contributions.
-   for (unsigned int i= 0; i<fCoeff.size() ; i++ ){
+   for (unsigned int i= 0; i<fCoeff.size() ; i++) {
       fastNLOCoeffBase* c = GetCoeffTable(i);
       // give contribution a reasonable name
       //char nbuf[400];
@@ -540,37 +555,51 @@ void fastNLOReader::OrderCoefficients() {
       //       c->SetName(nbuf);
 
       // data
-      if ( fastNLOCoeffData::CheckCoeffConstants(c,true) ) {
-         debug["OrderCoefficients"]<<"Found data table."<<endl;
+      if (fastNLOCoeffData::CheckCoeffConstants(c,true)) {
+         logger.debug["OrderCoefficients"]<<"Found data table."<<endl;
       }
       // additive contributions
-      else if ( fastNLOCoeffAddBase::CheckCoeffConstants(c,true) ) {
+      else if (fastNLOCoeffAddBase::CheckCoeffConstants(c,true)) {
          // Reference table
-         if ( ((fastNLOCoeffAddBase*)c)->IsReference() ) {
-            debug["OrderCoefficients"]<<"Found reference table."<<endl;
+         if (((fastNLOCoeffAddBase*)c)->IsReference()) {
+            logger.debug["OrderCoefficients"]<<"Found reference table."<<endl;
          }
          // Additive fixed order (perturbative) contribution
-         else if ( c->GetIContrFlag1() == 1 ) {
-            if ( c->IsLO() )            Coeff_LO  = c;
-            else if ( c->IsNLO() )      Coeff_NLO = c;
-            else if ( c->IsNNLO() )     Coeff_NNLO = c;
+         else if (c->GetIContrFlag1() == 1) {
+            if (c->IsLO()) {
+               logger.debug["OrderCoefficients"]<<"Found LO contribution."<<endl;
+               Coeff_LO = c;
+            } else if (c->IsNLO()) {
+               logger.debug["OrderCoefficients"]<<"Found NLO contribution."<<endl;
+               Coeff_NLO = c;
+            } else if (c->IsNNLO()) {
+               logger.debug["OrderCoefficients"]<<"Found NNLO contribution."<<endl;
+               Coeff_NNLO = c;
+            } else {
+               logger.error["OrderCoefficients"]<<"Found unknown fixed-order contribution, aborting!"<<endl;
+               exit(1);
+            }
          }
          // Threshold corrections
-         else if ( c->GetIContrFlag1() == 2 ) {
-            if ( c->GetIContrFlag2() == 1 )             Coeff_THC1 = c;
-            else if ( c->GetIContrFlag2() == 2 )        Coeff_THC2 = c;
-            else {
-               error["OrderCoefficients"]<<"Threshold correction implemented only up to 2-loops, exiting!\n";
+         else if (c->GetIContrFlag1() == 2) {
+            if (c->GetIContrFlag2() == 1) {
+               logger.debug["OrderCoefficients"]<<"Found THC1 contribution."<<endl;
+               Coeff_THC1 = c;
+            } else if (c->GetIContrFlag2() == 2) {
+               logger.debug["OrderCoefficients"]<<"Found THC2 contribution."<<endl;
+               Coeff_THC2 = c;
+            } else {
+               logger.error["OrderCoefficients"]<<"Threshold correction implemented only up to 2-loops, aborting!\n";
                exit(1);
             }
          }
       }
       // multiplicative corrections
-      else if ( fastNLOCoeffMult::CheckCoeffConstants(c,true) ) {
+      else if (fastNLOCoeffMult::CheckCoeffConstants(c,true)) {
          // Non-perturbative corrections
-         if ( c->GetIContrFlag1()==4 )  Coeff_NPC1 = c;
+         if (c->GetIContrFlag1()==4)  Coeff_NPC1 = c;
          else {
-            error["ReadTable"]<<"Further multiplicative corrections not yet implemented, stopped!\n";
+            logger.error["ReadTable"]<<"Further multiplicative corrections not yet implemented, stopped!\n";
             exit(1);
          }
       }
@@ -594,76 +623,64 @@ void fastNLOReader::OrderCoefficients() {
       BBlocksSMCalc[kThresholdCorrection].push_back(Coeff_THC2);
    }
 
-   // Assign fixed order calculations (LO must be [0]), switch on by default
+   // Assign fixed order calculations (LO must be [0], because second index corresponds to ESMOrder enum)
+   // Push null pointer if no LO ...!
+   BBlocksSMCalc[kFixedOrder].push_back(Coeff_LO);
    if (Coeff_LO)  {
-      BBlocksSMCalc[kFixedOrder].push_back(Coeff_LO);
+      //      BBlocksSMCalc[kFixedOrder].push_back(Coeff_LO);
    } else {
-      error["OrderCoefficients"]<<"Could not find any LO Calculation. Exiting!"<<endl;
-      exit(1);
+      warn["OrderCoefficients"]<<"Could not find any LO Calculation!"<<endl;
+      warn["OrderCoefficients"]<<"Separate evaluation of higher-order contributions currently in testing phase, beware of problems."<<endl;
+      warn["OrderCoefficients"]<<"Not all features will be available in this case, but a straight calculation should be possible. Use with care!"<<endl;
    }
+   // Push null pointer if no NLO ...!
+   BBlocksSMCalc[kFixedOrder].push_back(Coeff_NLO);
    if (Coeff_NLO) {
-      BBlocksSMCalc[kFixedOrder].push_back(Coeff_NLO);
+      //      BBlocksSMCalc[kFixedOrder].push_back(Coeff_NLO);
    } else {
       info["OrderCoefficients"]<<"Could not find any NLO calculation."<<endl;
    }
+   // Push null pointer if no NNLO ...!
+   BBlocksSMCalc[kFixedOrder].push_back(Coeff_NNLO);
    if (Coeff_NNLO) {
-      BBlocksSMCalc[kFixedOrder].push_back(Coeff_NNLO);
+      //      BBlocksSMCalc[kFixedOrder].push_back(Coeff_NNLO);
    } else {
       info["OrderCoefficients"]<<"Could not find any NNLO calculation."<<endl;
    }
 
    //int iprint = 2;
-   //PrintFastNLOTableConstants(iprint);
+   //Print(iprint);
 }
 
 
 //______________________________________________________________________________
 void fastNLOReader::SetCoefficientUsageDefault() {
-   //! Switch on LO and NLO contribution.
+   //! Switch on LO, NLO, and NNLO contribution.
    //! Deactivate all other contributions
-   bUseSMCalc.clear();
-   bUseSMCalc.resize(BBlocksSMCalc.size());
 
    // Switch all off
    for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
       for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
-         bUseSMCalc[j].push_back(false);
+         if (BBlocksSMCalc[j][i]) BBlocksSMCalc[j][i]->Enable(false);
       }
    }
-   // Activate LO and NLO
-   bUseSMCalc[kFixedOrder][kLeading] = true; //LO
-   bUseSMCalc[kFixedOrder][kNextToLeading] = true;//NLO
+   // If filled, activate LO, NLO, and NNLO
+   if (BBlocksSMCalc[kFixedOrder][kLeading]) BBlocksSMCalc[kFixedOrder][kLeading]->Enable();   //LO
+   if (BBlocksSMCalc[kFixedOrder][kNextToLeading]) BBlocksSMCalc[kFixedOrder][kNextToLeading]->Enable();  //NLO
+   if (BBlocksSMCalc[kFixedOrder][kNextToNextToLeading]) BBlocksSMCalc[kFixedOrder][kNextToNextToLeading]->Enable();  //NNLO
 }
 
 
 //______________________________________________________________________________
 void fastNLOReader::InitScalevariation() {
    //! Initialize to scale factors of (MuR,MuF) = (1,1)
-   debug["InitScalevariation"]<<"Try to initialize scale factors MuR and MuF to (1,1)."<<endl;
-
+   logger.debug["InitScalevariation"]<<"Try to initialize scale factors MuR and MuF to (1,1)."<<endl;
    if (!GetIsFlexibleScaleTable()) {
       bool SetScales = SetScaleFactorsMuRMuF(1.,1.);
-      if (!SetScales){
-         error["InitScalevariation"]<<"Could not find scale variation with scale factor 1.0, stopped!"<<endl;
+      if (!SetScales) {
+         logger.error["InitScalevariation"]<<"Could not find scale variation with scale factor 1.0, stopped!"<<endl;
          exit(1);
       }
-   // if (!GetIsFlexibleScaleTable()) {
-   //    if ( B_NLO() ) {
-   //       fastNLOCoeffAddFix* cNLO = (fastNLOCoeffAddFix*)B_NLO();
-   //       for (int iscls=0; iscls< GetNScaleVariations(); iscls++) {
-   //          const double muFac = cNLO->GetScaleFactor(iscls);
-   //          if (fabs(muFac-1.0) < 1.e-7) {
-   //             SetScaleVariation(iscls,true);
-   //             break;
-   //          }
-   //       }
-   //       if (fScalevar == -1) {
-   //          error["InitScalevariation"]<<"Could not found scale variation with scale factor 1.0. Exiting.\n";
-   //          exit(1);
-   //       }
-   //    } else {
-   //       // no NLO table -> no scale dependent contribrutions
-   //    }
    } else {
       // this is a MuVar table. You can vary mu_f and mu_r independently by any factor
       // and you can choose the functional form of mu_f and mu_r as functions of
@@ -671,16 +688,7 @@ void fastNLOReader::InitScalevariation() {
       fScaleFacMuR = 1.;
       fScaleFacMuF = 1.;
       fastNLOCoeffAddFlex* cNLO = (fastNLOCoeffAddFlex*)B_NLO();
-      if ( !cNLO ) cNLO = (fastNLOCoeffAddFlex*)B_LO();
-      // KR: Commented out since anyway always false (warning from clang compiler)!
-      //     cNLO->GetScaleDescr()[0].size() is of type unsigned int
-      //     The functional form for scale variations is set below.
-      // if (cNLO->GetScaleDescr()[0].size() <0) { // ???
-      //    warn["InitScalevariation"]<<"No scaledescription available.\n";
-      //    SetFunctionalForm(kScale1 , kMuR);
-      //    SetFunctionalForm(kScale1 , kMuF);
-      //    return;
-      // }
+      if (!cNLO) cNLO = (fastNLOCoeffAddFlex*)B_Any();
 
       // ---- DIS ---- //
       if (cNLO->GetNPDF() == 1) {
@@ -692,7 +700,7 @@ void fastNLOReader::InitScalevariation() {
          SetFunctionalForm(kScale1 , kMuR);
          SetFunctionalForm(kScale1 , kMuF);
       } else {
-         error<<"Unknown process.\n";
+         logger.error<<"Unknown process.\n";
          exit(1);
       }
    }
@@ -723,19 +731,20 @@ bool fastNLOReader::SetScaleVariation(int scalevar) {
    //!   'scalevar' table exists for all selected
    //!   contributions with extra scale tables.
    //! ------------------------------------------------
-   debug["SetScaleVariation"]<<"Setting to scalevar table "<<scalevar<<endl;
+   logger.debug["SetScaleVariation"]<<"Setting to scalevar table "<<scalevar<<endl;
 
    if (GetIsFlexibleScaleTable()) {
-      warn["SetScaleVariation"]<<"WARNING! This is a flexible-scale table. MuF scale variation tables are not necessary!"<<endl;
-      warn["SetScaleVariation"]<<"You should not have called this method for the active table. Nothing changed!"<<endl;
+      logger.warn["SetScaleVariation"]<<"WARNING! This is a flexible-scale table. MuF scale variation tables are not necessary!"<<endl;
+      logger.warn["SetScaleVariation"]<<"You should not have called this method for the active table. Nothing changed!"<<endl;
       return false;
    }
 
    // Check for maximal scale variation of all active SM calcs
+   // scalevarmax == 0 for contributions not requiring additional tables (LO, multiplicative)
    int scalevarmax = GetNScaleVariations();
-   if (scalevar >= scalevarmax) {
-      error["SetScaleVariation"]<<"This table has only "<<scalevarmax<<" scale variation(s) stored for all active contributions!"<<endl;
-      error["SetScaleVariation"]<<"You wanted to access the non-existing number "<<scalevar<<", stopped!"<<endl;
+   if ((scalevarmax != 0) && (scalevar >= scalevarmax)) {
+      logger.error["SetScaleVariation"]<<"This table has only "<<scalevarmax<<" scale variation(s) stored for all active contributions!"<<endl;
+      logger.error["SetScaleVariation"]<<"You wanted to access the non-existing number "<<scalevar<<", stopped!"<<endl;
       exit(1);
    }
 
@@ -745,36 +754,36 @@ bool fastNLOReader::SetScaleVariation(int scalevar) {
    // The following is only reasonable if called from SetScaleFactorsMuRMuF
    // Is it necessary here ?
    fastNLOCoeffAddFix* cNLO = (fastNLOCoeffAddFix*)B_NLO();
-   if ( !cNLO ) {
-      info["SetScaleVariation"]<<"No NLO calculation available."<<endl;
+   if (!cNLO) {
+      logger.info["SetScaleVariation"]<<"No NLO calculation available."<<endl;
       return true;
    }
 
    double fScaleFacMuF = cNLO->GetScaleFactor(fScalevar);
-   info["SetScaleVariation"]
-      <<"Selecting MuF table according to a multiplicative scale factor of the factorization scale of "
-      <<fScaleFacMuF<<" times the nominal scale."<<endl;
+   logger.info["SetScaleVariation"]
+         <<"Selecting MuF table according to a multiplicative scale factor of the factorization scale of "
+         <<fScaleFacMuF<<" times the nominal scale."<<endl;
 
    // check for threshold corrections.
    if (!BBlocksSMCalc[kThresholdCorrection].empty()) {
       bool lkthc = false;
       for (unsigned int i = 0 ; i <BBlocksSMCalc[kThresholdCorrection].size() ; i++) {
-         if (bUseSMCalc[kThresholdCorrection][i]) {
+         if ( BBlocksSMCalc[kThresholdCorrection][i] && BBlocksSMCalc[kThresholdCorrection][i]->IsEnabled() ) {
             lkthc = true;
          }
       }
 
       if (lkthc) {
          if (abs(fScaleFacMuR-fScaleFacMuF) > DBL_MIN) {
-            error["SetScaleVariation."]<<"Threshold corrections only allow for symmetric variations of the renormalization and factorization scales,"<<endl;
-            error["SetScaleVariation."]<<"but fScaleFacMuR = "<<fScaleFacMuR<<" is different from fScaleFacMuF = "<<fScaleFacMuF<<", stopped!"<<endl;
+            logger.error["SetScaleVariation."]<<"Threshold corrections only allow for symmetric variations of the renormalization and factorization scales,"<<endl;
+            logger.error["SetScaleVariation."]<<"but fScaleFacMuR = "<<fScaleFacMuR<<" is different from fScaleFacMuF = "<<fScaleFacMuF<<", stopped!"<<endl;
             exit(1);
          }
          fastNLOCoeffAddFix* cThC = (fastNLOCoeffAddFix*)B_ThC();
          double fScaleFacMuF2 = cThC->GetScaleFactor(fScalevar);
          if (abs(fScaleFacMuF2-fScaleFacMuF) > DBL_MIN) {
-            error["SetScaleVariation."]<<"Scale variations different for NLO and ThC contributions. This should never happen!"<<endl;
-            error["SetScaleVariation."]<<"Please do not use this method directly but only via SetScaleFactorsMuRMuF and check the return code!"<<endl;
+            logger.error["SetScaleVariation."]<<"Scale variations different for NLO and ThC contributions. This should never happen!"<<endl;
+            logger.error["SetScaleVariation."]<<"Please do not use this method directly but only via SetScaleFactorsMuRMuF and check the return code!"<<endl;
             exit(1);
          }
       }
@@ -783,37 +792,51 @@ bool fastNLOReader::SetScaleVariation(int scalevar) {
 }
 
 
-void fastNLOReader::UseHoppetScaleVariations(bool useHoppet){
+void fastNLOReader::UseHoppetScaleVariations(bool useHoppet) {
 
-   if ( FNLO_HOPPET[0] == '\0' ) {
-      error["UseHoppetScaleVariation."] << "Hoppet support was not compiled with fastNLO. "
-         << "Therefore you can't use Hoppet to calculate the scale variations." <<endl;
+#ifndef FNLO_HOPPET
+      logger.error["UseHoppetScaleVariation."] << "Hoppet support was not compiled with fastNLO. "
+            << "Therefore you can't use Hoppet to calculate the scale variations." <<endl;
       exit(1);
-   } else {
+#else 
       if (useHoppet) {
          if (GetIsFlexibleScaleTable()) {
-            info["UseHoppetScaleVariations"]<<"This is a 'flexible-scale' table, therefore you can already choose all desired scale variations without Hoppet."<<endl;
+            logger.info["UseHoppetScaleVariations"]<<"This is a 'flexible-scale' table, therefore you can already choose all desired scale variations without Hoppet."<<endl;
             fUseHoppet = false;
             return;
          }
-         fastNLOCoeffAddBase * c = (fastNLOCoeffAddBase*)B_LO();
+         fastNLOCoeffAddBase * c = (fastNLOCoeffAddBase*)B_Any();
          if (c->GetIPDFdef1() == 2) {
-            error["UseHoppetScaleVariations"] << "Hoppet scale variations not yet implemented for DIS." << std::endl;
+            logger.error["UseHoppetScaleVariations"] << "Hoppet scale variations not yet implemented for DIS." << std::endl;
             exit(1);
          }
 
-         info["UseHoppetScaleVariations"] << "Hoppet will be used to calculate scale variations." << std::endl;
+         logger.info["UseHoppetScaleVariations"] << "Hoppet will be used to calculate scale variations." << std::endl;
          fUseHoppet = true;
          HoppetInterface::InitHoppet(*this);
          FillPDFCache(1.);
-      }
-      else {
-         info["UseHoppetScaleVariations"] << "Hoppet will NOT be used to calculate scale variations." << std::endl;
+      } else {
+         logger.info["UseHoppetScaleVariations"] << "Hoppet will NOT be used to calculate scale variations." << std::endl;
          fUseHoppet = false;
       }
+#endif
+}
+
+
+//______________________________________________________________________________
+bool fastNLOReader::ActivateContribution(ESMCalculation eCalc, ESMOrder eOrd, bool SetOn) {
+
+   int  iContr = ContrId(eCalc, eOrd);
+   bool lSetOK = false;
+   if (iContr < 0) {
+      logger.warn["ActivateContribution"] << "The requested contribution eCalc = "<<eCalc<<" and eOrd = "<<eOrd<<"does not exist, nothing to be done!" << endl;
+   } else {
+      lSetOK = SetContributionON(eCalc, iContr, SetOn);
    }
+   return lSetOK;
 }
 
+
 //______________________________________________________________________________
 bool fastNLOReader::SetContributionON(ESMCalculation eCalc , unsigned int Id , bool SetOn) {
    //! Enable or disable a contribution to be considered in the cross section calculation
@@ -821,59 +844,78 @@ bool fastNLOReader::SetContributionON(ESMCalculation eCalc , unsigned int Id , b
    //!  - Use SetOn=false, to switch a contribution off
    //!
    //! Each contribution is identified by an ESMCalculation and by a universal Id.
-   //! For all available contributions in your table, call PrintTableInfo().
+   //! For all available contributions in your table, call PrintContributionSummary().
    //!
    //! The LO contribution can be e.g. addressed by (eCalc=fastNLO::kFixedOrder, Id=0);
    //! The NLO contribution can be e.g. addressed by (eCalc=fastNLO::kFixedOrder, Id=1);
    //!
    //! If an additional additive contribution is switched on, then the PDFCache and AlphasCache
    //! are refilled.
+   logger.debug["SetContributionON"]<<"Starting SetContributionON ..."<<endl;
+   logger.info["SetContributionON"]<<(SetOn?"Activating":"Deactivating")<<" contribution "<<_ContrName[eCalc]<<" with Id = "<<Id<<endl;
+
+   // sanity check 1
+   // existence of contribution pointer
+   if ( BBlocksSMCalc[eCalc].size() <=Id) {
+      logger.warn["SetContributionON"]
+            <<"Contribution "<<_ContrName[eCalc]<<" does not exist in this table, cannot switch it On/Off! Ignoring call."<<endl;
+      return false;
+   }
 
-   info["SetContributionON"]<<(SetOn?"Activating":"Deactivating")<<" contribution "<<_ContrName[eCalc]<<" with Id = "<<Id<<endl;
-
-   // sanity checks 1
-   // existence of contribution
-   if (bUseSMCalc[eCalc].size()<=Id || BBlocksSMCalc[eCalc].size() <=Id) {
-      warn["SetContributionON"]
-         <<"Contribution "<<_ContrName[eCalc]<<" does not exist in this table, cannot switch it On/Off! Ignoring call."<<endl;
-      // set to backed up original value
+   // sanity check 2
+   // contribution pointer != NULL pointer, i.e. contribution has been filled
+   if (!BBlocksSMCalc[eCalc][Id]) {
+      logger.warn["SetContributionON"]
+            <<"Contribution "<<_ContrName[eCalc]<<" has not been filled, cannot switch it On/Off! Ignoring call."<<endl;
       return false;
    }
 
    // backup original value
-   bool SetOld = bUseSMCalc[eCalc][Id];
+   bool SetOld = BBlocksSMCalc[eCalc][Id] && BBlocksSMCalc[eCalc][Id]->IsEnabled();
    // set the new value immediately, otherwise GetNScaleVariations(), which is used in FillAlphasCache, will give wrong result.
-   bUseSMCalc[eCalc][Id] = SetOn;
+   BBlocksSMCalc[eCalc][Id]->Enable(SetOn);
+
+   // check if selected subprocesses are compatible with the new contribution
+   if(!UpdateProcesses()) {
+      BBlocksSMCalc[eCalc][Id]->Enable(SetOld);
+      if(!UpdateProcesses()) {
+         logger.error["SetContirbutionON"]<<"Could not restore previous state. This usually means, that something really messed up"<<endl;
+         exit(1);
+      }
+      logger.warn["SetContributionON"]<<"Contribution"<<_ContrName[eCalc]<<" , ID = "<<Id<<", is not compatible with the current selected subprocesses, ignoring call."<<endl;
+      return false;
+   }
 
    // existence of scale variation for additive contributions (otherwise cache filling will fail!)
    fastNLOCoeffAddBase* c = (fastNLOCoeffAddBase*)BBlocksSMCalc[eCalc][Id];
    if (!GetIsFlexibleScaleTable(c) && !c->GetIAddMultFlag()) {
-      int scaleVar = c->GetNpow() == ILOord ? 0 : fScalevar;
-      // check that scaleVar is in allowed range, can otherwise lead to segfaults!
-      if (scaleVar >= GetNScaleVariations()) {
-         warn["SetContributionON"]
-            <<"Scale variation "<<scaleVar<<" of contribution "<<_ContrName[eCalc]<<" , Id = "<<Id<<", is > number of available scale variations "<<GetNScaleVariations()<<"! Ignoring call."<<endl;
+      unsigned int scalevar = c->GetNpow() == ILOord ? 0 : fScalevar;
+      // check that scalevar is in allowed range, can otherwise lead to segfaults!
+      // scalevarmax == 0 for contributions not requiring additional tables (LO, multiplicative)
+      unsigned int scalevarmax = GetNScaleVariations();
+      if ((scalevarmax != 0) && (scalevar >= scalevarmax)) {
+         logger.warn["SetContributionON"]
+               <<"Scale variation "<<scalevar<<" of contribution "<<_ContrName[eCalc]<<" , Id = "<<Id<<", is > number of available scale variations "<<scalevarmax<<"! Ignoring call."<<endl;
          // set to backed up original value
-         bUseSMCalc[eCalc][Id] = SetOld;
+         BBlocksSMCalc[eCalc][Id]->Enable(SetOld);
          return false;
       }
    }
 
-   if (!SetOld && SetOn && !fastNLOTools::IsEmptyVector(XSection_LO) ) {
+   //   if (!SetOld && SetOn && !fastNLOTools::IsEmptyVector(XSection_LO) ) {
+   if (!SetOld && SetOn) {
       if (!c->GetIAddMultFlag()) { // if 'new' additive contribution, then refill PDF and alpha_s cache.
          // Fill alpha_s cache
-         debug["SetContributionON"]<<"Call FillAlphasCache for contribution eCalc="<<eCalc<<"\tId="<<Id<<endl;
+         logger.debug["SetContributionON"]<<"Call FillAlphasCache for contribution eCalc="<<eCalc<<"\tId="<<Id<<endl;
          fAlphasCached = 0;
          FillAlphasCache();
          // Fill PDF cache
-         debug["SetContributionON"]<<"Call FillPDFCache for contribution eCalc="<<eCalc<<"\tId="<<Id<<endl;
+         logger.debug["SetContributionON"]<<"Call FillPDFCache for contribution eCalc="<<eCalc<<"\tId="<<Id<<endl;
          fPDFCached = 0;
          FillPDFCache(0.);
       }
    }
-   // Needs to be done in the beginning!
-   // set the new value
-   //   bUseSMCalc[eCalc][Id] = SetOn;
+   logger.debug["SetContributionON"]<<"... leaving SetContributionON."<<endl;
    return true;
 }
 
@@ -881,7 +923,7 @@ bool fastNLOReader::SetContributionON(ESMCalculation eCalc , unsigned int Id , b
 //______________________________________________________________________________
 int fastNLOReader::GetNScaleVariations() const {
    if (GetIsFlexibleScaleTable()) {
-      info["GetNScaleVariations"]<<"This is a 'flexible-scale' table, therefore you can choose all desired scale variations."<<endl;
+      logger.info["GetNScaleVariations"]<<"This is a 'flexible-scale' table, therefore you can choose all desired scale variations."<<endl;
       return 0;
    }
 
@@ -893,22 +935,24 @@ int fastNLOReader::GetNScaleVariations() const {
    for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
       for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
          fastNLOCoeffAddFix* c = (fastNLOCoeffAddFix*)BBlocksSMCalc[j][i];
-         // Check on contributions with extra scale tables (NLO, threshold corrections)
-         int kType  = c->GetIContrFlag1()-1;
-         int kOrder = c->GetIContrFlag2()-1;
-         debug["GetNScaleVariations"]<<"Contribution type is = "<<kType<<", contribution order is = "<<kOrder<<", contribution switch is = " <<bUseSMCalc[j][i]<<endl;
-         // Do not check pQCD LO or multiplicative corrections
-         if (bUseSMCalc[j][i] && !c->GetIAddMultFlag() &&
-             !(kType == kFixedOrder && kOrder == kLeading)) {
-            NoExtra = false;
-            if (c->GetNScalevar() < (int)scalevarmax) {
-               scalevarmax = c->GetNScalevar();
+         // Check on contributions with extra scale tables (NLO, NNLO, threshold corrections)
+         if (c) {   // No NULL pointer!
+            int kType  = c->GetIContrFlag1()-1;
+            int kOrder = c->GetIContrFlag2()-1;
+            logger.debug["GetNScaleVariations"]<<"Contribution type is = "<<kType<<", contribution order is = "<<kOrder<<", contribution switch is = " << c->IsEnabled() <<endl;
+            // Do not check pQCD LO or multiplicative corrections
+            if (c->IsEnabled() && !c->GetIAddMultFlag() &&
+                  !(kType == kFixedOrder && kOrder == kLeading)) {
+               NoExtra = false;
+               if (c->GetNScalevar() < (int)scalevarmax) {
+                  scalevarmax = c->GetNScalevar();
+               }
             }
          }
       }
    }
-   if (NoExtra) {scalevarmax = 1;}
-   debug["GetNScaleVariations"]<<"Found "<<scalevarmax<<" scale variations."<<endl;
+   if (NoExtra) {scalevarmax = 0;}
+   logger.debug["GetNScaleVariations"]<<"Found "<<scalevarmax<<" scale variations."<<endl;
    return scalevarmax;
 }
 
@@ -916,10 +960,9 @@ int fastNLOReader::GetNScaleVariations() const {
 //______________________________________________________________________________
 vector < double > fastNLOReader::GetScaleFactors() const {
    if (GetIsFlexibleScaleTable()) {
-      info["GetScaleFactors"]<<"This is a 'flexible scale table', therefore you can choose all desired scale variations."<<endl;
+      logger.info["GetScaleFactors"]<<"This is a 'flexible scale table', therefore you can choose all desired scale variations."<<endl;
       return vector<double>();
-   }
-   else
+   } else
       return ((fastNLOCoeffAddFix*)BBlocksSMCalc[kFixedOrder][kNextToLeading])->GetAvailableScaleFactors();
 }
 
@@ -930,7 +973,7 @@ string fastNLOReader::GetScaleDescription(const ESMOrder eOrder, int iScale) con
    if (eOrder < (int)BBlocksSMCalc[kFixedOrder].size())
       coeff = (fastNLOCoeffAddBase*) BBlocksSMCalc[kFixedOrder][eOrder];
    else {
-      error["GetScaleDescription"]<<"Requested contribution not found." << endl;
+      logger.error["GetScaleDescription"]<<"Requested contribution not found." << endl;
       exit(1);
    }
    return coeff->GetScaleDescription(iScale);
@@ -943,23 +986,152 @@ double fastNLOReader::GetNevt(const ESMOrder eOrder) const {
    if (eOrder < (int)BBlocksSMCalc[kFixedOrder].size())
       coeff = (fastNLOCoeffAddBase*) BBlocksSMCalc[kFixedOrder][eOrder];
    else {
-      error["GetScaleDescription"]<<"Requested contribution not found." << endl;
+      logger.error["GetNevt"]<<"Requested contribution not found." << endl;
       exit(1);
    }
    return coeff->GetNevt();
 }
+
+//______________________________________________________________________________
+int fastNLOReader::GetNSubproc(const ESMOrder eOrder) const {
+   //! Returns the number of subprocess contributions in one fixed order contribution. Note
+   //! that these subprocess contributions can consist of several subprocesses merged at
+   //! creation time of the table. Information about what subprocesses are included in each
+   //! contribution can be retrieved with the GetSubprocIndices function.
+
+   if ( eOrder < (int)BBlocksSMCalc[kFixedOrder].size())
+      return ((fastNLOCoeffAddBase*)BBlocksSMCalc[kFixedOrder][eOrder])->GetNSubproc();
+   else {
+      logger.error["GetNSubproc"] << "Requested contribution not found." << endl;
+      exit(1);
+   }
+}
+
+//______________________________________________________________________________
+vector < vector < pair < int,int > > > fastNLOReader::GetSubprocIndices( const ESMOrder eOrder ) const {
+   //! This function returns a list with length GetNSubproc containing a list of pairs for each
+   //! subprocess contribution. Each pair specifies a subprocess throug two PDGIDs involed in that process.
+
+   if ( eOrder < (int)BBlocksSMCalc[kFixedOrder].size())
+      return ((fastNLOCoeffAddBase*)BBlocksSMCalc[kFixedOrder][eOrder])->GetPDFCoeff();
+   else {
+      logger.error["GetSubprocIndices"] << "Requested contribution not found." << endl;
+      exit(1);
+   }
+}
+
 //______________________________________________________________________________
 vector < double > fastNLOReader::GetCrossSection() {
-   // Get fast calculated NLO cross section
+   // Get fast calculated cross section
    if (XSection.empty()) CalcCrossSection();
    return XSection;
 }
 
+//______________________________________________________________________________
+vector < double > fastNLOReader::GetCrossSection(bool lNorm) {
+   // Get fast calculated cross section
+   if (XSection.empty()) CalcCrossSection();
+   if (lNorm) {
+      vector < double > XNorm = GetNormCrossSection();
+      return XNorm;
+   } else {
+      return XSection;
+   }
+}
+
+//______________________________________________________________________________
+std::vector < std::map< double, double > > fastNLOReader::GetCrossSection_vs_x1() {
+   // Get fast calculated cross section
+   logger.warn<<"Function 'GetCrossSection_vs_x1' does _NOT_ return dSigma/dx but only the cross section contribution at the different x-nodes."<<endl;
+   logger.warn<<"In order to obtain dSigma/dx, the retured values must be divided by the step-size of the interpolation."<<endl;
+   if (XSection.empty()) CalcCrossSection();
+   return fXSection_vsX1;
+}
+
+//______________________________________________________________________________
+std::vector < std::map< double, double > > fastNLOReader::GetCrossSection_vs_x2() {
+   // Get fast calculated cross section
+   logger.warn<<"Function 'GetCrossSection_vs_x1' does _NOT_ return dSigma/dx but only the cross section contribution at the different x-nodes."<<endl;
+   logger.warn<<"In order to obtain dSigma/dx, the retured values must be divided by the step-size of the interpolation."<<endl;
+   if (XSection.empty()) CalcCrossSection();
+   return fXSection_vsX2;
+}
+
+//______________________________________________________________________________
+vector < double > fastNLOReader::GetNormCrossSection() {
+   // Check whether normalization is defined
+   if (INormFlag == 0) {
+      logger.error["GetNormCrossSection"]<<"Normalization not defined for this scenario, aborting!"<<endl;
+      logger.error["GetNormCrossSection"]<<"INormFlag = "<<INormFlag<<endl;
+      exit(1);
+   }
+   if (XSection.empty()) CalcCrossSection();
+   vector < double > XSectionNorm = XSection;
+
+   // // Second table to be loaded?
+   // if ( INormFlag < 0 ) {
+   //    string denomtable  = GetDenomTable();
+   //    fastNLOTable table = fastNLOTable(denomtable);
+   //    table.PrintContributionSummary();
+   //    fastNLOLHAPDF denom(table,GetLHAPDFFilename(),0);
+   // }
+
+   unsigned int nDim = GetNumDiffBin();
+   // iDim ranges from 0 to nDim-1
+   unsigned int iDim = abs(INormFlag)-1;
+   if (iDim > nDim-1) {
+      logger.error["GetNormCrossSection"]<<"Normalization to slice in dimension " << iDim << " not possible, aborting!"<<endl;
+      logger.error["GetNormCrossSection"]<<"INormFlag = "<<INormFlag<<", nDim = "<<nDim<<endl;
+      exit(1);
+   }
+   // Normalize each observable bin
+   int idivlo    = -1;
+   int idivup    = -1;
+   double xsnorm = 0.;
+   double twidth = 0.;
+   for (unsigned int iobs = 0; iobs < NObsBin; iobs++) {
+      // Cached result?
+      if (!(idivlo == IDivLoPointer[iobs]-1 && idivup == IDivUpPointer[iobs]-1)) {
+         idivlo = IDivLoPointer[iobs]-1;
+         idivup = IDivUpPointer[iobs]-1;
+         xsnorm = 0.;
+         twidth = 0.;
+         if (iDim > 0) {
+            if (GetIDim0Bin(idivlo) != GetIDim0Bin(idivup)) {
+               logger.warn["GetNormCrossSection"]<<"Normalization range goes beyond one slice in dimension " << iDim << "!"<<endl;
+               logger.warn["GetNormCrossSection"]<<"idivlo = "<<idivlo<<", IDim0Bin = "<<GetIDim0Bin(idivlo)<<endl;
+               logger.warn["GetNormCrossSection"]<<"idivup = "<<idivup<<", IDim0Bin = "<<GetIDim0Bin(idivup)<<endl;
+            }
+            if (iDim > 1) {
+               if (GetIDim1Bin(idivlo) != GetIDim1Bin(idivup)) {
+                  logger.warn["GetNormCrossSection"]<<"Normalization range goes beyond one slice in dimension " << iDim << "!"<<endl;
+                  logger.warn["GetNormCrossSection"]<<"idivlo = "<<idivlo<<", IDim1Bin = "<<GetIDim1Bin(idivlo)<<endl;
+                  logger.warn["GetNormCrossSection"]<<"idivup = "<<idivup<<", IDim1Bin = "<<GetIDim1Bin(idivup)<<endl;
+               }
+            }
+         }
+         for (int in = idivlo; in <= idivup; in++) {
+            double bwidth = GetObsBinUpBound(in,iDim) - GetObsBinLoBound(in,iDim);
+            xsnorm += XSection[in]*bwidth;
+            twidth += bwidth;
+         }
+      }
+      if (abs(xsnorm) > DBL_MIN) {
+         XSectionNorm[iobs] = XSectionNorm[iobs] / xsnorm;
+      } else {
+         logger.warn["GetNormCrossSection"]<<"Normalization divisor too small, normalized cross section set to -1!"<<endl;
+         logger.warn["GetNormCrossSection"]<<"xsnorm = "<<xsnorm<<endl;
+         XSectionNorm[iobs] = -1.;
+      }
+   }
+   return XSectionNorm;
+}
+
 //______________________________________________________________________________
 vector< vector < double > > fastNLOReader::GetCrossSection2Dim() {
    //! Get cross section as 2-dimensional vector according to defined binning
    if (GetNumDiffBin() != 2)
-      error["GetCrossSection2Dim"]<<"This function is only valid for NDiffBin=2"<<endl;
+      logger.error["GetCrossSection2Dim"]<<"This function is only valid for NDiffBin=2"<<endl;
    // Get fast calculated NLO cross section
    if (XSection.empty()) CalcCrossSection();
    vector< vector < double > > XSection2Dim;
@@ -974,23 +1146,24 @@ vector< vector < double > > fastNLOReader::GetCrossSection2Dim() {
    }
    return XSection2Dim;
 }
-//______________________________________________________________________________
+
+
+//_DEPRECATED___________________________________________________________________
 vector < double > fastNLOReader::GetKFactors() {
    // Get ratio of fast calculated NLO to LO cross section
-   if (XSection.empty()) CalcCrossSection();
+   // if (XSection.empty()) CalcCrossSection();
+   logger.error["GetKFactors"]<<"This function is ambiguous and therefore deprecated, aborted!"<<endl;
+   logger.error["GetKFactors"]<<"Please derive K factors as ratios of the desired cross sections."<<endl;
+   exit(1);
    return kFactor;
 }
 
 
 //______________________________________________________________________________
-vector < double > fastNLOReader::GetQScales(int irelord) {
+vector < double > fastNLOReader::GetQScales() {
    // Get XSection weighted Q scale in bin
    if (XSection.empty()) CalcCrossSection();
-   if (irelord == 0) {
-      return QScale_LO;
-   } else {
-      return QScale;
-   }
+   return QScale;
 }
 
 
@@ -1030,24 +1203,27 @@ void fastNLOReader::CalcReferenceCrossSection() {
       fastNLOCoeffAddBase* Coeff_LO_Ref = GetReferenceTable(kLeading);
       fastNLOCoeffAddBase* Coeff_NLO_Ref = GetReferenceTable(kNextToLeading);
       fastNLOCoeffAddBase* Coeff_NNLO_Ref = GetReferenceTable(kNextToNextToLeading);
-      if ( Coeff_LO_Ref && Coeff_NLO_Ref && Coeff_NNLO_Ref )
-         warn["CalcReferenceCrossSection"]<<"Found NNLO reference cross section. Returning reference of LO+NLO+NNLO.\n";
+      if (Coeff_LO_Ref && Coeff_NLO_Ref && Coeff_NNLO_Ref)
+         logger.warn["CalcReferenceCrossSection"]<<"Found NNLO reference cross section. Returning reference of LO+NLO+NNLO.\n";
       if (Coeff_LO_Ref && Coeff_NLO_Ref) {
          for (unsigned int i=0; i<NObsBin; i++) {
             for (int l=0; l<Coeff_LO_Ref->GetNSubproc(); l++) {
+               //TODO ask Klaus about this: if (!fSubprocActive[l]) continue;
                fastNLOCoeffAddFix* c = (fastNLOCoeffAddFix*)Coeff_LO_Ref;
                int xUnits = c->GetIXsectUnits();
                double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
                XSectionRef[i] +=  c->GetSigmaTilde(i,0,0,0,l) * unit / c->GetNevt(i,l) ; // no scalevariations in LO tables
             }
             for (int l=0; l<Coeff_NLO_Ref->GetNSubproc(); l++) {
+               //TODO ask Klaus about this: if (!fSubprocActive[l]) continue;
                fastNLOCoeffAddFix* c = (fastNLOCoeffAddFix*)Coeff_NLO_Ref;
                int xUnits = c->GetIXsectUnits();
                double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
                XSectionRef[i] +=  c->GetSigmaTilde(i,fScalevar,0,0,l) * unit / c->GetNevt(i,l);
             }
-            if ( Coeff_NNLO_Ref ) {
+            if (Coeff_NNLO_Ref) {
                for (int l=0; l<Coeff_NNLO_Ref->GetNSubproc(); l++) {
+                  //TODO ask Klaus about this: if (!fSubprocActive[l]) continue;
                   fastNLOCoeffAddFix* c = (fastNLOCoeffAddFix*)Coeff_NNLO_Ref;
                   int xUnits = c->GetIXsectUnits();
                   double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
@@ -1055,16 +1231,15 @@ void fastNLOReader::CalcReferenceCrossSection() {
                }
             }
          }
-      }
-      else
-         warn["CalcReferenceCrossSection"]<<"No reference cross sections for LO and NLO available.\n";
-   }
-   else {
+      } else
+         logger.warn["CalcReferenceCrossSection"]<<"No reference cross sections for LO and NLO available.\n";
+   } else {
       for (unsigned int i=0; i<NObsBin; i++) {
          fastNLOCoeffAddFlex* cLO = (fastNLOCoeffAddFlex*)BBlocksSMCalc[kFixedOrder][kLeading];
          int xUnits = cLO->GetIXsectUnits();
          double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
          for (int n=0; n<cLO->GetNSubproc(); n++) {
+            //TODO if (!fSubprocActive[n]) continue;
             XSectionRefMixed[i]             += cLO->SigmaRefMixed[i][n] * unit / cLO->GetNevt(i,n);
             XSectionRef_s1[i]               += cLO->SigmaRef_s1[i][n] * unit / cLO->GetNevt(i,n);
             XSectionRef_s2[i]               += cLO->SigmaRef_s2[i][n] * unit / cLO->GetNevt(i,n);
@@ -1073,6 +1248,7 @@ void fastNLOReader::CalcReferenceCrossSection() {
          xUnits = cNLO->GetIXsectUnits();
          unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
          for (int n=0; n<cNLO->GetNSubproc(); n++) {
+            //TODO if (!fSubprocActive[n]) continue;
             XSectionRefMixed[i]             += cNLO->SigmaRefMixed[i][n] * unit / cNLO->GetNevt(i,n);
             XSectionRef_s1[i]               += cNLO->SigmaRef_s1[i][n] * unit / cNLO->GetNevt(i,n);
             XSectionRef_s2[i]               += cNLO->SigmaRef_s2[i][n] * unit / cNLO->GetNevt(i,n);
@@ -1088,25 +1264,25 @@ bool fastNLOReader::PrepareCache() {
    // check pdf cache
    const double PDFcks = CalcNewPDFChecksum();
    if (fPDFCached==0. || (fPDFCached!=0. && fabs(PDFcks/fPDFCached -1.) > 1.e-7)) {
-      debug["PrepareCache"]<<"Need to refill PDFCache, since PDFCecksum="<<PDFcks<<" and fPDFCached="<<fPDFCached<<endl;
+      logger.debug["PrepareCache"]<<"Need to refill PDFCache, since PDFCecksum="<<PDFcks<<" and fPDFCached="<<fPDFCached<<endl;
       FillPDFCache(PDFcks);
-   } else  debug["PrepareCache"]<<"No need to refill PDFCache."<<endl;
+   } else  logger.debug["PrepareCache"]<<"No need to refill PDFCache."<<endl;
 
    // check pdf cache
    if (!fPDFSuccess) {
-      error["PrepareCache"]<<"Cannot calculate cross sections. PDF has not been initalized successfully."<<endl;
+      logger.error["PrepareCache"]<<"Cannot calculate cross sections. PDF has not been initalized successfully."<<endl;
       return false;
    }
 
    // check alpha_s cache
    const double asref = CalcReferenceAlphas();
    if (fAlphasCached == 0. || fAlphasCached != asref) {
-      debug["PrepareCache"]<<"Need to refill AlphasCache, since fAlphasCached="<<fAlphasCached<<endl;
+      logger.debug["PrepareCache"]<<"Need to refill AlphasCache, since fAlphasCached="<<fAlphasCached<<endl;
       FillAlphasCache();
    }
    // do we now have an alphas?
    if (fAlphasCached==0. || fAlphasCached != asref) {
-      error["PrepareCache"]<<"Filling of alpha_s cache failed. fAlphasCached="<<fAlphasCached<<"\tasref="<<asref<<endl;
+      logger.error["PrepareCache"]<<"Filling of alpha_s cache failed. fAlphasCached="<<fAlphasCached<<"\tasref="<<asref<<endl;
       return false;
    }
    return true;
@@ -1116,92 +1292,91 @@ bool fastNLOReader::PrepareCache() {
 //______________________________________________________________________________
 void fastNLOReader::CalcCrossSection() {
    //!
-   //!  Initialize the internal arrays with the NLO cross sections
-   //!  with the information from the FastNLO file, the pdf and
-   //!  the defined alpha_s
+   //!  Calculate cross section for all active additive and multiplicative
+   //!  contributions
+   //!
+   //!  xs = { sum(all active pert. add. contr.) + sum(all other active add. contr.) } * prod(all active multipl. contr.)
    //!
-   // xs = (sum(all active add. (perturbative) contr.) + sum(all other active add. contr.) * prod(all active multipl. contr.)
-   debug["CalcCrossSection"]<<endl;
+   logger.debug["CalcCrossSection"]<<"Starting CalcCrossSection ..."<<endl;
 
-   XSection_LO.clear();
    XSection.clear();
-   XSection_LO.resize(NObsBin);
    XSection.resize(NObsBin);
-   kFactor.clear();
-   kFactor.resize(NObsBin);
-   QScale_LO.clear();
+   fXSection_vsX1.clear();
+   fXSection_vsX2.clear();
+   fXSection_vsX1.resize(NObsBin);
+   fXSection_vsX2.resize(NObsBin);
    QScale.clear();
-   QScale_LO.resize(NObsBin);
    QScale.resize(NObsBin);
 
    // handle alpha_s and PDF Cache
    bool CacheOK = PrepareCache();
    if (!CacheOK) {
-      error["CalcCrossSection"]<<"Caching failed. Cannot calculate cross sections."<<endl;
+      logger.error["CalcCrossSection"]<<"Caching failed. Cannot calculate cross sections."<<endl;
       return;
+   } else {
+      logger.debug["CalcCrossSection"]<<"Caching ok, continue ..."<<endl;
    }
 
    // Perturbative (additive) contributions
    for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
       for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
-         if ( bUseSMCalc[j][i] ) {
-            if ( fastNLOCoeffAddFlex::CheckCoeffConstants(BBlocksSMCalc[j][i],true) )
+         if (BBlocksSMCalc[j][i] && BBlocksSMCalc[j][i]->IsEnabled()) {
+            if (fastNLOCoeffAddFlex::CheckCoeffConstants(BBlocksSMCalc[j][i],true))
                CalcCrossSectionv21((fastNLOCoeffAddFlex*)BBlocksSMCalc[j][i]);
-            else if ( fastNLOCoeffAddFix::CheckCoeffConstants(BBlocksSMCalc[j][i],true) )
+            else if (fastNLOCoeffAddFix::CheckCoeffConstants(BBlocksSMCalc[j][i],true))
                CalcCrossSectionv20((fastNLOCoeffAddFix*)BBlocksSMCalc[j][i]);
          }
       }
    }
 
-   // Check whether pQCD contributions beyond LO exist and are activated
-   bool lknlo = false;
+   // Check whether pQCD LO contributions or beyond exist and are activated
+   bool lklo = false;
+   bool lkho = false;
    if (!BBlocksSMCalc[kFixedOrder].empty()) {
       for (unsigned int i = 0 ; i <BBlocksSMCalc[kFixedOrder].size() ; i++) {
-         int kOrder = BBlocksSMCalc[kFixedOrder][i]->GetIContrFlag2()-1;
-         if (bUseSMCalc[kFixedOrder][i] && kOrder > 0) {
-            lknlo = true;
-            break;
+         int kOrder = -1;
+         if (BBlocksSMCalc[kFixedOrder][i]) {
+            kOrder = BBlocksSMCalc[kFixedOrder][i]->GetIContrFlag2()-1;
+         }
+         if (BBlocksSMCalc[kFixedOrder][i] && BBlocksSMCalc[kFixedOrder][i]->IsEnabled()) {
+            if (kOrder == 0) {
+               lklo = true;
+            } else if (kOrder > 0) {
+               lkho = true;
+            }
          }
       }
    }
 
    // Contributions from the a-posteriori scale variation
-   if (!GetIsFlexibleScaleTable() && lknlo) {
+   if (!GetIsFlexibleScaleTable() && lklo && lkho) {
       fastNLOCoeffAddFix* cNLO = (fastNLOCoeffAddFix*)B_NLO();
-      if ( fabs(fScaleFacMuF - cNLO->GetScaleFactor(fScalevar)) > DBL_MIN ) {
-         if (!fUseHoppet){
-            error["CalcCrossSection"] << "Inconsistent choice of chosen factorization scale table and fScaleFacMuF." << endl;
+      if (fabs(fScaleFacMuF - cNLO->GetScaleFactor(fScalevar)) > DBL_MIN) {
+         if (!fUseHoppet) {
+            logger.error["CalcCrossSection"] << "Inconsistent choice of chosen factorization scale table and fScaleFacMuF." << endl;
             exit(1);
          }
          CalcAposterioriScaleVariationMuF();
       }
-      if ( fabs(fScaleFacMuR - cNLO->GetScaleFactor(fScalevar)) > DBL_MIN ) {
+      if (fabs(fScaleFacMuR - cNLO->GetScaleFactor(fScalevar)) > DBL_MIN) {
          CalcAposterioriScaleVariationMuR();
       }
    }
 
-   // calculate LO cross sections
-   if (GetIsFlexibleScaleTable())
-      CalcCrossSectionv21((fastNLOCoeffAddFlex*)B_LO(),true);
-   else
-      CalcCrossSectionv20((fastNLOCoeffAddFix*)B_LO(),true);
-
-
    // non-perturbative corrections (multiplicative corrections)
    for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
       for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
-         if (bUseSMCalc[j][i] ) {
-            if ( fastNLOCoeffMult::CheckCoeffConstants( BBlocksSMCalc[j][i] , true ) ) {
+         if ( BBlocksSMCalc[j][i] && BBlocksSMCalc[j][i]->IsEnabled()) {
+            if (fastNLOCoeffMult::CheckCoeffConstants(BBlocksSMCalc[j][i] , true)) {
                fastNLOCoeffMult* cMult = (fastNLOCoeffMult*) BBlocksSMCalc[j][i];
-               if ( cMult->GetIContrFlag1() == 4 && cMult->GetIContrFlag2() == 1) {
-                  debug["CalcCrossSection"]<<"Multiplying with non-perturbative correction."<<endl;
+               if (cMult->GetIContrFlag1() == 4 && cMult->GetIContrFlag2() == 1) {
+                  logger.debug["CalcCrossSection"]<<"Multiplying with non-perturbative correction."<<endl;
                   for (unsigned int iB=0; iB<NObsBin; iB++) {
                      XSection[iB] *= cMult->GetMultFactor(iB);
-                     //            XSection_LO[iB]     *= BBlocksSMCalc[j][i]->fact[iB];
                   }
                } else {
-                  error["CalcCrossSection"]<<"Found unknown multiplicative correction. Printing coeff table and exiting..."<<endl;
-                  cMult->Print();
+                  logger.error["CalcCrossSection"]<<"Found unknown multiplicative correction. Printing coeff table and exiting..."<<endl;
+                  cMult->Print(-1);
                   exit(1);
                }
             }
@@ -1209,19 +1384,12 @@ void fastNLOReader::CalcCrossSection() {
       }
    }
 
-   // ---- k-factor calculation ---- //
-   debug["CalcCrossSection"]<<"Calculate k-factors: xs/xs_LO"<<endl;
-   for (unsigned int i=0; i<NObsBin; i++) {
-      kFactor[i] = XSection[i] / XSection_LO[i];
-   }
-
    // ---- Q-scale calculation ---- //
-   debug["CalcCrossSection"]<<"Calculate Q-scales: xsQ/xs"<<endl;
+   logger.debug["CalcCrossSection"]<<"Calculate Q-scales: xsQ/xs"<<endl;
    for (unsigned int i=0; i<NObsBin; i++) {
-      QScale_LO[i] = QScale_LO[i]/XSection_LO[i];
-      QScale[i]    = QScale[i]/XSection[i];
+      QScale[i] = QScale[i]/XSection[i];
    }
-
+   logger.debug["CalcCrossSection"]<<"... leaving CalcCrossSection."<<endl;
 }
 
 
@@ -1233,8 +1401,12 @@ void fastNLOReader::CalcAposterioriScaleVariationMuR() {
    double scalefac       = fScaleFacMuR / cNLO->GetScaleFactor(scaleVar);
 
    logger.debug["CalcAposterioriScaleVariationMuR"]<<"scalefac="<<scalefac<<endl;
-   if ( GetIsFlexibleScaleTable() ) { logger.error["CalcAposterioriScaleVariationMuR"]<<"This function is applicable only to non-flexible scale tables."<<endl; exit(1);}
+   if (GetIsFlexibleScaleTable()) { logger.error["CalcAposterioriScaleVariationMuR"]<<"This function is applicable only to non-flexible scale tables."<<endl; exit(1);}
    fastNLOCoeffAddFix* cLO  = (fastNLOCoeffAddFix*) B_LO();
+   if (cLO == NULL) {
+      logger.error["CalcAposterioriScaleVariationMuR"]<<"No leading order calculations available. Cannot calculate scale variations."<<endl;
+      exit(3);
+   }
    vector<double>* XS    = &XSection;
    vector<double>* QS    = &QScale;
    int xUnits = cLO->GetIXsectUnits();
@@ -1249,11 +1421,14 @@ void fastNLOReader::CalcAposterioriScaleVariationMuR() {
          double asnp1 = pow(cLO->AlphasTwoPi_v20[i][j],(n+1)/n);//as^n+1
          for (int k=0; k<nxmax; k++) {
             for (int l=0; l<cLO->GetNSubproc(); l++) {
+               if ( !cLO->SubIsEnabled(l) ) continue;
                double clo  = cLO->GetSigmaTilde(i,0,j,k,l) *  cLO->PdfLc[i][j][k][l] * unit / cLO->GetNevt(i,l);
                double xsci = asnp1 * clo * n * L * beta0;
                double mur  = fScaleFacMuR * cLO->GetScaleNode(i,0,j);
                XS->at(i) +=  xsci;
                QS->at(i) +=  xsci*mur;
+               fXSection_vsX1[i][cLO->GetX1(i,k)] += xsci;
+               //fXSection_vsX2[i][cLO->GetXNode2(i,k)] += xsci;
             }
          }
       }
@@ -1267,13 +1442,17 @@ void fastNLOReader::CalcAposterioriScaleVariationMuF() {
    int scaleVar          = cNLO->GetNpow() == ILOord ? 0 : fScalevar;
    double scalefac       = fScaleFacMuF / cNLO->GetScaleFactor(scaleVar);
 
-   debug["CalcAposterioriScaleVariationMuF"]<<"scalefac="<<scalefac<<endl;
-   if ( GetIsFlexibleScaleTable() ) { error["CalcAposterioriScaleVariationMuF"]<<"This function is only reasonable for non-flexible scale tables."<<endl; exit(1);}
+   logger.debug["CalcAposterioriScaleVariationMuF"]<<"scalefac="<<scalefac<<endl;
+   if (GetIsFlexibleScaleTable()) { logger.error["CalcAposterioriScaleVariationMuF"]<<"This function is only reasonable for non-flexible scale tables."<<endl; exit(1);}
    fastNLOCoeffAddFix* cLO  = (fastNLOCoeffAddFix*) B_LO();
+   if (cLO == NULL) {
+      logger.error["CalcAposterioriScaleVariationMuR"]<<"No leading order calculations available. Cannot calculate scale variations."<<endl;
+      exit(3);
+   }
    vector<double>* XS    = &XSection;
    int xUnits = cLO->GetIXsectUnits();
    const double n     = cLO->GetNpow();
-   debug["CalcAposterioriScaleVariationMuF"] << "Npow=" << n <<endl;
+   logger.debug["CalcAposterioriScaleVariationMuF"] << "Npow=" << n <<endl;
    for (unsigned int i=0; i<NObsBin; i++) {
       double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
       int nxmax = cLO->GetNxmax(i);
@@ -1281,11 +1460,14 @@ void fastNLOReader::CalcAposterioriScaleVariationMuF() {
          double asnp1 = pow(cLO->AlphasTwoPi_v20[i][j],(n+1)/n);//as^n+1
          for (int k=0; k<nxmax; k++) {
             for (int l=0; l<cLO->GetNSubproc(); l++) {
+               if (!cLO->SubIsEnabled(l)) continue;
                // TODO: Not implemented correctly. Need to fix DIS case.
                double clo  = cLO->GetSigmaTilde(i,0,j,k,l) *(cLO->PdfSplLc1[i][j][k][l] + cLO->PdfSplLc2[i][j][k][l]) * unit / cLO->GetNevt(i,l);
                double xsci = asnp1 * n * log(scalefac) * clo;
                //double xsci = asnp1 * n * log(scalefac) * clo;
                XS->at(i) -= xsci;
+               fXSection_vsX1[i][cLO->GetX1(i,k)] -= xsci;
+               //fXSection_vsX2[i][cLO->GetXNode2(i,k)] -= xsci;
             }
          }
       }
@@ -1294,77 +1476,106 @@ void fastNLOReader::CalcAposterioriScaleVariationMuF() {
 
 
 //______________________________________________________________________________
-void fastNLOReader::CalcCrossSectionv21(fastNLOCoeffAddFlex* c , bool IsLO) {
+void fastNLOReader::CalcCrossSectionv21(fastNLOCoeffAddFlex* c) {
    //!
    //!  Cross section calculation for DIS and HHC tables in v2.1 format
    //!
-   debug["CalcCrossSectionv21"]<<"Npow="<<c->GetNpow()<<"\tIsLO="<<IsLO<<endl;
+   logger.debug["CalcCrossSectionv21"]<<"Starting CalcCrossSectionv21 ..."<<endl;
 
-   vector<double>* XS = IsLO ? &XSection_LO : &XSection;
-   vector<double>* QS = IsLO ? &QScale_LO : &QScale;
+   // Test that c ist not a NULL pointer, i.e. an unfilled contribution, else return
+   if (!c) return;
+
+   vector<double>* XS = &XSection;
+   vector<double>* QS = &QScale;
    // KR: Having different IXsectUnits in different contributions only works when
    //     everything always scaled to Ipublunits (unique per table)
    // Get x section units of each contribution
    int xUnits = c->GetIXsectUnits();
-   debug["CalcCrossSectionv21"]<<"Ipublunits = " << Ipublunits << ", xUnits = " << xUnits << endl;
+   logger.debug["CalcCrossSectionv21"]<<"Ipublunits = " << Ipublunits << ", xUnits = " << xUnits << endl;
 
    for (unsigned int i=0; i<NObsBin; i++) {
       double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
       int nxmax = c->GetNxmax(i);
       for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
          for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
-            double Q2           = pow(c->GetScaleNode1(i,jS1),2);
+            double Q2           = c->GetScaleNode1(i,jS1)*c->GetScaleNode1(i,jS1);
             double mur          = CalcMu(kMuR , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuR);
             double muf          = CalcMu(kMuF , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
-            double mur2         = pow(mur,2);
-            double muf2         = pow(muf,2);
+            double mur2         = mur*mur;
+            double muf2         = muf*muf;
             for (int x=0; x<nxmax; x++) {
                for (int n=0; n<c->GetNSubproc(); n++) {
+                  if (!c->SubIsEnabled(n)) continue;
                   double as             = c->AlphasTwoPi[i][jS1][kS2];
                   double pdflc          = c->PdfLcMuVar[i][x][jS1][kS2][n];
                   if (pdflc == 0.) continue;
                   double fac  = as * pdflc * unit;
                   double xsci = c->SigmaTildeMuIndep[i][x][jS1][kS2][n] * fac / c->GetNevt(i,n);
-                  if ( c->GetNScaleDep() >= 5 ) {
-                     xsci             += c->SigmaTildeMuFDep [i][x][jS1][kS2][n] * log(muf2) * fac / c->GetNevt(i,n);
-                     xsci             += c->SigmaTildeMuRDep [i][x][jS1][kS2][n] * log(mur2) * fac / c->GetNevt(i,n);
-                     if ( c->GetIPDFdef1() == 2 ) {   // DIS tables use log(mu/Q2) instead of log(mu)
+                  if (c->GetNScaleDep() >= 5) {
+                     double lf2 = log(muf2);
+                     double lr2 = log(mur2);
+                     xsci             += c->SigmaTildeMuFDep [i][x][jS1][kS2][n] * lf2 * fac / c->GetNevt(i,n);
+                     xsci             += c->SigmaTildeMuRDep [i][x][jS1][kS2][n] * lr2 * fac / c->GetNevt(i,n);
+                     if (c->GetIPDFdef1() == 2 && c->fSTildeDISFormat==0) {     // DIS tables use log(mu/Q2) instead of log(mu) (but only for ln(mur), ln(muf))
                         xsci -= c->SigmaTildeMuFDep [i][x][jS1][kS2][n] * log(Q2) * fac / c->GetNevt(i,n);
                         xsci -= c->SigmaTildeMuRDep [i][x][jS1][kS2][n] * log(Q2) * fac / c->GetNevt(i,n);
                      }
-                     if ( c->GetNScaleDep() >= 6 ) {
-                        xsci             += c->SigmaTildeMuRRDep [i][x][jS1][kS2][n] * pow(log(mur2),2) * fac / c->GetNevt(i,n);
+                     if (c->GetNScaleDep() >= 6) {
+                        xsci             += c->SigmaTildeMuRRDep [i][x][jS1][kS2][n] * lr2*lr2 * fac / c->GetNevt(i,n);
                      }
-                     if ( c->GetNScaleDep() >= 7 ) {
-                        xsci             += c->SigmaTildeMuFFDep [i][x][jS1][kS2][n] * pow(log(muf2),2) * fac / c->GetNevt(i,n);
-                        xsci             += c->SigmaTildeMuRFDep [i][x][jS1][kS2][n] * log(mur2) * log(muf2) * fac / c->GetNevt(i,n);
+                     if (c->GetNScaleDep() >= 7) {
+                        xsci             += c->SigmaTildeMuFFDep [i][x][jS1][kS2][n] * lf2*lf2 * fac / c->GetNevt(i,n);
+                        xsci             += c->SigmaTildeMuRFDep [i][x][jS1][kS2][n] * lr2*lf2 * fac / c->GetNevt(i,n);
                      }
                   }
                   XS->at(i)   += xsci;
                   QS->at(i)   += xsci*mur;
+                  // cross section as 'functions' of x
+                  //double x1 = c->GetXNode1(i,x);
+                  //double x2 = c->GetXNode2(i,x);
+                  fXSection_vsX1[i][c->GetX1(i,x)] += xsci;
+                  //fXSection_vsX2[i][x2] += xsci;
                }
             }
          }
       }
    }
+   logger.debug["CalcCrossSectionv21"]<<"... leaving CalcCrossSectionv21."<<endl;
 }
 
 
 //______________________________________________________________________________
-void fastNLOReader::CalcCrossSectionv20(fastNLOCoeffAddFix* c , bool IsLO) {
+void fastNLOReader::CalcCrossSectionv20(fastNLOCoeffAddFix* c) {
    //!
    //!  Cross section calculation in v2.0 format
    //!
-   debug["CalcCrossSectionv20"]<<"Npow="<<c->GetNpow()<<"\tIsLO="<<IsLO<<endl;
+   logger.debug["CalcCrossSectionv20"]<<"Starting CalcCrossSectionv20 ..."<<endl;
+
+   // Test that c ist not a NULL pointer, i.e. an unfilled contribution, else return
+   if (!c) return;
+
+   /// Test that alpha_s cache is filled with non-zero values for this contribution
+   if (c->AlphasTwoPi_v20[0][0] < DBL_MIN) {
+      logger.error["CalcCrossSectionv20"]<<"Need to refill alpha_s cache for this contribution. Normally, should not be necessary here, aborted!"<<endl;
+      exit(1);
+      //      FillAlphasCacheInBlockBv20(c);
+   }
 
-   int scaleVar          = c->GetNpow() == ILOord ? 0 : fScalevar;
-   vector<double>* XS    = IsLO ? &XSection_LO : &XSection;
-   vector<double>* QS    = IsLO ? &QScale_LO : &QScale;
+   /// Test that PDF cache is filled with non-zero values for this contribution
+   if (abs(c->PdfLc[0][0][0][0]) < DBL_MIN) {
+      logger.debug["CalcCrossSectionv20"]<<"Need to refill PDF cache for this contribution. Normally, should not be necessary here, aborted!"<<endl;
+      exit(1);
+      //      FillPDFCache(0.,true);
+   }
+
+   int scaleVar       = c->GetNpow() == ILOord ? 0 : fScalevar;
+   vector<double>* XS = &XSection;
+   vector<double>* QS = &QScale;
    // KR: Having different IXsectUnits in different contributions only works when
    //     everything always scaled to Ipublunits (unique per table)
    // Get x section units of each contribution
    int xUnits = c->GetIXsectUnits();
-   debug["CalcCrossSectionv20"]<<"Ipublunits = " << Ipublunits << ", xUnits = " << xUnits << endl;
+   logger.debug["CalcCrossSectionv20"]<<"Ipublunits = " << Ipublunits << ", xUnits = " << xUnits << endl;
 
    for (unsigned int i=0; i<NObsBin; i++) {
       double unit = RescaleCrossSectionUnits(BinSize[i], xUnits);
@@ -1374,13 +1585,19 @@ void fastNLOReader::CalcCrossSectionv20(fastNLOCoeffAddFix* c , bool IsLO) {
          double mur      = scalefac * c->GetScaleNode(i,scaleVar,j);
          for (int k=0; k<nxmax; k++) {
             for (int l=0; l<c->GetNSubproc(); l++) {
+               if (!c->SubIsEnabled(l)) continue;
                double xsci     = c->GetSigmaTilde(i,scaleVar,j,k,l) *  c->AlphasTwoPi_v20[i][j]  * c->PdfLc[i][j][k][l] * unit / c->GetNevt(i,l);
                XS->at(i)      +=  xsci;
                QS->at(i)      +=  xsci*mur;
+               //double x1 = c->GetXNode1(i,k);
+               //double x2 = c->GetXNode2(i,k);
+               fXSection_vsX1[i][c->GetX1(i,k)] += xsci;
+               //fXSection_vsX2[i][x2] += xsci;
             }
          }
       }
    }
+   logger.debug["CalcCrossSectionv20"]<<"... leaving CalcCrossSectionv20."<<endl;
 }
 
 
@@ -1395,9 +1612,201 @@ void fastNLOReader::SetUnits(EUnits Unit) {
 }
 
 
+
+//______________________________________________________________________________
+std::vector<double> fastNLOReader::GetXFXSqrtS(double x, double muf) {
+   //!< Wrapper of GetXFX, but for alternative sqrt(s)
+   if (fSqrtSovSP==1) return GetXFX(x,muf);
+   if (x*fSqrtSovSP >= 1) return std::vector<double>(13,0);   //no unphysical x-values
+   vector<double> xfx = GetXFX(x*fSqrtSovSP,muf);
+   //for ( double& f : xfx ) f*=fSqrtSovSP;
+   return xfx;
+}
+
+
+
 //______________________________________________________________________________
-void fastNLOReader::FillAlphasCache() {
-   debug["FillAlphasCache"]<<endl;
+void fastNLOReader::SetNewSqrtS(double newSqrtS, double SqrtStable) {
+   //! Calculate cross section for a different sqrt(s)
+   //! Mind: When requesting a higher sqrt(s) than this table
+   //! was calculatedd for, then a (small) part of the phase space
+   //! is missing
+   //!
+   //! if SqrtStable set to 0, then sqrt is is taken from file
+   //! if newSqrtS set to 0, then center-of-mass reweighting is turned off
+   //!
+   //! Only implemented for hadron-hadron collissions, but not for DIS
+
+   if ( B_LO()  && (B_LO()->GetIPDFdef1() == 2) )  {
+      logger.error["SetNewSqrtS"]<<"Center-of-mass reweighting not implemented for DIS."<<endl;
+      exit(3);
+   }
+   if (SqrtStable == 0) SqrtStable = GetEcms();
+   if (newSqrtS == 0) newSqrtS = GetEcms();
+   fSqrtSovSP = SqrtStable/newSqrtS;
+
+   logger.info["SetNewSqrtS"]<<"Calculating cross sections at center-of-mass energy of "<<newSqrtS<<endl;
+   if (fSqrtSovSP<1)
+      logger.warn["SetNewSqrtS"]<<"Be careful! New center-of-mass energy is higher than that of the file. Some phase space is missing!"<<endl;
+
+
+}
+
+
+//______________________________________________________________________________
+void fastNLOReader::SetCalculateSingleSubprocessOnly(int iSub) {
+   //! Calculate only a single subprocess with id=iSub
+   //! Please inform yourself before on the ordering of the subprocesses,
+   //! and if these are ordered identically for all contributions (LO,NLO,NNLO).
+   //!
+   //!  iSub=-1 resets the calculation to all subprocesses
+
+   /*
+   fSubprocActive.resize(13*13);
+   logger.info["SetCalculateSingleSubprocessOnly"]<<endl;
+   logger.info["SetCalculateSingleSubprocessOnly"]<<"    ***  Use this function carefully ***"<<endl;
+   logger.info["SetCalculateSingleSubprocessOnly"]<<" Please inform yourself about the meaning of the subprocess id for the given file."<<endl;
+   logger.info["SetCalculateSingleSubprocessOnly"]<<" This may also change for the different contribution (LO,NLO,NNLO) of a calculation."<<endl;
+
+   if (iSub < 0) {
+      logger.info["SetCalculateSingleSubprocessOnly"]<<"Activating all contributions."<<endl;
+      fSubprocActive = std::vector<bool>(169,true);
+   }   
+   else if ( iSub < 169 ) {
+      logger.info["SetCalculateSingleSubprocessOnly"]<<"Deactivating all contributions, but id="<<iSub<<endl;
+      fSubprocActive = std::vector<bool>(169,false);
+      fSubprocActive[iSub]=true;
+   }
+   */
+   logger.warn["SetCalculateSingleSubprocessOnly"]<<endl<<"deprecated function, ignoring call"<<endl;
+}
+
+//______________________________________________________________________________
+void fastNLOReader::SetCalculateSubprocesses( const std::vector<int>& iSub ){
+   //! Calculate crosssection with several but not all Subprocesses included.
+   //! Information on the subprocesses available in the table can be retrieved
+   //! by calls to GetNSubproc and GetSubprocIndices. Also note, that subprocesses
+   //! cannot be split into single processes that were already merged at creation time
+   //! of the table.
+   //!
+   //! Use SetCalculateSingleSubprocessOnly( iSub=-1 ) to reset the calculation to use all processes.
+
+   /*
+   fSubprocActive.resize(13*13); //this could probably dropped to the number returned byGetNSubproc
+   logger.info["SetCalculateSubprocesses"]<<endl;
+   logger.info["SetCalculateSubprocesses"]<<"    ***  Use this function carefully ***"<<endl;
+   logger.info["SetCalculateSubprocesses"]<<" Please inform yourself about the meaning of the subprocess id for the given file."<<endl;
+   logger.info["SetCalculateSubprocesses"]<<" This may also change for the different contribution (LO,NLO,NNLO) of a calculation."<<endl;
+   
+   fSubprocActive = std::vector<bool>(13*13,false);
+   for ( int i = 0; i < iSub.size(); i++ )
+      if ( iSub[i] < 13*13 )
+         fSubprocActive[iSub[i]] = true;
+   */
+   logger.warn["SetCalculateSubprocesses"]<<endl<<"deprecated function, ignoring call"<<endl;
+
+}
+
+//______________________________________________________________________________
+void fastNLOReader::SelectProcesses( const std::vector< std::pair<int,int> >& proclist ) {
+   //! Selects subprocesses given in proclist. proclist is a vector of pairs each identifying
+   //! a single process by two PDGIDs. If the table is not compatible with the selected list,
+   //! nothing is changed and a warning is printed.
+   
+   vector< pair<int,int> >* old_list = fselected_processes;
+   fselected_processes = new vector< pair<int,int> >(proclist);
+   
+   if ( UpdateProcesses() ) {
+      delete old_list;
+      return;
+   }
+   delete fselected_processes;
+   fselected_processes = old_list;
+   if ( !UpdateProcesses() ) {
+      logger.error["SelectProcesses"]<<"could not restore previous state after fail, this means something really messed up";
+      exit(1);
+   }
+   
+   logger.warn["SelectProcesses"]<<"could not select requested subprocesses due to incompatible table, ignoring call"<<endl;
+   return;
+}
+
+
+//_____________________________________________________________________________
+void fastNLOReader::SelectProcesses( const std::string& processes ) {
+   std::vector< std::pair<int,int> > tmp;
+   if ( processes == "all" ) {
+      delete fselected_processes;
+      fselected_processes = NULL;
+      UpdateProcesses();
+   } else if ( processes == "none" ) {
+      tmp.clear();
+      SelectProcesses(tmp);
+   } else if ( processes == "gg" ) {
+      tmp = { {0,0} };
+      SelectProcesses(tmp);
+   } else if ( processes == "gq" ) {
+      tmp = { {0,-5},{0,-4},{0,-3},{0,-2},{0,-1},{0,1},{0,2},{0,3},{0,4},{0,5},
+              {-5,0},{-4,0},{-3,0},{-2,0},{-1,0},{1,0},{2,0},{3,0},{4,0},{5,0} };
+      SelectProcesses(tmp);
+   } else if ( processes == "qiqi" ) {
+      tmp = { {-5,-5},{-4,-4},{-3,-3},{-2,-2},{-1,-1},{1,1},{2,2},{3,3},{4,4},{5,5} };
+      SelectProcesses(tmp);
+   } else if ( processes == "qiai" ) {
+      tmp = { {-5,5},{-4,4},{-3,3},{-2,2},{-1,1},{1,-1},{2,-2},{3,-3},{4,-4},{5,-5} };
+      SelectProcesses(tmp);
+   } else if ( processes == "qiqj" ) {
+      tmp.clear();
+      for ( int i = 1; i<=5; i++ )
+         for ( int j = 1; j<=5; j++ )
+            if ( i != j ) {
+               tmp.push_back( {i,j} );
+               tmp.push_back( {-i,-j} );
+            }
+      SelectProcesses(tmp);
+   } else if ( processes == "qiaj" ) {
+      tmp.clear();
+      for ( int i = 1; i<=5; i++ )
+         for ( int j = 1; j<=5; j++ )
+            if ( i != j ) {
+               tmp.push_back( {i,-j} );
+               tmp.push_back( {-i,j} );
+            }
+      SelectProcesses(tmp);
+   } else {
+      logger.warn["SelectProcesses"]<<"unrecognized selection \""<<processes<<"\" ignoring call"<<endl;
+   }
+}
+
+//_____________________________________________________________________________
+bool fastNLOReader::UpdateProcesses() {
+   if ( fselected_processes ) {
+      // enable the selected processes
+      bool success = true;
+      for ( unsigned int j = 0; j<BBlocksSMCalc.size(); j++ ) {
+         for ( unsigned int i = 0; i < BBlocksSMCalc[j].size(); i++ ) {
+            fastNLOCoeffBase* c = BBlocksSMCalc[j][i];
+            // Check if the contribution is additive (and thus eventually has subprocess support)
+            if ( c && c->IsEnabled() && fastNLOCoeffAddBase::CheckCoeffConstants(c,true) ) {
+               ((fastNLOCoeffAddBase*)c)->SubEnableAll( false );
+               success &= ((fastNLOCoeffAddBase*)c)->SubSelect( *fselected_processes, true );
+            }
+         }
+      }
+      return success;
+   } else {
+      // enable all processes
+      for ( unsigned int j = 0; j<BBlocksSMCalc.size(); j++ )
+         for ( unsigned int i = 0; i < BBlocksSMCalc[j].size(); i++ )
+            if ( BBlocksSMCalc[j][i] && BBlocksSMCalc[j][i]->IsEnabled() && fastNLOCoeffAddBase::CheckCoeffConstants(BBlocksSMCalc[j][i], true) )
+               ((fastNLOCoeffAddBase*)BBlocksSMCalc[j][i])->SubEnableAll();
+      return true;
+   }
+}
+
+//______________________________________________________________________________
+void fastNLOReader::FillAlphasCache(bool lForce) {
+   logger.debug["FillAlphasCache"]<<endl;
    //!
    //!  Fill the internal alpha_s cache.
    //!  This is usally called automatically. Only if you
@@ -1406,30 +1815,30 @@ void fastNLOReader::FillAlphasCache() {
    //!
 
    // check if the alpha_s value is somehow reasonable
-   debug["FillAlphasCache"]<<"Sanity check!"<<endl;
+   logger.debug["FillAlphasCache"]<<"Sanity check!"<<endl;
    TestAlphas();
 
    // is there a need for a recalculation?
    const double asNew = CalcReferenceAlphas();
-   if (asNew == fAlphasCached) {
-      debug["FillAlphasCache"]<<"No need for a refilling of AlphasCache. asNew==fAlphasCached="<<asNew<<endl;
+   if (asNew == fAlphasCached && !lForce) {
+      logger.debug["FillAlphasCache"]<<"No need for a refilling of AlphasCache. asNew==fAlphasCached="<<asNew<<endl;
    } else {
       fAlphasCached = asNew;
       for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
          for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
             // Check that this contribution type j and no. i should actually be used
             // Otherwise deactivation of e.g. threshold corr. is not respected here
-            if (bUseSMCalc[j][i] ) {
+            if ( BBlocksSMCalc[j][i] && BBlocksSMCalc[j][i]->IsEnabled() ) {
                fastNLOCoeffBase* c = BBlocksSMCalc[j][i];
-               if ( fastNLOCoeffAddFlex::CheckCoeffConstants(c,true) )
+               if (fastNLOCoeffAddFlex::CheckCoeffConstants(c,true))
                   FillAlphasCacheInBlockBv21((fastNLOCoeffAddFlex*)c);
-               else if ( fastNLOCoeffAddFix::CheckCoeffConstants(c,true) )
+               else if (fastNLOCoeffAddFix::CheckCoeffConstants(c,true))
                   FillAlphasCacheInBlockBv20((fastNLOCoeffAddFix*)c);
-               else if ( fastNLOCoeffMult::CheckCoeffConstants(c,true) )
-                  info["FillAlphasCache"]<<"Nothing to be done for multiplicative contribution."<<endl;
+               else if (fastNLOCoeffMult::CheckCoeffConstants(c,true))
+                  logger.info["FillAlphasCache"]<<"Nothing to be done for multiplicative contribution."<<endl;
                else {
-                  error["FillAlphasCache"]<<"Could not identify contribution. Printing."<<endl;
-                  c->Print();
+                  logger.error["FillAlphasCache"]<<"Could not identify contribution. Printing."<<endl;
+                  c->Print(-1);
                }
             }
          }
@@ -1445,20 +1854,22 @@ void fastNLOReader::FillAlphasCacheInBlockBv20(fastNLOCoeffAddFix* c) {
    //!
 
    // todo: the flag IScaleDep should also indicate whether this contribution may contain scale variations
-   int scaleVar          = c->GetNpow() == ILOord ? 0 : fScalevar;
+   int scalevar          = c->GetNpow() == ILOord ? 0 : fScalevar;
 
-   // Sanity check that scaleVar is in allowed range
+   // Sanity check that scalevar is in allowed range
    // For thresh. corr. can otherwise lead to inf and then segfault!
-   if (scaleVar >= GetNScaleVariations()) {
-      error<<"Trying to refresh cache for non-existing scale variation no. "<<scaleVar<<" while only "<<GetNScaleVariations()<<" exist in total. Exiting."<<endl;
+   // scalevarmax == 0 for contributions not requiring additional tables (LO, multiplicative)
+   int scalevarmax = GetNScaleVariations();
+   if ((scalevarmax != 0) && (scalevar >= scalevarmax)) {
+      logger.error<<"Trying to refresh cache for non-existing scale variation no. "<<scalevar<<" while only "<<GetNScaleVariations()<<" exist in total. Exiting."<<endl;
       exit(1);
    }
-   double scalefac       = fScaleFacMuR/c->GetScaleFactor(scaleVar);
-   debug["FillAlphasCacheInBlockBv20"]<<"scalefac="<<scalefac<<"\tscaleVar="<<scaleVar<<endl;
+   double scalefac       = fScaleFacMuR/c->GetScaleFactor(scalevar);
+   logger.debug["FillAlphasCacheInBlockBv20"]<<"scalefac="<<scalefac<<"\tscalevar="<<scalevar<<endl;
 
    for (unsigned int i=0; i<NObsBin; i++) {
       for (int j=0; j<c->GetTotalScalenodes(); j++) {
-         double mur        = scalefac * c->GetScaleNode(i,scaleVar,j);
+         double mur        = scalefac * c->GetScaleNode(i,scalevar,j);
          double as         = CalcAlphas(mur);
          c->AlphasTwoPi_v20[i][j] = pow(as/TWOPI , c->GetNpow());
       }
@@ -1477,7 +1888,7 @@ void fastNLOReader::FillAlphasCacheInBlockBv21(fastNLOCoeffAddFlex* c) {
          for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
             double mur              = CalcMu(kMuR , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuR);
             double as               = CalcAlphas(mur);
-            double alphastwopi      = pow(as/TWOPI, c->GetNpow() );
+            double alphastwopi      = pow(as/TWOPI, c->GetNpow());
             c->AlphasTwoPi[i][jS1][kS2] = alphastwopi;
          }
       }
@@ -1503,7 +1914,7 @@ double fastNLOReader::CalcReferenceAlphas() {
    } else mu = 91.187611111115*(fScaleFacMuR+0.1)+fScalevar*0.1;
    double as = CalcAlphas(mu);
    if (std::isnan(as)) {
-      error["CalcReferenceAlphas"]<<"Reference alphas is a 'nan' for scale mu="<<mu<<endl;
+      logger.error["CalcReferenceAlphas"]<<"Reference alphas is a 'nan' for scale mu="<<mu<<endl;
       //exit(1);
    }
    return as;
@@ -1516,11 +1927,11 @@ double fastNLOReader::CalcNewPDFChecksum() {
    //! decide, whether PDF cache has to be refilled
 
    // init PDF and check success
-   debug["CalcNewPDFChecksum"]<<"Call InitPDF() in user module."<<endl;
+   logger.debug["CalcNewPDFChecksum"]<<"Call InitPDF() in user module."<<endl;
    fPDFSuccess = InitPDF();
-   debug["CalcNewPDFChecksum"]<<"Return value InitPDF() = "<<fPDFSuccess<<endl;
+   logger.debug["CalcNewPDFChecksum"]<<"Return value InitPDF() = "<<fPDFSuccess<<endl;
    if (!fPDFSuccess) {
-      warn["CalcPDFChecksum"]<<"PDF initialization failed. Please check PDF interface in your FastNLO user module."<<endl;
+      logger.warn["CalcPDFChecksum"]<<"PDF initialization failed. Please check PDF interface in your FastNLO user module."<<endl;
       return 0.;
    }
 
@@ -1529,7 +1940,9 @@ double fastNLOReader::CalcNewPDFChecksum() {
    if (GetIsFlexibleScaleTable()) {
       if (fMuFFunc==kExtern) muf = (*Fct_MuF)(91.,10.)/91.*(fScaleFacMuF+0.5) ;
       else muf = (91.1+0.1*fMuFFunc)/91.+fScaleFacMuF;
-   } else muf=(fScaleFacMuF+0.1)+fScalevar*0.1;
+   } else {
+      muf=(fScaleFacMuF+0.1)+fScalevar*0.1;
+   }
    double cks = CalcChecksum(muf);
    return cks;
 }
@@ -1540,8 +1953,8 @@ double fastNLOReader::CalcChecksum(double mufac) {
    //! caculate a checksum from the PDF in order to check
    //! if the PDF has changed. This is mandatory
    //! since the old LHAPDF code is written in fortran
-   //! and may PDFs may change without any notice.
-   debug["CalcChecksum"]<<"Calculate checksum of 13 flavors, 3 mu_f values, and 3 x-values, for scalefac="<<mufac<<endl;
+   //! and PDFs may change without any notice.
+   logger.debug["CalcChecksum"]<<"Calculate checksum of 13 flavors, 3 mu_f values, and 3 x-values, for scalefac="<<mufac<<endl;
    double cks = 0;
    vector<double> xfx(13);
    const double mf[3] = { 3,10,91.18};
@@ -1549,13 +1962,13 @@ double fastNLOReader::CalcChecksum(double mufac) {
    for (int jf = 0 ; jf<3 ; jf++) {
       double mu = mf[jf]* mufac;//(fScaleFacMuF+0.1)+fScalevar*0.1;
       for (int ix = 0 ; ix<3 ; ix++) {
-         xfx = GetXFX(x[ix],mu);
+         xfx = GetXFXSqrtS(x[ix],mu);
          for (unsigned int fl = 0 ; fl<xfx.size() ; fl++) {
             cks+=xfx[fl];
          }
       }
    }
-   debug["CalcChecksum"]<<"Calculated checksum = "<<cks<<endl;
+   logger.debug["CalcChecksum"]<<"Calculated checksum = "<<cks<<endl;
    return cks;
 }
 
@@ -1566,20 +1979,22 @@ bool fastNLOReader::TestAlphas() {
    //! yields realistic results.
    const double as = CalcAlphas(91.18);
    if (as < 0.01 || as > 0.5) {
-      warn["TestAlphas"]<<"The alphas value, returned by the user class seems to be unreasonably small/large."<<endl;
-      warn["TestAlphas"]<<"The evolution code calculated alphas(Mz~91.18GeV) = "<<as<<endl;
+      logger.warn["TestAlphas"]<<"The alphas value, returned by the user class seems to be unreasonably small/large."<<endl;
+      logger.warn["TestAlphas"]<<"The evolution code calculated alphas(Mz~91.18GeV) = "<<as<<endl;
       return false;
    }
-   debug["TestAlphas"]<<"Sanity check of alpha_s(MZ=91.18) = "<<as<<endl;
+   logger.debug["TestAlphas"]<<"Sanity check of alpha_s(MZ=91.18) = "<<as<<endl;
    return true;
 }
 
 
 //______________________________________________________________________________
 bool fastNLOReader::TestXFX() {
-   vector<double> pdftest = GetXFX(1.e-2,10);
-   if (pdftest.size() < 13) {
-      error["TestXFX"]<<"The pdf array must have the size of 13 flavors, but has only size "<<pdftest.size()<<"\n";
+   const double xtest  = 1.e-2;
+   const double mutest = 10;
+   vector<double> pdftest = GetXFX(xtest,mutest);
+   if (pdftest.size() != 13 && pdftest.size() != 14) {
+      logger.error["TestXFX"]<<"The pdf array must have either 13 flavours or 13+1 for an additional photon entry that is not yet used in fastNLO!" << endl << "   Here, the pdf array's size is: " << pdftest.size() << endl;
       return false;
    }
    // if ( pdftest[6] == 0. )printf("fastNLOReader. Warning. There seems to be no gluon in the pdf.\n");
@@ -1588,7 +2003,7 @@ bool fastNLOReader::TestXFX() {
    // if ( sum== 0. ) printf("fastNLOReader. Error. All 13 pdf probabilities are 0. There might be sth. wrong in the pdf interface. Please check FastNLOUser::GetXFX().\n");
    for (int i = 0 ; i<13 ; i++) {
       if (pdftest[i] > 1.e10 || (pdftest[i] < 1.e-10 && pdftest[i] > 1.e-15)) {
-         warn["TestXFX"]<<"The pdf probability of the "<<i<<"'s flavor seeems to be unreasonably large/small (pdf="<<pdftest[i]<<").\\n";
+         logger.warn["TestXFX"]<<"The pdf probability of the "<<i<<"'s flavor seeems to be unreasonably large/small (pdf="<<pdftest[i]<<") at x="<<xtest<<", mu="<<mutest<<".\n";
       }
    }
    return true;
@@ -1597,8 +2012,9 @@ bool fastNLOReader::TestXFX() {
 
 
 //______________________________________________________________________________
-void fastNLOReader::FillPDFCache(double chksum) {
-   debug["FillPDFCache"]<<"Passed chksum="<<chksum<<". Do not recalculate checksum (which calls InitPDF()) if chksum!=0."<<endl;
+void fastNLOReader::FillPDFCache(double chksum, bool lForce) {
+   logger.debug["FillPDFCache"]<<"Starting FillPDFCache ..."<<endl;
+   logger.debug["FillPDFCache"]<<"Passed chksum="<<chksum<<". Do not recalculate checksum (which calls InitPDF()) if chksum!=0."<<endl;
    //!
    //!  Fill the internal pdf cache.
    //!  This function has to be called by the user, since the
@@ -1606,40 +2022,39 @@ void fastNLOReader::FillPDFCache(double chksum) {
    //!
 
    // reset checknum
-   // check if the alpha_s value is somehow reasonable
    double PDFnew = chksum;
    if (chksum == 0.) {
-      debug["FillPDFCache"]<<"Calculate Checksum!"<<endl;
+      logger.debug["FillPDFCache"]<<"Calculate Checksum!"<<endl;
       PDFnew = CalcNewPDFChecksum();
       if (PDFnew==0.) {
-         warn["FillPDFCache"]<<"PDF Checksum is zero."<<endl;
+         logger.warn["FillPDFCache"]<<"PDF Checksum is zero."<<endl;
       }
-      debug["FillPDFCache"]<<"PDF Checksum = "<<PDFnew<<endl;
+      logger.debug["FillPDFCache"]<<"PDF Checksum = "<<PDFnew<<endl;
    }
 
    // is there a need for a recalculation?
-   if (fPDFCached != 0. && fabs(PDFnew/fPDFCached - 1.) < 1.e-7) {
-      debug["FillPDFCache"]<<"No need for a refilling of PDFCache. fPDFCached=RefreshPDFChecksum()"<<PDFnew<<endl;
+   if (fPDFCached != 0. && fabs(PDFnew/fPDFCached - 1.) < 1.e-7 && !lForce) {
+      logger.debug["FillPDFCache"]<<"No need for a refilling of PDFCache. fPDFCached=RefreshPDFChecksum()"<<PDFnew<<endl;
    } else {
-      debug["FillPDFCache"]<<"Refilling PDF cache"<<endl;
+      logger.debug["FillPDFCache"]<<"Refilling PDF cache"<<endl;
       fPDFCached = PDFnew;
 
       // check (or not) if the pdf is somehow reasonable
       TestXFX();
-      if ( FNLO_HOPPET[0] != '\0' ) {
-         if (fUseHoppet){
-            //Also refill Hoppet cache and assign new PDF
-            HoppetInterface::InitHoppet(*this);
-         }
+#ifdef FNLO_HOPPET
+      if (fUseHoppet) {
+	 //Also refill Hoppet cache and assign new PDF
+	 HoppetInterface::InitHoppet(*this);
       }
+#endif
 
       for (unsigned int j = 0 ; j<BBlocksSMCalc.size() ; j++) {
          for (unsigned int i = 0 ; i<BBlocksSMCalc[j].size() ; i++) {
             // Check that this contribution type j and no. i should actually be used
             // Otherwise deactivation of e.g. threshold corr. is not respected here
-            if (bUseSMCalc[j][i] ) {
+            if ( BBlocksSMCalc[j][i] && BBlocksSMCalc[j][i]->IsEnabled() ) {
                fastNLOCoeffBase* c = BBlocksSMCalc[j][i];
-               if ( fastNLOCoeffAddBase::CheckCoeffConstants(c,true) ) {
+               if (fastNLOCoeffAddBase::CheckCoeffConstants(c,true)) {
                   fastNLOCoeffAddBase* c = (fastNLOCoeffAddBase*)BBlocksSMCalc[j][i];
                   // linear: DIS-case
                   // ---- DIS ---- //
@@ -1647,8 +2062,13 @@ void fastNLOReader::FillPDFCache(double chksum) {
                      if (c->GetNPDFDim() == 0) {
                         if (!GetIsFlexibleScaleTable(c))
                            FillBlockBPDFLCsDISv20((fastNLOCoeffAddFix*)c);
-                        else
-                           FillBlockBPDFLCsDISv21((fastNLOCoeffAddFlex*)c);
+                        else {
+                           // DIS specific hack, as we do not intend to include data or mult. contributions
+                           if (BBlocksSMCalc[0][0] != NULL)
+                              FillBlockBPDFLCsDISv21((fastNLOCoeffAddFlex*)c,(fastNLOCoeffAddFlex*)BBlocksSMCalc[0][0]);
+                           else //otherwise, please simply use:
+                              FillBlockBPDFLCsDISv21((fastNLOCoeffAddFlex*)c);
+                        }
                      }
                   }
                   // ---- pp ---- //
@@ -1656,30 +2076,29 @@ void fastNLOReader::FillPDFCache(double chksum) {
                      if (!GetIsFlexibleScaleTable(c)) FillBlockBPDFLCsHHCv20((fastNLOCoeffAddFix*)c);
                      else FillBlockBPDFLCsHHCv21((fastNLOCoeffAddFlex*)c);
                   } else {
-                     error["FillPDFCache"]<<"IPDFdef of tables must be 1 or 2.\n";
+                     logger.error["FillPDFCache"]<<"IPDFdef of tables must be 1 or 2.\n";
                   }
-               }
-               else if ( fastNLOCoeffMult::CheckCoeffConstants(c,true) ) {
-                  info["FillPDFCache"]<<"Nothing to be done for multiplicative contribution."<<endl;
-               }
-               else {
-                  error["FillPDFCache"]<<"Could not identify contribution. Printing."<<endl;
-                  c->Print();
+               } else if (fastNLOCoeffMult::CheckCoeffConstants(c,true)) {
+                  logger.info["FillPDFCache"]<<"Nothing to be done for multiplicative contribution."<<endl;
+               } else {
+                  logger.error["FillPDFCache"]<<"Could not identify contribution. Printing."<<endl;
+                  c->Print(-1);
                }
             }
          }
       }
    }
+   logger.debug["FillPDFCache"]<<"... leaving FillPDFCache."<<endl;
 }
 
 
 //______________________________________________________________________________
 void fastNLOReader::FillBlockBPDFLCsDISv20(fastNLOCoeffAddFix* c) {
    //! Fill member variables in fastNLOCoeffAddFix with PDFCache
-   debug["FillBlockBPDFLCsDISv20"]<<endl;
+   logger.debug["FillBlockBPDFLCsDISv20"]<<endl;
    // todo: flag IScaleDep should indicate whether scale variations may exist or not.
-   int scaleVar          = c->GetNpow() == ILOord ? 0 : fScalevar;
-   double scalefac       = (c->GetScaleFactor(scaleVar) == fScaleFacMuF) ? 1. : fScaleFacMuF;
+   int scalevar          = c->GetNpow() == ILOord ? 0 : fScalevar;
+   double scalefac       = (c->GetScaleFactor(scalevar) == fScaleFacMuF) ? 1. : fScaleFacMuF;
    vector<double> xfx(13); // PDFs of all partons
    vector<double> xfxspl(13); // PDFs splitting functions of all partons
    if (!GetIsFlexibleScaleTable(c)) {
@@ -1688,15 +2107,15 @@ void fastNLOReader::FillBlockBPDFLCsDISv20(fastNLOCoeffAddFix* c) {
          for (int j=0; j<c->GetNScaleNode(); j++) {
             for (int k=0; k<nxmax; k++) {
                double xp     = c->GetXNode1(i,k);
-               double muf    = scalefac * c->GetScaleNode(i,scaleVar,j);
-               xfx = GetXFX(xp,muf);
+               double muf    = scalefac * c->GetScaleNode(i,scalevar,j);
+               xfx = GetXFXSqrtS(xp,muf);
 
-               if ( FNLO_HOPPET[0] != '\0' ) {
-                  if (fUseHoppet)
-                     xfxspl        = HoppetInterface::GetSpl(xp,muf);
-               }
+#ifdef FNLO_HOPPET
+	       if (fUseHoppet)
+		  xfxspl        = HoppetInterface::GetSpl(xp,muf);
+#endif
                c->PdfLc[i][j][k] = CalcPDFLinearCombination(c,xfx);
-               if (fUseHoppet){
+               if (fUseHoppet) {
                   c->PdfSplLc1[i][j][k] = CalcPDFLinearCombination(c, xfxspl);
                }
                //                vector < double > buffer = CalcPDFLinearCombDIS(xfx , c->GetNSubproc());
@@ -1711,16 +2130,43 @@ void fastNLOReader::FillBlockBPDFLCsDISv20(fastNLOCoeffAddFix* c) {
 
 
 //______________________________________________________________________________
-void fastNLOReader::FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* c) {
+void fastNLOReader::FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* c, fastNLOCoeffAddFlex* c0) {
    //! Fill member variables in fastNLOCoeffAddFlex with PDFCache
-   debug["FillBlockBPDFLCsDISv21"]<<endl;//<<"CoeffTable = "<<endl;
+   logger.debug["FillBlockBPDFLCsDISv21"]<<endl;//<<"CoeffTable = "<<endl;
 
    if (c->PdfLcMuVar.empty()) {
-      error<< "PdfLcMuVar is empty in CoeffTable. Printing and exiting."<<endl;
-      c->Print();
+      logger.error<< "PdfLcMuVar is empty in CoeffTable. Printing and exiting."<<endl;
+      c->Print(-1);
       exit(1);
    }
 
+   // we take the PDF coefficients from the first contributions if compatible
+   // this avoids repetive access to LHAPDF
+   //   static const bool SpeedUp = false;
+   static const bool SpeedUp = BBlocksSMCalc[0][0] != NULL;
+   bool IsCompatible = false;
+   if (SpeedUp) {
+      if (c0 != NULL && c0 != c && fCoeff.size()>1) {
+         IsCompatible = true;
+         for (unsigned int i=0; i<NObsBin; i++) {
+            IsCompatible &= (c->GetNScaleNode1(i) == c0->GetNScaleNode1(i)) ;
+            IsCompatible &= (c->GetNScaleNode2(i) == c0->GetNScaleNode2(i)) ;
+            IsCompatible &= (c->GetNxmax(i) == c0->GetNxmax(i)) ;
+         }
+         int i=0; // just the first obsbin
+         for (int x=0; x<c->GetNxmax(i); x++)
+            IsCompatible &= (c->GetXNode1(i,x) == c0->GetXNode1(i,x));
+         for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++)
+            IsCompatible &=  c->GetScaleNode1(i,jS1) ==  c0->GetScaleNode1(i,jS1);
+         for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
+            IsCompatible &=  c->GetScaleNode2(i,kS2) ==  c0->GetScaleNode2(i,kS2);
+         }
+      }
+      if (c==c0 && c->PdfXfx.empty())
+         fastNLOTools::ResizeFlexibleVector(c->PdfXfx,c->PdfLcMuVar);
+      //c->PdfXfx = c->PdfLcMuVar; // resize
+   }
+
    for (unsigned int i=0; i<NObsBin; i++) {
       // speed up! if mu_f is only dependent on one variable, we can safe the loop over the other one
       for (int x=0; x<c->GetNxmax(i); x++) {
@@ -1730,34 +2176,44 @@ void fastNLOReader::FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* c) {
             for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                   double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
-                  c->PdfLcMuVar[i][x][jS1][kS2] = CalcPDFLinearCombination(c,GetXFX(xp,muf));
-                  //c->PdfLcMuVar[i][x][jS1][kS2] = CalcPDFLinearCombDIS(GetXFX(xp,muf) , c->GetNSubproc() );
+
+                  if (SpeedUp) {
+                     if (c == c0)
+                        c->PdfXfx[i][x][jS1][kS2] = GetXFXSqrtS(xp,muf);
+                     c->PdfLcMuVar[i][x][jS1][kS2] = CalcPDFLinearCombination(c,c0->PdfXfx[i][x][jS1][kS2]);
+                  } else {
+                     // this is the default code !
+                     c->PdfLcMuVar[i][x][jS1][kS2] = CalcPDFLinearCombination(c,GetXFXSqrtS(xp,muf));
+                  }
+
+                  // if ( i==1 && x==1 && jS1==1 && kS2==1 ) {
+                  //    cout<<"muf="<<muf<<"\tpdf="<<c->PdfLcMuVar[i][x][jS1][kS2][0]<<"\tc="<<c<<endl;
+                  // }
+                  //c->PdfLcMuVar[i][x][jS1][kS2] = CalcPDFLinearCombDIS(GetXFXSqrtS(xp,muf) , c->GetNSubproc() );
                }
             }
-         }
-         else if (fMuFFunc == kScale2) { // speed up
+         } else if (fMuFFunc == kScale2) { // speed up
             for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                double muf = CalcMu(kMuF , 0 ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
-               //vector < double > buffer = CalcPDFLinearCombDIS(GetXFX(xp,muf) , c->GetNSubproc() );
-               vector<double > buffer = CalcPDFLinearCombination(c,GetXFX(xp,muf));
+               //vector < double > buffer = CalcPDFLinearCombDIS(GetXFXSqrtS(xp,muf) , c->GetNSubproc() );
+               vector<double > buffer = CalcPDFLinearCombination(c,GetXFXSqrtS(xp,muf));
                for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                   c->PdfLcMuVar[i][x][jS1][kS2] = buffer;
                }
             }
-         }
-         else if (fMuFFunc == kScale1) { // speed up
+         } else if (fMuFFunc == kScale1) { // speed up
             for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) , 0 , fScaleFacMuF);
-               //vector < double > buffer = CalcPDFLinearCombDIS(GetXFX(xp,muf) , c->GetNSubproc() );
-               vector<double > buffer = CalcPDFLinearCombination(c,GetXFX(xp,muf));
-                for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
-                   c->PdfLcMuVar[i][x][jS1][kS2] = buffer;
+               //vector < double > buffer = CalcPDFLinearCombDIS(GetXFXSqrtS(xp,muf) , c->GetNSubproc() );
+               vector<double > buffer = CalcPDFLinearCombination(c,GetXFXSqrtS(xp,muf));
+               for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
+                  c->PdfLcMuVar[i][x][jS1][kS2] = buffer;
                }
             }
          }
       }
    }
-   debug["FillBlockBPDFLCsDISv21"]<<"done." <<endl;
+   logger.debug["FillBlockBPDFLCsDISv21"]<<"done." <<endl;
 
 }
 
@@ -1765,9 +2221,9 @@ void fastNLOReader::FillBlockBPDFLCsDISv21(fastNLOCoeffAddFlex* c) {
 //______________________________________________________________________________
 void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
    //! Fill member variables in fastNLOCoeffAddFix with PDFCache
-   int scaleVar          = c->GetNpow() == ILOord ? 0 : fScalevar; // Use IScaleDep
-   double scalefac       = fScaleFacMuF/c->GetScaleFactor(scaleVar);
-   debug["FillBlockBPDFLCsHHCv20"]<<"scalefac="<<scalefac<<endl;
+   int scalevar          = c->GetNpow() == ILOord ? 0 : fScalevar; // Use IScaleDep
+   double scalefac       = fScaleFacMuF/c->GetScaleFactor(scalevar);
+   logger.debug["FillBlockBPDFLCsHHCv20"]<<"scalefac="<<scalefac<<endl;
 
    bool IsPPBar;
    // ----- if ppbar ---- //
@@ -1780,14 +2236,14 @@ void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
    }
    // ----- anything else ---- //
    else {
-      error<<"Found beam particles to have PDG codes " << c->NPDFPDG[0] << " and " << c->NPDFPDG[1] << ",\n";
-      error<<"but cannot deal with tables other than pp or ppbar, aborting! \n";
+      logger.error<<"Found beam particles to have PDG codes " << c->NPDFPDG[0] << " and " << c->NPDFPDG[1] << ",\n";
+      logger.error<<"but cannot deal with tables other than pp or ppbar, aborting! \n";
       exit(1);
    }
 
 
    // half matrix notation
-   if ( c->GetNPDFDim() == 1 ) {
+   if (c->GetNPDFDim() == 1) {
       vector < vector < double > > xfx; // PDFs of all partons
       vector < vector < double > > xfxspl; // PDFs splitting functions of all partons
       for (unsigned int i=0; i<NObsBin; i++) {
@@ -1795,19 +2251,19 @@ void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
          int nxbins1 = c->GetNxtot1(i); // number of columns in half matrix
          xfx.resize(nxbins1);
 
-         if (fUseHoppet){
+         if (fUseHoppet) {
             xfxspl.resize(nxbins1);
          }
          for (int j=0; j<c->GetNScaleNode(); j++) {
             // determine all pdfs of hadron1
             for (int k=0; k<nxbins1; k++) {
                double xp     = c->GetXNode1(i,k);
-               double muf    = scalefac * c->GetScaleNode(i,scaleVar,j);
-               xfx[k]        = GetXFX(xp,muf);
-               if ( FNLO_HOPPET[0] != '\0' ) {
-                  if (fUseHoppet)
-                     xfxspl[k]        = HoppetInterface::GetSpl(xp,muf);
-               }
+               double muf    = scalefac * c->GetScaleNode(i,scalevar,j);
+               xfx[k]        = GetXFXSqrtS(xp,muf);
+#ifdef FNLO_HOPPET
+	       if (fUseHoppet)
+		  xfxspl[k]        = HoppetInterface::GetSpl(xp,muf);
+#endif
             }
             int x1bin = 0;
             int x2bin = 0;
@@ -1819,7 +2275,7 @@ void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
                c->PdfLc[i][j][k] = CalcPDFLinearCombination(c,xfx[x1bin],xfx[x2bin], IsPPBar);
                // TODO: Georg was using (x1, x2) that was wrong with original x1bin, x2bin naming
                // TODO: Check with Georg what is correct now after the fix
-               if (fUseHoppet){
+               if (fUseHoppet) {
                   c->PdfSplLc1[i][j][k] = CalcPDFLinearCombination(c, xfx[x1bin], xfxspl[x2bin], IsPPBar);
                   c->PdfSplLc2[i][j][k] = CalcPDFLinearCombination(c, xfxspl[x1bin], xfx[x2bin], IsPPBar);
                }
@@ -1847,7 +2303,7 @@ void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
    }
 
    // full matrix notation
-   else if ( c->GetNPDFDim() == 2 ){
+   else if (c->GetNPDFDim() == 2) {
       vector < vector < double > > xfx1; // PDFs of all partons
       vector < vector < double > > xfx2; // PDFs of all partons
       vector < vector < double > > xfxspl1; // PDFs splitting functions of all partons
@@ -1858,38 +2314,36 @@ void fastNLOReader::FillBlockBPDFLCsHHCv20(fastNLOCoeffAddFix* c) {
          int nxbins2 = c->GetNxtot2(i); // number of xnodes ( == nxmax / Nxtot1[i] )
          xfx1.resize(nxbins1);
          xfx2.resize(nxbins2);
-         if (fUseHoppet){
+         if (fUseHoppet) {
             xfxspl1.resize(nxbins1);
             xfxspl2.resize(nxbins1);
          }
          for (int j=0; j<c->GetNScaleNode(); j++) {
             // determine all pdfs of hadron1
-            double muf    = scalefac * c->GetScaleNode(i,scaleVar,j);
+            double muf    = scalefac * c->GetScaleNode(i,scalevar,j);
             for (int k=0; k<nxbins1; k++) {
                double xp     = c->GetXNode1(i,k);
-               xfx1[k]        = GetXFX(xp,muf);
-               if ( FNLO_HOPPET[0] != '\0' ) {
+               xfx1[k]        = GetXFXSqrtS(xp,muf);
+#ifdef FNLO_HOPPET
                   if (fUseHoppet)
                      xfxspl1[k]        = HoppetInterface::GetSpl(xp,muf);
-               }
-
+#endif
             }
             // determine all pdfs of hadron2
             for (int k=0; k<nxbins2; k++) {
                double xp     = c->GetXNode2(i,k);
-               xfx2[k]       = GetXFX(xp,muf);
-               if ( FNLO_HOPPET[0] != '\0' ) {
+               xfx2[k]       = GetXFXSqrtS(xp,muf);
+#ifdef FNLO_HOPPET
                   if (fUseHoppet)
                      xfxspl2[k]        = HoppetInterface::GetSpl(xp,muf);
-               }
-
+#endif
             }
             // full matrix notation
             for (int k=0; k<nxmax; k++) {
                int x1bin = k % c->GetNxtot1(i);
                int x2bin = k / c->GetNxtot1(i);
                c->PdfLc[i][j][k] = CalcPDFLinearCombination(c,xfx1[x1bin],xfx2[x2bin], IsPPBar);
-               if (fUseHoppet){
+               if (fUseHoppet) {
                   c->PdfSplLc1[i][j][k] = CalcPDFLinearCombination(c, xfx1[x1bin], xfxspl2[x2bin], IsPPBar);
                   c->PdfSplLc2[i][j][k] = CalcPDFLinearCombination(c, xfxspl1[x1bin], xfx2[x2bin], IsPPBar);
                }
@@ -1906,7 +2360,7 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
    //! Fill member variables in fastNLOCoeffAddFlex with PDFCache
    //! The calculation is improved, if the factorization scale is
    //! calculated from only one scale variable (i.e. kScale1 or kScale2)
-   debug["FillBlockBPDFLCsHHCv21"]<<endl;
+   logger.debug["FillBlockBPDFLCsHHCv21"]<<endl;
    if (c->PdfLcMuVar.empty()) {
       cout<< "PdfLcMuVar in CoeffTable is not accessible (resized)."<<endl;
       exit(1);
@@ -1923,14 +2377,14 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
    }
    // ----- anything else ---- //
    else {
-      error<<"Found beam particles to have PDG codes " << c->NPDFPDG[0] << " and " << c->NPDFPDG[1] << ",\n";
-      error<<"but cannot deal with tables other than pp or ppbar, aborting! \n";
+      logger.error<<"Found beam particles to have PDG codes " << c->NPDFPDG[0] << " and " << c->NPDFPDG[1] << ",\n";
+      logger.error<<"but cannot deal with tables other than pp or ppbar, aborting! \n";
       exit(1);
    }
 
 
    // half-matrix notation
-   if ( c->GetNPDFDim() == 1 ) {
+   if (c->GetNPDFDim() == 1) {
       vector < vector < double > > xfx; // PDFs of all partons
       for (unsigned int i=0; i<NObsBin; i++) {
          int nxmax = c->GetNxmax(i);
@@ -1943,7 +2397,7 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   for (int k=0; k<nxbins1; k++) {
                      double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
                      double xp   = c->GetXNode1(i,k);
-                     xfx[k] = GetXFX(xp,muf);
+                     xfx[k] = GetXFXSqrtS(xp,muf);
                   }
                   int x1bin = 0;
                   int x2bin = 0;
@@ -1958,14 +2412,13 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   }
                }
             }
-         }
-         else if (fMuFFunc == kScale2) {   // speed up
+         } else if (fMuFFunc == kScale2) { // speed up
             for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                // determine all pdfs of hadron1
                for (int k=0; k<nxbins1; k++) {
                   double muf = CalcMu(kMuF , 0 ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
                   double xp     = c->GetXNode1(i,k);
-                  xfx[k] = GetXFX(xp,muf);
+                  xfx[k] = GetXFXSqrtS(xp,muf);
                }
                for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                   int x1bin = 0;
@@ -1980,14 +2433,13 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   }
                }
             }
-         }
-         else if (fMuFFunc == kScale1) {   // speed up
+         } else if (fMuFFunc == kScale1) { // speed up
             for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                // determine all pdfs of hadron1
                for (int k=0; k<nxbins1; k++) {
                   double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) , 0 , fScaleFacMuF);
                   double xp     = c->GetXNode1(i,k);
-                  xfx[k] = GetXFX(xp,muf);
+                  xfx[k] = GetXFXSqrtS(xp,muf);
                }
                for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                   int x1bin = 0;
@@ -2007,7 +2459,7 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
    }
 
    // full-matrix notation
-   else if ( c->GetNPDFDim() == 2 ) {
+   else if (c->GetNPDFDim() == 2) {
       vector < vector < double > > xfx1; // hadron1
       vector < vector < double > > xfx2; // hadron2
       for (unsigned int i=0; i<NObsBin; i++) {
@@ -2023,12 +2475,12 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
                   for (int k=0; k<nxbins1; k++) {
                      double xp   = c->GetXNode1(i,k);
-                     xfx1[k] = GetXFX(xp,muf);
+                     xfx1[k] = GetXFXSqrtS(xp,muf);
                   }
                   // determine all pdfs of hadron2
                   for (int k=0; k<nxbins2; k++) {
                      double xp   = c->GetXNode2(i,k);
-                     xfx2[k] = GetXFX(xp,muf);
+                     xfx2[k] = GetXFXSqrtS(xp,muf);
                   }
                   for (int x=0; x<nxmax; x++) {
                      // CalcPDFLinearCombination calculats Anti-proton from proton
@@ -2038,19 +2490,18 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   }
                }
             }
-         }
-         else if (fMuFFunc == kScale2) {   // speed up
+         } else if (fMuFFunc == kScale2) { // speed up
             for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                double muf = CalcMu(kMuF , 0 ,  c->GetScaleNode2(i,kS2) , fScaleFacMuF);
                // determine all pdfs of hadron1
                for (int k=0; k<nxbins1; k++) {
                   double xp  = c->GetXNode1(i,k);
-                  xfx1[k] = GetXFX(xp,muf);
+                  xfx1[k] = GetXFXSqrtS(xp,muf);
                }
                // determine all pdfs of hadron2
                for (int k=0; k<nxbins2; k++) {
                   double xp  = c->GetXNode2(i,k);
-                  xfx2[k] = GetXFX(xp,muf);
+                  xfx2[k] = GetXFXSqrtS(xp,muf);
                }
                for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                   for (int x=0; x<nxmax; x++) {
@@ -2060,19 +2511,18 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
                   }
                }
             }
-         }
-         else if (fMuFFunc == kScale1) {   // speed up
+         } else if (fMuFFunc == kScale1) { // speed up
             for (unsigned int jS1=0; jS1<c->GetNScaleNode1(i); jS1++) {
                // determine all pdfs of hadron1
                double muf = CalcMu(kMuF , c->GetScaleNode1(i,jS1) , 0 , fScaleFacMuF);
                for (int k=0; k<nxbins1; k++) {
                   double xp   = c->GetXNode1(i,k);
-                  xfx1[k] = GetXFX(xp,muf);
+                  xfx1[k] = GetXFXSqrtS(xp,muf);
                }
                // determine all pdfs of hadron2
                for (int k=0; k<nxbins2; k++) {
                   double xp   = c->GetXNode2(i,k);
-                  xfx2[k] = GetXFX(xp,muf);
+                  xfx2[k] = GetXFXSqrtS(xp,muf);
                }
                for (unsigned int kS2=0; kS2<c->GetNScaleNode2(i); kS2++) {
                   for (int x=0; x<nxmax; x++) {
@@ -2092,36 +2542,55 @@ void fastNLOReader::FillBlockBPDFLCsHHCv21(fastNLOCoeffAddFlex* c) {
 //______________________________________________________________________________
 void fastNLOReader::SetExternalFuncForMuR(double(*Func)(double,double)) {
    if (!GetIsFlexibleScaleTable()) {
-      warn["SetExternalFuncForMuR"]<<"This is not a flexible-scale table and SetExternalFuncForMuR has no impact.\n";
-      man<<"Please use a flexible-scale table, if you want to change your scale definition.\n";
+      logger.warn["SetExternalFuncForMuR"]<<"This is not a flexible-scale table and SetExternalFuncForMuR has no impact.\n";
+      logger.man<<"Please use a flexible-scale table, if you want to change your scale definition.\n";
       return;
    }
 
    Fct_MuR = Func;
    SetFunctionalForm(kExtern , kMuR);
-   info["SetExternalFuncForMuR"]<<"Testing external function:"<<endl;
-   info<<"Scale1 = 1 ,      Scale2 = 1        ->  mu = func(1,1)             = "<<(*Fct_MuR)(1,1)<<endl;
-   info<<"Scale1 = 91.1876, Scale2 = 91.1876  ->  mu = func(91.1876,91.1876) = "<<(*Fct_MuR)(91.1876,91.1876)<<endl;
-   info<<"Scale1 = 1,       Scale2 = 91.1876  ->  mu = func(1,91.1876)       = "<<(*Fct_MuR)(1,91.1876)<<endl;
-   info<<"Scale1 = 91.1876, Scale2 = 1        ->  mu = func(91.1876,1)       = "<<(*Fct_MuR)(91.1876,1)<<endl;
+   logger.info["SetExternalFuncForMuR"]<<"Testing external function:"<<endl;
+   logger.info<<"Scale1 = 1 ,      Scale2 = 1        ->  mu = func(1,1)             = "<<(*Fct_MuR)(1,1)<<endl;
+   logger.info<<"Scale1 = 91.1876, Scale2 = 91.1876  ->  mu = func(91.1876,91.1876) = "<<(*Fct_MuR)(91.1876,91.1876)<<endl;
+   logger.info<<"Scale1 = 1,       Scale2 = 91.1876  ->  mu = func(1,91.1876)       = "<<(*Fct_MuR)(1,91.1876)<<endl;
+   logger.info<<"Scale1 = 91.1876, Scale2 = 1        ->  mu = func(91.1876,1)       = "<<(*Fct_MuR)(91.1876,1)<<endl;
 }
 
 
 //______________________________________________________________________________
 void fastNLOReader::SetExternalFuncForMuF(double(*Func)(double,double)) {
    if (!GetIsFlexibleScaleTable()) {
-      warn["SetExternalFuncForMuF"]<<"This is not a flexible-scale table and SetExternalFuncForMuF has no impact.\n";
-      man<<"Please use a flexible-scale table, if you want to change your scale definition.\n";
+      logger.warn["SetExternalFuncForMuF"]<<"This is not a flexible-scale table and SetExternalFuncForMuF has no impact.\n";
+      logger.man<<"Please use a flexible-scale table, if you want to change your scale definition.\n";
       return;
    }
 
    Fct_MuF = Func;
    SetFunctionalForm(kExtern , kMuF);
-   info["SetExternalFuncForMuF"]<<"Testing external function:"<<endl;
-   info<<"Scale1 = 1 ,      Scale2 = 1        ->  mu = func(1,1)             = "<<(*Fct_MuF)(1,1)<<endl;
-   info<<"Scale1 = 91.1876, Scale2 = 91.1876  ->  mu = func(91.1876,91.1876) = "<<(*Fct_MuF)(91.1876,91.1876)<<endl;
-   info<<"Scale1 = 1,       Scale2 = 91.1876  ->  mu = func(1,91.1876)       = "<<(*Fct_MuF)(1,91.1876)<<endl;
-   info<<"Scale1 = 91.1876, Scale2 = 1        ->  mu = func(91.1876,1)       = "<<(*Fct_MuF)(91.1876,1)<<endl;
+   logger.info["SetExternalFuncForMuF"]<<"Testing external function:"<<endl;
+   logger.info<<"Scale1 = 1 ,      Scale2 = 1        ->  mu = func(1,1)             = "<<(*Fct_MuF)(1,1)<<endl;
+   logger.info<<"Scale1 = 91.1876, Scale2 = 91.1876  ->  mu = func(91.1876,91.1876) = "<<(*Fct_MuF)(91.1876,91.1876)<<endl;
+   logger.info<<"Scale1 = 1,       Scale2 = 91.1876  ->  mu = func(1,91.1876)       = "<<(*Fct_MuF)(1,91.1876)<<endl;
+   logger.info<<"Scale1 = 91.1876, Scale2 = 1        ->  mu = func(91.1876,1)       = "<<(*Fct_MuF)(91.1876,1)<<endl;
+}
+
+//______________________________________________________________________________
+void fastNLOReader::SetExternalConstantForMuR(double MuR) {
+   //! Set value for mu_r if mu_r is chosen to be constant
+   //! EScaleFunctionalForm == kConst
+   fConst_MuR = MuR;
+   logger.info << "Using constant value " << fConst_MuR << " for MuR" << endl;
+   SetFunctionalForm(kConst, kMuR);
+}
+
+
+//______________________________________________________________________________
+void fastNLOReader::SetExternalConstantForMuF(double MuF) {
+   //! Set value for mu_r if mu_r is chosen to be constant
+   //! EScaleFunctionalForm == kConst
+   fConst_MuF = MuF;
+   logger.info << "Using constant value " << fConst_MuF << " for MuF" << endl;
+   SetFunctionalForm(kConst, kMuF);
 }
 
 
@@ -2135,35 +2604,41 @@ void fastNLOReader::SetFunctionalForm(EScaleFunctionalForm func , fastNLO::EMuX
    //!
 
    if (!GetIsFlexibleScaleTable()) {
-      warn<<"This is not a flexible-scale table. SetFunctionalForm cannot be used.\n";
+      logger.warn<<"This is not a flexible-scale table. SetFunctionalForm cannot be used.\n";
       return;
    }
 
    // ---- setting scale ---- //
-   if (MuX == kMuR) fMuRFunc = func;
-   else fMuFFunc = func;
-
+   if (MuX == kMuR) {
+      fMuRFunc = func;
+      // Alphas Cache needs to be recalculated.
+      fAlphasCached = 0.;
+   } else {
+      fMuFFunc = func;
+      // PDF Cache needs to be recalculated.
+      fPDFCached = 0.;
+   }
 
    // ---- cross check ---- //
    if (func == kScale2 || func == kQuadraticSum ||  func == kQuadraticMean || func == kQuadraticSumOver4 ||
-       func == kLinearMean || func == kLinearSum  ||  func == kScaleMax || func == kScaleMin ||
-       func == kProd || func == kExpProd2 ) {
+         func == kLinearMean || func == kLinearSum  ||  func == kScaleMax || func == kScaleMin ||
+         func == kProd || func == kExpProd2 || func == kS2plusS1half || func == kS2plusS1fourth || func == kPow4Sum || func == kWgtAvg) {
 
       fastNLOCoeffAddFlex* cNLO = (fastNLOCoeffAddFlex*)B_NLO();
-      if ( !cNLO ) cNLO = (fastNLOCoeffAddFlex*)B_LO(); //crash safe
+      if (!cNLO) cNLO = (fastNLOCoeffAddFlex*)B_Any();   //crash safe
       int nnode = cNLO->GetNScaleNode2(0);
-      if (nnode <= 3) {
-         error<<"There is no second scale variable available in this table. Using fastNLO::kScale1 only.\n";
+      if (nnode < 1) {
+         logger.error<<"There is no second scale variable available in this table. Using fastNLO::kScale1 only.\n";
          SetFunctionalForm(kScale1,MuX);
       }
-      for (unsigned int i=0; i<NObsBin; i++) {
-         nnode = cNLO->GetNScaleNode2(i);
-         if (nnode < 4) {
-            warn<<"Scale2 has only very little nodes (n="<<nnode<<") in bin "<<i<<".\n";
-         }
-      }
+      // for (unsigned int i=0; i<NObsBin; i++) {
+      //    nnode = cNLO->GetNScaleNode2(i);
+      //    if (nnode < 4) {
+      //       logger.warn<<"Scale2 has only very little nodes (n="<<nnode<<") in bin "<<i<<".\n";
+      //    }
+      // }
    }
-   //PrintScaleSettings(MuX);//not yet ported to v2.2
+   PrintScaleSettings(MuX);//not yet ported to v2.2
 }
 
 
@@ -2180,11 +2655,9 @@ void fastNLOReader::SetMuFFunctionalForm(EScaleFunctionalForm func) {
 
 
 //______________________________________________________________________________
-
-
-
 bool fastNLOReader::SetScaleFactorsMuRMuF(double xmur, double xmuf) {
-   debug["SetScaleFactorsMuRMuF"]<<"Setting to scale factors xmur = "<<xmur<<" and xmuf = "<<xmuf<<endl;
+   logger.debug["SetScaleFactorsMuRMuF"]<<"Starting SetScaleFactorsMuRMuF ..."<<endl;
+   logger.debug["SetScaleFactorsMuRMuF"]<<"Setting to scale factors xmur = "<<xmur<<" and xmuf = "<<xmuf<<endl;
    /**
    // Set renormalization and factorization scale factors simultaneously for scale variations in all v2 tables.
    // You have to ReFill your cache!
@@ -2205,18 +2678,25 @@ bool fastNLOReader::SetScaleFactorsMuRMuF(double xmur, double xmuf) {
 
    // Check whether xmur and xmuf are positive and at least larger than 1.E-6
    if (xmur < 1.E-6 || xmuf < 1.E-6) {
-      error<<"Selected scale factors too small ( < 1.E-6 )! Ignoring call."<<endl;
+      logger.error<<"Selected scale factors too small ( < 1.E-6 )! Ignoring call."<<endl;
       return false;
    }
 
-   // Check whether pQCD contributions beyond LO exist and are activated
-   bool lknlo = false;
+   // Check whether pQCD LO contributions or beyond exist and are activated
+   bool lklo = false;
+   bool lkho = false;
    if (!BBlocksSMCalc[kFixedOrder].empty()) {
       for (unsigned int i = 0 ; i <BBlocksSMCalc[kFixedOrder].size() ; i++) {
-         int kOrder = BBlocksSMCalc[kFixedOrder][i]->GetIContrFlag2()-1;
-         if (bUseSMCalc[kFixedOrder][i] && kOrder > 0) {
-            lknlo = true;
-            break;
+         int kOrder = -1;
+         if (BBlocksSMCalc[kFixedOrder][i]) {
+            kOrder = BBlocksSMCalc[kFixedOrder][i]->GetIContrFlag2()-1;
+         }
+         if ( BBlocksSMCalc[kFixedOrder][i] && BBlocksSMCalc[kFixedOrder][i]->IsEnabled() ) {
+            if (kOrder == 0) {
+               lklo = true;
+            } else if (kOrder > 0) {
+               lkho = true;
+            }
          }
       }
    }
@@ -2225,121 +2705,154 @@ bool fastNLOReader::SetScaleFactorsMuRMuF(double xmur, double xmuf) {
    bool lkthc = false;
    if (!BBlocksSMCalc[kThresholdCorrection].empty()) {
       for (unsigned int i = 0 ; i <BBlocksSMCalc[kThresholdCorrection].size() ; i++) {
-         if (bUseSMCalc[kThresholdCorrection][i]) {
+	 cout<<"i="<<i<<"\tkThresholdCorrection="<<kThresholdCorrection<<endl;
+         if ( BBlocksSMCalc[kThresholdCorrection][i] && BBlocksSMCalc[kThresholdCorrection][i]->IsEnabled() ) {
             lkthc = true;
             break;
          }
       }
    }
+
+   // For fixed-order contributions scale factor variations are not possible without LO
+   if (!lklo && lkho && (fabs(xmur-1.) > DBL_MIN || fabs(xmuf-1.) > DBL_MIN)) {
+      logger.warn["SetScaleFactorsMuRMuF"]
+            <<"Without LO, scale factors different from unity for MuR and MuF are not allowed, nothing changed!\n";
+      logger.warn["SetScaleFactorsMuRMuF"]
+            <<"The method returns 'false', please check the return code and act appropriately.\n";
+      logger.man<<"Please do scale variations only, if all fixed-order contributions are present and switched on.\n";
+      return false;
+   }
+
+   // For threshold corrections xmur != xmuf is not allowed
    if (lkthc && fabs(xmur-xmuf) > DBL_MIN) {
-      warn["SetScaleFactorsMuRMuF"]
-         <<"Threshold corrections do not allow different scale factors for MuR and MuF, nothing changed!\n";
-      warn["SetScaleFactorsMuRMuF"]
-         <<"The method returns 'false', please check the return code and act appropriately.\n";
-      man<<"Please do only symmetric scale variations, i.e. xmur = xmuf, with threshold corrections switched on\n";
-      man<<"or deactivate threshold corrections first using\n";
-      man<<"FastNLOReader::SetContributionON(kTresholdCorrections,Id,false).\n";
+      logger.warn["SetScaleFactorsMuRMuF"]
+            <<"Threshold corrections do not allow different scale factors for MuR and MuF, nothing changed!\n";
+      logger.warn["SetScaleFactorsMuRMuF"]
+            <<"The method returns 'false', please check the return code and act appropriately.\n";
+      logger.man<<"Please do only symmetric scale variations, i.e. xmur = xmuf, with threshold corrections switched on\n";
+      logger.man<<"or deactivate threshold corrections first using\n";
+      logger.man<<"FastNLOReader::SetContributionON(kTresholdCorrections,Id,false).\n";
       return false;
    }
 
    // Deal with factorization scale first
    // Check whether corresponding xmuf variation exists in case of v2.0 table
-   if (!GetIsFlexibleScaleTable() && !fUseHoppet) {
-      const int ns = GetNScaleVariations();
-      debug["SetScaleFactorsMuRMuF"]<<"Found "<<ns<<" scale variations for contributions switched ON."<<endl;
-      int sfnlo = -1;
-      if (lknlo) {
-         for (int is = 0 ; is<ns ; is++) {
-            if (fabs(((fastNLOCoeffAddFix*)B_NLO())->GetScaleFactor(is)-xmuf) < DBL_MIN) {
-               sfnlo = is;
-               break;
+   if (!GetIsFlexibleScaleTable()) {
+
+      // Neither LO only, nor UseHoppet
+      if ((lkho || lkthc) && !fUseHoppet) {
+         const int ns = GetNScaleVariations();
+         logger.debug["SetScaleFactorsMuRMuF"]<<"Found "<<ns<<" scale variations for contributions switched ON."<<endl;
+
+         //         fastNLOCoeffAddFix* cLO   = (fastNLOCoeffAddFix*)B_LO();
+         fastNLOCoeffAddFix* cNLO  = (fastNLOCoeffAddFix*)B_NLO();
+         fastNLOCoeffAddFix* cNNLO = (fastNLOCoeffAddFix*)B_NNLO();
+
+         int sfho = -1;
+         if (lkho) {
+            for (int is = 0 ; is<ns ; is++) {
+               if (cNLO) {
+                  if (fabs(cNLO->GetScaleFactor(is)-xmuf) < DBL_MIN) {
+                     if (sfho != -1 && sfho != is) {
+                        logger.error["SetScaleFactorsMuRMuF"]<<"Inconsistent scale variations in higher-order contributions. Aborted!"<<endl;
+                        exit(1);
+                     }
+                     sfho = is;
+                  }
+               }
+               if (cNNLO) {
+                  if (fabs(cNNLO->GetScaleFactor(is)-xmuf) < DBL_MIN) {
+                     if (sfho != -1 && sfho != is) {
+                        logger.error["SetScaleFactorsMuRMuF"]<<"Inconsistent scale variations in higher-order contributions. Aborted!"<<endl;
+                        exit(1);
+                     } else {
+                        sfho = is;
+                     }
+                  }
+               }
             }
          }
-      }
-      int sfthc = -1;
-      if (lkthc) {
-         for (int is = 0 ; is<ns ; is++) {
-            if (fabs(((fastNLOCoeffAddFix*)B_ThC())->GetScaleFactor(is)-xmuf) < DBL_MIN) {
-               sfthc = is;
-               break;
+         int sfthc = -1;
+         if (lkthc) {
+            for (int is = 0 ; is<ns ; is++) {
+               if (fabs(((fastNLOCoeffAddFix*)B_ThC())->GetScaleFactor(is)-xmuf) < DBL_MIN) {
+                  sfthc = is;
+                  break;
+               }
             }
          }
-      }
-      if (lknlo && sfnlo == -1) {
-         warn["SetScaleFactorsMuRMuF"]<<"Could not find NLO table with given mu_f scale factor of "<<xmuf<<", nothing changed!"<<endl;
-         warn["SetScaleFactorsMuRMuF"]
-            <<"The method returns 'false', please check the return code and act appropriately.\n";
-         return false;
-      }
-      if (lkthc && sfthc == -1) {
-         warn["SetScaleFactorsMuRMuF"]<<"Could not find ThC table with given mu_f scale factor of "<<xmuf<<", nothing changed!"<<endl;
-         warn["SetScaleFactorsMuRMuF"]
-            <<"The method returns 'false', please check the return code and act appropriately.\n";
-         return false;
-      }
-      if (lkthc && lknlo && sfnlo != sfthc) {
-         warn["SetScaleFactorsMuRMuF"]<<"Order of scale variation tables different in NLO and ThC tables, "<<sfnlo<<" != "<<sfthc<<" !"<<endl;
-         warn["SetScaleFactorsMuRMuF"]<<"This is currently not supported, nothing changed!"<<endl;
-         warn["SetScaleFactorsMuRMuF"]
-            <<"The method returns 'false', please check the return code and act appropriately.\n";
-         return false;
-      }
-
-      // Finally change renormalization scale first. Otherwise safety check in SetScaleVariationfails!
-      fScaleFacMuR = xmur;
-      // Now set factorization scale
-      fScaleFacMuF = xmuf;
-      bool bSetScales = false;
-      if (lknlo) {
-         bSetScales = SetScaleVariation(sfnlo);
-         if (!bSetScales) {
-            error["SetScaleFactorsMuRMuF"]<<"NLO scale variation table "<<sfnlo<<" could not be selected, stopped!"<<endl;
-            exit(1);
+         if (lkho && sfho == -1) {
+            logger.warn["SetScaleFactorsMuRMuF"]<<"Could not find NLO table with given mu_f scale factor of "<<xmuf<<", nothing changed!"<<endl;
+            logger.warn["SetScaleFactorsMuRMuF"]
+                  <<"The method returns 'false', please check the return code and act appropriately.\n";
+            return false;
          }
-      } else { // LO only
-         bSetScales = SetScaleVariation(0);
-         if (!bSetScales) {
-            error["SetScaleFactorsMuRMuF"]<<"LO scale variation table "<< 0 <<" could not be selected, stopped!"<<endl;
-            exit(1);
+         if (lkthc && sfthc == -1) {
+            logger.warn["SetScaleFactorsMuRMuF"]<<"Could not find ThC table with given mu_f scale factor of "<<xmuf<<", nothing changed!"<<endl;
+            logger.warn["SetScaleFactorsMuRMuF"]
+                  <<"The method returns 'false', please check the return code and act appropriately.\n";
+            return false;
+         }
+         if (lkthc && lkho && sfho != sfthc) {
+            logger.warn["SetScaleFactorsMuRMuF"]<<"Order of scale variation tables different in NLO and ThC tables, "<<sfho<<" != "<<sfthc<<" !"<<endl;
+            logger.warn["SetScaleFactorsMuRMuF"]<<"This is currently not supported, nothing changed!"<<endl;
+            logger.warn["SetScaleFactorsMuRMuF"]
+                  <<"The method returns 'false', please check the return code and act appropriately.\n";
+            return false;
          }
-      }
-      PrintScaleSettings();
-   }
-   else if (fUseHoppet) {
-
-      debug["SetScaleFactorsMuRMuF"]<< "UseHoppet==true: Default factorization scale variation table (muF=1.0) will be enabled and "
-         << "Hoppet will be used to calculate scale variation contributions on the fly." << endl;
 
-      const int ns = GetNScaleVariations();
-      debug["SetScaleFactorsMuRMuF"]<<"Found "<<ns<<" scale variations for contributions switched ON."<<endl;
-      int sfnlo = -1;
-      if (lknlo) {
-         for (int is = 0 ; is<ns ; is++) {
-            if (fabs(((fastNLOCoeffAddFix*)B_NLO())->GetScaleFactor(is) - 1.0) < DBL_MIN) {
-               sfnlo = is;
-               break;
+         // Finally change renormalization scale first. Otherwise safety check in SetScaleVariationfails!
+         fScaleFacMuR = xmur;
+         // Now set factorization scale
+         fScaleFacMuF = xmuf;
+         bool bSetScales = false;
+         if (lkho) {
+            bSetScales = SetScaleVariation(sfho);
+            if (!bSetScales) {
+               logger.error["SetScaleFactorsMuRMuF"]<<"NLO scale variation table "<<sfho<<" could not be selected, stopped!"<<endl;
+               exit(1);
+            }
+         }
+      } else { // LO only or UseHoppet
+         logger.debug["SetScaleFactorsMuRMuF"]<<"Either LO only or UseHoppet==true. Enable default factorization scale variation (MuF=1.0)."<<endl;
+         logger.debug["SetScaleFactorsMuRMuF"]<<"If required, Hoppet will be used to calculate scale variation contributions on the fly." << endl;
+         const int ns = GetNScaleVariations();
+         logger.debug["SetScaleFactorsMuRMuF"]<<"Found "<<ns<<" scale variations for contributions switched ON."<<endl;
+         int sfho = -1;
+         if (lkho) {
+            for (int is = 0 ; is<ns ; is++) {
+               if (fabs(((fastNLOCoeffAddFix*)B_NLO())->GetScaleFactor(is) - 1.0) < DBL_MIN) {
+                  sfho = is;
+                  break;
+               }
             }
          }
-      }
 
-      bool bSetScales = false;
-      if (lknlo) {
-         bSetScales = SetScaleVariation(sfnlo);
-         if (!bSetScales) {
-            error["SetScaleFactorsMuRMuF"]<<"NLO scale variation table "<<sfnlo<<" could not be selected, stopped!"<<endl;
-            exit(1);
+         bool bSetScales = false;
+         if (lkho) {
+            bSetScales = SetScaleVariation(sfho);
+            if (!bSetScales) {
+               logger.error["SetScaleFactorsMuRMuF"]<<"NLO scale variation table "<<sfho<<" could not be selected, stopped!"<<endl;
+               exit(1);
+            }
+         } else {
+            bSetScales = SetScaleVariation(0);
+            if (!bSetScales) {
+               logger.error["SetScaleFactorsMuRMuF"]<<"LO scale variation table "<< 0 <<" could not be selected, stopped!"<<endl;
+               exit(1);
+            }
          }
+         fScaleFacMuR = xmur;
+         fScaleFacMuF = xmuf;
+         PrintScaleSettings();
       }
-      fScaleFacMuR = xmur;
-      fScaleFacMuF = xmuf;
-      PrintScaleSettings();
-   }
-   else {
+   } else { // Flexible-scale table
       fScaleFacMuR = xmur;
       fScaleFacMuF = xmuf;
       PrintScaleSettings(kMuR);
       PrintScaleSettings(kMuF);
    }
+   logger.debug["SetScaleFactorsMuRMuF"]<<"... leaving SetScaleFactorsMuRMuF."<<endl;
    return true;
 }
 
@@ -2347,8 +2860,8 @@ bool fastNLOReader::SetScaleFactorsMuRMuF(double xmur, double xmuf) {
 //______________________________________________________________________________
 void fastNLOReader::PrintScaleSettings(fastNLO::EMuX MuX) {
    if (!GetIsFlexibleScaleTable()) {
-      info["PrintScaleSettings"]<<"Renormalization scale chosen to be mu_r = "<<fScaleFacMuR<<" * "<<B_LO()->GetScaleDescription()<<endl;
-      info["PrintScaleSettings"]<<"Factorization scale chosen to be   mu_f = "<<fScaleFacMuF<<" * "<<B_LO()->GetScaleDescription()<<endl;
+      logger.info["PrintScaleSettings"]<<"Renormalization scale chosen to be mu_r = "<<fScaleFacMuR<<" * "<<B_Any()->GetScaleDescription()<<endl;
+      logger.info["PrintScaleSettings"]<<"Factorization scale chosen to be   mu_f = "<<fScaleFacMuF<<" * "<<B_Any()->GetScaleDescription()<<endl;
    } else {
       // ---- prepare printout ---- //
       static const string sname[2] = {"Renormalization","Factorization"};
@@ -2359,47 +2872,63 @@ void fastNLOReader::PrintScaleSettings(fastNLO::EMuX MuX) {
       char fname[100];
       switch (func) {
       case kScale1:
-         sprintf(fname,"%s^2",B_LO()->GetScaleDescription(0).c_str());
+         sprintf(fname,"%s^2",B_Any()->GetScaleDescription(0).c_str());
          break;
       case kScale2:
-         sprintf(fname,"%s^2",B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"%s^2",B_Any()->GetScaleDescription(1).c_str());
          break;
       case kQuadraticSum:
-         sprintf(fname,"(%s^2 + %s^2)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s^2 + %s^2)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kQuadraticMean:
-         sprintf(fname,"(%s^2 + %s^2)/2",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s^2 + %s^2)/2",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kQuadraticSumOver4:
-         sprintf(fname,"(%s^2 + %s^2)/4",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s^2 + %s^2)/4",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
+         break;
+      case kS2plusS1half:
+         sprintf(fname,"(%s^2 + 2*%s^2)/2",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
+         break;
+      case kS2plusS1fourth:
+         sprintf(fname,"%s^2/4 + %s^2",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
+         break;
+      case kPow4Sum:
+         sprintf(fname,"sqrt(%s^4 + %s^4)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
+         break;
+      case kWgtAvg:
+         sprintf(fname,"(%s^4 + %s^4)/ (%s^2 + %s^2) ",
+                 B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str(),
+                 B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kLinearMean:
-         sprintf(fname,"((%s+%s)/2)^2",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"((%s+%s)/2)^2",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kLinearSum:
-         sprintf(fname,"(%s+%s)^2",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s+%s)^2",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kScaleMax:
-         sprintf(fname,"max(%s^2,%s^2)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"max(%s^2,%s^2)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kScaleMin:
-         sprintf(fname,"min(%s^2,%s^2)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"min(%s^2,%s^2)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kProd:
-         sprintf(fname,"(%s*%s)^2)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s*%s)^2)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kExpProd2:
-         sprintf(fname,"(%s*exp(0.3*%s)^2)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"(%s*exp(0.3*%s)^2)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
          break;
       case kExtern:
-         sprintf(fname,"f_ext(%s,%s)",B_LO()->GetScaleDescription(0).c_str(),B_LO()->GetScaleDescription(1).c_str());
+         sprintf(fname,"f_ext(%s,%s)",B_Any()->GetScaleDescription(0).c_str(),B_Any()->GetScaleDescription(1).c_str());
+         break;
+      case kConst:
+         sprintf(fname,"%f", ((MuX==kMuR) ? fConst_MuR : fConst_MuF));
          break;
       default:
-         error<<"unknown scale choice.\n";
-
+         logger.error<<"unknown scale choice: "<<MuX<<"\tkConst would be: "<<kConst <<endl;
       }
-      info["PrintScaleSettings"]<<sname[isc]<<" scale chosen to be "<<smu[isc]<<"^2 = "
-          <<sfac<<"^2 * "<<fname<<endl;
+      logger.info["PrintScaleSettings"]<<sname[isc]<<" scale chosen to be "<<smu[isc]<<"^2 = "
+                                       <<sfac<<"^2 * "<<fname<<endl;
    }
 }
 
@@ -2410,8 +2939,8 @@ double fastNLOReader::CalcMu(fastNLO::EMuX kMuX , double scale1, double scale2,
    //!  Calculate the scales with the defined function and the
    //!  corresponding prefactor.
    //!
-   if (kMuX == kMuR && fScaleFacMuR != scalefac) error<<"Sth. went wrong with the scales.\n";
-   if (kMuX == kMuF && fScaleFacMuF != scalefac) error<<"Sth. went wrong with the scales.\n";
+   if (kMuX == kMuR && fScaleFacMuR != scalefac) logger.error<<"Sth. went wrong with the scales.\n";
+   if (kMuX == kMuF && fScaleFacMuF != scalefac) logger.error<<"Sth. went wrong with the scales.\n";
 
    EScaleFunctionalForm Func = (kMuX == kMuR) ? fMuRFunc : fMuFFunc;
    double mu = 0;
@@ -2420,6 +2949,10 @@ double fastNLOReader::CalcMu(fastNLO::EMuX kMuX , double scale1, double scale2,
    else if (Func == fastNLO::kQuadraticSum)      mu      = FuncMixedOver1(scale1,scale2);
    else if (Func == fastNLO::kQuadraticMean)     mu      = FuncMixedOver2(scale1,scale2);
    else if (Func == fastNLO::kQuadraticSumOver4) mu      = FuncMixedOver4(scale1,scale2);
+   else if (Func == fastNLO::kS2plusS1half)      mu      = FuncMixed2s2Ov2(scale1,scale2);
+   else if (Func == fastNLO::kS2plusS1fourth)    mu      = FuncMixed2s2Ov4(scale1,scale2);
+   else if (Func == fastNLO::kPow4Sum)           mu      = FuncPow4Sum(scale1,scale2);
+   else if (Func == fastNLO::kWgtAvg)            mu      = FuncWgtAvg(scale1,scale2);
    else if (Func == fastNLO::kLinearMean)        mu      = FuncLinearMean(scale1,scale2);
    else if (Func == fastNLO::kLinearSum)         mu      = FuncLinearSum(scale1,scale2);
    else if (Func == fastNLO::kScaleMax)          mu      = FuncMax(scale1,scale2);
@@ -2427,7 +2960,11 @@ double fastNLOReader::CalcMu(fastNLO::EMuX kMuX , double scale1, double scale2,
    else if (Func == fastNLO::kProd)              mu      = FuncProd(scale1,scale2);
    else if (Func == fastNLO::kExpProd2)          mu      = FuncExpProd2(scale1,scale2);
    else if (Func == fastNLO::kExtern)            mu      = (kMuX==kMuR) ? (*Fct_MuR)(scale1,scale2) : (*Fct_MuF)(scale1,scale2);
-   else error["CalcMu"]<<"Could not identify functional form for scales calculation.\n";
+   else if (Func == fastNLO::kConst)             mu      = (kMuX==kMuR) ? fConst_MuR : fConst_MuF;
+   else {
+      logger.error["CalcMu"]<<"Could not identify functional form for scales calculation.\n";
+      exit(4);
+   }
 
    return scalefac * mu;
 }
@@ -2435,19 +2972,43 @@ double fastNLOReader::CalcMu(fastNLO::EMuX kMuX , double scale1, double scale2,
 
 //______________________________________________________________________________
 double fastNLOReader::FuncMixedOver1(double scale1 , double scale2) {
-   return (sqrt((pow(scale1,2) + pow(scale2,2))  / 1.));
+   return (sqrt((scale1*scale1 + scale2*scale2)  / 1.));
 }
 
 
 //______________________________________________________________________________
 double fastNLOReader::FuncMixedOver2(double scale1 , double scale2) {
-   return (sqrt((pow(scale1,2) + pow(scale2,2))  / 2.));
+   return (sqrt((scale1*scale1 + scale2*scale2)  / 2.));
 }
 
 
 //______________________________________________________________________________
 double fastNLOReader::FuncMixedOver4(double scale1 , double scale2) {
-   return (sqrt((pow(scale1,2) + pow(scale2,2))  / 4.));
+   return (sqrt((scale1*scale1 + scale2*scale2)  / 4.));
+}
+
+
+//______________________________________________________________________________
+double fastNLOReader::FuncMixed2s2Ov2(double scale1 , double scale2) {
+   return (sqrt((scale1*scale1 + 2*scale2*scale2)  / 2.));
+}
+
+
+//______________________________________________________________________________
+double fastNLOReader::FuncMixed2s2Ov4(double scale1 , double scale2) {
+   return sqrt((scale1*scale1/4. + scale2*scale2));
+}
+
+
+//______________________________________________________________________________
+double fastNLOReader::FuncPow4Sum(double scale1 , double scale2) {
+   return sqrt(sqrt(pow(scale1,4) + pow(scale2,4)));
+}
+
+
+//______________________________________________________________________________
+double fastNLOReader::FuncWgtAvg(double scale1 , double scale2) {
+   return sqrt((pow(scale1,4) + pow(scale2,4)) / (scale1*scale1 + scale2*scale2));
 }
 
 
@@ -2492,7 +3053,7 @@ double fastNLOReader::FuncExpProd2(double scale1 , double scale2) {
 //______________________________________________________________________________
 int fastNLOReader::ContrId(const ESMCalculation eCalc, const ESMOrder eOrder) const {
    int Id = -1;
-   if (BBlocksSMCalc.empty() || bUseSMCalc[eCalc].empty()) {
+   if ( BBlocksSMCalc.empty() ) {
       return Id;
    }
 
@@ -2500,12 +3061,13 @@ int fastNLOReader::ContrId(const ESMCalculation eCalc, const ESMOrder eOrder) co
    string requested = _OrdName[eCalc][eOrder];
    // Loop over all available orders of contribution type eCalc
    for (unsigned int i=0; i<BBlocksSMCalc[eCalc].size(); i++) {
-      // Found order
-      int iFlag1 = BBlocksSMCalc[eCalc][i]->GetIContrFlag1();
-      int iFlag2 = BBlocksSMCalc[eCalc][i]->GetIContrFlag2();
-      string available = _OrdName[iFlag1-1][iFlag2-1];
-      if (available == requested) {
-         Id = i;
+      if (BBlocksSMCalc[eCalc][i]) {
+         int iFlag1 = BBlocksSMCalc[eCalc][i]->GetIContrFlag1();
+         int iFlag2 = BBlocksSMCalc[eCalc][i]->GetIContrFlag2();
+         string available = _OrdName[iFlag1-1][iFlag2-1];
+         if (available == requested) {
+            Id = i;
+         }
       }
    }
    return Id;
@@ -2519,18 +3081,31 @@ int fastNLOReader::ContrId(const ESMCalculation eCalc, const ESMOrder eOrder) co
 //______________________________________________________________________________
 
 
+//_DEPRECATED___________________________________________________________________
+void fastNLOReader::PrintTableInfo(const int iprint) const {
+   logger.warn["PrintTableInfo"]<<"This function is deprecated!"<<endl;
+   logger.warn["PrintTableInfo"]<<"Please use PrintContributionSummary instead."<<endl;
+}
+
+
+//_DEPRECATED___________________________________________________________________
+void fastNLOReader::PrintFastNLOTableConstants(const int iprint) const {
+   logger.warn["PrintTableInfo"]<<"This function is deprecated!"<<endl;
+   logger.warn["PrintTableInfo"]<<"Please use Print instead."<<endl;
+}
+
 
 //______________________________________________________________________________
-void fastNLOReader::PrintTableInfo(const int iprint) const {
+void fastNLOReader::PrintContributionSummary(int iprint) const {
    //! this function is inherited from fastNLOTable.
-   fastNLOTable::PrintTableInfo(iprint);
+   fastNLOTable::PrintContributionSummary(iprint);
 }
 
 
 //______________________________________________________________________________
-void fastNLOReader::PrintFastNLOTableConstants(const int iprint) const {
+void fastNLOReader::Print(int iprint) const {
    //! this function is inherited from fastNLOTable.
-   this->fastNLOTable::PrintFastNLOTableConstants(iprint);
+   fastNLOTable::Print(iprint);
 }
 
 
@@ -2571,7 +3146,8 @@ void fastNLOReader::PrintCrossSections() const {
             printf(" #                  ---->  from %9.3f to %9.3f in %s  <----\n",GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),GetDimLabel(0).c_str());
             lobindim2 = GetObsBinLoBound(i,0);
          }
-         printf(" #   %4.0f   | %9.3f - %9.3f       % 9.4e           % 5.2f      |\n",i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i],kFactor[i]);
+         //         printf(" #   %4.0f   | %9.3f - %9.3f       % 9.4e           % 5.2f      |\n",i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i],kFactor[i]);
+         printf(" #   %4.0f   | %9.3f - %9.3f       % 9.4e                 |\n",i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i]);
       }
    }
 
@@ -2653,8 +3229,10 @@ void fastNLOReader::PrintCrossSectionsWithReference() {
             printf(" #                    ---->  from %9.3f to %9.3f in %s  <----\n",GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),GetDimLabel(0).c_str());
             lobindim2 = GetObsBinLoBound(i,0);
          }
-         printf(" #   %4.0f   | %9.3f - %9.3f      % 9.4e           % 5.3f      |     % 9.4e            % 5.4f\n",
-                i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i],kFactor[i],xsref[i],(xs[i]-xsref[i])/xsref[i]*100.);
+         // printf(" #   %4.0f   | %9.3f - %9.3f      % 9.4e           % 5.3f      |     % 9.4e            % 5.4f\n",
+         //        i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i],kFactor[i],xsref[i],(xs[i]-xsref[i])/xsref[i]*100.);
+         printf(" #   %4.0f   | %9.3f - %9.3f      % 9.4e                 |     % 9.4e            % 5.4f\n",
+                i*1.,GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),xs[i],xsref[i],(xs[i]-xsref[i])/xsref[i]*100.);
       }
    }
 
@@ -2669,189 +3247,28 @@ void fastNLOReader::PrintCrossSectionsWithReference() {
 }
 
 
-//______________________________________________________________________________
-void fastNLOReader::PrintCrossSectionsDefault(const vector <double> kthc) const {
-   //!
-   //! Print observable binnning and cross sections at
-   //! LO, NLO and K factors like in Fortran Reader for comparison
-   //!
-   //! This function can only print double-differential crosss section tables.
-   //!
+//_DEPRECATED___________________________________________________________________
+void fastNLOReader::PrintCrossSectionsData() const {
+   logger.warn["PrintCrossSectionsData"]<<"This function is deprecated!"<<endl;
+   logger.warn["PrintCrossSectionsData"]<<"Please check fnlo-tk-cppread.cc for default print out."<<endl;
+   return;
+}
 
-   // Check on existence of 2-loop threshold corrections
-   //const int ithc2 = kthc.empty() ? -1 : ContrId( fastNLO::kThresholdCorrection, fastNLO::kNextToLeading);
-   const int ithc2 = kthc.empty() ? -1 : ContrId(kThresholdCorrection,kNextToLeading);
-
-   cout << _DSEPLC << endl;
-   printf(" Cross Sections\n");
-   if (!GetIsFlexibleScaleTable())
-      printf(" The scale chosen here are: mu_f = % #6.3f * %s, and mu_r = % #6.3f * %s \n",
-             fScaleFacMuF, B_LO()->GetScaleDescription().c_str(), fScaleFacMuR, B_LO()->GetScaleDescription().c_str());
-   cout << _SSEPLC << endl;
-
-   if (NDim == 1) {
-      // non-perturbative corrections (just first np correction)
-      const int inpc1 = ContrId(kNonPerturbativeCorrection,kLeading);
-      const vector < double > knpc = inpc1>-1 ? ((fastNLOCoeffMult*)BBlocksSMCalc[kNonPerturbativeCorrection][kLeading])->GetMultFactor() : vector<double>(NObsBin);
-
-      string header0 = "  IObs  Bin Size IODimO   ";
-      string header2 = "   LO cross section   NLO cross section   K NLO";
-      if (ithc2>-1)header2 += "     K THC";
-      if (inpc1>-1)header2 += "     K NPC";
-      unsigned int NDimBins[NDim];
-      printf("%s [ %-12s ] %s\n",
-             header0.c_str(),DimLabel[0].c_str(),header2.c_str());
-      cout << _SSEPLC << endl;
-      for (unsigned int i=0; i<NObsBin; i++) {
-         NDimBins[0] = 1;
-         if (ithc2<0 && inpc1<0) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %#18.11E %#18.11E %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),
-                   XSection_LO[i],XSection[i],kFactor[i]);
-         } else if (inpc1<0 && ithc2 != -1) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %#18.11E %#18.11E %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),
-                   XSection_LO[i],XSection[i],kFactor[i],kthc[i]);
-         } else if (inpc1>-1 && ithc2 == -1) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %#18.11E %#18.11E %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),
-                   XSection_LO[i],XSection[i],kFactor[i],knpc[i]);
-         } else {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %#18.11E %#18.11E %#9.5F %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),
-                   XSection_LO[i],XSection[i],kFactor[i],kthc[i],knpc[i]);
-         }
-         printf("\n");
-      }
-   } else if (NDim == 2) {
-      // non-perturbative corrections (just first np correction)
-      const int inpc1 = ContrId(kNonPerturbativeCorrection,kLeading);
-      const vector < double > knpc = inpc1>-1 ? ((fastNLOCoeffMult*)BBlocksSMCalc[kNonPerturbativeCorrection][kLeading])->GetMultFactor() : vector<double>(NObsBin);
-
-      string header0 = "  IObs  Bin Size IODimO ";
-      string header1 = "   IODimI ";
-      string header2 = " LO cross section   NLO cross section   K NLO";
-      if (ithc2>-1)header2 += "     K THC";
-      if (inpc1>-1)header2 += "     K NPC";
-      unsigned int NDimBins[NDim];
-      printf("%s [ %-12s ] %s [  %-12s  ] %s\n",
-             header0.c_str(),DimLabel[1].c_str(),header1.c_str(),DimLabel[0].c_str(),header2.c_str());
-      cout << _SSEPLC << endl;
-      for (unsigned int i=0; i<NObsBin; i++) {
-         for (unsigned int j=0; j<NDim; j++) {
-            if (i==0)                                  NDimBins[j] = 1;
-            else if (GetObsBinLoBound(i-1,j) < GetObsBinLoBound(i,j))       NDimBins[j]++;
-            else if (GetObsBinLoBound(i,j) < GetObsBinLoBound(i-1,j))       NDimBins[j] = 1;
-         }
-         if (ithc2<0 && inpc1<0) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %5.i  %-#8.2E  %-#8.2E %#18.11E %#18.11E %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),
-                   NDimBins[1],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),XSection_LO[i],XSection[i],kFactor[i]);
-         } else if (inpc1<0 && ithc2 != -1) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %5.i  %-#8.2E  %-#8.2E %#18.11E %#18.11E %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),
-                   NDimBins[1],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),XSection_LO[i],XSection[i],kFactor[i],kthc[i]);
-         } else if (inpc1>-1 && ithc2 == -1) {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %5.i  %-#8.2E  %-#8.2E %#18.11E %#18.11E %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),
-                   NDimBins[1],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),XSection_LO[i],XSection[i],kFactor[i],knpc[i]);
-         } else {
-            printf(" %5.i % -#10.4g %5.i % -#10.4g % -#10.4g %5.i  %-#8.2E  %-#8.2E %#18.11E %#18.11E %#9.5F %#9.5F %#9.5F",
-                   i+1,BinSize[i],NDimBins[0],GetObsBinLoBound(i,1),GetObsBinUpBound(i,1),
-                   NDimBins[1],GetObsBinLoBound(i,0),GetObsBinUpBound(i,0),XSection_LO[i],XSection[i],kFactor[i],kthc[i],knpc[i]);
-         }
-         printf("\n");
-      }
-   } else {
-      warn["PrintCrossSectionsDefault"]<<"Print out optimized for two dimensions. No output for "<<NDim<<" dimensions."<<endl;
-   }
 
+//_DEPRECATED___________________________________________________________________
+void fastNLOReader::PrintCrossSectionsDefault(const vector <double> kthc) const {
+   logger.warn["PrintCrossSectionsDefault"]<<"This function is deprecated!"<<endl;
+   logger.warn["PrintCrossSectionsDefault"]<<"Please check fnlo-tk-cppread.cc for default print out."<<endl;
+   exit(1);
+   return;
 }
 
 
-//______________________________________________________________________________
+//_DEPRECATED___________________________________________________________________
 void fastNLOReader::RunFastNLODemo() {
-   //!
-   //! This method prints out cross sections for different scale
-   //! variation tables. Though it also changes the currently stored
-   //! settings of this instance!
-   //!
-   //! RunFastNLODemo is changing settings (like scale choices) of this reader.
-   //!
-
-   info["RunFastNLODemo"]<<"RunFastNLODemo is changing settings (like scale choices) of this reader."<<endl;
-
-   // If flexible-scale table, set MuR and MuF functional forms
-   if (GetIsFlexibleScaleTable()) {
-      SetMuRFunctionalForm(fastNLO::kScale1);
-      SetMuFFunctionalForm(fastNLO::kScale1);
-      //SetMuRFunctionalForm(fastNLO::kExpProd2);
-      //SetMuRFunctionalForm(fastNLO::kExpProd2);
-   }
-
-   // Check on existence of LO and NLO (Id = -1 if not existing)
-   int ilo   = ContrId(fastNLO::kFixedOrder, fastNLO::kLeading);
-   int inlo  = ContrId(fastNLO::kFixedOrder, fastNLO::kNextToLeading);
-   if (ilo < 0 || inlo < 0) {
-      error["PrintFastNLODemo"]<<"LO and/or NLO not found, nothing to be done!\n";
-      return;
-   }
-   // Check on existence of 2-loop threshold corrections
-   int ithc2 = ContrId(fastNLO::kThresholdCorrection, fastNLO::kNextToLeading);
-
-   // Pre-define desired order of scale variations
-   const int nxmu = 4;
-   double xmu[nxmu] = {1.0, 0.25, 0.5, 2.0};
-   int   ixmu[nxmu] = { -1,   -1,  -1,  -1};
-   // Get number of available scale variations and check on available scale factors,
-   // in particular for MuF; set pointers
-   int nscls = GetNScaleVariations();
-   // With threshold corrections, allow only default scale (0)
-   if (ithc2 > -1) {
-      nscls = 1;
-   }
-   for (int iscls=0; iscls<nscls; iscls++) {
-      SetScaleVariation(iscls);
-      double fxmu = fScaleFacMuF;
-      for (int i=0; i<nxmu; i++) {
-         if (fabs(xmu[i]-fxmu) < 0.000001) {
-            ixmu[i] = iscls;
-         }
-      }
-   }
-
-   // Loop over scales
-   for (int iscls=0; iscls<nxmu; iscls++) {
-      // First result is with NLO, LO result via division by K factor
-      if (ixmu[iscls] > -1) {
-         SetScaleVariation(ixmu[iscls]);
-         CalcCrossSection();
-
-         // Second result: Include threshold corrections for NLO if available
-         vector < double > kthc;
-         if (ithc2 > -1) {
-            vector < double > stdk = kFactor;
-            bool SetOn = SetContributionON(fastNLO::kThresholdCorrection, ithc2, true);
-            if (!SetOn) {
-               warn["RunFastNLODemo"]<<"Contribution "<<_ContrName[fastNLO::kThresholdCorrection]<<" could not be switched on for scale variation number "<<iscls<<", skipped!"<<endl;
-               continue;
-            }
-            CalcCrossSection();
-            kthc = kFactor;
-            // Threshold K factor is NLO including 2-loop vs. NLO
-            for (unsigned int i=0; i<kthc.size(); i++) {
-               if (fabs(kFactor[i]) > DBL_MIN) {
-                  kthc[i] = kFactor[i]/stdk[i];
-               } else {
-                  kthc[i] = -1.;
-               }
-            }
-            SetContributionON(fastNLO::kThresholdCorrection, ithc2, false);
-         }
-
-         PrintCrossSectionsDefault(kthc);
-      }
-   }
+   logger.warn["RunFastNLODemo"]<<"This function is deprecated!"<<endl;
+   logger.warn["RunFastNLODemo"]<<"Please check fnlo-tk-examples.cc for examples."<<endl;
+   return;
 }
 
 
@@ -2867,7 +3284,7 @@ double fastNLOReader::RescaleCrossSectionUnits(double binsize, int xunits) {
       unit *= binsize;
    }
    // Rescale SigmaTilde to Ipublunits (accounts for potentially different settings in XSectUnits)
-   if ( xunits != Ipublunits ) {
+   if (xunits != Ipublunits) {
       unit /= pow(10.,xunits-Ipublunits);
    }
    return unit;
@@ -2875,52 +3292,61 @@ double fastNLOReader::RescaleCrossSectionUnits(double binsize, int xunits) {
 
 
 //______________________________________________________________________________
-fastNLOReader::XsUncertainty fastNLOReader::GetScaleUncertainty(const EScaleUncertaintyStyle eScaleUnc) {
+XsUncertainty fastNLOReader::GetScaleUncertainty(const EScaleUncertaintyStyle eScaleUnc) {
+   XsUncertainty XsUnc = GetScaleUncertainty(eScaleUnc, false);
+   return XsUnc;
+}
+
+
+//______________________________________________________________________________
+XsUncertainty fastNLOReader::GetScaleUncertainty(const EScaleUncertaintyStyle eScaleUnc, bool lNorm) {
    // Get 2- or 6-point scale uncertainty
    const double xmurs[7] = {1.0, 0.5, 2.0, 0.5, 1.0, 1.0, 2.0};
    const double xmufs[7] = {1.0, 0.5, 2.0, 1.0, 0.5, 2.0, 1.0};
-   fastNLOReader::XsUncertainty XsUnc;
+   XsUncertainty XsUnc;
 
    unsigned int NObsBin = GetNObsBin();
    unsigned int npoint = 0;
-   if ( eScaleUnc == kSymmetricTwoPoint ) {
+   if (eScaleUnc == kSymmetricTwoPoint) {
       npoint = 2;
-   } else if ( eScaleUnc == kAsymmetricSixPoint ) {
+   } else if (eScaleUnc == kAsymmetricSixPoint) {
       npoint = 6;
    }
 
-   debug["GetScaleUncertainty"]<<"npoint = "<<npoint<<endl;
-   if ( npoint == 0 ) {
-      info["GetScaleUncertainty"]<<"Only default scale selected, uncertainties will be zero."<<endl;
-   } else if ( npoint == 2 ) {
-      info["GetScaleUncertainty"]<<"Symmetric 2-point scale variations selected,"<<endl;
-   } else if ( npoint == 6 ) {
-      info["GetScaleUncertainty"]<<"Asymmetric 6-point scale variations selected,"<<endl;
+   logger.debug["GetScaleUncertainty"]<<"npoint = "<<npoint<<endl;
+   if (npoint == 0) {
+      logger.info["GetScaleUncertainty"]<<"Only default scale selected, uncertainties will be zero."<<endl;
+   } else if (npoint == 2) {
+      logger.info["GetScaleUncertainty"]<<"Symmetric 2-point scale variations selected,"<<endl;
+   } else if (npoint == 6) {
+      logger.info["GetScaleUncertainty"]<<"Asymmetric 6-point scale variations selected,"<<endl;
    } else {
-      error["GetScaleUncertainty"]<<"ERROR! No usual scale variation scheme selected, exiting."<<endl;
-      error["GetScaleUncertainty"]<<"npoint = "<<npoint<<endl;
+      logger.error["GetScaleUncertainty"]<<"ERROR! No usual scale variation scheme selected, exiting."<<endl;
+      logger.error["GetScaleUncertainty"]<<"npoint = "<<npoint<<endl;
       exit(1);
    }
 
+   vector < double > MyXSection;
    //! Cross section and absolute uncertainties
-   for ( unsigned int iscl = 0; iscl <= npoint; iscl++ ) {
+   for (unsigned int iscl = 0; iscl <= npoint; iscl++) {
       SetScaleFactorsMuRMuF(xmurs[iscl],xmufs[iscl]);
       CalcCrossSection();
-      for ( unsigned int iobs = 0; iobs < NObsBin; iobs++ ) {
-         if ( iscl == 0 ) {
-            XsUnc.xs.push_back(XSection[iobs]);
+      MyXSection = GetCrossSection(lNorm);
+      for (unsigned int iobs = 0; iobs < NObsBin; iobs++) {
+         if (iscl == 0) {
+            XsUnc.xs.push_back(MyXSection[iobs]);
             XsUnc.dxsu.push_back(0);
             XsUnc.dxsl.push_back(0);
          } else {
-            XsUnc.dxsu[iobs] = max(XsUnc.dxsu[iobs],XSection[iobs]-XsUnc.xs[iobs]);
-            XsUnc.dxsl[iobs] = min(XsUnc.dxsl[iobs],XSection[iobs]-XsUnc.xs[iobs]);
+            XsUnc.dxsu[iobs] = max(XsUnc.dxsu[iobs],MyXSection[iobs]-XsUnc.xs[iobs]);
+            XsUnc.dxsl[iobs] = min(XsUnc.dxsl[iobs],MyXSection[iobs]-XsUnc.xs[iobs]);
          }
       }
    }
 
    //! Divide by cross section != 0 to give relative uncertainties
-   for ( unsigned int iobs = 0; iobs < NObsBin; iobs++ ) {
-      if ( abs(XsUnc.xs[iobs]) > DBL_MIN ) {
+   for (unsigned int iobs = 0; iobs < NObsBin; iobs++) {
+      if (abs(XsUnc.xs[iobs]) > DBL_MIN) {
          XsUnc.dxsu[iobs] = XsUnc.dxsu[iobs] / XsUnc.xs[iobs];
          XsUnc.dxsl[iobs] = XsUnc.dxsl[iobs] / XsUnc.xs[iobs];
       } else {
@@ -2935,3 +3361,13 @@ fastNLOReader::XsUncertainty fastNLOReader::GetScaleUncertainty(const EScaleUnce
 
    return XsUnc;
 }
+
+std::vector< std::vector<double> > fastNLOReader::GetScaleUncertaintyVec(const EScaleUncertaintyStyle eScaleUnc) {
+   XsUncertainty xsUnc = fastNLOReader::GetScaleUncertainty(eScaleUnc);
+   std::vector<std::vector<double> > xsUncVec;
+   xsUncVec.resize(3);
+   xsUncVec[0] = xsUnc.xs;
+   xsUncVec[1] = xsUnc.dxsu;
+   xsUncVec[2] = xsUnc.dxsl;
+   return xsUncVec;
+}
diff --git a/FastNLO/src/fastNLOTable.cc b/FastNLO/src/fastNLOTable.cc
index 433b27a9f8300e0964157e2c3a8733cac0424387..2fec0d22893769f9c84ef94ded9713f06eff1136 100644
--- a/FastNLO/src/fastNLOTable.cc
+++ b/FastNLO/src/fastNLOTable.cc
@@ -1,23 +1,37 @@
+//#include "config.h"
 #include <algorithm>
 #include <cfloat>
 #include <cstdlib>
+#include <unistd.h>
 #include <set>
 #include "fastnlotk/fastNLOTable.h"
 #include "fastnlotk/fastNLOTools.h"
-
+// zlib wrapper library
+#ifdef HAVE_LIBZ
+#include "fastnlotk/zstr.hpp"
+#endif
 
 using namespace std;
+using namespace fastNLO;
 
 // ___________________________________________________________________________________________________
-//fastNLOTable::fastNLOTable() : PrimalScream("fastNLOTable") {
-fastNLOTable::fastNLOTable() : fastNLOBase() {
-   logger.SetClassName("fastNLOTable");
+bool fastNLOTable::fWelcomeOnce = false;
+
+
+// ___________________________________________________________________________________________________
+fastNLOTable::fastNLOTable()
+   : ffilename(""), fPrecision(8), Itabversion(), ScenName(),
+     logger("fastNLOTable"), fCoeff(), Ecms(), ILOord(), Ipublunits(),
+     ScDescript(), NObsBin(), NDim(), DimLabel(), IDiffBin(), Bin(),
+     BinSize(), INormFlag(), DenomTable(), IDivLoPointer(), IDivUpPointer() {
+   if (!fWelcomeOnce) PrintWelcomeMessage();
 }
 
 
 // ___________________________________________________________________________________________________
-fastNLOTable::fastNLOTable(string name) : fastNLOBase(name) {
-   logger.SetClassName("fastNLOTable");
+fastNLOTable::fastNLOTable(string name)  : ffilename(name), fPrecision(8), logger("fastNLOTable")  {
+   //logger.SetClassName("fastNLOTable");
+   if (!fWelcomeOnce) PrintWelcomeMessage();
    ReadTable();
 }
 
@@ -29,19 +43,22 @@ fastNLOTable::~fastNLOTable(){
 }
 
 // ___________________________________________________________________________________________________
-fastNLOTable::fastNLOTable(const fastNLOTable& tab)
-   : fastNLOBase(tab), fCoeff(tab.fCoeff.size()),
-    Ecms(tab.Ecms), ILOord(tab.ILOord), Ipublunits(tab.Ipublunits),
-    ScDescript(tab.ScDescript), NObsBin(tab.NObsBin), NDim(tab.NDim),
-    DimLabel(tab.DimLabel), IDiffBin(tab.IDiffBin), Bin(tab.Bin),
-    BinSize(tab.BinSize), INormFlag(tab.INormFlag),
-    DenomTable(tab.DenomTable), IDivLoPointer(tab.IDivLoPointer),
-    IDivUpPointer(tab.IDivUpPointer)
+fastNLOTable::fastNLOTable(const fastNLOTable& other)
+   : ffilename(other.ffilename), fPrecision(other.fPrecision),
+     Itabversion(other.Itabversion), ScenName(other.ScenName),
+     logger("fastNLOTable"),
+     fCoeff(other.fCoeff.size()),
+     Ecms(other.Ecms), ILOord(other.ILOord), Ipublunits(other.Ipublunits),
+     ScDescript(other.ScDescript), NObsBin(other.NObsBin), NDim(other.NDim),
+     DimLabel(other.DimLabel), IDiffBin(other.IDiffBin), Bin(other.Bin),
+     BinSize(other.BinSize), INormFlag(other.INormFlag),
+     DenomTable(other.DenomTable), IDivLoPointer(other.IDivLoPointer),
+     IDivUpPointer(other.IDivUpPointer)
 {
    //! Copy constructor
    logger.SetClassName("fastNLOTable");
-   for (size_t i = 0; i < tab.fCoeff.size(); ++i) {
-      fCoeff[i] = tab.fCoeff[i]->Clone();
+   for (size_t i = 0; i < other.fCoeff.size(); ++i) {
+      fCoeff[i] = other.fCoeff[i]->Clone();
    }
 }
 
@@ -58,22 +75,62 @@ void fastNLOTable::DeleteAllCoeffTable(){
 // ___________________________________________________________________________________________________
 void fastNLOTable::ReadTable(){
    //! Read file
-   ifstream* strm = OpenFileRead();
+   std::istream* strm = OpenFileRead();
    // read header
-   ReadHeader(*strm);
+   logger.debug["ReadTable"]<<"Reading header."<<endl;
+   int nCoeff = ReadHeader(*strm);
    // read scenario
+   logger.debug["ReadTable"]<<"Reading scenario."<<endl;
    ReadScenario(*strm);
    // read b-blocks
-   ReadCoeffTables(*strm);
+   logger.debug["ReadTable"]<<"Reading coeff tables."<<endl;
+   ReadCoeffTables(*strm, nCoeff);
    // close stream
+   logger.debug["ReadTable"]<<"Reading done closing files."<<endl;
    CloseFileRead(*strm);
 }
 
 
+//______________________________________________________________________________
+int fastNLOTable::ReadHeader(istream& table) {
+   //!<
+   //!< Read table header (formely named BlockA1 and BlockA2)
+   //!< return number of contributions to follow
+   //!<
+   table.peek();
+   if (table.eof()) {
+      logger.error["ReadHeader"]<<"Cannot read from stream."<<endl;
+   }
+
+   fastNLOTools::ReadMagicNo(table);
+   table >> Itabversion;
+   fastNLOTools::CheckVersion(Itabversion);
+   std::string test;
+   if ( Itabversion >= 24000 ) table >> test; // "fastNLO_Header
+   table >> ScenName;
+   if ( test != "" )  {
+      logger.warn["ReadHeader"]<<"Scenario name is not allowed to contain white spaces!!"<<endl;
+   }
+   // check if ScenName contains spaces
+   int Ncontrib,Ndata,Nmult;
+   table >> Ncontrib;
+   table >> Nmult ; // not used any longer
+   table >> Ndata;
+   fastNLOTools::ReadUnused(table); // NuserString
+   fastNLOTools::ReadUnused(table); // NuserInt
+   //fastNLOTools::ReadUnused(table); // IUserLines
+   fastNLOTools::ReadUnused(table); // NuserFloat
+   fastNLOTools::ReadUnused(table); // Imachine
+   fastNLOTools::ReadMagicNo(table);
+   fastNLOTools::PutBackMagicNo(table);
+   return Ncontrib+Ndata;
+}
+
+
 // ___________________________________________________________________________________________________
-void fastNLOTable::ReadCoeffTables(istream& table){
-   int nblocks = GetNcontrib()+GetNdata();
-   for(int i=0;i<nblocks;i++){
+void fastNLOTable::ReadCoeffTables(istream& table, int nCoeff){
+   //!< read nCoeff Coefficient tables (additive, multiplicative and data)
+   for (int i=0; i<nCoeff; i++) {
       fastNLOCoeffBase cTemp(NObsBin);
       cTemp.ReadBase(table);
       fastNLOCoeffBase* cN = ReadRestOfCoeffTable(cTemp, table);
@@ -95,28 +152,24 @@ fastNLOCoeffBase* fastNLOTable::ReadRestOfCoeffTable(const fastNLOCoeffBase& cB,
       fastNLOCoeffData* cN = new fastNLOCoeffData(cB);
       cN->ReadRest(table);
       return cN;
-   }
-   else if ( fastNLOCoeffMult::CheckCoeffConstants(&cB,quiet) ) {
+   } else if ( fastNLOCoeffMult::CheckCoeffConstants(&cB,quiet) ) {
       logger.debug["ReadRestOfCoeffTable"]<<"Found multiplicative contribution. Now reading in."<<endl;
       fastNLOCoeffMult* cN = new fastNLOCoeffMult(cB);
       cN->ReadRest(table);
       return cN;
-   }
-   else if ( fastNLOCoeffAddFix::CheckCoeffConstants(&cB,quiet) ) {
+   } else if ( fastNLOCoeffAddFix::CheckCoeffConstants(&cB,quiet) ) {
       logger.debug["ReadRestOfCoeffTable"]<<"Found additive fixed order contribution (v2.0). Now reading in."<<endl;
       fastNLOCoeffAddFix* cN = new fastNLOCoeffAddFix(cB);
       cN->ReadRest(table);
       return cN;
-   }
-   else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(&cB,quiet) ) {
+   } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(&cB,quiet) ) {
       logger.debug["ReadRestOfCoeffTable"]<<"Found additive flexible scale contribution. Now reading in."<<endl;
       fastNLOCoeffAddFlex* cN = new fastNLOCoeffAddFlex(cB,ILOord);
       cN->ReadRest(table);
       return cN;
-   }
-   else {
-      logger.error["ReadRestOfCoeffTable"]<<"Could not identify coefficient table. Print and exiting... "<<endl;
-      cB.Print();
+   } else {
+      logger.error["ReadRestOfCoeffTable"]<<"Could not identify coefficient table. Print and exiting ... "<<endl;
+      cB.Print(5);
       exit(1);
    }
    return NULL;
@@ -125,14 +178,28 @@ fastNLOCoeffBase* fastNLOTable::ReadRestOfCoeffTable(const fastNLOCoeffBase& cB,
 
 // ___________________________________________________________________________________________________
 void fastNLOTable::WriteTable() {
-   //! Write fastNLO table to file 'ffilename' (member)
-   logger.info["WriteTable"]<<"Writing fastNLO table to file: "<<ffilename<<endl;
-   ofstream* table = OpenFileWrite();
+   //!<
+   //!< WriteTable(). writes the full FastNLO table to
+   //!< the previously defined ffilename on disk.
+   //!< Write fastNLO table to file 'ffilename' (member)
+   std::string extension = ".gz";
+   bool compress = false;
+   if ((ffilename.length() >= extension.length()) and
+         (ffilename.compare(ffilename.length() - extension.length(), extension.length(), extension) == 0))
+   {
+      logger.info["WriteTable"]<<"Filename ends with .gz, therefore enable compression." << endl;
+      compress = true;
+   }
+
+   logger.info["WriteTable"]<<"Writing fastNLO table with " << GetNcontrib() << " theory contributions to file: " << ffilename << endl;
+   std::ostream* table = OpenFileWrite(compress);
+   logger.debug["WriteTable"]<<"Writing table header to file ..."<<endl;
    WriteHeader(*table);
+   logger.debug["WriteTable"]<<"Writing scenario to file ..."<<endl;
    WriteScenario(*table);
-   for(int i=0;i<GetNcontrib();i++){
+   for(int i=0;i<GetNcontrib()+GetNdata();i++){
       logger.debug["WriteTable"]<<"Writing coefficient table #"<<i<<endl;
-      GetCoeffTable(i)->Write(*table);
+      GetCoeffTable(i)->Write(*table,GetItabversion());
    }
    CloseFileWrite(*table);
 }
@@ -148,34 +215,50 @@ void fastNLOTable::WriteTable(string filename) {
 }
 
 
-// ___________________________________________________________________________________________________
-void fastNLOTable::ReadScenario(istream& table){
-   table.peek();
-   if (table.eof()){
-      logger.warn["ReadScenario"]<<"Cannot read from file."<<endl;
-   }
+//______________________________________________________________________________
+void fastNLOTable::WriteHeader(std::ostream& table) {
+   table << fastNLO::tablemagicno << sep;
+   table << GetItabversion() << sep;
+   if ( GetItabversion() >= 24000 ) table << "fastNLO_Header" << sep;
+   if ( ScenName.find(" ")!=string::npos )  {
+      logger.warn["WriteHeader"]<<"Scenario name is not allowed to contain white spaces!!"<<endl;
+      ScenName = ScenName.substr(0,ScenName.find(" "));
+      logger.warn["WriteHeader"]<<"Write ScenarioName: "<<ScenName<<endl;
+   }
+   table << ScenName << sep;
+   table << GetNcontrib() << sep;
+   table << GetNmult() << sep;
+   table << GetNdata() << sep;
+   table << 0 << sep; // NUserString
+   table << 0 << sep; // NuserInt
+   table << 0 << sep; // NuserFloat
+   table << 0 << sep; // Imachine
+}
 
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      logger.error["ReadScenario"]<<"Did not find initial magic number, aborting!"<<endl;
-      logger.error["ReadScenario"]<<"Please check compatibility of tables and program version!"<<endl;
-      exit(1);
-   }
 
+// ___________________________________________________________________________________________________
+void fastNLOTable::ReadScenario(istream& table){
+   //table.peek();
+   fastNLOTools::ReadMagicNo(table);
+   std::string test;
+   if ( Itabversion >= 24000 ) table >> test; // "fastNLO_Scenario
    table >> Ipublunits;
-   int  NScDescript = 0;
-   table >> NScDescript;
-   ScDescript.resize(NScDescript);
+   fastNLOTools::ReadFlexibleVector(ScDescript,table);
    char buffer[257];
-   table.getline(buffer,256);
-   for(int i=0;i<NScDescript;i++){
-      table.getline(buffer,256);
-      ScDescript[i] = buffer;
-      //      StripWhitespace(ScDescript[i]);
-   }
+   // size_t NScDescript = 0;
+   // table >> NScDescript;
+   // ScDescript.resize(NScDescript);
+   // table.getline(buffer,256);
+   // for(size_t i=0;i<NScDescript;i++){
+   //    table.getline(buffer,256);
+   //    ScDescript[i] = buffer;
+   //    //      StripWhitespace(ScDescript[i]);
+   // }
 
    table >> Ecms;
    table >> ILOord;
    table >> NObsBin;
+   //NDim = fastNLOTools::ReadFlexibleVector(DimLabel,table) -1 ;
    table >> NDim;
    DimLabel.resize(NDim);
    table.getline(buffer,256);
@@ -183,7 +266,7 @@ void fastNLOTable::ReadScenario(istream& table){
       table.getline(buffer,256);
       DimLabel[i] = buffer;
    }
-
+   //fastNLOTools::ReadFlexibleVector(IDiffBin,table,NDim);
    IDiffBin.resize(NDim);
    for(int i=NDim-1;i>=0;i--){
       table >>  IDiffBin[i];
@@ -201,17 +284,15 @@ void fastNLOTable::ReadScenario(istream& table){
          }
       }
    }
-
-   BinSize.resize(NObsBin);
-   for(unsigned int i=0;i<NObsBin;i++){
-      table >> BinSize[i];
-   }
+   fastNLOTools::ReadFlexibleVector(BinSize,table,NObsBin);
+   // BinSize.resize(NObsBin);
+   // for(unsigned int i=0;i<NObsBin;i++){
+   //    table >> BinSize[i];
+   // }
 
    table >> INormFlag;
-   if(INormFlag>1){
-      table >> DenomTable;
-   }
-   if(INormFlag>0){
+   if( INormFlag < 0 ) table >> DenomTable;
+   if( INormFlag != 0 ){
       IDivLoPointer.resize(NObsBin);
       IDivUpPointer.resize(NObsBin);
       for(unsigned int i=0;i<NObsBin;i++){
@@ -219,239 +300,798 @@ void fastNLOTable::ReadScenario(istream& table){
          table >> IDivUpPointer[i];
       }
    }
-
-   if (!fastNLOTools::ReadMagicNo(table)) {
-      logger.error["ReadScenario"]<<"Did not find final magic number, aborting!"<<endl;
-      logger.error["ReadScenario"]<<"Please check compatibility of tables and program version!"<<endl;
-      exit(1);
-   }
+   if ( Itabversion >= 24000 ) fastNLOTools::ReadUnused(table); // v2.4 yet unused
+   if ( Itabversion >= 24000 ) fastNLOTools::ReadUnused(table); // v2.4 yet unused
+   fastNLOTools::ReadMagicNo(table);
+   // if (!fastNLOTools::ReadMagicNo(table)) {
+   //    logger.error["ReadScenario"]<<"Did not find final magic number, aborting!"<<endl;
+   //    logger.error["ReadScenario"]<<"Please check compatibility of tables and program version!"<<endl;
+   //    exit(1);
+   // }
    fastNLOTools::PutBackMagicNo(table);
 }
 
 
 // ___________________________________________________________________________________________________
-void fastNLOTable::WriteScenario(ostream& table){
-   table << tablemagicno << endl;
-   table << Ipublunits << endl;
-   int NScDescript =  ScDescript.size();
-   table << NScDescript << endl;
-   for(int i=0;i<NScDescript;i++){
-      table << ScDescript[i] << endl;
-   }
-   table << Ecms << endl;
-   table << ILOord << endl;
-   table << NObsBin << endl;
-   table << NDim << endl;
+void fastNLOTable::WriteScenario(std::ostream& table){
+   table << fastNLO::tablemagicno << sep;
+   if ( GetItabversion() >= 24000 ) table << "fastNLO_Scenario" <<sep;
+   table << Ipublunits << sep;
+   size_t NScDescript = ScDescript.size();
+   table << NScDescript << sep;
+   for(size_t i=0;i<NScDescript;i++){
+      table << ScDescript[i] << sep;
+   }
+   table << Ecms << sep;
+   table << ILOord << sep;
+   logger.debug["WriteScenario"]<<"Writing NObsBin to be "<<NObsBin<<endl;
+   table << NObsBin << sep;
+   table << NDim << sep;
    for(int i=NDim-1;i>=0;i--){
-      table << DimLabel[i] << endl;
+      table << DimLabel[i] << sep;
    }
    for(int i=NDim-1;i>=0;i--){
-      table << IDiffBin[i] << endl;
+      table << IDiffBin[i] << sep;
    }
+   logger.debug["WriteScenario"]<<"Bin border size is "<<Bin.size()<<endl;
    for(unsigned int i=0;i<NObsBin;i++){
       for(int j=NDim-1;j>=0;j--){
-         table <<  Bin[i][j].first  << endl;
-         if(IDiffBin[j]==0 || IDiffBin[j]==2) table <<  Bin[i][j].second  << endl;
+         table <<  Bin[i][j].first  << sep;
+         if(IDiffBin[j]==0 || IDiffBin[j]==2) table <<  Bin[i][j].second  << sep;
       }
    }
    for(unsigned int i=0;i<NObsBin;i++){
-     table << BinSize[i]  << endl;
+     table << BinSize[i]  << sep;
    }
 
-   table << INormFlag << endl;
-   if(INormFlag>1){
-      table << DenomTable << endl;
+   table << INormFlag << sep;
+   if( INormFlag < 0 ){
+      table << DenomTable << sep;
    }
-   if(INormFlag>0){
+   if( INormFlag != 0 ){
       for(unsigned int i=0;i<NObsBin;i++){
-         table << IDivLoPointer[i] << endl;
-         table << IDivUpPointer[i] << endl;
+         table << IDivLoPointer[i] << sep;
+         table << IDivUpPointer[i] << sep;
       }
    }
+   if ( GetItabversion() >= 24000 ) table << 0 << sep; // v2.4 (yet unused)
+   if ( GetItabversion() >= 24000 ) table << 0 << sep; // v2.4 (yet unused)
 }
 
 
 // ___________________________________________________________________________________________________
 bool fastNLOTable::IsCompatible(const fastNLOTable& other) const {
    if ( !IsCompatibleHeader(other) ) return false;
+   if ( !IsCompatibleScenario(other) ) return false;
+   logger.info["IsCompatible"]<<"Tables seem to be compatible for merging/appending. Continuing."<<endl;
+   return true;
+}
+
+
+// ___________________________________________________________________________________________________
+bool fastNLOTable::IsCompatibleScenario(const fastNLOTable& other) const {
    bool potentialcompatible = true;
    if(Ipublunits != other.Ipublunits){
-      logger.warn["IsCompatible"]<<"Differing cross section units found: "<<Ipublunits<<" and "<<other.Ipublunits<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing cross section units found: "<<Ipublunits<<" and "<<other.Ipublunits<<endl;
       return false;
    }
    if(ScDescript != other.ScDescript){
-      logger.warn["IsCompatible"]<<"Differing scale description found."<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing scenario description found."<<endl;
       potentialcompatible = false;
    }
    if(!cmp(Ecms,other.Ecms)){
-      logger.warn["IsCompatible"]<<"Differing center-of-mass energy found: "<<Ecms<<" and "<<other.Ecms<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing center-of-mass energy found: "<<Ecms<<" and "<<other.Ecms<<endl;
       return false;
    }
    if(ILOord != other.ILOord){
-      logger.warn["IsCompatible"]<<"Differing ILOord found: "<<ILOord<<" and "<<other.GetLoOrder()<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing ILOord found: "<<ILOord<<" and "<<other.GetLoOrder()<<endl;
       return false;
    }
    if(NObsBin != other.NObsBin){
-      logger.warn["IsCompatible"]<<"Differing NObsBin found: "<<NObsBin<<" and "<<other.NObsBin<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing NObsBin found: "<<NObsBin<<" and "<<other.NObsBin<<endl;
       return false;
    }
    if(NDim != other.NDim){
-      logger.warn["IsCompatible"]<<"Differing NDim found: "<<NDim<<" and "<<other.NDim<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing NDim found: "<<NDim<<" and "<<other.NDim<<endl;
       return false;
    }
    if(DimLabel != other.DimLabel){
-      logger.warn["IsCompatible"]<<"Differing label of observables found."<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing label of observables found."<<endl;
       potentialcompatible = false;
    }
    if(IDiffBin != other.IDiffBin){
-      logger.warn["IsCompatible"]<<"Differing IDiffBin found."<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing IDiffBin found."<<endl;
       return false;
    }
    if(!cmp(Bin,other.Bin)){
-      logger.warn["IsCompatible"]<<"Differing Bin boundaries found."<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing Bin boundaries found."<<endl;
       return false;
    }
    if(!cmp(BinSize,other.BinSize)){
-      logger.warn["IsCompatible"]<<"Differing bin sizes found."<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing bin sizes found."<<endl;
       return false;
    }
    if(INormFlag != other.INormFlag){
-      logger.warn["IsCompatible"]<<"Differing INormFlag found: "<<INormFlag<<" and "<<other.INormFlag<<endl;
+      logger.warn["IsCompatibleScenario"]<<"Differing INormFlag found: "<<INormFlag<<" and "<<other.INormFlag<<endl;
       return false;
    }
-   if(INormFlag>1){
+   if(INormFlag<0){
       if(DenomTable != other.DenomTable){
-         logger.warn["IsCompatible"]<<"Differing DenomTable found."<<endl;
+         logger.warn["IsCompatibleScenario"]<<"Differing DenomTable found."<<endl;
          return false;
       }
    }
-   if(INormFlag>0){
+   if(INormFlag!=0){
       for(unsigned int i=0;i<NObsBin;i++){
          if(IDivLoPointer[i] != other.IDivLoPointer[i]){
-            logger.warn["IsCompatible"]<<"Differing IDivLoPointer["<<i<<"] found"<<endl;
+            logger.warn["IsCompatibleScenario"]<<"Differing IDivLoPointer["<<i<<"] found"<<endl;
             return false;
          }
          if(IDivUpPointer[i] != other.IDivUpPointer[i]){
-            logger.warn["IsCompatible"]<<"Differing IDivUpPointer["<<i<<"] found."<<endl;
+            logger.warn["IsCompatibleScenario"]<<"Differing IDivUpPointer["<<i<<"] found."<<endl;
             return false;
          }
       }
    }
-   if ( !potentialcompatible ) logger.warn["IsCompatible"]<<"Some labels have differing values, but relevant variables seem to be compatible. Continuing."<<endl;
+   if ( !potentialcompatible ) logger.warn["IsCompatibleScenario"]<<"Some labels have differing values, but relevant variables seem to be compatible. Continuing."<<endl;
    return true;
-
 }
 
 
 // ___________________________________________________________________________________________________
-void fastNLOTable::AddTable(const fastNLOTable& other){
-   // add another table to this table.
-   // Add either further contributions (higher-orders, data, non-pert corr, etc...)
-   // or increase statistics of fixed-order calc.
-   //
-   if ( !IsCompatible(other) ) {
-      logger.warn["AddTable"]<<"Table not compatible with this table. Ignoring command."<<endl;
-      return;
-   }
+bool fastNLOTable::IsCatenable(const fastNLOTable& other) const {
+   if ( !IsCatenableHeader(other) ) return false;
+   if ( !IsCatenableScenario(other) ) return false;
 
-   // loop over all contributions from 'other'-table
    const bool quiet = true;
    const int nc = other.GetNcontrib() + other.GetNdata();
+   // loop over all contributions from 'other'-table to check catenability
+   int matches[nc];
    for ( int ic=0 ; ic<nc; ic++ ) {
-      bool wasAdded = false;
+      matches[ic] = 0;
+      // check against all contributions from 'this'-table to check catenability
+      for (unsigned int j = 0; j<fCoeff.size() ; j++) {
+         fastNLOCoeffBase* cother = (fastNLOCoeffBase*)other.GetCoeffTable(ic);
+         // data?
+         if ( fastNLOCoeffData::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffData* cdatthis  = (fastNLOCoeffData*)fCoeff[j];
+            fastNLOCoeffData* cdatother = (fastNLOCoeffData*)other.GetCoeffTable(ic);
+            if ( cdatthis->IsCatenable(*cdatother) ) {
+               matches[ic]++;
+               continue;
+            }
+         }
+         // multiplicative?
+         else if ( fastNLOCoeffMult::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffMult* cmultthis  = (fastNLOCoeffMult*)fCoeff[j];
+            fastNLOCoeffMult* cmultother = (fastNLOCoeffMult*)other.GetCoeffTable(ic);
+            if ( cmultthis->IsCatenable(*cmultother) ) {
+               matches[ic]++;
+               continue;
+            }
+         }
+         // additive?
+         else if ( fastNLOCoeffAddBase::CheckCoeffConstants(cother,quiet) ) {
+            if ( fastNLOCoeffAddFix::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFix* cfixthis  = (fastNLOCoeffAddFix*)fCoeff[j];
+               fastNLOCoeffAddFix* cfixother = (fastNLOCoeffAddFix*)other.GetCoeffTable(ic);
+               if ( cfixthis->IsCatenable(*cfixother) ) {
+                  matches[ic]++;
+                  continue;
+               }
+            } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFlex* cflexthis  = (fastNLOCoeffAddFlex*)fCoeff[j];
+               fastNLOCoeffAddFlex* cflexother = (fastNLOCoeffAddFlex*)other.GetCoeffTable(ic);
+               if ( cflexthis->IsCatenable(*cflexother) ) {
+                  matches[ic]++;
+                  continue;
+               }
+            }
+         } else {
+            logger.error["IsCatenable"] << "Unknown contribution found. Aborted!" <<endl;
+            exit(1);
+         }
+      }
+   }
 
-      // is additive?
-      if ( other.GetCoeffTable(ic)->GetIAddMultFlag()==0) {
-         fastNLOCoeffAddBase* cadd = (fastNLOCoeffAddBase*)other.GetCoeffTable(ic);
-
-         // find compatible contribution, or add
-         for (unsigned int j = 0 ; j<fCoeff.size() ; j++) {
-            fastNLOCoeffAddBase* lhs = (fastNLOCoeffAddBase*)fCoeff[j];
-            if ( lhs->IsCompatible(*cadd) ) { // found compatible table
-               if ( wasAdded )
-                  logger.error["AddTable"]<<"This contribution was already added. It seems that there is one contribution twice in the table."<<endl;
-               else {
-                  logger.debug["AddTable"]<<"Summing contribution "<<ic<<" to fCoeff #"<<j<<endl;
-                  if ( fastNLOCoeffAddFlex::CheckCoeffConstants(lhs,quiet) ) {
-		     if ( !(lhs->IsCompatible(*cadd)) )
-			logger.warn["AddTable"]<<"Incompatible contributions found. Please check result carefully!"<<endl;
-		     lhs->Add(*cadd);
-		  }
-                  else if ( fastNLOCoeffAddFix::CheckCoeffConstants(lhs,quiet) ) {
-		     if ( !(lhs->IsCompatible(*cadd)) )
-			logger.warn["AddTable"]<<"Incompatible contributions found. Please check result carefully!"<<endl;
-		     lhs->Add(*cadd);
-		  }
-                  wasAdded = true;
+   // check match count; all numbers must be unity
+   bool catenable = true;
+   for ( int ic=0 ; ic<nc; ic++ ) {
+      if ( matches[ic] != 1 ) {
+         catenable = false;
+         logger.warn["IsCatenable"] << "Table contributions do not match. Catenation of observable bins not possible!" <<endl;
+         break;
+      }
+   }
+   if ( catenable ) {
+      logger.info["IsCatenable"]<<"Table contributions seem to be compatible for catenating observable bins. Continuing."<<endl;
+   }
+   return catenable;
+}
+
+
+// ___________________________________________________________________________________________________
+bool fastNLOTable::IsCatenableScenario(const fastNLOTable& other) const {
+   bool potentialcatenable = true;
+   if(Ipublunits != other.Ipublunits){
+      logger.warn["IsCatenableScenario"]<<"Differing cross section units found: "<<Ipublunits<<" and "<<other.Ipublunits<<endl;
+      return false;
+   }
+   if(ScDescript != other.ScDescript){
+      logger.warn["IsCatenableScenario"]<<"Differing scenario description found. Only the first one is kept."<<endl;
+      potentialcatenable = false;
+   }
+   if(!cmp(Ecms,other.Ecms)){
+      logger.warn["IsCatenableScenario"]<<"Differing center-of-mass energy found: "<<Ecms<<" and "<<other.Ecms<<endl;
+      return false;
+   }
+   if(ILOord != other.ILOord){
+      logger.warn["IsCatenableScenario"]<<"Differing ILOord found: "<<ILOord<<" and "<<other.GetLoOrder()<<endl;
+      return false;
+   }
+   if(NDim != other.NDim){
+      logger.warn["IsCatenableScenario"]<<"Differing NDim found: "<<NDim<<" and "<<other.NDim<<endl;
+      return false;
+   }
+   if(DimLabel != other.DimLabel){
+      logger.warn["IsCatenableScenario"]<<"Differing label of observables found."<<endl;
+      potentialcatenable = false;
+   }
+   if(IDiffBin != other.IDiffBin){
+      logger.warn["IsCatenableScenario"]<<"Differing IDiffBin found."<<endl;
+      return false;
+   }
+   if(INormFlag != other.INormFlag){
+      logger.warn["IsCatenableScenario"]<<"Differing INormFlag found: "<<INormFlag<<" and "<<other.INormFlag<<endl;
+      return false;
+   }
+   if(INormFlag<0){
+      if(DenomTable != other.DenomTable){
+         logger.warn["IsCatenableScenario"]<<"Differing DenomTable found."<<endl;
+         return false;
+      }
+   }
+   if ( !potentialcatenable ) logger.warn["IsCatenableScenario"]<<"Some labels have differing values, but relevant variables seem to be catenable. Continuing."<<endl;
+   return true;
+}
+
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::SetUserWeights(double wgt) {
+   //!< Set 'user' weights, which can be used for subsequent mergeing
+   for ( auto c : fCoeff) ((fastNLOCoeffAddBase*)c)->AccessWgtStat().SetWgtUser(wgt); // dangerous typecasting
+}
+// ___________________________________________________________________________________________________
+void fastNLOTable::SetUserWeights(std::vector<double > wgtsBin) {
+   //!< Set 'user' weights, which can be used for subsequent mergeing
+   for ( auto c : fCoeff) ((fastNLOCoeffAddBase*)c)->AccessWgtStat().SetWgtUser(wgtsBin); // dangerous typecasting
+}
+// ___________________________________________________________________________________________________
+void fastNLOTable::SetUserWeights(std::vector<std::vector<double> > wgtsBinProc) {
+   //!< Set 'user' weights, which can be used for subsequent mergeing
+   for ( auto c : fCoeff) ((fastNLOCoeffAddBase*)c)->AccessWgtStat().SetWgtUser(wgtsBinProc); // dangerous typecasting
+}
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::MergeTables(const std::vector<fastNLOTable*>& other, fastNLO::EMerge moption, double cutRMS) {
+   //!< Merge all other tables with the current one.
+   //!< Warning: data or multiplicative contributions might get lost
+   //!< Warning: Function may require lots of memory, because all contributions are kept in memory.
+
+   // --- all (other) options
+   if ( moption != kMean && moption != kMedian && cutRMS==0) {
+      for ( auto iTab :  other ) this->MergeTable(*iTab,moption);
+   }
+   // --- mean or median
+   else {
+      if ( other.size() < 30 )
+         logger.warn["MergeTables"]<<"Result may has a large spread, since only "<<other.size()+1<<" tables are merged."<<endl;
+
+      set<fastNLOCoeffBase*> ConsideredContrib;
+      // loop over contributions.
+      for ( unsigned int jc=0; jc<fCoeff.size(); jc++) {
+         if ( fastNLOCoeffAddBase::CheckCoeffConstants(fCoeff[jc],true) ) {
+            fastNLOCoeffAddBase* cadd = (fastNLOCoeffAddBase*)fCoeff[jc];
+            //set<fastNLOCoeffAddBase*> others;
+            vector<fastNLOCoeffAddBase*> others;
+            // ---- find corresponding 'other' contributions
+            for ( unsigned int ioth = 0 ; ioth<other.size() ; ioth++ ) {
+               const int ntot = other[ioth]->GetNcontrib() + other[ioth]->GetNdata();
+               for ( int ic=0; ic<ntot; ic++ ) {
+                  fastNLOCoeffAddBase* cother = (fastNLOCoeffAddBase*)other[ioth]->GetCoeffTable(ic); // too optimistic typecast
+                  if ( fastNLOCoeffAddBase::CheckCoeffConstants((fastNLOCoeffBase*)cother,true) ) {
+                     if ( cadd->IsCompatible(*cother) ) {
+                        //logger.info["MergeTables"]<<"Found compatible contributions"<<endl;
+                        others.push_back(cother); //insert()
+                        ConsideredContrib.insert(cother);
+                     }
+                  }
+               }
+            }
+            logger.info["MergeTables"]<<"Found "<<others.size()<<" compatible contributions."<<endl;
+
+            // loop over all compatible contributions and
+            vector<double > nAll{cadd->GetNevt()};
+            for ( auto othctr : others ) nAll.push_back( othctr->GetNevt());
+
+            if ( fastNLOCoeffAddFlex::CheckCoeffConstants(cadd,true) ) {//flexible
+               fastNLOCoeffAddFlex* ctrb = (fastNLOCoeffAddFlex*)cadd;
+               vector<fastNLO::v5d*> s0 = ctrb->AccessSigmaTildes();
+               vector<vector<fastNLO::v5d*> > sAll{s0};
+               vector<fastNLOCoeffAddFlex* > cAll{ctrb};
+               for ( auto othctr : others ) {
+                  sAll.push_back( ((fastNLOCoeffAddFlex*)othctr)->AccessSigmaTildes());
+                  //nAll.push_back( ((fastNLOCoeffAddFlex*)othctr)->GetNevt());
+                  cAll.push_back((fastNLOCoeffAddFlex*)othctr);
+               }
+               int cMax = s0.size();
+               for ( int ii = cMax-1 ; ii>= 0 ; ii-- ) {
+                  if ( s0[ii]->size()==0 ) cMax--;
+               }
+               vector<double > vals(sAll.size()); // allocate only once
+
+//<<<<<<< .mine
+			      // for ( int im = 0 ; im<cMax ; im++ ) { // mu-indep, mur, muf, ...
+			      // 	 vals.clear();
+			      // 	 double mean0 = 0;
+			      // 	 double rms = 0;
+			      // 	 unsigned int n0 = 0;
+			      // 	 if ( cutRMS != 0 ) {
+			      // 	    for ( unsigned int is = 0 ; is < sAll.size() ; is++ ) {
+			      // 	       //vals[is] = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+			      // 	       double vv = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+			      // 	       if ( vv != 0 ) {
+			      // 		  mean0 += vv;
+			      // 		  rms   += vv*vv;
+			      // 		  n0++;
+			      // 	       }
+			      // 	    }
+			      // 	    if ( n0 != 0 ) {
+			      // 	       mean0 /= n0;
+			      // 	       rms = sqrt(rms/n0);
+			      // 	    }
+			      // 	 }
+				 
+			      // 	 // fill 'vals'
+			      // 	 //vals.reserve(sAll.size());
+			      // 	 for ( unsigned int is = 0 ; is < sAll.size() ; is++ ) {
+			      // 	    double vv = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+			      // 	    if ( ( cutRMS == 0 && vv != 0 ) ||
+			      // 		 ( cutRMS!=0 && vv!=0 && n0 !=0 && fabs(vv-mean0) < rms*cutRMS ) ){
+			      // 	       // fill vals array again, now with cuts	
+			      // 	       vals.push_back(vv);
+			      // 	    }
+			      // 	    // else if ( (*sAll[0][im])[iobs][x][jS1][kS2][n]!=0 && vv!=0 ) {
+			      // 	    //    cout<<"discard tab-ID="<<is<<"\trms="<<rms<<"\tvv-mean="<<fabs(vv-mean0)<<endl;
+			      // 	    // }
+			      // 	 }
+			      // 	 if ( cutRMS!=0  && n0 != vals.size() ) 
+			      // 	    logger.info["MergeTables"]<<"Discarded "<<sAll.size()-vals.size()<<" value(s) out of "<< sAll.size()<<" [CutRMS or zero] (bin="<<iobs<<", proc="<<n<<")."<<endl;
+			      // 	 if ( cutRMS!=0  && n0!=0 && vals.size()==0 ) {
+			      // 	    logger.error["MergeTables"]<<"Too tight RMS cut. No values remain. Exiting."<<endl;
+			      // 	    exit(1);
+			      // 	 }
+				 
+			      // 	 // assign merged values
+			      // 	 if ( moption == kMean  ) {
+			      // 	    double mean = 0;
+			      // 	    for ( auto ii : vals ) mean+=ii;
+			      // 	    //(*s0[im])[iobs][x][jS1][kS2][n] = mean*nAll[0]/sAll.size();
+			      // 	    if ( mean != 0 ) 
+			      // 	       (*s0[im])[iobs][x][jS1][kS2][n] = mean*nAll[0]/vals.size();
+			      // 	    else 
+			      // 	       (*s0[im])[iobs][x][jS1][kS2][n] = 0;
+			      // 	 }
+			      // 	 else if ( moption == kMedian ) {
+			      // 	    double median = 0;
+			      // 	    if ( vals.size() ) {
+			      // 	       std::nth_element( vals.begin(), vals.begin()+vals.size()/2,vals.end() );
+			      // 	       median = vals[vals.size()/2];
+			      // 	       if ( vals.size()%2 == 0 ) {
+			      // 		  median = (median + *(std::max_element(vals.begin(),vals.begin()+vals.size()/2))) /2.;
+			      // 	       }
+			      // 	       // printf("mu[%d] mean=% 8.2e\trms=% 8.2e\tv0=% 8.2e\tmedian=% 8.2e\n",
+			      // 	       // 	   im,     mean*nAll[0],    rms*nAll[0],
+			      // 	       // 	   (*s0[im])[iobs][x][jS1][kS2][n],   median * nAll[0] );
+			      // 	    }
+			      // 	    (*s0[im])[iobs][x][jS1][kS2][n] = median*nAll[0]; // nAll[0] is 'new' normalisation
+			      // 	 }
+			      // 	 else {// cutRMS !=0
+			      // 	    double wsum=0, ssum=0; //nsum=0
+			      // 	    unsigned int nn = 0;
+// =======
+                for (unsigned int iobs=0 ; iobs<ctrb->SigmaTildeMuIndep.size() ; iobs++) {
+                   for (unsigned int jS1=0; jS1<ctrb->GetNScaleNode1(iobs); jS1++) {
+                      for (unsigned int kS2=0; kS2<ctrb->GetNScaleNode2(iobs); kS2++) {
+                         for (int x=0; x<ctrb-> GetNxmax(iobs); x++) {
+                            for (int n=0; n<ctrb->GetNSubproc(); n++) {
+// >>>>>>> .r2418
+
+                               for ( int im = 0 ; im<cMax ; im++ ) { // mu-indep, mur, muf, ...
+                                  vals.clear();
+                                  double mean0 = 0;
+                                  double rms = 0;
+                                  unsigned int n0 = 0;
+                                  if ( cutRMS != 0 ) {
+                                     for ( unsigned int is = 0 ; is < sAll.size() ; is++ ) {
+                                        //vals[is] = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+                                        double vv = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+                                        if ( vv != 0 ) {
+                                           mean0 += vv;
+                                           rms   += vv*vv;
+                                           n0++;
+                                        }
+                                     }
+                                     if ( n0 != 0 ) {
+                                        mean0 /= n0;
+                                        rms = sqrt(rms/n0);
+                                     }
+                                  }
+
+                                  // fill 'vals'
+                                  //vals.reserve(sAll.size());
+                                  for ( unsigned int is = 0 ; is < sAll.size() ; is++ ) {
+                                     double vv = (*sAll[is][im])[iobs][x][jS1][kS2][n] / nAll[is];
+                                     if ( ( cutRMS == 0 && vv != 0 ) ||
+                                          ( cutRMS!=0 && vv!=0 && n0 !=0 && fabs(vv-mean0) < rms*cutRMS ) ){
+                                        // fill vals array again, now with cuts
+                                        vals.push_back(vv);
+                                     }
+                                     // else if ( (*sAll[0][im])[iobs][x][jS1][kS2][n]!=0 && vv!=0 ) {
+                                     //    cout<<"discard tab-ID="<<is<<"\trms="<<rms<<"\tvv-mean="<<fabs(vv-mean0)<<endl;
+                                     // }
+                                  }
+                                  if ( cutRMS!=0  && n0 != vals.size() )
+                                     logger.info["MergeTables"]<<"Discarded "<<sAll.size()-vals.size()<<" value(s) out of "<< sAll.size()<<" [CutRMS or zero] (bin="<<iobs<<", proc="<<n<<")."<<endl;
+                                  if ( cutRMS!=0  && n0!=0 && vals.size()==0 ) {
+                                     logger.error["MergeTables"]<<"Too tight RMS cut. No values remain. Exiting."<<endl;
+                                     exit(1);
+                                  }
+
+                                  // assign merged values
+                                  if ( moption == kMean  ) {
+                                     double mean = 0;
+                                     if ( vals.size() ) {
+                                        for ( auto ii : vals ) mean+=ii;
+                                        mean /= vals.size();
+                                     }
+                                     (*s0[im])[iobs][x][jS1][kS2][n] = mean*nAll[0];
+                                  }
+                                  else if ( moption == kMedian ) {
+                                     double median = 0;
+                                     if ( vals.size() ) {
+                                        std::nth_element( vals.begin(), vals.begin()+vals.size()/2,vals.end() );
+                                        median = vals[vals.size()/2];
+                                        if ( vals.size()%2 == 0 ) {
+                                           median = (median + *(std::max_element(vals.begin(),vals.begin()+vals.size()/2))) /2.;
+                                        }
+                                        // printf("mu[%d] mean=% 8.2e\trms=% 8.2e\tv0=% 8.2e\tmedian=% 8.2e\n",
+                                        //          im,     mean*nAll[0],    rms*nAll[0],
+                                        //          (*s0[im])[iobs][x][jS1][kS2][n],   median * nAll[0] );
+                                     }
+                                     (*s0[im])[iobs][x][jS1][kS2][n] = median*nAll[0]; // nAll[0] is 'new' normalisation
+                                  }
+                                  else {// cutRMS !=0
+                                     double wsum=0, ssum=0; //nsum=0
+                                     unsigned int nn = 0;
+// ??????
+                                    for ( fastNLOCoeffAddFlex* cit : cAll ) {
+                                       double w2 = cit->GetMergeWeight(moption,n,iobs);
+                                       double s2 = (*cit->AccessSigmaTildes()[im])[iobs][x][jS1][kS2][n];
+                                       double n2 = cit->GetNevt();
+                                       double vv = s2 / n2;
+                                       //
+                                       if ( (cutRMS == 0 && vv != 0 ) ||
+                                            ( cutRMS!=0 && vv!=0 && n0 !=0 && fabs(vv-mean0) < rms*cutRMS ) ) {
+                                          ssum += w2*s2/n2;
+                                          wsum += w2;
+                                          //nsum += n2;
+                                          nn++;
+                                       }
+                                    }
+
+                                    if ( nn != vals.size() ) {
+                                       logger.error["MergeTables"]<<"'Cutflow' for median/mean not identical to other weights. Please contact developers."<<endl;
+                                       cout<<"nn="<<nn<<"\tvals.size()="<<vals.size()<<"\tsAll.size()="<<sAll.size()<<endl;
+                                       exit(3);
+                                    }
+                                    if ( wsum != 0 )
+                                       (*s0[im])[iobs][x][jS1][kS2][n] = ssum / wsum * nAll[0];
+                                    else
+                                       (*s0[im])[iobs][x][jS1][kS2][n] = 0;
+                                    //s1 = ( w1*s1/n1 + w2*s2/n2 ) / (w1 + w2 ) * ( n1 + n2 ) ;
+                                 }
+                              }
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+            else { // fixed scale
+               fastNLOCoeffAddFix* ctrb = (fastNLOCoeffAddFix*)cadd;
+               vector<double> vals(nAll.size());
+               for (unsigned int iobs=0 ; iobs<ctrb->SigmaTilde.size() ; iobs++) {
+                  for (unsigned int s=0 ; s<ctrb->SigmaTilde[iobs].size() ; s++) {
+                     for (unsigned int x=0 ; x<ctrb->SigmaTilde[iobs][s].size() ; x++) {
+                        for (unsigned int l=0 ; l<ctrb->SigmaTilde[iobs][s][x].size() ; l++) {
+                           for (unsigned int p=0 ; p<ctrb->SigmaTilde[iobs][s][x][l].size() ; p++) {
+
+                              double mean0 = 0;
+                              double rms = 0;
+                              if ( cutRMS != 0 ) {
+                                 mean0 += ctrb->SigmaTilde[iobs][s][x][l][p] / ctrb->GetNevt()  ;
+                                 rms   += ctrb->SigmaTilde[iobs][s][x][l][p] / ctrb->GetNevt() * ctrb->SigmaTilde[iobs][s][x][l][p] / ctrb->GetNevt();
+                                 for ( auto othctr : others ) {
+                                    mean0 += ((fastNLOCoeffAddFix*)othctr)->SigmaTilde[iobs][s][x][l][p] / othctr->GetNevt();
+                                    rms += ((fastNLOCoeffAddFix*)othctr)->SigmaTilde[iobs][s][x][l][p] / othctr->GetNevt()*((fastNLOCoeffAddFix*)othctr)->SigmaTilde[iobs][s][x][l][p] / othctr->GetNevt();
+                                 }
+                                 mean0 /= nAll.size();
+                                 rms = sqrt(rms/nAll.size());
+                              }
+
+                              if ( moption == kMean  ) { // mergeing option 'mean'
+                                 if ( cutRMS==0 ) { // no cut on RMS
+                                    double mean = ctrb->SigmaTilde[iobs][s][x][l][p] / ctrb->GetNevt()  ;
+                                    for ( auto othctr : others )
+                                       mean += ((fastNLOCoeffAddFix*)othctr)->SigmaTilde[iobs][s][x][l][p] / othctr->GetNevt();
+                                    ctrb->SigmaTilde[iobs][s][x][l][p] = mean*nAll[0]/nAll.size();
+                                 }
+                                 else { // with RMS cut
+                                    unsigned int nn=0;
+                                    double mean=0;
+                                    double v = ctrb->SigmaTilde[iobs][s][x][l][p] / ctrb->GetNevt()  ;
+                                    if ( fabs(v-mean0) < rms*cutRMS ) {mean+=v; nn++;}
+                                    for ( auto othctr : others ) {
+                                       v =  ((fastNLOCoeffAddFix*)othctr)->SigmaTilde[iobs][s][x][l][p] / othctr->GetNevt();
+                                       if ( fabs(v-mean0) < rms*cutRMS ) {mean+=v; nn++;}
+                                    }
+                                    ctrb->SigmaTilde[iobs][s][x][l][p] = mean*nAll[0]/nn;
+                                    if ( nn!=nAll.size() ) cout<<"[CutRMS] Discarded "<<nAll.size()-nn<<" table values out of "<< nAll.size()<<" (bin="<<iobs<<", proc="<<p<<")."<<endl;
+                                 }
+                              }
+                              else if ( moption == kMedian ) { // mergeing option 'median'
+                                 if ( cutRMS==0 ) { // cut on RMS
+                                    cout<<"todo fadfoo"<<endl;
+                                    exit(3);
+                                 }
+                                 else { // no RMS cut
+                                    vals[0] = ctrb->SigmaTilde[iobs][s][x][l][p]  / ctrb->GetNevt();
+                                    for ( unsigned int is = 0 ; is < others.size() ; is++ ) {
+                                       vals[is+1] = ((fastNLOCoeffAddFix*)others[is])->SigmaTilde[iobs][s][x][l][p] / others[is]->GetNevt();
+                                    }
+                                    std::nth_element( vals.begin(), vals.begin()+vals.size()/2,vals.end() );
+                                    double median = vals[vals.size()/2];
+                                    if ( vals.size()%2 == 0 ) {
+                                       median = (median + *(std::max_element(vals.begin(),vals.begin()+vals.size()/2))) /2.;
+                                    }
+                                    ctrb->SigmaTilde[iobs][s][x][l][p] = median*nAll[0];
+                                 }
+                              }
+                              else {// cutRMS !=0
+                                 cout<<"Not Implemented. todo."<<endl;
+                                 exit(2);
+                              }
+
+                           }
+                        }
+                     }
+                  }
                }
             }
-	    // else {
-	    //    logger.warn["AddTable"]<<"Incompatible tables found!"<<endl;
-	    // }
+            // add number of events together
+            for ( auto othctr : others ) {
+               cadd->AccessWgtStat().Add(othctr->GetWgtStat());
+            }
+            cadd->Nevt = nAll[0];
+            double nTot = 0;
+            for ( auto ii : nAll ) nTot+=ii;
+            cadd->NormalizeCoefficients(nTot);
          }
       }
-      else {
-         // check if this data or 'mult' contribution already exists (which should not happen)
-         cout<<"todo. Check if data table already exists!."<<endl;
+      // check for further contributions, which have not been considered!
+      for ( unsigned int ioth = 0 ; ioth<other.size() ; ioth++ ) {
+         const int ntot = other[ioth]->GetNcontrib() + other[ioth]->GetNdata();
+         for ( int ic=0; ic<ntot; ic++ ) {
+            if ( ConsideredContrib.count(other[ioth]->GetCoeffTable(ic)) == 0 ){
+               logger.error["MergeTables"]<<"Some contribution is not considered and thus gets lost!"<<endl;
+               logger.error["MergeTables"]<<"All input tables to the function fastNLOTable::MergeTables() must be already present in the current fastNLOTable instance."<<endl;
+               exit(3);
+            }
+         }
       }
+      logger.info["MergeTables"]<<(moption == kMean ? "Mean" : "Median")<<" out of "<< other.size()+1<<" tables calculated successfully."<<endl;
+   }
+}
+
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::MergeTable(const fastNLOTable& other, fastNLO::EMerge moption) {
+   //!< Merge another table with the current one.
+   //!< Use the option moption in order to specify the weighting procedure.
+   //!<    + Default option uses 'normalisation' constant Nevt (usually called 'merge')
+   //!<    + Other weighting options are available.
+   //!<    + Weighting which consider weights for individual bins and subprocesses can be chosen.
+   //!<    + Tables can be 'appended', i.e. the sum of the cross sections is calculated.
+
+   // --- sanity and info messages
+   if ( moption==fastNLO::kMedian || moption==fastNLO::kMean) {
+      logger.error["MergeTable"]<<"Options 'median' and 'mean' are not available when mergeing (only) two tables. Please use program fnlo-tk-merge2."<<endl; exit(1);
+   }
+   if ( moption == fastNLO::kUnweighted || moption == fastNLO::kAdd )
+      logger.info["AppendTable"]<<"Adding (appending) another table. Resulting table will have weight 1 if option 'append' or 'unweighted' is used."<<endl;
+   if ( moption == fastNLO::kUnweighted )
+      logger.warn["AppendTable"]<<"Option 'unweighted' requested. Do you probably want to use the number of entries instead (option = kNumEvent)? Continuing."<<endl;
+
+   // --- just call AddTable
+   AddTable(other,moption);
+   return ;
+}
+
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::AddTable(const fastNLOTable& other, fastNLO::EMerge moption) {
+   // Add another table to this table.
+   // Either increase statistics of existing fixed-order contribution or
+   // add further contributions (or both, if many tables are merged)
+   //
+   if ( !IsCompatible(other) ) {
+      logger.error["AddTable"]<<"Tried to add/merge incompatible tables. Aborted!"<<endl;
+      exit(1);
+   }
 
-      // couldn't find a corresponding contribution.
-      // add this contribution as new contrib.
+   // These are counters for the newly read other table ...,
+   const int ntot = other.GetNcontrib() + other.GetNdata();
+   // but we need also to bookkeep this for the current table!
+   int newnc = fCoeff.size();
+   int newnd = 0;
+   bool quiet = true;
+   for ( unsigned int jc=0; jc<fCoeff.size(); jc++) {
+      fastNLOCoeffBase* cthis = (fastNLOCoeffBase*)fCoeff[jc];
+      if ( fastNLOCoeffData::CheckCoeffConstants(cthis,quiet) ) {
+         newnc--;
+         newnd++;
+      }
+   }
+   // Loop over all contributions from 'other'-table
+   for ( int ic=0; ic<ntot; ic++ ) {
+      logger.info["fastNLOTable::AddTable"]<<"Adding contribution no. " << ic << endl;
+      bool wasAdded = false;
+      // Find matching contribution from 'this'-table
+      for ( unsigned int jc=0; jc<fCoeff.size(); jc++) {
+         fastNLOCoeffBase* cother = (fastNLOCoeffBase*)other.GetCoeffTable(ic);
+         // Identify type of other coeff table
+         // Additive fixed-order?
+         if ( fastNLOCoeffAddBase::CheckCoeffConstants(cother,quiet) ) {
+            if ( fastNLOCoeffAddFix::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFix* clhs = (fastNLOCoeffAddFix*)fCoeff[jc];
+               fastNLOCoeffAddFix* crhs = (fastNLOCoeffAddFix*)other.GetCoeffTable(ic);
+               if ( clhs->IsCompatible(*crhs) ) {
+                  logger.info["AddTable"]<<"Found matching fix-scale additive contribution." << endl;
+                  logger.debug["AddTable"]<<"Summing contribution "<<ic<<" to fCoeff #"<<jc<<endl;
+                  clhs->Add(*crhs,moption);
+                  wasAdded = true;
+               }
+            }
+            else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFlex* clhs = (fastNLOCoeffAddFlex*)fCoeff[jc];
+               fastNLOCoeffAddFlex* crhs = (fastNLOCoeffAddFlex*)other.GetCoeffTable(ic);
+               if ( clhs->IsCompatible(*crhs) ) {
+                  logger.info["AddTable"]<<"Found matching flex-scale additive contribution." << endl;
+                  logger.debug["AddTable"]<<"Summing contribution "<<ic<<" to fCoeff #"<<jc<<endl;
+                  clhs->Add(*crhs,moption);
+                  wasAdded = true;
+               }
+            }
+            // all weights are additive, and already been aded by fastNLOCoeffBase::Add();
+            // ((fastNLOCoeffAddBase*)fCoeff[jc])->AccessWgtStat().Add( ((fastNLOCoeffAddBase*)other.GetCoeffTable(ic))->GetWgtStat() );
+         }
+         // Multiplicative?
+         else if ( fastNLOCoeffMult::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffMult* clhs = (fastNLOCoeffMult*)fCoeff[jc];
+            fastNLOCoeffMult* crhs = (fastNLOCoeffMult*)other.GetCoeffTable(ic);
+            if ( clhs->IsCompatible(*crhs) ) {
+               logger.error["AddTable"]<<"Found matching multiplicative contribution. This is not allowed. Aborted!" << endl;
+               wasAdded = true;
+               exit(1);
+            }
+         }
+         // Data?
+         else if ( fastNLOCoeffData::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffData* clhs = (fastNLOCoeffData*)fCoeff[jc];
+            fastNLOCoeffData* crhs = (fastNLOCoeffData*)other.GetCoeffTable(ic);
+            if ( clhs->IsCompatible(*crhs) ) {
+               logger.error["AddTable"]<<"Found matching data contribution. This is not allowed. Aborted!" << endl;
+               wasAdded = true;
+               exit(1);
+            }
+         }
+         // Unknown
+         else {
+            logger.error["AddTable"]<<"Could not identify contribution. Print and abort!" << endl;
+            cother->Print(-1);
+            exit(1);
+         }
+      }
+      // Couldn't find a corresponding contribution,
+      // so add this contribution as new.
       if ( !wasAdded ) {
          logger.info["AddTable"]<<"Adding new contribution to table."<<endl;
          fastNLOCoeffBase* add = other.GetCoeffTable(ic);
-         if ( fastNLOCoeffData::CheckCoeffConstants(add,quiet) ) {
-            add = new fastNLOCoeffData((fastNLOCoeffData&)*add);
-            Ndata++;
-         }
-         else if ( fastNLOCoeffMult::CheckCoeffConstants(add,quiet) )
-            add = new fastNLOCoeffMult((fastNLOCoeffMult&)*add);
-         else if ( fastNLOCoeffAddFix::CheckCoeffConstants(add,quiet) )
+         if ( fastNLOCoeffAddFix::CheckCoeffConstants(add,quiet) ) {
             add = new fastNLOCoeffAddFix((fastNLOCoeffAddFix&)*add);
-         else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(add,quiet) )
+            // Adjust new theory contribution counter
+            newnc++;
+         } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(add,quiet) ) {
             add = new fastNLOCoeffAddFlex((fastNLOCoeffAddFlex&)*add);
+            newnc++;
+         } else if ( fastNLOCoeffMult::CheckCoeffConstants(add,quiet) ) {
+            add = new fastNLOCoeffMult((fastNLOCoeffMult&)*add);
+            newnc++;
+         } else if ( fastNLOCoeffData::CheckCoeffConstants(add,quiet) ) {
+            add = new fastNLOCoeffData((fastNLOCoeffData&)*add);
+            // Adjust new data counter
+            newnd++;
+         }
          CreateCoeffTable(fCoeff.size(),add);
-         ///     Ndata++, and ncontrib++, n
       }
    }
+   // Check # of coefficients
+   if ( (int)fCoeff.size() != newnc + newnd ) {
+      logger.error["AddTable"]<<"Sorry, I'm confused about the no. of contributions. Aborted!" << endl;
+      logger.error["AddTable"]<<"newnc = " << newnc << ", newnd = " << newnd << ", fCoeff.size() = " << fCoeff.size() << endl;
+      exit(1);
+   }
+   // Set nc and nd for current table to be written out eventually
+   // SetNcontrib(newnc);
+   // SetNdata(newnd);
 }
 
 
-// // ___________________________________________________________________________________________________
-// int fastNLOTable::CreateCoeffBase(int no){
-//    //fastNLOCoefficients* blockb = new fastNLOCoefficients(NObsBin,ILOord);
-//    fastNLOCoeffBase* blockb = new fastNLOCoeffBase(NObsBin);
-//    return CreateCoeffTable(no,blockb);
-// }
+// ___________________________________________________________________________________________________
+void fastNLOTable::CatenateTable(const fastNLOTable& other) {
+   // Catenate another table to this table.
+   // All contributions must be identically defined.
+   //
+   static unsigned int table_count = 0;
+   if ( !IsCatenable(other) ) {
+      logger.error["CatenateTable"]<<"Tried to catenate incompatible tables. Aborted!"<<endl;
+      exit(1);
+   } else {
+      table_count++;
+   }
+   for ( unsigned int iObs=0; iObs<other.GetNObsBin(); iObs++ ) {
+      this->CatBinToTable(other,iObs,table_count);
+   }
+}
 
 
 // ___________________________________________________________________________________________________
-//int fastNLOTable::CreateCoeffTable(int no,fastNLOCoefficients *newblockb){
-int fastNLOTable::CreateCoeffTable(int no,fastNLOCoeffBase *newblockb){
-   if((no+1)>(int)fCoeff.size())
+int fastNLOTable::CreateCoeffTable(int no, fastNLOCoeffBase *newblockb) {
+   // Attention: Proper adaptation of Ncontrib and Ndata, which are set each time a table is read,
+   // to the current value of the table in memory must be done in the calling routine!
+   logger.debug["CreateCoeffTable"]<<"Old: Ncontrib = " << GetNcontrib() << ", Ndata = " << GetNdata() << ", fCoeff.size() = " << fCoeff.size() << endl;
+   logger.debug["CreateCoeffTable"]<<"Creating coefficient table no. " << no << ", actual fCoeff.size() is: " << fCoeff.size() << endl;
+   if ( (no+1) > (int)fCoeff.size() ) {
       fCoeff.resize(no+1);
+      logger.debug["CreateCoeffTable"]<<"Creating new coefficient table no. " << no << endl;
+   }
    fCoeff[no] = newblockb;
-   //Ncontrib++; // member of fastNLOBase
-   Ncontrib = fCoeff.size();
+   //Ncontrib = fCoeff.size();
    return 0;
 }
 
 
 // ___________________________________________________________________________________________________
 bool fastNLOTable::cmp(const double x1, const double x2) const {
-   double norm;
-   if (x1>0.){
-      norm = x1;
-   }else{
-      norm = 1.; // If x1 is 0, do not try to calculate relative deviation, use absolute
-   }
+   double norm = (x1>0.) ? x1 : 1.; // If x1 is 0, do not try to calculate relative deviation, use absolute
    return((fabs(x1-x2)/norm)<1e-7);
 }
 
 bool fastNLOTable::cmp(const vector<double>& x1,const vector<double>& x2) const {
    bool result = true;
    for(unsigned int i = 0; i<x1.size() ;i++ ){
-      result = result & cmp (x1[i],x2[i]);
+      result &= cmp (x1[i],x2[i]);
    }
    return result;
 }
@@ -459,7 +1099,7 @@ bool fastNLOTable::cmp(const vector<double>& x1,const vector<double>& x2) const
 bool fastNLOTable::cmp(const vector<vector<double> >& x1, const vector<vector<double> >& x2) const {
    bool result = true;
    for(unsigned int i = 0; i<x1.size() ;i++ ){
-      result = result & cmp (x1[i],x2[i]);
+      result &=  cmp (x1[i],x2[i]);
    }
    return result;
 }
@@ -478,9 +1118,6 @@ bool fastNLOTable::cmp(const vector<vector<pair<double,double> > >& x1, const ve
 // ___________________________________________________________________________________________________
 void fastNLOTable::SetLoOrder(int LOOrd){
    ILOord = LOOrd;
-   //    for(unsigned int i = 0; i<fCoeff.size() ;i++ ){
-   //       fCoeff[i]->fILOord = LOOrd; // fCoeff should not need this member!
-   //    }
 }
 
 
@@ -521,7 +1158,33 @@ void fastNLOTable::SetDimLabel( string label, unsigned int iDim , bool IsDiff ){
 
 
 // ___________________________________________________________________________________________________
-//fastNLOCoefficients* fastNLOTable::GetCoeffTable(int no) const {
+int fastNLOTable::GetNmult() const {
+   int ret = 0;
+   for ( unsigned int i = 0 ; i<fCoeff.size() ; i++ )
+      if ( (fCoeff[i]->GetIDataFlag()==0) && (fCoeff[i]->GetIAddMultFlag()==1) ) ret++;
+   return ret;
+}
+
+
+// ___________________________________________________________________________________________________
+int fastNLOTable::GetNcontrib() const {
+   int ret = 0;
+   for ( unsigned int i = 0 ; i<fCoeff.size() ; i++ )
+      if ( (fCoeff[i]->GetIDataFlag()==0) /*&& (fCoeff[i]->GetIAddMultFlag()==0)*/ ) ret++;
+   return ret;
+}
+
+
+// ___________________________________________________________________________________________________
+int fastNLOTable::GetNdata() const {
+   int ret = 0;
+   for ( unsigned int i = 0 ; i<fCoeff.size() ; i++ )
+      if ( (fCoeff[i]->GetIDataFlag()==1) && (fCoeff[i]->GetIAddMultFlag()==0) ) ret++;
+   return ret;
+}
+
+
+// ___________________________________________________________________________________________________
 fastNLOCoeffBase* fastNLOTable::GetCoeffTable(int no) const {
    if ( no >= (int)fCoeff.size() ){
       logger.warn["GetCoeffTable"]<<"There is no contribution with number "<<no<<" but only "<<fCoeff.size()<<". Returning null pointer."<<endl;
@@ -534,7 +1197,7 @@ fastNLOCoeffBase* fastNLOTable::GetCoeffTable(int no) const {
 
 // ___________________________________________________________________________________________________
 fastNLOCoeffData* fastNLOTable::GetDataTable() const {
-   for (unsigned int i= 0; i<fCoeff.size() ; i++ ){
+   for (unsigned int i= 0; i<fCoeff.size() ; i++ ) {
       fastNLOCoeffBase* c = GetCoeffTable(i);
       if ( fastNLOCoeffData::CheckCoeffConstants(c,true) ) {
          return (fastNLOCoeffData*)c;
@@ -545,7 +1208,7 @@ fastNLOCoeffData* fastNLOTable::GetDataTable() const {
 
 
 // ___________________________________________________________________________________________________
-fastNLOCoeffAddBase* fastNLOTable::GetReferenceTable(ESMOrder eOrder) const {
+fastNLOCoeffAddBase* fastNLOTable::GetReferenceTable(fastNLO::ESMOrder eOrder) const {
    for (unsigned int i= 0; i<fCoeff.size() ; i++ ){
       fastNLOCoeffBase* c = GetCoeffTable(i);
       if ( fastNLOCoeffAddBase::CheckCoeffConstants(c,true) ) {
@@ -1075,7 +1738,7 @@ int fastNLOTable::GetObsBinNumber( double obs0, double obs1, double obs2 ) const
 
 
 // ___________________________________________________________________________________________________
-// Some other info getters
+// Some other info getters/setters
 // ___________________________________________________________________________________________________
 string fastNLOTable::GetRivetId() const {
    string identifier("RIVET_ID");
@@ -1092,66 +1755,57 @@ string fastNLOTable::GetRivetId() const {
    return found;
 }
 
+string fastNLOTable::GetXSDescr() const {
+   string identifier("sigma");
+   for (size_t i=0; i < ScDescript.size(); ++i) {
+      if (ScDescript[i].find(identifier) != string::npos){
+         return ScDescript[i];
+      }
+   }
+   return "Undefined";
+}
 
-// ___________________________________________________________________________________________________
-// Info print out functionality
-// ___________________________________________________________________________________________________
-
+vector <string> fastNLOTable::GetScDescr() const {
+   return ScDescript;
+}
 
-// ___________________________________________________________________________________________________
-void fastNLOTable::Print() const {
-   fastNLOBase::Print();
-   PrintScenario();
+void fastNLOTable::SetScDescr(std::vector <std::string> ScDescr) {
+   size_t NScDescript = ScDescr.size();
+   fastNLOTable::ScDescript.resize(NScDescript);
+   for (size_t i=0; i < NScDescript; ++i) {
+      fastNLOTable::ScDescript[i] = ScDescr[i];
+   }
 }
 
+void fastNLOTable::SetNObsBin(int NObs) {
+   fastNLOTable::NObsBin = NObs;
+}
 
-// ___________________________________________________________________________________________________
-void fastNLOTable::PrintScenario() const {
-   printf("\n **************** FastNLO Table: Scenario ****************\n\n");
-   printf("    Ipublunits                    %d\n",Ipublunits);
-   for(unsigned int i=0;i<ScDescript.size();i++){
-      printf("    ScDescript[%d]                 %s\n",i,ScDescript[i].data());
-   }
-   printf("    Ecms                          %7.4f\n",Ecms);
-   printf("    ILOord                        %d\n",ILOord);
-   printf("    NDim                          %d\n",NDim);
-   for(unsigned int i=0;i<NDim;i++){
-      printf("     - DimLabel[%d]                %s\n",i,DimLabel[i].data());
-   }
-   for(unsigned int i=0;i<NDim;i++){
-      printf("     - IDiffBin[%d]               %d\n",i,IDiffBin[i]);
-   }
-   printf("    NObsBin                       %d\n",NObsBin);
-   for(unsigned int i=0;i<NObsBin;i++){
-      for(unsigned int j=0;j<NDim;j++){
-         printf("     -  - LoBin[%d][%d]             %7.4f\n", i,j,Bin[i][j].first);
-         if(IDiffBin[j]==2)
-            printf("     -  - UpBin[%d][%d]             %7.4f\n", i,j,Bin[i][j].second);
-      }
+void fastNLOTable::SetBinSize(std::vector < double > NewBinSize) {
+   size_t NewSize = NewBinSize.size();
+   fastNLOTable::BinSize.resize(NewSize);
+   for (size_t i=0; i < NewSize; ++i) {
+      fastNLOTable::BinSize[i] = NewBinSize[i];
    }
-   for(unsigned int i=0;i<NObsBin;i++){
-      printf("     - BinSize[%d]                %7.4f\n", i,BinSize[i]);
-   }
-   printf("    INormFlag                     %d\n",INormFlag);
+}
 
-   if(INormFlag>1){
-      printf("    DenomTable                    %s\n",DenomTable.data());
-   }
-   if(INormFlag>0){
-      for(unsigned int i=0;i<NObsBin;i++){
-         printf("     - IDivLoPointer[%d]               %d\n",i,IDivLoPointer[i]);
-         printf("     - IDivUpPointer[%d]               %d\n",i,IDivUpPointer[i]);
-      }
+void fastNLOTable::SetBins(std::vector < std::vector <std::pair<double,double> > > NewBins) {
+   size_t NewSize = NewBins.size();
+   fastNLOTable::Bin.resize(NewSize);
+   for (size_t i=0; i < NewSize; ++i) {
+      fastNLOTable::Bin[i] = NewBins[i];
    }
-   printf("\n ********************************************************\n\n");
-
 }
 
 
-//______________________________________________________________________________
-void fastNLOTable::PrintFastNLOTableConstants(const int iprint) const {
-   //if ( logger.debug.GetSpeak() ) iprint=10000;
-   //
+
+// ___________________________________________________________________________________________________
+// Info print out functionality
+// ___________________________________________________________________________________________________
+
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::Print(int iprint) const {
    // Define different levels of detail for printing out table content
    // The minimum (iprint = 0) just gives basic scenario information
    // including the employed code with references. The additional levels
@@ -1167,127 +1821,122 @@ void fastNLOTable::PrintFastNLOTableConstants(const int iprint) const {
    //          5: Also print sigma tilde of Block B (not implemented yet)
 
    //
-   // Print basic scenario information (always)
-   //
+   // Print table header
    char buffer[1024];
    cout  << endl;
-   cout  << _CSEPSC << endl;
-   snprintf(buffer, sizeof(buffer), "Information on fastNLO scenario: %s",ScenName.data());
-   logger.shout << buffer << endl;
-   cout  << _SSEPSC << endl;
-   snprintf(buffer, sizeof(buffer), "Description:");
+   cout  << fastNLO::_CSEPSC << endl;
+   snprintf(buffer, sizeof(buffer), "Information on table header");
    logger.shout << buffer << endl;
-   for (unsigned int i=0; i<ScDescript.size(); i++) {
-      printf(" #   %s\n",ScDescript[i].data());
-   }
-   printf(" #\n");
-   printf(" # Centre-of-mass energy Ecms: % -#10.4g GeV\n",Ecms);
-   printf(" #\n");
-   printf(" # Tot. no. of observable bins: %3i in %1i dimensions:\n",NObsBin,NDim);
-   printf(" #\n");
-   printf(" # No. of contributions: %1i\n",Ncontrib);
+   cout  << fastNLO::_SSEPSC << endl;
+   PrintHeader(iprint);
 
    //
-   // Print basic contribution information (always)
+   // Print scenario information
+   PrintScenario(iprint);
+
    //
+   // Loop over available contributions
    for (unsigned int j = 0 ; j<fCoeff.size() ; j++) {
       fastNLOCoeffBase* c = fCoeff[j];
-      if ( iprint == 0 ) {
-         printf(" # Contribution %1i:\n",j+1);
-         for (unsigned int i=0; i<c->CtrbDescript.size(); i++) {
-            printf(" #   %s\n",c->CtrbDescript[i].data());
-         }
-         if ( fastNLOCoeffAddBase::CheckCoeffConstants(c,true) ) {
-            fastNLOCoeffAddBase* cA = (fastNLOCoeffAddBase*)c;
-            double nevt = cA->GetNevt();
-            printf(" #   No. of events: %#17.0F\n",nevt);
-         }
-         printf(" #   provided by:\n");
-         for (unsigned int i=0; i<c->CodeDescript.size(); i++) {
-            printf(" #   %s\n",c->CodeDescript[i].data());
-         }
+      char buffer[1024];
+      cout  << endl;
+      cout  << fastNLO::_CSEPSC << endl;
+      snprintf(buffer, sizeof(buffer), "Information on table contribution no. %d: %s",j,c->CtrbDescript[0].data());
+      logger.shout << buffer << endl;
+      cout  << fastNLO::_SSEPSC << endl;
+      // Print information for each contribution
+      c->Print(iprint);
+   }
+}
 
-         if ( fastNLOCoeffAddFix::CheckCoeffConstants(c,true) ) {
-            fastNLOCoeffAddFix* cFix = (fastNLOCoeffAddFix*)c;
-            int NScaleDim = cFix->GetNScaleDim();
-            printf(" #   Scale dimensions: %1i\n",NScaleDim);
-            for (int i=0; i<NScaleDim; i++) {
-               for (unsigned int j=0; j<cFix->ScaleDescript[i].size(); j++) {
-                  printf(" #     Scale description for dimension %1i:          %s\n",i+1,cFix->ScaleDescript[i][j].data());
-               }
-               printf(" #     Number of scale variations for dimension %1i: %1i\n",NScaleDim,cFix->GetNScalevar());
-               printf(" #     Available scale settings for dimension %1i:\n",NScaleDim);
-               for (int k=0; k<cFix->GetNScalevar(); k++) { // fastNLOReader has method: 'GetNScaleVariations()', which returns nr of scale variations for all active tables!
-                  printf(" #       Scale factor number %1i:                   % #10.4f\n",k+1,cFix->GetScaleFactor(k));
+
+// ___________________________________________________________________________________________________
+void fastNLOTable::PrintScenario(int iprint) const {
+   //
+   //  Print scenario information for table
+   //  iprint: iprint > 0: Print more info ...
+   //
+   logger.debug["PrintScenario"] << "Printing info on scenario: " << ScenName.data() << endl;
+   char buffer[1024];
+   cout  << endl;
+   cout  << fastNLO::_CSEPSC << endl;
+   snprintf(buffer, sizeof(buffer), "Information on fastNLO scenario: %s",ScenName.data());
+   logger.shout << buffer << endl;
+   cout  << fastNLO::_SSEPSC << endl;
+   if ( !(iprint < 0) ) {
+      cout << fastNLO::_DSEP20C << " fastNLO Table: Scenario " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: Scenario " << fastNLO::_CSEP20 << endl;
+   }
+   fastNLOTools::PrintVector(ScDescript,"Scenario description (ScDescript)","#");
+   printf(" #\n");
+   printf(" # Publ. x section (10^-Ipublunits b)  %d\n",Ipublunits);
+   printf(" # Centre-of-mass energy (Ecms/GeV)    %5.0f\n",Ecms);
+   printf(" # Power in a_s of LO process (ILOord) %d\n",ILOord);
+   printf(" # No. of observable bins (NObsBin)    %d\n",NObsBin);
+   printf(" # Dim. of observable binning (NDim)   %d\n",NDim);
+   printf(" #\n");
+   fastNLOTools::PrintVector(DimLabel,"Dimension labels (DimLabel)","#");
+   fastNLOTools::PrintVector(IDiffBin,"Differential dimension (IDiffBin)","#");
+   printf(" #\n");
+   if ( abs(iprint) > 1 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 1) " << fastNLO::_SSEP20 << endl;
+      for (unsigned int i=0; i<NObsBin; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==NObsBin-1) {
+            for (unsigned int j=0; j<NDim; j++) {
+               printf(" #   LoBin[%d][%d]                        %7.4f\n", i,j,Bin[i][j].first);
+               if ( IDiffBin[j]==2 ) {
+                  printf(" #   UpBin[%d][%d]                       %7.4f\n", i,j,Bin[i][j].second);
                }
-               printf(" #     Number of scale nodes for dimension %1i:      %1i\n",NScaleDim,cFix->GetNScaleNode());
-            }
-            printf(" #   PDF dimensions: %1i\n",cFix->GetNPDF());
-            int fPDFDim = cFix->GetNPDFDim();
-            if ( fPDFDim == 0 ) {
-               printf(" #     x-interpolation storage format: Linear\n");
-            } else if ( fPDFDim == 1 ) {
-               printf(" #     x-interpolation storage format: Half-Matrix\n");
-            } else if ( fPDFDim == 2 ) {
-               printf(" #     x-interpolation storage format: Full-Matrix\n");
-            } else {
-               logger.error["PrintFastNLOTableConstants"] << "Unknown interpolation storage structure, aborting! "
-                                                          << " NPDFDim = " << fPDFDim << endl;
-            }
-            printf(" #     Number of x1 nodes range from %2i to %2i\n",cFix->GetNxtot1(0),cFix->GetNxtot1(NObsBin-1));
-            if (fPDFDim == 2) {
-               printf(" #     Number of x2 nodes range from %2i to %2i\n",cFix->GetNxtot2(0),cFix->GetNxtot2(NObsBin-1));
-            }
-         } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(c,true) ) {
-            fastNLOCoeffAddFlex* cFlex = (fastNLOCoeffAddFlex*)c;
-            int NScaleDim = cFlex->GetNScaleDim();
-            if (! (NScaleDim == 1)) {
-               logger.error["PrintFastNLOTableConstants"] << "Flex-scale tables must have scale dimensions of one, aborting! "
-                                                   << "NScaleDim = " << NScaleDim <<endl;
-               exit(1);
-            }
-            // Not useful for flex-scale tables
-            //            printf(" #   Scale dimensions: %1i\n",NScaleDim);
-            for (int i=0; i<NScaleDim; i++) {
-               printf(" #   Scale description for flexible scale %1i:          %s\n",1,cFlex->ScaleDescript[i][0].data());
-               printf(" #     Number of scale nodes in first observable bin:      %2i\n",cFlex->GetNScaleNode1(0));
-               printf(" #     Number of scale nodes in last  observable bin:      %2i\n",cFlex->GetNScaleNode1(NObsBin-1));
-               printf(" #   Scale description for flexible scale %1i:          %s\n",2,cFlex->ScaleDescript[i][1].data());
-               printf(" #     Number of scale nodes in first observable bin:      %2i\n",cFlex->GetNScaleNode2(0));
-               printf(" #     Number of scale nodes in last  observable bin:      %2i\n",cFlex->GetNScaleNode2(NObsBin-1));
             }
-         } else {
-            // Anything else to write for multiplicative or data contributions?
          }
-      } else {
-         fCoeff[j]->Print();
+      }
+      for (unsigned int i=0; i<NObsBin; i++) {
+         // Print only for first and last observable bin
+         if (i==0 || i==NObsBin-1) {
+            printf(" #   BinSize[%d]                       %7.4f\n", i,BinSize[i]);
+         }
       }
    }
-   if (iprint > 0) {
-      Print();
+   if( INormFlag != 0 ) {
+      printf(" # Normalization flag (INormFlag)      %d\n",INormFlag);
+      if ( INormFlag<0 ) {
+         printf(" # Normalization table (DenomTable)    %s\n",DenomTable.data());
+      }
+      if ( abs(iprint) > 1 ) {
+         cout << fastNLO::_SSEP20C << " Extended information (iprint > 1) " << fastNLO::_SSEP20 << endl;
+         for (unsigned int i=0; i<NObsBin; i++) {
+            // Print only for first and last observable bin
+            if (i==0 || i==NObsBin-1) {
+               printf(" #  IDivLoPointer[%d]               %d\n",i,IDivLoPointer[i]);
+               printf(" #  IDivUpPointer[%d]               %d\n",i,IDivUpPointer[i]);
+            }
+         }
+      }
+      printf(" #\n");
    }
-   logger.shout << "" << endl;
-   cout  << _CSEPSC << endl;
+   printf(" # Total no. of contributions (theory + optional data) in this table: %d\n",(int)fCoeff.size());
+   cout << fastNLO::_CSEPSC << endl;
 }
 
 
 //______________________________________________________________________________
-void fastNLOTable::PrintTableInfo(const int iprint) const {
-   logger.debug["PrintTableInfo"] << "Printing flag iprint = " << iprint << endl;
+void fastNLOTable::PrintContributionSummary(int iprint) const {
    //
-   //  Print basic info about fastNLO table and its contributions
-   //   - iprint: iprint > 0: print also contribution descriptions
+   //  Print summary of contributions available in table
+   //  iprint: iprint > 0: Print full descriptions (all lines) for each contribution
    //
-
+   logger.debug["PrintContributionSummary"] << "Printing flag iprint = " << iprint << endl;
    char buffer[1024];
    cout  << endl;
-   cout  << _CSEPSC << endl;
-   logger.shout << "Overview on contribution types and numbers contained in table:" << endl;
-   cout  << _SSEPSC << endl;
-   snprintf(buffer, sizeof(buffer), "Number of contributions: %2i", Ncontrib);
+   cout  << fastNLO::_CSEPSC << endl;
+   logger.shout << "Overview on contribution types and numbers contained in table: " << ffilename << endl;
+   cout  << fastNLO::_SSEPSC << endl;
+   snprintf(buffer, sizeof(buffer), "Total number of contributions: %2i", (int)fCoeff.size());
    logger.shout << buffer << endl;
 
-   int iccount[21] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
+   int iccount[21] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int ictype = 0;
    string coeffname;
    for (unsigned int j = 0 ; j<fCoeff.size() ; j++) {
@@ -1299,180 +1948,643 @@ void fastNLOTable::PrintTableInfo(const int iprint) const {
          ictype = fCoeff[j]->GetIContrFlag1()-1;
          coeffname = fastNLO::_ContrName[ictype];
       }
-      // KR: How can I access ContrId from here ???
       iccount[ictype]++;
-      logger.shout << "  No.: " << j+1 << ", type: " << coeffname <<", Id: " << iccount[ictype]
-            << ", order: " << c->GetContributionDescription()[0]
-            << ", by: " << c->GetCodeDescription()[0] << endl;
+      snprintf(buffer, sizeof(buffer), "  No.: %d, type: %-30.30s, Id: %d, order: %-20.20s, by: %s",
+               j+1,
+               coeffname.c_str(),
+               iccount[ictype]-1,
+               c->GetContributionDescription()[0].c_str(),
+               c->GetCodeDescription()[0].c_str());
+      logger.shout << buffer << endl;
+
       if (iprint > 0) {
          for (unsigned int k = 0 ; k<c->GetCodeDescription().size(); k++) {
-            snprintf(buffer, sizeof(buffer), "\t\t%s",c->GetCodeDescription()[k].c_str());
+            snprintf(buffer, sizeof(buffer), "          %s",c->GetCodeDescription()[k].c_str());
             logger.shout << buffer << endl;
          }
       }
    }
-   cout << _CSEPSC << endl;
+   int nc = 0;
+   for ( int icnt=0; icnt<21; icnt++ ) {
+      nc += iccount[icnt];
+   }
+   if ( iccount[2]+iccount[3] != GetNmult() ) {
+      logger.warn["PrintContributionSummary"] << "Multiplicative contribution not correctly advertised in table header." << endl;
+      logger.warn["PrintContributionSummary"] << "Nmult = " << GetNmult() <<
+         " should equal " << iccount[2]+iccount[3] << " instead. Continue anyway, since not actually used." << endl;
+   }
+   if ( iccount[20] > 1 ) {
+      logger.error["PrintContributionSummary"] << "Maximally one data contribution allowed per table," << endl;
+      logger.error["PrintContributionSummary"] << "but found " << iccount[20] << "! Aborted!" << endl;
+      exit(1);
+   }
+   if ( iccount[20] != GetNdata() ) {
+      if ( nc == GetNcontrib()+GetNdata() ) {
+         logger.warn["PrintContributionSummary"] << "Data contribution not correctly advertised in table header." << endl;
+         logger.warn["PrintContributionSummary"] << "Ncontrib = " << GetNcontrib() << " and Ndata = " << GetNdata() <<
+            " should equal " << nc-1 << " and " << iccount[20] << " instead. Continue anyway, since only sum is actually used." << endl;
+      } else {
+         logger.error["PrintContributionSummary"] << "Inconsistent number of contributions found!" << endl;
+         logger.error["PrintContributionSummary"] << "Ncontrib = " << GetNcontrib() << " and Ndata = " << GetNdata() <<
+            " should be " << nc-1 << " and " << iccount[20] << " instead. Aborted!" << endl;
+         exit(1);
+      }
+   }
+   cout << fastNLO::_CSEPSC << endl;
+}
+
+
+//_DEPRECATED___________________________________________________________________
+void fastNLOTable::PrintFastNLOTableConstants(const int iprint) const {
+   logger.error["PrintFastNLOTableConstants"]<<"This function is deprecated, aborted!"<<endl;
+   logger.error["PrintFastNLOTableConstants"]<<"Please use Print instead."<<endl;
+}
 
+
+//_DEPRECATED___________________________________________________________________
+void fastNLOTable::PrintTableInfo(const int iprint) const {
+   logger.error["PrintTableInfo"]<<"This function is deprecated, aborted!"<<endl;
+   logger.error["PrintTableInfo"]<<"Please use PrintContributionSummary instead."<<endl;
 }
 
 
 // DO NOT USE ANYTHING BELOW! DOES NOT WORK YET!
 // ___________________________________________________________________________________________________
 // DO NOT USE! DOES NOT WORK YET!
-unsigned int fastNLOTable::GetIDimBin(unsigned int iObsBin, unsigned int iDim) const {
-   //! Returns bin number in dimension iDim
-   //  iDim larger than table dimensions --> logger.error exit
-   logger.error["fastNLOTable::GetIDimBin"] << "DO NOT USE! DOES NOT WORK YET!" << endl;
-   const unsigned int idiff = GetNumDiffBin();
-   if ( ! (iDim < idiff) ) {
-      logger.error["fastNLOTable::GetIDimBin"] << "Requested dimension iDim not available, aborted!" << endl;
+// unsigned int fastNLOTable::GetIDimBin(unsigned int iObsBin, unsigned int iDim) const {
+//    //! Returns bin number in dimension iDim
+//    //  iDim larger than table dimensions --> logger.error exit
+//    logger.error["fastNLOTable::GetIDimBin"] << "DO NOT USE! DOES NOT WORK YET!" << endl;
+//    const unsigned int idiff = GetNumDiffBin();
+//    if ( ! (iDim < idiff) ) {
+//       logger.error["fastNLOTable::GetIDimBin"] << "Requested dimension iDim not available, aborted!" << endl;
+//       exit(1);
+//    }
+//    //  Otherwise there always must be at least one bin!
+//    if ( Bin.size() == 0 || Bin[0].size() == 0 ) {
+//       logger.error["fastNLOTable::GetIDimBin"] << "No observable bins defined, aborted!" << endl;
+//       exit(1);
+//    }
+//    if ( iObsBin >= NObsBin ) {
+//       logger.error["fastNLOTable::GetIDimBin"] << "Observable bin out of range, aborted!" << endl;
+//       exit(1);
+//    }
+//    vector < unsigned int > ibin(NDim);
+//    vector < double > lobin(NDim);
+//    for ( unsigned int jdim = 0; jdim<=iDim; jdim++ ) {
+//       ibin.push_back(0);
+//       lobin.push_back(Bin[0][jdim].first);
+//    }
+//    for ( unsigned int iobs = 0; iobs<Bin.size(); iobs++ ) {
+//       if (iDim == 2) {
+//          if ( lobin[0] < Bin[iobs][0].first ) {
+//             for (unsigned int k=0; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[0]++;
+//             for (unsigned int k=1; k<=iDim; k++) {
+//                ibin[k] = 0;
+//             }
+//          } else if ( lobin[1] < Bin[iobs][1].first ) {
+//             for (unsigned int k=1; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[1]++;
+//             for (unsigned int k=2; k<=iDim; k++) {
+//                ibin[k] = 0;
+//             }
+//          } else if ( lobin[2] < Bin[iobs][2].first ) {
+//             for (unsigned int k=2; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[2]++;
+//          }
+//       } else if (iDim == 1) {
+//          if ( lobin[0] < Bin[iobs][0].first ) {
+//             for (unsigned int k=0; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[0]++;
+//             for (unsigned int k=1; k<=iDim; k++) {
+//                ibin[k] = 0;
+//             }
+//          } else if ( lobin[1] < Bin[iobs][1].first ) {
+//             for (unsigned int k=1; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[1]++;
+//          }
+//       } else if (iDim == 0 ) {
+//          if ( lobin[0] < Bin[iobs][0].first ) {
+//             for (unsigned int k=0; k<=iDim; k++) {
+//                lobin[k] = Bin[iobs][k].first;
+//             }
+//             ibin[0]++;
+//          }
+//       }
+//       if ( iobs == iObsBin ) {
+//          return ibin[iDim];
+//       }
+//    }
+//    logger.error["fastNLOTable::GetIDimBin"] << "Observable bin not found. This should never happen, aborted!" << endl;
+//    exit(1);
+// }
+//
+//
+// ___________________________________________________________________________________________________
+// DO NOT USE! DOES NOT WORK YET!
+// vector < pair < double, double > > fastNLOTable::GetBinBoundaries(int iDim0Bin, int iDim1Bin, int iDim2Bin) {
+//    //!
+//    //! Get bin boundaries for first, second, and third dimension
+//    //!    Assuming for instance following 2-dimensional binning scheme:
+//    //!
+//    //!    iDim0Bin  ________________________________
+//    //!       0      |___|___|___|_______|__|__|____|
+//    //!  D    1      |____|____|____|_____|____|____|
+//    //!  I    2      |__|__|___|__|__|___|__|___|___|
+//    //!  M    3      |______|_______|_________|_____|
+//    //!       4      |__________|_______|_________|_|
+//    //!  0    5      |______________|______|___|____|
+//    //!       6      |_______|_______|______|_______|
+//    //!                            DIM 1
+//    //!  iDim1Bin may be different for each iDim0Bin
+//    //!
+//    //! usage e.g.:
+//    //! int LowerBoundary = GetBinBoundaries(ibin)[dim].first;
+//    //! int UpperBoundary = GetBinBoundaries(ibin)[dim].second;
+//    //! 'dim' must be smaller than number of parameters passed to GetBinBoundaries
+//    //! usage e.g.:
+//    //! int LoYBin  = GetBinBoundaries(2)[0].first;
+//    //! int UpPtBin = GetBinBoundaries(2,5)[1].second;
+//    //! int LoYBin  = GetBinBoundaries(2,5)[0].second;
+//    logger.error["GetBinBoundaries"] << "DO NOT USE! DOES NOT WORK YET!" << endl;
+//    vector<pair<double,double> > BinRet(NDim);
+//    const int idiff = GetNumDiffBin();
+//
+//    if ( idiff==1 ) {
+//       if ( iDim0Bin<0 || iDim0Bin >= (int)NObsBin ) {
+//          logger.warn["GetBinBoundaries"]<<"0th dimension does only have "<<NObsBin<<" but bin "<<iDim0Bin<<" was requested."<<endl;
+//          return BinRet;
+//       }
+//       return Bin[iDim0Bin];
+//    }
+//    else if ( idiff==2) {
+//       unsigned int nDim1 = GetNDim1Bins(iDim0Bin);
+//       unsigned int nDim0 = GetNDim0Bins();
+//       // sanity
+//       if ( iDim0Bin < 0 || iDim0Bin >= (int)nDim0 ) {
+//          logger.warn["GetBinBoundaries"]<<"Dimension 2 does only have "<<nDim0<<" but bin "<<iDim0Bin<<" was requested."<<endl;
+//       }
+//       if ( iDim1Bin < 0 || iDim1Bin >= (int)nDim1 ) {
+//          logger.warn["GetBinBoundaries"]<<"Dimension 1 does only have "<<nDim1<<" but bin "<<iDim1Bin<<" was requested."<<endl;
+//       }
+//       int iObs = 0;
+//       for ( int i0 = 0 ; i0<iDim0Bin ; i0++ ) {
+//          iObs += GetNDim1Bins(i0);
+//       }
+//       iObs += iDim1Bin;
+//       return Bin[iObs];
+//    }
+//    else if ( idiff == 3 ) {
+//       unsigned int nDim0 = GetNDim0Bins();
+//       unsigned int nDim1 = GetNDim1Bins(iDim0Bin);
+//       unsigned int nDim2 = GetNDim2Bins(iDim0Bin,iDim1Bin);
+//       // sanity
+//       if ( iDim0Bin < 0 || iDim0Bin >= (int)nDim0 ) {
+//          logger.warn["GetBinBoundaries"]<<"Dimension 0 does only have "<<nDim0<<" but bin "<<iDim0Bin<<" was requested."<<endl;
+//       }
+//       if ( iDim1Bin < 0 || iDim1Bin >= (int)nDim1 ) {
+//          logger.warn["GetBinBoundaries"]<<"Dimension 1 does only have "<<nDim1<<" but bin "<<iDim1Bin<<" was requested."<<endl;
+//       }
+//       if ( iDim2Bin < 0 || iDim2Bin >= (int)nDim2 ) {
+//          logger.warn["GetBinBoundaries"]<<"Dimension 2 does only have "<<nDim2<<" but bin "<<iDim2Bin<<" was requested."<<endl;
+//       }
+//       logger.error["GetBinBoundaries"]<<"todo. Further code no yet implemented."<<endl;
+//
+//    }
+//    else {
+//       logger.error["GetBinBoundaries"]<<"Higher than triple-differential binnings are not implemented."<<endl;
+//    }
+//    return BinRet;
+//
+// }
+
+
+// Erase observable bin; iObsIdx is the C++ array index to be removed and
+// not the observable bin no. running from 1 to NObsBin
+template<typename T> void fastNLOTable::EraseBin(vector<T>& v, unsigned int idx) {
+   if ( v.empty() ) {
+      logger.warn["fastNLOTable::EraseBin"]<<"Empty vector, nothing to erase!" << endl;
+   } else if ( idx < v.size() ) {
+      logger.info["fastNLOTable::EraseBin"]<<"Erasing vector index no. " << idx << endl;
+      v.erase(v.begin()+idx);
+   } else {
+      logger.error["fastNLOTable::EraseBin"]<<"Bin no. larger than vector size, aborted!" << endl;
       exit(1);
    }
-   //  Otherwise there always must be at least one bin!
-   if ( Bin.size() == 0 || Bin[0].size() == 0 ) {
-      logger.error["fastNLOTable::GetIDimBin"] << "No observable bins defined, aborted!" << endl;
+}
+
+
+void fastNLOTable::EraseBinFromTable(unsigned int iObsIdx) {
+   if ( IsNorm() != 0 ) {
+      logger.error["EraseBinFromTable"]<<"Not implemented yet for normalisable tables. Aborted!" << endl;
       exit(1);
    }
-   if ( iObsBin >= NObsBin ) {
-      logger.error["fastNLOTable::GetIDimBin"] << "Observable bin out of range, aborted!" << endl;
+
+   logger.info["fastNLOTable::EraseBinFromTable"]<<"Erasing from table the observable index no. " << iObsIdx << endl;
+   // Changes to table header block A2
+   EraseBin(fastNLOTable::Bin,iObsIdx);
+   EraseBin(fastNLOTable::BinSize,iObsIdx);
+   if ( fastNLOTable::INormFlag != 0 ) {
+      EraseBin(fastNLOTable::IDivLoPointer,iObsIdx);
+      EraseBin(fastNLOTable::IDivUpPointer,iObsIdx);
+   }
+   // Changes to table contributions block B
+   for ( int ic = 0; ic<GetNcontrib()+GetNdata(); ic++ ) {
+      logger.info["fastNLOTable::EraseBinFromTable"]<<"Erasing the observable index no. " << iObsIdx << " from contribution no. " << ic << endl;
+      fastNLOCoeffAddBase* ctmp = (fastNLOCoeffAddBase*)fCoeff[ic];
+
+      // Identify type of coeff-table
+      bool quiet = true;
+      if ( fastNLOCoeffData::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.info["EraseBinFromTable"]<<"Found data contribution. Now erasing index no. " << iObsIdx << endl;
+         fastNLOCoeffData* cdata = (fastNLOCoeffData*)fCoeff[ic];
+         cdata->EraseBin(iObsIdx);
+      } else if ( fastNLOCoeffMult::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.info["EraseBinFromTable"]<<"Found multiplicative contribution. Now erasing index no. " << iObsIdx << endl;
+         fastNLOCoeffMult* cmult = (fastNLOCoeffMult*)fCoeff[ic];
+         cmult->EraseBin(iObsIdx);
+      } else if ( fastNLOCoeffAddFix::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.info["EraseBinFromTable"]<<"Found additive fix-table contribution. Now erasing index no. " << iObsIdx << endl;
+         fastNLOCoeffAddFix* cfix = (fastNLOCoeffAddFix*)fCoeff[ic];
+         cfix->EraseBin(iObsIdx);
+      } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.info["EraseBinFromTable"]<<"Found additive flex-table contribution. Now erasing index no. " << iObsIdx << endl;
+         fastNLOCoeffAddFlex* cflex = (fastNLOCoeffAddFlex*)fCoeff[ic];
+         cflex->EraseBin(iObsIdx);
+      } else {
+         logger.error["EraseBinFromTable"]<<"Could not identify contribution. Print and abort!" << endl;
+         ctmp->Print(-1);
+         exit(1);
+      }
+   }
+   // Reduce no. of observable bins
+   SetNObsBin(GetNObsBin()-1);
+}
+
+
+
+// Multiply observable bin; iObsIdx is the C++ array index to be multiplied and
+// not the observable bin no. running from 1 to NObsBin
+template<typename T> void fastNLOTable::MultiplyBin(vector<T>& v, unsigned int idx, double fact) {
+   if ( v.empty() ) {
+      logger.warn["fastNLOTable::MultiplyBin"]<<"Empty vector, nothing to multiply!" << endl;
+   } else if ( idx < v.size() ) {
+      logger.info["fastNLOTable::MultiplyBin"]<<"Multiplying vector index no. " << idx << endl;
+      v[idx] *= fact;
+   } else {
+      logger.error["fastNLOTable::MultiplyBin"]<<"Bin no. larger than vector size, aborted!" << endl;
       exit(1);
    }
-   vector < unsigned int > ibin(NDim);
-   vector < double > lobin(NDim);
-   for ( unsigned int jdim = 0; jdim<=iDim; jdim++ ) {
-      ibin.push_back(0);
-      lobin.push_back(Bin[0][jdim].first);
-   }
-   for ( unsigned int iobs = 0; iobs<Bin.size(); iobs++ ) {
-      if (iDim == 2) {
-         if ( lobin[0] < Bin[iobs][0].first ) {
-            for (unsigned int k=0; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
-            }
-            ibin[0]++;
-            for (unsigned int k=1; k<=iDim; k++) {
-               ibin[k] = 0;
-            }
-         } else if ( lobin[1] < Bin[iobs][1].first ) {
-            for (unsigned int k=1; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
-            }
-            ibin[1]++;
-            for (unsigned int k=2; k<=iDim; k++) {
-               ibin[k] = 0;
+}
+
+void fastNLOTable::MultiplyBinSize(unsigned int iObsIdx, double fact) {
+   logger.debug["fastNLOTable::MultiplyBinSize"]<<"Multiplying the bin size of the observable index no. " << iObsIdx << " by " << fact << endl;
+   MultiplyBin(fastNLOTable::BinSize,iObsIdx,fact);
+}
+
+void fastNLOTable::MultiplyBinInTable(unsigned int iObsIdx, double fact) {
+   logger.debug["fastNLOTable::MultiplyBinInTable"]<<"Multiplying the observable index no. " << iObsIdx << endl;
+   // Changes to table header block A2
+   // Changes to table contributions block B
+   for ( int ic = 0; ic<GetNcontrib()+GetNdata(); ic++ ) {
+      logger.debug["fastNLOTable::MultiplyBinInTable"]<<"Multiplying the observable index no. " << iObsIdx << " from contribution no. " << ic << endl;
+      fastNLOCoeffAddBase* ctmp = (fastNLOCoeffAddBase*)fCoeff[ic];
+
+      // Identify type of coeff-table
+      bool quiet = true;
+      if ( fastNLOCoeffData::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.debug["MultiplyBinInTable"]<<"Found data contribution. Skipped! Index no. " << iObsIdx << endl;
+         fastNLOCoeffData* cdata = (fastNLOCoeffData*)fCoeff[ic];
+         cdata->MultiplyBin(iObsIdx,fact);
+      } else if ( fastNLOCoeffMult::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.debug["MultiplyBinInTable"]<<"Found multiplicative contribution. Skipped! Index no. " << iObsIdx << endl;
+         fastNLOCoeffMult* cmult = (fastNLOCoeffMult*)fCoeff[ic];
+         cmult->MultiplyBin(iObsIdx,fact);
+      } else if ( fastNLOCoeffAddFix::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.debug["MultiplyBinInTable"]<<"Found additive fix-table contribution. Now multiplying index no. " << iObsIdx << endl;
+         fastNLOCoeffAddFix* cfix = (fastNLOCoeffAddFix*)fCoeff[ic];
+         cfix->MultiplyBin(iObsIdx,fact);
+      } else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(ctmp,quiet) ) {
+         logger.debug["MultiplyBinInTable"]<<"Found additive flex-table contribution. Now multiplying index no. " << iObsIdx << endl;
+         fastNLOCoeffAddFlex* cflex = (fastNLOCoeffAddFlex*)fCoeff[ic];
+         cflex->MultiplyBin(iObsIdx,fact);
+      } else {
+         logger.error["MultiplyBinInTable"]<<"Could not identify contribution. Print and abort!" << endl;
+         ctmp->Print(-1);
+         exit(1);
+      }
+   }
+}
+
+void fastNLOTable::CatBinToTable(const fastNLOTable& other, unsigned int iObsIdx, unsigned int table_count) {
+   logger.info["fastNLOTable::CatBinToTable"]<<"Catenating the observable bin index no. " << iObsIdx << " from other table to this." << endl;
+   // Changes to table header block A2
+   CatBin(other,iObsIdx,table_count);
+   // Changes to table contributions block B
+   // Loop over all contributions from 'other'-table
+   for ( int ic=0; ic<other.GetNcontrib()+other.GetNdata(); ic++ ) {
+      logger.info["fastNLOTable::CatBinToTable"]<<"Catenating the observable index no. " << iObsIdx << " from contribution no. " << ic << endl;
+      // Find matching contribution from 'this'-table
+      for ( unsigned int jc=0; jc<fCoeff.size(); jc++) {
+         bool quiet = true;
+         //         fastNLOCoeffBase* cthis  = (fastNLOCoeffBase*)fCoeff[jc];
+         fastNLOCoeffBase* cother = (fastNLOCoeffBase*)other.GetCoeffTable(ic);
+         // Identify type of other coeff table
+         // Additive fixed-order?
+         if ( fastNLOCoeffAddBase::CheckCoeffConstants(cother,quiet) ) {
+            if ( fastNLOCoeffAddFix::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFix* clhs = (fastNLOCoeffAddFix*)fCoeff[jc];
+               fastNLOCoeffAddFix* crhs = (fastNLOCoeffAddFix*)other.GetCoeffTable(ic);
+               if ( clhs->IsCatenable(*crhs) ) {
+                  logger.info["CatBinToTable"]<<"Found fix-scale additive contribution. Now catenating index no. " << iObsIdx << endl;
+                  clhs->CatBin(*crhs,iObsIdx);
+                  continue;
+               }
             }
-         } else if ( lobin[2] < Bin[iobs][2].first ) {
-            for (unsigned int k=2; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
+            else if ( fastNLOCoeffAddFlex::CheckCoeffConstants(cother,quiet) ) {
+               fastNLOCoeffAddFlex* clhs = (fastNLOCoeffAddFlex*)fCoeff[jc];
+               fastNLOCoeffAddFlex* crhs = (fastNLOCoeffAddFlex*)other.GetCoeffTable(ic);
+               if ( clhs->IsCatenable(*crhs) ) {
+                  logger.info["CatBinToTable"]<<"Found flex-scale additive contribution. Now catenating index no. " << iObsIdx << endl;
+                  clhs->CatBin(*crhs,iObsIdx);
+                  continue;
+               }
             }
-            ibin[2]++;
          }
-      } else if (iDim == 1) {
-         if ( lobin[0] < Bin[iobs][0].first ) {
-            for (unsigned int k=0; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
-            }
-            ibin[0]++;
-            for (unsigned int k=1; k<=iDim; k++) {
-               ibin[k] = 0;
-            }
-         } else if ( lobin[1] < Bin[iobs][1].first ) {
-            for (unsigned int k=1; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
+         // Multiplicative?
+         else if ( fastNLOCoeffMult::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffMult* clhs = (fastNLOCoeffMult*)fCoeff[jc];
+            fastNLOCoeffMult* crhs = (fastNLOCoeffMult*)other.GetCoeffTable(ic);
+            if ( clhs->IsCatenable(*crhs) ) {
+               logger.info["CatBinToTable"]<<"Found multiplicative contribution. Now catenating index no. " << iObsIdx << endl;
+               clhs->CatBin(*crhs,iObsIdx);
+               continue;
             }
-            ibin[1]++;
          }
-      } else if (iDim == 0 ) {
-         if ( lobin[0] < Bin[iobs][0].first ) {
-            for (unsigned int k=0; k<=iDim; k++) {
-               lobin[k] = Bin[iobs][k].first;
+         // Data?
+         else if ( fastNLOCoeffData::CheckCoeffConstants(cother,quiet) ) {
+            fastNLOCoeffData* clhs = (fastNLOCoeffData*)fCoeff[jc];
+            fastNLOCoeffData* crhs = (fastNLOCoeffData*)other.GetCoeffTable(ic);
+            if ( clhs->IsCatenable(*crhs) ) {
+               logger.info["CatBinToTable"]<<"Found data contribution. Now catenating index no. " << iObsIdx << endl;
+               clhs->CatBin(*crhs,iObsIdx);
+               continue;
             }
-            ibin[0]++;
+         }
+         // Unknown
+         else {
+            logger.error["CatBinToTable"]<<"Could not identify contribution. Print and abort!" << endl;
+            cother->Print(-1);
+            exit(1);
          }
       }
-      if ( iobs == iObsBin ) {
-         return ibin[iDim];
+   }
+   // Increase no. of observable bins
+   SetNObsBin(GetNObsBin()+1);
+}
+
+// Catenate observable bin
+void fastNLOTable::CatBin(const fastNLOTable& other, unsigned int iObsIdx, unsigned int table_count) {
+   logger.debug["fastNLOTable::CatBin"]<<"Catenating observable bin in scenario header corresponding to bin index " << iObsIdx << endl;
+   if ( Bin.size() == 0 ) {
+      say::error["CatBin"]<<"Bin size cannot be zero for a fastNLO table. Aborted!" << endl;
+      exit(1);
+   }
+   static unsigned int noff = 0;
+   static unsigned int ntab = 0;
+   unsigned int nold = Bin.size();
+   if ( ntab != table_count ) {
+      ntab = table_count;
+      noff = nold;
+   }
+   Bin.resize(nold+1);
+   Bin[nold] = other.Bin[iObsIdx];
+   BinSize.resize(nold+1);
+   BinSize[nold] = other.BinSize[iObsIdx];
+   if ( fastNLOTable::INormFlag != 0 ) {
+      IDivLoPointer.resize(nold+1);
+      IDivUpPointer.resize(nold+1);
+      if ( fastNLOTable::INormFlag == 2 ) {
+         IDivLoPointer[nold] = noff + other.IDivLoPointer[iObsIdx];
+         IDivUpPointer[nold] = noff + other.IDivUpPointer[iObsIdx];
+      } else {
+         say::error["CatBin"]<<"Table catenation not yet implemented for INormFlag = " << fastNLOTable::INormFlag << ". Aborted!" << endl;
+         exit(1);
       }
    }
-   logger.error["fastNLOTable::GetIDimBin"] << "Observable bin not found. This should never happen, aborted!" << endl;
-   exit(1);
 }
 
+//
+// functions previously included in fastNLOBase
+//
 
-// ___________________________________________________________________________________________________
-// DO NOT USE! DOES NOT WORK YET!
-vector < pair < double, double > > fastNLOTable::GetBinBoundaries(int iDim0Bin, int iDim1Bin, int iDim2Bin) {
-   //!
-   //! Get bin boundaries for first, second, and third dimension
-   //!    Assuming for instance following 2-dimensional binning scheme:
-   //!
-   //!    iDim0Bin  ________________________________
-   //!       0      |___|___|___|_______|__|__|____|
-   //!  D    1      |____|____|____|_____|____|____|
-   //!  I    2      |__|__|___|__|__|___|__|___|___|
-   //!  M    3      |______|_______|_________|_____|
-   //!       4      |__________|_______|_________|_|
-   //!  0    5      |______________|______|___|____|
-   //!       6      |_______|_______|______|_______|
-   //!                            DIM 1
-   //!  iDim1Bin may be different for each iDim0Bin
-   //!
-   //! usage e.g.:
-   //! int LowerBoundary = GetBinBoundaries(ibin)[dim].first;
-   //! int UpperBoundary = GetBinBoundaries(ibin)[dim].second;
-   //! 'dim' must be smaller than number of parameters passed to GetBinBoundaries
-   //! usage e.g.:
-   //! int LoYBin  = GetBinBoundaries(2)[0].first;
-   //! int UpPtBin = GetBinBoundaries(2,5)[1].second;
-   //! int LoYBin  = GetBinBoundaries(2,5)[0].second;
-   logger.error["GetBinBoundaries"] << "DO NOT USE! DOES NOT WORK YET!" << endl;
-   vector<pair<double,double> > BinRet(NDim);
-   const int idiff = GetNumDiffBin();
-
-   if ( idiff==1 ) {
-      if ( iDim0Bin<0 || iDim0Bin >= (int)NObsBin ) {
-         logger.warn["GetBinBoundaries"]<<"0th dimension does only have "<<NObsBin<<" but bin "<<iDim0Bin<<" was requested."<<endl;
-         return BinRet;
-      }
-      return Bin[iDim0Bin];
-   }
-   else if ( idiff==2) {
-      unsigned int nDim1 = GetNDim1Bins(iDim0Bin);
-      unsigned int nDim0 = GetNDim0Bins();
-      // sanity
-      if ( iDim0Bin < 0 || iDim0Bin >= (int)nDim0 ) {
-         logger.warn["GetBinBoundaries"]<<"Dimension 2 does only have "<<nDim0<<" but bin "<<iDim0Bin<<" was requested."<<endl;
-      }
-      if ( iDim1Bin < 0 || iDim1Bin >= (int)nDim1 ) {
-         logger.warn["GetBinBoundaries"]<<"Dimension 1 does only have "<<nDim1<<" but bin "<<iDim1Bin<<" was requested."<<endl;
-      }
-      int iObs = 0;
-      for ( int i0 = 0 ; i0<iDim0Bin ; i0++ ) {
-         iObs += GetNDim1Bins(i0);
-      }
-      iObs += iDim1Bin;
-      return Bin[iObs];
-   }
-   else if ( idiff == 3 ) {
-      unsigned int nDim0 = GetNDim0Bins();
-      unsigned int nDim1 = GetNDim1Bins(iDim0Bin);
-      unsigned int nDim2 = GetNDim2Bins(iDim0Bin,iDim1Bin);
-      // sanity
-      if ( iDim0Bin < 0 || iDim0Bin >= (int)nDim0 ) {
-         logger.warn["GetBinBoundaries"]<<"Dimension 0 does only have "<<nDim0<<" but bin "<<iDim0Bin<<" was requested."<<endl;
-      }
-      if ( iDim1Bin < 0 || iDim1Bin >= (int)nDim1 ) {
-         logger.warn["GetBinBoundaries"]<<"Dimension 1 does only have "<<nDim1<<" but bin "<<iDim1Bin<<" was requested."<<endl;
-      }
-      if ( iDim2Bin < 0 || iDim2Bin >= (int)nDim2 ) {
-         logger.warn["GetBinBoundaries"]<<"Dimension 2 does only have "<<nDim2<<" but bin "<<iDim2Bin<<" was requested."<<endl;
-      }
-      logger.error["GetBinBoundaries"]<<"todo. Further code no yet implemented."<<endl;
+//______________________________________________________________________________
+std::istream* fastNLOTable::OpenFileRead() {
+   //! Open file-stream for reading table
+   // does file exist?
+   if (access(ffilename.c_str(), R_OK) != 0) {
+      logger.error["OpenFileRead"]<<"File does not exist! Was looking for: "<<ffilename<<". Exiting."<<endl;
+      exit(1);
+   }
 
+   // check if filename ends with .gz
+#ifdef HAVE_LIBZ
+   std::istream* strm = (istream*)(new zstr::ifstream(ffilename.c_str(),ios::in));
+   if ( strm ) logger.info["OpenFileRead"]<<"Opened file "<<ffilename<<" successfully."<<endl;
+   return strm;
+#else
+   const std::string ending = ".gz";
+   if (ffilename.length() >= ending.length() && ffilename.compare(ffilename.length() - ending.length(), ending.length(), ending) == 0) {
+      logger.error["ReadHeader"]<<"Input file has a .gz file extension but zlib support is not enabled! Please unzip file first."<<endl;
+      exit(1);
    }
-   else {
-      logger.error["GetBinBoundaries"]<<"Higher than triple-differential binnings are not implemented."<<endl;
+   std::istream* strm = (istream*)(new ifstream(ffilename.c_str(),ios::in));
+   return strm;
+#endif
+
+}
+
+
+//______________________________________________________________________________
+void fastNLOTable::CloseFileRead(std::istream& strm) {
+   //! Close file-stream
+   // strm.close();
+   delete &strm;
+}
+
+
+//______________________________________________________________________________
+std::ostream* fastNLOTable::OpenFileWrite(bool compress) {
+   //! open ostream for writing tables
+   //! do overwrite existing table
+   if (access(ffilename.c_str(), F_OK) == 0) {
+      logger.info["OpenFileWrite"]<<"Overwriting the already existing table file: " << ffilename << endl;
+   }
+#ifdef HAVE_LIBZ
+   std::ostream* stream = compress ?
+      (ostream*)(new zstr::ofstream(ffilename)) :
+      (ostream*)(new std::ofstream(ffilename));
+#else
+   std::ostream* stream = (ostream*)(new std::ofstream(ffilename));
+   if ( compress ) logger.info["OpenFileWrite"]<<"gz-compression requested, but compilation was performed without zlib."<<endl;
+#endif
+
+   if (!stream->good()) {
+      logger.error["OpenFileWrite"]<<"Cannot open file '"<<ffilename<<"' for writing. Aborting."<<endl;
+      exit(2);
+   }
+   stream->precision(fPrecision);
+   return stream;
+}
+
+
+//______________________________________________________________________________
+void fastNLOTable::CloseFileWrite(std::ostream& table) {
+   //! close stream and delete object;
+   table << fastNLO::tablemagicno << sep;
+   table << fastNLO::tablemagicno << sep;
+   // table.close();
+   delete &table;
+}
+
+
+//______________________________________________________________________________
+bool fastNLOTable::IsCompatibleHeader(const fastNLOTable& other) const {
+   if ( trunc(Itabversion/10000) != trunc(other.GetItabversion()/10000)) {
+      logger.error["IsCompatibleHeader"]<<"Differing major versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      return false;
+   } else if ( ( trunc(Itabversion/1000) <= 22 && trunc(other.GetItabversion()/1000) >= 23 ) ||
+               ( trunc(Itabversion/1000) >= 23 && trunc(other.GetItabversion()/1000) <= 22 ) ) {
+      logger.error["IsCompatibleHeader"]<<"Incompatible minor versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      return false;
+   } else if ( Itabversion != other.GetItabversion() ) {
+      logger.warn["IsCompatibleHeader"]<<"Differing sub-versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      logger.warn["IsCompatibleHeader"]<<"Please check your result carefully!"<<endl;
+   }
+   if (GetNdata() + other.GetNdata() > 1) {
+      logger.warn["IsCompatibleHeader"]<<"Two tables containing both experimental data are incompatible"<<endl;
+      return false;
+   }
+   if (ScenName!= other.GetScenName()) {
+      logger.warn["IsCompatibleHeader"]<<"Differing names of scenarios: "<<ScenName.c_str()<<" and "<<other.ScenName.c_str()<<endl;
+      // continue...
    }
-   return BinRet;
+   return true;
+}
+
 
+//______________________________________________________________________________
+bool fastNLOTable::IsCatenableHeader(const fastNLOTable& other) const {
+   if ( trunc(Itabversion/10000) != trunc(other.GetItabversion()/10000)) {
+      logger.error["IsCatenableHeader"]<<"Differing major versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      return false;
+   } else if ( ( trunc(Itabversion/1000) <= 22 && trunc(other.GetItabversion()/1000) >= 23 ) ||
+               ( trunc(Itabversion/1000) >= 23 && trunc(other.GetItabversion()/1000) <= 22 ) ) {
+      logger.error["IsCatenableHeader"]<<"Incatenable minor versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      return false;
+   } else if ( Itabversion != other.GetItabversion() ) {
+      logger.warn["IsCatenableHeader"]<<"Differing sub-versions of table format: "<<Itabversion<<" and "<<other.GetItabversion()<<endl;
+      logger.warn["IsCatenableHeader"]<<"Please check your result carefully!"<<endl;
+   }
+   if (GetNcontrib() != other.GetNcontrib()) {
+      logger.warn["IsCatenableHeader"]<<"Differing number of contributions: "<<GetNcontrib()<<" and "<<other.GetNcontrib()<<endl;
+      return false;
+   }
+   if (GetNmult() != other.GetNmult()) {
+      logger.warn["IsCatenableHeader"]<<"Differing number of multiplicative contributions: "<<GetNmult()<<" and "<<other.GetNmult()<<endl;
+      return false;
+   }
+   if (GetNdata() != other.GetNdata()) {
+      logger.warn["IsCatenableHeader"]<<"Differing number of data contributions: "<<GetNdata()<<" and "<<other.GetNdata()<<endl;
+      return false;
+   }
+   return true;
+}
+
+//______________________________________________________________________________
+void fastNLOTable::PrintHeader(int iprint) const {
+   if ( !(iprint < 0) ) {
+      cout << fastNLO::_DSEP20C << " fastNLO Table: Header " << fastNLO::_DSEP20 << endl;
+   } else {
+      cout << endl << fastNLO::_CSEP20C << " fastNLO Table: Header " << fastNLO::_CSEP20 << endl;
+   }
+   printf(" # Table version (Itabversion)         %d\n",Itabversion);
+   printf(" # Scenario name (ScenName)            %s\n",ScenName.data());
+   printf(" # Theory contributions (Ncontrib)     %d\n",GetNcontrib());
+   printf(" # Data contribution 0/1 (Ndata)       %d\n",GetNdata());
+   if ( abs(iprint) > 0 ) {
+      cout << fastNLO::_SSEP20C << " Extended information (iprint > 0) " << fastNLO::_SSEP20 << endl;
+      printf(" #   Separator (tablemagicno)            %d\n",fastNLO::tablemagicno);
+      printf(" #   Unused (Nmult)                      %d\n",GetNmult());
+   }
+   cout << fastNLO::_CSEPSC << endl;
+}
+
+
+//______________________________________________________________________________
+void fastNLOTable::PrintWelcomeMessage() {
+
+   char fnlo[100];
+   sprintf(fnlo,"%c[%d;%dmfast%c[%d;%dmNLO\033[0m",27,0,31,27,0,34);
+   char subproject[100]      = FNLO_SUBPROJECT;
+   char package_version[100] = FNLO_VERSION;
+   char svnrev[100]          = FNLO_SVNREV;
+   char authors[500]         = FNLO_AUTHORS;
+   char webpage[500]         = FNLO_WEBPAGE;
+   char authorsv14[200]      = FNLO_AUTHORSv14;
+   char quotev14[200]        = FNLO_QUOTEv14;
+   char authorsv2[200]       = FNLO_AUTHORSv2;
+   char quotev2[200]         = FNLO_QUOTEv2;
+   char years[100]           = FNLO_YEARS;
+
+   cout  << endl;
+   cout  << fastNLO::_CSEPSC << endl;
+   speaker &shout = logger.shout;
+   cout << " #" << endl;
+   shout << fnlo << "_" << subproject << endl;
+   shout << "Version " << package_version << "_" << svnrev << endl;
+   cout << " #" << endl;
+   shout << "C++ program and toolkit to read and create fastNLO v2 tables and" << endl;
+   shout << "derive QCD cross sections using PDFs, e.g. from LHAPDF" << endl;
+   cout << " #" << endl;
+   cout  << fastNLO::_SSEPSC << endl;
+   cout << " #" << endl;
+   shout << "Copyright © " << years << " " << fnlo << " Collaboration" << endl;
+   shout << authors << endl;
+   cout << " #" << endl;
+   shout << "This program is free software: you can redistribute it and/or modify" << endl;
+   shout << "it under the terms of the GNU General Public License as published by" << endl;
+   shout << "the Free Software Foundation, either version 3 of the License, or" << endl;
+   shout << "(at your option) any later version." << endl;
+   cout << " #" << endl;
+   shout << "This program is distributed in the hope that it will be useful," << endl;
+   shout << "but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl;
+   shout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << endl;
+   shout << "GNU General Public License for more details." << endl;
+   cout << " #" << endl;
+   shout << "You should have received a copy of the GNU General Public License" << endl;
+   shout << "along with this program. If not, see <http://www.gnu.org/licenses/>." << endl;
+   cout << " #" << endl;
+   cout  << fastNLO::_SSEPSC << endl;
+   cout << " #" << endl;
+   shout << "The projects web page can be found at:" << endl;
+   shout << "  " << webpage << endl;
+   cout << " #" << endl;
+   shout << "If you use this code, please cite:" << endl;
+   shout << "  " << authorsv14 << ", " << quotev14 << endl;
+   shout << "  " << authorsv2 << ", " << quotev2 << endl;
+   cout << " #" << endl;
+   cout  << fastNLO::_CSEPSC << endl;
+   fWelcomeOnce = true;
 }
diff --git a/FastNLO/src/fastNLOTools.cc b/FastNLO/src/fastNLOTools.cc
index 33c0c1831ac361459c6f3db08455d451cb5c9bc1..047c4bc1e4647aa604f08112f45fbcfaf055f0c7 100644
--- a/FastNLO/src/fastNLOTools.cc
+++ b/FastNLO/src/fastNLOTools.cc
@@ -10,22 +10,30 @@ using namespace fastNLO;
 
 namespace fastNLOTools {
 
+   //________________________________________________________________________________________________________________ //
+   bool CheckVersion(int version ){
+      if ( fastNLO::CompatibleVersions.count(version) == 0 ) {
+         error["fastNLOTools::CheckVersion"]<<"This table version ("<<version<<") is incompatible with this fastNLO code."<<endl;
+         error["fastNLOTools::CheckVersion"]<<"Supported table versions are:";
+         for ( auto i : fastNLO::CompatibleVersions ) error>>" "<<i;
+         error>>""<<endl;
+         error["fastNLOTools::CheckVersion"]<<"Exiting."<<endl;
+         exit(1);
+         return false;
+      }
+      return true;
+   }
+
+
    //________________________________________________________________________________________________________________ //
    int ReadVector(vector<double >& v, istream& table , double nevts ){
       //! Read values according to the size() of the given vector
       //! from table (v2.0 format).
       for( unsigned int i=0 ; i<v.size() ; i++){
-         // KR: Add check on inf and NaN
-         //         table >> v[i];
-         //         v[i] *= nevts;
-         char buffer[256];
-         table >> buffer;
-         double value = atof(buffer);
-         if ( isfinite(value) ) {
-            v[i]  = value;
-            v[i] *= nevts;
-         } else {
-            error["ReadVector"]<<"Non-finite number read from table, aborted! value = " << value << endl;
+         table >> v[i];
+         v[i] *= nevts;
+         if ( !isfinite(v[i]) ) {
+            error["ReadVector"]<<"Non-finite number read from table, aborted! value = " << v[i] << endl;
             error["ReadVector"]<<"Please check the table content." << endl;
             exit(1);
          }
@@ -33,39 +41,86 @@ namespace fastNLOTools {
       return v.size();
    }
 
+   //________________________________________________________________________________________________________________ //
+   int ReadUnused(istream& table ){
+      //! Read values, which are not known to the current code.
+      int nLines = 0;
+      table >> nLines;
+      if ( nLines==fastNLO::tablemagicno ) {
+         error["ReadUnused"]<<"Number of lines identical to magic number. Exiting."<<endl; exit(3);
+      }
+      string sUnused;
+      if ( nLines > 0 ) std::getline(table,sUnused); // discard empty space due to precendent >>
+      for( int i=0 ; i<nLines ; i++)
+         std::getline(table,sUnused);
+      return nLines;
+   }
+
 
    //________________________________________________________________________________________________________________ //
    int ReadFlexibleVector(vector<double >& v, istream& table , int nProcLast , double nevts ){
       int nn = 0;
       if ( nProcLast == 0 ) {
-         int size = 0;
-         table >> size; nn++;
-         v.resize(size);
+         table >> nProcLast;
+         nn++;
       }
-      else {
-         v.resize(nProcLast);
+      v.resize(nProcLast);
+      for(unsigned int i0=0;i0<v.size();i0++){
+         table >> v[i0];
+         v[i0] *= nevts;
+         nn++;
+         if ( !isfinite(v[i0]) ) {
+            error["ReadFlexibleVector"]<<"Non-finite number read from table, aborted! value = " << v[i0] << endl;
+            error["ReadFlexibleVector"]<<"Please check the table content." << endl;
+            exit(1);
+         }
       }
+      return nn;
+   }
+
+   //________________________________________________________________________________________________________________ //
+   int ReadFlexibleVector(vector<unsigned long long >& v, istream& table , int nProcLast , double nevts ){
+      int nn = 0;
+      if ( nProcLast == 0 ) {
+         table >> nProcLast;
+         nn++;
+      }
+      v.resize(nProcLast);
       for(unsigned int i0=0;i0<v.size();i0++){
-         // KR: Add check on inf and NaN
-         //         table >> v[i0];
-         //         v[i0] *= nevts;
          char buffer[256];
          table >> buffer;
          double value = atof(buffer);
-         if ( isfinite(value) ) {
-            v[i0]  = value;
-            v[i0] *= nevts;
-            nn++;
-         } else {
-            error["ReadFlexibleVector"]<<"Non-finite number read from table, aborted! value = " << value << endl;
-            error["ReadFlexibleVector"]<<"Please check the table content." << endl;
-            exit(1);
-         }
+         v[i0]  = value;
+         v[i0] *= nevts;
+         nn++;
       }
       return nn;
    }
 
 
+   //________________________________________________________________________________________________________________ //
+   int ReadFlexibleVector(vector<std::string >& v, istream& table , int size , double nevts ){
+      if ( size == 0 ) table >> size;
+      v.resize(size);
+      if ( size > 0 ) std::getline(table,v[0]); // discard empty space due to precendent >>
+      for( auto& i : v) {
+         std::getline(table,i);
+      }
+      return v.size() + 1;
+   }
+
+
+   //________________________________________________________________________________________________________________ //
+   int ReadFlexibleVector(vector<int >& v, istream& table , int size , double nevts ){
+      if ( size == 0 ) table >> size;
+      v.resize(size);
+      for( auto& i : v) {
+         table >> i;
+      }
+      return v.size() + 1;
+   }
+
+
    //________________________________________________________________________________________________________________ //
    void ResizeVector( v7d& v, int dim0 , int dim1, int dim2, int dim3, int dim4, int dim5, int dim6 ){
       if ( dim0 > 0 ){
@@ -211,7 +266,7 @@ namespace fastNLOTools {
          return -1000;
       }
       if ( nProcLast == 0 )
-         table << v.size() << endl;
+         table << v.size() << sep;
       if ( nProcLast != 0 && nProcLast != (int)v.size() )
          warn["fastNLOTools::WriteFlexibleVector(double)"]
             <<"Dimension of this vector is not compatible with its size (i.e. nProclast ="<<nProcLast<<", v.size()="<<v.size()<<endl;
@@ -219,7 +274,6 @@ namespace fastNLOTools {
       return ( nProcLast == 0 ) ? n+1 : n;
    }
 
-
    //______________________________________________________________________________
    int WriteFlexibleVector(const vector<string >& v, ostream& table, int nProcLast, double nevts) {
       //! Write 1-dimensional flexible table to disk
@@ -229,7 +283,7 @@ namespace fastNLOTools {
       if ( nevts!= 1 ) warn["fastNLOTools::WriteFlexibleVector(string)"]
          <<"String variable cannot be divided by integer number! Ignoring nevts="<<nevts<<endl;
       if ( nProcLast == 0 )
-         table << v.size() << endl;
+         table << v.size() << sep;
       if ( nProcLast != 0 && nProcLast != (int)v.size() )
          warn["fastNLOTools::WriteFlexibleVector(string)"]
             <<"Dimension of this vector is not compatible with its size (i.e. nProclast ="<<nProcLast<<", v.size()="<<v.size()<<endl;
@@ -246,7 +300,7 @@ namespace fastNLOTools {
       if ( nevts!= 1 ) warn["fastNLOTools::WriteFlexibleVector(unsigned long long)"]
          <<"String variable cannot be divided by integer number! Ignoring nevts="<<nevts<<endl;
       if ( nProcLast == 0 )
-         table << v.size() << endl;
+         table << v.size() << sep;
       if ( nProcLast != 0 && nProcLast != (int)v.size() )
          warn["fastNLOTools::WriteFlexibleVector(string)"]
             <<"Dimension of this vector is not compatible with its size (i.e. nProclast ="<<nProcLast<<", v.size()="<<v.size()<<endl;
@@ -263,7 +317,7 @@ namespace fastNLOTools {
       if ( nevts!= 1 ) warn["fastNLOTools::WriteFlexibleVector(int)"]
          <<"Refusing dividing integer numbers by each other! Ignoring nevts="<<nevts<<endl;
       if ( nProcLast == 0 )
-         table << v.size() << endl;
+         table << v.size() << sep;
       if ( nProcLast != 0 && nProcLast != (int)v.size() )
          warn["fastNLOTools::WriteFlexibleVector(int)"]
             <<"Dimension of this vector is not compatible with its size (i.e. nProclast ="<<nProcLast<<", v.size()="<<v.size()<<endl;
@@ -277,7 +331,7 @@ namespace fastNLOTools {
       for(string::iterator achar = str.end(); achar>str.begin();achar--) {
          if (*achar==0x20 || *achar==0x00){
             str.erase(achar);
-         }else{
+         } else {
             break;
          }
       }
@@ -289,16 +343,24 @@ namespace fastNLOTools {
       for(int i=0;i<(int)(log10((double)tablemagicno)+1);i++){
          table.unget();
       }
+      table.unget();
    }
 
-
    //______________________________________________________________________________
    bool ReadMagicNo(istream& table) {
       //! read and crosscheck magic number
-      int key = 0;
-      table >> key;
-      if(key != tablemagicno){
-         error["ReadMagicNo"]<<"Found "<<key<<" instead of "<<tablemagicno<<"."<<endl;
+      if (table.eof()){
+         error["ReadMagicNo"]<<"Cannot read from file. Exiting"<<endl;
+         exit(3);
+      }
+      string line;
+      std::getline(table,line);
+      if ( line=="" ) std::getline(table,line);  // last one was '<<'
+      if( line != std::to_string(tablemagicno)){
+         error["ReadMagicNo"]<<"Found '"<<line<<"' instead of "<<tablemagicno<<"."<<endl;
+         error["ReadMagicNo"]<<"Did not find magic number, aborting!"<<endl;
+         error["ReadMagicNo"]<<"Please check compatibility of tables and program version. Exiting."<<endl;
+         exit(2);
          return false;
       };
       return true;
diff --git a/FastNLO/src/speaker.cc b/FastNLO/src/speaker.cc
index 9d842d65b8fbe493dc0c63478fe8527771e21c7a..afb9e6c55aecaa7ae847c3a3aa263df46ed46262 100644
--- a/FastNLO/src/speaker.cc
+++ b/FastNLO/src/speaker.cc
@@ -8,10 +8,14 @@
 
 using namespace std;
 
-
 std::map<unsigned long,speaker*>* speaker::list = NULL;
 std::ostream* speaker::weg = NULL;
+// Set default logging level to start with; should be INFO.
+// Use DEBUG only for debugging code executed before
+// SetGlobalVerbosity(say::Verbosity volume)
+// can be called from within the program.
 say::Verbosity speaker::fverb = say::INFO;
+//say::Verbosity speaker::fverb = say::DEBUG;
 unsigned long speaker::ct = 0;
 bool speaker::fe2cerr = true;
 
@@ -54,7 +58,7 @@ const speaker& speaker::operator=(const speaker& other)
    list->erase(fii);
    fii=ct;
    (*list)[ct++] = this;
- 
+
    fquiet=other.fquiet;
    pref=other.pref;
    errs=other.errs;
@@ -107,15 +111,16 @@ int speaker::SetGlobalVerbosity(say::Verbosity volume) {
    return c;
 }
 
-\
 PrimalScream::PrimalScream(std::string classname) { //,std::string prefix=""){
    debug = speaker(" # DEBUG.   ",say::DEBUG);
-   man   = speaker(" # MANUAL.  ",say::MANUAL);
+   man   = speaker(" # USAGE.   ",say::MANUAL);
    info  = speaker(" # INFO.    ",say::INFO);
    warn  = speaker(" # WARNING! ",say::WARNING);
    error = speaker(" # ERROR!   ",say::ERROR,true);
    shout = speaker(" # ",say::ERROR,false);
    shout.SetClassName(___cn);
+   yell = speaker("",say::ERROR,false);
+   yell.SetClassName(___cn);
    SetClassName(classname);
    //debug["PrimalScream"]<<"Primal Scream initialized."<<std::endl;
 }
@@ -128,6 +133,7 @@ void PrimalScream::SetClassName(const std::string classname){
    warn.SetClassName(___cn);
    error.SetClassName(___cn);
    shout.SetClassName(___cn);
+   yell.SetClassName(___cn);
 }
 
 void PrimalScream::SetVerbosity(say::Verbosity volume) {
@@ -137,17 +143,19 @@ void PrimalScream::SetVerbosity(say::Verbosity volume) {
    warn.DoSpeak(warn.GetVolume() >= volume);
    error.DoSpeak(error.GetVolume() >= volume);
    shout.DoSpeak(shout.GetVolume() >= volume);
+   yell.DoSpeak(yell.GetVolume() >= volume);
 }
 
 namespace say {
-speaker debug(" # DEBUG.   ",say::DEBUG);
-speaker man  (" # ",say::MANUAL);
-speaker info (" # INFO.    ",say::INFO);
-speaker warn (" # WARNING! ",say::WARNING);
-speaker error(" # ERROR!   ",say::ERROR,true);
-speaker shout(" # ",say::ERROR,false);
-//debug["namespace say"]<<"speakers initialized."<<std::endl;
-int SetGlobalVerbosity(Verbosity verbosity) {
-   return speaker::SetGlobalVerbosity(verbosity);
-};
+   speaker debug(" # DEBUG.   ",say::DEBUG);
+   speaker man  (" # USAGE.   ",say::MANUAL);
+   speaker info (" # INFO.    ",say::INFO);
+   speaker warn (" # WARNING! ",say::WARNING);
+   speaker error(" # ERROR!   ",say::ERROR,true);
+   speaker shout(" # ",say::ERROR,false);
+   speaker yell("",say::ERROR,false);
+   //debug["namespace say"]<<"speakers initialized."<<std::endl;
+   int SetGlobalVerbosity(Verbosity verbosity) {
+      return speaker::SetGlobalVerbosity(verbosity);
+   };
 }