diff --git a/LArCalorimeter/LArCafJobs/CMakeLists.txt b/LArCalorimeter/LArCafJobs/CMakeLists.txt
index b97f1dfcfaf403bc6080508a1213673f2a2c53f7..bb7c0e9200803a66da89a7fee9cc98c20109aa90 100644
--- a/LArCalorimeter/LArCafJobs/CMakeLists.txt
+++ b/LArCalorimeter/LArCafJobs/CMakeLists.txt
@@ -44,11 +44,6 @@ atlas_add_dictionary( LArCafJobsDict
                       LArCafJobs/selection.xml
                       LINK_LIBRARIES LArCafJobsLib )
 
-atlas_add_executable( LArQuickHistMerge
-                      src/LArQuickHistMerge.cxx
-                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                      LINK_LIBRARIES ${ROOT_LIBRARIES} DataQualityUtils CxxUtils )
-
 atlas_add_executable( LArSamplesMerge
                       src/LArSamplesMerge.cxx
                       INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
@@ -57,7 +52,7 @@ atlas_add_executable( LArSamplesMerge
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 atlas_install_joboptions( share/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} --extend-ignore=F401,F821 )
-atlas_install_scripts( share/LArHistMerge_trf.py share/LArMerge_tf.py share/LArCAF_tf.py share/LArNoiseBursts_tf.py share/LArNoiseBursts_fromraw_tf.py share/LArPulseShape_tf.py share/LArCells_tf.py share/LArSCDump_tf.py share/LArSCRecoTest_tf.py )
+atlas_install_scripts( share/LArMerge_tf.py share/LArCAF_tf.py share/LArNoiseBursts_tf.py share/LArNoiseBursts_fromraw_tf.py share/LArPulseShape_tf.py share/LArCells_tf.py share/LArSCDump_tf.py share/LArSCRecoTest_tf.py )
 
 atlas_add_test( LArCellsEmpty_test
 		SCRIPT share/LArCellsEmpty_test.sh
diff --git a/LArCalorimeter/LArCafJobs/share/LArHistMerge_trf.py b/LArCalorimeter/LArCafJobs/share/LArHistMerge_trf.py
deleted file mode 100755
index 9e01983c05d2af57abca0b16215d842387fcfd11..0000000000000000000000000000000000000000
--- a/LArCalorimeter/LArCafJobs/share/LArHistMerge_trf.py
+++ /dev/null
@@ -1,234 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-
-from __future__ import print_function
-
-import sys, os, pickle, pprint, subprocess
-
-from LArCafJobs.GetLBsToIgnore import getLBsToIgnore
-
-
-#########################################################################
-
-# Utility function
-
-def getFileMap(fname, dsname, nevts=0, guid='') :
-  if os.path.isfile(fname) :
-    dataMap = { 'lfn': fname,
-                'dataset' : dsname,
-                'events' : nevts
-          }
-    if guid : 
-      dataMap['GUID'] = guid      
-  else : 
-    dataMap = {}
-  return dataMap
-
-#########################################################################
-
-
-def getPFN(filespec):
-   if isinstance(filespec,dict):
-     if "svcclass" in filespec:
-       os.environ["STAGE_SVCCLASS"]=filespec["svcclass"]
-       pass
-     
-     if 'pfn' in filespec:
-       return filespec['pfn']
-     else:
-       print ("ERROR: Unknown file specification (dict):")
-       print (filespec)
-       sys.exit(-1)
-       
-     
-   if isinstance(filespec,str):
-     names=filespec.split('#')
-     if len(names)!=2:
-       print ("ERROR: Unexpected file specification (string):")
-       print (filespec)
-       sys.exit(-1)
-     else:
-       return names[1]
-     
-     
-
-
-def getRunLB(fname):
-   filename=fname.split("/")[-1] #Strip off path
-   elem=filename.split(".")
-   #File name example:
-   #data11_7TeV.00190618.physics_CosmicCalo.recon.HIST.f411._lb0826._SFO-ALL._0001.1
-   if (len(elem) <6):
-     print ("ERROR: Invalid file name format. Expected at least six subfileds, got",filename)
-     sys.exit(-1)
-     pass
-
-   step=elem[3]
-   if step != 'recon':
-     return (-1,-1)
-
-   rnStr=elem[1]
-
-   if not rnStr.isdigit():
-     print ("ERROR: Can't get run number, got",rnStr)
-     sys.exit(-1)
-     pass
-   run=int(rnStr,10)
-
-   LBStr=elem[6]
-   if (len(LBStr)<4):
-     print ("ERROR: Can't get LB number, got",LBStr)
-     sys.exit(-1)
-     pass
-
-   LBStr=LBStr[3:]
-   if not LBStr.isdigit():
-     print ("ERROR: Can't get LB number, got",LBStr)
-     sys.exit(-1)
-     pass
-
-   LB=int(LBStr,10)
-   return (run,LB)
-
-
-def larMerge(dataMap) :
-
-  print ("\n##################################################################")
-  print (  "##                 ATLAS Tier0 LAr CAF file Merging             ##")
-  print (  "##################################################################\n")
-
-  print ("\nFull Tier-0 run options:\n")
-  pprint.pprint(dataMap)
-  
-  inputList = []
-
-  badLBs=set()
-
-  inFiles=dataMap['inputHistFiles']
-
-
-  if len(inFiles)>0:
-    firstFile=getPFN(inFiles[0])
-    runnumber=getRunLB(firstFile)[0]
-    if runnumber==-1:
-      print ("Encountered pre-merged file, no bad-LB checking done" )
-    else:
-      print ("Found run number",runnumber)
-      badLBs=getLBsToIgnore(runnumber)
-     
-    
-  for val in inFiles:
-    pfn=getPFN(val)
-    if len(badLBs)>0:
-      LB=getRunLB(pfn)[1]
-      if LB in badLBs:
-        print ("Ignoring bad LumiBlock",LB)
-        continue
-    inputList.append(pfn)
-  sys.stdout.flush()  
-  #print ("\ninputLArFiles list:\n")
-  #pprint.pprint(inputList)
-
-  #Write input file list to temporary file:
-  templist=open("inputfiles.txt","w")
-  for infile in inputList:
-    templist.write(infile+"\n")
-    pass
-  templist.close()
-
-
-  # output file
-  outputDSName = dataMap['outputLArHistFile'].split('#')[0]
-  outputFile = dataMap['outputLArHistFile'].split('#')[1]
-
-  print ('\nOutput file name:', outputFile)
-
-  retcode = 0
-
-  cmd="LArQuickHistMerge.exe -i inputfiles.txt " + outputFile
-  
-  try:
-    retcode = subprocess.call(cmd, shell=True)
-    print ('retcode =',retcode)
-    if retcode != 0 : 
-      retcode = 62601
-      acronym =  "LARQUICKHISTMEGE PROBLEM"
-  except OSError as e :
-    retcode = 62600
-    print (e)
-    acronym = "SUBPROCESS EXECUTION PROBLEM"
-    pass
-
-  if retcode==0:
-    cmd ="DQWebDisplay.py " + outputFile +" LArDisplay 111"
-    print ("Attempt to run",cmd)
-    try:
-      retcodeDQM = subprocess.call(cmd, shell=True)
-      print ('retcode =',retcodeDQM)
-    except Exception as e:
-      print ("Attempt failed with exception")
-      print (e)
-    
- 
-  # get info for report gpickle file 
-  if retcode == 0 :
-    outputMap = getFileMap(outputFile, outputDSName, nevts=0)
-    outFiles = [ outputMap ]
-    acronym = 'OK'
-  else:
-    outFiles = []
-    outputMap = {}
-    print ("ERROR: problem in LAr Histogram merging!")
-    if retcode == 62600 :
-      acronym = 'TRF_LAR_FILE_INPUT_ERROR'
-    elif retcode == 62601 :  
-      acronym = 'TRF_LAR_MERGE_ERROR'
-
-
-
-  # assemble job report map, pickle it
-  outMap = { 'prodsys': { 'trfCode': retcode,
-                          'trfAcronym': acronym,  
-                          'jobOutputs': outFiles,
-                          'jobInputs': inFiles,
-                        }
-           }              
-  f = open('jobReport.gpickle', 'wb')
-  pickle.dump(outMap, f)
-  f.close()
-
-  print ("\n##################################################################")
-  print (  "## End of job.")
-  print (  "##################################################################\n")
-
-
-
-########################################
-## main()
-########################################
-
-if __name__ == "__main__":
-
-  if len(sys.argv) == 2 and sys.argv[1].startswith('--argdict=') :
-    picklefile = sys.argv[1][len('--argdict='):]
-    # extract parameters from pickle file
-    print ("Using pickled file ", picklefile, " for input parameters")
-    f = open(picklefile, 'rb')
-    dataMap = pickle.load(f)
-    f.close()
-    larMerge(dataMap)
-  elif len(sys.argv) == 3 and sys.argv[1].startswith('--inputFiles=') and sys.argv[2].startswith('--outputFile=') :
-    inputFiles = sys.argv[1][13:].split(',')
-    outputFile = sys.argv[2][13:]
-    dataMap = {}
-    dataMap['inputHistFiles'] = inputFiles
-    dataMap['outputLArHistFile'] = outputFile
-    larMerge(dataMap)
-  else :
-    print ("Input format wrong --- either have: ")
-    print ("   --argdict=<pickled-dictionary containing input info> ")
-    print ("   with key/value pairs: ")
-    print ("   or (old way): ")
-    print ("   --inputFiles=file1,file2,...,fileN --outputFile=file")
-    exit(1)
diff --git a/LArCalorimeter/LArCafJobs/share/UploadAMITag.larcaf.py b/LArCalorimeter/LArCafJobs/share/UploadAMITag.larcaf.py
index 331e7c2eba1b888c0b2d61e4918eba8a68a69289..b680dfdf11eebdb0fe0ce2bb54418c4dea200066 100755
--- a/LArCalorimeter/LArCafJobs/share/UploadAMITag.larcaf.py
+++ b/LArCalorimeter/LArCafJobs/share/UploadAMITag.larcaf.py
@@ -54,18 +54,6 @@ processConfigs['merge'] = {
     }
 
 
-processConfigs['histmerge'] = {
-    'inputs': { 'inputHistFiles': {'metatype':'inputLFNlistDA'} },
-    'outputs': { 'outputLArHistFile': {'dstype': 'LARHIST'}, }, 
-    'tasktransinfo': { 'trfpath': 'LArHistMerge_trf.py',
-                       'trfsetupcmd': trfsetuppath+'setuptrf.sh '+patcharea+' RELEASE '+trfsetuppath+'specialsetup_tier0.sh' },
-    'phconfig': {}, 
-    'description': 'Merges LAr Monitoring Histograms. Uses RELEASE' 
-    }
-
-
-
-
 
 
 description_var = '. Used in production from Feb 2015 onwards.'
diff --git a/LArCalorimeter/LArCafJobs/src/LArQuickHistMerge.cxx b/LArCalorimeter/LArCafJobs/src/LArQuickHistMerge.cxx
deleted file mode 100644
index 12bf8599187b8fab4fab8197753b1565e06f21bc..0000000000000000000000000000000000000000
--- a/LArCalorimeter/LArCafJobs/src/LArQuickHistMerge.cxx
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
-*/
-
-
-#include "CxxUtils/checker_macros.h"
-ATLAS_NO_CHECK_FILE_THREAD_SAFETY;
-
-
-//Standalone compilation:
-//g++ -g -o mergetest.exe `root-config --libs --cflags` -L InstallArea/i686-slc5-gcc43-opt/lib/ -l DataQualityUtils LArHistMerge.version2.cxx
-
-// This file uses thread-unsafe classes from DataQualityUtils.
-ATLAS_NO_CHECK_FILE_THREAD_SAFETY;
-
-#include "TSystem.h"
-#include "TH1.h"
-#include "TH2.h"
-#include "TFile.h"
-#include "TKey.h"
-#include "TTree.h"
-
-#include <iostream>
-#include <string>
-#include <vector>
-#include <fstream>
-
-#include "DataQualityUtils/MonitoringFile.h" 
-
-#define MAXSKIPPEDFILES 10
-#define MAXSKIPPEDFILESFRACTION 0.1
-
-TFile* openWithRetry(const char* path, const unsigned nTrys=3) {
-  TFile* f=nullptr;
-  unsigned iTry=0;
-  unsigned sleepSeconds=30;
-  while (!f && iTry<nTrys) {
-    f=TFile::Open(path,"READ");
-    if (!f || !(f->IsOpen())) {
-      ++iTry;
-      std::cout << "WARNING: Failed to open file " << path << " on " << iTry << ". attempt." << std::endl;
-      if (iTry<nTrys) {
-	std::cout << "Will re-try after " << sleepSeconds << " seconds..." << std::endl;
-	sleep(sleepSeconds);
-	f=nullptr;
-	sleepSeconds*=2;
-      }
-      else {//no more attempts
-	std::cout << "No more retrys" << std::endl;
-      }
-    }//end if file not open
-  }// end while
-  return f;
-}
-
-class histCollection {
-  
-public:
-  
-  explicit histCollection(bool debug=false) : m_dbg(debug) {};
-  void addDirectory(TDirectory* dir, const std::string& dirName);
-  size_t size() {return m_data.size();};
-  void addFile(TFile* in);
-  void print();
-  void write(TFile* out);
-
-  void addExclusion(const std::string& dir);
-
-private:
-  class histPerDir_t {
-  public:
-    histPerDir_t(const std::string& nameIn, TObject* objIn, TTree* md, bool dbg=false); 
-    std::string name;
-    TObject* obj;
-    void (*mergeMethod)(TObject* a, const TObject* b);    
-  };
-
-  struct histDir_t {
-    explicit histDir_t(TTree* mdIn): md(mdIn) {};
-    std::vector<histPerDir_t> histos;
-    TTree* md;
-  };
-
-
-private:
-  bool isExcluded(const std::string& dir);
-  std::map<std::string,histDir_t> m_data;
-  bool m_dbg;
-  std::vector<std::string> m_exclusion;
-  
-};
-
-
-void histCollection::addExclusion(const std::string& dir) {
-  m_exclusion.push_back(dir);
-  return;
-}
-
-bool histCollection::isExcluded(const std::string& dir) {
-
-  const size_t firstSlash=dir.find('/',1);
-  if (firstSlash==std::string::npos) return false;
-
-  std::vector<std::string>::const_iterator it=m_exclusion.begin();
-  std::vector<std::string>::const_iterator it_e=m_exclusion.end();
-  for(;it!=it_e;++it) {
-    const std::string& excl=*it;
-    const size_t s=excl.size();
-    //std::cout << "Comparing " << dir << " (index "<< firstSlash <<") with " << excl << std::endl; 
-    if (dir.compare(firstSlash,s,excl)==0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
-void histCollection::print() {
-  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
-  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
-  for(;it!=it_e;++it) {
-    const histDir_t& hd=it->second;
-    std::cout << "Dir: " << it->first <<" has "<<hd.histos.size()<<" histos"<<std::endl;
-    std::vector<histPerDir_t>::const_iterator it1=hd.histos.begin();
-    std::vector<histPerDir_t>::const_iterator it1_e=hd.histos.end();
-    for (;it1!=it1_e;++it1) 
-      std::cout << "\t" << it1->name << std::endl;
-  }
-
-  std::cout << "\nExclusion List: " << std::endl;
-  std::vector<std::string>::const_iterator sit=m_exclusion.begin();
-  std::vector<std::string>::const_iterator sit_e=m_exclusion.end();
-  for(;sit!=sit_e;++sit) 
-    std::cout << "\t" << *sit << std::endl;
-
-  return;
-}
-
-template<class HIST> 
-void defaultMerge(TObject* a, const TObject* b) {
-  ((HIST*)a)->Add((HIST*)b);
-  return;
-}
-
-void weightedAverageTH1 ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH1* a1=(dynamic_cast<TH1*>(a));
-  const TH1* b1=dynamic_cast<const TH1*>(b);
-  if (!b1 || !a1)
-    std::cout << "ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_weightedAverage(*a1,*b1);
-  return;
-}
-
-void weightedAverageTH2 ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH2* a1=(dynamic_cast<TH2*>(a));
-  const TH2* b1=(dynamic_cast<const TH2*>(b));
-  if (!b1 || !a1)
-    std::cout << "ERROR in weightedAverageTH2: Object not of type TH2" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_weightedAverage2D(*a1,*b1);
-  return;
-}
-
-void weightedEff ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH1* a1=(dynamic_cast<TH1*>(a));
-  const TH1* b1=(dynamic_cast<const TH1*>(b));
-  if (!b1 || !a1) 
-    std::cout << "ERROR in weightedEff: Object not of type TH1" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_weightedEff(*a1,*b1);
-  return;
-}
-
-void mergeRMS ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH1* a1=(dynamic_cast<TH1*>(a));
-  const TH1* b1=dynamic_cast<const TH1*>(b);
-   if (!b1 || !a1) 
-    std::cout << "ERROR in mergeRMS: Object not of type TH1" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_RMS(*a1,*b1);
-  return;
-}
-
-void RMSpercentDeviation ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH1* a1=(dynamic_cast<TH1*>(a));
-  const TH1* b1=dynamic_cast<const TH1*>(b);
-  if (!b1 || !a1) 
-    std::cout << "ERROR in RMSpercentDeviation: Object not of type TH1" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_RMSpercentDeviation(*a1,*b1);
-  return;
-}
-
-void perBinEffPerCent ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-  TH1* a1=(dynamic_cast<TH1*>(a));
-  const TH1* b1=dynamic_cast<const TH1*>(b);
-  if (!b1 || !a1) 
-    std::cout << "ERROR in getBinEffPerCent: Object not of type TH1" << std::endl;
-  else
-    dqutils::MonitoringFile::merge_perBinEffPerCent(*a1,*b1);
-  return;
-}
-
-void lowerLB ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
-   TH1* a1=(dynamic_cast<TH1*>(a));
-   const TH1* b1=dynamic_cast<const TH1*>(b);
-   if (!b1 || !a1) 
-     std::cout << "ERROR in lowerLB: Object not of type TH1" << std::endl;
-   else
-     dqutils::MonitoringFile::merge_lowerLB(*a1,*b1);
-   return;
-}
-
-void identical(TObject* a, const TObject* b) {
-   TH1* a1=(dynamic_cast<TH1*>(a));
-   const TH1* b1=dynamic_cast<const TH1*>(b);
-   TH2* c1=(dynamic_cast<TH2*>(a));
-   const TH2* d1=dynamic_cast<const TH2*>(b);
-   if (a1 and b1){
-     dqutils::MonitoringFile::merge_identical(*a1,*b1);
-   } else if (c1 and d1){
-     dqutils::MonitoringFile::merge_identical(*c1,*d1);
-   } else {
-     std::cout << "ERROR in identical: Object not of type THist" << std::endl;
-     std::cout << a1 << " " << b1 << " " << c1 << " " <<d1 <<std::endl;
-   }
-   return;
-}
-    
-
-histCollection::histPerDir_t::histPerDir_t(const std::string& nameIn, TObject* objIn, TTree* md, bool dbg) : 
-  name (nameIn),
-  obj(objIn),
-  mergeMethod(nullptr)
-{
-
-  //Some sanity checks:
-  if (!objIn) {
-    std::cout << "ERROR while adding " << nameIn << ": Histogram pointer is NULL" << std::endl;
-    return;
-  }
-
-  char howToMerge[256]={};
-  char mdName[256]={};
-  strcpy(howToMerge,"<default>");
-  if (!md) {
-    std::cout << "ERROR while adding " << nameIn << ": No metadata tree. Use default merging method" << std::endl;
-  }
-  else {
-      md->SetBranchAddress("MergeMethod", howToMerge);
-      md->SetBranchAddress("Name", mdName);
-      unsigned nEntries = md->GetEntries();
-      for (unsigned i=0;i<nEntries;++i) {
-	md->GetEntry(i);
-	if (name.compare(mdName)==0) break;
-      }
-  }
-
-  if (dbg) std::cout << "Name:" << mdName << " mergeMethod=" << howToMerge << std::endl;
-  if (nullptr!=dynamic_cast<TH1*>(obj)) {
-    if (!strcmp(howToMerge,"<default>")) 
-      mergeMethod=&defaultMerge<TH1>;
-    else if (!strcmp(howToMerge,"weightedAverage")) 
-      mergeMethod=&weightedAverageTH1;
-    else if (!strcmp(howToMerge,"weightedEff")) 
-      mergeMethod=&weightedEff;
-    else if (!strcmp(howToMerge,"mergeRMS"))
-      mergeMethod=&mergeRMS;
-    else if (!strcmp(howToMerge,"RMSpercentDeviation")) 
-      mergeMethod=&RMSpercentDeviation;
-    else if (!strcmp(howToMerge,"perBinEffPerCent"))
-      mergeMethod=&perBinEffPerCent;
-    else if (!strcmp(howToMerge,"lowerLB")) 
-      mergeMethod=&lowerLB;
-    else if (!strcmp(howToMerge,"identical")) 
-      mergeMethod=&identical;
-
-    else {
-      std::cout << "ERROR: Unknown merging method (" << howToMerge << ") for object of type TH1 named " << nameIn << std::endl;
-      obj=nullptr;
-    }
-  }// end if TH1
-  else if (nullptr!=dynamic_cast<TH2*>(obj)) {
-     if (!strcmp(howToMerge,"<default>")) 
-      mergeMethod=&defaultMerge<TH2>;
-    else if (!strcmp(howToMerge,"weightedAverage")) 
-      mergeMethod=&weightedAverageTH2;
-    else {
-      std::cout << "ERROR: Unknown merging method (" << howToMerge << ") for object of type TH2 named " << nameIn << std::endl;
-      obj=nullptr;
-    }
-     
-  }// end if TH2
-  else {
-    std::cout << "Object "<< name  << " has unkown type" << std::endl;  
-    obj=nullptr;
-  }
-}
-
-
-void histCollection::addDirectory(TDirectory* dir, const std::string& dirName) {
-  TIter next( dir->GetListOfKeys() );
-  TKey* key;
-  while((key=(TKey*)next()))  {
-    const char* name=key->GetName();
-    const char* classname=key->GetClassName();
-    if (m_dbg) std::cout << "Found name " << name << ", classname=" << classname << std::endl;
-    const std::string newName=dirName+"/"+name;
-
-    if (this->isExcluded(newName)) {
-      std::cout << "Path " << newName << " excluded" << std::endl;
-      return;
-    }
-
-    if (!strncmp(classname,"TH1",3) || !strncmp(classname,"TH2",3) || !strncmp(classname,"TProfile",8)) {
-      std::map<std::string,histDir_t>::iterator mIt=m_data.find("dirName");
-      
-      if (mIt==m_data.end()) { // New top-level directory
-	TTree* md=(TTree*)dir->Get("metadata");
-	if (!md) std::cout << "ERROR: Did not find metadata tree in directroy " << dirName << std::endl;
-	mIt=m_data.insert(std::make_pair(dirName,histDir_t(md))).first;
-      }
-      histPerDir_t histo(name,key->ReadObj(),mIt->second.md,m_dbg);
-
-      // Check if we already have this histogram in the list
-      bool found = 0;
-      for (auto it1=mIt->second.histos.begin(); it1!=mIt->second.histos.end();++it1) {
-	if( it1->name == name){
-	  found=1;
-	  break;
-	}
-      }
-      if ( found == 0 ){ // Add the histrogam if we didn't already have it
-	mIt->second.histos.push_back(histo);
-      }
-
-    }
-    else if (!strncmp(classname,"TDirectory",10)) {
-      TObject* obj = key->ReadObj();
-      TDirectory* subdir = dynamic_cast<TDirectory*>( obj );
-      if (subdir) {
-	this->addDirectory(subdir,newName);
-      }
-    }
-    else if (!strcmp(classname,"TTree") && (!strcmp(name,"metadata"))) {
-      //std::cout << "Found Metadata tree" << std::endl;
-    }
-    else {
-      std::cout << "Ignored objects '" << name << "' of type "<< classname << std::endl;
-    } 
-  }
-  return;
-}
-
-
-void histCollection::addFile(TFile* in) {
-  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
-  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
-  for(;it!=it_e;++it) {
-    const std::string& dirName=it->first;
-    const histDir_t& hd=it->second;
-    std::vector<histPerDir_t>::const_iterator it1=hd.histos.begin();
-    std::vector<histPerDir_t>::const_iterator it1_e=hd.histos.end();
-    for (;it1!=it1_e;++it1) {
-      const std::string fullName=dirName+"/"+it1->name;
-      if (!it1->obj) {
-	std::cout << "Object " << fullName << " not properly set up. Not merged." << std::endl;
-	continue;
-      }
-      TObject* obj=in->Get(fullName.c_str());
-      if (!obj) {
-	std::cout << "ERROR: Could not access path " << fullName <<" in file " << in->GetName() << std::endl;
-      }
-      else
-	(*it1->mergeMethod)(it1->obj,obj);
-    }//End loop over histograms in directory
-  }//End loop over directory names
-  return;
-}
-
-void histCollection::write(TFile* out) {
-  unsigned nWritten=0;
-  unsigned nIgnored=0;
-  TDirectory* histDir=nullptr;
-  std::string lastDir;
-  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
-  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
-  for(;it!=it_e;++it) {
-    const std::string fulldir=it->first + "/";
-    //Create dirs if necessary
-    std::string::size_type j=0,j1=0;
-    while (j1!=std::string::npos) {
-      do {
-	j=j1+1;
-	j1=fulldir.find('/',j);
-	//std::cout << "Inner loop " << fulldir.substr(0,j1) << " << ==? " <<  lastDir.substr(0,j1) << std::endl;
-      }
-      while(j1!=std::string::npos && !fulldir.compare(0,j1,lastDir,0,j1));
-      const std::string currDirAtLevel(fulldir.substr(j,j1-j));
-      const std::string currFullDir(fulldir.substr(0,j1));
-      const std::string currBaseDir(fulldir.substr(0,j));
-      //std::cout << "Working on dir " << fulldir << " [" << currFullDir << " " << currBaseDir << " " << currDirAtLevel << std::endl;
-      lastDir=currFullDir;
-      out->cd(currBaseDir.c_str());
-      gDirectory->mkdir(currDirAtLevel.c_str());
-    }//End outer while loop - full directory created 
-    //std::cout << "Done creating " << fulldir << std::endl;
-    out->cd(fulldir.c_str());
-    it->second.md->SetDirectory(histDir);
-    it->second.md->Write(nullptr,TObject::kOverwrite);
-    std::vector<histPerDir_t>::const_iterator ith=it->second.histos.begin();
-    std::vector<histPerDir_t>::const_iterator ith_e=it->second.histos.end();
-    for (;ith!=ith_e;++ith) {
-      if (ith->obj) {
-	ith->obj->Write();
-	std::cout << "Writing " <<  ith->name << " to dir " << fulldir << std::endl;
-	++nWritten;
-      }
-      else {
-	std::cout << "NOT writing " <<  ith->name << ". Invalid." << std::endl;
-	++nIgnored;
-      }
-    }//End loop over histograms in one directory
-  }//End loop over directories;
-  std::cout << "Wrote " << nWritten << " histograms to output file.";
-  if (nIgnored) 
-    std::cout << " Omitting " << nIgnored << " histograms." << std::endl;
-  else
-    std::cout << std::endl;
-  return;
-}
-
-std::vector<std::string> splitString(const std::string& in, const std::string& delim) {
-  std::vector<std::string> retvec;
-  size_t pos1=0,pos2=0;
-  while (pos2!=std::string::npos) {
-    pos2=in.find_first_of(delim,pos1);
-    const std::string sub=in.substr(pos1,pos2-pos1);
-    if (!sub.empty())
-      retvec.push_back(sub);
-    pos1=pos2+1;
-  }
-  return retvec;
-}
-
-bool readFromTextFile(const char* filename, std::vector<std::string>& out) {
-  std::ifstream ifs (filename, std::ifstream::in );
-  if (!ifs.good()) {
-    std::cout << "Failed to open file " << filename << " for reading." << std::endl;
-    return false;
-  }
-  while (ifs.good()) {
-    std::string line;
-    getline(ifs,line);
-    //Bit of cleaning and splitting:
-    const std::vector<std::string> linetok=splitString(line," ,;\t\n");
-    std::vector<std::string>::const_iterator it=linetok.begin();
-    std::vector<std::string>::const_iterator it_e=linetok.end();
-    for(;it!=it_e;++it) {
-      if ((*it)[0]=='#') break; //ingore all characters behind '#'
-      out.push_back(*it);
-    }
-    //if (!line.size()) continue;
-    //out.push_back(line);
-  }
-  ifs.close();
-  return true;
-}
-
-// =================================================================================================
-int main(int argc, char** argv) {
-
-  if (argc<2 || (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")))) {
-    std::cout << "Syntax:\n" << argv[0] << " [-v ] [-i inputTextFile] [-d directroy] <outfile> <infile1> <infile2> .... " << std::endl;
-    std::cout << "  -v verbose " << std::endl;
-    return -1;
-  }
-
-  bool debug=false;
-  std::string outFileName;
-  std::vector<std::string> inFileNames;
-  std::vector<std::string> baseDirs;
-
-  for(int iArg=1;iArg<argc;++iArg) {
-    if (!strcmp(argv[iArg],"-v")) {
-      debug=true;
-      continue;
-    }
-
-    if (!strcmp(argv[iArg],"-d")) {
-      ++iArg;
-      if (argc<=iArg) {
-	std::cout << "ERROR: Expected a parameter (directory name) after '-d'" << std::endl;
-	return -1;
-      }
-      baseDirs.push_back(std::string(argv[iArg]));
-      continue;
-    }
-    
-
-    if (!strcmp(argv[iArg],"-i")) {
-      ++iArg;
-      if (argc<=iArg) {
-	std::cout << "ERROR: Expected text file name after '-i'" << std::endl;
-	return -1;
-      }
-      readFromTextFile(argv[iArg],inFileNames);
-      continue;
-    }
-    if (outFileName.empty())
-      outFileName=argv[iArg];
-    else
-      inFileNames.push_back(std::string(argv[iArg]));
-  }//end loop over arguments
-  
-  
-  if (outFileName.empty()) {
-    std::cout << "ERROR: No output file name given!" << std::endl;
-    return -1;
-  }
-
-  if (!gSystem->AccessPathName(outFileName.c_str())) {
-    std::cout << "ERROR: Output file " << outFileName << " exists already!" << std::endl;
-    return -1;
-  }
-
-  if (inFileNames.empty()) {
-    std::cout << "WARNING: No input files given! Will produce empty output file" << std::endl;
-  }
-
-
-  std::cout << "Number of input files: " << inFileNames.size() << std::endl;
-  std::cout << "Output file: " << outFileName << std::endl;
-  
-  if (baseDirs.empty()) {
-    baseDirs.push_back("LAr");
-    baseDirs.push_back("CaloMonitoring/LArCellMon_NoTrigSel");
-    baseDirs.push_back("CaloTopoClusters/CalBAR");
-    baseDirs.push_back("CaloTopoClusters/CalECA");
-    baseDirs.push_back("CaloTopoClusters/CalECC");
-    baseDirs.push_back("CaloTopoClusters/CalEMBAR");
-    baseDirs.push_back("CaloTopoClusters/CalEMECA");
-    baseDirs.push_back("CaloTopoClusters/CalEMECC");
-
-  }
-  else {
-    //clean superfluos slash characters
-    for (size_t i=0;i<baseDirs.size();++i) {
-      std::vector<std::string> dirtok=splitString(baseDirs[i],std::string("/"));
-      if (dirtok.empty()) {
-	baseDirs[i].clear();
-	continue;
-      }
-      baseDirs[i]=dirtok[0];
-      for (size_t j=1;j<dirtok.size();++j) {
-	baseDirs[i]+="/"+dirtok[j];
-      }//eld loop over dir tokens
-    }//end loop over directories
-  }
-
-  // Keeping track of which directories we found
-  std::vector<std::string> foundDirs;
-
-  histCollection listOfHists(debug);
-  listOfHists.addExclusion("/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
-
-  TFile* in1=nullptr;
-  std::string runDir("/");
-  size_t fileIndex=0;
-  unsigned nSkippedFiles=0;
-
-  const size_t nFiles=inFileNames.size(); 
-
-  //Loop to find the first non-empty file
-  //for (;fileIndex<nFiles && runDir.size()==1;++fileIndex) {
-  for (;fileIndex<nFiles && foundDirs.size()!=baseDirs.size() ;++fileIndex) {
-    //in1=TFile::Open(inFileNames[fileIndex].c_str(),"READ");
-    in1=openWithRetry(inFileNames[fileIndex].c_str());
-    if (!in1) {
-      std::cout << "ERROR: Could not open first file " << inFileNames[fileIndex] << "after all attempts" << std::endl;
-      if (nSkippedFiles>MAXSKIPPEDFILES) {
-	std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
-	return -1;
-      }
-      if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
-	std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
-	return -1;
-      }
-      ++nSkippedFiles;
-      std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
-      continue;
-    }
-
-    std::cout << "First loop: Working on file " << inFileNames[fileIndex] <<std::endl;
-    //Get run_XXXX directory name
-    TIter next(in1->GetListOfKeys() );
-    TKey* key;
-    while((key=(TKey*)next()))  {
-      const char* name=key->GetName();
-      if (!strncmp(name,"run_",4)) {
-	if (runDir.size()>1) {
-	  std::cout << "ERROR More than one run_XXX directory found! Ignoring " <<  name << std::endl;
-	}
-	else
-	  runDir.append(name);
-      }
-    }
- 
-    if (runDir.size()==1) {
-      std::cout << "WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
-      in1->Close();
-      continue;
-    }
-
-    //Collect histogram directories
-    std::vector<std::string>::const_iterator dIt=baseDirs.begin();
-    std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
-
-    for (;dIt!=dIt_e;++dIt) {
-      std::string dirName=runDir+"/"+(*dIt);
-      // In case we are looping over more files to find the directory
-
-      TDirectory* dir=dynamic_cast<TDirectory*>(in1->Get(dirName.c_str()));
-      if (!dir) {
-	std::cout << "Did not find directory " << dirName <<" in file "<<inFileNames[fileIndex].c_str()<<" !" << std::endl;
-	continue;
-      }
-      if (std::find(foundDirs.begin(), foundDirs.end(), dirName) != foundDirs.end())
-	{
-	  std::cout<<"Already found "<<dirName<<" before"<<std::endl;
-	  //continue;
-	}else{
-	foundDirs.push_back(dirName);
-      }
-      if (debug) std::cout << "Found directory " << dirName <<" in file "<<inFileNames[fileIndex].c_str()<<" !" << std::endl;
-      listOfHists.addDirectory(dir,dirName);
-    }
-
-    std::cout << "Number of directories: " << listOfHists.size() << std::endl;
-    std::cout<<"SIZE "<< listOfHists.size() <<std::endl;
-
-    if (debug) listOfHists.print();
-    
-    //std::cout << "Closing first file" << std::endl;
-    //in1->Close("R");
-    //delete in1;
-  }//end loop to find first non-empty file
- 
-  for (;fileIndex<nFiles;++fileIndex) { // Loop over remaining files
-    const char* filename=inFileNames[fileIndex].c_str();
-    //TFile* in=TFile::Open(filename,"READ");
-    TFile* in=openWithRetry(filename);
-    if (!in) {
-      std::cout << "ERROR: Could not open file " << filename << "after all attempts" << std::endl;
-      if (nSkippedFiles>MAXSKIPPEDFILES) {
-	std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
-	return -1;
-      }
-      if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
-	std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
-	return -1;
-      }
-      ++nSkippedFiles;
-      std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
-      continue;
-    }
-    std::cout << "Working on file " << filename << std::endl;
-    TObject* dirObj=in->Get(runDir.c_str()+1);
-    if (!dirObj) {
-      std::cout << "Directory " << runDir << " not found. Ignoring apprently empty file" << std::endl;
-    }
-    else
-      listOfHists.addFile(in);
-    in->Close();
-    delete in;
-  }
-
-  TFile* out=new TFile(outFileName.c_str(),"NEW");
-  if (!out || !out->IsOpen()) {
-    std::cout << "ERROR: Failed to open output file " << outFileName << " for writing" << std::endl;
-    return -1;
-  }
-  listOfHists.write(out);
-  out->Close();
-  delete out;
-
-  if (in1 && in1->IsOpen()) {
-    in1->Close();
-    delete in1;
-  }
-
-  if (nSkippedFiles>0) {
-    std::cout << "WARNING: Skipped " << nSkippedFiles << " input file(s)." << std::endl;
-  }
-
-  return 0;
-}