diff --git a/Root/LinkDef.h b/Root/LinkDef.h
index 08244fcaf5fca4c5f666a64d50365771cfd93c0d..40993dfafc3913c4e645aa1b2b948a592833ee35 100644
--- a/Root/LinkDef.h
+++ b/Root/LinkDef.h
@@ -15,6 +15,7 @@
 #include "VLQAnalysis/VLQ_TruthManager.h"
 #include "VLQAnalysis/VLQ_TtbarSystematicsManager.h"
 #include "VLQAnalysis/VLQ_VariableComputer.h"
+#include "VLQAnalysis/VLQ_WeightManager.h"
 
 #pragma link off all globals;
 #pragma link off all classes;
@@ -34,5 +35,6 @@
 #pragma link C++ class VLQ_TruthManager;
 #pragma link C++ class VLQ_TtbarSystematicsManager;
 #pragma link C++ class VLQ_VariableComputer;
+#pragma link C++ class VLQ_WeightManager;
 
 #endif
diff --git a/Root/VLQ_Analysis_Data2015.cxx b/Root/VLQ_Analysis_Data2015.cxx
index 38e67340235345aa91c4b7f57f2a1525a8aa792f..edefa2931439b95fb04267b56da407a4001fde9b 100644
--- a/Root/VLQ_Analysis_Data2015.cxx
+++ b/Root/VLQ_Analysis_Data2015.cxx
@@ -12,7 +12,7 @@
 #include "IFAETopFramework/OutputTreeManager.h"
 #include "IFAETopFramework/CommonConstants.h"
 #include "IFAETopFramework/AnalysisObject.h"
-#include "IFAETopFramework/WeightManager.h"
+//#include "IFAETopFramework/WeightManager.h"
 #include "IFAETopFramework/AnalysisUtils.h"
 #include "IFAETopFramework/TriggerInfo.h"
 #include "IFAETopFramework/Selection.h"
@@ -25,7 +25,7 @@
 #include "VLQAnalysis/VLQ_VariableComputer.h"
 #include "VLQAnalysis/VLQ_Enums.h"
 #include "VLQAnalysis/VLQ_TruthManager.h"
-#include "VLQAnalysis/VLQ_WeightSetter.h"
+#include "VLQAnalysis/VLQ_WeightManager.h"
 #include "VLQAnalysis/VLQ_TRFManager.h"
 #include "VLQAnalysis/VLQ_Selector.h"
 #include "VLQAnalysis/string_utils.h"
@@ -55,8 +55,8 @@ m_anaTools(0),
 m_varComputer(0),
 m_truthMngr(0),
 m_TRFMngr(0),
-m_weightMngr(0),
-m_weightSetter(0)
+m_weightMngr(0)//,
+//m_weightSetter(0)
 {
   m_channels.clear();
   m_topTaggers.clear();
@@ -134,7 +134,10 @@ bool VLQ_Analysis_Data2015::Begin(){
   // Declaration of the WeightManager, and reading in of nominal and systematic weight components
   //
   if(m_opt -> MsgLevel() == Debug::DEBUG) std::cout << "Declaring WeightManager" << std::endl;
-  m_weightMngr = new WeightManager( m_opt, m_ntupData, m_outData );
+  m_weightMngr = new VLQ_WeightManager( m_opt, m_ntupData, m_outData );
+
+
+  /*
   m_weightMngr    ->  SetConfigBlock( "ISQCD", ( m_opt -> SampleName() == SampleName::QCD ) );
   m_weightMngr    ->  SetConfigBlock( "USEPUWEIGHT", m_opt -> UsePileUpWeight() );
   m_weightMngr    ->  SetConfigBlock( "USELEPTONSF", m_opt -> UseLeptonsSF() );
@@ -142,9 +145,6 @@ bool VLQ_Analysis_Data2015::Begin(){
   m_weightMngr    ->  SetConfigBlock( "RECOMPUTEBTAGGINGWEIGHTS", (m_opt -> DoTRF() && m_opt -> RecomputeTRF()) || m_opt -> RecomputeBtagSF() );
   m_weightMngr    ->  SetConfigBlock( "RUNLEPTONSYSTEMATICS", m_opt -> ComputeWeightSys() );
 
-  bool isTtbar =  (m_opt -> SampleName() == SampleName::TTBAR) || (m_opt -> SampleName() == SampleName::TTBARBB)
-  || (m_opt -> SampleName() == SampleName::TTBARCC) || (m_opt -> SampleName() == SampleName::TTBARLIGHT);
-
   bool isVjets22 = ( (m_opt -> StrSampleName().find("W+JETS22") != std::string::npos)
   || (m_opt -> StrSampleName().find("Z+JETS22") != std::string::npos) );
   m_weightMngr    ->  SetConfigBlock( "SCALETTBARHTSLICES", isTtbar && m_opt -> ScaleTtbarHtSlices() );
@@ -154,8 +154,11 @@ bool VLQ_Analysis_Data2015::Begin(){
   m_weightMngr    ->  SetConfigBlock( "USETTBARNNLOREWEIGHTING", isTtbar && m_opt -> ApplyTtbarNNLOCorrection() );
   m_weightMngr    ->  SetConfigBlock( "COMPUTETTCCNLO", isTtbar && m_opt -> ComputeTtccNLO() );
   m_weightMngr    ->  SetConfigBlock( "USEVJETSSHERPA22RW", isVjets22 && m_opt -> ApplyVjetsSherpa22RW() );
+  */
+  m_weightMngr->AddVLQNominalWeights(); 
+  if(m_opt->ComputeWeightSys()) m_weightMngr->AddVLQSystematicWeights();
 
-  m_weightMngr -> AddAllWeights();
+  //m_weightMngr -> AddAllWeights();
   m_weightMngr -> Print( false );
 
   //
@@ -572,6 +575,10 @@ bool VLQ_Analysis_Data2015::Begin(){
   //
   // Declaration of the VLQ_TruthManager object (to recover and treat truth information)
   //
+  bool isTtbar =  (m_opt -> SampleName() == SampleName::TTBAR) || (m_opt -> SampleName() == SampleName::TTBARBB)
+  || (m_opt -> SampleName() == SampleName::TTBARCC) || (m_opt -> SampleName() == SampleName::TTBARLIGHT);
+
+
   if( ( m_opt -> SampleName() == SampleName::VLQ ) || isTtbar ) {
     m_truthMngr = new VLQ_TruthManager( m_opt, m_ntupData );
   } else {
@@ -611,7 +618,7 @@ bool VLQ_Analysis_Data2015::Begin(){
   //
   // Weight affectation class
   //
-  m_weightSetter = new VLQ_WeightSetter( m_opt, m_ntupData, m_outData, m_weightMngr );
+  //m_weightSetter = new VLQ_WeightSetter( m_opt, m_ntupData, m_outData, m_weightMngr );
 
   return true;
 }
@@ -853,7 +860,7 @@ bool VLQ_Analysis_Data2015::Process(Long64_t entry)
   //                                                          #
   //###########################################################
   //ALERTRISHA - add option for low jet multiplicity regions
-  if( m_outData -> o_jets_n < 5 || (m_outData-> o_channel_type==VLQ_Enums::FULLHAD && m_outData -> o_jets_n < 6) ){
+  if( m_outData -> o_jets_n < 4 || (m_outData-> o_channel_type==VLQ_Enums::FULLHAD && m_outData -> o_jets_n < 6) ){
     m_outData -> o_rejectEvent |= 1 << VLQ_Enums::JETS_REJECTED;
   }
   if(m_opt -> MsgLevel() == Debug::DEBUG) std::cout << "==> After jets selection" << std::endl;
@@ -875,13 +882,13 @@ bool VLQ_Analysis_Data2015::Process(Long64_t entry)
   //###########################################################
 
   if ( !(m_opt -> IsData() || (m_opt -> SampleName() == SampleName::QCD)) ) {
-    m_weightSetter -> SetCrossSectionWeight();
+    m_weightMngr -> SetCrossSectionWeight();
     if( (m_opt -> SampleName() == SampleName::TTBARBB) || (m_opt -> SampleName() == SampleName::TTBARCC)
     || (m_opt -> SampleName() == SampleName::TTBARLIGHT) || (m_opt -> SampleName() == SampleName::TTBAR) ){
-      m_weightSetter -> SetTtbbWeights();
-      m_weightSetter -> SetTtccWeights();
-      m_weightSetter -> SetTtbarGeneratorSystematics();
-      if(m_opt->ScaleTtbarHtSlices()){ m_weightSetter -> SetTtbarHtSliceScale(); }
+      m_weightMngr -> SetTtbbWeights();
+      m_weightMngr -> SetTtccWeights();
+      m_weightMngr -> SetTtbarGeneratorSystematics();
+      if(m_opt->ScaleTtbarHtSlices()){ m_weightMngr -> SetTtbarHtSliceScale(); }
     }
   }
 
@@ -1061,7 +1068,7 @@ bool VLQ_Analysis_Data2015::Terminate()
   delete m_outMngrHist;
   delete m_outMngrTree;
 
-  delete m_weightSetter;
+  delete m_weightMngr;
   delete m_TRFMngr;
   delete m_selector;
 
diff --git a/Root/VLQ_Options.cxx b/Root/VLQ_Options.cxx
index 0edbe05a01acf2d1797a6e849774d999798be589..177601a9f555925d027aee12aebd7f371ff13d88 100644
--- a/Root/VLQ_Options.cxx
+++ b/Root/VLQ_Options.cxx
@@ -56,6 +56,7 @@ m_lepPtCut(28.),
 m_btagOP("77"),
 m_TRFCDIPath("xAODBTaggingEfficiency/13TeV/2016-20_7-13TeV-MC15-CDI-July12_v1.root"),
 m_QCDMode("none"),
+m_do_regions(""),
 m_filterType(NOFILTER)
 {}
 
@@ -105,6 +106,7 @@ OptionsBase(q)
     m_btagOP            = q.m_btagOP;
     m_TRFCDIPath        = q.m_TRFCDIPath;
     m_QCDMode           = q.m_QCDMode;
+    m_do_regions        = q. m_do_regions;
     m_maxb              = q.m_maxb;
     m_filterType        = q.m_filterType;
 }
@@ -217,6 +219,8 @@ bool VLQ_Options::IdentifyOption ( const std::string &argument, const std::strin
             m_TRFCDIPath = temp_val;
         } else if( temp_arg.find("--QCDMODE") != std::string::npos ){
             m_QCDMode = temp_val.c_str();
+        } else if( temp_arg.find("--DOREGIONS") != std::string::npos ){
+            m_do_regions = temp_val.c_str();
         }
         //
         // Int arguments
@@ -265,6 +269,7 @@ void VLQ_Options::PrintOptions(){
     std::cout << " m_recomputeTRF            = " << m_recomputeTRF      << std::endl;
     std::cout << " m_TRFCDIPath              = " << m_TRFCDIPath        << std::endl;
     std::cout << " m_qcdMode                 = " << m_QCDMode           << std::endl;
+    std::cout << " m_do_regions              = " << m_do_regions        << std::endl;
     std::cout << " m_maxb                    = " << m_maxb              << std::endl;
     std::cout << " m_RCNsubjetsCut           = " << m_RCNsubjetsCut     << std::endl;
     std::cout << " m_RCJetsPtCut             = " << m_RCJetsPtCut       << std::endl;
diff --git a/Root/VLQ_Selector.cxx b/Root/VLQ_Selector.cxx
index b527cbeb9f234a2b49dd77a3d0296909ba02cb26..27e1081af655390880d424b9dc4f6a22f93abd18 100644
--- a/Root/VLQ_Selector.cxx
+++ b/Root/VLQ_Selector.cxx
@@ -1,5 +1,8 @@
 #include <iostream>
 #include <algorithm>
+#include <ctype.h>
+//#include <locale>
+#include "IFAETopFramework/AnalysisUtils.h"
 #include "IFAETopFramework/OptionsBase.h"
 #include "IFAETopFramework/OutputHistManager.h"
 #include "IFAETopFramework/OutputTreeManager.h"
@@ -23,6 +26,18 @@ VLQ_Selector::VLQ_Selector( VLQ_Options *opt, const VLQ_NtupleData *ntupData
   m_outData(outData),
   m_anaTools(anaTools),
   m_outMngrHist(0),
+  m_do_presel(false),
+  m_do_validn_reg(false),
+  m_do_fit_reg(false),
+  m_do_lowb(false),
+  m_do_split_emu(false),
+  m_do_lowj(false),
+  m_do_highj(false),
+  m_do_old_boost(false),
+  m_do_new_boost(false),
+  m_do_merge_boost(false),
+  m_do_split_mtb(false),
+  m_do_split_mbb(false),
   m_sel_indices(NULL),
   m_sel_names(NULL),
   m_sel_lep_prop(NULL),
@@ -32,8 +47,10 @@ VLQ_Selector::VLQ_Selector( VLQ_Options *opt, const VLQ_NtupleData *ntupData
   m_sel_M_prop(NULL),
   m_sel_T_prop(NULL),
   m_sel_H_prop(NULL),
+  m_sel_TH_prop(NULL),
   m_sel_Mbb_prop(NULL),
-  m_sel_Mtb_prop(NULL)//,
+  m_sel_Mtb_prop(NULL)
+
   //m_nsel(0)
 {
 
@@ -49,6 +66,16 @@ SelectorBase(q)
     m_outData              = q.m_outData;
     m_anaTools             = q.m_anaTools;
     m_outMngrHist          = q.m_outMngrHist;
+    m_do_presel            = q.m_do_presel;
+    m_do_validn_reg        = q.m_do_validn_reg;
+    m_do_fit_reg           = q.m_do_fit_reg;
+    m_do_lowb              = q.m_do_lowb;
+    m_do_split_emu         = q.m_do_split_emu;
+    m_do_lowj              = q.m_do_lowj;
+    m_do_highj             = q.m_do_highj;
+    m_do_old_boost         = q.m_do_old_boost;
+    m_do_new_boost         = q.m_do_new_boost;
+    m_do_merge_boost       = q.m_do_merge_boost;
     m_sel_indices          = new std::map<std::string, int>(*(q.m_sel_indices));
     m_sel_names            = new std::map<int, std::string>(*(q.m_sel_names));
     m_sel_lep_prop         = new std::vector<SelProp>(*(q.m_sel_lep_prop));
@@ -58,6 +85,7 @@ SelectorBase(q)
     m_sel_M_prop           = new std::vector<SelProp>(*(q.m_sel_M_prop));
     m_sel_T_prop           = new std::vector<SelProp>(*(q.m_sel_T_prop));
     m_sel_H_prop           = new std::vector<SelProp>(*(q.m_sel_H_prop));
+    m_sel_TH_prop          = new std::vector<SelProp>(*(q.m_sel_TH_prop));
     m_sel_Mbb_prop         = new std::vector<SelProp>(*(q.m_sel_Mbb_prop));
     m_sel_Mtb_prop         = new std::vector<SelProp>(*(q.m_sel_Mtb_prop));
 
@@ -74,13 +102,45 @@ VLQ_Selector::~VLQ_Selector(){
 //
 bool VLQ_Selector::Init(){
   if(m_opt->MsgLevel() == Debug::DEBUG){
-		std::cout<<" Inside VLQ_Selector::Init()"<<std::endl;
-	}
-
-	//only looking at the very final regions
-	const bool onlyFinal = m_opt -> OnlyDumpFinalRegions();
+    std::cout<<" Inside VLQ_Selector::Init()"<<std::endl;
+  }
 
-  //============================  Initialise top selections ==================================
+  std::string doRegions = m_opt->DoRegions();
+  std::string reg; reg.clear();
+  std::string::size_type pos = 0;
+  do{
+    pos = AnalysisUtils::ParseString(doRegions, reg, ",");
+    AnalysisUtils::TrimString(reg);
+    if     (reg == "PRESEL")     m_do_presel       = true;
+    else if(reg == "VALIDATION") m_do_validn_reg   = true;
+    else if(reg == "FIT")        m_do_fit_reg      = true;
+    else if(reg == "LOWB")       m_do_lowb         = true;
+    else if(reg == "SPLITEMU")   m_do_split_emu    = true;
+    else if(reg == "LOWJ")       m_do_lowj         = true;
+    else if(reg == "HIGHJ")      m_do_highj        = true;
+    else if(reg == "OLDBOOST")   m_do_old_boost    = true;
+    else if(reg == "NEWBOOST")   m_do_new_boost    = true;
+    else if(reg == "MERGEBOOST") m_do_merge_boost  = true;
+    else{ std::cout<<"VLQ_Selector::Init() -->WARNING: Unknown region option "<<reg<< std::endl; }
+  }while(pos != std::string::npos);
+
+  std::cout<< " doRegions = "<<m_opt->DoRegions()<<std::endl;
+  std::cout<< " m_do_presel = "<< m_do_presel << std::endl;
+  std::cout<< " m_do_validn_reg = "<< m_do_validn_reg << std::endl;
+  std::cout<< " m_do_fit_reg = "<< m_do_fit_reg << std::endl;
+  std::cout<< " m_do_lowb = "<< m_do_lowb << std::endl;
+  std::cout<< " m_do_split_emu = "<< m_do_split_emu << std::endl;
+  std::cout<< " m_do_lowj = "<< m_do_lowj << std::endl;
+  std::cout<< " m_do_highj = "<< m_do_highj << std::endl;
+  std::cout<< " m_do_old_boost = "<< m_do_old_boost << std::endl;
+  std::cout<< " m_do_new_boost = "<< m_do_new_boost << std::endl;
+  std::cout<< " m_do_merge_boost = "<< m_do_merge_boost << std::endl;
+
+
+  //only looking at the very final regions
+  //const bool onlyFinal = m_opt -> OnlyDumpFinalRegions();
+
+  //============================  Initialise top selections and add rules for primary ancestors ==================================
   m_sel_indices = new std::map<std::string, int>();
   m_sel_names = new std::map<int, std::string>();
 
@@ -91,19 +151,19 @@ bool VLQ_Selector::Init(){
       MakeSelProp("1el", c_1el_chan) , MakeSelProp("1mu", c_1mu_chan) });
 
   m_sel_jet_prop = new std::vector<SelProp>({
-      MakeSelProp("4jin", c_4jin, "")
-	,MakeSelProp("4jex", c_4jex, "4jin"), MakeSelProp("5jin", c_5jin, "4jin")
-	,MakeSelProp("5jex", c_5jex, "5jin"), MakeSelProp("6jin", c_6jin, "5jin")
-	,MakeSelProp("6_8jin", c_6_8jin, "6jin"), MakeSelProp("7jin", c_7jin, "6jin")
-	,MakeSelProp("6jex", c_6jex, "6_8jin")
-	,MakeSelProp("7jex", c_7jex, "7jin"), MakeSelProp("8jin", c_8jin, "7jin")
-	,MakeSelProp("8jex", c_8jex, "8jin"), MakeSelProp("9jin", c_9jin, "8jin") });
+    MakeSelProp("4jin", c_4jin, "")
+    ,MakeSelProp("4jex", c_4jex, "4jin"), MakeSelProp("5jin", c_5jin, "4jin")
+    ,MakeSelProp("5jex", c_5jex, "5jin"), MakeSelProp("6jin", c_6jin, "5jin")
+    ,MakeSelProp("6_8jwin", c_6_8jwin, "6jin"), MakeSelProp("7jin", c_7jin, "6jin")
+    ,MakeSelProp("6jex", c_6jex, "6_8jwin")
+    ,MakeSelProp("7jex", c_7jex, "7jin"), MakeSelProp("8jin", c_8jin, "7jin")
+    ,MakeSelProp("8jex", c_8jex, "8jin"), MakeSelProp("9jin", c_9jin, "8jin") });
 
   m_sel_bjet_prop = new std::vector<SelProp>({
-      MakeSelProp("0bex", c_0bex, ""), MakeSelProp("1bin", c_1bin, "")
-	,MakeSelProp("1bex", c_1bex, "1bin"), MakeSelProp("2bin", c_2bin, "1bin")
-	,MakeSelProp("2bex", c_2bex, "2bin"), MakeSelProp("3bin", c_3bin, "2bin")
-	,MakeSelProp("3bex", c_3bex, "3bin"), MakeSelProp("4bin", c_4bin, "3bin") });
+    MakeSelProp("0bex", c_0bex, ""), MakeSelProp("1bin", c_1bin, "")
+    ,MakeSelProp("1bex", c_1bex, "1bin"), MakeSelProp("2bin", c_2bin, "1bin")
+    ,MakeSelProp("2bex", c_2bex, "2bin"), MakeSelProp("3bin", c_3bin, "2bin")
+    ,MakeSelProp("3bex", c_3bex, "3bin"), MakeSelProp("4bin", c_4bin, "3bin") });
 
   m_sel_M_prop = new std::vector<SelProp>({
       MakeSelProp("0Mex",c_0Mex), MakeSelProp("1Mex", c_1Mex), MakeSelProp("2Min", c_2Min) });
@@ -112,7 +172,10 @@ bool VLQ_Selector::Init(){
       MakeSelProp("0Tin",c_0Tin), MakeSelProp("0Tex",c_0Tex), MakeSelProp("1Tex", c_1Tex), MakeSelProp("2Tin", c_2Tin) });
 
   m_sel_H_prop = new std::vector<SelProp>({
-      MakeSelProp("0Hex",c_0Hex), MakeSelProp("1Hex", c_1Hex), MakeSelProp("2Hin", c_2Hin) });
+      MakeSelProp("0Hex",c_0Hex), MakeSelProp("1Hex", c_1Hex), MakeSelProp("2Hin", c_2Hin), MakeSelProp("0_1Hwin", c_0_1Hwin) });
+
+  m_sel_TH_prop = new std::vector<SelProp>({
+      MakeSelProp("0THex",c_0THex), MakeSelProp("1THex", c_1THex), MakeSelProp("2THex", c_2THex), MakeSelProp("2THin", c_2THin), MakeSelProp("3THin", c_3THin) });
 
   m_sel_Mbb_prop = new std::vector<SelProp>({
       MakeSelProp("LowMbb",c_LowMbb), MakeSelProp("HighMbb", c_HighMbb) });
@@ -128,90 +191,160 @@ bool VLQ_Selector::Init(){
   for(auto selprop : *m_sel_M_prop){ AddSelectionIndex(selprop.name, selprop.index); }
   for(auto selprop : *m_sel_T_prop){ AddSelectionIndex(selprop.name, selprop.index); }
   for(auto selprop : *m_sel_H_prop){ AddSelectionIndex(selprop.name, selprop.index); }
+  for(auto selprop : *m_sel_TH_prop){ AddSelectionIndex(selprop.name, selprop.index); }
   for(auto selprop : *m_sel_Mbb_prop){ AddSelectionIndex(selprop.name, selprop.index); }
   for(auto selprop : *m_sel_Mtb_prop){ AddSelectionIndex(selprop.name, selprop.index); }
 
   if(m_opt->MsgLevel() == Debug::DEBUG){ std::cout<<"Added all top selections "<<std::endl; }
   //========================== Add desired regions ================================================
 
-  std::vector<std::string> bjet_presellist{"2bin", "2bex", "3bex", "4bin"};
-  if(m_opt->DoLowBRegions()){
-    bjet_presellist.push_back("0bex");
-    bjet_presellist.push_back("1bex");
-  }
+  //======== PRESELECTION=========
+  if(m_do_presel){
 
-  std::vector<std::string> bjet_analist{ "2bex", "3bex", "4bin"};
-
-  std::vector<std::string> boostlist = {
-	"2Tin1Hex", "2Tin0Hex",
-	"1Tex1Hex", "1Tex0Hex",
-	"0Tex1Hex", "0Tex0Hex",
-	"0Tin2Hin" };
-	//"2Tin2Hin", "2Tin1Hex", "2Tin0Hex",
-	//"1Tex2Hin", "1Tex1Hex", "1Tex0Hex",
-	//"0Tex2Hin", "0Tex1Hex", "0Tex0Hex"};
-	if(!onlyFinal){
-		boostlist.push_back("2Min");
-		boostlist.push_back("1Mex");
-		boostlist.push_back("0Mex");
-	}
+    std::vector<std::string> v_bjet_presel = {"2bin"};
+    if(m_do_lowb){
+      v_bjet_presel.push_back("0bex");
+      v_bjet_presel.push_back("1bex");
+    }
 
-  if(m_opt->DoOneLeptonAna()){
-		std::vector<std::string> subchanlist = {""};
-		if(!onlyFinal){
-			subchanlist.push_back("_el");
-			subchanlist.push_back("_mu");
-		}
-		std::vector < std::string > vec_jets = {"5jex", "6jin"};
-		if(!onlyFinal){
-			vec_jets.push_back("5jin");
-			vec_jets.push_back("6_8jin");
-			vec_jets.push_back("9jin");
-		}
-		for( std::string jet : vec_jets ){
-			if(!onlyFinal){
-				for( std::string bjet : bjet_presellist ){
-					for( std::string subchannel : subchanlist ){
-						AddVLQSelection("c1lep"+jet+bjet+subchannel, true, false);
-					}
-				} //presel bjet channels
-			}
-			for( std::string bjet : bjet_analist ){
-				for( std::string boost : boostlist ){
-					AddVLQSelection("c1lep"+boost+jet+bjet, true, false);
-					if(!onlyFinal){
-						AddVLQSelection("c1lep"+boost+jet+bjet+"LowMbb", true, false);
-						AddVLQSelection("c1lep"+boost+jet+bjet+"HighMbb", true, false);
-					}
-				}
-			}//ana bjet channels
-		}//jet
-
-  }//1-lepton
-
-  if(m_opt->DoZeroLeptonAna()){
-
-		for( std::string jet : {"6jex", "7jin"} ){
-			if(!onlyFinal){
-				for( std::string bjet : bjet_presellist ){
-					AddVLQSelection("c0lep"+jet+bjet, true, false);
-				}//presel bjet channels
-			}
-			for( std::string bjet : bjet_analist ){
-				//Split in boost
-				for( std::string boost : boostlist ){
-					AddVLQSelection("c0lep"+boost+jet+bjet, true, false);
-					if(!onlyFinal){
-						AddVLQSelection("c0lep"+boost+jet+bjet+"LowMtbmin", true, false);
-						AddVLQSelection("c0lep"+boost+jet+bjet+"HighMtbmin", true, false);
-					}
-				}
-			}//ana bjet channels
-		}//jet
-
-  }//0-lepton
+    if(m_opt->DoOneLeptonAna()){
+      std::vector<std::string> v_jet_presel = {"5jin"};
+      if(m_do_lowj){
+        v_jet_presel.push_back("4jex");
+        v_jet_presel.push_back("4jin");
+      }
+      for(const std::string& jet : v_jet_presel){
+        for(const std::string& bjet : v_bjet_presel){
+          AddVLQSelection("c1lep"+jet+bjet, true, false);
+          if(m_do_split_emu){
+            AddVLQSelection("c1lep"+jet+bjet+"_el", true, false);
+            AddVLQSelection("c1lep"+jet+bjet+"_mu", true, false);
+          }
+        }//bjet
+      }//jet
+    }//1-lep
+
+    if(m_opt->DoZeroLeptonAna()){
+      std::vector<std::string> v_jet_presel = {"6jin"};
+      if(m_do_lowj){
+        v_jet_presel.push_back("4jex");
+        v_jet_presel.push_back("4jin");
+        v_jet_presel.push_back("5jex");
+        v_jet_presel.push_back("5jin");
+      }
+      for(const std::string& jet : v_jet_presel){
+        for(const std::string& bjet : v_bjet_presel){
+          AddVLQSelection("c0lep"+jet+bjet, true, false);
+        }//bjet
+      }//jet
+    }//0-lep
+
+  }//Preselection regions
+
+  if(m_do_fit_reg || m_do_validn_reg){
+    std::vector<std::string> bjet_analist{ "2bex", "3bex", "4bin"};
+
+    std::vector<std::string> boostlist_1L{};
+    std::vector<std::string> boostlist_0L{};
+
+    if(m_do_old_boost){
+      std::vector<std::string> boostlist_old = {"2Min", "1Mex", "0Mex"};
+      boostlist_1L.insert(boostlist_1L.end(), boostlist_old.begin(), boostlist_old.end());
+      boostlist_0L.insert(boostlist_0L.end(), boostlist_old.begin(), boostlist_old.end());
+    }
+    if(m_do_new_boost){
+      std::vector<std::string> boostlist_new = {
+        "2Tin2Hin", "2Tin1Hex", "2Tin0Hex",
+        "1Tex2Hin", "1Tex1Hex", "1Tex0Hex",
+        "0Tex2Hin", "0Tex1Hex", "0Tex0Hex",
+      };
+      boostlist_0L.insert(boostlist_0L.end(), boostlist_new.begin(), boostlist_new.end());
+    }
+    if(m_do_merge_boost){
+      std::vector<std::string> boostlist_super_merge = {
+        "3THin", "2THex", "1THex", "0THex"
+      };
+      boostlist_0L.insert(boostlist_0L.end(), boostlist_super_merge.begin(), boostlist_super_merge.end());
+
+      std::vector<std::string> boostlist_1L_merge = {
+        "2Tin0_1Hwin",
+        "1Tex1Hex", "1Tex0Hex",
+        "0Tex1Hex", "0Tex0Hex",
+        "0Tin2Hin" };
+
+      if(m_do_validn_reg){
+        boostlist_1L_merge.push_back("2THin");
+      }
+      boostlist_1L.insert(boostlist_1L.end(), boostlist_1L_merge.begin(), boostlist_1L_merge.end());
+      boostlist_0L.insert(boostlist_0L.end(), boostlist_1L_merge.begin(), boostlist_1L_merge.end());
+    }
+
+    //Remove overlaps between different boost options so that any region is only added once
+    std::set<std::string> boostset_1L(boostlist_1L.begin(), boostlist_1L.end());
+    std::set<std::string> boostset_0L(boostlist_0L.begin(), boostlist_0L.end());
+
+    //0-lepton fit regions
+    if(m_opt->DoZeroLeptonAna()){
+      std::vector<std::string> jet_analist_0L{};
+      if(m_do_fit_reg){ jet_analist_0L.push_back("7jin"); }
+      if(m_do_lowj)  {
+        jet_analist_0L.push_back("4jex");
+        jet_analist_0L.push_back("5jex");
+      }
+      if(m_do_validn_reg){
+        jet_analist_0L.push_back("6jex");
+      }
+      for( const std::string& jet : jet_analist_0L ){
+        for( std::string bjet : bjet_analist ){
+          for( std::string boost : boostset_0L ){
+            AddVLQSelection("c0lep"+boost+jet+bjet, true, false);
+            if(m_do_split_mtb){
+              AddVLQSelection("c0lep"+boost+jet+bjet+"LowMtbmin", true, false);
+              AddVLQSelection("c0lep"+boost+jet+bjet+"HighMtbmin", true, false);
+            }//mbb split
+          }//boost list
+        }//ana bjet channels
+      }//jet
+    }//0-lepton
+
+    if(m_opt->DoOneLeptonAna()){
+      std::vector<std::string> jet_analist_1L{};
+      if(m_do_fit_reg){
+        jet_analist_1L.push_back("6jin");
+      }
+      if(m_do_highj)  {
+        jet_analist_1L.push_back("6_8jwin");
+        jet_analist_1L.push_back("9jin");
+      }
+      if(m_do_lowj)  {
+        jet_analist_1L.push_back("4jex");
+      }
+      if(m_do_validn_reg){
+        jet_analist_1L.push_back("5jex");
+      }
+      for( const std::string& jet : jet_analist_1L ){
+        for( const std::string& bjet : bjet_analist ){
+          for( const std::string& boost : boostset_1L ){
+            //Remove the 2TH merging for the fit regions (only in the validation regions)
+            if(boost=="2THin" && (jet!="5jex" || bjet!="4bin") ) continue;
+            //Avoid the too fine splitting in the 4bin VRs
+            if(jet=="5jex" && bjet=="4bin" && ( boost=="1Tex1Hex" || boost=="2Tin0_1Hwin" || boost=="0Tin2Hin" ) ) continue;
+            //otherwise, add the region
+            AddVLQSelection("c1lep"+boost+jet+bjet, true, false);
+            //Only do mbb splitting for old mass-tagged jet regions
+            if(m_do_split_mbb && ( (boost.find("Mex") != std::string::npos) || (boost.find("Min") != std::string::npos) ) ){
+              AddVLQSelection("c1lep"+boost+jet+bjet+"LowMbb", true, false);
+              AddVLQSelection("c1lep"+boost+jet+bjet+"HighMbb", true, false);
+            }//mbb split
+          }//boost list
+        }//ana bjet channels
+      }//jet
+    }//1-lepton
+
+  }//Fit/validation regions
 
   return true;
+
 }
 
 //______________________________________________________________________________
@@ -235,7 +368,6 @@ Selection* VLQ_Selector::AddVLQSelection(const std::string& name, bool do_runop,
 //______________________________________________________________________________
 //
 Selection* VLQ_Selector::MakeSelection(const int index, const std::string& name){
-
   if(m_opt->MsgLevel() == Debug::DEBUG){ std::cout<<" VLQ_Selector::MakeSelection with name "<<name<<" and index "<<index<<std::endl; }
 
   if( (index < 0) && name.empty() ){
@@ -256,128 +388,150 @@ Selection* VLQ_Selector::MakeSelection(const int index, const std::string& name)
   SelProp* sprop_M = NULL;
   SelProp* sprop_T = NULL;
   SelProp* sprop_H = NULL;
+  SelProp* sprop_TH = NULL;
   SelProp* sprop_Mbb = NULL;
   SelProp* sprop_Mtb = NULL;
 
   //=============== Lepton part =====================
-	if(sel_name.find("lep") != std::string::npos){
-		for(SelProp lepprop : *m_sel_lep_prop){
-			if( sel_name.find(lepprop.name) != std::string::npos ){
-				sprop_lep = &lepprop;
-				break;
-			}
-		}
-		if(sprop_lep == NULL){
-			std::cerr << " Cannnot identify lepton channel for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
+  if(sel_name.find("lep") != std::string::npos){
+    for(SelProp lepprop : *m_sel_lep_prop){
+      if( sel_name.find(lepprop.name) != std::string::npos ){
+	sprop_lep = &lepprop;
+	break;
+      }
+    }
+    if(sprop_lep == NULL){
+      std::cerr << " Cannnot identify lepton channel for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
 	}
   //=============== Jet part ========================
-	if( (sel_name.find("jin") != std::string::npos) || (sel_name.find("jex") != std::string::npos) ){
-
-		for(SelProp jetprop : *m_sel_jet_prop){
-			if( sel_name.find(jetprop.name) != std::string::npos ){
-				sprop_jet = &jetprop;
-				break;
-			}
-		}
-		if(sprop_jet == NULL){
-			std::cerr << " Cannnot identify jet multiplicity requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  if( (sel_name.find("jin") != std::string::npos) || (sel_name.find("jex") != std::string::npos) ){
+
+    for(SelProp jetprop : *m_sel_jet_prop){
+      if( sel_name.find(jetprop.name) != std::string::npos ){
+        sprop_jet = &jetprop;
+        break;
+      }
+    }
+    if(sprop_jet == NULL){
+      std::cerr << " Cannnot identify jet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
   //=============== B-jet part ========================
   //if(sel_name.find("b") != std::string::npos){
-	if( (sel_name.find("bin") != std::string::npos) || (sel_name.find("bex") != std::string::npos) ){
-		for(SelProp bjetprop : *m_sel_bjet_prop){
-			if( sel_name.find(bjetprop.name) != std::string::npos ){
-				sprop_bjet = &bjetprop;
-				break;
-			}
-		}
-		if(sprop_bjet == NULL){
-			std::cerr << " Cannnot identify bjet multiplicity requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  if( (sel_name.find("bin") != std::string::npos) || (sel_name.find("bex") != std::string::npos) ){
+    for(SelProp bjetprop : *m_sel_bjet_prop){
+      if( sel_name.find(bjetprop.name) != std::string::npos ){
+        sprop_bjet = &bjetprop;
+        break;
+      }
+    }
+    if(sprop_bjet == NULL){
+      std::cerr << " Cannnot identify bjet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
 
   //============== M-tag part =========================
-	if( (sel_name.find("Min") != std::string::npos) || (sel_name.find("Mex") != std::string::npos) ){
-		for(SelProp Mprop : *m_sel_M_prop){
-			if( sel_name.find(Mprop.name) != std::string::npos ){
-				sprop_M = &Mprop;
-				break;
-			}
-		}
-		if(sprop_M == NULL){
-			std::cerr << " Cannnot identify M-tagged jet multiplicity requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  if( (sel_name.find("Min") != std::string::npos) || (sel_name.find("Mex") != std::string::npos) ){
+    for(SelProp Mprop : *m_sel_M_prop){
+      if( sel_name.find(Mprop.name) != std::string::npos ){
+        sprop_M = &Mprop;
+        break;
+      }
+    }
+    if(sprop_M == NULL){
+      std::cerr << " Cannnot identify M-tagged jet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
+
+  //============== TH-tag part =========================
+  if( (sel_name.find("THin") != std::string::npos) || (sel_name.find("THex") != std::string::npos) ){
+    for(SelProp THprop : *m_sel_TH_prop){
+      if( sel_name.find(THprop.name) != std::string::npos ){
+        sprop_TH = &THprop;
+        break;
+      }
+    }
+    if(sprop_TH == NULL){
+      std::cerr << " Cannnot identify TH-tagged jet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
 
   //============== T-tag part =========================
-	if( (sel_name.find("Tin") != std::string::npos) || (sel_name.find("Tex") != std::string::npos) ){
-		for(SelProp Tprop : *m_sel_T_prop){
-			if( sel_name.find(Tprop.name) != std::string::npos ){
-				sprop_T = &Tprop;
-				break;
-			}
-		}
-		if(sprop_T == NULL){
-			std::cerr << " Cannnot identify T-tagged jet multiplicity requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  //Check that the character preceding "T" is a digit
+  if( ( (sel_name.find("Tin") != std::string::npos) && (std::isdigit(sel_name.substr(sel_name.find("Tin")-1)[0] )) )
+      || ( (sel_name.find("Tex") != std::string::npos) && (std::isdigit(sel_name.substr(sel_name.find("Tex")-1)[0] )) ) ){
+    for(SelProp Tprop : *m_sel_T_prop){
+      if( sel_name.find(Tprop.name) != std::string::npos ){
+        sprop_T = &Tprop;
+        break;
+      }
+    }
+    if(sprop_T == NULL){
+      std::cerr << " Cannnot identify T-tagged jet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
 
   //============== H-tag part =========================
-	if( (sel_name.find("Hin") != std::string::npos) || (sel_name.find("Hex") != std::string::npos) ){
-		for(SelProp Hprop : *m_sel_H_prop){
-			if( sel_name.find(Hprop.name) != std::string::npos ){
-				sprop_H = &Hprop;
-				break;
-			}
-		}
-		if(sprop_H == NULL){
-			std::cerr << " Cannnot identify H-tagged jet multiplicity requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  //Check that the character preceding "H" is a digit (to distinguish this option from "TH"
+  if( ( (sel_name.find("Hin") != std::string::npos) && (std::isdigit(sel_name.substr(sel_name.find("Hin")-1)[0] )) )
+      || ( (sel_name.find("Hex") != std::string::npos) && (std::isdigit(sel_name.substr(sel_name.find("Hex")-1)[0] )) )
+      || ( (sel_name.find("Hwin") != std::string::npos) && (std::isdigit(sel_name.substr(sel_name.find("Hwin")-1)[0] )) ) ){
+    for(SelProp Hprop : *m_sel_H_prop){
+      if( sel_name.find(Hprop.name) != std::string::npos ){
+        sprop_H = &Hprop;
+        break;
+      }
+    }
+    if(sprop_H == NULL){
+      std::cerr << " Cannnot identify H-tagged jet multiplicity requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
+
 
   //============== Mbb part =========================
-	if(sel_name.find("Mbb") != std::string::npos){
-		for(SelProp Mbbprop : *m_sel_Mbb_prop){
-			if( sel_name.find(Mbbprop.name) != std::string::npos ){
-				sprop_Mbb = &Mbbprop;
-				break;
-			}
-		}
-		if(sprop_Mbb == NULL){
-			std::cerr << " Cannnot identify Mbb requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  if(sel_name.find("Mbb") != std::string::npos){
+    for(SelProp Mbbprop : *m_sel_Mbb_prop){
+      if( sel_name.find(Mbbprop.name) != std::string::npos ){
+        sprop_Mbb = &Mbbprop;
+        break;
+      }
+    }
+    if(sprop_Mbb == NULL){
+      std::cerr << " Cannnot identify Mbb requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
 
   //============== Mtb part =========================
-	if(sel_name.find("Mtb") != std::string::npos){
-		for(SelProp Mtbprop : *m_sel_Mtb_prop){
-			if( sel_name.find(Mtbprop.name) != std::string::npos ){
-				sprop_Mtb = &Mtbprop;
-				break;
-			}
-		}
-		if(sprop_Mtb == NULL){
-			std::cerr << " Cannnot identify Mtb requirements for selection "<<name<<std::endl;
-			return NULL;
-		}
-		n_nodes++;
-	}
+  if(sel_name.find("Mtb") != std::string::npos){
+    for(SelProp Mtbprop : *m_sel_Mtb_prop){
+      if( sel_name.find(Mtbprop.name) != std::string::npos ){
+        sprop_Mtb = &Mtbprop;
+        break;
+      }
+    }
+    if(sprop_Mtb == NULL){
+      std::cerr << " Cannnot identify Mtb requirements for selection "<<name<<std::endl;
+      return NULL;
+    }
+    n_nodes++;
+  }
 
   //============================= Only certain selection patterns are currently allowed =========================
   if( (n_nodes > 1) && !sprop_lep ){ //If no lepton channel found for a compound selection
@@ -389,10 +543,10 @@ Selection* VLQ_Selector::MakeSelection(const int index, const std::string& name)
     return NULL;
   }
 
-  if( !( (sprop_M==NULL) || ( (sprop_T==NULL) && (sprop_H==NULL) ) ) ){
+  if( !( (sprop_M==NULL) || ( (sprop_T==NULL) &&  (sprop_H==NULL) &&  (sprop_TH==NULL) ) ) ){
     std::cerr << " It is inadvisable to apply M-tagged jet cut together ";
-		std::cerr << "with a cut on T-tagging or H-tagging. Please check selection pattern ";
-	  std::cerr << name << ". Exiting. "<<std::endl;
+    std::cerr << "with a cut on T-tagging or H-tagging. Please check selection pattern ";
+    std::cerr << name << ". Exiting. "<<std::endl;
     return NULL;
   }
 
@@ -407,55 +561,57 @@ Selection* VLQ_Selector::MakeSelection(const int index, const std::string& name)
     AddAncestor(*sel, sel_name.substr(0, sel_name.find("_")), true);
     if(sel_name.find("_el") != std::string::npos){ SelectorBase::AddAncestor(*sel, c_1el_chan); }
     else if(sel_name.find("_mu") != std::string::npos){ SelectorBase::AddAncestor(*sel, c_1mu_chan); }
-	}//el/mu channel splitting is done last
-	else{
-		if( !(sprop_bjet || sprop_M || sprop_T || sprop_H || sprop_Mbb || sprop_Mtb)  ){
-
-			if(sprop_jet->primanc_name.empty()){
-				SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index}, sprop_lep->index);
-			}
-			else{
-				AddPrimary(*sel, "c"+sprop_lep->name+sprop_jet->primanc_name);
-				SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index});
-			}
-
-		}//Lep + jet
-		else if( !(sprop_M || sprop_T || sprop_H || sprop_Mbb || sprop_Mtb) ){
-
-			if(sprop_bjet->primanc_name.empty()){
-				AddAncestor(*sel, "c"+sprop_lep->name+sprop_jet->name, true);
-			}
-			else{
-				AddPrimary(*sel, "c"+sprop_lep->name+sprop_jet->name+sprop_bjet->primanc_name);
-				SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index, sprop_bjet->index});
-			}
-		} //Lep + jet + bjet
-		else if( !(sprop_Mbb || sprop_Mtb) ){
-			AddAncestor(*sel, "c"+sprop_lep->name+sprop_jet->name+sprop_bjet->name, true);
-			if(sprop_M){ SelectorBase::AddAncestor(*sel, sprop_M->index); }
-			else{
-				if(sprop_T ){ SelectorBase::AddAncestor(*sel, sprop_T->index); }
-				if(sprop_H ){ SelectorBase::AddAncestor(*sel, sprop_H->index); }
-			}
-		}//Lep-jet-bjet + boost
-		else{
-			std::string s_boost = "";
-			if(sprop_M){s_boost += sprop_M->name; }
-			if(sprop_T){s_boost += sprop_T->name; }
-			if(sprop_H){s_boost += sprop_H->name; }
-
-			if(sprop_Mbb){
-				AddAncestor(*sel, "c" + sprop_lep->name + s_boost + sprop_jet->name + sprop_bjet->name, true);
-				SelectorBase::AddAncestor(*sel, sprop_Mbb->index);
-			}
-			else if(sprop_Mtb){
-				AddAncestor(*sel, "c" + sprop_lep->name + s_boost + sprop_jet->name + sprop_bjet->name, true);
-				SelectorBase::AddAncestor(*sel, sprop_Mtb->index);
-			}
-		}
-		if(m_opt->MsgLevel() == Debug::DEBUG){ std::cout<<" Selection "<<sel_name<<" successfully added"<<std::endl; }
-
-	}//if not el or mu channel
+  }//el/mu channel splitting is done last
+  else{
+    if( !(sprop_bjet || sprop_M || sprop_TH|| sprop_T || sprop_H || sprop_Mbb || sprop_Mtb)  ){
+
+      if(sprop_jet->primanc_name.empty()){
+        SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index}, sprop_lep->index);
+      }
+      else{
+        AddPrimary(*sel, "c"+sprop_lep->name+sprop_jet->primanc_name);
+        SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index});
+      }
+
+    }//Lep + jet
+    else if( !(sprop_M || sprop_TH || sprop_T || sprop_H || sprop_Mbb || sprop_Mtb) ){
+
+      if(sprop_bjet->primanc_name.empty()){
+        AddAncestor(*sel, "c"+sprop_lep->name+sprop_jet->name, true);
+      }
+      else{
+        AddPrimary(*sel, "c"+sprop_lep->name+sprop_jet->name+sprop_bjet->primanc_name);
+        SelectorBase::AddAncestors(*sel, {sprop_lep->index, sprop_jet->index, sprop_bjet->index});
+      }
+    } //Lep + jet + bjet
+    else if( !(sprop_Mbb || sprop_Mtb) ){
+      AddAncestor(*sel, "c"+sprop_lep->name+sprop_jet->name+sprop_bjet->name, true);
+      if(sprop_M){ SelectorBase::AddAncestor(*sel, sprop_M->index); }
+      else{
+        if(sprop_T ){ SelectorBase::AddAncestor(*sel, sprop_T->index); }
+        if(sprop_H ){ SelectorBase::AddAncestor(*sel, sprop_H->index); }
+        if(sprop_TH ){ SelectorBase::AddAncestor(*sel, sprop_TH->index); }
+      }
+    }//Lep-jet-bjet + boost
+    else{
+      std::string s_boost = "";
+      if(sprop_M){s_boost += sprop_M->name; }
+      if(sprop_T){s_boost += sprop_T->name; }
+      if(sprop_H){s_boost += sprop_H->name; }
+      if(sprop_TH){s_boost += sprop_TH->name; }
+
+      if(sprop_Mbb){
+        AddAncestor(*sel, "c" + sprop_lep->name + s_boost + sprop_jet->name + sprop_bjet->name, true);
+        SelectorBase::AddAncestor(*sel, sprop_Mbb->index);
+      }
+      else if(sprop_Mtb){
+        AddAncestor(*sel, "c" + sprop_lep->name + s_boost + sprop_jet->name + sprop_bjet->name, true);
+        SelectorBase::AddAncestor(*sel, sprop_Mtb->index);
+      }
+    }
+    if(m_opt->MsgLevel() == Debug::DEBUG){ std::cout<<" Selection "<<sel_name<<" successfully added"<<std::endl; }
+
+  }//if not el or mu channel
 
   return sel;
 }
@@ -504,7 +660,7 @@ bool VLQ_Selector::PassSelection(const int index){
   else if(index == c_7jex){ pass = (m_outData->o_jets_n == 7); }
   else if(index == c_8jex){ pass = (m_outData->o_jets_n == 8); }
 
-  else if(index == c_6_8jin){ pass = (m_outData->o_jets_n >= 6) && (m_outData->o_jets_n <= 8); }
+  else if(index == c_6_8jwin){ pass = (m_outData->o_jets_n >= 6) && (m_outData->o_jets_n <= 8); }
 
   else if(index == c_4jin){ pass = (m_outData->o_jets_n >= 4); }
   else if(index == c_5jin){ pass = (m_outData->o_jets_n >= 5); }
@@ -530,7 +686,13 @@ bool VLQ_Selector::PassSelection(const int index){
   else if(index == c_1Hex){ pass = (m_outData->o_taggedjets_n.at("RCMHiggs") == 1); }
   else if(index == c_1Hin){ pass = (m_outData->o_taggedjets_n.at("RCMHiggs") >= 1); }
   else if(index == c_2Hin){ pass = (m_outData->o_taggedjets_n.at("RCMHiggs") >= 2); }
+  else if(index == c_0_1Hwin){ pass = (m_outData->o_taggedjets_n.at("RCMHiggs") == 0 || m_outData->o_taggedjets_n.at("RCMHiggs") == 1); }
 
+  else if(index == c_0THex){ pass = (m_outData->o_taggedjets_n.at("RCMTop")+m_outData->o_taggedjets_n.at("RCMHiggs") == 0); }
+  else if(index == c_1THex){ pass = (m_outData->o_taggedjets_n.at("RCMTop")+m_outData->o_taggedjets_n.at("RCMHiggs") == 1); }
+  else if(index == c_2THex){ pass = (m_outData->o_taggedjets_n.at("RCMTop")+m_outData->o_taggedjets_n.at("RCMHiggs") == 2); }
+  else if(index == c_2THin){ pass = (m_outData->o_taggedjets_n.at("RCMTop")+m_outData->o_taggedjets_n.at("RCMHiggs") >= 2); }
+  else if(index == c_3THin){ pass = (m_outData->o_taggedjets_n.at("RCMTop")+m_outData->o_taggedjets_n.at("RCMHiggs") >= 3); }
 
   //=========== B-tag multiplicities ====================
   else if(index == c_0bex){ pass = m_anaTools->PassBTagRequirement(0, false); }
diff --git a/Root/VLQ_WeightManager.cxx b/Root/VLQ_WeightManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..358e914aab5edd05d4e179b5ac144ab5bc60802b
--- /dev/null
+++ b/Root/VLQ_WeightManager.cxx
@@ -0,0 +1,585 @@
+#include "VLQAnalysis/VLQ_WeightManager.h"
+
+//#include "IFAETopFramework/WeightManager.h"
+#include "IFAETopFramework/SampleInfo.h"
+#include "IFAETopFramework/AnalysisObject.h"
+
+#include "VLQAnalysis/VLQ_Options.h"
+#include "VLQAnalysis/VLQ_NtupleData.h"
+#include "VLQAnalysis/VLQ_OutputData.h"
+#include "VLQAnalysis/VLQ_Enums.h"
+#include "VLQAnalysis/VLQ_QCDWeight.h"
+#include "VLQAnalysis/VLQ_TtbarSystematicsManager.h"
+#include "VLQAnalysis/VLQ_VariableComputer.h"
+
+#include "IFAEReweightingTools/HFSystDataMembers.h"
+#include "IFAEReweightingTools/ttbbNLO_syst.h"
+#include "IFAEReweightingTools/ttccNLO_syst.h"
+#include "IFAEReweightingTools/TtbarFractionReweighter.h"
+
+
+#include <iostream>
+#include <stdexcept> // invalid_argument
+#include <string>
+
+using std::string;
+
+
+//_____________________________________________________________________________________
+//
+VLQ_WeightManager::VLQ_WeightManager( VLQ_Options *opt, const VLQ_NtupleData* ntupleData, VLQ_OutputData* outputData ):
+  WeightManager(opt, ntupleData, outputData),
+  m_vlq_opt(opt),
+  m_vlq_ntupData(ntupleData),
+  m_vlq_outData(outputData),
+  //m_weightMngr(weightManager),
+  m_sampleInfo(0),
+  m_qcdWeight(0),
+  m_varComputer(0),
+  m_tool_HFsyst(0),
+  m_tool_ttFractionRw(0),
+  m_ttbar_syst_weight(0)
+{
+    ///////////////////////////////////////
+    // Cross-section weight
+    ///////////////////////////////////////
+  if ( !(m_vlq_opt -> IsData() || (m_vlq_opt -> SampleName() == SampleName::QCD)) ) {
+        std::string path = "";
+        path += std::getenv("ROOTCOREBIN") + std::string("/data/VLQAnalysis/samples_info.dat");
+        string sampleId = opt -> StrSampleID();
+        m_sampleInfo = new SampleInfo( sampleId, path );
+        if(!m_sampleInfo->Ready()){
+            throw std::invalid_argument(string(__FILE__)+"\n"+
+                                        " Could not identify sample '"+sampleId+"'"
+                                        " in the provided config file '"+path+"'. \n"
+                                        " Please check !"
+                                        " Normalisation will be crap !");
+        }
+    }
+
+    //////////////////////////////////////
+    // QCD weight tool
+    //////////////////////////////////////
+    m_qcdWeight     = new VLQ_QCDWeight();
+    m_varComputer   = new VLQ_VariableComputer(m_vlq_opt);
+
+    //
+    // ttbar-related
+    //
+    if(m_vlq_opt -> SampleName() == SampleName::TTBARBB || m_vlq_opt -> SampleName() == SampleName::TTBARCC ||
+       m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT || m_vlq_opt -> SampleName() == SampleName::TTBAR ){
+
+        //////////////////////////////////////
+        // tt+bb reweighting tool
+        //////////////////////////////////////
+
+        // Declaration of ttbb_syst class
+        if( m_vlq_opt -> RecomputeTtBbRw () ){
+            m_tool_HFsyst = new ttbbNLO_syst( m_vlq_opt -> StrSampleID(),std::getenv("ROOTCOREBIN")+std::string("/data/IFAEReweightingTools/ttbbNormRw.root"),
+                                              std::getenv("ROOTCOREBIN")+std::string("/data/IFAEReweightingTools/ttbbShapeRw.root"));
+            m_tool_HFsyst -> Init();
+        }
+
+        // Declaration of Ttbar Fraction Rw tool
+        if( m_vlq_opt -> ReweightTtbarFractions () ){
+            m_tool_ttFractionRw = new TtbarFractionReweighter(m_vlq_opt -> StrSampleID(), std::getenv("ROOTCOREBIN")+std::string("/data/IFAEReweightingTools/TtbarHFFractions_Rw.root"));
+            m_tool_ttFractionRw -> Init();
+        }
+
+        //////////////////////////////////////
+        // ttbar systematic uncertainties (generator comparisons)
+        //////////////////////////////////////
+
+        m_ttbar_syst_weight = new VLQ_TtbarSystematicsManager( m_vlq_opt, m_vlq_outData, m_vlq_ntupData );
+        m_ttbar_syst_weight -> Init(std::getenv("ROOTCOREBIN")+std::string("/data/VLQAnalysis/ttbarSystematics.root"));
+
+    }
+}
+
+//_____________________________________________________________________________________
+//
+VLQ_WeightManager::VLQ_WeightManager( const VLQ_WeightManager &q ) : WeightManager(q) {
+    m_vlq_opt               = q.m_vlq_opt;
+    m_vlq_ntupData          = q.m_vlq_ntupData;
+    m_vlq_outData           = q.m_vlq_outData;
+    //m_weightMngr        = q.m_weightMngr;
+
+    m_sampleInfo        = q.m_sampleInfo;
+    m_qcdWeight         = q.m_qcdWeight;
+    m_varComputer       = q.m_varComputer;
+    m_tool_HFsyst       = q.m_tool_HFsyst;
+    m_tool_ttFractionRw = q.m_tool_ttFractionRw;
+    m_ttbar_syst_weight = q.m_ttbar_syst_weight;
+}
+
+//_____________________________________________________________________________________
+//
+VLQ_WeightManager::~VLQ_WeightManager(){
+    if(m_sampleInfo) delete m_sampleInfo;
+    if(m_qcdWeight) delete m_qcdWeight;
+    if(m_varComputer) delete m_varComputer;
+    if(m_tool_HFsyst) delete m_tool_HFsyst;
+    if(m_tool_ttFractionRw) delete m_tool_ttFractionRw;
+    if(m_ttbar_syst_weight) delete m_ttbar_syst_weight;
+}
+
+/*
+//                                                                                                                                                                                                      
+// Declaration of the WeightManager, and reading in of nominal and systematic weight components                                                                                                         
+//                                                                                                                                                                                                      
+if(m_vlq_opt -> MsgLevel() == Debug::DEBUG) std::cout << "Declaring WeightManager" << std::endl;
+m_weightMngr = new WeightManager( m_vlq_opt, m_vlq_ntupData, m_vlq_outData );
+m_weightMngr    ->  SetConfigBlock( "ISQCD", ( m_vlq_opt -> SampleName() == SampleName::QCD ) );
+m_weightMngr    ->  SetConfigBlock( "USEPUWEIGHT", m_vlq_opt -> UsePileUpWeight() );
+m_weightMngr    ->  SetConfigBlock( "USELEPTONSF", m_vlq_opt -> UseLeptonsSF() );
+m_weightMngr    ->  SetConfigBlock( "USELEPTONTRIGGERSF", m_vlq_opt -> UseLeptonTrigger() );
+m_weightMngr    ->  SetConfigBlock( "RECOMPUTEBTAGGINGWEIGHTS", (m_vlq_opt -> DoTRF() && m_vlq_opt -> RecomputeTRF()) || m_vlq_opt -> RecomputeBtagSF() );
+m_weightMngr    ->  SetConfigBlock( "RUNLEPTONSYSTEMATICS", m_vlq_opt -> ComputeWeightSys() );
+
+bool isTtbar =  (m_vlq_opt -> SampleName() == SampleName::TTBAR) || (m_vlq_opt -> SampleName() == SampleName::TTBARBB)
+  || (m_vlq_opt -> SampleName() == SampleName::TTBARCC) || (m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT);
+
+bool isVjets22 = ( (m_vlq_opt -> StrSampleName().find("W+JETS22") != std::string::npos)
+		   || (m_vlq_opt -> StrSampleName().find("Z+JETS22") != std::string::npos) );
+m_weightMngr    ->  SetConfigBlock( "SCALETTBARHTSLICES", isTtbar && m_vlq_opt -> ScaleTtbarHtSlices() );
+m_weightMngr    ->  SetConfigBlock( "USETTBBCORRECTION", isTtbar && m_vlq_opt -> ApplyTtbbCorrection() );
+m_weightMngr    ->  SetConfigBlock( "USETTBARFRACTIONSREWEIGHTING", isTtbar && m_vlq_opt -> ReweightTtbarFractions() );
+m_weightMngr    ->  SetConfigBlock( "ISTTBAR", isTtbar );
+m_weightMngr    ->  SetConfigBlock( "USETTBARNNLOREWEIGHTING", isTtbar && m_vlq_opt -> ApplyTtbarNNLOCorrection() );
+m_weightMngr    ->  SetConfigBlock( "COMPUTETTCCNLO", isTtbar && m_vlq_opt -> ComputeTtccNLO() );
+m_weightMngr    ->  SetConfigBlock( "USEVJETSSHERPA22RW", isVjets22 && m_vlq_opt -> ApplyVjetsSherpa22RW() );
+
+
+ //weight_WZ_2_2   = 0
+ //weight_btag     = 0
+ //weight_elec     = 0
+ //weight_elec_trigger = 0
+ //weight_jvt      = 0
+ //weight_mc       = 0
+ //weight_muon     = 0
+ //weight_muon_trigger = 0
+ //weight_pu       = 0
+ //weight_ttbar_NNLO = 0
+ //weight_ttbar_NNLO_1L = 0
+
+*/
+
+
+//_____________________________________________________________________________________
+//
+bool VLQ_WeightManager::AddVLQNominalWeights(){
+
+  if( m_vlq_opt -> SampleName() == SampleName::QCD ){
+    AddAndInitWeight("weight_qcd", "", true, false);
+  }
+  else{
+
+    AddAndInitWeight("weight_mc");
+    AddAndInitWeight("weight_jvt");
+
+    AddAndInitWeight("weight_norm", "", true, false);
+
+    if(m_vlq_opt->UsePileUpWeight()){ AddAndInitWeight("weight_pu"); } 
+
+    if(m_vlq_opt->UseLeptonsSF()){
+      AddAndInitWeight("weight_elec");
+      AddAndInitWeight("weight_muon");
+      if(m_vlq_opt->UseLeptonTrigger()){
+	AddAndInitWeight("weight_elec_trigger");
+	AddAndInitWeight("weight_muon_trigger");
+      }
+    }
+
+    if((m_vlq_opt -> DoTRF() && m_vlq_opt -> RecomputeTRF()) || m_vlq_opt -> RecomputeBtagSF()){
+      AddAndInitWeight("weight_btag_recomputed", "", true, false);
+    }
+    else{
+      AddAndInitWeight("weight_btag");
+    }
+
+    if( (m_vlq_opt -> SampleName() == SampleName::TTBAR) || (m_vlq_opt -> SampleName() == SampleName::TTBARBB)
+	|| (m_vlq_opt -> SampleName() == SampleName::TTBARCC) || (m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT) ){
+      
+      if(m_vlq_opt->ApplyTtbbCorrection()){
+	AddAndInitWeight("weight_ttbb", "weight_ttbb_ttbb_Nominal_weight");
+      }
+      
+      if(m_vlq_opt->ReweightTtbarFractions()){
+	AddAndInitWeight("weight_ttbar_fractions_rw", "", true, false);
+      }
+      
+      if(m_vlq_opt->ApplyTtbarNNLOCorrection()){
+	AddAndInitWeight("weight_ttbar_NNLO");
+      }
+    }//ttbar
+    if( (m_vlq_opt -> StrSampleName().find("W+JETS22") != std::string::npos)
+	|| (m_vlq_opt -> StrSampleName().find("Z+JETS22") != std::string::npos) ){
+      AddAndInitWeight("weight_WZ_2_2");
+    }
+
+  }//!QCD
+  
+  
+  return true;
+}
+
+
+//_____________________________________________________________________________________
+//
+bool VLQ_WeightManager::AddVLQSystematicWeights(){
+  
+  AddAndInitWeight("weight_jvt_UP", "", false, true, "weight_jvt_JET_JvtEfficiency__1up", "weight_jvt");
+  AddAndInitWeight("weight_jvt_DOWN", "", false, true, "weight_jvt_JET_JvtEfficiency__1down", "weight_jvt");
+
+  if(m_vlq_opt->UsePileUpWeight()){
+    AddAndInitWeight("weight_pu_UP", "", false, true, "weight_pu_PRW_DATASF__1up", "weight_pu");
+    AddAndInitWeight("weight_pu_DOWN", "", false, true, "weight_pu_PRW_DATASF__1down", "weight_pu");
+  }
+
+  if(m_vlq_opt->UseLeptonsSF()){
+
+    std::vector<std::string> el_sys_comp = {"Reco", "ID", "Iso" };
+    for(const std::string& el_sys : el_sys_comp){
+      AddAndInitWeight("weight_elec_"+el_sys+"_UP", "", false, true, "weight_elec_EL_EFF_"+el_sys+"_TOTAL_1NPCOR_PLUS_UNCOR__1up", "weight_elec");
+      AddAndInitWeight("weight_elec_"+el_sys+"_DOWN", "", false, true, "weight_elec_EL_EFF_"+el_sys+"_TOTAL_1NPCOR_PLUS_UNCOR__1down", "weight_elec");
+    }
+
+    std::map<std::string, std::vector<std::string> > mu_sys_comp = { 
+      {"EFF", {"STAT", "SYS", "STAT_LOWPT", "SYS_LOWPT"}}, 
+      {"ISO",{"STAT", "SYS"}}, 
+      {"TTVA", {"STAT", "SYS"}} 
+    };
+    for(std::pair<std::string, std::vector<std::string> > mu_sys_pair : mu_sys_comp){
+
+      for(const std::string& mu_sys : mu_sys_pair.second){
+	AddAndInitWeight("weight_muon_"+mu_sys_pair.first+"_"+mu_sys+"_UP","",false, true, "weight_muon_MUON_"+mu_sys_pair.first+"_"+mu_sys+"__1up", "weight_muon");  
+	AddAndInitWeight("weight_muon_"+mu_sys_pair.first+"_"+mu_sys+"_DOWN","",false, true, "weight_muon_MUON_"+mu_sys_pair.first+"_"+mu_sys+"__1down", "weight_muon");  
+      }
+
+    }
+
+    if(m_vlq_opt->UseLeptonTrigger()){
+
+      std::vector<std::string> el_trig_sys_comp = {"TriggerEff", "Trigger"};
+      for(const std::string& el_trig_sys : el_trig_sys_comp){
+	AddAndInitWeight("weight_elec_"+el_trig_sys+"_UP", "", false, true, "weight_elec_trigger_EL_EFF_"+el_trig_sys+"_TOTAL_1NPCOR_PLUS_UNCOR__1up", "weight_elec_trigger");
+	AddAndInitWeight("weight_elec_"+el_trig_sys+"_DOWN", "", false, true, "weight_elec_trigger_EL_EFF_"+el_trig_sys+"_TOTAL_1NPCOR_PLUS_UNCOR__1down", "weight_elec_trigger");
+      }
+      std::vector<std::string> mu_trig_sys_comp = {"TrigStatUncertainty", "TrigSystUncertainty"};
+      for(const std::string& mu_trig_sys : mu_trig_sys_comp){
+	AddAndInitWeight("weight_muon_"+mu_trig_sys+"_UP", "", false, true, "weight_muon_trigger_MUON_EFF_"+mu_trig_sys+"__1up", "weight_muon_trigger");
+	AddAndInitWeight("weight_muon_"+mu_trig_sys+"_DOWN", "", false, true, "weight_muon_trigger_MUON_EFF_"+mu_trig_sys+"__1down", "weight_muon_trigger");
+      }
+
+    }//trigger
+
+  }//lepton SF
+
+
+  std::string btag_name = ""; 
+  std::string btag_vartype = "";
+  bool btag_isinput = true; 
+  if((m_vlq_opt -> DoTRF() && m_vlq_opt -> RecomputeTRF()) || m_vlq_opt -> RecomputeBtagSF()){
+    btag_name = "weight_btag_recomputed";
+    btag_isinput = false;
+  }
+  else{
+    btag_name = "weight_btag"; 
+  }
+
+  for(int i = 0; i <=4; i++ ){
+    AddAndInitWeight(Form("%s_B_EV_Up_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_B_%i__1up",i), btag_name); 
+    AddAndInitWeight(Form("%s_B_EV_Down_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_B_%i__1down",i), btag_name); 
+  }
+
+  for(int i = 0; i <=3; i++ ){
+    AddAndInitWeight(Form("%s_C_EV_Up_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_C_%i__1up",i), btag_name); 
+    AddAndInitWeight(Form("%s_C_EV_Down_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_C_%i__1down",i), btag_name); 
+  }
+
+  for(int i = 0; i <=13; i++ ){
+    AddAndInitWeight(Form("%s_Light_EV_Up_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_Light_%i__1up",i), btag_name); 
+    AddAndInitWeight(Form("%s_Light_EV_Down_%i",btag_name.c_str(),i), "", false, btag_isinput, Form("weight_btag_FT_EFF_Eigen_Light_%i__1down",i), btag_name); 
+  }
+
+  AddAndInitWeight(btag_name+"_extrapolation_Up", "", false, btag_isinput, "weight_btag_FT_EFF_extrapolation__1up", btag_name); 
+  AddAndInitWeight(btag_name+"_extrapolation_Down", "", false, btag_isinput, "weight_btag_FT_EFF_extrapolation__1down", btag_name); 
+
+  AddAndInitWeight(btag_name+"_extrapolation_from_charm_Up", "", false, btag_isinput, "weight_btag_FT_EFF_extrapolation_from_charm__1up", btag_name); 
+  AddAndInitWeight(btag_name+"_extrapolation_from_charm_Down", "", false, btag_isinput, "weight_btag_FT_EFF_extrapolation_from_charm__1down", btag_name); 
+
+  if( (m_vlq_opt -> SampleName() == SampleName::TTBAR) || (m_vlq_opt -> SampleName() == SampleName::TTBARBB)
+      || (m_vlq_opt -> SampleName() == SampleName::TTBARCC) || (m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT) ){
+    
+    std::vector<std::string> ttbar_sys_comp = {"PS", "GEN", "GENPS", "RADHI", "RADLOW"};
+    for(const std::string& ttbar_sys : ttbar_sys_comp){
+      AddAndInitWeight("weight_ttbar_"+ttbar_sys,"",false, false, "", "weight_ttbar_NNLO");
+    }
+    
+    if(m_vlq_opt->ApplyTtbbCorrection()){
+
+      std::vector<std::string> ttbb_sys_comp = {"CSS_KIN", "MSTW", "NNPDF", "Q_CMMPS", "glosoft", "defaultX05", "defaultX2", "MPIup", "MPIdown", "MPIfactor", "aMcAtNloHpp", "aMcAtNloPy8"};
+      for(const std::string& ttbb_sys : ttbb_sys_comp){
+	AddAndInitWeight("weight_ttbb_"+ttbb_sys, "", false, false, "weight_ttbb_ttbb_"+ttbb_sys+"_weight", "weight_ttbb");
+      }
+ 
+    }//ttbb correction
+
+  }//ttbar samples
+
+
+  return true;
+  
+}
+
+
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetTtbarHtSliceScale(){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetTtbarHtSliceScale(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    SetNominalComponent("weight_ttbar_htslice", 1.);
+
+    bool is1L  = ( m_vlq_outData-> o_channel_type == VLQ_Enums::ELECTRON ) || ( m_vlq_outData-> o_channel_type == VLQ_Enums::MUON );
+    bool is0L = ( m_vlq_outData-> o_channel_type == VLQ_Enums::FULLHAD );
+    if(is1L){
+      if( m_vlq_ntupData -> d_runNumber == 407009 ){ SetNominalComponent("weight_ttbar_htslice", 1.02849); }
+      else if( m_vlq_ntupData -> d_runNumber == 407010 ){ SetNominalComponent("weight_ttbar_htslice", 1.02637); }
+      else if( m_vlq_ntupData -> d_runNumber == 407011 ){ SetNominalComponent("weight_ttbar_htslice", 0.872646); }
+    }
+    else if(is0L){
+      if( m_vlq_ntupData -> d_runNumber == 407009 ){ SetNominalComponent("weight_ttbar_htslice", 1.04571); }
+      else if( m_vlq_ntupData -> d_runNumber == 407010 ){ SetNominalComponent("weight_ttbar_htslice", 0.983895); }
+      else if( m_vlq_ntupData -> d_runNumber == 407011 ){ SetNominalComponent("weight_ttbar_htslice", 0.916687); }
+    }
+
+    return true;
+}
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetCrossSectionWeight(){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetCrossSectionWeight(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    if(!m_sampleInfo){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetCrossSectionWeight(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+    if( m_vlq_opt -> IsData() || m_vlq_opt -> SampleName() == SampleName::QCD ){
+        return false;
+    }
+    SetNominalComponent( "weight_norm", m_sampleInfo -> NormFactor() );
+    return true;
+}
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetQCDWeight( const int channel ){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetQCDWeight(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    if( m_vlq_opt -> SampleName() != SampleName::QCD ){
+        return false;
+    }
+    bool isElectronChannel = ( channel == VLQ_Enums::ELECTRON );
+    bool isMuonChannel = ( channel == VLQ_Enums::MUON );
+    if( !m_vlq_opt -> RecomputeQCDWeight() || (!isElectronChannel && !isMuonChannel) ){
+        SetNominalComponent("weight_qcd", 1. );
+        return false;
+    }
+    if(!m_varComputer){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetQCDWeight(): m_varComputer is null ... Please check !" << std::endl;
+        abort();
+    }
+    if(!m_qcdWeight){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetQCDWeight(): m_qcdWeight is null ... Please check !" << std::endl;
+        abort();
+    }
+
+    double minDR = 0;
+    AnalysisObject *lepton = nullptr;
+    if(isElectronChannel){
+        minDR = m_varComputer -> GetMindR( *(m_vlq_outData -> o_jets), *(m_vlq_outData -> o_el) );
+        lepton = m_vlq_outData -> o_el -> at(0);
+    }
+    else if(isMuonChannel){
+        minDR = m_varComputer -> GetMindR( *(m_vlq_outData -> o_jets), *(m_vlq_outData -> o_mu) );
+        lepton = m_vlq_outData -> o_mu -> at(0);
+    }
+
+    bool isBoosted = false;
+    if( m_vlq_opt -> QCDMode() == "FJ" ){
+        isBoosted = true;
+    } else if( m_vlq_opt -> QCDMode() == "DEP" ){
+        if(m_vlq_outData -> o_taggedjets_n.at("RCTTMass") > 0){
+            isBoosted = true;
+        } else {
+            isBoosted = false;
+        }
+    }
+    const double qcdWeight = m_qcdWeight -> RetrieveWeight( isElectronChannel, lepton->Pt(), minDR, ((int)lepton->GetMoment("signal")==1), isMuonChannel, isBoosted );
+    SetNominalComponent("weight_qcd", qcdWeight );
+    if(m_vlq_opt->MsgLevel()==Debug::DEBUG){
+        std::cout << "Electron: " << isElectronChannel << "   pT = " << lepton->Pt() << "  dR = " << minDR << "   Tight: ";
+        std::cout << ((int)lepton->GetMoment("signal")==1) << "  Boosted: " << isBoosted << "  Weight: " << qcdWeight << std::endl;
+    }
+    return true;
+}
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetTtbbWeights(){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetTtbbWeights(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    if(m_vlq_opt -> SampleName() == SampleName::TTBARBB || m_vlq_opt -> SampleName() == SampleName::TTBARCC ||
+       m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT || m_vlq_opt -> SampleName() == SampleName::TTBAR ){
+
+        //
+        // NLO tt+bb Sherpa-based reweighting
+        //
+        if( m_vlq_opt -> ApplyTtbbCorrection() && m_vlq_opt -> RecomputeTtBbRw () ){
+
+            if(!m_tool_HFsyst){
+                std::cerr << "<!> Error in VLQ_WeightManager::SetTtbbWeights(): m_tool_HFsyst is null ... Please check !" << std::endl;
+                abort();
+            }
+
+            if(m_vlq_opt -> MsgLevel() == Debug::DEBUG) std::cout << "==> Evaluating TtBb Weigths" << std::endl;
+            HFSystDataMembers *dm_HFsyst = new HFSystDataMembers();
+            std::map<std::string,float> mapsOfHFweights;
+            mapsOfHFweights.clear();
+
+            dm_HFsyst -> q1_pt              = m_vlq_ntupData->d_q1_pt;
+            dm_HFsyst -> q1_eta             = m_vlq_ntupData->d_q1_eta;
+            dm_HFsyst -> qq_pt              = m_vlq_ntupData->d_qq_pt;
+            dm_HFsyst -> qq_dr              = m_vlq_ntupData->d_qq_dr;
+            dm_HFsyst -> top_pt             = m_vlq_ntupData->d_top_pt / 1000.;
+            dm_HFsyst -> ttbar_pt           = m_vlq_ntupData->d_ttbar_pt / 1000.;
+            dm_HFsyst -> HF_Classification  = m_vlq_ntupData -> d_HF_Classification;
+
+            mapsOfHFweights = m_tool_HFsyst->GetttHFWeights(dm_HFsyst);
+
+            SetNominalComponent("weight_ttbb", mapsOfHFweights["ttbb_Nominal_weight"]);
+
+            if( m_vlq_opt -> ComputeWeightSys() ){
+                SetSystematicComponent("weight_ttbb_CSS_KIN",    mapsOfHFweights["ttbb_CSS_KIN_weight"]);
+                SetSystematicComponent("weight_ttbb_MSTW",       mapsOfHFweights["ttbb_MSTW_weight"]);
+                SetSystematicComponent("weight_ttbb_NNPDF",      mapsOfHFweights["ttbb_NNPDF_weight"]);
+                SetSystematicComponent("weight_ttbb_Q_CMMPS",    mapsOfHFweights["ttbb_Q_CMMPS_weight"]);
+                SetSystematicComponent("weight_ttbb_glosoft",    mapsOfHFweights["ttbb_glosoft_weight"]);
+                SetSystematicComponent("weight_ttbb_defaultX05", mapsOfHFweights["ttbb_defaultX05_weight"]);
+                SetSystematicComponent("weight_ttbb_defaultX2",  mapsOfHFweights["ttbb_defaultX2_weight"]);
+                SetSystematicComponent("weight_ttbb_MPIup",      mapsOfHFweights["ttbb_MPIup_weight"]);
+                SetSystematicComponent("weight_ttbb_MPIdown",    mapsOfHFweights["ttbb_MPIdown_weight"]);
+                SetSystematicComponent("weight_ttbb_MPIfactor",  mapsOfHFweights["ttbb_MPIfactor_weight"]);
+                SetSystematicComponent("weight_ttbb_aMcAtNloHpp",mapsOfHFweights["ttbb_aMcAtNloHpp_weight"]);
+                SetSystematicComponent("weight_ttbb_aMcAtNloPy8",mapsOfHFweights["ttbb_aMcAtNloPy8_weight"]);
+            }
+
+            delete dm_HFsyst;
+            if(m_vlq_opt -> MsgLevel() == Debug::DEBUG) std::cout << "==> After TtBb weights" << std::endl;
+        }
+
+        //
+        // tt+bb/cc/light fraction reweithing in the different ttbar generators
+        //
+        if( m_vlq_opt -> ReweightTtbarFractions () ){
+            if(!m_tool_ttFractionRw){
+                std::cerr << "<!> Error in VLQ_WeightManager::SetTtbbWeights(): m_tool_ttFractionRw is null ... Please check !" << std::endl;
+                abort();
+            }
+            SetNominalComponent("weight_ttbar_fractions_rw", m_tool_ttFractionRw->GetTtbarFraction_Rw(m_vlq_ntupData -> d_HF_SimpleClassification) );
+        }
+    } else {
+        return false;
+    }
+    return true;
+}
+
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetTtccWeights(){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetTtbbWeights(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    if(!m_vlq_opt->ComputeWeightSys() || !m_vlq_opt -> ComputeTtccNLO()){
+        return true;
+    }
+
+
+    if(m_vlq_opt -> SampleName() == SampleName::TTBARBB || m_vlq_opt -> SampleName() == SampleName::TTBARCC ||
+       m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT || m_vlq_opt -> SampleName() == SampleName::TTBAR ){
+
+        //
+        // NLO tt+cc
+        //
+
+
+      float ttccNLO_weight=ttccNLO_syst::CharmRW(m_vlq_ntupData -> d_HF_Classification, m_vlq_ntupData->d_q1_pt, m_vlq_ntupData->d_q1_eta, m_vlq_ntupData->d_qq_pt, m_vlq_ntupData->d_qq_dr);
+
+
+      SetSystematicComponent("weight_ttcc_NLO", ttccNLO_weight);
+
+      if(m_vlq_opt -> MsgLevel() == Debug::DEBUG) std::cout << "==> After TtCc weights" << std::endl;
+
+
+    } else{
+      return false;
+    }
+    return true;
+}
+
+
+
+
+//____________________________________________________________________________________
+//
+bool VLQ_WeightManager::SetTtbarGeneratorSystematics(){
+  /*
+    if(!m_weightMngr){
+        std::cerr << "<!> Error in VLQ_WeightManager::SetTtbbWeights(): m_weightMngr is null ... Please check !" << std::endl;
+        abort();
+    }
+  */
+    if(!m_vlq_opt->ComputeWeightSys()){
+        return true;
+    }
+
+    if(m_vlq_opt -> SampleName() == SampleName::TTBARBB || m_vlq_opt -> SampleName() == SampleName::TTBARCC ||
+       m_vlq_opt -> SampleName() == SampleName::TTBARLIGHT || m_vlq_opt -> SampleName() == SampleName::TTBAR ){
+
+        if(!m_ttbar_syst_weight){
+            std::cerr << "<!> Error in VLQ_WeightManager::SetTtbarGeneratorSystematics(): m_ttbar_syst_weight is null ... Please check !" << std::endl;
+            abort();
+        }
+        SetSystematicComponent( "weight_ttbar_PS",    m_ttbar_syst_weight -> GetTtbarSystWeight(VLQ_TtbarSystematicsManager::PS)      );
+        SetSystematicComponent( "weight_ttbar_GEN",   m_ttbar_syst_weight -> GetTtbarSystWeight(VLQ_TtbarSystematicsManager::GEN)     );
+        SetSystematicComponent( "weight_ttbar_GENPS", m_ttbar_syst_weight -> GetTtbarSystWeight(VLQ_TtbarSystematicsManager::GENPS)   );
+        SetSystematicComponent( "weight_ttbar_RADHI", m_ttbar_syst_weight -> GetTtbarSystWeight(VLQ_TtbarSystematicsManager::RADHI)   );
+        SetSystematicComponent( "weight_ttbar_RADLOW",m_ttbar_syst_weight -> GetTtbarSystWeight(VLQ_TtbarSystematicsManager::RADLOW)  );
+
+    } else {
+        return false;
+    }
+    return true;
+}
diff --git a/VLQAnalysis/VLQ_Analysis_Data2015.h b/VLQAnalysis/VLQ_Analysis_Data2015.h
index 40b3b197637e2c3d94d6e416c4fa91cf480cd66f..1bb9875f85a0289714a98a180ab5940d7ca10571 100644
--- a/VLQAnalysis/VLQ_Analysis_Data2015.h
+++ b/VLQAnalysis/VLQ_Analysis_Data2015.h
@@ -8,7 +8,7 @@
 //IFAEFramework classes
 class OutputHistManager;
 class OutputTreeManager;
-class WeightManager;
+//class WeightManager;
 
 //VLQ specific classes
 class VLQ_Options;
@@ -17,7 +17,7 @@ class VLQ_AnalysisTools;
 class VLQ_VariableComputer;
 class VLQ_TruthManager;
 class VLQ_TRFManager;
-class VLQ_WeightSetter;
+class VLQ_WeightManager;
 class VLQ_NtupleData;
 class VLQ_NtupleReader;
 class VLQ_Selector;
@@ -48,8 +48,7 @@ private:
     VLQ_VariableComputer *m_varComputer;
     VLQ_TruthManager *m_truthMngr;
     VLQ_TRFManager *m_TRFMngr;
-    WeightManager *m_weightMngr;
-    VLQ_WeightSetter *m_weightSetter;
+    VLQ_WeightManager *m_weightMngr;
     VLQ_Selector *m_selector;
     std::map < std::string, std::vector < std::string > > m_channels;
     std::vector < std::string > m_topTaggers;
diff --git a/VLQAnalysis/VLQ_Options.h b/VLQAnalysis/VLQ_Options.h
index 8d274fed3fc4d3318f576138f6b82f909e6981b4..7586c6dad3acb896b3024fae2ae4cc47f14b7356 100644
--- a/VLQAnalysis/VLQ_Options.h
+++ b/VLQAnalysis/VLQ_Options.h
@@ -67,6 +67,7 @@ public:
     inline std::string BtagOP() const { return m_btagOP; }
     inline std::string TRFCDIPath() const { return m_TRFCDIPath; }
     inline std::string QCDMode() const { return m_QCDMode; }
+    inline std::string DoRegions() const { return m_do_regions; }
     // doubles
     inline double RCJetsPtCut() const { return m_RCJetsPtCut; }
     inline double JetsPtCut() const { return m_jetsPtCut; }
@@ -122,6 +123,7 @@ private:
     std::string m_btagOP;
     std::string m_TRFCDIPath;
     std::string m_QCDMode;
+    std::string m_do_regions;
     FilteringType m_filterType;
 
 };
diff --git a/VLQAnalysis/VLQ_Selector.h b/VLQAnalysis/VLQ_Selector.h
index 2fdb6b949c7002624f07f0326bc6aabe4de60336..57c2a0fede0daba28c642a402d1acd1c9d40d1a3 100644
--- a/VLQAnalysis/VLQ_Selector.h
+++ b/VLQAnalysis/VLQ_Selector.h
@@ -27,13 +27,14 @@ public:
 
     //=========== Top selections =========================
   enum VLQTopSels{ c_1l_chan=1, c_1el_chan, c_1mu_chan, c_0l_chan,
-		   c_4jex, c_5jex, c_6jex, c_7jex, c_8jex, c_6_8jin, 
+		   c_4jex, c_5jex, c_6jex, c_7jex, c_8jex, c_6_8jwin,
 		   c_4jin, c_5jin, c_6jin, c_7jin, c_8jin, c_9jin,
 		   c_0bex, c_1bex, c_2bex, c_3bex,
 		   c_0bin, c_1bin, c_2bin, c_3bin, c_4bin,
-		   c_0Mex, c_1Mex, c_2Min, 
+		   c_0Mex, c_1Mex, c_2Min,
 		   c_0Tex, c_0Tin, c_1Tex, c_1Tin, c_2Tin,
-		   c_0Hex, c_0Hin, c_1Hex, c_1Hin, c_2Hin,
+		   c_0Hex, c_0Hin, c_1Hex, c_1Hin, c_2Hin, c_0_1Hwin,
+		   c_0THex, c_1THex, c_2THex, c_2THin, c_3THin,
 		   c_LowMtbmin, c_HighMtbmin, c_LowMbb, c_HighMbb, TOPSEL_MAX
   };
 
@@ -44,11 +45,11 @@ public:
 
     //=========== Top selections =========================
     c_1l_chan, c_1el_chan, c_1mu_chan, c_0l_chan,
-    c_4jex, c_5jex, c_6jex, c_7jex, c_8jex, c_6_8j, 
+    c_4jex, c_5jex, c_6jex, c_7jex, c_8jex, c_6_8j,
     c_4jin, c_5jin, c_6jin, c_7jin, c_8jin, c_9jin,
     c_0bex, c_1bex, c_2bex, c_3bex,
     c_0bin, c_1bin, c_2bin, c_3bin, c_4bin,
-    c_0Mex, c_1Mex, c_2Min, 
+    c_0Mex, c_1Mex, c_2Min,
     c_0THex, c_0THin, c_1THex, c_1THin, c_2THin,
     c_0Tex, c_0Tin, c_1Tex, c_1Tin, c_2Tin,
     c_0Hex, c_0Hin, c_1Hex, c_1Hin, c_2Hin,
@@ -65,7 +66,7 @@ public:
 
     inline void SetOutputHistManager(OutputHistManager* outMngrHist){ m_outMngrHist = outMngrHist; }
     //inline void SetOutputTreeManager(OutputTreeManager* outMngrTree){ m_outMngrTree = outMngrTree; }
-    
+
     //virtual bool AddFlag(Selection& sel , const std::string& flag, const bool value=true );
     //using SelectorBase::AddFlag;
     //void FillSelIndMap();
@@ -79,9 +80,9 @@ public:
 
     int GetSelectionIndex( const std::string& sel_name);
     std::string GetSelectionName( const int sel_index);
- 
+
     virtual bool PassSelection( const int index );
-    virtual bool RunOperations(const Selection& sel) const;    
+    virtual bool RunOperations(const Selection& sel) const;
 
  protected:
     virtual Selection* MakeSelection( const int index, const std::string& name="" );
@@ -101,17 +102,31 @@ public:
     OutputHistManager* m_outMngrHist;
     //OutputTreeManager* m_outMngrTree;
 
-    std::map<std::string, int>* m_sel_indices;    
-    std::map<int, std::string>* m_sel_names;    
-    std::vector<SelProp>* m_sel_lep_prop;    
-    std::vector<SelProp>* m_sel_lepflav_prop;    
-    std::vector<SelProp>* m_sel_jet_prop;    
-    std::vector<SelProp>* m_sel_bjet_prop;    
-    std::vector<SelProp>* m_sel_M_prop;    
-    std::vector<SelProp>* m_sel_T_prop;    
-    std::vector<SelProp>* m_sel_H_prop;    
-    std::vector<SelProp>* m_sel_Mbb_prop;    
-    std::vector<SelProp>* m_sel_Mtb_prop;    
+    bool m_do_presel;
+    bool m_do_validn_reg;
+    bool m_do_fit_reg;
+    bool m_do_lowb;
+    bool m_do_split_emu;
+    bool m_do_lowj;
+    bool m_do_highj;
+    bool m_do_old_boost;
+    bool m_do_new_boost;
+    bool m_do_merge_boost;
+    bool m_do_split_mtb;
+    bool m_do_split_mbb;
+
+    std::map<std::string, int>* m_sel_indices;
+    std::map<int, std::string>* m_sel_names;
+    std::vector<SelProp>* m_sel_lep_prop;
+    std::vector<SelProp>* m_sel_lepflav_prop;
+    std::vector<SelProp>* m_sel_jet_prop;
+    std::vector<SelProp>* m_sel_bjet_prop;
+    std::vector<SelProp>* m_sel_M_prop;
+    std::vector<SelProp>* m_sel_T_prop;
+    std::vector<SelProp>* m_sel_H_prop;
+    std::vector<SelProp>* m_sel_TH_prop;
+    std::vector<SelProp>* m_sel_Mbb_prop;
+    std::vector<SelProp>* m_sel_Mtb_prop;
 
 
     //int m_nsel;
diff --git a/VLQAnalysis/VLQ_WeightManager.h b/VLQAnalysis/VLQ_WeightManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..77c8cd14d7ed9323664020b2c22063c78e63fbe9
--- /dev/null
+++ b/VLQAnalysis/VLQ_WeightManager.h
@@ -0,0 +1,61 @@
+#ifndef VLQ_WEIGHTSETTER_H
+#define VLQ_WEIGHTSETTER_H
+
+//in IFAETopFramework
+#include "IFAETopFramework/WeightManager.h"
+class SampleInfo;
+
+//in VLQAnalysis
+class VLQ_Options;
+class VLQ_OutputData;
+class VLQ_NtupleData;
+class VLQ_QCDWeight;
+class VLQ_VariableComputer;
+class VLQ_TtbarSystematicsManager;
+
+//in IFAEReweightingTools
+class ttbbNLO_syst;
+class TtbarFractionReweighter;
+class ttccNLO_syst;
+
+class VLQ_WeightManager : public WeightManager {
+    
+public:
+    //
+    // Standard C++ functions
+    //
+    VLQ_WeightManager( VLQ_Options *opt, const VLQ_NtupleData* ntupleData, VLQ_OutputData* outputData );
+    VLQ_WeightManager( const VLQ_WeightManager & );
+    virtual ~VLQ_WeightManager();
+    
+    //
+    // Class specific functions
+    //
+    bool AddVLQNominalWeights(); 
+    bool AddVLQSystematicWeights(); 
+    
+    //virtual bool ComputeNominalWeight();
+
+    bool SetCrossSectionWeight();
+    bool SetQCDWeight( const int channel );
+    bool SetTtbbWeights();
+    bool SetTtccWeights();
+    bool SetTtbarGeneratorSystematics();
+    bool SetTtbarHtSliceScale();
+    
+private:
+    VLQ_Options *m_vlq_opt;
+    const VLQ_NtupleData *m_vlq_ntupData;
+    VLQ_OutputData *m_vlq_outData;
+    //WeightManager *m_weightMngr;
+    
+    SampleInfo *m_sampleInfo;
+    VLQ_QCDWeight *m_qcdWeight;
+    VLQ_VariableComputer *m_varComputer;
+    ttbbNLO_syst *m_tool_HFsyst;
+    TtbarFractionReweighter *m_tool_ttFractionRw;
+    VLQ_TtbarSystematicsManager *m_ttbar_syst_weight;
+    
+};
+
+#endif //VLQ_WEIGHTSETTER_H
diff --git a/data/samples_info.dat b/data/samples_info.dat
index 793affc0c5b4473873e3a3f4d4dac671b978fd35..26479ff729bc829ba8846ae80d940eede7d12250 100644
--- a/data/samples_info.dat
+++ b/data/samples_info.dat
@@ -265,4 +265,4 @@
 302478. 491000.0 0.0223
 302480. 492000.0 0.0117
 302481. 249000.0 0.00634
-302482. 247000.0 0.0035
+302482. 247000.0 0.0035
\ No newline at end of file
diff --git a/python/ProduceSampleDATfile.py b/python/ProduceSampleDATfile.py
index aee36d592aa3b149ffeb42e38f7ed06103ebba00..201c4bfbf58b70df9309762c169042f4a9ff7b21 100644
--- a/python/ProduceSampleDATfile.py
+++ b/python/ProduceSampleDATfile.py
@@ -120,4 +120,4 @@ configFile.close()
 ##________________________________________________________
 ## Removing list folder
 os.system("rm -rf " + listFolder) #list files folder
-##........................................................
+##........................................................
\ No newline at end of file