diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/DEVELOPERS b/PhysicsAnalysis/TauID/TauDiscriminant/DEVELOPERS new file mode 100644 index 0000000000000000000000000000000000000000..5db36bd3a0ccfe204f1e78ba91ce89d98f260973 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/DEVELOPERS @@ -0,0 +1,13 @@ +A Message to Developers +----------------------- + + + + +* Your Athena-based algorithms MUST inherit from +TauDiscriToolBase and implement the interface there. + +* If you want your id method to be useable by +TauIDReader on ROOT ntuples, your underlying id +class MUST inherit from MethodBase (and implement +the interface) and MUST NOT depend on Athena-based headers. diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/README b/PhysicsAnalysis/TauID/TauDiscriminant/README new file mode 120000 index 0000000000000000000000000000000000000000..92cacd285355271487b7e379dba6ca60f9a554a4 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/README @@ -0,0 +1 @@ +README.rst \ No newline at end of file diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/README.rst b/PhysicsAnalysis/TauID/TauDiscriminant/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..e1dd49788755e9f8be8febef1a31bd135a821878 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/README.rst @@ -0,0 +1,80 @@ +.. -*- mode: rst -*- + +Compilation within Athena +========================= + +To compile TauDiscriminant for use in Athena:: + + cd cmt + make + cd .. + + +Standalone Compilation +====================== + +Note: this does not require Athena in any way (setup or installed) +Note: that means **DO NOT SETUP ATHENA BEFORE DOING THE FOLLOWING** +(See "Known Problems" below) + +To compile a standalone library for use with ROOT and Python:: + + cd cmt + make -f Makefile.Standalone + cd .. + +This produces the shared object lib/libTauDiscriminant.so +Put this shared object in your ``LD_LIBRARY_PATH`` by executing:: + + source setup.sh + +The library may now be loaded in CINT like this:: + + gSystem->Load("libTauDiscriminant.so"); + +or in Python like this:: + + import ROOT + ROOT.gSystem.Load("libTauDiscriminant.so") + +Now you may follow the same procedure as in run/tauid-redo:: + + import ROOT + ROOT.gSystem.Load("libTauDiscriminant.so") + from ROOT import TauID + reader = TauID.TauIDReader(True) + # etc. + + +Recalculate Tau ID on D3PD (ROOT ntuples) +========================================= + +Compile TauDiscriminant by one of the two methods above and source setup.sh +Then execute tauid-redo:: + + tauid-redo *.root + +This will create new D3PDs with a suffix appended to the filenames +which contain branches for the newly calculated discriminants. +For more information execute:: + + tauid-redo --help + + +Known Problems +============== + +When running tauid-redo after a standalone compilation it might crash with:: + + AttributeError: type object 'TauID' has no attribute 'Types' + +This is most likely because you have Athena setup. Don't setup Athena. +Just use the default Python/ROOT installation on your system. + + +Additional Tools +================ + +Tools used to train BDTs, apply MVAs to ROOT ntuples, make performance plots, +convert TMVA BDT xml or MethodCuts files into TauDiscriminant format, etc. +are in the "taumva" package. taumva is now available from TauDiscriminantTools. diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/BoostedDecisionTree.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/BoostedDecisionTree.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b14d54b1c35e85e54061856c047ee175801fb85c --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/BoostedDecisionTree.cxx @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: BoostedDecisionTree.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/BoostedDecisionTree.h" + +float BoostedDecisionTree::response() const { + + float sum = 0.; + float norm = 0.; + Node* currentNode = 0; + DecisionNode* decision = 0; + LeafNode<float>* leafNode = 0; + vector<pair<Node*,float> >::const_iterator tree = this->trees.begin(); + while(tree != this->trees.end()) { + currentNode = (*tree).first; + while (!currentNode->isLeaf()) { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) { + currentNode = decision->getRightChild(); + } else { + currentNode = decision->getLeftChild(); + } + if (!currentNode) return -200.; + } + leafNode = static_cast<LeafNode<float>*>(currentNode); + sum += ((*tree).second)*leafNode->getValue(); + norm += (*tree).second; + ++tree; + } + return norm > 0. ? sum/norm : -100.; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/CommonLikelihood.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/CommonLikelihood.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0c990748003183184ce5add3e5ce9d93afc5f7cf --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/CommonLikelihood.cxx @@ -0,0 +1,626 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: CommonLikelihood.cxx + * + * Author: Martin Flechl (mflechl@cern.ch) + * Marcin Wolter (marcin.wolter@cern.ch) + * updated 16 May 2011 + */ + +#include "TauDiscriminant/CommonLikelihood.h" +#include <cmath> + + +TString m=""; +const double SMALL = 1.e-6; + +bool CommonLikelihood::build(const string& filename) { + + if (filename != ""){ //otherwise try defaults from constructor + vector<string> substrings; + this->splitString(filename,substrings,","); + if (substrings.size()==3){ + m_tauFilename=substrings[0]; + m_jetFilename=substrings[1]; + m_cutFilename=substrings[2]; + } else{ + //to do: otherwise, try defaults..... + print("Exactly 3 files required, e.g. \"pdf_taus.root,pdf_jet.root,LMTCutsLLH.root\".",0); + } + m="PDF files: tau="+m_tauFilename+", jet="+m_jetFilename+", cuts="+m_cutFilename; + print(m,0); + } + + return (this->readPDFHistograms() && this->readLMTCuts() && this->smoothPDFHistograms()); +} + +int CommonLikelihood::response(int ilmt, int /*option*/) const { + if(ilmt < 0 || ilmt > 2) + return 0; + std::vector<TGraph*> cuts; + int prongcat = m_prongindex; + if(prongcat==0) + cuts=m_vLMTCuts1P; + else if(prongcat==1) + cuts=m_vLMTCuts3P; + else + return 0; + if(cuts.size()!=3) + return 0; + double cut = cuts.at(ilmt)->Eval(m_et/1000.); + if ( m_llh>cut ) return 1; + else return 0; +} + +bool CommonLikelihood::calcLLHValue(const map<string,const float*>* floatVariables, + const map<string,const int*>* intVariables, int option=0){ + //option 0: safe llh; 1: default llh; 2: use whatever vars given in maps above + + m="In calcLLHValue, option="; m+=option; + print(m,2); + + m_llh=-999; + + map<string,const float*>::const_iterator it_floats; + map<string,const int*>::const_iterator it_ints; + + map<string,float> allVariables; + map<string,float>::const_iterator it_all; + + int author; + it_ints = intVariables->find("AUTHOR"); + if (it_ints == intVariables->end()) { + it_floats = floatVariables->find("AUTHOR"); + if (it_floats == floatVariables->end()) { + print("Cannot find AUTHOR in booked float or int variables!",0); + return false; + } else{ + author=(int)*(it_floats->second); + } + } else{ + author=*(it_ints->second); + } + if ( author==2 ){ + print("Author==2, assigning llh value -1111!",1); + m_llh=-1111; return true; + } //as tauRec does + + it_floats = floatVariables->find("PT"); + if (it_floats == floatVariables->end()) { + print("Cannot find PT in booked float variables!",0); + return false; + } + float et=*(it_floats->second); + + + it_floats = floatVariables->find("ETA"); + if (it_floats == floatVariables->end()) { + print("Cannot find ETA in booked float variables!",0); + return false; + } + float eta=*(it_floats->second); + if ( fabs(eta)>2.5 ){ print("Not within eta range",2); m_llh=-96; return true;} //as tauRec does + + it_ints = intVariables->find("NUMTRACK"); + if (it_ints == intVariables->end()) { + print("Cannot find NUMTRACK in booked int variables!",0); + return false; + } + int numtrack=*(it_ints->second); + if ( numtrack<1 ) { print("0 tracks",2); m_llh=-97; return true;} //as tauRec does + m_prongindex=0; //1pr + if (numtrack>=2) m_prongindex=1; //3pr + m_ntau[m_prongindex]++; +/* + it_ints = intVariables->find("NUMPI0"); + if (it_ints == intVariables->end()) { + it_ints = intVariables->find("NPI0"); + if (it_ints == intVariables->end()) { + print("Cannot find NUMPI0 in booked int variables!",0); + return false; + } + } + int numpi0=*(it_ints->second); +*/ + int nvtx=1; + it_ints = intVariables->find("NUM_PILEUP_AND_PRIMARY_VERTICES"); + if (it_ints == intVariables->end()) { + print("Cannot find NUM_PILEUP_AND_PRIMARY_VERTICES in booked int variables!",0); + print("Setting value to 1 and will try running, but the output will not be valid.",0); + } else nvtx=*(it_ints->second); + m_nvtx=nvtx; + + m="author: "; m+=author; m+=", et:"; m+=et; m+=", eta:"; m+=eta; + m+=", numtrack:"; m+=numtrack; //m+=", numpi0:"; m+=numpi0; + print(m,1); + + + allVariables = getVariables(floatVariables, intVariables, numtrack, author, option); + + + + m="nInts: "; m+=intVariables->size(); m+=", nFloats: "; m+=floatVariables->size(); + m+=", nAll: "; m+=allVariables.size(); + m+=", numtrack="; m+=numtrack; + print(m,1); + //print(m,0); + + //check if all vars are there + if (option==0){ //safeLLH + if ( ( numtrack==1 && (allVariables.size()!=NVAR_SAFE_1P) ) || ( numtrack>=2 && (allVariables.size()!=NVAR_SAFE_3P) ) ){ + print("Not all safe variables found... giving up! Use the llhall option to run over a specific set of variables.",0); + return false; + } + } + + + double calcLH=0; + + print("Start filling vars",2); + + for(it_all=allVariables.begin(); it_all!=allVariables.end(); ++it_all){ + m="Var: "+it_all->first; + int ivar=this->varNameToNumber(it_all->first); + if (ivar<0){ print("ERROR: Unknown Variable "+it_all->first,0+(m_ntau[m_prongindex]>1)); continue; } + m+=", var #"; m+=ivar; m+=", value="; m+=it_all->second; + print(m,1); + + calcLH+=getSingleLLHRatio(ivar, numtrack, author, et, nvtx, (float) it_all->second); + } + + m_et = et; + m_llh=calcLH; + return true; +} + + +map<string,float> CommonLikelihood::getVariables(const map<string,const float*>* floatVariables, const map<string,const int*>* intVariables, const int numtrack,const int author, const int option) const{ + + + + const string use_safe[2][NVAR_SAFE_3P]={ + {"CORRCENTFRAC","CORRFTRK","TRKAVGDIST","NUMWIDETRACK","IPSIGLEADTRK",""}, //1PR + {"CORRCENTFRAC","CORRFTRK","TRKAVGDIST","DRMAX","MASSTRKSYS","TRFLIGHTPATHSIG"}}; //3PR + + const string use_def[2][NVAR_DEF]={ + {"TRKAVGDIST","CORRFTRK","IPSIGLEADTRK","DRMAX","MASSTRKSYS","TRFLIGHTPATHSIG","NUMWIDETRACK","CORRCENTFRAC"}, + {"TRKAVGDIST","CORRFTRK","IPSIGLEADTRK","DRMAX","MASSTRKSYS","TRFLIGHTPATHSIG","NUMWIDETRACK","CORRCENTFRAC"} + }; +/* {"EMRADIUS","ISOLFRAC","STRIPWIDTH2","NSTRIP","ETHAD2ETTRACKS","ETEM2ETTRACKS","ETTRACKS2ET","", "", "", "", + "NISOLTRK","MVISEFLOW","IPZ0SINTHETASIGLEADTRK","IPSIGLEADLOOSETRK",""}, + {"EMRADIUS","ISOLFRAC","STRIPWIDTH2","NSTRIP","ETHAD2ETTRACKS","ETEM2ETTRACKS","ETTRACKS2ET","DRMIN","DRMAX","TRKWIDTH2","MASSTRKSYS", + "NISOLTRK","MVISEFLOW","", "IPSIGLEADLOOSETRK","TRFLIGHTPATHSIG"}}; +*/ + const string use_author3[NVAR_DEF] = {"","","","","","","","","","TRKWIDTH2","MASSTRKSYS","NISOLTRK","MVISEFLOW","IPZ0SINTHETASIGLEADTRK","","TRFLIGHTPATHSIG"}; + const string use_3trk[NVAR_DEF] = {"","","","","","","","","","TRKWIDTH2","MASSTRKSYS","","","","",""}; + + + map<string,const float*>::const_iterator it_floats; + map<string,const int*>::const_iterator it_ints; + + int prong=m_prongindex; //1pr + + map<string, float> allVariables; + + + float et = 1.; + it_floats = floatVariables->find("ET"); + if (it_floats != floatVariables->end()) { + et=*(it_floats->second); + } + else et=99.; + + + switch (option){ + case 0: //safe + for(unsigned int i=0; i<NVAR_SAFE_3P; i++) { + if (use_safe[prong][i] != "") { + it_floats = floatVariables->find(use_safe[prong][i]); + if (it_floats != floatVariables->end()) { + if ( it_floats->first=="ETTRACKS2ET" ){ + print("Modified etTracks2Et",2); + if (fabs(et)<SMALL) allVariables[it_floats->first]= *(it_floats->second)/et; + else allVariables[it_floats->first] = 999.; + } + else allVariables[it_floats->first]= *(it_floats->second); + } + + it_ints = intVariables->find(use_safe[prong][i]); + if (it_ints != intVariables->end()) { + allVariables[it_ints->first]= *(it_ints->second); + } + + } + } + break; + case 1: //def + if ( author==1 ){ //no track-seed + for(unsigned int i=0; i<NVAR_DEF; i++) { + if (use_author3[i] != "") { + it_floats = floatVariables->find(use_author3[i]); + if (it_floats != floatVariables->end()) { + allVariables[it_floats->first]= *(it_floats->second); + } + + it_ints = intVariables->find(use_author3[i]); + if (it_ints != intVariables->end()) { + allVariables[it_ints->first]= *(it_ints->second); + } + } + } + } + else if ( numtrack!=3 ){ //not exactly 3 tracks + for(unsigned int i=0; i<NVAR_DEF; i++) { + if (use_3trk[i] != "") { + it_floats = floatVariables->find(use_3trk[i]); + if (it_floats != floatVariables->end()) { + allVariables[it_floats->first]= *(it_floats->second); + } + + it_ints = intVariables->find(use_3trk[i]); + if (it_ints != intVariables->end()) { + allVariables[it_ints->first]= *(it_ints->second); + } + } + } + } + else { + for(unsigned int i=0; i<NVAR_DEF; i++) { + if (use_def[prong][i] != "") { + it_floats = floatVariables->find(use_def[prong][i]); + if (it_floats != floatVariables->end()) { + allVariables[it_floats->first]= *(it_floats->second); + } + + it_ints = intVariables->find(use_def[prong][i]); + if (it_ints != intVariables->end()) { + allVariables[it_ints->first]= *(it_ints->second); + } + } + } + } + break; + default: + print("ERROR: getVariables, option > 1",0); + break;;//take any var + } + + return allVariables; + +} + + + + + +float CommonLikelihood::getSingleLLHRatio(const int ivar, const int numtrack, const int author, const float et, const int nvtx, const float value){ + + float LLHR = this->getSimpleSingleLLHRatio( ivar, numtrack, author, et, nvtx, value ); + + //for now hard-coding the pt-bin boundaries (45,100), should be automatized... + float border[]={45.,100.}; + for(int b=0;b<2;b++){ + float closetoborder=et/1000.-(border[b]); + + double uppBorder = 10.0; + double lowBorder = 10.0; + + if( border[b] >= 100. && numtrack == 1 && !(m_doTrigger) ) { + uppBorder = 60.0; + lowBorder = 30.0; + } + + if( closetoborder >= 0 && fabs(closetoborder) < uppBorder ) { + float nextbin = (border[b]-lowBorder/2.0)*1000.0; + float LLHRnext = this->getSimpleSingleLLHRatio( ivar, numtrack, author, nextbin, nvtx, value ); + LLHR = LLHR*((uppBorder+fabs(closetoborder))/(uppBorder*2.0)) + LLHRnext*((uppBorder-fabs(closetoborder))/(uppBorder*2.0)); + } + + + if( closetoborder < 0 && fabs(closetoborder) < lowBorder ) { + float nextbin = (border[b]+uppBorder/2.0)*1000.0; + float LLHRnext = this->getSimpleSingleLLHRatio( ivar, numtrack, author, nextbin, nvtx, value ); + LLHR = LLHR*((lowBorder+fabs(closetoborder))/(lowBorder*2.0)) + LLHRnext*((lowBorder-fabs(closetoborder))/(lowBorder*2.0)); + } + } + return LLHR; +} + + + +float CommonLikelihood::getSimpleSingleLLHRatio(const int ivar, const int numtrack, const int author, const float et, const int nvtx, const float value){ + + const std::string prongs[]={"","1prong","","3prong"}; + const std::string classes[]={"both","calo"}; + + int prongcat=1; int authorcat=0; + if(numtrack >= 2){ prongcat=3; authorcat=0; } + if(author==2) return -1111; + std::string prongType=prongs[prongcat]; + std::string authorType=classes[authorcat]; + + char text[100]; + sprintf(text,"_v%d",ivar); + std::string hNameLong = "hpdf"; + hNameLong+=+"_"+prongType; + hNameLong+=+"_"+authorType; + hNameLong.append(text); + TH3F *hratio = m_pdfHistogramsRatio[hNameLong]; + + m="tau nentries: "; m+=hratio->GetEntries(); m+=", nbins: "; m+=hratio->GetNbinsX(); + print(m,2); + TAxis *xaxis = hratio->GetXaxis(); + TAxis *yaxis = hratio->GetYaxis(); + TAxis *zaxis = hratio->GetZaxis(); + + float xMin = xaxis->GetXmin(); + float xMax = xaxis->GetXmax(); // + + m=""; m+=xMin; m+=" - "; m+=xMax; + print(m,2); + float etMax = yaxis->GetXmax(); + float vtxMax = zaxis->GetXmax(); + + int p_nvtx=nvtx; + float temp_et=et; + if ( nvtx>vtxMax ) p_nvtx=(int) vtxMax; + if ( temp_et/1000.0>etMax ) temp_et=(etMax*1000)-1; + if (value<xMin) return 0; + + float varLL = this->Interpolate(hratio,value,temp_et/1000.0,p_nvtx); + + m="llhratio value of this var: "; m+=varLL; + print(m,1); + + return varLL; +} + + + +bool CommonLikelihood::readPDFHistograms() { + print("in readPDFHistograms()",2); + + m_tauFile = new TFile(m_tauFilename.c_str()); + m_jetFile = new TFile(m_jetFilename.c_str()); + + const int nProngdirs=2; + const int nClassdirs=1; + const std::string prongs[nProngdirs]={"1prong","3prong"}; + const std::string classes[nClassdirs]={"both"/*,"calo"*/}; + + for (int iProng=0; iProng<nProngdirs; iProng++) { + for (int iClass=0; iClass<nClassdirs; iClass++) { + std::string prongDir = prongs[iProng]; + std::string classDir = classes[iClass]; + for (int ivar=0; ivar<=NVAR; ivar++) { + + char text[100]; + sprintf(text,"_v%d",ivar); + std::string hNameLong = "hpdf"; + hNameLong+=+"_"+prongDir; + hNameLong+=+"_"+classDir; + hNameLong.append(text); + std::string hname = prongDir+"/"+classDir+"/"+hNameLong; + + TH3F* hTmp_tau = (TH3F*)m_tauFile->Get(hname.c_str()); + TH3F* hTmp_jet = (TH3F*)m_jetFile->Get(hname.c_str()); + + m_pdfHistogramsTau[hNameLong] = (TH3F*)hTmp_tau; + m_pdfHistogramsJet[hNameLong] = (TH3F*)hTmp_jet; + + } + } + } + + return true; +} + +bool CommonLikelihood::readLMTCuts() { + print("in readLMTCuts()",2); + + m_cutFile = new TFile(m_cutFilename.c_str()); + if(m_cutFile==0) return false; //assert(m_cutFile!=0); + tg_loose_cuts_1P = (TGraph*) m_cutFile->Get("1prong/loose"); + tg_medium_cuts_1P = (TGraph*) m_cutFile->Get("1prong/medium"); + tg_tight_cuts_1P = (TGraph*) m_cutFile->Get("1prong/tight"); + + if(tg_loose_cuts_1P==0 || tg_medium_cuts_1P==0 || tg_tight_cuts_1P==0) + return false; + m_vLMTCuts1P.push_back(tg_loose_cuts_1P); + m_vLMTCuts1P.push_back(tg_medium_cuts_1P); + m_vLMTCuts1P.push_back(tg_tight_cuts_1P); + tg_loose_cuts_3P = (TGraph*) m_cutFile->Get("3prong/loose"); + tg_medium_cuts_3P = (TGraph*) m_cutFile->Get("3prong/medium"); + tg_tight_cuts_3P = (TGraph*) m_cutFile->Get("3prong/tight"); + + if(tg_loose_cuts_3P==0 || tg_medium_cuts_3P==0 || tg_tight_cuts_3P==0) + return false; + m_vLMTCuts3P.push_back(tg_loose_cuts_3P); + m_vLMTCuts3P.push_back(tg_medium_cuts_3P); + m_vLMTCuts3P.push_back(tg_tight_cuts_3P); + + return true; +} + + +bool CommonLikelihood::smoothPDFHistograms() { + print("in smoothPDFHistograms()",2); + + const int nProngdirs=2; + const int nClassdirs=1; + const std::string prongs[nProngdirs]={"1prong","3prong"}; + const std::string classes[nClassdirs]={"both"/*,"calo"*/}; + + for (int iProng=0; iProng<nProngdirs; iProng++) { + for (int iClass=0; iClass<nClassdirs; iClass++) { + std::string prongDir = prongs[iProng]; + std::string classDir = classes[iClass]; + for (int ivar=0; ivar<=NVAR; ivar++) { + char text[100]; + sprintf(text,"_v%d",ivar); + std::string hNameLong = "hpdf"; + hNameLong+=+"_"+prongDir; + hNameLong+=+"_"+classDir; + hNameLong.append(text); + if (m_pdfHistogramsTau[hNameLong] && m_pdfHistogramsJet[hNameLong]){ + if (m_smooth) { + this->smooth3D(m_pdfHistogramsTau[hNameLong]); + this->smooth3D(m_pdfHistogramsJet[hNameLong]); + } + m_pdfHistogramsRatio[hNameLong] = this->divideLog(m_pdfHistogramsTau[hNameLong],m_pdfHistogramsJet[hNameLong]); + } + } + } + } + return true; +} + +void CommonLikelihood::smooth3D(TH3F* hTmp){ + + for (int i=1;i<=hTmp->GetNbinsY();i++){ + for (int j=1;j<=hTmp->GetNbinsZ();j++){ + TH1D* tmp = hTmp->ProjectionX("projX",i,i,j,j,""); + tmp->Smooth(5); + for (int k=1;k<=tmp->GetNbinsX();k++) + hTmp->SetBinContent(k,i,j,tmp->GetBinContent(k)); + delete tmp; tmp=0; + } + } +} + +TH3F* CommonLikelihood::divideLog(TH3F* hTmpTau, TH3F* hTmpJet){ + if ( + hTmpTau->GetNbinsX() != hTmpJet->GetNbinsX() || + hTmpTau->GetNbinsY() != hTmpJet->GetNbinsY() || + hTmpTau->GetNbinsZ() != hTmpJet->GetNbinsZ() + ) return 0; + TH3F* hTmpRatio = new TH3F(*hTmpTau); + hTmpRatio->Reset(); + for (int i=0;i<=hTmpTau->GetNbinsY()+1;i++){ + for (int j=0;j<=hTmpTau->GetNbinsZ()+1;j++){ + for (int k=0;k<=hTmpTau->GetNbinsX()+1;k++) { + float tauLL = hTmpTau->GetBinContent(k,i,j); + float jetLL = hTmpJet->GetBinContent(k,i,j); + if(fabs(jetLL)<SMALL) jetLL = SMALL; + if(!tauLL) tauLL = SMALL; + float varLL=TMath::Log(tauLL/jetLL); + hTmpRatio->SetBinContent(k,i,j,varLL); + } + } + } + return hTmpRatio; +} + +Double_t CommonLikelihood::Interpolate(TH3F* hist, Double_t x, Double_t y, Double_t z) +{ + // Given a point x, approximates the value via linear interpolation + // based on the two nearest bin centers + + + Int_t ibin = hist->FindBin(x,y,z); + Int_t xbin, ybin, zbin; + hist->GetBinXYZ(ibin, xbin, ybin, zbin); + if (!m_smooth) return hist->GetBinContent(ibin); + + Double_t x0,x1,y0,y1; + + if(xbin<=1 || xbin>=hist->GetNbinsX()) { + return hist->GetBinContent(ibin); + } else { + if(x<=hist->GetXaxis()->GetBinCenter(xbin)) { + y0 = hist->GetBinContent(xbin-1, ybin, zbin); + x0 = hist->GetXaxis()->GetBinCenter(xbin-1); + y1 = hist->GetBinContent(xbin, ybin, zbin); + x1 = hist->GetXaxis()->GetBinCenter(xbin); + } else { + y0 = hist->GetBinContent(xbin, ybin, zbin); + x0 = hist->GetXaxis()->GetBinCenter(xbin); + y1 = hist->GetBinContent(xbin+1, ybin, zbin); + x1 = hist->GetXaxis()->GetBinCenter(xbin+1); + } + if (fabs(x1-x0)<SMALL && fabs(x1-x0)!=0.) return y0 + (x-x0)*((y1-y0)/(x1-x0)); + else return 999.; + } +} + +int CommonLikelihood::varNameToNumber(std::string varname) const { + if(varname=="emRadius" || varname=="EMRADIUS" ) return 0; + if(varname=="isolFrac" || varname=="ISOLFRAC" ) return 1; + if(varname=="stripWidth2" || varname=="STRIPWIDTH2" ) return 2; + if(varname=="nStrip" || varname=="NSTRIP" ) return 3; + if(varname=="etHad2etTracks" || varname=="ETHAD2ETTRACKS" ) return 4; + if(varname=="etEM2etTracks" || varname=="ETEM2ETTRACKS" ) return 5; + if(varname=="etTracks2et" || varname=="ETTRACKS2ET" ) return 6; + if(varname=="etEM2Et" || varname=="ETEM2ET" || varname=="EMFRACTIONCALIB" || varname=="EMFRACTIONATEMSCALE" ) return 7; + if(varname=="etOverPtLeadTrk" || varname=="ETOVERPTLEADTRK" ) return 8; + if(varname=="dRmin" || varname=="DRMIN" ) return 9; + if(varname=="dRmax" || varname=="DRMAX" ) return 10; + if(varname=="trkWidth2" || varname=="TRKWIDTH2" ) return 11; + if(varname=="massTrkSys" || varname=="MASSTRKSYS" ) return 12; + if(varname=="nIsolTrk" || varname=="NISOLTRK" ) return 13; + if(varname=="MVisEflow" || varname=="MVISEFLOW" ) return 14; + if(varname=="ipZ0SinThetaSigLeadTrk" || varname=="IPZ0SINTHETASIGLEADTRK" ) return 15; + if(varname=="ipSigLeadLooseTrk" || varname=="IPSIGLEADLOOSETRK" ) return 16; + if(varname=="trFlightPathSig" || varname=="TRFLIGHTPATHSIG" ) return 17; + if(varname=="centFrac" || varname=="CENTFRAC" ) return 18; + if(varname=="numEffClus" || varname=="NUMEFFCLUS" ) return 19; + if(varname=="trkAvgDist" || varname=="TRKAVGDIST" ) return 20; + if(varname=="topoInvMass" || varname=="TOPOINVMASS" ) return 21; + if(varname=="calRadius" || varname=="CALRADIUS" ) return 22; + + if(varname=="ipSigLeadTrk" || varname=="IPSIGLEADTRK" ) return 23; + if(varname=="benchdRLeadTrkLeadCluster" || varname=="BENCHDRLEADTRKLEADCLUSTER" ) return 24; + if(varname=="benchdRLeadTrk2ndLeadCluster" || varname=="BENCHDRLEADTRK2NDLEADCLUSTER" ) return 25; + if(varname=="benchdRLeadCluster2ndLeadCluster" || varname=="BENCHDRLEADCLUSTER2NDLEADCLUSTER" ) return 26; + if(varname=="lead2ClusterEOverAllCusterE" || varname=="LEAD2CLUSTEREOVERALLCLUSTERE" ) return 27; + if(varname=="geoTrackRadius" || varname=="GEOTRACKRADIUS" ) return 28; + if(varname=="geoTrackMass" || varname=="GEOTRACKMASS" ) return 29; + if(varname=="geoCentFrac" || varname=="GEOCENTFRAC" ) return 30; + if(varname=="geoTopoInvMass" || varname=="GEOTOPOINVMASS" ) return 31; + if(varname=="geoCoreEnergyFraction" || varname=="GEOCOREENERGYFRACTION" ) return 32; + if(varname=="geoCoreClusterEMRadius" || varname=="GEOCORECLUSTEREMRADIUS" ) return 33; + if(varname=="geodRLeadTrkLeadCluster" || varname=="GEODRLEADTRKLEADCLUSTER" ) return 34; + if(varname=="geodRLeadTrk2ndLeadCluster" || varname=="GEODRLEADTRK2NDLEADCLUSTER" ) return 35; + if(varname=="geodRLeadCluster2ndLeadCluster" || varname=="GEODRLEADCLUSTER2NDLEADCLUSTER" ) return 36; + if(varname=="geoEClusterOverETau" || varname=="GEOECLUSTEROVERETAU" ) return 37; + if(varname=="NClusters" || varname=="NCLUSTERS" ) return 38; + if(varname=="NeffClusters" || varname=="NEFFCLUSTERS" ) return 39; + if(varname=="effTopoInvMass" || varname=="EFFTOPOINVMASS" ) return 40; + if(varname=="effdRLeadTrkLeadCluster" || varname=="EFFDRLEADTRKLEADCLUSTER" ) return 41; + if(varname=="effdRLeadTrk2ndLeadCluster" || varname=="EFFDRLEADTRK2NDLEADCLUSTER" ) return 42; + if(varname=="effdRLeadCluster2ndLeadCluster" || varname=="EFFDRLEADCLUSTER2NDLEADCLUSTER" ) return 43; + if(varname=="effEClusterOverETau" || varname=="EFFECLUSTEROVERETAU" ) return 44; + if(varname=="Eiso" || varname=="EISO" ) return 45; + if(varname=="ClusterEMRadius" || varname=="CLUSTEREMRADIUS" ) return 46; + if(varname=="ClusterCentFrac" || varname=="CLUSTERCENTFRAC" ) return 47; + if(varname=="effEMRadius" || varname=="EFFEMRADIUS" ) return 48; + if(varname=="effCentFrac" || varname=="EFFCENTFRAC" ) return 49; + if(varname=="numWideTrack" || varname=="NUMWIDETRACK" ) return 50; + if(varname=="charge" || varname=="CHARGE" ) return 51; + if(varname=="nPi0" || varname=="NPI0" ) return 52; + if(varname=="corrcentFrac" || varname=="CORRCENTFRAC" ) return 53; + if(varname=="corrfTrk" || varname=="CORRFTRK" ) return 56; + + + print("ERROR: Variable name not corresponding to a PDF variable: "+varname,2); + return -1; +} + +void CommonLikelihood::splitString(const string& str, vector<string>& substrings, const string& delimiters) const{ + // Skip delimiters at beginning. + string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (string::npos != pos || string::npos != lastPos){ + // Found a token, add it to the vector. + substrings.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/CutsDecisionTree.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/CutsDecisionTree.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fbc709b6466ab1927f9cb6174c9e130b13fb5ec8 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/CutsDecisionTree.cxx @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: Cuts.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/CutsDecisionTree.h" + +float CutsDecisionTree::response(unsigned int level) const { + + DecisionNode* decision = 0; + LeafNode<float>* leafNode = 0; + if (level >= this->trees.size()) return false; + Node* currentNode = this->trees[level].first; + while (!currentNode->isLeaf()) { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) { + currentNode = decision->getRightChild(); + } else { + currentNode = decision->getLeftChild(); + } + if (!currentNode) return false; + } + leafNode = static_cast<LeafNode<float>*>(currentNode); + return leafNode->getValue(); +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/EMFCluster.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/EMFCluster.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bac23ddbcc6c21ac8690f5ca5ffc5a61e14f5294 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/EMFCluster.cxx @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//*******************************************************// +// Name: EMFCluster.cxx // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: A simple class to house cluster // +// TLorentzVectors and their associated fractions of // +// energy in different calorimeter layers // +//*******************************************************// + +#include "TauDiscriminant/EMFCluster.h" + +//--------------------------------------------------------- +// Default Constructor +//--------------------------------------------------------- +EMFCluster::EMFCluster() +{} + + +//--------------------------------------------------------- +// Initiate TLorentzVector Contructor +//--------------------------------------------------------- +EMFCluster::EMFCluster(double pt) +{ + m_cluster = TLorentzVector(pt, 0.0, 0.0, 0.0); + m_PSSF = 0.0; + m_EM2F = 0.0; + m_EM3F = 0.0; +} + + + +//--------------------------------------------------------- +// Main constructor +//--------------------------------------------------------- +EMFCluster::EMFCluster(const TLorentzVector& inCluster, + double inPSSF, + double inEM2F, + double inEM3F) +{ + m_cluster = inCluster; + + m_PSSF = inPSSF; + m_EM2F = inEM2F; + m_EM3F = inEM3F; + + update(); +} + + +//--------------------------------------------------------- +// Destructor +//--------------------------------------------------------- +EMFCluster::~EMFCluster() +{} + + +//----------------------------------------------------------- +// Update method +//----------------------------------------------------------- +void EMFCluster::update() +{ + m_HADF = 1 - m_PSSF - m_EM2F - m_EM3F; + m_pseudoHADF = 1 - m_PSSF - m_EM2F; + + double clE = m_cluster.E(); + + m_PSSE = m_PSSF*clE; + m_EM2E = m_EM2F*clE; + m_EM3E = m_EM3F*clE; + m_HADE = m_HADF*clE; + m_pseudoHADE = m_pseudoHADF*clE; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/LinkDef.h b/PhysicsAnalysis/TauID/TauDiscriminant/Root/LinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..c8efc8d9debb0e33186f3c324473dcb3aeaa769e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/LinkDef.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef __TAUDISCRIMINANT__ +#define __TAUDISCRIMINANT__ + +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/MethodDummy.h" +#include "TauDiscriminant/MethodLLH.h" +#include "TauDiscriminant/MethodTransform.h" +#include "TauDiscriminant/Types.h" +#include "TauDiscriminant/TauIDReader.h" +#include "TauDiscriminant/TauDetailsManagerStandalone.h" + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ namespace TauID; +#pragma link C++ namespace TauID::Types; + +#pragma link C++ enum TauID::Types::MethodType; +#pragma link C++ class TauID::TauIDReader; +#pragma link C++ class TauID::TauDetailsManagerStandalone; +#pragma link C++ class TauID::MethodBase; +#pragma link C++ class TauID::MethodDummy; +#pragma link C++ class TauID::MethodTransform; +#pragma link C++ class TauID::MethodBDT; +#pragma link C++ class TauID::MethodCuts; +#pragma link C++ class TauID::MethodLLH; + +#endif +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBDT.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBDT.cxx new file mode 100644 index 0000000000000000000000000000000000000000..93648af524f141517a37b8cbc6a28a9f63ee1533 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBDT.cxx @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: MethodBDT.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/MethodBDT.h" + +using namespace TauID; + +float MethodBDT::response() const +{ + if (!this->isBuilt) return -101.; + BoostedDecisionTree* bdt = getCurrentCategory(); + return bdt ? bdt->response() : -201.; +} + +bool MethodBDT::build(const string& filename, bool checkTree) +{ + #ifdef __STANDALONE + TreeReader reader(this->verbose); + #else + TreeReader reader; + #endif + reader.setVariables(&this->floatVariables, &this->intVariables); + this->categoryTree = reader.build(filename,checkTree); + if (this->categoryTree != 0) + { + this->isBuilt = true; + return true; + } + return false; +} + +BoostedDecisionTree* MethodBDT::getCurrentCategory() const +{ + PointerLeafNode<BoostedDecisionTree>* leafNode; + DecisionNode* decision; + Node* currentNode = this->categoryTree; + if (!currentNode) return 0; + while (!currentNode->isLeaf()) + { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) + { + currentNode = decision->getRightChild(); + } + else + { + currentNode = decision->getLeftChild(); + } + if (!currentNode) return 0; + } + leafNode = static_cast<PointerLeafNode<BoostedDecisionTree>*>(currentNode); + return leafNode->getValue(); +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBase.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4e4b0cc1b0a78771596467d8d06d87f0d087f6d4 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodBase.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "TauDiscriminant/MethodBase.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodCuts.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodCuts.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b2d260eb74d4774c8efba8a0fdaea13ea2526f42 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodCuts.cxx @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: CutsMethod.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/MethodCuts.h" + +using namespace TauID; + +float MethodCuts::response(unsigned int level) const +{ + if (!this->isBuilt) return 0.; + CutsDecisionTree* cuts = getCurrentCategory(); + return cuts ? cuts->response(level) : 0.; +} + +bool MethodCuts::build(const string& filename, bool checkTree) +{ + #ifdef __STANDALONE + TreeReader reader(this->verbose); + #else + TreeReader reader; + #endif + reader.setVariables(&this->floatVariables,&this->intVariables); + this->categoryTree = reader.build(filename,checkTree); + if (this->categoryTree != 0) + { + this->isBuilt = true; + return true; + } + return false; +} + +CutsDecisionTree* MethodCuts::getCurrentCategory() const +{ + PointerLeafNode<CutsDecisionTree>* leafNode; + DecisionNode* decision; + Node* currentNode = this->categoryTree; + while (!currentNode->isLeaf()) + { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) + { + currentNode = decision->getRightChild(); + } + else + { + currentNode = decision->getLeftChild(); + } + } + leafNode = static_cast<PointerLeafNode<CutsDecisionTree>*>(currentNode); + return leafNode->getValue(); +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodDummy.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodDummy.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d90dd811bc89b9fb3e91e25e46910731dfea2a81 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodDummy.cxx @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: MethodDummy.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/MethodDummy.h" + +using namespace TauID; + +float MethodDummy::response() const +{ + return 0.; +} + +bool MethodDummy::build(const string&, bool) +{ + return true; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodLLH.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodLLH.cxx new file mode 100644 index 0000000000000000000000000000000000000000..7fbdec7a05e340e0e30d8dbdf7da443f23d062fa --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodLLH.cxx @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: MethodLLH.cxx + * + * Author: Martin Flechl (mflechl@cern.ch) + */ + +#include "TauDiscriminant/MethodLLH.h" + +using namespace TauID; + +float MethodLLH::response(unsigned int level) const { + + if (llh){ + std::string m="MethodLLH: Calling calcLLHValue, level="; m+=level; m+=",name="; m+=getName(); + print(m); + + if (level==0) { + + llh->calcLLHValue(&this->floatVariables,&this->intVariables,m_option); + + } + + float llhratio=llh->getLLHValue(); + + + if (level==3) return llhratio; + else return llh->response(level,m_option); + } else{ + return -99; + } +} + +bool MethodLLH::build(const string& filename, bool check) { + + print("In MethodLLH::build"); + print("Reminder: The safe and default likelihood will only return the same values as during"); + print(" reconstruction if all required variables are given. This is currently not checked."); + + if (this->getName()=="llhsafe") m_option=0; + else if (this->getName()=="llhdef") m_option=1; + else m_option=2; + + #ifdef __STANDALONE + llh = new CommonLikelihood(this->verbose); + #else + llh = new CommonLikelihood(); + #endif + + check = llh->build(filename); + this->isBuilt=check; + + return check; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodTransform.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodTransform.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1a0f0b89de7873e8a662fc6f77cffa65a26c84c2 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/MethodTransform.cxx @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: MethodTransform.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/MethodTransform.h" + +using namespace TauID; + +float MethodTransform::response() const +{ + if (!this->isBuilt) return -101.; + Transformation* trans = getCurrentCategory(); + return trans ? trans->response() : -201.; +} + +bool MethodTransform::build(const string& filename, bool checkTree) +{ + #ifdef __STANDALONE + TreeReader reader(this->verbose); + #else + TreeReader reader; + #endif + reader.setVariables(&this->floatVariables,&this->intVariables); + this->categoryTree = reader.build(filename,checkTree); + if (this->categoryTree != 0) + { + this->isBuilt = true; + return true; + } + return false; +} + +Transformation* MethodTransform::getCurrentCategory() const +{ + PointerLeafNode<Transformation>* leafNode; + DecisionNode* decision; + Node* currentNode = this->categoryTree; + if (!currentNode) return 0; + while (!currentNode->isLeaf()) + { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) + { + currentNode = decision->getRightChild(); + } + else + { + currentNode = decision->getLeftChild(); + } + if (!currentNode) return 0; + } + leafNode = static_cast<PointerLeafNode<Transformation>*>(currentNode); + return leafNode->getValue(); +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/Node.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Node.cxx new file mode 100644 index 0000000000000000000000000000000000000000..17924b97e6ce83e0305e564cca4ecc6de0e2cf6b --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Node.cxx @@ -0,0 +1,11 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: Node.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/Node.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/NoiseCorrIsol.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/NoiseCorrIsol.cxx new file mode 100644 index 0000000000000000000000000000000000000000..deb0c56587ab75b4311a472cadd0dabb6a7ce988 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/NoiseCorrIsol.cxx @@ -0,0 +1,210 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//*******************************************************// +// Name: NoiseCorrIsol.cxx // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: A class to provide isolation based // +// pileup/underlying event correction to the clusters // +// of tau decays // +//*******************************************************// + +#include "TauDiscriminant/NoiseCorrIsol.h" +#include "math.h" +#include <iostream> + +//--------------------------------------------------------- +// Default Constructor +//--------------------------------------------------------- +NoiseCorrIsol::NoiseCorrIsol() +{} + + +//--------------------------------------------------------- +// Main constructor 1 +//--------------------------------------------------------- +NoiseCorrIsol::NoiseCorrIsol(const TLorentzVector& tau, + const std::vector<TLorentzVector>& clusters, + double innerDR, + double outerDR, + bool eff) + : m_clusters(clusters), + m_tau(tau), + m_innerDR(innerDR), + m_outerDR(outerDR), + m_eff(eff) +{ + m_areaRatio = areaRatio(); +} + + +//--------------------------------------------------------- +// Main constructor 2 +//--------------------------------------------------------- +NoiseCorrIsol::NoiseCorrIsol(const TLorentzVector& tau, + const std::vector<EMFCluster>& clusters, + double innerDR, + double outerDR, + bool eff) + : m_EMFClusters(clusters), + m_tau(tau), + m_innerDR(innerDR), + m_outerDR(outerDR), + m_eff(eff) +{ + m_areaRatio = areaRatio(); +} + + +//--------------------------------------------------------- +// Destructor +//--------------------------------------------------------- +NoiseCorrIsol::~NoiseCorrIsol() +{} + + +//--------------------------------------------------------- +// Ratio of areas calculation +//--------------------------------------------------------- +double NoiseCorrIsol::areaRatio() +{ + double delta = m_outerDR*m_outerDR - m_innerDR*m_innerDR; + if(delta != 0) + return (m_innerDR*m_innerDR)/(delta); + + else return 99999999.0; +} + + +//--------------------------------------------------------- +// Correcting clusters (pure TLorentzVectors) +//--------------------------------------------------------- +std::vector<TLorentzVector> NoiseCorrIsol::correctedClustersTLV() +{ + + // Calculate correction + std::vector<TLorentzVector> innerClusters; + int nCl = (int)m_clusters.size(); + double outerPt = 0; + + //Obtain isolation ring energy (outerE) and inner clusters + for(int i = 0; i < nCl; ++i) + { + double dR = m_tau.DeltaR(m_clusters.at(i)); + + if( (dR < m_outerDR)&&(dR > m_innerDR) ) + outerPt += m_clusters.at(i).Pt(); + + if( dR < m_innerDR ) + innerClusters.push_back(m_clusters.at(i)); + } + + int nInCl = (int)innerClusters.size(); + + double correction = 0.0; + if(nInCl != 0) correction = (outerPt * m_areaRatio) / nInCl; + std::vector<TLorentzVector> finalClusters; + + //Apply correction + for(int i = 0; i < nInCl; ++i) + { + double correctedPt = innerClusters.at(i).Pt() - correction; + double Eta = innerClusters.at(i).Eta(); + double Phi = innerClusters.at(i).Phi(); + + if(correctedPt > 0) //Reject clusters with smaller E than the correction E + { + TLorentzVector corrCluster; + corrCluster.SetPtEtaPhiM(correctedPt, Eta, Phi, 0); + finalClusters.push_back(corrCluster); + } + } + + return finalClusters; +} + + + +//--------------------------------------------------------- +// Correcting clusters (EMFClusters) +//--------------------------------------------------------- +std::vector<EMFCluster> NoiseCorrIsol::correctedClusters() +{ + + // Calculate correction + std::vector<EMFCluster> innerClusters; + int nCl = (int)m_EMFClusters.size(); + double outerPt = 0; + + //Obtain isolation ring energy (outerE) and inner clusters + for(int i = 0; i < nCl; ++i) + { + double dR = m_tau.DeltaR(m_EMFClusters.at(i).TLV()); + + if( (dR < m_outerDR)&&(dR > m_innerDR) ) + outerPt += m_EMFClusters.at(i).TLV().Pt(); + + if( dR < m_innerDR ) + innerClusters.push_back(m_EMFClusters.at(i)); + } + + int nInCl = (int)innerClusters.size(); + double correction = 0.0; + if(nInCl>0) correction = (outerPt * m_areaRatio) / nInCl; + std::vector<EMFCluster> finalClusters; + + //Apply correction + for(int i = 0; i < nInCl; ++i) + { + double correctedPt = innerClusters.at(i).TLV().Pt() - correction; + double Eta = innerClusters.at(i).TLV().Eta(); + double Phi = innerClusters.at(i).TLV().Phi(); + + if(correctedPt > 0) //Reject clusters with smaller E than the correction E + { + TLorentzVector corrCluster; + corrCluster.SetPtEtaPhiM(correctedPt, Eta, Phi, 0); + EMFCluster corrEMFCluster(corrCluster, innerClusters.at(i).PSSF(), innerClusters.at(i).EM2F(), innerClusters.at(i).EM3F()); + finalClusters.push_back(corrEMFCluster); + } + } + + if(m_eff) return effClusters(finalClusters); + return finalClusters; +} + + +//--------------------------------------------------------- +// Calculating effective clusters (post-correction) +//--------------------------------------------------------- +bool EComp(const EMFCluster& iCluster, const EMFCluster& jCluster) +{ return (iCluster.TLV().E() > jCluster.TLV().E()); } + +std::vector<EMFCluster> NoiseCorrIsol::effClusters(const std::vector<EMFCluster>& inputClusters) +{ + int nInputClusters = (int)inputClusters.size(); + std::vector<EMFCluster> inClusters = inputClusters; + + double SumSquare = 0; + double SquareSum = 0; + + for(int i = 0; i < nInputClusters; ++i) + { + double E = inClusters.at(i).TLV().E(); + SquareSum += E; + SumSquare += E*E; + } + + double NEff = 0; + if(SumSquare != 0.0) NEff = ceil((SquareSum*SquareSum)/SumSquare); + + std::sort(inClusters.begin(), inClusters.end(), EComp); + + std::vector<EMFCluster> outputClusters; + + for(int i = 0; i < NEff; ++i) + outputClusters.push_back(inClusters.at(i)); + + return outputClusters; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/Pi0Finder.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Pi0Finder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..382924c18887664a497e084dde3b0c24e1ae4a45 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Pi0Finder.cxx @@ -0,0 +1,526 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//*******************************************************// +// Name: Pi0Finder.cxx // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: Main class to find which clusters are // +// the pi0s in tau decays involving neutral pions // +//*******************************************************// + +#include "TauDiscriminant/Pi0Finder.h" +#include "TauDiscriminant/NoiseCorrIsol.h" +#include "math.h" +#include <iostream> + + +//--------------------------------------------------------- +// Default Constructor +//--------------------------------------------------------- +Pi0Finder::Pi0Finder() +{} + + + +//--------------------------------------------------------- +// Constructor 1 +//--------------------------------------------------------- +Pi0Finder::Pi0Finder(const std::vector<TLorentzVector>& tracks, + const std::vector<EMFCluster>& clusters, + bool twoPi0s, + double resImportance, + double turnOnPoint, + double turnOnRate, + double PSSFactor, + double EM2Factor, + double twoPi0Strength, + bool usePseudoHADF, + bool effClusters ) : m_tracks(tracks), + m_usePseudoHADF(usePseudoHADF), + m_twoPi0s(twoPi0s), + m_resImportance(resImportance), + m_turnOnPoint(turnOnPoint), + m_turnOnRate(turnOnRate), + m_PSSFactor(PSSFactor), + m_EM2Factor(EM2Factor), + m_twoPi0Strength(twoPi0Strength), + m_caloE(0), + m_caloHADE(0), + m_trkE(0), + m_trkHADF(0), + m_doubleCountingE(0), + m_applyCorrCluster1(false), + m_applyCorrCluster2(false), + m_keepCluster1(false), + m_keepCluster2(false), + m_noMatch(true), + m_selEMFCluster1(0.000001), + m_selEMFCluster2(0.000001), + m_selEMFClusterNotCorr1(0.000001), + m_selEMFClusterNotCorr2(0.000001) +{ + TLorentzVector trksys; + for(unsigned int i = 0; i < m_tracks.size(); ++i) + trksys += m_tracks[i]; + + NoiseCorrIsol NCI(trksys, clusters, 0.3, 0.4, effClusters); + m_EMFClusters = NCI.correctedClusters(); + + execute(); +} + + +//--------------------------------------------------------- +// Constructor 2 +//--------------------------------------------------------- +Pi0Finder::Pi0Finder(const std::vector<TLorentzVector>& tracks, + const std::vector<TLorentzVector>& clusters, + const std::vector<float>& PSSFs, + const std::vector<float>& EM2Fs, + const std::vector<float>& EM3Fs, + bool twoPi0s, + double resImportance, + double turnOnPoint, + double turnOnRate, + double PSSFactor, + double EM2Factor, + double twoPi0Strength, + bool usePseudoHADF, + bool effClusters ) : m_tracks(tracks), + m_usePseudoHADF(usePseudoHADF), + m_twoPi0s(twoPi0s), + m_resImportance(resImportance), + m_turnOnPoint(turnOnPoint), + m_turnOnRate(turnOnRate), + m_PSSFactor(PSSFactor), + m_EM2Factor(EM2Factor), + m_twoPi0Strength(twoPi0Strength), + m_caloE(0), + m_caloHADE(0), + m_trkE(0), + m_trkHADF(0), + m_doubleCountingE(0), + m_applyCorrCluster1(false), + m_applyCorrCluster2(false), + m_keepCluster1(false), + m_keepCluster2(false), + m_noMatch(true), + m_selEMFCluster1(0.000001), + m_selEMFCluster2(0.000001), + m_selEMFClusterNotCorr1(0.000001), + m_selEMFClusterNotCorr2(0.000001) +{ + std::vector<EMFCluster> tmpEMFClusters = convertToEMFClusters(clusters, PSSFs, EM2Fs, EM3Fs); + for(unsigned int i = 0; i < m_tracks.size(); ++i) + m_trkSys += m_tracks[i]; + NoiseCorrIsol NCI(m_trkSys, tmpEMFClusters, 0.3, 0.4, effClusters); + m_EMFClusters = NCI.correctedClusters(); + execute(); +} + + +//--------------------------------------------------------- +// Destructor +//--------------------------------------------------------- +Pi0Finder::~Pi0Finder() +{} + + +//--------------------------------------------------------- +// Execute the pi0 finding +//--------------------------------------------------------- +void Pi0Finder::execute() +{ + preSelParameters(); + if(m_twoPi0s) select2(); + else select(); + + postSelParameters(); + + if(m_keepCluster1) + { + if(m_applyCorrCluster1) m_selEMFCluster1 = correct(m_selEMFClusterNotCorr1); + else m_selEMFCluster1 = m_selEMFClusterNotCorr1; + } + + if(m_keepCluster2) + { + if(m_applyCorrCluster2) m_selEMFCluster2 = correct(m_selEMFClusterNotCorr2); + else m_selEMFCluster2 = m_selEMFClusterNotCorr2; + } +} + + +//--------------------------------------------------------- +// Parameters to be used in the selection +//--------------------------------------------------------- +void Pi0Finder::preSelParameters() +{ + //Build the track system + int ntracks = (int)m_tracks.size(); + + m_trkE = 0; + + for(int i = 0; i < ntracks; ++i) + m_trkE += m_tracks.at(i).E(); + + //Calculate calo quantities + int nclusters = (int)m_EMFClusters.size(); + m_caloE = 0; + m_caloHADE = 0; + + for(int i = 0; i < nclusters; ++i) + { + double clE = m_EMFClusters.at(i).TLV().E(); + double clHADE = m_EMFClusters.at(i).pseudoHADE(); + if(!m_usePseudoHADF) + clHADE = m_EMFClusters.at(i).HADE(); + + m_caloE += clE; + m_caloHADE += clHADE; + } + if(m_trkE != 0) m_trkHADF = m_caloHADE/m_trkE; +} + + +//--------------------------------------------------------- +// Calculate scores and select cluster with highest score +//--------------------------------------------------------- +void Pi0Finder::select() +{ + double pi0ScoreMin = 0.0; + EMFCluster cl1; + int nclusters = (int)m_EMFClusters.size(); + + for(int i = 0; i < nclusters; ++i) + { + double clE = m_EMFClusters.at(i).TLV().E(); + double HADF = m_EMFClusters.at(i).HADF(); + double rawRecoE = m_caloE - m_trkE; + double rawERes = 999999.0; + if(rawRecoE != 0) rawERes = sqrt(fabs(clE/rawRecoE - 1.0)); + double PSSE = m_EMFClusters.at(i).PSSE(); + double pi0Score = PSSE/(HADF + m_resImportance*rawERes + 0.0000001); + if(pi0Score > pi0ScoreMin) + { + pi0ScoreMin = pi0Score; + cl1 = m_EMFClusters.at(i); + m_noMatch = false; + } + } + if(!m_noMatch) + m_selEMFClusterNotCorr1 = cl1; +} + + + +//--------------------------------------------------------- +// Calculate scores and select pair of clusters with +// highest score +//--------------------------------------------------------- +void Pi0Finder::select2() +{ + double pi0ScoreMin = 0.0; + EMFCluster cl1; + EMFCluster cl2; + + int nclusters = (int)m_EMFClusters.size(); + + for(int i = 0; i < nclusters; ++i) + { + + double clE1 = m_EMFClusters.at(i).TLV().E(); + double clEta1 = m_EMFClusters.at(i).TLV().Eta(); + double HADF1 = m_EMFClusters.at(i).HADF(); + double rawRecoE1 = m_caloE - m_trkE; + double rawERes1 = 9999999.0; + if(rawRecoE1 != 0) rawERes1 = sqrt(fabs(clE1/rawRecoE1 - 1.0)); + double PSSE1 = m_EMFClusters.at(i).PSSE(); + + double pi0Score1 = PSSE1/(HADF1 + m_resImportance*rawERes1 + 0.0000001); + + if((pi0Score1 > pi0ScoreMin) && (fabs(clEta1) < 5.0)) + { + pi0ScoreMin = pi0Score1; + cl1 = m_EMFClusters.at(i); + TLorentzVector empty; + EMFCluster EMFempty(empty, 0, 0, 0); + cl2 = EMFempty; + m_noMatch = false; + m_keepCluster1 = true; + m_keepCluster2 = false; + } + + for(int j = 0; j < nclusters; ++j) + { + if(j > i) // Do not pair a cluster with itself + { + double clE_i = m_EMFClusters.at(i).TLV().E(); + double clE_j = m_EMFClusters.at(j).TLV().E(); + double clEta_i = m_EMFClusters.at(i).TLV().Eta(); + double clEta_j = m_EMFClusters.at(j).TLV().Eta(); + double HADE_i = m_EMFClusters.at(i).HADE(); + double HADE_j = m_EMFClusters.at(j).HADE(); + double clE = clE_i + clE_j; + double HADF = 0.0; + if(clE != 0) HADF = (HADE_i + HADE_j)/clE; + double rawRecoE = m_caloE - m_trkE; + double rawERes = 999999.0; + if(rawRecoE != 0) rawERes = sqrt(fabs(clE/rawRecoE - 1.0)); + double PSSE_i = m_EMFClusters.at(i).PSSE(); + double PSSE_j = m_EMFClusters.at(j).PSSE(); + double PSSE = PSSE_i + PSSE_j; + + double pi0Score = m_twoPi0Strength*PSSE/(HADF + m_resImportance*rawERes + 0.0000001); + + if((pi0Score > pi0ScoreMin) &&(fabs(clEta_i) < 5.0 && fabs(clEta_j) < 5.0)) + { + pi0ScoreMin = pi0Score; + cl1 = m_EMFClusters.at(i); + cl2 = m_EMFClusters.at(j); + m_noMatch = false; + m_keepCluster1 = true; + m_keepCluster2 = true; + } + } + } + } + if(!m_noMatch) + { + m_selEMFClusterNotCorr1 = cl1; + m_selEMFClusterNotCorr2 = cl2; + } +} + + + + +//--------------------------------------------------------- +// Parameters to be used in the correction +//--------------------------------------------------------- +void Pi0Finder::postSelParameters() +{ + double clE1 = 0.0; + double clEta1 = 10.0; + double clE2 = 0.0; + double clEta2 = 10.0; + + if(m_keepCluster1) + { + clE1 = m_selEMFClusterNotCorr1.TLV().E(); + clEta1 = m_selEMFClusterNotCorr1.TLV().Eta(); + } + + if(m_keepCluster2) + { + clE2 = m_selEMFClusterNotCorr2.TLV().E(); + clEta2 = m_selEMFClusterNotCorr2.TLV().Eta(); + } + + + double DCTwoClusters = 1.0; + double DCCluster1 = 1.0; + double DCCluster2 = 1.0; + + if(m_caloE > 0.0) + { + DCTwoClusters = (clE1 + clE2 + m_trkE)/m_caloE; + DCCluster1 = (clE1 + m_trkE)/m_caloE; + DCCluster2 = (clE2 + m_trkE)/m_caloE; + + } + + bool TwoClusterCorrection = (DCTwoClusters > m_turnOnPoint); + bool Cluster1Correction = (DCCluster1 > m_turnOnPoint); + bool Cluster2Correction = (DCCluster1 > m_turnOnPoint); + + if((clE1 > 0.0 && clEta1 < 5.0) && (clE2 > 0.0 && clEta2 < 5.0)) + { + m_doubleCountingE = DCTwoClusters; + + m_keepCluster1 = true; + m_keepCluster2 = true; + + if(TwoClusterCorrection) + { + if(Cluster1Correction) m_applyCorrCluster1 = true; + if(Cluster2Correction) m_applyCorrCluster2 = true; + + if(!Cluster1Correction && !Cluster2Correction) + { + if(DCCluster1 > DCCluster2) m_applyCorrCluster1 = true; + else m_applyCorrCluster2 = true; + } + } + } + + else if((clE1 == 0.0 || clEta1 > 5.0) && (clE2 > 0.0 && clEta2 < 5.0)) + { + m_doubleCountingE = DCCluster2; + m_keepCluster1 = false; + m_keepCluster2 = true; + if(Cluster2Correction) m_applyCorrCluster2 = true; + } + + else if((clE2 == 0.0 || clEta2 > 5.0) && (clE1 > 0.0 && clEta1 < 5.0)) + { + m_doubleCountingE = DCCluster1; + m_keepCluster1 = true; + m_keepCluster2 = false; + if(Cluster1Correction) m_applyCorrCluster1 = true; + } + + else + { + m_doubleCountingE = 0; + m_applyCorrCluster1 = false; + m_applyCorrCluster2 = false; + m_keepCluster1 = false; + m_keepCluster2 = false; + m_noMatch = true; + + } +} + + +//--------------------------------------------------------- +// Contamination Correction +//--------------------------------------------------------- +EMFCluster Pi0Finder::correct(const EMFCluster& cl) +{ + //Start by extracting the EMFCluster since a new one will have to be built + + double E = cl.TLV().E(); + double Eta = cl.TLV().Eta(); + double Phi = cl.TLV().Phi(); + double M = cl.TLV().M(); + double PSSF = cl.PSSF(); + double EM2F = cl.EM2F(); + double EM3F = cl.EM3F(); + double HADE = cl.HADE(); +// double HADF = cl.HADF(); + + if(m_usePseudoHADF) + { + HADE = cl.pseudoHADE(); +// HADF = cl.pseudoHADF(); + } + double PSSE = cl.PSSE(); + double EM2E = cl.EM2E(); + + double ChPiContaminationE = m_trkE; + if(m_trkHADF > 0.0) ChPiContaminationE = HADE/m_trkHADF; + double corrE = (E - ChPiContaminationE); + double corrE2 = 0.0; + if(m_doubleCountingE > 0.0) corrE2 = (m_PSSFactor*PSSE + m_EM2Factor*EM2E)/m_doubleCountingE; + + double corrScale = -exp(m_turnOnRate*(m_turnOnPoint - m_doubleCountingE)) + 1; + + //If there is substantial hadronic energy, use trkHADF + TLorentzVector newCl; + double effE = E; + if(m_caloHADE > 0.0) effE = (1 - corrScale)*E + corrScale*((1-HADE/m_caloHADE)*corrE2 + (HADE/m_caloHADE)*corrE); + + //Correct direction + double corrPt = effE/cosh(Eta); + + newCl.SetPtEtaPhiM(corrPt, Eta, Phi, M); + + EMFCluster newEMFCl(newCl, PSSF, EM2F, EM3F); + + return newEMFCl; +} + + +//--------------------------------------------------------- +// give pi0 Mass +//--------------------------------------------------------- +EMFCluster Pi0Finder::giveMass(const EMFCluster& cl) +{ + double Pt = cl.TLV().Pt(); + double Eta = cl.TLV().Eta(); + double Phi = cl.TLV().Phi(); + double PSSF = cl.PSSF(); + double EM2F = cl.EM2F(); + double EM3F = cl.EM3F(); + double mass = 135; + + TLorentzVector newTLV; + newTLV.SetPtEtaPhiM(Pt, Eta, Phi, mass); + return EMFCluster(newTLV, PSSF, EM2F, EM3F); +} + + +//--------------------------------------------------------- +// Return reconstructed visible tau +//--------------------------------------------------------- +TLorentzVector Pi0Finder::visTauTLV() const +{ + int ntracks = (int)m_tracks.size(); + TLorentzVector trksys; + + for(int i = 0; i < ntracks; ++i) + { + double Pt = m_tracks.at(i).Pt(); + double Eta = m_tracks.at(i).Eta(); + double Phi = m_tracks.at(i).Phi(); + + TLorentzVector trk; + trk.SetPtEtaPhiM(Pt, Eta, Phi, 140); + trksys += trk; + } + + TLorentzVector visTau = trksys; + if(!m_noMatch) + { + TLorentzVector pi0s; + + if(m_twoPi0s) + { + double pi0sPt = m_selEMFCluster1.TLV().Pt() + m_selEMFCluster2.TLV().Pt(); + TLorentzVector pi0sdirection = m_selEMFCluster1.TLV() + m_selEMFCluster2.TLV(); + double pi0sEta = pi0sdirection.Eta(); + double pi0sPhi = pi0sdirection.Phi(); + + + pi0s.SetPtEtaPhiM(pi0sPt, pi0sEta, pi0sPhi, 135); + } + else + pi0s.SetPtEtaPhiM(m_selEMFCluster1.TLV().Pt(), m_selEMFCluster1.TLV().Eta(), m_selEMFCluster1.TLV().Phi(), 135); + + visTau += pi0s; + + } + + return visTau; +} + + +//--------------------------------------------------------- +// Converts the 4 std::vectors to 1 EMFCluster std::vector +//--------------------------------------------------------- + +std::vector<EMFCluster> Pi0Finder::convertToEMFClusters(const std::vector<TLorentzVector>& clusters, + const std::vector<float>& PSSFs, + const std::vector<float>& EM2Fs, + const std::vector<float>& EM3Fs) +{ + int clsize = (int)clusters.size(); + int pssfsize = (int)PSSFs.size(); + int em2fsize = (int)EM2Fs.size(); + int em3fsize = (int)EM3Fs.size(); + + std::vector<EMFCluster> emfclusters; + + if(clsize == pssfsize && pssfsize == em2fsize && em2fsize == em3fsize) + { + for(int i = 0; i < clsize; ++i) + { + EMFCluster emfcl(clusters.at(i), PSSFs.at(i), EM2Fs.at(i), EM3Fs.at(i)); + emfclusters.push_back(emfcl); + } + } + + return emfclusters; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauDetailsManagerStandalone.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauDetailsManagerStandalone.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f1b1c143bfd3f82ebd6fba58abb02e2329748500 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauDetailsManagerStandalone.cxx @@ -0,0 +1,356 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + /** + * file: TauDetailsManagerStandalone.cxx + * + * Author: Pawel malecki (Pawel.Malecki@cern.ch) + */ + + +#include "TauDiscriminant/TauDetailsManagerStandalone.h" + +#include <utility> +#include <iostream> +#include <TFile.h> +#include <math.h> + +// redefine the macro to print strings instead of enums as in TauDetails.h +#undef ENUM_OR_STRING +#define ENUM_OR_STRING( x ) #x + +using namespace std; +using namespace TauID; + +// Arrays of the string representations of the detail names + +namespace Details +{ + + string IntTauDetailStringS[] = + { + INT_TAU_DETAILS + }; + + string FloatTauDetailStringS[] = + { + FLOAT_TAU_DETAILS + }; + + string IntEventDetailStringS[] = + { + INT_EVENT_DETAILS + }; + + string FloatEventDetailStringS[] = + { + FLOAT_EVENT_DETAILS + }; +} + +// The default value for all details +const float TauDetailsManagerStandalone::LOW_NUMBER = -1111.; + +TauDetailsManagerStandalone::TauDetailsManagerStandalone(TTree *tree) { + + + //hard-coded for a while + m_clusterCone = 0.2; + if(tree) m_tree = tree; + + // Initialize the vector containing the tau-based variables + this->float_data = vector<float>(Details::__FloatTauDetail__END__+1, LOW_NUMBER); + this->int_data = vector<int>(Details::__IntTauDetail__END__+1, int(LOW_NUMBER)); + + // Initialize the vector containing the event-based variables + this->float_event_data = vector<float>(Details::__FloatEventDetail__END__+1, LOW_NUMBER); + this->int_event_data = vector<int>(Details::__IntEventDetail__END__+1, int(LOW_NUMBER)); + + // Maps of the string representations to the addresses of the values in the above vectors + unsigned int i; + for (i = 0; i < this->float_data.size()-1; ++i) + { + this->float_details.insert(pair<string,float*>(Details::FloatTauDetailStringS[i],&this->float_data[i])); + } + for (i = 0; i < this->float_event_data.size()-1; ++i) + { + this->float_details.insert(pair<string,float*>(Details::FloatEventDetailStringS[i],&this->float_event_data[i])); + } + for (i = 0; i < this->int_data.size()-1; ++i) + { + this->int_details.insert(pair<string,int*>(Details::IntTauDetailStringS[i],&this->int_data[i])); + } + for (i = 0; i < this->int_event_data.size()-1; ++i) + { + this->int_details.insert(pair<string,int*>(Details::IntEventDetailStringS[i],&this->int_event_data[i])); + } + + m_tree = 0; + + + tau_charge = 0; + tau_author = 0; + tau_numTrack = 0; + tau_seedCalo_nWideTrk = 0; + tau_eta = 0; + tau_phi = 0; + tau_pt = 0; + tau_seedCalo_trkAvgDist = 0; + tau_etOverPtLeadTrk = 0; + tau_calcVars_EMFractionAtEMScale = 0; + tau_TRTHTOverLT_LeadTrk = 0; + tau_seedCalo_dRmax = 0; + tau_leadTrack_eta = 0; + tau_calcVars_ChPiEMEOverCaloEME = 0; + tau_seedTrk_secMaxStripEt = 0; + tau_seedTrk_hadLeakEt = 0; + tau_seedTrk_sumEMCellEtOverLeadTrkPt = 0; + tau_calcVars_corrFTrk = 0; + tau_calcVars_corrCentFrac = 0; + tau_seedCalo_isolFrac = 0; + tau_seedCalo_hadRadius = 0; + tau_calcVars_PSSFraction = 0; + tau_seedCalo_nStrip = 0; + tau_massTrkSys = 0; + tau_ipSigLeadTrk = 0; + tau_trFlightPathSig = 0; + tau_calcVars_EMPOverTrkSysP = 0; + evt_calcVars_numGoodVertices = -1111; + tau_pi0_n = 0; + tau_pi0_vistau_m = 0; + tau_pi0_vistau_pt = 0; + tau_leadTrkPt = 0; + tau_seedCalo_etEMAtEMScale = 0; + tau_seedCalo_etHadAtEMScale = 0; + tau_leadTrack_phi = 0; + + b_tau_charge = 0; + b_tau_author = 0; + b_tau_numTrack = 0; + b_tau_seedCalo_nWideTrk = 0; + b_tau_eta = 0; + b_tau_phi = 0; + b_tau_pt = 0; + b_tau_seedCalo_trkAvgDist = 0; + b_tau_etOverPtLeadTrk = 0; + b_tau_calcVars_EMFractionAtEMScale = 0; + b_tau_TRTHTOverLT_LeadTrk = 0; + b_tau_seedCalo_dRmax = 0; + b_tau_leadTrack_eta = 0; + b_tau_calcVars_ChPiEMEOverCaloEME = 0; + b_tau_seedTrk_secMaxStripEt = 0; + b_tau_seedTrk_hadLeakEt = 0; + b_tau_seedTrk_sumEMCellEtOverLeadTrkPt = 0; + b_tau_calcVars_corrFTrk = 0; + b_tau_calcVars_corrCentFrac = 0; + b_tau_seedCalo_isolFrac = 0; + b_tau_seedCalo_hadRadius = 0; + b_tau_calcVars_PSSFraction = 0; + b_tau_seedCalo_nStrip = 0; + b_tau_massTrkSys = 0; + b_tau_ipSigLeadTrk = 0; + b_tau_trFlightPathSig = 0; + b_tau_calcVars_EMPOverTrkSysP = 0; + + b_evt_calcVars_numGoodVertices = 0; + b_tau_pi0_n = 0; + b_tau_pi0_vistau_m = 0; + b_tau_pi0_vistau_pt = 0; + + b_tau_leadTrkPt = 0; + b_tau_seedTrk_sumEMCellEtOverLeadTrkPt = 0; + b_tau_seedCalo_etEMAtEMScale = 0; + b_tau_seedCalo_etHadAtEMScale = 0; + b_tau_leadTrack_eta = 0; + b_tau_leadTrack_phi = 0; + + + doTrigger = false; +} +bool TauDetailsManagerStandalone::initTree(TTree* tree) +{ + if(!tree) return false; + m_tree = (TTree*)tree;//->Clone("newtree"); + m_tree->SetBranchStatus("evt_calcVars_numGoodVertices",1); + m_tree->SetBranchAddress("evt_calcVars_numGoodVertices",&evt_calcVars_numGoodVertices,&b_evt_calcVars_numGoodVertices); + m_tree->SetBranchStatus("tau_*",1); + m_tree->SetBranchAddress("tau_charge",&tau_charge,&b_tau_charge); + m_tree->SetBranchAddress("tau_author",&tau_author,&b_tau_author); + m_tree->SetBranchAddress("tau_numTrack",&tau_numTrack,&b_tau_numTrack); + m_tree->SetBranchAddress("tau_seedCalo_nWideTrk",&tau_seedCalo_nWideTrk,&b_tau_seedCalo_nWideTrk); + m_tree->SetBranchAddress("tau_eta",&tau_eta,&b_tau_eta); + m_tree->SetBranchAddress("tau_phi",&tau_phi,&b_tau_phi); + m_tree->SetBranchAddress("tau_pt",&tau_pt,&b_tau_pt); + m_tree->SetBranchAddress("tau_seedCalo_trkAvgDist",&tau_seedCalo_trkAvgDist,&b_tau_seedCalo_trkAvgDist); + m_tree->SetBranchAddress("tau_etOverPtLeadTrk",&tau_etOverPtLeadTrk,&b_tau_etOverPtLeadTrk); + m_tree->SetBranchAddress("tau_calcVars_EMFractionAtEMScale",&tau_calcVars_EMFractionAtEMScale,&b_tau_calcVars_EMFractionAtEMScale); + m_tree->SetBranchAddress("tau_TRTHTOverLT_LeadTrk",&tau_TRTHTOverLT_LeadTrk,&b_tau_TRTHTOverLT_LeadTrk); + m_tree->SetBranchAddress("tau_seedCalo_dRmax",&tau_seedCalo_dRmax,&b_tau_seedCalo_dRmax); + m_tree->SetBranchAddress("tau_leadTrack_eta",&tau_leadTrack_eta,&b_tau_leadTrack_eta); + m_tree->SetBranchAddress("tau_calcVars_ChPiEMEOverCaloEME",&tau_calcVars_ChPiEMEOverCaloEME,&b_tau_calcVars_ChPiEMEOverCaloEME); + m_tree->SetBranchAddress("tau_seedTrk_secMaxStripEt",&tau_seedTrk_secMaxStripEt,&b_tau_seedTrk_secMaxStripEt); + m_tree->SetBranchAddress("tau_seedTrk_hadLeakEt",&tau_seedTrk_hadLeakEt,&b_tau_seedTrk_hadLeakEt); + m_tree->SetBranchAddress("tau_seedTrk_sumEMCellEtOverLeadTrkPt",&tau_seedTrk_sumEMCellEtOverLeadTrkPt,&b_tau_seedTrk_sumEMCellEtOverLeadTrkPt); + m_tree->SetBranchAddress("tau_calcVars_corrFTrk",&tau_calcVars_corrFTrk,&b_tau_calcVars_corrFTrk); + m_tree->SetBranchAddress("tau_calcVars_corrCentFrac",&tau_calcVars_corrCentFrac,&b_tau_calcVars_corrCentFrac); + m_tree->SetBranchAddress("tau_seedCalo_isolFrac",&tau_seedCalo_isolFrac,&b_tau_seedCalo_isolFrac); + m_tree->SetBranchAddress("tau_seedCalo_hadRadius",&tau_seedCalo_hadRadius,&b_tau_seedCalo_hadRadius); + m_tree->SetBranchAddress("tau_calcVars_PSSFraction",&tau_calcVars_PSSFraction,&b_tau_calcVars_PSSFraction); + m_tree->SetBranchAddress("tau_calcVars_EMPOverTrkSysP",&tau_calcVars_EMPOverTrkSysP,&b_tau_calcVars_EMPOverTrkSysP); + m_tree->SetBranchAddress("tau_seedCalo_nStrip",&tau_seedCalo_nStrip,&b_tau_seedCalo_nStrip); + m_tree->SetBranchAddress("tau_massTrkSys",&tau_massTrkSys,&b_tau_massTrkSys); + m_tree->SetBranchAddress("tau_ipSigLeadTrk",&tau_ipSigLeadTrk,&b_tau_ipSigLeadTrk); + m_tree->SetBranchAddress("tau_trFlightPathSig",&tau_trFlightPathSig,&b_tau_trFlightPathSig); + m_tree->SetBranchAddress("tau_pi0_n",&tau_pi0_n,&b_tau_pi0_n); + m_tree->SetBranchAddress("tau_pi0_vistau_m",&tau_pi0_vistau_m,&b_tau_pi0_vistau_m); + m_tree->SetBranchAddress("tau_pi0_vistau_pt",&tau_pi0_vistau_pt,&b_tau_pi0_vistau_pt); + + m_tree->SetBranchAddress("tau_leadTrkPt",&tau_leadTrkPt,&b_tau_leadTrkPt); + m_tree->SetBranchAddress("tau_seedCalo_etEMAtEMScale",&tau_seedCalo_etEMAtEMScale,&b_tau_seedCalo_etEMAtEMScale); + m_tree->SetBranchAddress("tau_seedCalo_etHadAtEMScale",&tau_seedCalo_etHadAtEMScale,&b_tau_seedCalo_etHadAtEMScale); + + m_tree->SetBranchAddress("tau_leadTrack_phi",&tau_leadTrack_phi,&b_tau_leadTrack_phi); + + + + m_tree->SetMakeClass(1); + return true; + +} + + +bool TauDetailsManagerStandalone::updateEvent(int entry) +{ + // Reset the buffers at the beginning of each event + this->float_event_data.assign(this->float_event_data.size(), LOW_NUMBER); + this->int_event_data.assign(this->int_event_data.size(), int(LOW_NUMBER)); + + if(!m_tree){ + cout<<"ERROR: no TTree assigned!"<<endl; + return false; + + } + m_tree->GetEntry(entry); + + + this->int_event_data[Details::NUM_PILEUP_AND_PRIMARY_VERTICES] = evt_calcVars_numGoodVertices; + + + return true; +} + +bool TauDetailsManagerStandalone::update(unsigned int itau) { + + // Reset the buffers before setting the variables of each tau + this->float_data.assign(this->float_data.size(), LOW_NUMBER); + this->int_data.assign(this->int_data.size(), int(LOW_NUMBER)); + + if(!m_tree){ + cout<<"ERROR: no TTree assigned!"<<endl; + return false; + + } + + + + this->float_data[Details::TRKAVGDIST] = tau_seedCalo_trkAvgDist->at(itau); + this->int_data[Details::AUTHOR] = tau_author->at(itau); + this->float_data[Details::ETOVERPTLEADTRK] = tau_etOverPtLeadTrk->at(itau); + this->float_data[Details::EMFRACTIONATEMSCALE] = tau_calcVars_EMFractionAtEMScale->at(itau); + this->float_data[Details::TRT_NHT_OVER_NLT] = tau_TRTHTOverLT_LeadTrk->at(itau); + this->float_data[Details::DRMAX] = tau_seedCalo_dRmax->at(itau); + this->float_data[Details::ABS_ETA_LEAD_TRACK] = fabs(tau_leadTrack_eta->at(itau)); + this->float_data[Details::CHPIEMEOVERCALOEME] = tau_calcVars_ChPiEMEOverCaloEME->at(itau); + this->float_data[Details::SECMAXSTRIPET] = tau_seedTrk_secMaxStripEt->at(itau); + this->float_data[Details::HADLEAKET] = tau_seedTrk_hadLeakEt->at(itau); + this->float_data[Details::SUMEMCELLETOVERLEADTRKPT] = tau_seedTrk_sumEMCellEtOverLeadTrkPt->at(itau); + this->float_data[Details::CORRFTRK] = tau_calcVars_corrFTrk->at(itau); + this->float_data[Details::CORRCENTFRAC] = tau_calcVars_corrCentFrac->at(itau); + this->float_data[Details::ISOLFRAC] = tau_seedCalo_isolFrac->at(itau); + this->float_data[Details::HADRADIUS] = tau_seedCalo_hadRadius->at(itau); + this->float_data[Details::EMPOVERTRKSYSP] = tau_calcVars_EMPOverTrkSysP->at(itau); + this->float_data[Details::PSSFRACTION] = tau_calcVars_PSSFraction->at(itau); + this->int_data[Details::NSTRIP] = tau_seedCalo_nStrip->at(itau); + this->int_data[Details::NUMTRACK] = tau_numTrack->at(itau); + this->float_data[Details::PT] = tau_pt->at(itau); + this->float_data[Details::ETA] = tau_eta->at(itau); + this->int_data[Details::NUMWIDETRACK] = tau_seedCalo_nWideTrk->at(itau); + this->float_data[Details::MASSTRKSYS] = tau_massTrkSys->at(itau); + this->float_data[Details::IPSIGLEADTRK] = tau_ipSigLeadTrk->at(itau); + this->int_data[Details::TAU_PI0_N] = tau_pi0_n->at(itau); + this->float_data[Details::TAU_PTRATIO] = tau_pi0_vistau_pt->at(itau)/tau_pt->at(itau); + this->float_data[Details::TAU_PI0_VISTAU_M] = tau_pi0_vistau_m->at(itau); + this->float_data[Details::TRFLIGHTPATHSIG] = tau_trFlightPathSig->at(itau); + + // solve for E3 + float tau_sumETCellsLAr = tau_seedTrk_sumEMCellEtOverLeadTrkPt->at(itau) * tau_leadTrkPt->at(itau); + float tau_sumEMCellET = tau_seedCalo_etEMAtEMScale->at(itau); + float tau_E3 = tau_sumETCellsLAr - tau_sumEMCellET; + // remove E3 + float tau_seedCalo_etHadAtEMScale_noE3 = tau_seedCalo_etHadAtEMScale->at(itau) - tau_E3; + float tau_seedCalo_etEMAtEMScale_yesE3 = tau_seedCalo_etEMAtEMScale->at(itau) + tau_E3; + + //calculate new EMFraction + this->float_data[Details::EMFRACTIONATEMSCALE_MOVEE3] = tau_seedCalo_etEMAtEMScale_yesE3/(tau_seedCalo_etEMAtEMScale_yesE3+tau_seedCalo_etHadAtEMScale_noE3); + + + this->float_data[Details::TAU_ABSDELTAETA] = fabs(tau_leadTrack_eta->at(itau)-tau_eta->at(itau)); + this->float_data[Details::TAU_ABSDELTAPHI] = fabs(tau_leadTrack_phi->at(itau)-tau_phi->at(itau)); + this->float_data[Details::TAU_SEEDTRK_SECMAXSTRIPETOVERPT] = (tau_leadTrkPt->at(itau)!=0?tau_seedTrk_secMaxStripEt->at(itau)/tau_leadTrkPt->at(itau):LOW_NUMBER); + + + + + + + + return true; +} + +const float* TauDetailsManagerStandalone::getFloatDetailAddress(Details::FloatTauDetail detail) const { + + return &this->float_data[detail]; +} + +const int* TauDetailsManagerStandalone::getIntDetailAddress(Details::IntTauDetail detail) const { + + return &this->int_data[detail]; +} + +const float* TauDetailsManagerStandalone::getFloatDetailAddress(Details::FloatEventDetail detail) const { + + return &this->float_event_data[detail]; +} + +const int* TauDetailsManagerStandalone::getIntDetailAddress(Details::IntEventDetail detail) const { + + return &this->int_event_data[detail]; +} + +float TauDetailsManagerStandalone::getFloatDetailValue(Details::FloatTauDetail detail) const { + + return this->float_data[detail]; +} + +int TauDetailsManagerStandalone::getIntDetailValue(Details::IntTauDetail detail) const { + + return this->int_data[detail]; +} + +float TauDetailsManagerStandalone::getFloatDetailValue(Details::FloatEventDetail detail) const { + + return this->float_event_data[detail]; +} + +int TauDetailsManagerStandalone::getIntDetailValue(Details::IntEventDetail detail) const { + + return this->int_event_data[detail]; +} + +int TauDetailsManagerStandalone::getNtau() +{ + if(tau_pt) return tau_pt->size(); + else return 0; +} + diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauIDReader.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauIDReader.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bc8dd60b5800cf0d37cccf369ecbea65663f0708 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TauIDReader.cxx @@ -0,0 +1,774 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include "TauDiscriminant/TauIDReader.h" +#include "TROOT.h" +#include <iomanip> + +using namespace TauID; + +void TauIDReader::print() const +{ + ios_base::fmtflags original_flags = cout.flags(); + vector<string>::const_iterator name_it(this->methodNames.begin()); + vector<float*>::const_iterator it_float(this->methodBuffer.begin()); + cout << "Methods:" << endl; + for(; it_float != this->methodBuffer.end(); ++it_float) + { + cout << left << setw(40) << setfill('.') << *(name_it++) << ' ' << **it_float << endl; + } + cout << "Variables:" << endl; + name_it = this->floatNames.begin(); + it_float = this->floatVariables.begin(); + for(; it_float != this->floatVariables.end(); ++it_float) + { + cout << left << setw(40) << setfill('.') << *(name_it++) << ' ' << **it_float << endl; + } + name_it = this->vectFloatNames.begin(); + it_float = this->vectFloatVariables.begin(); + for(; it_float != this->vectFloatVariables.end(); ++it_float) + { + cout << left << setw(40) << setfill('.') << *(name_it++) << ' ' << **it_float << endl; + } + name_it = this->intNames.begin(); + vector<int*>::const_iterator it_int(this->intVariables.begin()); + for(; it_int != this->intVariables.end(); ++it_int) + { + cout << left << setw(40) << setfill('.') << *(name_it++) << ' ' << **it_int << endl; + } + name_it = this->vectIntNames.begin(); + it_int = this->vectIntVariables.begin(); + for(; it_int != this->vectIntVariables.end(); ++it_int) + { + cout << left << setw(40) << setfill('.') << *(name_it++) << ' ' << **it_int << endl; + } + cout.flags(original_flags); +} + +bool TauIDReader::bookMethod(Types::MethodType type, const string& name, const string& filename, unsigned int numResponses) { + + if (name.size() == 0) + { + cout << "You must supply a non-empty name" << endl; + return false; + } + + if (numResponses == 0) + { + cout << "Number of responses must be non-zero" << endl; + return false; + } + + if (find(methodNames.begin(),methodNames.end(),name) != methodNames.end()) + { + cout << "Method with name " << name << " was already booked." << endl; + return false; + } + + MethodBase* method; + if (type == Types::CUTS) + { + method = new MethodCuts(name); + + } + else if (type == Types::BDT) + { + method = new MethodBDT(name); + } + else if (type == Types::LLH) + { + method = new MethodLLH(name); + } + else if (type == Types::DUMMY) + { + method = new MethodDummy(name); + } + else if (type == Types::TRANSFORM) + { + method = new MethodTransform(name); + } + else + { + return false; + } + + if (verbose) cout << "Booking method " << name << endl; + + // Add variables that reference the outputs of other methods + vector<pair<string,string> >::const_iterator methodvar_it(this->methodVariables.begin()); + vector<string>::const_iterator method_name_it; + for (; methodvar_it != this->methodVariables.end(); ++methodvar_it) + { + method_name_it = find(this->methodNames.begin(),this->methodNames.end(),methodvar_it->second); + method->addVariable(methodvar_it->first,this->methodBuffer[method_name_it - this->methodNames.begin()],'F'); + } + + //vector<int*>::const_iterator it_val_int(intVariables.begin()); + vector<string>::const_iterator it_name(intNames.begin()); + for (; it_name != intNames.end();) + { + //method->addVariable(*(it_name++),*(it_val_int++),'I'); + string valname = *(it_name++); + const map<string,int*> *dets = m_tdms->getIntDetails(); + method->addVariable(valname,dets->at(valname),'I'); + } + + //vector<float*>::const_iterator it_val_float(floatVariables.begin()); + it_name = floatNames.begin(); + for (;/* it_val_float != floatVariables.end() &&*/ it_name != floatNames.end();) + { + string valname = *(it_name++); + const map<string,float*> *dets = m_tdms->getFloatDetails(); + std::cout<<valname<<std::endl; + method->addVariable(valname,dets->at(valname),'F'); + } + + //it_val_int = vectIntVariables.begin(); + it_name = vectIntNames.begin(); + for (; /*it_val_int != vectIntVariables.end() &&*/ it_name != vectIntNames.end();) + { + string valname = *(it_name++); + const map<string,int*> *dets = m_tdms->getIntDetails(); + method->addVariable(valname,dets->at(valname),'I'); + } + + //it_val_float = vectFloatVariables.begin(); + it_name = vectFloatNames.begin(); + for (; /*it_val_float != vectFloatVariables.end() &&*/ it_name != vectFloatNames.end();) + { + string valname = *(it_name++); + const map<string,float*> *dets = m_tdms->getFloatDetails(); + method->addVariable(valname,dets->at(valname),'F'); + } + + if (!method->build(filename,false)) + { + cout << "Initializing the method " << name << " failed." << endl; + delete method; + return false; + } + + this->methodNames.push_back(name); + this->methodBuffer.push_back(new float(0.)); + this->methods.push_back(pair<MethodBase*,vector<vector<float>* > >(method,vector<vector<float>* >(numResponses, 0))); + vector<vector<float>* >::iterator it = methods.back().second.begin(); + for (; it != methods.back().second.end(); ++it) + { + *it = new vector<float>(); + } + return true; +} + +bool TauIDReader::addVariable(const string& name, const string& type, const string& branchName) { + + if (this->verbose) cout << "Adding variable " << name << " --> " << branchName << endl; + if (find(this->allVariableNames.begin(), this->allVariableNames.end(), name) != this->allVariableNames.end()) + { + cout << "Variable " << name << " has already been booked" << endl; + return false; + } +// if (find(this->allBranchNames.begin(), this->allBranchNames.end(), branchName) != this->allBranchNames.end()) +// { +// cout << "A variable referring to branch " << branchName << " has already been booked" << endl; +// return false; +// } + vector<string>::const_iterator it(find(this->methodNames.begin(),this->methodNames.end(),branchName)); + if (it != this->methodNames.end()) + { + if (this->verbose) cout << "Branch matches name of method previously booked" << endl; + if (type != "F") + { + cout << "The type of all method outputs are scalar floats" << endl; + cout << "Variable referring to branch " << branchName << " must be of type \"F\"" << endl; + return false; + } + if (this->verbose) cout << "This variable will refer to the output of that method" << endl; + this->allVariableNames.push_back(name); + this->allBranchNames.push_back(branchName); + this->methodVariables.push_back(pair<string,string>(name,branchName)); + return true; + } + if (type == "F") + { + this->floatNames.push_back(name); + this->allVariableNames.push_back(name); + //this->floatBranches.push_back(branchName); + //this->allBranchNames.push_back(branchName); + this->floatVariables.push_back(new float(0.)); + return true; + } + else if (type == "I") + { + this->intNames.push_back(name); + this->allVariableNames.push_back(name); + //this->intBranches.push_back(branchName); + //this->allBranchNames.push_back(branchName); + this->intVariables.push_back(new int(0)); + return true; + } + else if (type == "VF") + { + this->vectFloatNames.push_back(name); + this->allVariableNames.push_back(name); + //this->vectFloatBranches.push_back(branchName); + //this->allBranchNames.push_back(branchName); + this->vectFloatVariables.push_back(new float(0.)); + this->vectorMode = true; + return true; + } + else if (type == "VI") + { + this->vectIntNames.push_back(name); + this->allVariableNames.push_back(name); + //this->vectIntBranches.push_back(branchName); + //this->allBranchNames.push_back(branchName); + this->vectIntVariables.push_back(new int(0)); + this->vectorMode = true; + return true; + } + cout << "Unknown variable type " << type << " for variable " << name << endl; + return false; +} + +bool TauIDReader::checkBranch(TTree* tree, const char* name, string type, bool checkType) +{ + if (!tree) + { + return false; + } + TBranch* branch = tree->GetBranch(name); + if (!branch) + { + cout << "Branch " << name << " does not exist!" << endl; + return false; + } + if (checkType) + { + if (strcmp(type.c_str(), branch->GetClassName())) + { + cout << "Branch " << name << " does not contain the correct type: " << branch->GetClassName() << " (expected " << type << ")" << endl; + return false; + } + } + return true; +} + +bool TauIDReader::setOutput(const string& outputFileName, const string& _outputDir) +{ + if (this->own_output) + { + delete this->output; + } + this->own_output = true; + this->output = new TFile(outputFileName.c_str(),"NEW"); + gROOT->GetListOfFiles()->Remove(this->output); + if (!this->output->IsOpen() || this->output->IsZombie()) + { + cout << "Could not create " << outputFileName << endl; + return false; + } + if (!this->output->GetDirectory(_outputDir.c_str())) + { + cout << "Could not find directory " << _outputDir << " in " << outputFileName << endl; + return false; + } + this->output->cd(_outputDir.c_str()); + if (this->verbose) + { + cout << "Output is now " << outputFileName; + if (_outputDir != "") + { + cout << "/" << _outputDir; + } + cout << endl; + } + this->outputDir = _outputDir; + return true; +} + +bool TauIDReader::setOutput(TFile& outputFile, const string& _outputDir) +{ + return this->setOutput(&outputFile, _outputDir); +} + +bool TauIDReader::setOutput(TFile* outputFile, const string& _outputDir) +{ + if (!outputFile) + { + cout << "NULL file!" << endl; + return false; + } + if (!outputFile->IsOpen() || outputFile->IsZombie()) + { + cout << "File is not open!" << endl; + return false; + } + if (this->own_output) + { + delete this->output; + } + this->own_output = false; + this->output = outputFile; + if (!this->output->GetDirectory(_outputDir.c_str())) + { + cout << "Could not find directory " << _outputDir << " in " << outputFile->GetName() << endl; + return false; + } + this->output->cd(_outputDir.c_str()); + if (this->verbose) + { + cout << "Output is now " << outputFile->GetName(); + if (outputDir != "") + { + cout << "/" << _outputDir; + } + cout << endl; + } + this->outputDir = _outputDir; + return true; +} + +int TauIDReader::classify(const string& inputTreeName, const string& outputTreeName, + const string& inputFileName, const string& inputDir, + bool makeFriend, + bool copyTree) +{ + unsigned int entries(0); + TFile* input = new TFile(inputFileName.c_str(), "READ"); + if (!input->IsOpen() || input->IsZombie()) + { + cout << "Could not open " << inputFileName << endl; + delete input; + return -1; + } + // Try to cd to desired directory in input ROOT file + if (!input->GetDirectory(inputDir.c_str())) + { + delete input; + cout << "Could not find directory " << inputDir << " in " << inputFileName << endl; + return -1; + } + input->cd(inputDir.c_str()); + TTree* tree = (TTree*)input->Get(inputTreeName.c_str()); + if (!tree) + { + cout << "Could not find tree " << inputTreeName << " in file " << inputFileName; + if (inputDir != "") + { + cout << "/" << inputDir << endl; + } + else + { + cout << endl; + } + delete input; + return -1; + } + entries = tree->GetEntries(); + TTree* outputTree = this->classify(tree, outputTreeName, copyTree); + if (!outputTree) + { + delete tree; + delete input; + return -1; + } + if (makeFriend) + { + if (verbose) + { + cout << "Making input tree a friend of output tree" << endl; + } + if (inputDir == "") + { + outputTree->AddFriend(inputTreeName.c_str(), inputFileName.c_str()); + } + else + { + string fullInputDir(inputFileName + "/" + inputDir); + outputTree->AddFriend(inputTreeName.c_str(), fullInputDir.c_str()); + } + } + this->output->cd(this->outputDir.c_str()); + outputTree->Write("",TObject::kOverwrite); + delete tree; + delete input; + delete outputTree; + return entries; +} + +TTree* TauIDReader::classify(TTree& tree, const string& outputTreeName, bool copyTree) +{ + return this->classify(&tree, outputTreeName, copyTree); +} + +TTree* TauIDReader::classify(TTree* tree, const string& outputTreeName, bool copyTree) +{ + if (!this->output) + { + cout << "No output file has been previously specified" << endl; + return 0; + } + if (!this->output->IsOpen() || this->output->IsZombie()) + { + cout << "Output file is not open" << endl; + return 0; + } + if (!tree) + { + cout << "Input tree is NULL!" << endl; + return 0; + } + int lastStatus(0); + unsigned long entry(0); + unsigned long numEntries(tree->GetEntries()); + if (numEntries == 0) + { + cout << "The input tree has no entries!" << endl; + return 0; + } + if (this->methods.size()==0) + { + cout << "No methods were booked successfully!" << endl; + return 0; + } + if (tree->GetNbranches() == 0) + { + cout << "Input tree contains no branches!" << endl; + return 0; + } + + + + m_tdms->initTree(tree); + + + vector<pair<MethodBase*,vector<vector<float>* > > >::iterator method_it; + vector<int*>::iterator intvalue_it; + vector<float*>::iterator floatvalue_it; + vector<string>::const_iterator intbranch_it; + vector<string>::const_iterator floatbranch_it; + vector<string>::const_iterator intname_it; + vector<string>::const_iterator floatname_it; + + + TTree* outputTree(0); + // this has already been checked in setOutput to succeed + this->output->cd(this->outputDir.c_str()); + + // Create the output tree + if (copyTree) + { + // Make sure that all branches are activated + tree->SetBranchStatus("*",1); + + // Deactivate the branches we will use for the Methods (if they already exist in the input tree) + for (method_it = methods.begin(); method_it != methods.end(); ++method_it) + { + for (unsigned int i(0); i<(method_it->second).size(); ++i) + { + string name = method_it->first->getName(); + if ((method_it->second).size() > 1) + { + name += to_string<unsigned int>(i); + } + if (tree->GetBranch(name.c_str())) + { + tree->SetBranchStatus(name.c_str(),0); + } + } + } + if (verbose) + { + cout << "Cloning input tree... " << flush; + } + outputTree = tree->CloneTree(-1,"fast"); + if (!outputTree) + { + if (verbose) cout << "fail" << endl; + cout << "Could not clone tree" << endl; + return 0; + } + outputTree->Write("",TObject::kOverwrite); + if (verbose) + { + cout << "done" << endl; + } + if (outputTree->GetNbranches() == 0) + { + cout << "The output tree contains no branches" << endl; + cout << "They were probably all deactivated before cloning the input tree" << endl; + delete outputTree; + return 0; + } + // Separate the cloned tree from the original + tree->CopyAddresses(outputTree, true); + //outputTree->ResetBranchAddresses(); + //outputTree->SetBranchStatus("*",0); + } + else + { + outputTree = new TTree(outputTreeName.c_str(),outputTreeName.c_str()); + } + + // Disable all branches of the input tree + tree->SetBranchStatus("*",0); + // Only the required branches are reactivated below + + m_tdms->initTree(tree); + + // Scalar variables: + + // Set the addresses of the int variables +// intvalue_it = intVariables.begin(); +// intbranch_it = intBranches.begin(); + + +// for ( ; intvalue_it != intVariables.end() && intbranch_it != intBranches.end(); ) +// { +// +// if (!checkBranch(tree,intbranch_it->c_str(),string("int"),false)) +// { +// delete outputTree; +// return 0; +// } +// +// tree->SetBranchStatus(intbranch_it->c_str(),1); +// if (tree->SetBranchAddress((intbranch_it++)->c_str(),*(intvalue_it++)) != 0) +// { +// delete outputTree; +// return 0; +// } +// +// } +// +// // Set the addresses of the float variables +// floatvalue_it = floatVariables.begin(); +// floatbranch_it = floatBranches.begin(); +// for (; floatvalue_it != floatVariables.end() && floatbranch_it != floatBranches.end(); ) +// { +// if (!checkBranch(tree,floatbranch_it->c_str(),string("float"),false)) +// { +// delete outputTree; +// return 0; +// } +// tree->SetBranchStatus(floatbranch_it->c_str(),1); +// if (tree->SetBranchAddress((floatbranch_it++)->c_str(),*(floatvalue_it++)) != 0) +// { +// delete outputTree; +// return 0; +// } +// } +// +// // Vector variables: +// +// vector<vector<int>* > intBuffer(vectIntVariables.size(),0); +// vector<vector<float>* > floatBuffer(vectFloatVariables.size(),0); +// +// // Set the addresses of the int vector variables +// vector<vector<int>* >::iterator intbuffer_it(intBuffer.begin()); +// intbranch_it = vectIntBranches.begin(); +// for (; intbuffer_it != intBuffer.end() && intbranch_it != vectIntBranches.end(); ) +// { +// if (!checkBranch(tree,intbranch_it->c_str(),string("vector<int>"))) +// { +// delete outputTree; +// return 0; +// } +// tree->SetBranchStatus(intbranch_it->c_str(),1); +// if (tree->SetBranchAddress((intbranch_it++)->c_str(),&(*(intbuffer_it++))) != 0) +// { +// delete outputTree; +// return 0; +// } +// } +// +// // Set the addresses of the float vector variables +// vector<vector<float>* >::iterator floatbuffer_it(floatBuffer.begin()); +// floatbranch_it = vectFloatBranches.begin(); +// for (; floatbuffer_it != floatBuffer.end() && floatbranch_it != vectFloatBranches.end(); ) +// { +// if (!checkBranch(tree,floatbranch_it->c_str(),string("vector<float>"))) +// { +// delete outputTree; +// return 0; +// } +// tree->SetBranchStatus(floatbranch_it->c_str(),1); +// if (tree->SetBranchAddress((floatbranch_it++)->c_str(),&(*(floatbuffer_it++))) != 0) +// { +// delete outputTree; +// return 0; +// } +// } + + vector<TBranch*> outputBranches; + + + // Initialize new branches in the output tree + for (method_it = methods.begin(); method_it != methods.end(); ++method_it) + { + for (unsigned int i(0); i<(method_it->second).size(); ++i) + { + string name = method_it->first->getName(); + if ((method_it->second).size() > 1) + { + name += to_string<unsigned int>(i); + } + method_it->second[i]->clear(); + if (this->vectorMode) + { + outputBranches.push_back(outputTree->Branch(name.c_str(),"std::vector<float>",&(method_it->second[i]))); + } + else + { + method_it->second[i]->push_back(0.); + outputBranches.push_back(outputTree->Branch(name.c_str(),&(*(method_it->second[i]->begin())),(name+"/F").c_str())); + } + } + } + +// void* sampleVector(0); +// bool sampleIsInt(false); + unsigned int vectorLength; + +// if (this->vectorMode) +// { +// if (vectIntVariables.size() > 0) +// { +// sampleVector = intBuffer[0]; +// sampleIsInt = true; +// } +// else +// { +// sampleVector = floatBuffer[0]; +// } +// } + + vector<TBranch*>::const_iterator outputBranches_it; + vector<TBranch*>::const_iterator outputBranches_end(outputBranches.end()); + + // The main event loop + + for (; entry < numEntries; ++entry) + { + tree->GetEntry(entry); + m_tdms->updateEvent(entry); + + + if (verbose) + { + int newStatus = int(100*(entry+1)/numEntries); + if (newStatus != lastStatus || entry == 0) + { + cout << "\rClassifying " << numEntries << " entries... " << newStatus << '%' << flush; + lastStatus = newStatus; + } + } + if (this->vectorMode) + { + // Assume all vectors have the same length (as they should...) + // TODO: protect against vectors of differing length +// if (sampleIsInt) +// vectorLength = static_cast<vector<int>* >(sampleVector)->size(); +// else +// vectorLength = static_cast<vector<float>* >(sampleVector)->size(); + + vectorLength = m_tdms->getNtau(); + + for (method_it = methods.begin(); method_it != methods.end(); ++method_it) + { + for (unsigned int i(0); i<(method_it->second).size(); ++i) + { + *(method_it->second)[i] = vector<float>(vectorLength,0.); + } + } + + for (unsigned int j(0); j < vectorLength; ++j) + { + + m_tdms->update(j); + + // Copy buffers to stage +/* intbuffer_it = intBuffer.begin(); + intvalue_it = this->vectIntVariables.begin(); + for (; intbuffer_it != intBuffer.end();) + { + **(intvalue_it++) = (**(intbuffer_it++))[j]; + } + floatbuffer_it = floatBuffer.begin(); + floatvalue_it = this->vectFloatVariables.begin(); + for (; floatbuffer_it != floatBuffer.end();) + { + **(floatvalue_it++) = (**(floatbuffer_it++))[j]; + }*/ + method_it = methods.begin(); + unsigned int k(0); + // Fill the output vector containing each Method's response + for (; method_it != methods.end(); ++method_it) + { + for (unsigned int i(0); i<(method_it->second).size(); ++i) + { + float response = method_it->first->response(i); + *(this->methodBuffer[k]) = response; + (*(method_it->second[i]))[j] = response; + } + ++k; + } + } + } + else + { + unsigned int j(0); + // Get the response from each Method + for (method_it = methods.begin(); method_it != methods.end(); ++method_it) + { + for (unsigned int i(0); i<(method_it->second).size(); ++i) + { + float response = method_it->first->response(i); + *(this->methodBuffer[j]) = response; + (*((method_it->second)[i]))[0] = response; + } + ++j; + } + } + if (copyTree) + { + outputBranches_it = outputBranches.begin(); + for(; outputBranches_it != outputBranches_end; ++outputBranches_it) + { + if ((*outputBranches_it)->Fill() < 1) + { + if (verbose) + { + cout << endl; + } + cout << "There was an error when filling the output tree" << endl; + delete outputTree; + return 0; + } + } + } + else + { + if (outputTree->Fill() < 1) + { + if (verbose) + { + cout << endl; + } + cout << "There was an error when filling the output tree" << endl; + delete outputTree; + return 0; + } + } + } + if (verbose) + { + cout << endl; + } + return outputTree; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/Transformation.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Transformation.cxx new file mode 100644 index 0000000000000000000000000000000000000000..881e588aac3cc1d64a90f80c9238d4caf6bb6caa --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Transformation.cxx @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: Transformation.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include "TauDiscriminant/Transformation.h" + +float Transformation::response() const { + + Node* currentNode = 0; + DecisionNode* decision = 0; + LeafNode<float>* leafNode = 0; + vector<pair<Node*,float> >::const_iterator tree = this->trees.begin(); + if (tree == this->trees.end()) return -200.; + currentNode = (*tree).first; + while (!currentNode->isLeaf()) { + decision = static_cast<DecisionNode*>(currentNode); + if (decision->goRight()) { + currentNode = decision->getRightChild(); + } else { + currentNode = decision->getLeftChild(); + } + if (!currentNode) return -200.; + } + leafNode = static_cast<LeafNode<float>*>(currentNode); + return leafNode->getValue(); +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeReader.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeReader.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e5aa846935e3fb20185706cb07f3695a2caf6b33 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeReader.cxx @@ -0,0 +1,748 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include "TauDiscriminant/TreeReader.h" +#include "TROOT.h" +#include "TNamed.h" +#include "TFile.h" +#include "TGraph.h" +#include "TGraph2D.h" +#include "TF1.h" + +bool isGoodTree(Node* node) +{ + if (!node) return false; + LeafNode<float> dummyLeafNode; + if (string(typeid(dummyLeafNode).name()).compare(typeid(*node).name())==0) return true; + return isGoodTree(node->getLeftChild()) && isGoodTree(node->getRightChild()); +} + +void findBadNodes(Node* node, vector<Node*>& badNodes) +{ + if (!node) return; + LeafNode<float> dummyLeafNode; + if (string(typeid(dummyLeafNode).name()).compare(typeid(*node).name())==0) return; + UnivariateCut<float>* intNode = static_cast<UnivariateCut<float>*>(node); + if (!intNode->isComplete()) badNodes.push_back(intNode); + findBadNodes(node->getLeftChild(),badNodes); + findBadNodes(node->getRightChild(),badNodes); +} + +string signature(Node* node, vector<Node*>* badNodes, string hash = "") +{ + if(!node) return hash; + if (badNodes) + { + if (find(badNodes->begin(),badNodes->end(),node) != badNodes->end()) hash += "[BAD]"; + } + Node* child = node->getLeftChild(); + if (child) hash = signature(child,badNodes,hash+"1")+"2"; + child = node->getRightChild(); + if (child) hash = signature(child,badNodes,hash+"3")+"2"; + return hash; +} + +void getLeafNodes(Node* node, vector<Node*>& leafNodes) +{ + if (!node) return; + if (node->isLeaf()) + { + leafNodes.push_back(node); + return; + } + getLeafNodes(node->getLeftChild(),leafNodes); + getLeafNodes(node->getRightChild(),leafNodes); +} + +void getIncompleteNodes(Node* node, vector<Node*>& incompleteNodes) +{ + if (!node) return; + if (!node->isComplete()) + { + incompleteNodes.push_back(node); + } + getIncompleteNodes(node->getLeftChild(),incompleteNodes); + getIncompleteNodes(node->getRightChild(),incompleteNodes); +} + +void attachTree(Node* tree, Node* subtree) +{ + if (!tree || !subtree) return; + vector<Node*> incompleteNodes; + getIncompleteNodes(tree, incompleteNodes); + vector<Node*>::iterator it(incompleteNodes.begin()); + for (;it != incompleteNodes.end(); ++it) + { + if(!(*it)) return; + if(!(*it)->getLeftChild()) static_cast<DecisionNode*>(*it)->setLeftChild(subtree->clone()); + if(!(*it)->getRightChild()) static_cast<DecisionNode*>(*it)->setRightChild(subtree->clone()); + } +} + +Node* createBalancedTree(const vector<DecisionNode*>& nodes) +{ + if (nodes.size() == 0) return 0; + DecisionNode* root = nodes.at(nodes.size()/2); + if (!root) return 0; + vector<DecisionNode*>::const_iterator midpoint(nodes.begin()+nodes.size()/2); + vector<DecisionNode*> leftTree(nodes.begin(),midpoint); + vector<DecisionNode*> rightTree(midpoint+1,nodes.end()); + root->setLeftChild(createBalancedTree(leftTree)); + root->setRightChild(createBalancedTree(rightTree)); + return root; +} + +Node* createBinningTree(const void* variable, char type, const vector<float>& binCuts) +{ + vector<float>::const_iterator it(binCuts.begin()); + vector<DecisionNode*> nodes; + for (;it != binCuts.end(); ++it) + { + if (type == 'F') + { + nodes.push_back(new UnivariateCut<float>((float*)variable,*it)); + } + else if (type == 'I') + { + nodes.push_back(new UnivariateCut<int>((int*)variable,(int)*it)); + } + else + { + return 0; + } + } + return createBalancedTree(nodes); +} + +Node* buildCategoryTree(const vector<Node*>& binningTrees) +{ + vector<Node*>::const_iterator it(binningTrees.begin()); + Node* tree = *(it++); + if (!tree) return 0; + tree = tree->clone(); + for (;it != binningTrees.end(); ++it) + { + attachTree(tree,*(it)); + } + vector<Node*> incompleteNodes; + getIncompleteNodes(tree,incompleteNodes); + it = incompleteNodes.begin(); + for (;it != incompleteNodes.end(); ++it) + { + if(!(*it)) return 0; + if(!(*it)->getLeftChild()) static_cast<DecisionNode*>(*it)->setLeftChild(new PointerLeafNode<TreeVector>()); + if(!(*it)->getRightChild()) static_cast<DecisionNode*>(*it)->setRightChild(new PointerLeafNode<TreeVector>()); + } + return tree; +} + +bool hasEnding(const string& fullString, const string& ending) +{ + if (fullString.length() > ending.length()) + { + return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); + } + else + { + return false; + } +} + +template<typename T> +bool read(istream& file, T& data, Format format) +{ + if (format == ASCII || format == ROOTFILE) + { + if ((file >> data).fail()) + { + return false; + } + } + else + { + file.read((char*)&data,sizeof(T)); + } + return true; +} + +bool good_file(TFile* file) +{ + if (!file) + return false; + return file->IsOpen() && !file->IsZombie(); +} + +Node* TreeReader::readTree( + istream& treeFile, + TFile* rootFile, + Format format, + vector<string>& variableList, + vector<char>& variableTypeList, + unsigned int& numNodes) +{ + int variable; + int idata; + float fdata; + string line; + Node* rootNode(0); + Node* node(0); + stack<DecisionNode*> parentNodeStack; + DecisionNode* parent(0); + if (!read<int>(treeFile,variable,format)) + { + print("Failed extracting variable index from the discriminant file"); + return 0; + } + while (variable != ENDOFTREE) + { + if (variable == LEAF) + { // parsing leaf node + if (!read<float>(treeFile,fdata,format)) + { + print("Failed extracting leaf node purity"); + return 0; + } + node = new LeafNode<float>(fdata); + } + else if (variable == POINTERLEAF) + { + node = new PointerLeafNode<TreeVector>(); + } + else if(variable == GRAPH || variable == FUNC || variable == TRANS) // Now reading a UnivariateSlidingCut1D/Tranformation node + { + int numPoints; + string expression; + string graphName; + float lowX, highX; + float lowY, highY; + if (variable == GRAPH) + { + if (!read<int>(treeFile,numPoints,format)) + { + print("Failed extracting number of points for a UnivariateSlidingCut1D node"); + return 0; + } + if (numPoints < 2) + { + print("Invalid number of points in UnivariateSlidingCut1D node"); + return 0; + } + } + else if (variable == FUNC) + { + treeFile >> expression; + getline(treeFile,line); // Discard \n + } + else + { + if (!rootFile) + { + print("Requested a transformation but input file is not a ROOT file"); + return 0; + } + if (!good_file(rootFile)) + { + print("Input ROOT file is not open while trying to get transformation!"); + return 0; + } + treeFile >> graphName; + getline(treeFile,line); // Discard \n + } + int varX, varY; + if (!read<int>(treeFile,varX,format)) + { + print("Failed extracting X for a UnivariateSlidingCut1D node"); + return 0; + } + if (variable == TRANS) + { + if(!read<float>(treeFile,lowX,format) || !read<float>(treeFile,highX,format)) + { + print("Failed extracting bounds on X for transformation"); + return 0; + } + } + if (!read<int>(treeFile,varY,format)) + { + print("Failed extracting Y for a UnivariateSlidingCut1D node"); + return 0; + } + if (variable == TRANS) + { + if(!read<float>(treeFile,lowY,format) || !read<float>(treeFile,highY,format)) + { + print("Failed extracting bounds on Y for transformation"); + return 0; + } + } + if (varX < 0 || varY < 0) + { + print("Invalid X or Y for UnivariateSlidingCut1D node"); + return 0; + } + TObject* graph; + if (variable == GRAPH) + { + graph = new TGraph(numPoints); + } + else if (variable == FUNC) + { + graph = new TF1(expression.c_str(),expression.c_str(),0.,1.); + } + else + { + TGraph2D* tempgraph = dynamic_cast<TGraph2D*>(rootFile->Get(graphName.c_str())); + if (!tempgraph) + { + print("Could not get transformation graph from ROOT file"); + return 0; + } + //tempgraph = dynamic_cast<TGraph2D*>(tempgraph->Clone()); + graph = tempgraph; + } + if (variableTypeList[varX] == 'F' && variableTypeList[varY] == 'I') + { + map<string,const float*>::const_iterator it1(floatVariables->find(variableList[varX])); + if (it1 == floatVariables->end()) + { + print("A Did not find variable "+variableList[varX]+" in booked float variables!"); + return 0; + } + map<string,const int*>::const_iterator it2(intVariables->find(variableList[varY])); + if (it2 == intVariables->end()) + { + print("B Did not find variable "+variableList[varY]+" in booked float variables!"); + return 0; + } + if (variable == GRAPH) + { + node = new UnivariateSlidingCut1D<int,TGraph,float>(it2->second,static_cast<TGraph*>(graph),it1->second); + } + else if (variable == FUNC) + { + node = new UnivariateSlidingCut1D<int,TF1,float>(it2->second,static_cast<TF1*>(graph),it1->second); + } + else + { + node = new TransformationNode<float,int,TGraph2D>(it1->second,lowX,highX,it2->second,lowY,highY,static_cast<TGraph2D*>(graph)); + } + } + else if (variableTypeList[varX] == 'I' && variableTypeList[varY] == 'F') + { + map<string,const int*>::const_iterator it1(intVariables->find(variableList[varX])); + if (it1 == intVariables->end()) + { + print("Did not find variable "+variableList[varX]+" in booked int variables!"); + return 0; + } + map<string,const float*>::const_iterator it2(floatVariables->find(variableList[varY])); + if (it2 == floatVariables->end()) + { + print("Did not find variable "+variableList[varY]+" in booked int variables!"); + return 0; + } + if (variable == GRAPH) + { + node = new UnivariateSlidingCut1D<float,TGraph,int>(it2->second,static_cast<TGraph*>(graph),it1->second); + } + else if (variable == FUNC) + { + node = new UnivariateSlidingCut1D<float,TF1,int>(it2->second,static_cast<TF1*>(graph),it1->second); + } + else + { + node = new TransformationNode<int,float,TGraph2D>(it1->second,lowX,highX,it2->second,lowY,highY,static_cast<TGraph2D*>(graph)); + } + } + else if (variableTypeList[varX] == 'F' && variableTypeList[varY] == 'F') + { + map<string,const float*>::const_iterator it1(floatVariables->find(variableList[varX])); + if (it1 == floatVariables->end()) + { + print("D Did not find variable "+variableList[varX]+" in booked float variables!"); + return 0; + } + map<string,const float*>::const_iterator it2(floatVariables->find(variableList[varY])); + if (it2 == floatVariables->end()) + { + print("E Did not find variable "+variableList[varY]+" in booked float variables!"); + return 0; + } + if (variable == GRAPH) + { + node = new UnivariateSlidingCut1D<float,TGraph,float>(it2->second,static_cast<TGraph*>(graph),it1->second); + } + else if (variable == FUNC) + { + node = new UnivariateSlidingCut1D<float,TF1,float>(it2->second,static_cast<TF1*>(graph),it1->second); + } + else + { + node = new TransformationNode<float,float,TGraph2D>(it1->second,lowX,highX,it2->second,lowY,highY,static_cast<TGraph2D*>(graph)); + } + } + else if (variableTypeList[varX] == 'I' && variableTypeList[varY] == 'I') + { + map<string,const int*>::const_iterator it1(intVariables->find(variableList[varX])); + if (it1 == intVariables->end()) + { + print("Did not find variable "+variableList[varX]+" in booked int variables!"); + return 0; + } + map<string,const int*>::const_iterator it2(intVariables->find(variableList[varY])); + if (it2 == intVariables->end()) + { + print("Did not find variable "+variableList[varY]+" in booked int variables!"); + return 0; + } + if (variable == GRAPH) + { + node = new UnivariateSlidingCut1D<int,TGraph,int>(it2->second,static_cast<TGraph*>(graph),it1->second); + } + else if (variable == FUNC) + { + node = new UnivariateSlidingCut1D<int,TF1,int>(it2->second,static_cast<TF1*>(graph),it1->second); + } + else + { + node = new TransformationNode<int,int,TGraph2D>(it1->second,lowX,highX,it2->second,lowY,highY,static_cast<TGraph2D*>(graph)); + } + } + else + { + print("Unsupported variable type in list found in discriminant file!"); + return 0; + } + if (variable == GRAPH) + { + TGraph* tgraph = static_cast<TGraph*>(graph); + float X,Y; + for (int k(0); k < numPoints; ++k ) + { + if (!read<float>(treeFile,X,format) || !read<float>(treeFile,Y,format)) + { + print("Failed extracting X,Y for a UnivariateSlidingCut1D node"); + delete node; + delete rootNode; + return 0; + } + tgraph->SetPoint(k,X,Y); + } + } + } + else + { // parsing internal node + if (variableTypeList[variable] == 'F')\ + { // internal node cuts on float + map<string,const float*>::const_iterator it(floatVariables->find(variableList[variable])); + if (it == floatVariables->end()) + { + print("F Did not find variable "+variableList[variable]+" in booked float variables!"); + return 0; + } + if (!read<float>(treeFile,fdata,format)) + { + print("Failed extracting internal float node cut"); + return 0; + } + node = new UnivariateCut<float>(it->second,fdata); + } + else if (variableTypeList[variable] == 'I') + { // internal node cuts on int + map<string,const int*>::const_iterator it(intVariables->find(variableList[variable])); + if (it == intVariables->end()) + { + print("Did not find variable "+variableList[variable]+" in booked int variables!"); + return 0; + } + if (!read<int>(treeFile,idata,format)) + { + print("Failed extracting internal int node cut"); + return 0; + } + node = new UnivariateCut<int>(it->second,idata); + } + else + { // unknown node type + print("Unsupported variable type in list found in discriminant file!"); + return 0; + } + } + ++numNodes; + + if (parentNodeStack.empty()) + { + if (variable == LEAF) + { + print("Corrupt tree! Adding leaf node as root node."); + delete node; + return 0; + } + rootNode = node; + } + else + { + parent = parentNodeStack.top(); + while (parent->isComplete()) + { + parentNodeStack.pop(); + if (parentNodeStack.empty()) + { + print("Corrupt tree! Expected a parent node."); + delete node; + delete rootNode; + return 0; + } + parent = parentNodeStack.top(); + } + if (!parent->getLeftChild()) + { + parent->setLeftChild(node); + } + else if (!parent->getRightChild()) + { + parent->setRightChild(node); + } + else + { + print("Corrupt tree! Attempted to add a child to a complete node!"); + delete node; + delete rootNode; + return 0; + } + } + + if (variable != LEAF) + { + parentNodeStack.push(static_cast<DecisionNode*>(node)); + } + + if (!read<int>(treeFile,variable,format)) + { + print("Failed extracting variable index"); + delete rootNode; + return 0; + } + } + while (!parentNodeStack.empty()) parentNodeStack.pop(); + return rootNode; +} + +Node* TreeReader::build( + const string& filename, + bool checkTree) +{ + + Format format; + if (hasEnding(filename, ".bin")) + { + format = BINARY; + if (verbose) print("Reading input as binary"); + } + else if (hasEnding(filename, ".txt")) + { + format = ASCII; + if (verbose) print("Reading input as ASCII text"); + } + else if (hasEnding(filename, ".root")) + { + format = ROOTFILE; + if (verbose) print("Reading input as ROOT file"); + } + else + { + print("Unknown discriminant format"); + return 0; + } + + unsigned int numVariables; + Node* categoryTree; + Node* rootNode; + vector<string> tokens; + string line; + string token; + vector<string> variableList; + vector<char> variableTypeList; + vector<string> binningVariableList; + vector<char> binningVariableTypeList; + char type; + unsigned int numNodes(0); + + istream* treeInfoTemp; + ifstream treeFile; + istringstream treeString; + TFile* file(0); + + if (format == ROOTFILE) + { + // read in tree data from ROOT file and place in stringstream + file = new TFile(filename.c_str(), "READ"); + if (!good_file(file)) + { + print("The discriminant ROOT file "+filename+" will not open!"); + return 0; + } + TNamed* treeInfoText = (TNamed*)file->Get("TreeInfo"); + if (!treeInfoText) + { + print("Could not find TreeInfo in discriminant ROOT file!"); + file->Close(); + return 0; + } + string treeInfoTextString(treeInfoText->GetTitle()); + treeString.str(treeInfoTextString); + delete treeInfoText; + treeInfoTemp = &treeString; + } + else + { + treeFile.open(filename.c_str(),ios::in); + if (!treeFile.is_open()) + { + print("The discriminant file "+filename+" will not open!"); + return 0; + } + treeInfoTemp = &treeFile; + } + istream& treeInfo(*treeInfoTemp); + + unsigned int numBinningVariables = 0; + if ((treeInfo >> numBinningVariables).fail()) + { + print("Failed extracting the number of binning variables in the discriminant file!"); + return 0; + } + + binningVariableList = vector<string>(numBinningVariables,""); + binningVariableTypeList = vector<char>(numBinningVariables,'F'); + + for (unsigned int j(0); j < numBinningVariables; ++j) + { + if ((treeInfo >> binningVariableList[j]).fail()) + { + print("Failed extracting a variable name from the discriminant file"); + return 0; + } + if ((treeInfo >> type).fail()) + { + print("Failed extracting a variable type from the discriminant file"); + return 0; + } + if (type != 'F' && type != 'I') + { + print("Unsupported variable type found in the discriminant file: "+type); + return 0; + } + binningVariableTypeList[j] = type; + } + getline(treeFile,line); // discard \n + + if (numBinningVariables > 0) + { + categoryTree = readTree(treeInfo,file,ASCII,binningVariableList,binningVariableTypeList,numNodes); + } + else + { + categoryTree = new PointerLeafNode<TreeVector>(); + } + + if ((treeInfo >> numVariables).fail()) + { + print("Failed extracting number of variables from the discriminant file!"); + delete categoryTree; + return 0; + } + + variableList = vector<string>(numVariables,""); + variableTypeList = vector<char>(numVariables,'F'); + + for (unsigned int j(0); j < numVariables; ++j) + { + if ((treeInfo >> variableList[j]).fail()) + { + print("Failed extracting a variable name from the discriminant file"); + delete categoryTree; + return 0; + } + if ((treeInfo >> type).fail()) + { + print("Failed extracting a variable type from the discriminant file"); + delete categoryTree; + return 0; + } + if (type != 'F' && type != 'I') + { + print("Unsupported variable type found in the discriminant file: "+type); + delete categoryTree; + return 0; + } + variableTypeList[j] = type; + } + getline(treeInfo,line); // discard \n + + // Get vector of all leaf nodes of the category tree and initialize an iterator + vector<Node*> categories; + vector<Node*>::const_iterator category_it, category_end; + getLeafNodes(categoryTree, categories); + category_it = categories.begin(); + category_end = categories.end(); + + unsigned int numTrees; + float weight; + + // Build the (categorized) TreeVector + TreeVector* treeVector; + for (;category_it != category_end; ++category_it) + { + numNodes = 0; + treeVector = new TreeVector(); + static_cast<PointerLeafNode<TreeVector>* >(*category_it)->setValue(treeVector); + + if (!read<unsigned int>(treeInfo,numTrees,format)) print("Failed extracting number of trees from the discriminant file!"); + + for (unsigned int j(0); j < numTrees; ++j) + { + rootNode = 0; + + if (!read<float>(treeInfo,weight,format)) + { + print("Failed extracting tree weight from the discriminant file"); + delete categoryTree; + return 0; + } + rootNode = readTree(treeInfo,file,format,variableList,variableTypeList,numNodes); + if (!rootNode) + { + print("Null tree!"); + delete categoryTree; + return 0; + } + if (checkTree) + { + vector<Node*> badNodes; + findBadNodes(rootNode,badNodes); + if (badNodes.size()>0) + { + print("Tree is not well-formed!"); + print("Bad tree has signature: "+signature(rootNode,&badNodes)); + delete categoryTree; + return 0; + } + } + treeVector->addTree(rootNode,weight); + } + if (verbose) print("Created a tree vector with "+to_string(numNodes)+" nodes"); + } + treeFile.close(); + if (file) + { + //file->Close(); + } + //delete file; + return categoryTree; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeVector.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeVector.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3385305b2cba89d05b7915842026ba2bfbfae5d0 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/TreeVector.cxx @@ -0,0 +1,6 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "TauDiscriminant/TreeVector.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/Root/Types.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Types.cxx new file mode 100644 index 0000000000000000000000000000000000000000..42a0d57e4e6ac9b4f3e69222293b3add043d7552 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/Root/Types.cxx @@ -0,0 +1,5 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/Types.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/BoostedDecisionTree.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/BoostedDecisionTree.h new file mode 100644 index 0000000000000000000000000000000000000000..fa8200b721708b55fc4f3dc8d4dab28dfbe5889e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/BoostedDecisionTree.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef BOOSTEDDECISIONTREE_H +#define BOOSTEDDECISIONTREE_H + +#include <iostream> +#include <string> +#include <vector> +#include <map> +#include <utility> +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/TreeVector.h" + +using namespace std; + +class BoostedDecisionTree : public TreeVector { + + public: + + //!< Default Constructor + BoostedDecisionTree() {} + + /** + * @brief Returns the @c float score for the set of variables and values in @c variableMap. + * @param variableMap + */ + float response() const; + +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CommonLikelihood.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CommonLikelihood.h new file mode 100644 index 0000000000000000000000000000000000000000..c207b745c51f43bb12f954b85ed42a76051e8549 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CommonLikelihood.h @@ -0,0 +1,158 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: CommonLikelihood.h + * + * Author: Martin Flechl (mflechl@cern.ch) + */ + +#ifndef COMMONLIKELIHOOD_H +#define COMMONLIKELIHOOD_H + +#include <iostream> +#include <string> +#include <vector> +#include <map> +#include <assert.h> +#ifndef __STANDALONE +#include "GaudiKernel/MsgStream.h" +#endif + +#include "TH3.h" +#include "TFile.h" +#include "TString.h" +#include "TMath.h" +#include "TGraph.h" +using namespace std; + +//mw added +////////////////////////////////////////////////////////////////////////////////////////////// +const unsigned int NVAR_SAFE_1P=5; +const unsigned int NVAR_SAFE_3P=6; +const unsigned int NVAR_DEF=16; +////////////////////////////////////////////////////////////////////////////////////////////// + + +class CommonLikelihood{ + + public: + + //Constructor +#ifndef __STANDALONE + CommonLikelihood(bool _verbose=false,MsgStream* _log = 0):log(_log), +#else + CommonLikelihood(bool _verbose=false): +#endif + m_tauFile(NULL), + m_jetFile(NULL), + m_cutFile(NULL), + m_mu_correction_factor_1P(0.317), + m_mu_correction_factor_3P(0.117), + tg_loose_cuts_1P(NULL), + tg_medium_cuts_1P(NULL), + tg_tight_cuts_1P(NULL), + tg_loose_cuts_3P(NULL), + tg_medium_cuts_3P(NULL), + tg_tight_cuts_3P(NULL), + m_doTrigger(false) + { + if (_verbose) cout << "CommonLikelihood: Creating Instance..." << endl; + m_tauFilename="pdfs_tau.root"; + m_jetFilename="pdfs_jets.root"; + m_cutFilename="LMTCutsLLH.root"; + m_llh=-99; + m_et=-9999.; + m_prongindex=-1; + m_ntau[0]=0; m_ntau[1]=0; + NVAR=56; + DEBUG=0; + if (_verbose) DEBUG=1; + this->verbose = _verbose; + // DEBUG=2; + m_smooth = false; + } + ~CommonLikelihood(){ + if(m_tauFile) m_tauFile->Close(); + delete m_tauFile; + if(m_jetFile) m_jetFile->Close(); + delete m_jetFile; + if(m_cutFile) m_cutFile->Close(); + delete m_cutFile; + } + bool build(const string& filename); + int response(int level=-1, int option=-1) const; + bool calcLLHValue(const map<string,const float*>* floatVariables, + const map<string,const int*>* intVariables, int option); + float getLLHValue(){ return m_llh; } + + void setDoTrigger(bool trig) { m_doTrigger = trig; } + + private: + + bool readPDFHistograms(); + bool readLMTCuts(); + bool smoothPDFHistograms(); + void smooth3D(TH3F* hTmp); + TH3F* divideLog(TH3F* hTmpTau, TH3F* hTmpJet); + Double_t Interpolate(TH3F* hist, Double_t x, Double_t y, Double_t z); + int varNameToNumber(std::string varname) const; + float getSingleLLHRatio(const int ivar, const int numtrack, const int author, const float et, const int nvtx, const float value); + float getSimpleSingleLLHRatio(const int ivar, const int numtrack, const int author, const float et, const int nvtx, const float value); + bool skipVar(const TString varname,const int numtrack,const int author,const int option) const; + void splitString(const string& str, vector<string>& substrings, const string& delimiters = " ") const; + + void print(TString message, int level) const { +#ifndef __STANDALONE + if (log) { + if (level<=0) (*log) << "WARNING" << message << endreq; + else (*log) << "DEBUG" << message << endreq; + } + else +#endif + if (level<=DEBUG) cout << message << endl; + } + +#ifndef __STANDALONE + MsgStream* log; +#endif + + std::string m_tauFilename; + std::string m_cutFilename; + std::string m_jetFilename; + TFile *m_tauFile; + TFile *m_jetFile; + TFile *m_cutFile; + float m_llh; + float m_et; + int m_prongindex; + int m_nvtx; + int m_ntau[2]; + bool m_smooth; + + double m_mu_correction_factor_1P; + double m_mu_correction_factor_3P; + + std::vector<TGraph*> m_vLMTCuts1P; + std::vector<TGraph*> m_vLMTCuts3P; + int NVAR; + std::map<std::string,TH3F*> m_pdfHistogramsTau; + std::map<std::string,TH3F*> m_pdfHistogramsJet; + std::map<std::string,TH3F*> m_pdfHistogramsRatio; + TGraph* tg_loose_cuts_1P; + TGraph* tg_medium_cuts_1P; + TGraph* tg_tight_cuts_1P; + TGraph* tg_loose_cuts_3P; + TGraph* tg_medium_cuts_3P; + TGraph* tg_tight_cuts_3P; + + bool m_doTrigger; + + int DEBUG; + bool verbose; + + map<string,float> getVariables(const map<string,const float*>* floatVariables,const map<string,const int*>* intVariables, const int numtrack, const int author, const int option) const; +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CutsDecisionTree.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CutsDecisionTree.h new file mode 100644 index 0000000000000000000000000000000000000000..bde85473dc6f8db6343456649fb967faff9f6fd5 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/CutsDecisionTree.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef CUTSDECISIONTREE_H +#define CUTSDECISIONTREE_H + +#include <iostream> +#include <string> +#include <vector> +#include <map> +#include <utility> +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/TreeVector.h" + +using namespace std; + +class CutsDecisionTree: public TreeVector { + + public: + + //!< Default Constructor + CutsDecisionTree() {} + + float response(unsigned int level) const; +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/EMFCluster.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/EMFCluster.h new file mode 100644 index 0000000000000000000000000000000000000000..3092b134f2da100646296585c5fa0ec93267621e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/EMFCluster.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EMFCluster_H +#define EMFCluster_H + +//*******************************************************// +// Name: EMFCluster.h // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: A simple class to house cluster // +// TLorentzVectors and their associated fractions of // +// energy in different calorimeter layers // +//*******************************************************// + +#include <TLorentzVector.h> + +class EMFCluster +{ +public: + //Constructor, Destructor + EMFCluster(); + EMFCluster(double pt); + EMFCluster(const TLorentzVector& inCluster, + double inPSSF, + double inEM2F, + double inEM3F); + ~EMFCluster(); + + //Getters + TLorentzVector TLV() const {return m_cluster;} + + double PSSF() const {return m_PSSF;} + double EM2F() const {return m_EM2F;} + double EM3F() const {return m_EM3F;} + double HADF() const {return m_HADF;} + double pseudoHADF() const {return m_pseudoHADF;} + + double PSSE() const {return m_PSSE;} + double EM2E() const {return m_EM2E;} + double EM3E() const {return m_EM3E;} + double HADE() const {return m_HADE;} + double pseudoHADE() const {return m_pseudoHADE;} + + //Comparison operator + bool operator< (const EMFCluster& rhs) const + { return (m_cluster.E() < rhs.TLV().E()); } + +private: + //Cluster 4-vector + TLorentzVector m_cluster; + + //Layer related info + double m_PSSF; // Fraction on energy in the PreSampler and Strip layers + double m_EM2F; // Fraction of energy in layer 2 of the EM calorimeter + double m_EM3F; // Fraction of energy in layer 3 of the EM calorimeter + double m_HADF; // Fraction of energy in the hadronic calorimeter + double m_pseudoHADF; // Fraction of energy in layer 3 of the EM calorimeter and hadronic calorimeter + + double m_PSSE; // Energy in the PreSampler and Strip layers + double m_EM2E; // Energy in layer 2 of the EM calorimeter + double m_EM3E; // Energy in layer 3 of the EM calorimeter + double m_HADE; // Energy in the hadronic calorimeter + double m_pseudoHADE; // Energy in layer 3 of the EM calorimeter and hadronic calorimeter + + //Calculate the hadronic fractions and energies + void update(); +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauBits.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauBits.h new file mode 100644 index 0000000000000000000000000000000000000000..0d58ca62688d73f8a47c95be07d0a7adb292cbe9 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauBits.h @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// AUTHOR: Noel Dawe +#ifndef FAKETAUBITS_H +#define FAKETAUBITS_H + +#include <bitset> +#include <algorithm> +#include "xAODTau/TauJet.h" +#include "DataModel/DataVector.h" +#include "SGTools/CLASS_DEF.h" + +namespace TauBit +{ + enum TauBit + { + BDT_LOOSE_BKG, + BDT_MEDIUM_BKG, + BDT_TIGHT_BKG + }; +} + +class FakeTauBits +{ + typedef TauBit::TauBit TauBit; + friend class FakeTauBitsContainer; + + public: + + FakeTauBits(const xAOD::TauJet* tau): + tau(tau) + {} + + void setBit(TauBit bit, bool value) + { + bits[bit] = value; + } + + bool getBit(TauBit bit) const + { + return bits[bit]; + } + + private: + + std::bitset<32> bits; + const xAOD::TauJet* tau; +}; + +class FakeTauBitsContainer: public DataVector<FakeTauBits> +{ + public: + + FakeTauBitsContainer( SG::OwnershipPolicy own = SG::OWN_ELEMENTS ): + DataVector<FakeTauBits>( own ) {} + + const FakeTauBits* getBitsAssocTo(const xAOD::TauJet* tau) const + { + if (!tau) + return 0; + FakeTauBitsContainer::const_iterator it(this->begin()); + FakeTauBitsContainer::const_iterator it_end(this->end()); + for(; it != it_end; ++it) + { + if (tau == (*it)->tau) + return *it; + } + return 0; + } + + const FakeTauBits* getBitsAssocTo(const xAOD::TauJet& tau) const + { + FakeTauBitsContainer::const_iterator it(this->begin()); + FakeTauBitsContainer::const_iterator it_end(this->end()); + for(; it != it_end; ++it) + { + if (&tau == (*it)->tau) + return *it; + } + return 0; + } +}; + +SG_BASE( FakeTauBitsContainer, DataVector<FakeTauBits> ); + +CLASS_DEF( FakeTauBitsContainer , 1316558256 , 1 ) + +#endif // FAKETAUBITS diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauScores.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauScores.h new file mode 100644 index 0000000000000000000000000000000000000000..c89bf4e1122206298573530502c0648506a58ec9 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/FakeTauScores.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// AUTHOR: Noel Dawe +#ifndef FAKETAUSCORES_H +#define FAKETAUSCORES_H + +#include <algorithm> +#include "xAODTau/TauJet.h" +#include "DataModel/DataVector.h" +#include "SGTools/CLASS_DEF.h" + +namespace TauScore +{ + enum TauScore + { + BDT_TRANS_BKG, + BDT_TRANS_SIG, + BDT_PI0_PRIMARY, + BDT_PI0_SECONDARY, + __END__ + }; +} + +class FakeTauScores +{ + // DR: clang32 is confused by this + // typedef TauScore::TauScore TauScore; + friend class FakeTauScoresContainer; + + public: + + FakeTauScores(const xAOD::TauJet* tau): + scores(TauScore::__END__,0.), + tau(tau) + {} + + void setScore(TauScore::TauScore score, float value) + { + scores[score] = value; + } + + float getScore(TauScore::TauScore score) const + { + return scores[score]; + } + + private: + + std::vector<float> scores; + const xAOD::TauJet* tau; +}; + +class FakeTauScoresContainer: public DataVector<FakeTauScores> +{ + public: + + FakeTauScoresContainer( SG::OwnershipPolicy own = SG::OWN_ELEMENTS ): + DataVector<FakeTauScores>( own ) {} + + const FakeTauScores* getScoresAssocTo(const xAOD::TauJet* tau) const + { + if (!tau) + return 0; + FakeTauScoresContainer::const_iterator it(this->begin()); + FakeTauScoresContainer::const_iterator it_end(this->end()); + for(; it != it_end; ++it) + { + if (tau == (*it)->tau) + return *it; + } + return 0; + } + + const FakeTauScores* getScoresAssocTo(const xAOD::TauJet& tau) const + { + FakeTauScoresContainer::const_iterator it(this->begin()); + FakeTauScoresContainer::const_iterator it_end(this->end()); + for(; it != it_end; ++it) + { + if (&tau == (*it)->tau) + return *it; + } + return 0; + } +}; + +SG_BASE( FakeTauScoresContainer, DataVector<FakeTauScores> ); + +CLASS_DEF( FakeTauScoresContainer , 1249450621 , 1 ) + +#endif // FAKETAUSCORES diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBDT.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBDT.h new file mode 100644 index 0000000000000000000000000000000000000000..6097e77edf3bd5926216bd981a5a10e0efc6cbd9 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBDT.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef METHODBDT_H +#define METHODBDT_H + +#include <string> +#include <vector> +#include <stack> +#include <map> +#include <utility> +#include <iostream> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <typeinfo> +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/BoostedDecisionTree.h" +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/TreeReader.h" + +using namespace std; + +namespace TauID +{ + class MethodBDT : public MethodBase + { + public: + + //!< Default constructor + #ifdef __STANDALONE + MethodBDT(const string& _name = "", bool _verbose = false): + MethodBase(_name,_verbose), + isBuilt(false), + categoryTree(0) + {} + #else + MethodBDT(const string& _name = ""): + MethodBase(_name), + isBuilt(false), + categoryTree(0) + {} + #endif + + //!< Destructor + ~MethodBDT() + { + delete this->categoryTree; + } + + bool build(const string& filename, bool checkTree = false); + + float response() const; + + float response(unsigned int level) const + { + if (level != 0) + { + print("MethodBDT does not output more than one possible response."); + print("Use a MethodCuts on the MethodBDT response to determine loose, medium, and tight boolean values."); + } + return response(); + } + + BoostedDecisionTree* getCurrentCategory() const; + + Types::MethodType getType() const + { + return Types::BDT; + } + + void addVariable(const string& _name, const void* _value, char type = 'F') + { + MethodBase::addVariable(_name,_value,type); + } + + #ifndef __STANDALONE + void setDetails(const TauDetailsManager& manager) + { + MethodBase::setDetails(manager); + } + #endif + + private: + + bool isBuilt; + Node* categoryTree; + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBase.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBase.h new file mode 100644 index 0000000000000000000000000000000000000000..a8227f4106891ebe2cd53ed4f4afd8e540da15ea --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodBase.h @@ -0,0 +1,177 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef METHODBASE_H +#define METHODBASE_H + +#include <string> +#include <iostream> +#include <map> +#include <algorithm> +#include "TauDiscriminant/Types.h" + +#ifndef __STANDALONE + //including the Message Stream Member + #include "AthenaKernel/MsgStreamMember.h" + #include "TauDiscriminant/TauDetailsManager.h" +#endif + +using namespace std; + +namespace TauID +{ + class MethodBase + { + public: + + //////////////////////////////////////////////////////////// + /// The name is an arbitrary name set by the user and should + /// have no influence on the behaviour of the method + //////////////////////////////////////////////////////////// + #ifdef __STANDALONE + MethodBase(const string& _name = "", bool _verbose = false): + name(_name), + verbose(_verbose) + {} + #else + MethodBase(const string& _name = ""): + name(_name) + {} + #endif + + virtual ~MethodBase() {} + + /////////////////////////////////////////////////////////// + /// Return the value of a continuous discriminant + /////////////////////////////////////////////////////////// + virtual float response() const =0; + + /////////////////////////////////////////////////////////// + /// This method should only be used for cut-based + /// methods for responses at different levels of + /// "tightness." For continuous discriminants, this + /// method should print a warning message and + /// return the value of response() above. + /////////////////////////////////////////////////////////// + virtual float response(unsigned int level) const =0; + + string getName() const + { + return name; + } + + /////////////////////////////////////////////////////////// + /// Add a variable. You should not need to + /// override this method. + /////////////////////////////////////////////////////////// + void addVariable(const string& _name, const void* value, char type = 'F') + { + if (!value) + { + print("Variable pointer is NULL!"); + return; + } + string localname = _name; + // Convert to uppercase: + std::transform(localname.begin(), localname.end(), localname.begin(), &upper); + if (type == 'F') + { + this->floatVariables[localname] = (const float*)value; + } + else if (type == 'I') + { + this->intVariables[localname] = (const int*)value; + } + else + { + print("Unsupported variable type!"); + } + } + + #ifndef __STANDALONE + ////////////////////////////////////////////////////////// + /// This method is used in Athena to set the + /// variables instead of the addVariable method + ////////////////////////////////////////////////////////// + void setDetails(const TauDetailsManager& manager) + { + const map<string,float*>* floatDetails = manager.getFloatDetails(); + map<string,float*>::const_iterator it1(floatDetails->begin()); + for (; it1 != floatDetails->end(); ++it1 ) + { + this->addVariable(it1->first,it1->second,'F'); + } + const map<string,int*>* intDetails = manager.getIntDetails(); + map<string,int*>::const_iterator it2(intDetails->begin()); + for (; it2 != intDetails->end(); ++it2 ) + { + this->addVariable(it2->first,it2->second,'I'); + } + } + #endif + + void print(string message) const + { + #ifdef __STANDALONE + if (this->verbose) + { + cout << message << endl; + } + #else + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << message << endreq; + } + #endif + } + + //////////////////////////////////////////////////////////// + /// Build the discriminant from an input file + /// The first parameter is a filename. Your method + /// should be saved in only one file. + /// Specifying a list of files here separated + /// by commas, for example, is not acceptable. + /// The boolean parameter is optional and may be + /// used to optionally validate your method after + /// building from your input file. + //////////////////////////////////////////////////////////// + virtual bool build(const string&, bool = false) =0; + + virtual Types::MethodType getType() const =0; + + #ifndef __STANDALONE + //Declaring the Message method for further use + MsgStream& msg( MSG::Level lvl ) const { return m_msg << lvl ; } + + //Declaring the Method providing Verbosity Level + bool msgLvl( MSG::Level lvl ) const { return m_msg.get().level() <= lvl ; } + #endif + + private: + + static int upper(int c) + { + return std::toupper((unsigned char)c); + } + + string name; + + protected: + + #ifdef __STANDALONE + bool verbose; + #else + //Declaring private message stream member. + mutable Athena::MsgStreamMember m_msg ; + #endif + + map<string,const float*> floatVariables; + map<string,const int*> intVariables; + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodCuts.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodCuts.h new file mode 100644 index 0000000000000000000000000000000000000000..3f9a72f6bcee64d9abca6c64803f05f1b4dd3f31 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodCuts.h @@ -0,0 +1,98 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef METHODCUTS_H +#define METHODCUTS_H + +#include <string> +#include <vector> +#include <stack> +#include <map> +#include <utility> +#include <iostream> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <typeinfo> +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/CutsDecisionTree.h" +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/TreeReader.h" + +using namespace std; + +namespace TauID +{ + class MethodCuts : public MethodBase + { + public: + + //!< Default constructor + #ifdef __STANDALONE + MethodCuts(const string& _name = "", bool _verbose = false): + MethodBase(_name,_verbose), + isBuilt(false), + nLevels(0), + categoryTree(0) + {} + #else + MethodCuts(const string& _name = ""): + MethodBase(_name), + isBuilt(false), + nLevels(0), + categoryTree(0) + {} + #endif + + //!< Destructor + ~MethodCuts() + { + delete this->categoryTree; + } + + bool build(const string& filename, bool checkTree = false); + + float response() const + { + return response(0); + } + + float response(unsigned int level) const; + + unsigned int numLevels() const + { + return this->nLevels; + } + + CutsDecisionTree* getCurrentCategory() const; + + Types::MethodType getType() const + { + return Types::CUTS; + } + + void addVariable(const string& _name, const void* _value, char type = 'F') + { + MethodBase::addVariable(_name,_value,type); + } + + #ifndef __STANDALONE + void setDetails(const TauDetailsManager& manager) + { + MethodBase::setDetails(manager); + } + #endif + + private: + + bool isBuilt; + unsigned int nLevels; + Node* categoryTree; + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodDummy.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodDummy.h new file mode 100644 index 0000000000000000000000000000000000000000..23943206f2b7bef4553b85a1ddc898d1922c025d --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodDummy.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * MethodDummy is used for speed benchmarking the other Methods. + * A better approximation of a Method's processing time per classification instance + * is after subtraction of the processing time per entry of MethodDummy to remove + * data I/O time and other constant overhead. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef METHODDUMMY_H +#define METHODDUMMY_H + +#include "TauDiscriminant/MethodBase.h" + +using namespace std; + +namespace TauID +{ + class MethodDummy : public MethodBase + { + public: + + //!< Default constructor + #ifdef __STANDALONE + MethodDummy(const string& _name = "", bool _verbose = false): + MethodBase(_name,_verbose) + {} + #else + MethodDummy(const string& _name = ""): + MethodBase(_name) + {} + #endif + + //!< Destructor + ~MethodDummy() + {} + + bool build(const string& filename, bool checkTree = false); + + float response() const; + + float response(unsigned int level) const + { + if (level != 0) + { + print("MethodDummy does not output more than one possible response."); + } + return response(); + } + + Types::MethodType getType() const + { + return Types::DUMMY; + } + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodLLH.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodLLH.h new file mode 100644 index 0000000000000000000000000000000000000000..5879fb0290ea8ff8f11f08ba93cacd7d152bb004 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodLLH.h @@ -0,0 +1,81 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: MethodLLH.h + * + * Author: Martin Flechl (mflechl@cern.ch) + */ + +#ifndef METHODLLH_H +#define METHODLLH_H + +#include <string> +#include <vector> +#include <stack> +#include <map> +#include <utility> +#include <iostream> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <typeinfo> +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/CommonLikelihood.h" + +using namespace std; + +namespace TauID +{ + class MethodLLH : public MethodBase { + + public: + + #ifdef __STANDALONE + MethodLLH(const string& _name = "", bool _verbose = false): + MethodBase(_name,_verbose), + isBuilt(false), + nLevels(0), + llh(NULL) + {} + #else + MethodLLH(const string& _name = ""): + MethodBase(_name), + isBuilt(false), + nLevels(0), + llh(NULL) + {} + #endif + + ~MethodLLH() { + delete llh; + } + + bool build(const string& filename, bool check=false); + + float response() const { return response(0); } + + float response(unsigned int level) const; + + unsigned int numLevels() const { return this->nLevels; } + + Types::MethodType getType() const{ return Types::LLH; } + + void addVariable(const string& _name, const void* _value, char type = 'F') { MethodBase::addVariable(_name,_value,type); } + + #ifndef __STANDALONE + void setDetails(const TauDetailsManager& manager){ MethodBase::setDetails(manager); } + void setDoTrigger(const TauDetailsManager& manager) { llh->setDoTrigger(manager.getDoTrigger()); } + #endif + + private: + + bool isBuilt; + unsigned int nLevels; + CommonLikelihood* llh; + int m_option; + + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodTransform.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodTransform.h new file mode 100644 index 0000000000000000000000000000000000000000..0e9a5f48d5d4ecbc2ac243d82d426555f984ff0f --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/MethodTransform.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef METHODTRANSFORM_H +#define METHODTRANSFORM_H + +#include <string> +#include <vector> +#include <stack> +#include <map> +#include <utility> +#include <iostream> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <typeinfo> +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/TreeReader.h" +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/Transformation.h" + +using namespace std; + +namespace TauID +{ + class MethodTransform : public MethodBase + { + public: + + //!< Default constructor + #ifdef __STANDALONE + MethodTransform(const string& _name = "", bool _verbose = false): + MethodBase(_name,_verbose), + isBuilt(false), + categoryTree(0) + {} + #else + MethodTransform(const string& _name = ""): + MethodBase(_name), + isBuilt(false), + categoryTree(0) + {} + #endif + + //!< Destructor + ~MethodTransform() + { + delete this->categoryTree; + } + + bool build(const string& filename, bool check = false); + + float response() const; + + float response(unsigned int level) const + { + if (level != 0) + { + print("MethodTransform does not output more than one possible response."); + } + return response(); + } + + Transformation* getCurrentCategory() const; + + Types::MethodType getType() const + { + return Types::TRANSFORM; + } + + void addVariable(const string& _name, const void* _value, char type = 'F') + { + MethodBase::addVariable(_name,_value,type); + } + + #ifndef __STANDALONE + void setDetails(const TauDetailsManager& manager) + { + MethodBase::setDetails(manager); + } + #endif + + private: + + bool isBuilt; + Node* categoryTree; + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Node.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Node.h new file mode 100644 index 0000000000000000000000000000000000000000..2cbcffa8ebb5ea38b03ddc82ae5ef761548cf066 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Node.h @@ -0,0 +1,371 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! This is a node class. +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include <iostream> +using namespace std; + +#ifndef NODE_H +#define NODE_H + +//!< Abstract base class +class Node +{ + public: + + virtual ~Node() {} + virtual bool isLeaf(void) const =0; + virtual bool isComplete(void) const =0; + virtual Node* clone(void) const =0; + virtual Node* getLeftChild(void) const =0; + virtual Node* getRightChild(void) const =0; +}; + +class DecisionNode: public Node +{ + public: + + /** + * @brief Set left child of this node. + * @param child a @c Node pointer to the new left child. + */ + void setLeftChild(Node* child) + { + if (leftChild != 0) delete leftChild; + leftChild = child; + } + + /** + * @brief Set right child of this node. + * @param child a @c Node pointer to the new right child. + */ + void setRightChild(Node* child) + { + if (rightChild != 0) delete rightChild; + rightChild = child; + } + + /** + * @brief Returns a pointer to the left child node. + * @return a @c Node pointer to the left child node. + */ + Node* getLeftChild() const { return this->leftChild; } + + /** + * @brief Returns a pointer to the right child node. + * @return a @c Node pointer to the right child node. + */ + Node* getRightChild() const { return this->rightChild; } + + /** + * @brief Returns true if node has no children and false otherwise. + * @return true if node has no children and false otherwise. + */ + bool isLeaf() const { return !this->rightChild && !this->leftChild; } + + /** + * @brief Returns true if both children exist. + * @return true if both children exist. + */ + bool isComplete() const { return this->rightChild && this->leftChild; } + + //virtual void setLeftChild(Node* node) =0; + //virtual void setRightChild(Node* node) =0; + virtual bool goRight(void) const =0; + + protected: + + Node* leftChild; + Node* rightChild; +}; + +template <class T> +class UnivariateCut: public DecisionNode +{ + public: + + //!< Constructor + UnivariateCut(const T* _feature, T _cut): + feature(_feature), + cut(_cut) + { + this->leftChild = 0; + this->rightChild = 0; + } + + //!< Copy Constructor + UnivariateCut(const UnivariateCut<T>& other) + { + this->feature = other.feature; + this->cut = other.cut; + this->leftChild = other.leftChild ? other.leftChild->clone() : 0; + this->rightChild = other.rightChild ? other.rightChild->clone() : 0; + } + + //!< Destructor + ~UnivariateCut() + { + delete this->rightChild; + delete this->leftChild; + } + + Node* clone() const + { + UnivariateCut<T>* node = new UnivariateCut<T>(this->feature,this->cut); + if (this->leftChild) node->setLeftChild(this->leftChild->clone()); + if (this->rightChild) node->setRightChild(this->rightChild->clone()); + return node; + } + + bool goRight() const { return this->feature ? *this->feature > this->cut : false; } + + const T* getFeature() const { return this->feature; } + + T getValue() const { return this->feature ? *this->feature : -9999.; } + + T getCut() const { return this->cut; } + + private: + + const T* feature; //!< Pointer to the variable which is cut on at this node. + T cut; //!< The cut. +}; + +template <class T, class U, class V> +class UnivariateSlidingCut1D: public DecisionNode +{ + public: + + //!< Constructor + UnivariateSlidingCut1D(const T* _feature, U* _function, const V* _variable): + feature(_feature), + function(_function), + variable(_variable) + { + this->leftChild = 0; + this->rightChild = 0; + } + + //!< Copy Constructor + UnivariateSlidingCut1D(const UnivariateSlidingCut1D<T,U,V>& other) + { + this->feature = other.feature; + this->function = other.function->Clone(); + this->variable = other.variable; + this->leftChild = other.leftChild ? other.leftChild->clone() : 0; + this->rightChild = other.rightChild ? other.rightChild->clone() : 0; + } + + //!< Destructor + ~UnivariateSlidingCut1D() + { + delete this->function; + delete this->rightChild; + delete this->leftChild; + } + + Node* clone() const + { + UnivariateSlidingCut1D<T,U,V>* node = new UnivariateSlidingCut1D<T,U,V>(this->feature,(U*)this->function->Clone(),this->variable); + if (this->leftChild) node->setLeftChild(this->leftChild->clone()); + if (this->rightChild) node->setRightChild(this->rightChild->clone()); + return node; + } + + bool goRight() const + { + return this->feature && this->variable ? *this->feature > this->function->Eval(float(*this->variable)) : false; + } + + private: + + const T* feature; + U* function; + const V* variable; +}; + +template <class T, class U, class V, class W> +class MultivariateCut2D: public DecisionNode +{ + public: + + //!< Constructor + MultivariateCut2D(T* _function, const U* _x, const V* _y, W _cut): + function(_function), + x(_x), + y(_y), + cut(_cut) + { + this->leftChild = 0; + this->rightChild = 0; + } + + //!< Copy Constructor + MultivariateCut2D(const MultivariateCut2D<T,U,V,W>& other) + { + this->function = other.function->Clone(); + this->x = other.x; + this->y = other.y; + this->cut = other.cut; + this->leftChild = other.leftChild ? other.leftChild->clone() : 0; + this->rightChild = other.rightChild ? other.rightChild->clone() : 0; + } + + //!< Destructor + ~MultivariateCut2D() + { + delete this->function; + delete this->rightChild; + delete this->leftChild; + } + + Node* clone() const + { + MultivariateCut2D<T,U,V,W>* node = new MultivariateCut2D<T,U,V,W>((T*)this->function->Clone(),this->x,this->y,this->cut); + if (this->leftChild) node->setLeftChild(this->leftChild->clone()); + if (this->rightChild) node->setRightChild(this->rightChild->clone()); + return node; + } + + bool goRight() const + { + return this->function && this->x && this->y ? this->function->Eval(float(*this->x),float(*this->y)) > cut : false; + } + + private: + + T* function; + const U* x; + const V* y; + W cut; +}; + + +template <class T> +class LeafNode: public Node +{ + public: + + LeafNode(T _value = 0):value(_value){} + + LeafNode(const LeafNode<T>& other) { this->value = other.value; } + + ~LeafNode(){} + + Node* clone() const { return new LeafNode<T>(this->value); } + + bool isLeaf() const { return true; } + + Node* getLeftChild() const { return 0; } + + Node* getRightChild() const { return 0; } + + bool isComplete() const { return true; } + + virtual T getValue() const { return this->value; } + + void setValue(T _value) { this->value = _value; } + + private: + + T value; +}; + +template <class X, class Y, class G> +class TransformationNode: public LeafNode<float> +{ + public: + + TransformationNode(const X* _x, float _xlow, float _xhigh, const Y* _y, float _ylow, float _yhigh, G* _transform): + x(_x), + xlow(_xlow), + xhigh(_xhigh), + y(_y), + ylow(_ylow), + yhigh(_yhigh), + transform(_transform) + {} + + TransformationNode(const TransformationNode<X,Y,G>& other) + { + this->x = other.x; + this->xlow = other.xlow; + this->xhigh = other.xhigh; + this->y = other.y; + this->ylow = other.ylow; + this->yhigh = other.yhigh; + this->transform = other.transform->Clone(); + } + + ~TransformationNode() + { + //delete transform; + } + + Node* clone() const + { + return new TransformationNode<X,Y,G>(x,xlow,xhigh,y,ylow,yhigh,(G*)transform->Clone()); + } + + float getValue() const + { + float _x = float(*x); + float _y = float(*y); + if (_x < xlow) + _x = xlow; + else if (_x > xhigh) + _x = xhigh; + if (_y < ylow) + _y = ylow; + else if (_y > yhigh) + _y = yhigh; + return this->transform->Interpolate(_x, _y); + } + + private: + + const X* x; + float xlow; + float xhigh; + const Y* y; + float ylow; + float yhigh; + G* transform; +}; + +template <class T> +class PointerLeafNode: public Node +{ + public: + + PointerLeafNode(T* _value = 0):value(_value){} + + PointerLeafNode(const PointerLeafNode<T>& other) { this->value = other.value; } + + ~PointerLeafNode() { delete this->value; } + + Node* clone() const { return new PointerLeafNode<T>(this->value); } + + bool isLeaf() const { return true; } + + Node* getLeftChild() const { return 0; } + + Node* getRightChild() const { return 0; } + + bool isComplete() const { return true; } + + T* getValue() const { return this->value; } + + void setValue(T* _value) { this->value = _value; } + + private: + + T* value; +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/NoiseCorrIsol.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/NoiseCorrIsol.h new file mode 100644 index 0000000000000000000000000000000000000000..627d84e280d3f0a61a93321d5df0ced62dbb5e2b --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/NoiseCorrIsol.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef NOISECORRISOL_H +#define NOISECORRISOL_H + +//*******************************************************// +// Name: NoiseCorrIsol.h // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: A class to provide isolation based // +// pileup/underlying event correction to the clusters // +// of tau decays // +//*******************************************************// + +#include <TLorentzVector.h> +#include "TauDiscriminant/EMFCluster.h" +#include <vector> + +class NoiseCorrIsol +{ +public: + // Constructors, Destructors + NoiseCorrIsol(); + + NoiseCorrIsol(const TLorentzVector& tau, + const std::vector<TLorentzVector>& clusters, + double innerDR=0.3, + double outerDR=0.4, + bool eff=false); + + NoiseCorrIsol(const TLorentzVector& tau, + const std::vector<EMFCluster>& clusters, + double innerDR=0.3, + double outerDR=0.4, + bool eff=false); + + ~NoiseCorrIsol(); + + //Getters + std::vector<TLorentzVector> correctedClustersTLV(); + std::vector<EMFCluster> correctedClusters(); + +private: + + std::vector<TLorentzVector> m_clusters; + std::vector<EMFCluster> m_EMFClusters; + + TLorentzVector m_tau; + + double m_innerDR; + double m_outerDR; + double m_areaRatio; + + double areaRatio(); + std::vector<EMFCluster> effClusters(const std::vector<EMFCluster>& inputClusters); + + bool m_eff; + +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Pi0Finder.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Pi0Finder.h new file mode 100644 index 0000000000000000000000000000000000000000..75150d100366b8623b4d6493341bf1f999bbd57b --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Pi0Finder.h @@ -0,0 +1,123 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef PI0FINDER_H +#define PI0FINDER_H + +//*******************************************************// +// Name: Pi0Finder.h // +// Author: Michel Trottier-McDonald <mtm@cern.ch> // +// Description: Main class to find which clusters are // +// the pi0s in tau decays involving neutral pions // +//*******************************************************// + +#include <TLorentzVector.h> +#include "TauDiscriminant/EMFCluster.h" +#include <vector> + +class Pi0Finder +{ +public: + // Constructors, Destructors + Pi0Finder(); + + Pi0Finder(const std::vector<TLorentzVector>& tracks, + const std::vector<EMFCluster>& clusters, + bool twoPi0s = true, + double resImportance = 1.0, + double turnOnPoint = 1.05, + double turnOnRate = 9, + double PSSFactor = 1.4, + double EM2Factor = 0.4, + double twoPi0Strength = 0.4, + bool usePseudoHADF = true, + bool effClusters = false); + + Pi0Finder(const std::vector<TLorentzVector>& tracks, + const std::vector<TLorentzVector>& clusters, + const std::vector<float>& PSSFs, + const std::vector<float>& EM2Fs, + const std::vector<float>& EM3Fs, + bool twoPi0s = true, + double resImportance = 1.0, + double turnOnPoint = 1.05, + double turnOnRate = 9, + double PSSFactor = 1.4, + double EM2Factor = 0.4, + double twoPi0Strength = 0.4, + bool usePseudoHADF = true, + bool effClusters = false); + + ~Pi0Finder(); + + //Getters + TLorentzVector visTauTLV() const; //Returns the visible tau + TLorentzVector pi0TLV1() const {return m_selEMFCluster1.TLV();} + TLorentzVector pi0TLV2() const {return m_selEMFCluster2.TLV();} + TLorentzVector pi0NotCorrTLV1() const {return m_selEMFClusterNotCorr1.TLV();} + TLorentzVector pi0NotCorrTLV2() const {return m_selEMFClusterNotCorr2.TLV();} + EMFCluster pi0EMFCluster1() const {return m_selEMFCluster1;} + EMFCluster pi0EMFCluster2() const {return m_selEMFCluster2;} + double doubleCounting() const {return m_doubleCountingE;} + bool corrected1() const {return m_applyCorrCluster1;} + bool corrected2() const {return m_applyCorrCluster2;} + bool noMatch() const {return m_noMatch;} + +private: + + //The candidate clusters (after noise correction) + std::vector<EMFCluster> m_EMFClusters; + + //the tracks + std::vector<TLorentzVector> m_tracks; + + //General parameters + bool m_usePseudoHADF; + bool m_twoPi0s; + + //Selection parameters + double m_resImportance; // Importance of the resolution of the cluster energy compared to calo energy - track energy + + //Contamination correction parameters + double m_turnOnPoint; // Value of energy double counting at which the correction turns on. + double m_turnOnRate; // How quickly the correction turns on after the turn on point + double m_PSSFactor; // How many times the PreSampler-Strip Energy when finding the corrected energy + double m_EM2Factor; // How many times the EMLayer 2 Energy when finding the corrected energy + double m_twoPi0Strength; //Biases the preference for finding 1 or 2 clusters + + //Internal transient parameters + double m_caloE; // total calorimeter energy + double m_caloHADE; // total hadronic (pseudo-hadronic) calorimeter energy + double m_trkE; // total track system energy + double m_trkHADF; // energy in the hadronic (pseudo-hadronic) calorimeter divided by the track energy + double m_doubleCountingE; // Values above 1 roughly indicates energy double counting, used to decide to correct cluster energy or not + bool m_applyCorrCluster1; // Apply correction to cluster 1 + bool m_applyCorrCluster2; // Apply correction to cluster 2 + bool m_keepCluster1; // Keep Cluster1 + bool m_keepCluster2; // Keep Cluster2 + bool m_noMatch; // True if no pi0 has been selected + + TLorentzVector m_trkSys; + + //Results + EMFCluster m_selEMFCluster1; + EMFCluster m_selEMFCluster2; + EMFCluster m_selEMFClusterNotCorr1; + EMFCluster m_selEMFClusterNotCorr2; + + //Internal methods + void preSelParameters(); // Calculate pre-selection internal transient parameters + void postSelParameters(); // Calculate post-selection internal transient parameters + void select(); // Select one pi0 cluster + void select2(); // Select two pi0 clusters + EMFCluster correct(const EMFCluster& cl); // Correct the energy of one contaminated cluster + EMFCluster giveMass(const EMFCluster& cl); // Give the pi0 mass to uncorrected clusters + void execute(); // Execute the pi0 finding + std::vector<EMFCluster> convertToEMFClusters(const std::vector<TLorentzVector>& clusters, + const std::vector<float>& PSSFs, + const std::vector<float>& EM2Fs, + const std::vector<float>& EM3Fs); +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCuts.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCuts.h new file mode 100644 index 0000000000000000000000000000000000000000..2fc682b0856865c555cc418d49f9b82687dae9ab --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCuts.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUCUTS_H +#define TAUCUTS_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> + +using namespace TauID; + +class TauCuts: public TauDiscriToolBase +{ + public: + + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauCuts(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent) + { + declareInterface<TauDiscriToolBase>(this); + declareProperty( "cuts", m_fileName); + } + + virtual ~TauCuts() {} + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode prepare(const TauDetailsManager&); + + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + virtual StatusCode finalize(); + + private: + + std::string m_fileName; + MethodCuts* m_cutsManager; +}; + +#endif // TAUCUTS_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCutsEleVeto.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCutsEleVeto.h new file mode 100644 index 0000000000000000000000000000000000000000..e3bfabb864487badc95443136aadaa7e620226c4 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauCutsEleVeto.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUCUTSELEVETO_H +#define TAUCUTSELEVETO_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> + +class TauCutsEleVeto: public TauDiscriToolBase +{ + public: + + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauCutsEleVeto(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent), + detailsManager(0), + useLCscale(false) + { + declareInterface<TauDiscriToolBase>(this); + + declareProperty("useLCscale", this->useLCscale); + } + + virtual ~TauCutsEleVeto() {} + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode prepare(const TauDetailsManager&); + + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + virtual StatusCode finalize(); + + private: + + const TauDetailsManager* detailsManager; + bool useLCscale; +}; + +#endif // TAUCUTSELEVETO_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetails.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetails.h new file mode 100644 index 0000000000000000000000000000000000000000..052fccef3998e80fcf3e32daf3707ec1cff63793 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetails.h @@ -0,0 +1,146 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Author: Noel Dawe <Noel-dot-Dawe-AT-cern-dot-ch> + */ + +#ifndef TAUDETAILS_H +#define TAUDETAILS_H + +#include <string> + +// Add new details to the proper block below (4 blocks: int/float tau details and int/float event details) +// Use all caps, but note that in the end, detail names are case insensitive +// since they are always compared in the uppercase state when building the discriminants at init +// Using this "ENUM_OR_STRING" macro allows as to use the same list to init enums (below) +// as well as arrays of strings (in the same order) (see TauDetailsManager.cxx) + +#define INT_TAU_DETAILS \ + ENUM_OR_STRING( AUTHOR ), \ + ENUM_OR_STRING( TAU_PI0_N ), \ + ENUM_OR_STRING( CHARGE ), \ + ENUM_OR_STRING( NUMTRACK ), \ + ENUM_OR_STRING( NUMWIDETRACK ), \ + ENUM_OR_STRING( NSTRIP ), \ + ENUM_OR_STRING( NISOLLOOSETRK ), \ + ENUM_OR_STRING( NPI0 ), \ + ENUM_OR_STRING( NPI0CL), \ + ENUM_OR_STRING( NISOLTRK ), \ + ENUM_OR_STRING( NUMTOPOCLUSTERS ), \ + ENUM_OR_STRING( __IntTauDetail__END__ ) + +#define FLOAT_TAU_DETAILS \ + ENUM_OR_STRING( ETA ), \ + ENUM_OR_STRING( ABS_ETA ), \ + ENUM_OR_STRING( ABS_ETA_LEAD_TRACK ), \ + ENUM_OR_STRING( TAU_ABSDELTAETA ), \ + ENUM_OR_STRING( TAU_ABSDELTAPHI ), \ + ENUM_OR_STRING( PHI ), \ + ENUM_OR_STRING( E ), \ + ENUM_OR_STRING( ET ), \ + ENUM_OR_STRING( PT ), \ + ENUM_OR_STRING( EMFRACTIONATEMSCALE ), \ + ENUM_OR_STRING( EMRADIUS ), \ + ENUM_OR_STRING( HADRADIUS ), \ + ENUM_OR_STRING( CALRADIUS ), \ + ENUM_OR_STRING( ISOLFRAC ), \ + ENUM_OR_STRING( CENTFRAC ), \ + ENUM_OR_STRING( STRIPWIDTH2 ), \ + ENUM_OR_STRING( TRFLIGHTPATHSIG ), \ + ENUM_OR_STRING( IPSIGLEADTRK ), \ + ENUM_OR_STRING( IPSIGLEADLOOSETRK ), \ + ENUM_OR_STRING( ETOVERPTLEADTRK ), \ + ENUM_OR_STRING( PTLEADTRKOVERET ), \ + ENUM_OR_STRING( IPZ0SINTHETASIGLEADTRK ), \ + ENUM_OR_STRING( MASSTRKSYS ), \ + ENUM_OR_STRING( TRKWIDTH2 ), \ + ENUM_OR_STRING( TRKAVGDIST ), \ + ENUM_OR_STRING( ETEFLOWOVERET ), \ + ENUM_OR_STRING( MEFLOW ), \ + ENUM_OR_STRING( SUMPT3TRK ), \ + ENUM_OR_STRING( SUMPT ), \ + ENUM_OR_STRING( DRMIN ), \ + ENUM_OR_STRING( DRMAX ), \ + ENUM_OR_STRING( SUMPT_OVER_ET ), \ + ENUM_OR_STRING( SUMPT3TRK_OVER_ET ), \ + ENUM_OR_STRING( ETHAD_EM_OVER_SUMPT3TRK ), \ + ENUM_OR_STRING( ETEM_EM_OVER_SUMPT3TRK ), \ + ENUM_OR_STRING( ETHAD_EM_OVER_SUMPT ), \ + ENUM_OR_STRING( ETEM_EM_OVER_SUMPT ), \ + ENUM_OR_STRING( TRT_NHT_OVER_NLT ), \ + ENUM_OR_STRING( M ), \ + ENUM_OR_STRING( TOPOINVMASS ), \ + ENUM_OR_STRING( EFFTOPOINVMASS ), \ + ENUM_OR_STRING( JVF ), \ + ENUM_OR_STRING( PT_PILEUP ), \ + ENUM_OR_STRING( TRACK_ISO ), \ + ENUM_OR_STRING( CALO_ISO ), \ + ENUM_OR_STRING( CALO_ISO_CORRECTED ), \ + ENUM_OR_STRING( LEAD2CLUSTEREOVERALLCLUSTERE ), \ + ENUM_OR_STRING( LEAD3CLUSTEREOVERALLCLUSTERE ), \ + ENUM_OR_STRING( HADLEAKET ),\ + ENUM_OR_STRING( SUMEMCELLETOVERLEADTRKPT ),\ + ENUM_OR_STRING( SECMAXSTRIPET ),\ + ENUM_OR_STRING( BDTJETSCORE ),\ + ENUM_OR_STRING( CHPIEMEOVERCALOEME ),\ + ENUM_OR_STRING( PSSFRACTION ),\ + ENUM_OR_STRING( EMPOVERTRKSYSP ),\ + ENUM_OR_STRING( EMEOVERTRKSYSE ), \ + ENUM_OR_STRING( CORRCENTFRAC ), \ + ENUM_OR_STRING( CORRFTRK ), \ + ENUM_OR_STRING( TAU_PI0_VISTAU_M ), \ + ENUM_OR_STRING( TAU_PTRATIO ), \ + ENUM_OR_STRING( INTERAXIS_ETA ), \ + ENUM_OR_STRING( INTERAXIS_PHI ), \ + ENUM_OR_STRING( PI0CL1_PT ), \ + ENUM_OR_STRING( PI0CL1_ETA ), \ + ENUM_OR_STRING( PI0CL1_PHI ), \ + ENUM_OR_STRING( PI0CL2_PT ), \ + ENUM_OR_STRING( PI0CL2_ETA ), \ + ENUM_OR_STRING( PI0CL2_PHI ), \ + ENUM_OR_STRING( VISTAU_PI0CL_PT ), \ + ENUM_OR_STRING( VISTAU_PI0CL_ETA ), \ + ENUM_OR_STRING( VISTAU_PI0CL_PHI ), \ + ENUM_OR_STRING( VISTAU_PI0CL_M ), \ + ENUM_OR_STRING( EMFRACTIONATEMSCALE_MOVEE3 ), \ + ENUM_OR_STRING( TAU_SEEDTRK_SECMAXSTRIPETOVERPT ), \ + ENUM_OR_STRING( __FloatTauDetail__END__ ) + +#define INT_EVENT_DETAILS \ + ENUM_OR_STRING( NUMVERTICES ), \ + ENUM_OR_STRING( NUMGOODVERTICES ),\ + ENUM_OR_STRING( NUM_PILEUP_AND_PRIMARY_VERTICES ),\ + ENUM_OR_STRING( __IntEventDetail__END__ ) + +#define FLOAT_EVENT_DETAILS \ + ENUM_OR_STRING( __FloatEventDetail__END__ ) + +#undef ENUM_OR_STRING +#define ENUM_OR_STRING( x ) x + +namespace Details +{ + enum IntTauDetail + { + INT_TAU_DETAILS + }; + + enum FloatTauDetail + { + FLOAT_TAU_DETAILS + }; + + enum IntEventDetail + { + INT_EVENT_DETAILS + }; + + enum FloatEventDetail + { + FLOAT_EVENT_DETAILS + }; +} + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManager.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManager.h new file mode 100644 index 0000000000000000000000000000000000000000..6845c6dda39cdc6a0678c270b20cca41f1519d18 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManager.h @@ -0,0 +1,151 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! + * file: TauDetailsManager.h + * + * This class provides a handle on the features used for tau/jet separation. + * + * To add new details: first add the enum entry in TauDetails.h and then + * implement the code in TauDetailsManager.cxx which sets the value for each tau/event + * + * Author: Noel Dawe (Noel-dot-Dawe-AT-cern-dot-ch) + */ + +#ifndef TAUDETAILSMANAGER_H +#define TAUDETAILSMANAGER_H + +#include <string> +#include <vector> +#include <map> +#include <algorithm> +#include <iostream> +#include <iomanip> + +#include "TauDiscriminant/TauDetails.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +#include "xAODTau/TauDefs.h" +#include "StoreGate/StoreGateSvc.h" +#include "AthenaKernel/MsgStreamMember.h" + +using namespace std; + +class TauDetailsManager +{ + public: + + static const float LOW_NUMBER; + + //!< Default constructor + TauDetailsManager(StoreGateSvc* =0, bool isTrigger=false); + + //!< Destructor + ~TauDetailsManager() {} + + const map<string,float*>* getFloatDetails() const { return &this->float_details; } + + const map<string,int*>* getIntDetails() const { return &this->int_details; } + + const float* getFloatDetailAddress(Details::FloatTauDetail) const; + + const int* getIntDetailAddress(Details::IntTauDetail) const; + + float getFloatDetailValue(Details::FloatTauDetail) const; + + int getIntDetailValue(Details::IntTauDetail) const; + + const float* getFloatDetailAddress(Details::FloatEventDetail) const; + + const int* getIntDetailAddress(Details::IntEventDetail) const; + + float getFloatDetailValue(Details::FloatEventDetail) const; + + int getIntDetailValue(Details::IntEventDetail) const; + + bool getDoTrigger() const { return doTrigger; } + + bool updateEvent(); + + bool update(const xAOD::TauJet& tauJet); //keep for backward compatibility + bool update_with_edm(xAOD::TauJet& tauJet); + + bool setNpi0(xAOD::TauJet& tauJet, int nPi0); + + friend MsgStream& operator<<(MsgStream&, const TauDetailsManager&); + + friend ostream& operator<<(ostream&, const TauDetailsManager&); + + //Declaring the Message method for further use + MsgStream& msg( MSG::Level lvl ) const { return m_msg << lvl; } + + //Declaring the Method providing Verbosity Level + bool msgLvl( MSG::Level lvl ) const { return m_msg.get().level() <= lvl; } + + protected: + + template <class stream> + void printOn(stream& o) const; + + private: + + map<string,float*> float_details; + map<string,int*> int_details; + vector<float> float_data; + vector<int> int_data; + vector<float> float_event_data; + vector<int> int_event_data; + StoreGateSvc* storeGate; + bool doTrigger; + mutable Athena::MsgStreamMember m_msg; + + float m_clusterCone; +}; + +template <class stream> +void TauDetailsManager::printOn(stream& o) const +{ + ios_base::fmtflags original_flags = (ios_base::fmtflags)o.flags(); + o << "\n\n"; + map<string,float*>::const_iterator it_float(this->float_details.begin()); + map<string,float*>::const_iterator it_float_end(this->float_details.end()); + const float* float_value(0); + for(; it_float != it_float_end; ++it_float) + { + o << left << setw(40) << setfill('.') << (it_float->first); + float_value = it_float->second; + if (float_value) + o << " " << *float_value << "\n"; + else + o << " NULL\n"; + } + + map<string,int*>::const_iterator it_int(this->int_details.begin()); + map<string,int*>::const_iterator it_int_end(this->int_details.end()); + const int* int_value(0); + for(; it_int != it_int_end; ++it_int) + { + o << left << setw(40) << setfill('.') << (it_int->first); + int_value = it_int->second; + if (int_value) + o << " " << *int_value << "\n"; + else + o << " NULL\n"; + } + o.flags(original_flags); +} + +inline MsgStream& operator<<(MsgStream& o, const TauDetailsManager& manager) +{ + manager.printOn<MsgStream>(o); + return o; +} + +inline ostream& operator<<(ostream& o, const TauDetailsManager& manager) +{ + manager.printOn<ostream>(o); + return o; +} + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManagerStandalone.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManagerStandalone.h new file mode 100644 index 0000000000000000000000000000000000000000..634a9577d8a193c823420d1b6aa7b1c99a072680 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDetailsManagerStandalone.h @@ -0,0 +1,176 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! + * file: TauDetailsManagerStandalone.h + * + * This class provides a handle on the features used for tau/jet separation in standalone mode. + * + * To add new details: first add the enum entry in TauDetails.h and then + * implement the code in TauDetailsManagerStandalone.cxx which sets the value for each tau/event + * + * Author: Pawel Malecki(Pawel dot Malecki at cern dot ch) + */ + + +#ifndef TAUDETAILSMANAGERSTANDALONE_H +#define TAUDETAILSMANAGERSTANDALONE_H + + + +#include <string> +#include <vector> +#include <map> + + +#include "TauDiscriminant/TauDetails.h" + +#include <TTree.h> + +using namespace std; + +namespace TauID{ + class TauDetailsManagerStandalone + { + public: + + static const float LOW_NUMBER; + + //!< Default constructor + TauDetailsManagerStandalone(TTree* tree = 0); + + //!< Destructor + ~TauDetailsManagerStandalone() {} + + const map<string,float*>* getFloatDetails() const { return &this->float_details; } + + const map<string,int*>* getIntDetails() const { return &this->int_details; } + + const float* getFloatDetailAddress(Details::FloatTauDetail) const; + + const int* getIntDetailAddress(Details::IntTauDetail) const; + + float getFloatDetailValue(Details::FloatTauDetail) const; + + int getIntDetailValue(Details::IntTauDetail) const; + + const float* getFloatDetailAddress(Details::FloatEventDetail) const; + + const int* getIntDetailAddress(Details::IntEventDetail) const; + + float getFloatDetailValue(Details::FloatEventDetail) const; + + int getIntDetailValue(Details::IntEventDetail) const; + + bool getDoTrigger() const { return doTrigger; } + + bool updateEvent(int entry); + + bool update(unsigned int itau); + + bool initTree(TTree* tree); + + int getNtau(); + + + //Declaring the Message method for further use + + //Declaring the Method providing Verbosity Level + + + private: + + map<string,float*> float_details; + map<string,int*> int_details; + vector<float> float_data; + vector<int> int_data; + vector<float> float_event_data; + vector<int> int_event_data; + bool doTrigger; + + float m_clusterCone; + + TTree *m_tree; + + + + /// non-vector variables + int evt_calcVars_numGoodVertices; + + ///vector variables + vector<float> *tau_charge; + vector<int> *tau_author; + vector<int> *tau_numTrack; + vector<int> *tau_seedCalo_nWideTrk; + vector<float> *tau_eta; + vector<float> *tau_phi; + vector<float> *tau_pt; + vector<float> *tau_seedCalo_trkAvgDist; + vector<float> *tau_etOverPtLeadTrk; + vector<float> *tau_calcVars_EMFractionAtEMScale; + vector<float> *tau_TRTHTOverLT_LeadTrk; + vector<float> *tau_seedCalo_dRmax; + vector<float> *tau_leadTrack_eta; + vector<float> *tau_calcVars_ChPiEMEOverCaloEME; + vector<float> *tau_seedTrk_secMaxStripEt; + vector<float> *tau_seedTrk_hadLeakEt; + vector<float> *tau_seedTrk_sumEMCellEtOverLeadTrkPt; + vector<float> *tau_calcVars_corrFTrk; + vector<float> *tau_calcVars_corrCentFrac; + vector<float> *tau_seedCalo_isolFrac; + vector<float> *tau_seedCalo_hadRadius; + vector<float> *tau_calcVars_PSSFraction; + vector<float> *tau_calcVars_EMPOverTrkSysP; + vector<int> *tau_seedCalo_nStrip; + vector<float> *tau_massTrkSys; + vector<float> *tau_ipSigLeadTrk; + vector<float> *tau_trFlightPathSig; + vector<float> *tau_pi0_vistau_m; + vector<float> *tau_pi0_vistau_pt; + vector<int> *tau_pi0_n; + vector<float> *tau_seedCalo_etEMAtEMScale; + vector<float> *tau_seedCalo_etHadAtEMScale; + vector<float> *tau_leadTrkPt; + vector<float> *tau_leadTrack_phi; + + TBranch *b_evt_calcVars_numGoodVertices; + TBranch *b_tau_charge; + TBranch *b_tau_author; + TBranch *b_tau_numTrack; + TBranch *b_tau_seedCalo_nWideTrk; + TBranch *b_tau_eta; + TBranch *b_tau_phi; + TBranch *b_tau_pt; + TBranch *b_tau_seedCalo_trkAvgDist; + TBranch *b_tau_etOverPtLeadTrk; + TBranch *b_tau_calcVars_EMFractionAtEMScale; + TBranch *b_tau_TRTHTOverLT_LeadTrk; + TBranch *b_tau_seedCalo_dRmax; + TBranch *b_tau_leadTrack_eta; + TBranch *b_tau_calcVars_ChPiEMEOverCaloEME; + TBranch *b_tau_seedTrk_secMaxStripEt; + TBranch *b_tau_seedTrk_hadLeakEt; + TBranch *b_tau_seedTrk_sumEMCellEtOverLeadTrkPt; + TBranch *b_tau_calcVars_corrFTrk; + TBranch *b_tau_calcVars_corrCentFrac; + TBranch *b_tau_seedCalo_isolFrac; + TBranch *b_tau_seedCalo_hadRadius; + TBranch *b_tau_calcVars_PSSFraction; + TBranch *b_tau_seedCalo_nStrip; + TBranch *b_tau_massTrkSys; + TBranch *b_tau_ipSigLeadTrk; + TBranch *b_tau_trFlightPathSig; + TBranch *b_tau_calcVars_EMPOverTrkSysP; + TBranch *b_tau_pi0_n; + TBranch *b_tau_pi0_vistau_m; + TBranch *b_tau_pi0_vistau_pt; + TBranch *b_tau_seedCalo_etEMAtEMScale; + TBranch *b_tau_seedCalo_etHadAtEMScale; + TBranch *b_tau_leadTrkPt; + TBranch *b_tau_leadTrack_phi; + + }; +} +#endif + diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriBuilder.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..a9078a95b210295733eba5868fa4ae7eddd53eb0 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriBuilder.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauDiscriBuilder.h +// package: PhysicsAnalysis/TauID/TauDiscriminant +// authors: M. Wolter, A. Kaczmarska +// date: 13 March 2008 +//----------------------------------------------------------------------------- + +#ifndef DISCRIBUILDER_TAU_H +#define DISCRIBUILDER_TAU_H + +#include "GaudiKernel/ToolHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" +#include "TauDiscriminant/TauDetailsManager.h" + +#include <string> + +class TauDiscriToolBase; +class StoreGateSvc; + +class TauDiscriBuilder: public AthAlgorithm +{ + public: + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauDiscriBuilder( const std::string &name, ISvcLocator *pSvcLocator ); + ~TauDiscriBuilder(); + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + + private: + std::string tauInputContainerName; + ToolHandleArray<TauDiscriToolBase> tools; + TauDetailsManager* manager; +}; +#endif // DISCRIBUILDER_TAU_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriToolBase.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriToolBase.h new file mode 100644 index 0000000000000000000000000000000000000000..6495243d2cae8657cb57f46f2c0d06968c97deaf --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriToolBase.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauDiscriToolBase.h +// package: PhysicsAnalysis/TauID/TauDiscriminant +// authors: M. Wolter, A. Kaczmarska +// date: 13 March 2008 +//----------------------------------------------------------------------------- + +#ifndef DISCRITOOLBASE_TAU_H +#define DISCRITOOLBASE_TAU_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "AthenaBaseComps/AthMessaging.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include "TauDiscriminant/FakeTauBits.h" +#include "TauDiscriminant/FakeTauScores.h" + +class TauDiscriToolBase: public AthAlgTool +{ + public: + + TauDiscriToolBase( const std::string& type, + const std::string& name, + const IInterface * parent): + AthAlgTool(type, name, parent) + {} + + virtual ~TauDiscriToolBase(){} + + //----------------------------------------------------------------- + //! InterfaceID implementation needed for ToolHandle + //----------------------------------------------------------------- + static const InterfaceID& interfaceID() + { + static const InterfaceID TauDiscriToolBaseID( "TauDiscriToolBase", 1, 0 ); + return TauDiscriToolBaseID; + } + + //----------------------------------------------------------------- + //! Tool initializer + //----------------------------------------------------------------- + virtual StatusCode prepare(const TauDetailsManager&) = 0; + + //----------------------------------------------------------------- + //! Execute - called for each tau candidate + //----------------------------------------------------------------- + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*) = 0; + + //----------------------------------------------------------------- + //! Finalizer + //----------------------------------------------------------------- + virtual StatusCode finalize() = 0; +}; + +#endif // DISCRITOOLBASE_TAU_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriminantDict.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriminantDict.h new file mode 100644 index 0000000000000000000000000000000000000000..e6940e3f8d83ebe86b31a375c766d0adb6e67ec1 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauDiscriminantDict.h @@ -0,0 +1,15 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/// This file is needed to create the Reflex dictionaries. +#ifndef TAUD_DICT_H +#define TAUD_DICT_H +#include "TauDiscriminant/Types.h" +#include "TauDiscriminant/TauIDReader.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/MethodLLH.h" +#include "TauDiscriminant/MethodDummy.h" +#include "TauDiscriminant/MethodTransform.h" +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauEleBDT.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauEleBDT.h new file mode 100644 index 0000000000000000000000000000000000000000..b913b8929ceea7719a8462eb1fa7b5469cffdf6e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauEleBDT.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! This class implements an Athena algorithm for evaluating the BDT score for tau jets. +/*! + * Tool for BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TAUELEBDT_H +#define TAUELEBDT_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/MethodTransform.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> +#include <PathResolver/PathResolver.h> +#include "xAODTau/TauJet.h" +#include "TFile.h" +#include "TH2F.h" + +using namespace std; +using namespace TauID; + +class TauEleBDT: public TauDiscriToolBase +{ + public: + + //!< Constructor + TauEleBDT(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent), + eleBDTFile(""), + eleBitsFile(""), + eleBitsRootFile(""), + cutsFile(NULL), + hloose(NULL), hmedium(NULL), htight(NULL), + eleBDT(NULL), + eleBits(NULL) + { + declareInterface<TauDiscriToolBase>(this); + + declareProperty("eleBDT", this->eleBDTFile); + declareProperty("eleBits", this->eleBitsFile); + declareProperty("eleBitsRoot", this->eleBitsRootFile); + } + + //!< Destructor + virtual ~TauEleBDT() {} + + /** + * @brief The boosted decision trees are built. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode prepare(const TauDetailsManager&); + + /** + * @brief Values of the tau parameters are extracted and a boosted decision tree score is retrieved. + * @param tauJet a @c xAOD::TauJet pointer to a tau jet candidate. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + /** + * @brief Allocated memory is freed. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode finalize(); + + private: + + float eleScore; //!< Holds the current electron score which is used by a MethodCuts instance to determine if it passes loose, medium, or tight. + + string eleBDTFile; //!< The @c string name of the bdt file for electron rejection. + string eleBitsFile; //!< The @c string name of the file used to define the loose, medium, and tight cuts for electron rejection. + string eleBitsRootFile; //!< The @c string name of the ROOT file used to define the loose, medium, and tight cuts for electron rejection. + TFile *cutsFile; + TH2F *hloose, *hmedium, *htight; //!< Histograms storing eta/pt for loose/medium/tight cuts + MethodBDT* eleBDT; //!< A pointer to the @c MethodBDT used to construct and evaluate BDTs used for electron discrimination. + MethodCuts* eleBits; //!< A pointer to the @c MethodCuts used to determine whether the current electron BDT score passes loose, medium, or tight cut. +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauIDReader.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauIDReader.h new file mode 100644 index 0000000000000000000000000000000000000000..ba41cb71dd1535744a59b14460d63cd94709e4ed --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauIDReader.h @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TAUIDREADER_H +#define TAUIDREADER_H + +#include <string> +#include <vector> +#include <map> +#include <utility> +#include <algorithm> + +#include "TTree.h" +#include "TFile.h" +#include "TauDiscriminant/MethodBase.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/MethodLLH.h" +#include "TauDiscriminant/MethodDummy.h" +#include "TauDiscriminant/MethodTransform.h" +#include "TauDiscriminant/TauDetailsManagerStandalone.h" + + +using namespace std; + +namespace TauID +{ + class TauIDReader + { + public: + + TauIDReader(bool _verbose = false): + verbose(_verbose), + vectorMode(false), + output(0), + own_output(true) + { + m_tdms = new TauDetailsManagerStandalone(); + + + } + + ~TauIDReader() + { + vector<pair<MethodBase*, vector<vector<float>* > > >::iterator it(this->methods.begin()); + for (;it != this->methods.end(); ++it) + { + vector<vector<float>* >::iterator it2(it->second.begin()); + for (; it2 != it->second.end(); ++it2) + { + delete *it2; + } + delete it->first; + } + vector<float*>::iterator it_float(this->methodBuffer.begin()); + for(; it_float != this->methodBuffer.end(); ++it_float) + { + delete *it_float; + } + it_float = this->floatVariables.begin(); + for(; it_float != this->floatVariables.end(); ++it_float) + { + delete *it_float; + } + it_float = this->vectFloatVariables.begin(); + for(; it_float != this->vectFloatVariables.end(); ++it_float) + { + delete *it_float; + } + vector<int*>::iterator it_int(this->intVariables.begin()); + for(; it_int != this->intVariables.end(); ++it_int) + { + delete *it_int; + } + it_int = this->vectIntVariables.begin(); + for(; it_int != this->vectIntVariables.end(); ++it_int) + { + delete *it_int; + } + if (this->own_output) + { + delete this->output; + } + delete m_tdms; + } + + bool bookMethod(Types::MethodType type, const string& name, const string& filename, unsigned int numResponses = 1); + + bool addVariable(const string& name, const string& type = "F", const string& branchName=""); + + bool setOutput(const string& outputFileName, const string& outputDir = ""); + + bool setOutput(TFile* outputFile, const string& outputDir = ""); + + bool setOutput(TFile& outputFile, const string& outputDir = ""); + + TTree* classify(TTree& tree, const string& outputTreeName, bool copyTree = false); + + TTree* classify(TTree* tree, const string& outputTreeName, bool copyTree = false); + + // return the number of entries in the tree or -1 if there was a problem + int classify(const string& inputTreeName, const string& outputTreeName, + const string& inputFileName, const string& inputDir = "", + bool makeFriend = true, + bool copyTree = false); + + private: + + bool checkBranch(TTree* tree, const char* name, string type, bool checkType = true); + void print() const; + + bool verbose; + bool vectorMode; + + TFile* output; + string outputDir; + bool own_output; + + vector<string> methodNames; + vector<pair<MethodBase*, vector<vector<float>* > > > methods; + vector<float*> methodBuffer; + vector<pair<string,string> > methodVariables; + + vector<int*> intVariables; + vector<string> intNames; + vector<string> intBranches; + vector<float*> floatVariables; + vector<string> floatNames; + vector<string> floatBranches; + + vector<int*> vectIntVariables; + vector<string> vectIntNames; + vector<string> vectIntBranches; + vector<float*> vectFloatVariables; + vector<string> vectFloatNames; + vector<string> vectFloatBranches; + + vector<string> allVariableNames; + vector<string> allBranchNames; + + TauDetailsManagerStandalone *m_tdms; + }; +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauJetBDT.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauJetBDT.h new file mode 100644 index 0000000000000000000000000000000000000000..fe787ae54062e9f693594473ed459796ebfcc0e9 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauJetBDT.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! This class implements an Athena algorithm for evaluating the BDT score for tau jets. +/*! + * Tool for BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TAUJETBDT_H +#define TAUJETBDT_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/MethodCuts.h" +#include "TauDiscriminant/MethodTransform.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> +#include <PathResolver/PathResolver.h> +#include "xAODTau/TauJet.h" + +using namespace std; +using namespace TauID; + +class TauJetBDT: public TauDiscriToolBase +{ + public: + + //!< Constructor + TauJetBDT(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent), + jetBDTFile(""), + jetSigBitsFile(""), + jetBkgBitsFile(""), + jetSigTransFile(""), + jetBkgTransFile(""), + jetBDT(NULL), + jetSigBits(NULL), + jetBkgBits(NULL), + jetSigTrans(NULL), + jetBkgTrans(NULL) + { + declareInterface<TauDiscriToolBase>(this); + + declareProperty("jetBDT", this->jetBDTFile); + declareProperty("jetSigBits",this->jetSigBitsFile); + declareProperty("jetBkgBits",this->jetBkgBitsFile); + declareProperty("jetSigTrans",this->jetSigTransFile); + declareProperty("jetBkgTrans",this->jetBkgTransFile); + } + + //!< Destructor + virtual ~TauJetBDT() {} + + /** + * @brief The boosted decision trees are built. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode prepare(const TauDetailsManager&); + + /** + * @brief Values of the tau parameters are extracted and a boosted decision tree score is retrieved. + * @param tauJet a @c xAOD::TauJet pointer to a tau jet candidate. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + /** + * @brief Allocated memory is freed. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode finalize(); + + private: + + float jetScore; //!< Holds the current jet score which is used by a MethodCuts instance to determine if it passes loose, medium, or tight. + + string jetBDTFile; //!< The @c string name of the bdt file for jet rejection. + string jetSigBitsFile; //!< The @c string name of the file used to define the loose, medium, and tight cuts on the signal taus for jet rejection. + string jetBkgBitsFile; //!< The @c string name of the file used to define the loose, medium, and tight cuts on the background jets for jet rejection. + string jetSigTransFile; + string jetBkgTransFile; + + MethodBDT* jetBDT; //!< A pointer to the @c MethodBDT used to construct and evaluate BDTs used for jet discrimination. + MethodCuts* jetSigBits; //!< A pointer to the @c MethodCuts used to determine whether the current jet BDT score passes loose, medium, or tight signal cut. + MethodCuts* jetBkgBits; //!< A pointer to the @c MethodCuts used to determine whether the current jet BDT score passes loose, medium, or tight background cut. + MethodTransform* jetSigTrans; + MethodTransform* jetBkgTrans; +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauLLH.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauLLH.h new file mode 100644 index 0000000000000000000000000000000000000000..9d7438ff6aa1e30e2e0bc63f3b8b4f842b5f236d --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauLLH.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: TauLLH.h + * + * Author: Martin Flechl (mflechl@cern.ch) + */ + +#ifndef TAULLHRERUN_H +#define TAULLHRERUN_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/MethodLLH.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> + +using namespace TauID; + +class TauLLH: public TauDiscriToolBase +{ + public: + + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauLLH(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent) + { + declareInterface<TauDiscriToolBase>(this); + declareProperty( "FileNameTauPDF", m_fileNameTauPDF = "pdfs_tau.root" ); + declareProperty( "FileNameJetPDF", m_fileNameJetPDF = "pdfs_jet.root"); + declareProperty( "FileNameLMTCuts", m_fileNameLMTCuts = "LMTCutsLLH.root"); + } + + virtual ~TauLLH() {} + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode prepare(const TauDetailsManager&); + + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + virtual StatusCode finalize(); + + private: + + std::string m_fileNameTauPDF; + std::string m_fileNameJetPDF; + std::string m_fileNameLMTCuts; + + MethodLLH* m_defllh; + MethodLLH* m_safellh; +}; + +#endif // TAULLHRERUN_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauMuonVeto.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauMuonVeto.h new file mode 100644 index 0000000000000000000000000000000000000000..26a15749170476671718acc78b500b9071b7cc78 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauMuonVeto.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUMUONVETO_H +#define TAUMUONVETO_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> + +class TauMuonVeto: public TauDiscriToolBase +{ + public: + + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauMuonVeto(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent), + detailsManager(0) + { + declareInterface<TauDiscriToolBase>(this); + } + + virtual ~TauMuonVeto() {} + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode prepare(const TauDetailsManager&); + + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + virtual StatusCode finalize(); + + private: + + const TauDetailsManager* detailsManager; +}; + +#endif // TAUMUONVETO_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0BDT.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0BDT.h new file mode 100644 index 0000000000000000000000000000000000000000..95f6b90b65c2959d571fac85c1679e6442ee192c --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0BDT.h @@ -0,0 +1,76 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//! This class implements an Athena algorithm for evaluating the BDT score for pi0s. +/*! + * Tool for BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TAUPI0BDT_H +#define TAUPI0BDT_H + +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/MethodBDT.h" +#include "TauDiscriminant/TauDetailsManager.h" +#include <string> +#include <PathResolver/PathResolver.h> +#include "xAODTau/TauJet.h" + +using namespace std; +using namespace TauID; + +class TauPi0BDT: public TauDiscriToolBase +{ + public: + + //!< Constructor + TauPi0BDT(const string& type, + const string& name, + const IInterface* parent): + TauDiscriToolBase(type, name, parent), + pi0BDTPrimaryFile(""), + pi0BDTSecondaryFile(""), + pi0BDTPrimary(NULL), + pi0BDTSecondary(NULL) + { + declareInterface<TauDiscriToolBase>(this); + + declareProperty("pi0BDTPrimary", this->pi0BDTPrimaryFile); + declareProperty("pi0BDTSecondary", this->pi0BDTSecondaryFile); + } + + //!< Destructor + virtual ~TauPi0BDT() {} + + /** + * @brief The boosted decision trees are built. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode prepare(const TauDetailsManager&); + + /** + * @brief Values of the tau parameters are extracted and a boosted decision tree score is retrieved. + * @param tauJet a @c xAOD::TauJet pointer to a tau jet candidate. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode execute(xAOD::TauJet*, FakeTauBits*, FakeTauScores*); + + /** + * @brief Allocated memory is freed. + * @return @c StatusCode StatusCode::FAILURE if there were problems and StatusCode::SUCCESS otherwise. + */ + virtual StatusCode finalize(); + + private: + + string pi0BDTPrimaryFile; //!< The @c string name of the bdt file for establishing the presence of pi0s + string pi0BDTSecondaryFile; //!< The @c string name of the bdt file for differentiating 2 from 1 pi0s + + MethodBDT* pi0BDTPrimary; //!< A pointer to the @c MethodBDT used to construct and evaluate BDTs used for establishing the presence of pi0s + MethodBDT* pi0BDTSecondary; //!< A pointer to the @c MethodBDT used to construct and evaluate BDTs used for differentiating 2 from 1 pi0s +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0Clusters.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0Clusters.h new file mode 100644 index 0000000000000000000000000000000000000000..3922283ac60bbfebabfb9e4b610846c4dbe37c5c --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TauPi0Clusters.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/*! + * file: TauPi0Clusters.h + * + * This class provides a handle on the Pi0Finder algorithm, and pass the resultin data to storegate + * + * Author: Michel Trottier-McDonald (mtm-AT-cern-dot-ch) + */ + +#ifndef TAUPI0CLUSTERS_H +#define TAUPI0CLUSTERS_H + +#include "TauDiscriminant/TauDetails.h" +#include "xAODTau/TauJet.h" +#include "TauDiscriminant/Pi0Finder.h" + +class TauPi0Clusters +{ +public: + + static const float LOW_NUMBER; + + //!< Constructor + TauPi0Clusters(const xAOD::TauJet& tauJet); + + //!< Destructor + ~TauPi0Clusters() {} + + //Getters + float get_cl1_Pt() const {return m_cl1_Pt;} + float get_cl1_Eta() const {return m_cl1_Eta;} + float get_cl1_Phi() const {return m_cl1_Phi;} + + float get_cl2_Pt() const {return m_cl2_Pt;} + float get_cl2_Eta() const {return m_cl2_Eta;} + float get_cl2_Phi() const {return m_cl2_Phi;} + + float get_tau_vis_Pt() const {return m_tau_vis_Pt;} + float get_tau_vis_Eta() const {return m_tau_vis_Eta;} + float get_tau_vis_Phi() const {return m_tau_vis_Phi;} + float get_tau_vis_M() const {return m_tau_vis_M;} + + +private: + + // Data members to return + + // Cluster 1 4-vector + float m_cl1_Pt; + float m_cl1_Eta; + float m_cl1_Phi; + + // Cluster 2 4-vector + float m_cl2_Pt; + float m_cl2_Eta; + float m_cl2_Phi; + + // Tau 4-vector from pi0s and tracks + float m_tau_vis_Pt; + float m_tau_vis_Eta; + float m_tau_vis_Phi; + float m_tau_vis_M; + + // Run Pi0Finder + void runPi0Finder(const xAOD::TauJet& tauJet); + +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Transformation.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Transformation.h new file mode 100644 index 0000000000000000000000000000000000000000..375c5acf40c95627610d8c7340d7c8a1d67c7f75 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Transformation.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TRANSFORMATION_H +#define TRANSFORMATION_H + +#include <iostream> +#include <string> +#include <vector> +#include <map> +#include <utility> +#include "TauDiscriminant/Node.h" +#include "TauDiscriminant/TreeVector.h" + +using namespace std; + +class Transformation : public TreeVector { + + public: + + //!< Default Constructor + Transformation() {} + + /** + * @brief Returns the @c float score for the set of variables and values in @c variableMap. + * @param variableMap + */ + float response() const; + +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeReader.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeReader.h new file mode 100644 index 0000000000000000000000000000000000000000..16b2e4ea41d70ebf75b341d95f742a1a3ff927bd --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeReader.h @@ -0,0 +1,118 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TREEREADER_H +#define TREEREADER_H + +#include <map> +#include <stack> +#include <vector> +#include <string> +#include <utility> +#include <iostream> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <typeinfo> +#include "TreeVector.h" +#include "Node.h" +#include "TFile.h" +#ifndef __STANDALONE + #include "GaudiKernel/MsgStream.h" +#endif + +using namespace std; + +enum Format { + ASCII, + BINARY, + ROOTFILE +}; + +enum { + ENDOFTREE = -1, + LEAF = -2, + POINTERLEAF = -3, + GRAPH = -4, + FUNC = -5, + TRANS = -6 +}; + +class TreeReader { + + public: + + #ifdef __STANDALONE + TreeReader(bool _verbose = false): + verbose(_verbose), + floatVariables(0), + intVariables(0) + {} + #else + TreeReader(bool _verbose = false, MsgStream* _log = 0): + verbose(_verbose), + floatVariables(0), + intVariables(0), + log(_log) + {} + #endif + + ~TreeReader(){} + + void setVariables(const map<string,const float*>* _floatVariables, + const map<string,const int*>* _intVariables) + { + this->floatVariables = _floatVariables; + this->intVariables = _intVariables; + } + + Node* build(const string& filename, bool checkTree = false); + + void print(string message) const + { + #ifndef __STANDALONE + if (log) + { + (*log) << "DEBUG" << message << endreq; + } + else + #endif + cout << message << endl; + } + + private: + + Node* readTree(istream& treeFile, + TFile* rootFile, + Format format, + vector<string>& variableList, + vector<char>& variableTypeList, + unsigned int& numNodes); + bool verbose; + const map<string,const float*>* floatVariables; + const map<string,const int*>* intVariables; + #ifndef __STANDALONE + MsgStream* log; + #endif +}; + +/** This templated class is used to convert a string to various data types. +This is used when tokenizing the BDT input file to build the boosted decision trees.*/ +template <class T> +inline bool from_string(T& t, const string& s) { + istringstream ss(s); + return !(ss >> t).fail(); +} + +template <class T> +inline string to_string (const T& t) { + stringstream ss; + ss << t; + return ss.str(); +} +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeVector.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeVector.h new file mode 100644 index 0000000000000000000000000000000000000000..96c3141da0df0a048127823eef69c1eb8f4ad098 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/TreeVector.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#ifndef TREEVECTOR_H +#define TREEVECTOR_H + +#include <vector> +#include <utility> +#include "TauDiscriminant/Node.h" + +using namespace std; + +class TreeVector { + + public: + + //!< Destructor + ~TreeVector() { + vector<pair<Node*,float> >::iterator it(this->trees.begin()); + while (it != this->trees.end()) delete (*it++).first; + } + + /** + * @brief Adds a decision tree rooted at the node @c root with a weight of @c weight. + * @param root a @c Node* pointer to the root node. + * @param weight the @c float weight of the decision tree. + */ + void addTree(Node* root, float weight) { + this->trees.push_back(pair<Node*,float>(root,weight)); + } + + protected: + + vector<pair<Node*,float> > trees; +}; + +#endif diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Types.h b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Types.h new file mode 100644 index 0000000000000000000000000000000000000000..65f7b80751e80ae7f7986df9809fb484d73d4a3e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/Types.h @@ -0,0 +1,24 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// AUTHOR: Noel Dawe +#ifndef TYPES_H +#define TYPES_H + +namespace TauID +{ + namespace Types + { + enum MethodType + { + DUMMY, + CUTS, + BDT, + LLH, + TRANSFORM + }; + } +} + +#endif // TYPES_H diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/selection.xml b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..adc974cf6e611b9c0c64287982ba9ecad804adce --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/TauDiscriminant/selection.xml @@ -0,0 +1,10 @@ +<lcgdict> + <enum pattern="TauID::Types::*"/> + <variable pattern="TauID::Types::*"/> + <class name="TauID::TauIDReader"/> + <class name="TauID::MethodCuts"/> + <class name="TauID::MethodBDT"/> + <class name="TauID::MethodLLH"/> + <class name="TauID::MethodDummy"/> + <class name="TauID::MethodTransform"/> +</lcgdict> diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.RootCore b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.RootCore new file mode 100644 index 0000000000000000000000000000000000000000..90fc95518edee8e73356134e84b9eb0204fb6082 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.RootCore @@ -0,0 +1,5 @@ +PACKAGE = TauDiscriminant +PACKAGE_PRELOAD = Tree Hist Matrix +PACKAGE_CXXFLAGS = -D__STANDALONE + +include $(ROOTCOREDIR)/Makefile-common diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.Standalone b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.Standalone new file mode 100644 index 0000000000000000000000000000000000000000..07edc9e2b58375c128656d313f177fe9c84244dc --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/Makefile.Standalone @@ -0,0 +1,108 @@ +# Author: Noel Dawe (Noel.Dawe@cern.ch) +# TauDiscriminant standalone makefile + +# --- External configuration ---------------------------------- +ifeq ($(wildcard $(ROOTSYS)/test/Makefile.arch),) + include $(ROOTSYS)/etc/Makefile.arch +else + include $(ROOTSYS)/test/Makefile.arch +endif + +# ------------------------------------------------------------- +# General flags +# ------------------------------------------------------------- +PACKAGE = TauDiscriminant +OUTPUTDIR = ../StandAlone +SRCDIR = ../Root +HDIR = ../$(PACKAGE) + +# Get these from Makefile.arch above +#CC = g++ +#CCFLAGS = -g -m32 -fPIC -Wall -W -Woverloaded-virtual -Wno-parentheses -Wno-unused-parameter -Wno-unused-variable +#LDFLAGS = -g -m32 -fPIC + +MFLAGS = -MM -Wall -W -Woverloaded-virtual +INCLUDES += -I${ROOTSYS}/include -I.. -I$(HDIR) -I$(SRCDIR) +CPPFLAGS += -D__STANDALONE + +# Need these to avoid loading dependent libraries when ROOT starts +LINKLIBS = -L${ROOTSYS}/lib -lHist -lMatrix + +# ------------------------------------------------------------- +# ROOT Cint +# ------------------------------------------------------------- +CINT = taudiscriminantcint +LDEFFILE = $(SRCDIR)/LinkDef.h +CINTFILE = $(HDIR)/TauDiscriminantCint.cxx +CINTFILEH = $(HDIR)/TauDiscriminantCint.h +CINTOBJ = $(HDIR)/TauDiscriminantCint.o + +SRC = Types.cxx TauIDReader.cxx TauDetailsManagerStandalone.cxx MethodBase.cxx MethodDummy.cxx MethodTransform.cxx MethodBDT.cxx MethodCuts.cxx MethodLLH.cxx TreeVector.cxx Node.cxx TreeReader.cxx BoostedDecisionTree.cxx CommonLikelihood.cxx CutsDecisionTree.cxx Transformation.cxx +SOURCES = $(addprefix $(SRCDIR)/,$(SRC)) $(CINTFILE) +HDR = $(patsubst %.cxx,%.h,$(SRC)) +HEADERS = $(addprefix $(HDIR)/,$(HDR)) +OBJECTS = $(patsubst %.cxx,%.o,$(SOURCES)) +DEPS = $(patsubst %.h,%.d,$(HEADERS)) + +DICTS = $(HDIR)/$(PACKAGE)Dict.h +SELECTION = $(HDIR)/selection.xml + +# ------------------------------------------------------------- +# Libraries +# ------------------------------------------------------------- +SHLIBFILE = $(OUTPUTDIR)/lib$(PACKAGE).so + +ifeq ($(PLATFORM),macosx) +EXTRALDFLAGS = -install_name @rpath/$(SHLIBFILE) +endif + +# get libraries of ROOT +define ldlinksuffixROOT + $(addsuffix $(LDLINKSUFFIX),$(Lib)) $(shell if [ "$(findstring -Ldlink2,$(OPTIONS))" ]; then echo $(addsuffix _pkgid_$(ROOTVER),$(Lib)); fi) +endef + +# ------------------------------------------------------------- +# Compilation +# ------------------------------------------------------------- + +default: shlib + +# Implicit rule making all dependency Makefiles included at the end of this makefile +%.d: %.cxx $(HEADERS) + @echo "Making $@" + @set -e; $(CC) $(MFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $< \ + | awk '{ sub("^$(notdir $*).o:","$*.o $@:") ; print }' > $@ ;\ + [ -s $@ ] || rm -f $@ + +# Implicit rule to compile all classes +%.o : %.cxx + @echo "Compiling $<" + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< -o $*.o + +# Rule to make ROOTCINT output file +$(CINTOBJ) : $(HEADERS) $(LDEFFILE) + @echo "Running rootcint" + @$(ROOTSYS)/bin/rootcint -f $(CINTFILE) -c -p $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(HEADERS) $(LDEFFILE) + @echo "Compiling $(CINTFILE)" + @$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(CINTFILE) -o $@ + +rootcint : $(HEADERS) $(LDEFFILE) + @echo "Running rootcint" + $(ROOTSYS)/bin/rootcint -f $(CINTFILE) -c -p $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(HEADERS) $(LDEFFILE) + +# Rule to combine objects into a shared library +$(SHLIBFILE): $(OBJECTS) + @echo "Linking $(SHLIBFILE)" + @mkdir -p $(OUTPUTDIR) + @rm -f $(SHLIBFILE) + @$(LD) $(CXXFLAGS) $(SOFLAGS) $(LINKLIBS) $(EXTRALDFLAGS) $(OBJECTS) -o $(SHLIBFILE) + @rm -f $(OUTPUTDIR)/$(PACKAGE)Lib.so + @ln -s $(SHLIBFILE) $(OUTPUTDIR)/$(PACKAGE)Lib.so + +-include $(DEPS) + +taudiscriminantcint: $(CINTOBJ) +shlib: $(SHLIBFILE) + +clean: + @rm -f ../*/*.o ../*/*.d diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/cmt/requirements b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..fd32c2464cc939cf46159454494a6876a9e8f725 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/cmt/requirements @@ -0,0 +1,54 @@ +package TauDiscriminant +author Marcin Wolter, Noel Dawe + +use AtlasPolicy AtlasPolicy-* +use GaudiInterface GaudiInterface-* External +use xAODTau xAODTau-* Event/xAOD +use SGTools SGTools-* Control +use DataModel DataModel-* Control +use AthenaKernel AthenaKernel-* Control +use PathResolver PathResolver-* Tools +use StoreGate StoreGate-* Control +use AtlasROOT AtlasROOT-* External +use AthenaBaseComps AthenaBaseComps-* Control +apply_tag ROOTBasicLibs +apply_tag ROOTMathLibs + +macro_append TauDiscriminant_shlibflags "-L$(ROOTSYS)/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lm -ldl -lpthread -rdynamic" + +# suggested by RootCore +#library TauDiscriminantLib "../Root/*.cxx" +#apply_pattern named_installed_library library=TauDiscriminantLib + +apply_pattern dual_use_library files="../Root/*.cxx ../src/*.cxx" + +apply_pattern declare_joboptions files="../share/*.py" + +apply_pattern declare_runtime files="../share/*.root ../share/*.dat ../share/*.txt ../share/*.bin" + +apply_pattern declare_python_modules files="../python/*.py" + +# debug +# private +# macro cppdebugflags '$(cppdebugflags_s)' +# macro_remove componentshr_linkopts "-Wl,-s" + +private +use AtlasCLHEP AtlasCLHEP-* External +use AnalysisUtils AnalysisUtils-* PhysicsAnalysis/AnalysisCommon +#use CaloEvent CaloEvent-* Calorimeter +use FourMomUtils FourMomUtils-* Event +#use Particle Particle-* Reconstruction +use TrkEventPrimitives TrkEventPrimitives-* Tracking/TrkEvent +#use TrkTrackSummary TrkTrackSummary-* Tracking/TrkEvent +use xAODTracking xAODTracking-* Event/xAOD +#use VxVertex VxVertex-* Tracking/TrkEvent +use AtlasReflex AtlasReflex-* External -no_auto_imports +use CaloUtils CaloUtils-* Calorimeter +use xAODCaloEvent xAODCaloEvent-* Event/xAOD +use CaloGeoHelpers CaloGeoHelpers-* Calorimeter + +apply_pattern lcgdict dict=TauDiscriminant selectionfile=selection.xml headerfiles="../TauDiscriminant/TauDiscriminantDict.h" + +macro_append ROOT_linkopts " -lPyROOT" +end_private diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/python/TauDiscriGetter.py b/PhysicsAnalysis/TauID/TauDiscriminant/python/TauDiscriGetter.py new file mode 100644 index 0000000000000000000000000000000000000000..0af8405649990fb636b6b55447770a4e3159081d --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/python/TauDiscriGetter.py @@ -0,0 +1,168 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +# AUTHOR: Marcin.Wolter@cern.ch +# CREATED: 20 March 2008 +# +# 23 Nov 2010: cleaning up (Noel Dawe) + +from AthenaCommon.Logging import logging +from AthenaCommon.AlgSequence import AlgSequence +#from AthenaCommon.AppMgr import ToolSvc + +from RecExConfig.Configured import Configured +import traceback + +def singleton(cls): + + log = logging.getLogger('%s::__init__'% cls.__name__) + instances = {} + def getinstance(*args, **kwargs): + if cls in instances: + log.warning("Attempting to construct more than one %s. Returning the singleton."% cls.__name__) + return instances[cls] + obj = cls(*args, **kwargs) + instances[cls] = obj + return obj + return getinstance + +# to disable singleton behaviour comment out the following line: +@singleton +class TauDiscriGetter(Configured): + + def __init__(self, name = "TauDiscriminant", + container = "TauRecContainer", + sequence = None, + do_upstream_algs = False, + do_only_fakebits = False, + do_Pi0 = True, # Temporary, turns on the dumping of pi0 scores + msglevel = 3): + + self.sequence = sequence + if sequence is None: + self.sequence = AlgSequence() + self.name = name + self.container = container + self.upstream_algs = do_upstream_algs + self.only_fakebits = do_only_fakebits # temporary hack + self.do_Pi0 = do_Pi0 # Temporary, turns on the dumping of pi0 scores + self.msglevel = msglevel + Configured.__init__(self) + + def configure(self): + + from AthenaCommon.AppMgr import ToolSvc + + mlog = logging.getLogger('TauDiscriGetter::configure:') + + try: + from TauDiscriminant.TauDiscriminantConf import TauDiscriBuilder + TauDiscriBuilder.OutputLevel = self.msglevel + tauDiscriBuilder = TauDiscriBuilder( + self.name, + container = self.container) + except Exception: + mlog.error("could not find TauDiscriBuilder") + print traceback.format_exc() + return False + + tools = [] + + if not self.only_fakebits: + """ + Cut-based tau-jet identification + """ +# try: +# from TauDiscriminant.TauDiscriminantConf import TauCuts +# TauCuts.OutputLevel = self.msglevel +# tauCuts = TauCuts(cuts = "cuts.txt") +# tools.append(tauCuts) +# except Exception: +# mlog.error("could not find TauCuts in TauDiscriminant") +# print traceback.format_exc() +# return False + """ + Cut-based electron veto + """ + try: + from TauDiscriminant.TauDiscriminantConf import TauCutsEleVeto + TauCutsEleVeto.OutputLevel = self.msglevel + tauCutsEleVeto = TauCutsEleVeto() + tools.append(tauCutsEleVeto) + except Exception: + mlog.error("could not find TauCutsEleVeto in TauDiscriminant") + print traceback.format_exc() + return False + """ + Muon veto + """ + try: + from TauDiscriminant.TauDiscriminantConf import TauMuonVeto + TauMuonVeto.OutputLevel = self.msglevel + tauMuonVeto = TauMuonVeto() + tools.append(tauMuonVeto) + except Exception: + mlog.error("could not find TauMuonVeto in TauDiscriminant") + print traceback.format_exc() + return False + + + try: + from TauDiscriminant.TauDiscriminantConf import TauPi0BDT + TauPi0BDT.OutputLevel = self.msglevel + taupi0BDT = TauPi0BDT(pi0BDTPrimary="pi0Primary.BDT.bin", + pi0BDTSecondary="pi0Secondary.BDT.bin") + tools.append(taupi0BDT) + except Exception: + mlog.error("could not find TauPi0BDT in TauDiscriminant") + print traceback.format_exc() + return False + + + + """ + Likelihood tau-jet identification + """ + try: + from TauDiscriminant.TauDiscriminantConf import TauLLH + TauLLH.OutputLevel = self.msglevel + tauLLH = TauLLH() + tools.append(tauLLH) + except Exception: + mlog.error("could not find TauLLH in TauDiscriminant") + print traceback.format_exc() + return False + """ + BDT tau-jet identification + """ + try: + from TauDiscriminant.TauDiscriminantConf import TauJetBDT + TauJetBDT.OutputLevel = self.msglevel + taujetBDT = TauJetBDT(jetBDT="jet.BDT.bin", + jetSigTrans="sig.trans.jet.BDT.root", + jetBkgTrans="", + jetSigBits="sig.bits.jet.BDT.txt", + jetBkgBits="bkg.bits.jet.BDT.txt") + tools.append(taujetBDT) + except Exception: + mlog.error("could not find TauJetBDT in TauDiscriminant") + print traceback.format_exc() + return False + """ + BDT electron veto + """ + try: + from TauDiscriminant.TauDiscriminantConf import TauEleBDT + TauEleBDT.OutputLevel = self.msglevel + taueleBDT = TauEleBDT(eleBDT="ele.BDT.bin", + eleBits="", eleBitsRoot="cuts.eBDT.root") + tools.append(taueleBDT) + except Exception: + mlog.error("could not find TauEleBDT in TauDiscriminant") + print traceback.format_exc() + return False + + + tauDiscriBuilder.tools = tools + + self.sequence += tauDiscriBuilder + return True diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/TauEnergyCalibration_jobOption.py b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauEnergyCalibration_jobOption.py new file mode 100644 index 0000000000000000000000000000000000000000..ed4a1ba652eee55a4a897d38bd08cba69e030ae3 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauEnergyCalibration_jobOption.py @@ -0,0 +1,39 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +f = open('input.txt', 'r') +inputFiles = f.readlines() +f.close() +inputFiles = [item.strip() for item in inputFiles] + +from AthenaCommon.AthenaCommonFlags import jobproperties as jp +jp.AthenaCommonFlags.FilesInput = inputFiles + +include('AthenaPython/read_file.py') + +from AthenaCommon.AppMgr import theApp, ServiceMgr +from AthenaCommon.AlgSequence import AlgSequence +job = AlgSequence() + +import AthenaPoolCnvSvc.ReadAthenaPool +theApp.EvtMax = -1 + +if True: # run only TauEnergyCalibration + from TauDiscriminant.TauDiscriminantConf import TauEnergyCalibration + TauEnergyCalibration.OutputLevel = DEBUG + tauEnergyCalibration = TauEnergyCalibration('TauEnergyCalibration') + tauEnergyCalibration.tauContainerKey = 'TauRecContainer' + tauEnergyCalibration.calibrationFile = 'EnergyCalibration.root' + tauEnergyCalibration.vertexContainerKey = 'VxPrimaryCandidate' + job += tauEnergyCalibration +else: + from TauDiscriminant.TauDiscriGetter import TauDiscriGetter + TauDiscriGetter(do_upstream_algs = True, msglevel = DEBUG) + + + + + + + + + diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.C b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.C new file mode 100644 index 0000000000000000000000000000000000000000..a9bdb038148bc2e2e6fcb240e010617d607a2d43 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.C @@ -0,0 +1,68 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include <string> +#include "TFile.h" +#include "TTree.h" + +using namespace std; + +void TauIDAnalysisExample(string filename) +{ + if (gSystem->Load("libTauDiscriminant.so") != 0) + { + cout << "Could not load libTauDiscriminant.so" << endl; + } + using namespace TauID; + + TFile* file = TFile::Open(filename.c_str()); + if (!file) + { + cout << "Could not open " << filename << endl; + return; + } + TTree* tree = (TTree*)file->Get("tauPerf"); + if (!tree) + { + cout << "Could not find tree named tauPerf" << endl; + return; + } + MethodBDT* bdt = new MethodBDT("MyBDT"); + float et; + int numTrack; + float emRadius; + float centFrac; + float trkAvgDist; + float etOverPtLeadTrk; + float emFractionAtEMScale; + float massTrkSys; + float topoInvMass; + float trFlightPathSig; + int numVertices; + + bdt->addVariable("numTrack",&numTrack,"I"); + bdt->addVariable("emRadius",&emRadius,"F"); + bdt->addVariable("centFrac",¢Frac,"F"); + bdt->addVariable("trkAvgDist",&trkAvgDist,"F"); + bdt->addVariable("etOverPtLeadTrk",&etOverPtLeadTrk,"F"); + bdt->addVariable("emFractionAtEMScale",&emFractionAtEMScale,"F"); + bdt->addVariable("massTrkSys",&massTrkSys,"F"); + bdt->addVariable("topoInvMass",&topoInvMass,"F"); + bdt->addVariable("trFlightPathSig",&trFlightPathSig,"F"); + bdt->addVariable("numVertices",&numVertices,"I"); + if (!bdt->build("../share/jet.BDT.bin")) + { + cout "Could not build BDT" << endl; + return; + } + + for(unsigned int ievent(0); ievent < tree->GetEntries(); ++ievent) + { + tree->GetEntry(ievent); + for (unsigned int itau(0); itau < (*tree)["tau_n"]; ++itau) + { + et = (*tree)["tau_Et"][itau]; + } + } +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.py b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.py new file mode 100644 index 0000000000000000000000000000000000000000..975bedcd81406c21c8456b523cf81d91547a3ff8 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/TauIDAnalysisExample.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +# +# A simple script demonstrating how to use MethodBDT, MethodCuts, etc. in python +# +################################################################################ + +import sys +import ROOT +ROOT.gSystem.Load("libTauDiscriminant.so") +from ROOT import TauID +from array import array +from itertools import izip +import math + +ROOT.gInterpreter.GenerateDictionary("vector<vector<float> >", "vector") +ROOT.gInterpreter.GenerateDictionary("vector<vector<int> >", "vector") + +dphi = lambda phi1, phi2 : abs(math.fmod((math.fmod(phi1, 2*math.pi) - math.fmod(phi2, 2*math.pi)) + 3*math.pi, 2*math.pi) - math.pi) + +dR = lambda eta1, phi1, eta2, phi2: math.sqrt((eta1 - eta2)**2 + dphi(phi1, phi2)**2) + +filename = sys.argv[1] + +file = ROOT.TFile.Open(filename) +tree = file.Get("tauPerf") + +bdt = TauID.MethodBDT() +bdtbits = TauID.MethodCuts() +cuts = TauID.MethodCuts() + +variables = { + "numTrack" : array('i',[0]), + "num_pileup_and_primary_vertices" : array('i',[0]), + "centFrac" : array('f',[0]), + "etOverpTLeadTrk" : array('f',[0]), + "trkAvgDist" : array('f',[0]), + "effTopoInvMass" : array('f',[0]), + "ipSigLeadTrk" : array('f',[0]), + "lead3ClusterEOverAllClusterE" : array('f',[0]), + "numWideTrack" : array('i',[0]), + "calRadius" : array('f',[0]), + "drMax" : array('f',[0]), + "massTrkSys" : array('f',[0]), + "trFlightPathSig" : array('f',[0]), + "pt" : array('f',[0]), + "BDT" : array('f',[0]), + "CALO_ISO_CORRECTED" : array('f',[0]) +} + +for var, value in variables.items(): + bdt.addVariable(var.upper(), value, value.typecode.upper()) + bdtbits.addVariable(var.upper(), value, value.typecode.upper()) + cuts.addVariable(var.upper(), value, value.typecode.upper()) + +if not bdt.build("../share/jet.BDT.bin"): + sys.exit(1) + +if not bdtbits.build("../share/sig.bits.jet.BDT.txt"): + sys.exit(1) + +if not cuts.build("../share/cuts.txt"): + sys.exit(1) + +for entry in xrange(tree.GetEntries()): + tree.GetEntry(entry) + # update event variables + nvtx = len(filter(lambda v: (tree.vxp_type[v]==1 and tree.vxp_nTracks[v]>=4) or \ + (tree.vxp_type[v]==3 and tree.vxp_nTracks[v]>=2), range(tree.vxp_n))) + variables["num_pileup_and_primary_vertices"][0] = nvtx + + for itau in xrange(tree.tau_n): + # update tau variables + variables["numTrack"][0] = tree.tau_seedCalo_numTrack[itau] + variables["centFrac"][0] = tree.tau_seedCalo_centFrac[itau] + variables["etOverpTLeadTrk"][0] = tree.tau_etOverPtLeadTrk[itau] + variables["trkAvgDist"][0] = tree.tau_seedCalo_trkAvgDist[itau] + variables["effTopoInvMass"][0] = tree.tau_effTopoInvMass[itau] + variables["ipSigLeadTrk"][0] = tree.tau_ipSigLeadTrk[itau] + variables["numWideTrack"][0] = tree.tau_seedCalo_wideTrk_n[itau] + variables["calRadius"][0] = tree.tau_calcVars_calRadius[itau] + variables["drMax"][0] = tree.tau_calcVars_drMax[itau] + variables["massTrkSys"][0] = tree.tau_massTrkSys[itau] + variables["trFlightPathSig"][0] = tree.tau_trFlightPathSig[itau] + variables["pt"][0] = tree.tau_pt[itau] + + # calculate lead3ClusterEOverAllClusterE + clusterE = sorted(tree.tau_cluster_E[itau], reverse=True) + totE = sum(clusterE) + variables["lead3ClusterEOverAllClusterE"][0] = sum(clusterE[:3]) / totE if totE > 0 else -1111. + + # calculate CALO_ISO_CORRECTED + jvf = tree.tau_jet_jvtxf[itau] + sumPtTrk = tree.tau_jet_sumPtTrk[itau] + pt_pileup = (1. - jvf) * sumPtTrk + calo_iso = 0. + for E, eta, phi in izip(tree.tau_cluster_E[itau], tree.tau_cluster_eta[itau], tree.tau_cluster_phi[itau]): + if .2 <= dR(tree.tau_seedCalo_eta[itau], tree.tau_seedCalo_phi[itau], eta, phi) < .4: + calo_iso += E / math.cosh(eta) + max_pileup_correction = 4000. + alpha = 1. + pileup_correction = alpha * pt_pileup + if pileup_correction > max_pileup_correction: + pileup_correction = max_pileup_correction + calo_iso_corrected = calo_iso - pileup_correction + variables["CALO_ISO_CORRECTED"][0] = calo_iso_corrected + + bdtScore = bdt.response() + variables["BDT"][0] = bdtScore + + print "BDT Score: %.3f"% bdtScore + print "BDT Loose: %i"% bdtbits.response(0) + print "BDT Medium: %i"% bdtbits.response(1) + print "BDT Tight: %i"% bdtbits.response(2) + print "Cuts Loose: %i"% cuts.response(0) + print "Cuts Medium: %i"% cuts.response(1) + print "Cuts Tight: %i"% cuts.response(2) + print "-"*30 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/jobOptions.py b/PhysicsAnalysis/TauID/TauDiscriminant/run/jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..ffcac520e0056e7d0f674e4f140d98f120ebc272 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/jobOptions.py @@ -0,0 +1,33 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +""" +These minimal job options are for testing only!!! +""" + +import AthenaPoolCnvSvc.ReadAthenaPool +#ServiceMgr.EventSelector.InputCollections = ['/tmp/simonyan/mc11_7TeV.106052.PythiaZtautau.merge.AOD.e825_s1324_s1300_r2731_r2700_tid518036_00/AOD.518036._000301.pool.root.1'] +ServiceMgr.EventSelector.InputCollections = ['inputAODFile=/afs/cern.ch/work/p/pmalecki/mc12_8TeV.147818.Pythia8_AU2CTEQ6L1_Ztautau.merge.AOD.e1176_s1479_s1470_r3553_r3549_tid779134_00/AOD.779134._000258.pool.root.1'] + + + +from RecExConfig.RecFlags import rec + +rec.readRDO=False +rec.readESD=False # set true for ESD reading +rec.readAOD=True # set false for ESD reading +rec.doWriteAOD=False +rec.doWriteESD=False +rec.doWriteTAG=False +rec.doCBNT=False +rec.doHist=False +rec.doTruth=False +rec.AutoConfiguration=['everything'] +#rec.doFloatingPointException=True + +include ("RecExCommon/RecExCommon_topOptions.py") + +from AthenaCommon.AppMgr import theApp +from TauDiscriminant.TauDiscriGetter import TauDiscriGetter +TauDiscriGetter(msglevel = VERBOSE) + +theApp.EvtMax = 500 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/minJobOptions.py b/PhysicsAnalysis/TauID/TauDiscriminant/run/minJobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..703ed0be5a8301de6ca807296ba0bdf2378c7ca3 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/minJobOptions.py @@ -0,0 +1,24 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +""" +These minimal job options are for testing only!!! +""" +import AthenaPoolCnvSvc.ReadAthenaPool + +# lxplus +ServiceMgr.EventSelector.InputCollections = \ + ['/scratchdisk2/end/data/valid1.105200.T1_McAtNlo_Jimmy.recon.AOD.e603_s932_r1588_tid172295_00/AOD.172295._000154.pool.root.1'] + +# SFU T3 +#ServiceMgr.EventSelector.InputCollections = \ +# ['/cluster/data03/endw/ntuples/AOD/valid1.105200.T1_McAtNlo_Jimmy.recon.AOD.e603_s932_r1588_tid172295_00/AOD.172295._000001.pool.root.1'] + +from AthenaCommon.AppMgr import theApp +from TauDiscriminant.TauDiscriGetter import TauDiscriGetter + +#TauDiscriGetter(do_upstream_algs = True, msglevel = VERBOSE) +#TauDiscriGetter(do_upstream_algs = False, do_only_fakebits = True, msglevel = VERBOSE) + +TauDiscriGetter(msglevel=VERBOSE, do_Pi0=True) + +theApp.EvtMax = 10 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/tauIDReader_LLH.py b/PhysicsAnalysis/TauID/TauDiscriminant/run/tauIDReader_LLH.py new file mode 100755 index 0000000000000000000000000000000000000000..f66260ee9c7d560dd17082b874a98cfbdcd91b51 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/tauIDReader_LLH.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python + +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +#File tauLikelihood_rerunOnDPD.py +#by Martin.Flechl@cern.ch, Marcin.Wolter@cern.ch +#based on Noel's example +# +#usage: tauIDReader_LLH.py D3PD_file_name.root +import PyCintex +import ROOT +import os +import sys + +#ifile="DPD.root" +ifile=sys.argv[1]; +ofile="FOR_DPD.root" + +inputType=0 #0 TauDPD, 1 small TauDPD, 2 Dugan's tiny D4PD + + +if (inputType==0): + m_treename="tauPerf" + m_vartypeF="VF" + m_vartypeI="VI" + m_authortype="VI" +if (inputType==1): + m_treename="tauPerfSmall" + m_vartypeF="VF" + m_vartypeI="VI" + m_authortype="VI" +if (inputType==2): + m_treename="D4PD" + m_vartypeF="F" + m_vartypeI="I" + m_authortype="F" + +print "Setting up..." +output = ROOT.TFile.Open(ofile,"recreate") +### mw app = ROOT.TauID.TauIDReader(output,True) +app = ROOT.TauID.TauIDReader(True) +app.setOutput(output,"") + +#Commented out variables are not needed when running the safeLLH +#Comment in to rerun the full LLH +variables = [ + ("author","tau_author",m_authortype), + ("eta","tau_eta",m_vartypeF), + ("numTrack","tau_numTrack",m_vartypeI), + ("et","tau_Et",m_vartypeF), + ("nPi0","tau_nPi0",m_vartypeI), + ("NUM_PILEUP_AND_PRIMARY_VERTICES","evt_calcVars_numGoodVertices","I"), # number of good vertices + ("vxp_n","vxp_n","I"), # not quite correct, these are all vertices + ("vxp_nTracks","vxp_nTracks","VI"), +# ("emRadius","tau_seedCalo_EMRadius",m_vartypeF), #0 +# ("isolFrac","tau_seedCalo_isolFrac",m_vartypeF), #1 +# ("stripWidth2","tau_seedCalo_stripWidth2",m_vartypeF), #2 +# ("nStrip","tau_seedCalo_nStrip",m_vartypeI), #3 +# ("etHad2etTracks","tau_calcVars_etHadSumPtTracks",m_vartypeF), #4 +# ("etEM2etTracks","tau_calcVars_etEMSumPtTracks",m_vartypeF), #5 +# ("etTracks2et","tau_calcVars_sumTrkPt",m_vartypeF), #6, code divides the quantity by et!! +# ("emFractionCalib","tau_calcVars_emFracCalib",m_vartypeF), #7 +# ("emFractionAtEMScale","tau_calcVars_emFracCalib",m_vartypeF), #7 not quite correct, but not in current D3PD +# ("etOverPtLeadTrk","tau_etOverPtLeadTrk",m_vartypeF), #8 +# ("dRmin","tau_calcVars_drMin",m_vartypeF), #9 + ("dRmax","tau_calcVars_drMax",m_vartypeF), #10 +# ("trkWidth2","tau_trkWidth2",m_vartypeF), #11 + ("massTrkSys","tau_massTrkSys",m_vartypeF), #12 +# ("nIsolTrk","tau_seedTrk_nIsolTrk",m_vartypeI), #13 +# ("MVisEflow","tau_m",m_vartypeF), #14 +# ("ipZ0sinThetaSigLeadTrk","tau_ipZ0SinThetaSigLeadTrk",m_vartypeF), #15 +# ("ipSigLeadLooseTrk","tau_ipSigLeadLooseTrk",m_vartypeF), #16 + ("trFlightPathSig","tau_trFlightPathSig",m_vartypeF), #17 + ("centFrac","tau_seedCalo_centFrac",m_vartypeF), #18 +# ("numEffClus","tau_calcVars_numEffTopoClusters",m_vartypeF), #19 + ("trkAvgDist","tau_seedCalo_trkAvgDist",m_vartypeF), #20 +# ("topoInvMass","tau_topoInvMass",m_vartypeF), #21 + ("calRadius","tau_calcVars_calRadius",m_vartypeF), #22 + + ("lead2ClusterEOverAllClusterE","tau_calcVars_lead2ClusterEOverAllClusterE",m_vartypeF), #27 + ("numWideTrack","tau_seedCalo_wideTrk_n",m_vartypeI), #50 missing + + + ] + +for varName,branchName,type in variables: + app.addVariable(varName,branchName,type) + +# "CUTS" or "BDT", name of cuts/BDT file, number of responses +# (i.e. 3 for cuts (loose, medium, tight), 1 for BDT) +print "Finding PDF files" +filePDFtau = "pdfs_tau.root" +filePDFjet = "pdfs_jet.root" +fileLMTCuts = "LMTCutsLLH.root" +dataPathList = os.environ['DATAPATH'].split(os.pathsep) +dataPathList.insert(0, os.curdir) +from AthenaCommon.Utils.unixtools import FindFile +fileNameTau = FindFile(filePDFtau, dataPathList, os.R_OK ) +fileNameJet = FindFile(filePDFjet, dataPathList, os.R_OK ) +fileNameLMTCuts = FindFile(fileLMTCuts, dataPathList, os.R_OK ) +if (not fileNameTau): + print "Input PDF not found" +print "Tau PDF file name: ", fileNameTau +print "Jet PDF file name: ", fileNameJet +fileNames=fileNameTau+","+fileNameJet+","+fileNameLMTCuts +#print "String: ", fileNames + +print "Booking Method: LLH" +### mw app.bookMethod("LLH","llhsafe",fileNames,4) +app.bookMethod(ROOT.TauID.Types.LLH,"llhsafe",fileNames,4) +#app.bookMethod("LLH","llhdef",fileNames,4) +#app.bookMethod("LLH","llhall",fileNames,4) + +print "Opening input file" +input = ROOT.TFile.Open(ifile) +tree = input.Get(m_treename) + +print "Obtaining Discriminant ",tree,m_treename," ",ifile +# mw llhTree = app.classify(tree,"taullh","") +llhTree = app.classify(tree,"taullh",True) + +llhTree.AddFriend(m_treename,ifile) +output.cd() + +print "Writing output",output.GetName() +llhTree.Write() + +output.Close() diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/run/tauid-redo b/PhysicsAnalysis/TauID/TauDiscriminant/run/tauid-redo new file mode 100755 index 0000000000000000000000000000000000000000..f48f88d86ae136fdcf133bec7221e23ea15f64d1 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/run/tauid-redo @@ -0,0 +1,236 @@ +#!/usr/bin/env python + +from optparse import OptionParser + +parser = OptionParser(usage="%prog [options] file1.root file2.root ...") +parser.add_option("-t","--tree", action="store", type="str", dest="treename", + default="tau", help="name of tree in D3PD") +parser.add_option("-m","--methods", action="store", type="str", dest="methods", + default="BDT,BDTE,PI0P,PI0S,LLH", help="list of methods to run separated by commas") +parser.add_option("-d","--derived-methods", action="store", type="str", dest="extramethods", + default="BBDTCUTS,SBDTCUTS", help="list of derived methods to run separated by commas, set to NONE if you wish to skip these") +parser.add_option("--clone", action="store_true", dest="clonetree", + default=False, help="copy all branches from each input tree into each output tree") +parser.add_option("--friend", action="store_true", dest="friendtree", + default=False, help="make each input tree a friend of each output tree") +parser.add_option("--idir", action="store", type="str", dest="inputdir", + default="", help="the directory in which the input tree is located in each ROOT file") +parser.add_option("--odir", action="store", type="str", dest="outputdir", + default="", help="the directory in which to write the output tree in each output ROOT file") +parser.add_option("--flat", action="store_true", dest="flat", + default=False, help="the ntuples are flat (D4PD)") +parser.add_option("-v","--verbose", action="store_true", dest="verbose", + default=False, help="show verbose output") +options, args = parser.parse_args() + +import sys + +if not args: + print "specify at least one input ROOT file" + sys.exit(1) + +try: + import ROOT +except: + sys.exit("Could not import ROOT module. Is PyROOT installed?") + +try: + import PyCintex + from ROOT import TauID +except: + try: + ROOT.gSystem.Load("libTauDiscriminant.so") + from ROOT import TauID + except: + print "Could not import TauID module" + print "Be sure to do one of the following:" + print ' 1) Setup Athena, compile TauDiscriminant with "make", and source setup.sh' + print ' 2) Compile standalone TauDiscriminant with "make -f Makefile.Standalone", and source setup.sh' + sys.exit(1) + +import os +import time + +def find_file(filename, search_path_var='PATH', include_working=True): + """ + find filename in PATH with the option of including + the current working directory in the search + """ + if not os.environ.has_key(search_path_var): + sys.exit("Environment variable $%s is not defined"% search_path_var) + search_path = os.environ[search_path_var] + paths = search_path.split(os.pathsep) + if include_working: + paths = ['.'] + paths + for path in paths: + fullpath = os.path.join(path, filename) + if os.path.exists(fullpath): + return os.path.abspath(fullpath) + sys.exit("Could not find %s in %s"%(filename, search_path_var)) + +if options.flat: + variables = [ + ("AUTHOR","I"), + ("ETA","F"), + ("TRKAVGDIST","F"), + ("ETOVERPTLEADTRK","F"), + ("EMFRACTIONATEMSCALE","F"), + ("TRT_NHT_OVER_NLT","F"), + ("NUM_PILEUP_AND_PRIMARY_VERTICES","I"), + ("DRMAX","F"), + ("ABS_ETA_LEAD_TRACK","F"), + ("CHPIEMEOVERCALOEME","F"), + ("SECMAXSTRIPET","F"), + ("HADLEAKET","F"), + ("SUMEMCELLETOVERLEADTRKPT","F"), + ("CORRFTRK","F"), + ("CORRCENTFRAC","F"), + ("ISOLFRAC","F"), + ("HADRADIUS","F"), + ("EMPOVERTRKSYSP","F"), + ("PSSFRACTION","F"), + ("NSTRIP","I"), + ("NUMTRACK","I"), + ("PT","F"), + ("NUMWIDETRACK","I"), + ("MASSTRKSYS","F"), + ("IPSIGLEADTRK","F"), + ("TRFLIGHTPATHSIG","F"), + ("TAU_PTRATIO","F"), + ("TAU_PI0_N","I"), + ("TAU_PI0_VISTAU_M","F"), + ("EMFRACTIONATEMSCALE_MOVEE3","F"), + ("TAU_ABSDELTAETA","F"), + ("TAU_SEEDTRK_SECMAXSTRIPETOVERPT","F"), + ("TAU_ABSDELTAPHI","F"), + + ] +else: + variables = [ ("AUTHOR","VI"), + ("ETA","VF"), + ("TRKAVGDIST","VF"), + ("ETOVERPTLEADTRK","VF"), + ("EMFRACTIONATEMSCALE","VF"), + ("TRT_NHT_OVER_NLT","VF"), + ("NUM_PILEUP_AND_PRIMARY_VERTICES","I"), + ("DRMAX","VF"), + ("ABS_ETA_LEAD_TRACK","VF"), + ("CHPIEMEOVERCALOEME","VF"), + ("SECMAXSTRIPET","VF"), + ("HADLEAKET","VF"), + ("SUMEMCELLETOVERLEADTRKPT","VF"), + ("CORRFTRK","VF"), + ("CORRCENTFRAC","VF"), + ("ISOLFRAC","VF"), + ("HADRADIUS","VF"), + ("EMPOVERTRKSYSP","VF"), + ("PSSFRACTION","VF"), + ("NSTRIP","VI"), + ("NUMTRACK","VI"), + ("PT","VF"), + ("NUMWIDETRACK","VI"), + ("MASSTRKSYS","VF"), + ("IPSIGLEADTRK","VF"), + ("TRFLIGHTPATHSIG","VF"), + ("TAU_PTRATIO","VF"), + ("TAU_PI0_N","VI"), + ("TAU_PI0_VISTAU_M","VF"), + ("EMFRACTIONATEMSCALE_MOVEE3","VF"), + ("TAU_ABSDELTAETA","VF"), + ("TAU_SEEDTRK_SECMAXSTRIPETOVERPT","VF"), + ("TAU_ABSDELTAPHI","VF"), + ] + +#cutsfile = find_file("cuts.txt","DATAPATH",True) +jetBDTfile = find_file("jet.BDT.bin","DATAPATH",True) +eleBDTfile = find_file("ele.BDT.bin","DATAPATH",True) +pi0pBDTfile = find_file("pi0Primary.BDT.bin","DATAPATH",True) +pi0sBDTfile = find_file("pi0Secondary.BDT.bin","DATAPATH",True) +llh_files = find_file("pdfs_tau.root","DATAPATH",True)+","+find_file("pdfs_jet.root","DATAPATH",True)+","+find_file("LMTCutsLLH.root","DATAPATH",True) + +sBDTCutsfile = find_file("sig.bits.jet.BDT.txt","DATAPATH",True) +bBDTCutsfile = find_file("bkg.bits.jet.BDT.txt","DATAPATH",True) + +options.methods = list(set(options.methods.split(','))) +options.extramethods = list(set(options.extramethods.split(','))) + +methods = { +# "CUTS": (TauID.Types.CUTS, "CUTS", cutsfile, 3), + "BDT": (TauID.Types.BDT, "BDTJetScore", jetBDTfile, 1), + "BDTE": (TauID.Types.BDT, "BDTEleScore", eleBDTfile, 1), + "PI0P": (TauID.Types.BDT, "Pi0PrimaryScore",pi0pBDTfile,1), + "PI0S": (TauID.Types.BDT, "Pi0SecondaryScore",pi0sBDTfile,1), + "LLH": (TauID.Types.LLH, "llhsafe",llh_files,4), +} + +extraMethods = { + "SBDTCUTS": (TauID.Types.CUTS, "SBDTJetScore", sBDTCutsfile, 3), + "BBDTCUTS": (TauID.Types.CUTS, "BBDTJetScore", bBDTCutsfile, 3), +} + +methodVariables = [ + ("BDT","F","BDTJetScore"), + ("BDTE","F","BDTEleScore"), + ("PI0P","F","Pi0PrimaryScore"), + ("PI0S","F","Pi0SecondaryScore"), + ("LLH","F","llhsafe"), + + +] + +reader = TauID.TauIDReader(options.verbose) + +for variable,typename in variables: + if not reader.addVariable(variable,typename): + sys.exit("Abort") + +for method in options.methods: + if methods.has_key(method): + if not reader.bookMethod(*methods[method]): + sys.exit("Aborted") + else: + sys.exit("Method %s is not defined"% method) + +for variable,typename,branch in methodVariables: + if not reader.addVariable(variable, typename, branch): + sys.exit("Abort") + +if extraMethods: + for method in options.extramethods: + if not method == "NONE": + if extraMethods.has_key(method): + if not reader.bookMethod(*extraMethods[method]): + sys.exit("Aborted") + else: + sys.exit("Method %s is not defined"% method) + +# Suppress warnings +ROOT.gErrorIgnoreLevel = ROOT.kError + +if options.verbose: + print "=============================================" +totalTime = 0. +totalEntries = 0 +for filename in args: + print "Processing %s..."% filename + outputfilename = filename+".tauid-redo.root" + if not reader.setOutput(outputfilename, options.outputdir): + sys.exit("Aborted") + t1 = time.time() + entries = reader.classify(options.treename, options.treename, filename, options.inputdir, options.friendtree, options.clonetree) + if entries <= 0: + + sys.exit("Aborted") + dt = time.time() - t1 + totalTime += dt + totalEntries += entries + if options.verbose: + print "Total time: %.3f [sec]"%dt + print "<Time per entry>: %i [microsec]"%int(1000000*dt/entries) + print "Finished processing %s"% filename + print "=============================================" +if options.verbose: + print "Total time for all files: %.3f [min]"% (totalTime/60) + if totalEntries > 0: + print "<Time per entry> over all files: %i [microsec]"%int(1000000*totalTime/totalEntries) +print "Done" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/setup.sh b/PhysicsAnalysis/TauID/TauDiscriminant/setup.sh new file mode 100644 index 0000000000000000000000000000000000000000..304d2656725338e9fcbc8e497c185654305e7548 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/setup.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +######################################################## +# +# Update env variables for running in standalone mode +# on D3PDs (ROOT ntuples) with tauid-redo +# or scripts in taumva (see README) +# +# - Noel Dawe +# +######################################################## + +# deterine path to this script +# http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done +TD_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + +export LD_LIBRARY_PATH=${TD_DIR}/StandAlone${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} +export PATH=${TD_DIR}/run${PATH:+:$PATH} +export DATAPATH=${TD_DIR}/share${DATAPATH:+:$DATAPATH} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/EnergyCalibration.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/EnergyCalibration.root new file mode 100644 index 0000000000000000000000000000000000000000..ce496c79bb2c8bbbd94c9ebe8a41b0e1747341c1 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/EnergyCalibration.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/LMTCutsLLH.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/LMTCutsLLH.root new file mode 100644 index 0000000000000000000000000000000000000000..24f4f48502f5d7b79299227c5e97c58c21de8716 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/LMTCutsLLH.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/TauDiscri_jobOptions.py b/PhysicsAnalysis/TauID/TauDiscriminant/share/TauDiscri_jobOptions.py new file mode 100755 index 0000000000000000000000000000000000000000..a18556d6509f17f3b9ab87fe5c0f6a092a08fb41 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/share/TauDiscri_jobOptions.py @@ -0,0 +1,2 @@ +from TauDiscriminant.TauDiscriGetter import TauDiscriGetter +TauDiscriGetter() diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/bkg.bits.jet.BDT.txt b/PhysicsAnalysis/TauID/TauDiscriminant/share/bkg.bits.jet.BDT.txt new file mode 100644 index 0000000000000000000000000000000000000000..df7f16c5859614f2ae97ba9926c04fb961635382 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/share/bkg.bits.jet.BDT.txt @@ -0,0 +1,179 @@ +1 +NUMTRACK I +0 1 +-3 +-3 +-1 +2 +BDT F +PT F +3 +1.000000E+00 +-4 22 +1 0 +0.000000 0.518400 +15257.155700 0.518400 +15801.688600 0.517600 +16393.516200 0.519800 +17031.783300 0.516600 +17730.442600 0.521400 +18495.901500 0.523600 +19333.822700 0.523300 +20280.374400 0.522300 +21333.054500 0.529000 +22488.162300 0.528600 +23777.609800 0.535000 +25239.947200 0.539800 +26919.403000 0.543800 +28851.328600 0.546700 +31087.770400 0.556400 +33769.034400 0.559300 +37162.997000 0.581400 +41954.037500 0.596400 +50340.639900 0.612200 +72907.442500 0.668200 +100000.000000 0.668200 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 22 +1 0 +0.000000 0.618000 +15257.155700 0.618000 +15801.688600 0.609600 +16393.516200 0.618500 +17031.783300 0.615000 +17730.442600 0.620100 +18495.901500 0.634100 +19333.822700 0.618700 +20280.374400 0.628900 +21333.054500 0.633100 +22488.162300 0.640300 +23777.609800 0.643800 +25239.947200 0.647400 +26919.403000 0.654200 +28851.328600 0.661400 +31087.770400 0.672800 +33769.034400 0.681100 +37162.997000 0.717500 +41954.037500 0.731800 +50340.639900 0.743800 +72907.442500 0.793800 +100000.000000 0.793800 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 22 +1 0 +0.000000 0.773400 +15257.155700 0.773400 +15801.688600 0.777100 +16393.516200 0.781100 +17031.783300 0.776700 +17730.442600 0.788800 +18495.901500 0.790200 +19333.822700 0.787200 +20280.374400 0.798300 +21333.054500 0.816600 +22488.162300 0.779800 +23777.609800 0.803400 +25239.947200 0.835900 +26919.403000 0.818100 +28851.328600 0.854600 +31087.770400 0.834200 +33769.034400 0.846100 +37162.997000 0.872900 +41954.037500 0.876200 +50340.639900 0.876100 +72907.442500 0.902900 +100000.000000 0.902900 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +3 +1.000000E+00 +-4 22 +1 0 +0.000000 0.436700 +16000.007700 0.436700 +17911.972000 0.432700 +19717.259300 0.433700 +21470.598800 0.425500 +23177.059000 0.421200 +24925.380500 0.398400 +26680.763400 0.426800 +28449.353600 0.393500 +30257.536300 0.420400 +32147.890800 0.402200 +34196.679100 0.407800 +36422.228100 0.403200 +38834.308800 0.415600 +41599.517400 0.407200 +44913.180800 0.422300 +49074.177400 0.406700 +54502.529500 0.360100 +62009.981200 0.421800 +72562.859400 0.398200 +88765.527900 0.405200 +100000.000000 0.405200 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 22 +1 0 +0.000000 0.530700 +16000.007700 0.530700 +17911.972000 0.537900 +19717.259300 0.528000 +21470.598800 0.529600 +23177.059000 0.527900 +24925.380500 0.536600 +26680.763400 0.537500 +28449.353600 0.533700 +30257.536300 0.541100 +32147.890800 0.531500 +34196.679100 0.534900 +36422.228100 0.538100 +38834.308800 0.539900 +41599.517400 0.546400 +44913.180800 0.547100 +49074.177400 0.551700 +54502.529500 0.550100 +62009.981200 0.552800 +72562.859400 0.554200 +88765.527900 0.568800 +100000.000000 0.568800 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 22 +1 0 +0.000000 0.660700 +16000.007700 0.660700 +17911.972000 0.687400 +19717.259300 0.676800 +21470.598800 0.679300 +23177.059000 0.675100 +24925.380500 0.677000 +26680.763400 0.696700 +28449.353600 0.695900 +30257.536300 0.692100 +32147.890800 0.686300 +34196.679100 0.685800 +36422.228100 0.700000 +38834.308800 0.728600 +41599.517400 0.705300 +44913.180800 0.712500 +49074.177400 0.706500 +54502.529500 0.716500 +62009.981200 0.704800 +72562.859400 0.708300 +88765.527900 0.712800 +100000.000000 0.712800 +-2 0.000000E+00 +-2 1.000000E+00 +-1 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.eBDT.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.eBDT.root new file mode 100644 index 0000000000000000000000000000000000000000..34fc6599a980992dc6347bd03ac7c17d616d1edc Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.eBDT.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.txt b/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.txt new file mode 100644 index 0000000000000000000000000000000000000000..ba98b560c74ce887de517483e73aaac090f4b4c3 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/share/cuts.txt @@ -0,0 +1,93 @@ +1 +NUMTRACK I +0 1 +-3 +-3 +-1 +6 +TRKAVGDIST F +ETOVERPTLEADTRK F +CALO_ISO_CORRECTED F +NUMWIDETRACK I +PT F +TRFLIGHTPATHSIG F +3 +1.000000E+00 +-5 0.0667*(80000.<=x)+(417./x+0.0824-2.61e-7*x)*(x<80000.) +4 0 +1 4.000000E+00 +2 6.000000E+03 +3 9999 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 +1.000000E+00 +-5 0.0667*(80000.<=x)+(417./x+0.0824-2.61e-7*x)*(x<80000.) +4 0 +1 3.330000E+00 +2 4.000000E+03 +3 0 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 +1.000000E+00 +-5 0.0567*(80000.<=x)+(417./x+0.0724-2.61e-7*x)*(x<80000.) +4 0 +1 2.500000E+00 +2 3.000000E+03 +3 0 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 +3 +1.000000E+00 +-5 0.048*(80000.<=x)+(375./x+0.0696-3.28e-7*x)*(x<80000.) +4 0 +1 3.330000E+00 +2 7.000000E+03 +3 9999 +5 -9.999000E+03 +-2 0.000000E+00 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 +1.000000E+00 +-5 0.048*(80000.<=x)+(375./x+0.0696-3.28e-7*x)*(x<80000.) +4 0 +1 3.330000E+00 +2 7.000000E+03 +3 0 +5 0.000000E+00 +-2 0.000000E+00 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 +1.000000E+00 +-5 0.038*(80000.<=x)+(375./x+0.0596-3.28e-7*x)*(x<80000.) +4 0 +1 2.500000E+00 +2 4.000000E+03 +3 0 +5 5.000000E-01 +-2 0.000000E+00 +-2 1.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-2 0.000000E+00 +-1 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_jet.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_jet.root new file mode 100644 index 0000000000000000000000000000000000000000..0bda98ce1378f6dd7497992283ddf2190d29ac7d Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_jet.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_tau.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_tau.root new file mode 100644 index 0000000000000000000000000000000000000000..9fc7a07067d8903a1d4d96ba7b8de855dd877206 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/pdfs_tau.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Primary.BDT.bin b/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Primary.BDT.bin new file mode 100644 index 0000000000000000000000000000000000000000..711ea8de8963f0acf38f3e9da51f80c8eec2d6a1 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Primary.BDT.bin differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Secondary.BDT.bin b/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Secondary.BDT.bin new file mode 100644 index 0000000000000000000000000000000000000000..0f76f5fb2c1d61778c365482118a7b6e50b67e28 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/pi0Secondary.BDT.bin differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.bits.jet.BDT.txt b/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.bits.jet.BDT.txt new file mode 100644 index 0000000000000000000000000000000000000000..432acacd12ad71f367813444609e44bc968aa4f6 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.bits.jet.BDT.txt @@ -0,0 +1,359 @@ +1 +NUMTRACK I +0 1 +-3 +-3 +-1 +2 +BDT F +PT F +3 +1.000000E+00 +-4 50 +1 0 +0.000000 0.500800 +16140.164100 0.500800 +16910.560500 0.504500 +17686.359400 0.511500 +18468.919900 0.515400 +19258.222700 0.522000 +20052.459000 0.526400 +20862.914100 0.525800 +21685.084000 0.532500 +22524.728500 0.535200 +23396.103500 0.536700 +24297.113300 0.540300 +25222.515600 0.540100 +26180.726600 0.543500 +27173.009800 0.547500 +28203.728500 0.548300 +29291.011700 0.546200 +30445.728500 0.554500 +31678.771500 0.552800 +33008.894500 0.558600 +34464.570300 0.561900 +36079.656200 0.561800 +37919.226600 0.566600 +40129.968800 0.572100 +43075.921900 0.573000 +48713.335900 0.578400 +57510.192600 0.586100 +67274.898000 0.581600 +77039.603500 0.584600 +86804.309000 0.577000 +96569.014500 0.588300 +106101.859400 0.587400 +115657.031200 0.590000 +126005.000000 0.583300 +137251.093800 0.589500 +149065.281200 0.590200 +161429.625000 0.591900 +174342.312500 0.591000 +187864.937500 0.590100 +202402.296900 0.588900 +218018.359400 0.590200 +235117.968800 0.590600 +254758.593800 0.591700 +277347.875000 0.593200 +303140.625000 0.588500 +333448.437500 0.591600 +372086.750000 0.591000 +426726.468800 0.596100 +544437.242200 0.595300 +800000.000000 0.595300 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 50 +1 0 +0.000000 0.545100 +16140.164100 0.545100 +16910.560500 0.550200 +17686.359400 0.556700 +18468.919900 0.560100 +19258.222700 0.567200 +20052.459000 0.572700 +20862.914100 0.572400 +21685.084000 0.582100 +22524.728500 0.583500 +23396.103500 0.585600 +24297.113300 0.591400 +25222.515600 0.595100 +26180.726600 0.597200 +27173.009800 0.600500 +28203.728500 0.603800 +29291.011700 0.602900 +30445.728500 0.609300 +31678.771500 0.610800 +33008.894500 0.616200 +34464.570300 0.619500 +36079.656200 0.621200 +37919.226600 0.628800 +40129.968800 0.632500 +43075.921900 0.636000 +48713.335900 0.642500 +57510.192600 0.650800 +67274.898000 0.646300 +77039.603500 0.649900 +86804.309000 0.637700 +96569.014500 0.655800 +106101.859400 0.657000 +115657.031200 0.658600 +126005.000000 0.656200 +137251.093800 0.660200 +149065.281200 0.661200 +161429.625000 0.664500 +174342.312500 0.662400 +187864.937500 0.660800 +202402.296900 0.660100 +218018.359400 0.662200 +235117.968800 0.663600 +254758.593800 0.663100 +277347.875000 0.665700 +303140.625000 0.660200 +333448.437500 0.664600 +372086.750000 0.664200 +426726.468800 0.664400 +544437.242200 0.666500 +800000.000000 0.666500 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 50 +1 0 +0.000000 0.629700 +16140.164100 0.629700 +16910.560500 0.636700 +17686.359400 0.641400 +18468.919900 0.645800 +19258.222700 0.653400 +20052.459000 0.658000 +20862.914100 0.658900 +21685.084000 0.664400 +22524.728500 0.668400 +23396.103500 0.669200 +24297.113300 0.676000 +25222.515600 0.678000 +26180.726600 0.681500 +27173.009800 0.683900 +28203.728500 0.687700 +29291.011700 0.688800 +30445.728500 0.694100 +31678.771500 0.693300 +33008.894500 0.699900 +34464.570300 0.702900 +36079.656200 0.703900 +37919.226600 0.710000 +40129.968800 0.713300 +43075.921900 0.713200 +48713.335900 0.719600 +57510.192600 0.731600 +67274.898000 0.730600 +77039.603500 0.733900 +86804.309000 0.712300 +96569.014500 0.728900 +106101.859400 0.730700 +115657.031200 0.732700 +126005.000000 0.731900 +137251.093800 0.733300 +149065.281200 0.733200 +161429.625000 0.734900 +174342.312500 0.733400 +187864.937500 0.731600 +202402.296900 0.731400 +218018.359400 0.731000 +235117.968800 0.731600 +254758.593800 0.729700 +277347.875000 0.729600 +303140.625000 0.727500 +333448.437500 0.726900 +372086.750000 0.725900 +426726.468800 0.723500 +544437.242200 0.721900 +800000.000000 0.721900 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +3 +1.000000E+00 +-4 54 +1 0 +0.000000 0.475900 +16737.960900 0.475900 +17778.316400 0.486800 +18761.082000 0.493800 +19706.365200 0.499200 +20633.343800 0.508300 +21536.095700 0.507600 +22419.902300 0.514500 +23295.601600 0.518000 +24168.896500 0.518200 +25048.230500 0.521700 +25926.437500 0.521800 +26810.982400 0.523700 +27718.646500 0.527400 +28641.666000 0.530700 +29588.650400 0.531400 +30562.250000 0.533300 +31560.375000 0.536000 +32591.238300 0.535000 +33675.078100 0.534600 +34845.664100 0.537900 +36110.484400 0.537600 +37502.226600 0.537400 +39085.468800 0.541400 +40938.511700 0.542400 +43325.445300 0.544200 +47172.777300 0.546200 +51147.618800 0.553600 +54163.379700 0.555200 +57179.140600 0.559500 +60194.901600 0.553300 +63210.662500 0.556300 +69002.991800 0.557000 +77571.889500 0.554300 +86140.787100 0.549600 +94709.684800 0.556900 +103278.582400 0.559200 +113960.257800 0.566600 +127432.898400 0.573900 +142193.531200 0.572500 +157442.937500 0.567700 +172714.281200 0.569600 +188320.218800 0.569400 +204392.218800 0.568100 +221300.218800 0.569500 +239779.281200 0.563800 +260790.500000 0.560600 +284605.312500 0.552500 +310978.187500 0.553500 +341455.000000 0.549900 +380790.156200 0.533900 +435189.375000 0.529400 +550179.007800 0.506700 +800000.000000 0.506700 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 54 +1 0 +0.000000 0.506300 +16737.960900 0.506300 +17778.316400 0.515900 +18761.082000 0.518400 +19706.365200 0.524600 +20633.343800 0.534000 +21536.095700 0.533500 +22419.902300 0.540100 +23295.601600 0.543000 +24168.896500 0.541400 +25048.230500 0.546000 +25926.437500 0.546800 +26810.982400 0.547600 +27718.646500 0.552600 +28641.666000 0.553300 +29588.650400 0.554800 +30562.250000 0.555200 +31560.375000 0.558800 +32591.238300 0.559000 +33675.078100 0.558100 +34845.664100 0.562000 +36110.484400 0.561300 +37502.226600 0.562300 +39085.468800 0.566600 +40938.511700 0.567200 +43325.445300 0.569100 +47172.777300 0.571100 +51147.618800 0.581800 +54163.379700 0.586600 +57179.140600 0.589000 +60194.901600 0.585000 +63210.662500 0.586900 +69002.991800 0.589400 +77571.889500 0.588300 +86140.787100 0.582900 +94709.684800 0.577500 +103278.582400 0.597000 +113960.257800 0.602500 +127432.898400 0.610700 +142193.531200 0.610700 +157442.937500 0.607800 +172714.281200 0.606200 +188320.218800 0.608500 +204392.218800 0.603200 +221300.218800 0.606800 +239779.281200 0.603400 +260790.500000 0.600900 +284605.312500 0.593700 +310978.187500 0.593500 +341455.000000 0.589100 +380790.156200 0.580900 +435189.375000 0.577000 +550179.007800 0.560000 +800000.000000 0.560000 +-2 0.000000E+00 +-2 1.000000E+00 +-1 +1.000000E+00 +-4 54 +1 0 +0.000000 0.557000 +16737.960900 0.557000 +17778.316400 0.564000 +18761.082000 0.565500 +19706.365200 0.574000 +20633.343800 0.582200 +21536.095700 0.585500 +22419.902300 0.592200 +23295.601600 0.596300 +24168.896500 0.598100 +25048.230500 0.597700 +25926.437500 0.599700 +26810.982400 0.602500 +27718.646500 0.607900 +28641.666000 0.609400 +29588.650400 0.607700 +30562.250000 0.610200 +31560.375000 0.614200 +32591.238300 0.616500 +33675.078100 0.615000 +34845.664100 0.616800 +36110.484400 0.616800 +37502.226600 0.621000 +39085.468800 0.625400 +40938.511700 0.627700 +43325.445300 0.629700 +47172.777300 0.630300 +51147.618800 0.643900 +54163.379700 0.647900 +57179.140600 0.645000 +60194.901600 0.642200 +63210.662500 0.648400 +69002.991800 0.655800 +77571.889500 0.659200 +86140.787100 0.649900 +94709.684800 0.640300 +103278.582400 0.675100 +113960.257800 0.682000 +127432.898400 0.691200 +142193.531200 0.691900 +157442.937500 0.686900 +172714.281200 0.687000 +188320.218800 0.689900 +204392.218800 0.681800 +221300.218800 0.684600 +239779.281200 0.684200 +260790.500000 0.680400 +284605.312500 0.673400 +310978.187500 0.674600 +341455.000000 0.662800 +380790.156200 0.658300 +435189.375000 0.652200 +550179.007800 0.641500 +800000.000000 0.641500 +-2 0.000000E+00 +-2 1.000000E+00 +-1 diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.trans.jet.BDT.root b/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.trans.jet.BDT.root new file mode 100644 index 0000000000000000000000000000000000000000..ba5ba57ee1a7f5b1c813237fd7d1f4b5b229d167 Binary files /dev/null and b/PhysicsAnalysis/TauID/TauDiscriminant/share/sig.trans.jet.BDT.root differ diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauBits.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauBits.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3f2bc8cf305d2bddeb6e5cee162157c24ec359ec --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauBits.cxx @@ -0,0 +1,5 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/FakeTauBits.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauScores.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauScores.cxx new file mode 100644 index 0000000000000000000000000000000000000000..51c598358cd77979d2d9215bf51ef2c79e3a1321 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/FakeTauScores.cxx @@ -0,0 +1,5 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/FakeTauScores.h" diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCuts.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCuts.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f0aa40e04f832119c6e014bc17d66eeb0104eb27 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCuts.cxx @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/TauCuts.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +// #include "tauEvent/TauPID.h" +// #include "tauEvent/TauJetParameters.h" +#include "xAODTau/TauDefs.h" +#include <PathResolver/PathResolver.h> + +using namespace xAOD; +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauCuts::prepare(const TauDetailsManager& manager) +{ + m_cutsManager = new MethodCuts("TauCuts"); + m_cutsManager->setDetails(manager); + + string cutsPath = PathResolver::find_file(m_fileName, "DATAPATH"); + + if ( !m_cutsManager->build(cutsPath) ) { + ATH_MSG_FATAL("unable to build cuts manager"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauCuts::finalize() +{ + delete m_cutsManager; + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauCuts::execute(xAOD::TauJet* tau, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ + bool loose(false), medium(false), tight(false); + + if (tau->nTracks() > 0) + { + loose = m_cutsManager->response(0); + medium = m_cutsManager->response(1); + tight = m_cutsManager->response(2); + } + +// Analysis::TauPID *p_tauid = tau->tauID(); + + tau->setIsTau(TauJetParameters::TauCutLoose, loose); + tau->setIsTau(TauJetParameters::TauCutMedium, medium); + tau->setIsTau(TauJetParameters::TauCutTight, tight); + + // Verbose messaging for extra info + if (msgLvl(MSG::VERBOSE)) + { + if (!((!loose && !medium && !tight) || (loose && !medium && !tight) || (loose && medium && !tight) || (loose && medium && tight))) + { + msg(MSG::VERBOSE) << "Bad cuts!" << endreq; + } + msg(MSG::VERBOSE) << "TauCutLoose: " << tau->isTau(TauJetParameters::TauCutLoose) << endreq; + msg(MSG::VERBOSE) << "TauCutMedium: " << tau->isTau(TauJetParameters::TauCutMedium) << endreq; + msg(MSG::VERBOSE) << "TauCutTight: " << tau->isTau(TauJetParameters::TauCutTight) << endreq; + } + + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCutsEleVeto.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCutsEleVeto.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6eff019da595f64eebd9491680288ea11eff4ba0 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauCutsEleVeto.cxx @@ -0,0 +1,206 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/TauCutsEleVeto.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +// #include "tauEvent/TauPID.h" +// #include "tauEvent/TauJetParameters.h" +#include "xAODTau/TauDefs.h" +#include "TauDiscriminant/TauDetails.h" +#include <PathResolver/PathResolver.h> + +using namespace xAOD; + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauCutsEleVeto::prepare(const TauDetailsManager& manager) +{ + this->detailsManager = &manager; + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauCutsEleVeto::finalize() +{ + return StatusCode::SUCCESS; +} +/* Cut-based electron veto implementation + * + * + * returns false if it a tau + * true if it is an electron candidate + * This function can also work on D3PD-level: + * input D3PD variables: ****************************************************** + * eta : tau_seedCalo_track_eta (track with highest tau_seedCalo_track_pt) + * TrkAvgDist: tau_seedCalo_trkAvgDist + * HoP : tau_seedCalo_etHadAtEMScale/tau_leadTrkPt + * EoP : tau_seedCalo_etEMAtEMScale/tau_leadTrkPt + * TrtRatio : tau_calcVars_TRTHTOverLT_LeadTrk + * **************************************************************************** + * Usage: + * tauElectronVeto(float eta, float TrkAvgDist, float HoP, + * float EoP, float TrtRatio, int qual) + * qual: loose, medium, tight or tighter + * returns true if the object is identified as an electron by the algorithm + * ATLAS tauWG supported points: loose, medium and tight, tighter is for test + * purposes + * + * Changes since the last release (12 May 2011) + * + * eta range changed: central taus were defined 0.0-1.7 now 0.0-2.0 + * variables replaced: + * OLD VARIABLE (ATHENA REL16) -> NEW VARIABLE (ATHENA REL17) + * tau_seedTrk_secMaxStripEt -> tau_seedCalo_trkAvgDist + * tau_seedTrk_hadLeakEt -> tau_seedCalo_etHadAtEMScale/tau_leadTrkPt + * tau_seedTrk_sumEMCellEtOverLeadTrkPt -> tau_seedCalo_etEMAtEMScale/tau_leadTrkPt + * **************************************************************************** + * nikolaos.rompotis at cern.ch - 6 Oct 2011 + * + */ +bool tauElectronVeto(float eta, float TrkAvgDist, float HoP, + float EoP, float TrtRatio, int qual) { + float TrkAvgDist_C0, HoP_C0, EoP_C0, TrtRatio_C0a, TrtRatio_C0b, TrtRatio_C0c; + float HoP_C1, EoP_C1; + + // define the cut values ............. + if (qual == 0) { + TrkAvgDist_C0= 0.026; + HoP_C0 = 0.060; + EoP_C0 = 0.868; + TrtRatio_C0a = 0.227; + TrtRatio_C0b = 0.108; + TrtRatio_C0c = 0.151; + + HoP_C1 = 0.088; + EoP_C1 = 0.102; + } + else if (qual == 1) { + TrkAvgDist_C0= 0.051; + HoP_C0 = 0.090; + EoP_C0 = 0.812; + TrtRatio_C0a = 0.162; + TrtRatio_C0b = 0.069; + TrtRatio_C0c = 0.097; + + HoP_C1 = 0.195; + EoP_C1 = 1.076; + } + else if (qual == 2) { + TrkAvgDist_C0= 0.096; + HoP_C0 = 0.035; + EoP_C0 = 0.104; + TrtRatio_C0a = 0.107; + TrtRatio_C0b = 0.254; + TrtRatio_C0c = 0.085; + + HoP_C1 = 0.301; + EoP_C1 = 2.550; + + } + else if (qual == 3) { + TrkAvgDist_C0= 0.096; + HoP_C0 = 0.066; + EoP_C0 = 0.103; + TrtRatio_C0a = 0.098; + TrtRatio_C0b = 0.708; + TrtRatio_C0c = 0.056; + + HoP_C1 = 0.560; + EoP_C1 = 1.582; + } + else { + std::cout << "No such option for qual=" << qual << endl; + return false; + } + + if (qual == 1) { + if (tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 0)) + return true; + } + else if (qual == 2) { + if (tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 1)) + return true; + } + else if (qual == 3) { // tighter is defined also wrt to the medium + if (tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 2)) + return true; + } + + // ................................... + if ( fabs(eta) < 2.0 ) { // central taus + // + if (HoP > HoP_C0) { + if ( TrtRatio <= TrtRatio_C0a) return false; + else return true; + } + else { + if (TrkAvgDist > TrkAvgDist_C0) { + if (TrtRatio <= TrtRatio_C0b) return false; + else return true; + } + else { + if (TrtRatio <= TrtRatio_C0c && EoP <= EoP_C0) return false; + else return true; + } + } + } + else { // forward taus + if (HoP > HoP_C1) return false; + else { + if (EoP <= EoP_C1) return false; + else return true; + } + } +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauCutsEleVeto::execute(xAOD::TauJet* tau, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ + + if (!detailsManager) + { + return StatusCode::FAILURE; + } + bool loose(false), medium(false), tight(false); + // demand exactly 1 track and calo or calo+track driven tau + if (tau->nTracks() == 1) + { +// const Analysis::TauCommonDetails* commonDetails(tau->details<Analysis::TauCommonDetails>()); + float etHadAtEMScale; + tau->detail(TauJetParameters::etHadAtEMScale,etHadAtEMScale); + float etEMAtEMScale; + tau->detail(TauJetParameters::etEMAtEMScale,etEMAtEMScale); + float lcScale = 1; + if(this->useLCscale) tau->detail(TauJetParameters::LC_TES_precalib,lcScale); + + float eta = tau->track(0)->eta();//detailsManager->getFloatDetailValue(Details::ABS_ETA_LEAD_TRACK); + float TrkAvgDist = detailsManager->getFloatDetailValue(Details::TRKAVGDIST); + float leadTrkPt = tau->track(0)->pt(); + float HoP = leadTrkPt!=0?etHadAtEMScale*lcScale/leadTrkPt:0; + float EoP = leadTrkPt!=0?etEMAtEMScale*lcScale/leadTrkPt:0; + //float HoP = detailsManager->getFloatDetailValue(Details::ETHADATEMSCALE)/leadTrkPt; + //float EoP = detailsManager->getFloatDetailValue(Details::ETEMATEMSCALE)/leadTrkPt; + float TrtRatio = detailsManager->getFloatDetailValue(Details::TRT_NHT_OVER_NLT); + + loose = tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 0); + medium = tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 1); + tight = tauElectronVeto(eta, TrkAvgDist, HoP, EoP, TrtRatio, 2); + } + +// Analysis::TauPID *p_tauid = tau->tauID(); + + tau->setIsTau(TauJetParameters::ElectronVetoLoose, loose); + tau->setIsTau(TauJetParameters::ElectronVetoMedium, medium); + tau->setIsTau(TauJetParameters::ElectronVetoTight, tight); + + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDetailsManager.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDetailsManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6b7401df7d2897aa585fc603a250651a5b4cd52e --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDetailsManager.cxx @@ -0,0 +1,441 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: TauDetailsManager.cxx + * + * Author: Noel Dawe (end1@sfu.ca) + */ + +#include <iostream> + +#include "TauDiscriminant/TauDetailsManager.h" +#include "TauDiscriminant/TauPi0Clusters.h" +#include <utility> + +#include "xAODTau/TauJet.h" +#include "xAODTracking/TrackParticle.h" +// #include "TrkTrackSummary/TrackSummary.h" +#include "xAODTracking/VertexContainer.h" +#include "TrkEventPrimitives/VertexType.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODCaloEvent/CaloCluster.h" +#include "FourMomUtils/P4Helpers.h" +#include "AnalysisUtils/AnalysisMisc.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "CaloUtils/CaloVertexedCluster.h" + +// redefine the macro to print strings instead of enums as in TauDetails.h +#undef ENUM_OR_STRING +#define ENUM_OR_STRING( x ) #x + +using CLHEP::GeV; +using namespace std; +using namespace xAOD; + +// Arrays of the string representations of the detail names +namespace Details { +string IntTauDetailString[] = { INT_TAU_DETAILS }; +string FloatTauDetailString[] = { FLOAT_TAU_DETAILS }; +string IntEventDetailString[] = { INT_EVENT_DETAILS }; +string FloatEventDetailString[] = { FLOAT_EVENT_DETAILS }; +} + +// The default value for all details +const float TauDetailsManager::LOW_NUMBER = -1111.; + +TauDetailsManager::TauDetailsManager(StoreGateSvc* storeGateSvc, bool isTrigger) +{ + this->storeGate = storeGateSvc; + this->doTrigger = isTrigger; + //hard-coded for a while + m_clusterCone = 0.2; + + // Initialize the vector containing the tau-based variables + this->float_data = vector<float>(Details::__FloatTauDetail__END__ + 1,LOW_NUMBER); + this->int_data = vector<int>(Details::__IntTauDetail__END__ + 1,int(LOW_NUMBER)); + + // Initialize the vector containing the event-based variables + this->float_event_data = vector<float>( Details::__FloatEventDetail__END__ + 1, LOW_NUMBER); + this->int_event_data = vector<int>(Details::__IntEventDetail__END__ + 1, int(LOW_NUMBER)); + + // Maps of the string representations to the addresses of the values in the above vectors + unsigned int i; + for (i = 0; i < this->float_data.size() - 1; ++i) { + this->float_details.insert( pair<string, float*>(Details::FloatTauDetailString[i], &this->float_data[i])); + } + for (i = 0; i < this->float_event_data.size() - 1; ++i) { + this->float_details.insert(pair<string, float*>(Details::FloatEventDetailString[i],&this->float_event_data[i])); + } + for (i = 0; i < this->int_data.size() - 1; ++i) { + this->int_details.insert( pair<string, int*>(Details::IntTauDetailString[i], &this->int_data[i])); + } + for (i = 0; i < this->int_event_data.size() - 1; ++i) { + this->int_details.insert( pair<string, int*>(Details::IntEventDetailString[i], &this->int_event_data[i])); + } +} + +bool TauDetailsManager::updateEvent() +{ + // Reset the buffers at the beginning of each event + this->float_event_data.assign(this->float_event_data.size(), LOW_NUMBER); + this->int_event_data.assign(this->int_event_data.size(), int(LOW_NUMBER)); + + if (this->storeGate && this->doTrigger) { + //vertex information not available at EF, thus use default values to get correct bin; also retrievin VertexContainer will crash for TrigTauDiscriminant + this->int_event_data[Details::NUMGOODVERTICES] = 1; + this->int_event_data[Details::NUM_PILEUP_AND_PRIMARY_VERTICES] = 1; + return true; + } else if (this->storeGate) { + const xAOD::VertexContainer* priVertices(0); + StatusCode sc = this->storeGate->retrieve(priVertices, "PrimaryVertices"); + if (sc.isFailure()) { + return false; + } + if (priVertices) { + this->int_event_data[Details::NUMVERTICES] = priVertices->size(); + + //Martin Flechl, Nov 16, 2010: calculate number of good vertices + int nGoodVtx(0); + int nPileupPrimaryVtx(0); + xAOD::VertexContainer::const_iterator vxIter = priVertices->begin(); + xAOD::VertexContainer::const_iterator vxIterEnd = priVertices->end(); + for (; vxIter != vxIterEnd; ++vxIter) { + if (!(*vxIter)) continue; + // FF, March 2014 + // attention: the lines below may work in Athena, but not in xAOD standalone mode, which is used for end-user analysis + /* + std::vector<Trk::VxTrackAtVertex*>* vxTrackAtVertex = (*vxIter)->vxTrackAtVertex(); + if (!vxTrackAtVertex) continue; + if ( vxTrackAtVertex->size() >= 4) nGoodVtx++; + + if ((vxTrackAtVertex->size() >= 4 && (*vxIter)->vertexType() == xAOD::VxType::PriVtx ) || \ + (vxTrackAtVertex->size() >= 2 && (*vxIter)->vertexType() == xAOD::VxType::PileUp ) ) nPileupPrimaryVtx++; + */ + + // this works also in xAOD standalone mode, however, did not checked if results are the same + int nTrackParticles = (*vxIter)->nTrackParticles(); + if (nTrackParticles >= 4) nGoodVtx++; + if ( (nTrackParticles >= 4 && (*vxIter)->vertexType() == xAOD::VxType::PriVtx) || + (nTrackParticles >= 2 && (*vxIter)->vertexType() == xAOD::VxType::PileUp) + ) + nPileupPrimaryVtx++; + + } + this->int_event_data[Details::NUMGOODVERTICES] = nGoodVtx; + this->int_event_data[Details::NUM_PILEUP_AND_PRIMARY_VERTICES] = nPileupPrimaryVtx; + } + } + return true; +} + +bool TauDetailsManager::setNpi0(xAOD::TauJet& tauJet, int nPi0) +{ + this->int_data[Details::TAU_PI0_N] = nPi0; + tauJet.setDetail(TauJetParameters::nPi0Topo, static_cast<int>(nPi0)); + + //ATH_MSG_VERBOSE("setting Npi0 = "<<nPi0); + //std::cout<<"setting Npi0 = "<<nPi0<<std::endl; + return true; +} + +// const version of TauDetailsManager::update +// calculate variables and store them only in internal memory +bool TauDetailsManager::update(const xAOD::TauJet& tauJet) +{ + // Reset the buffers before setting the variables of each tau + this->float_data.assign(this->float_data.size(), LOW_NUMBER); + this->int_data.assign(this->int_data.size(), int(LOW_NUMBER)); + + // there is no author flag currently + // so keeping for backward compatibility only + this->int_data[Details::AUTHOR] = 3; + + unsigned int numTrack(tauJet.nTracks()); + + //========================================================================================== + // get variables from tau EDM + //========================================================================================== + this->int_data[Details::CHARGE] = tauJet.charge(); + this->int_data[Details::NUMTRACK] = numTrack; + this->int_data[Details::NUMWIDETRACK] = tauJet.nWideTracks(); + + this->float_data[Details::ETA] = tauJet.eta(); + this->float_data[Details::ABS_ETA] = fabs(tauJet.eta()); + + this->float_data[Details::PHI] = tauJet.phi(); + this->float_data[Details::E] = tauJet.e(); + this->float_data[Details::ET] = tauJet.pt(); + this->float_data[Details::PT] = tauJet.pt(); + this->float_data[Details::M] = tauJet.m(); + + float etOverpTLeadTrk; + tauJet.detail(TauJetParameters::etOverPtLeadTrk, etOverpTLeadTrk); + this->float_data[Details::ETOVERPTLEADTRK] = etOverpTLeadTrk; + this->float_data[Details::PTLEADTRKOVERET] = etOverpTLeadTrk > 0 ? 1. / etOverpTLeadTrk : LOW_NUMBER; + + tauJet.detail(TauJetParameters::ipZ0SinThetaSigLeadTrk, this->float_data[Details::IPZ0SINTHETASIGLEADTRK]); + tauJet.detail(TauJetParameters::ipSigLeadTrk, this->float_data[Details::IPSIGLEADTRK]); + tauJet.detail(TauJetParameters::massTrkSys, this->float_data[Details::MASSTRKSYS]); + tauJet.detail(TauJetParameters::trkWidth2, this->float_data[Details::TRKWIDTH2]); + tauJet.detail(TauJetParameters::trFlightPathSig, this->float_data[Details::TRFLIGHTPATHSIG]); + + float etEflow = 0; + tauJet.detail(TauJetParameters::etEflow, etEflow); + this->float_data[Details::ETEFLOWOVERET] = (tauJet.pt() > 0) ? etEflow / tauJet.pt() : LOW_NUMBER; + + // this variable is not filled anymore by tauRec + //tauJet.detail(TauJetParameters::mEflow, this->float_data[Details::MEFLOW]); + + tauJet.detail(TauJetParameters::stripWidth2, this->float_data[Details::STRIPWIDTH2]); + tauJet.detail(TauJetParameters::EMRadius, this->float_data[Details::EMRADIUS]); + tauJet.detail(TauJetParameters::hadRadius, this->float_data[Details::HADRADIUS]); + tauJet.detail(TauJetParameters::isolFrac, this->float_data[Details::ISOLFRAC]); + tauJet.detail(TauJetParameters::centFrac, this->float_data[Details::CENTFRAC]); + tauJet.detail(TauJetParameters::nStrip, this->int_data[Details::NSTRIP]); + tauJet.detail(TauJetParameters::trkAvgDist, this->float_data[Details::TRKAVGDIST]); + + float etEMScale, etEMScale1, etEMScale2; + tauJet.detail(TauJetParameters::etEMAtEMScale, etEMScale1); + tauJet.detail(TauJetParameters::etHadAtEMScale, etEMScale2); + etEMScale = etEMScale1 + etEMScale2; + this->float_data[Details::EMFRACTIONATEMSCALE] = (etEMScale != 0) ? etEMScale1 / etEMScale : LOW_NUMBER; + + float emradius, hadradius; + tauJet.detail(TauJetParameters::EMRadius, emradius); + tauJet.detail(TauJetParameters::hadRadius, hadradius); + this->float_data[Details::CALRADIUS] = (etEMScale != 0) ? (etEMScale1 * emradius + etEMScale2 * hadradius) / etEMScale : LOW_NUMBER; + + // New cluster-based variables + tauJet.detail(TauJetParameters::lead2ClusterEOverAllClusterE, this->float_data[Details::LEAD2CLUSTEREOVERALLCLUSTERE]); + tauJet.detail(TauJetParameters::lead3ClusterEOverAllClusterE, this->float_data[Details::LEAD3CLUSTEREOVERALLCLUSTERE]); + tauJet.detail(TauJetParameters::caloIso, this->float_data[Details::CALO_ISO]); + tauJet.detail(TauJetParameters::caloIsoCorrected, this->float_data[Details::CALO_ISO_CORRECTED]); + + // Topocluster variables: + tauJet.detail(TauJetParameters::topoInvMass, this->float_data[Details::TOPOINVMASS]); + tauJet.detail(TauJetParameters::effTopoInvMass, this->float_data[Details::EFFTOPOINVMASS]); + + tauJet.detail(TauJetParameters::PSSFraction, this->float_data[Details::PSSFRACTION]); + tauJet.detail(TauJetParameters::ChPiEMEOverCaloEME, this->float_data[Details::CHPIEMEOVERCALOEME] ); + tauJet.detail(TauJetParameters::EMPOverTrkSysP, this->float_data[Details::EMPOVERTRKSYSP]); + + // get intermediate axis + TLorentzVector tauInterAxis = tauJet.p4(TauJetParameters::IntermediateAxis); + this->float_data[Details::INTERAXIS_ETA] = tauInterAxis.Eta(); + this->float_data[Details::INTERAXIS_PHI] = tauInterAxis.Phi(); + + // this variable is special: when TauDiscriminant is called first time, this variable is empty + // in case TauDiscriminant::TauDetailsManager is called after a full TauDiscriminant run or on a already full processed AOD/xAOD + // this variable is filled properly + this->float_data[Details::BDTJETSCORE] = tauJet.discriminant(TauJetParameters::BDTJetScore); + + + //========================================================================================== + // calculate now variables needed for TauID not calculated by tauRec + //========================================================================================== + const xAOD::Jet* pJetSeed = (*tauJet.jetLink()); + if (!pJetSeed) { + //ATH_MSG_WARNING("tau does not have jet seed"); + return StatusCode::SUCCESS; + } + + // JVF and PT_PILEUP + float pt_pileup = 0.; + if (!this->doTrigger) { + // jvf and sumPtTrk are now a vector and the old run1-type jvf value is stored in the 0-th element + // sumPtTrk is calculated wrt Vertices + std::vector<float> sumPtTrkvec; + std::vector<float> jvfvec; + + // ToDo: still need to check if the 500MeV threshold is correct + pJetSeed->getAttribute(xAOD::JetAttribute::SumPtTrkPt500, sumPtTrkvec); + pJetSeed->getAttribute(xAOD::JetAttribute::JVF, jvfvec); + + float jvf = 0.0; + float sumPtTrk = 0.0; + if (!jvfvec.empty() && !sumPtTrkvec.empty()) { + // ToDo: need to check if first vertex is the vertex we want to use here! + jvf = jvfvec[0]; + sumPtTrk = sumPtTrkvec[0]; + } else { + msg(MSG::WARNING) << "jvf value vector and/or sumPtTrk vector returned from seed jet is empty!" << endreq; + } + pt_pileup = (1.0 - jvf) * sumPtTrk; + this->float_data[Details::JVF] = jvf; + this->float_data[Details::PT_PILEUP] = pt_pileup; + } + + // track-based variables for pi0 counting and ele veto + if (numTrack > 0) { + // variables used by the cut-based e-veto + tauJet.detail(TauJetParameters::hadLeakEt, this->float_data[Details::HADLEAKET]); + tauJet.detail(TauJetParameters::sumEMCellEtOverLeadTrkPt, this->float_data[Details::SUMEMCELLETOVERLEADTRKPT]); + tauJet.detail(TauJetParameters::secMaxStripEt, this->float_data[Details::SECMAXSTRIPET]); + + // Used by cut-based eveto: + if (tauJet.track(0)) { + this->float_data[Details::ABS_ETA_LEAD_TRACK] = fabs( tauJet.track(0)->eta() ); + this->float_data[Details::TAU_ABSDELTAETA] = fabs( tauJet.track(0)->eta() - tauJet.eta() ); + this->float_data[Details::TAU_ABSDELTAPHI] = fabs( tauJet.track(0)->phi() - tauJet.phi() ); + this->float_data[Details::TAU_SEEDTRK_SECMAXSTRIPETOVERPT] = (tauJet.track(0)->pt() != 0) ? this->float_data[Details::SECMAXSTRIPET] / tauJet.track(0)->pt() : LOW_NUMBER; + // solve for E3 + float tau_sumETCellsLAr = this->float_data[Details::SUMEMCELLETOVERLEADTRKPT] * tauJet.track(0)->pt(); + float tau_sumEMCellET = etEMScale1; + float tau_E3 = tau_sumETCellsLAr - tau_sumEMCellET; + + // remove E3 + float tau_seedCalo_etHadAtEMScale_noE3 = etEMScale2 - tau_E3; + float tau_seedCalo_etEMAtEMScale_yesE3 = etEMScale1 + tau_E3; + + //calculate new EMFraction + this->float_data[Details::EMFRACTIONATEMSCALE_MOVEE3] = tau_seedCalo_etEMAtEMScale_yesE3 / (tau_seedCalo_etEMAtEMScale_yesE3 + tau_seedCalo_etHadAtEMScale_noE3); + } + + // for pi0 counting + float sumpT3Trk(0.); + float sumpT(0.); + float dRmin = -1 * LOW_NUMBER; + float dR; + + for (unsigned int i(0); i < numTrack; ++i) { + if (i < 3) sumpT3Trk += tauJet.track(i)->pt(); + sumpT += tauJet.track(i)->pt(); + dR = tauJet.p4().DeltaR(tauJet.track(i)->p4()); + if (dRmin > dR) dRmin = dR; + } + + this->float_data[Details::SUMPT3TRK] = sumpT3Trk; + this->float_data[Details::SUMPT] = sumpT; + this->float_data[Details::DRMIN] = dRmin; + tauJet.detail(TauJetParameters::dRmax, this->float_data[Details::DRMAX]); + + if (tauJet.pt() != 0) { + this->float_data[Details::SUMPT_OVER_ET] = sumpT / tauJet.pt(); + this->float_data[Details::SUMPT3TRK_OVER_ET] = sumpT3Trk / tauJet.pt(); + } + + if (sumpT3Trk != 0) { + this->float_data[Details::ETHAD_EM_OVER_SUMPT3TRK] = etEMScale2 / sumpT3Trk; + this->float_data[Details::ETEM_EM_OVER_SUMPT3TRK] = etEMScale1 / sumpT3Trk; + } + if (sumpT != 0) { + this->float_data[Details::ETHAD_EM_OVER_SUMPT] = etEMScale2 / sumpT; + this->float_data[Details::ETEM_EM_OVER_SUMPT] = etEMScale1 / sumpT; + } + + uint8_t numberOfTRTHighThresholdHits; + tauJet.track(0)->summaryValue(numberOfTRTHighThresholdHits, xAOD::numberOfTRTHighThresholdHits); + uint8_t numberOfTRTHits; + tauJet.track(0)->summaryValue(numberOfTRTHits, xAOD::numberOfTRTHits); + uint8_t numberOfTRTHighThresholdOutliers; + tauJet.track(0)->summaryValue(numberOfTRTHighThresholdOutliers, xAOD::numberOfTRTHighThresholdOutliers); + uint8_t numberOfTRTOutliers; + tauJet.track(0)->summaryValue(numberOfTRTOutliers, xAOD::numberOfTRTOutliers); + this->float_data[Details::TRT_NHT_OVER_NLT] = + (numberOfTRTHits + numberOfTRTOutliers) > 0 ? + float( numberOfTRTHighThresholdHits + numberOfTRTHighThresholdOutliers) / float(numberOfTRTHits + numberOfTRTOutliers) : LOW_NUMBER; + } + + //Pi0 Cluster finding variables + TauPi0Clusters tpc = TauPi0Clusters(tauJet); + + this->float_data[Details::PI0CL1_PT] = tpc.get_cl1_Pt(); + this->float_data[Details::PI0CL1_ETA] = tpc.get_cl1_Eta(); + this->float_data[Details::PI0CL1_PHI] = tpc.get_cl1_Phi(); + + this->float_data[Details::PI0CL2_PT] = tpc.get_cl2_Pt(); + this->float_data[Details::PI0CL2_ETA] = tpc.get_cl2_Eta(); + this->float_data[Details::PI0CL2_PHI] = tpc.get_cl2_Phi(); + + this->float_data[Details::VISTAU_PI0CL_PT] = tpc.get_tau_vis_Pt(); + this->float_data[Details::VISTAU_PI0CL_ETA] = tpc.get_tau_vis_Eta(); + this->float_data[Details::VISTAU_PI0CL_PHI] = tpc.get_tau_vis_Phi(); + this->float_data[Details::VISTAU_PI0CL_M] = tpc.get_tau_vis_M(); + this->float_data[Details::TAU_PI0_VISTAU_M] = tpc.get_tau_vis_M(); + this->float_data[Details::TAU_PTRATIO] = (tauJet.pt() != 0) ? tpc.get_tau_vis_Pt() / tauJet.pt() : LOW_NUMBER; + // this->int_data[Details::TAU_PI0_N] = 0; //this guy is set elsewhere + + // TRACK_ISO + float track_iso(0.); + for (unsigned int i_track(0); i_track < tauJet.nWideTracks(); ++i_track) { + track_iso += tauJet.wideTrack(i_track)->pt(); + } + this->float_data[Details::TRACK_ISO] = track_iso; + + //Corrected CENTRALITY FRACTION and FTRK + float centFrac; + tauJet.detail(TauJetParameters::centFrac, centFrac); + float corrFtrk = this->float_data[Details::PTLEADTRKOVERET]; + + int nVtx = this->int_event_data[Details::NUM_PILEUP_AND_PRIMARY_VERTICES]; + + if (nVtx != int(LOW_NUMBER) && !this->doTrigger) { + if (tauJet.pt() < 80 * GeV) + centFrac = centFrac + 0.003 * nVtx; + + if (corrFtrk != float(LOW_NUMBER)) + corrFtrk = corrFtrk + 0.003 * nVtx; + } + + this->float_data[Details::CORRCENTFRAC] = centFrac; + this->float_data[Details::CORRFTRK] = corrFtrk; + + return true; +} + +// non-const version of update +bool TauDetailsManager::update_with_edm(xAOD::TauJet& tauJet) +{ + // update first the internal storage of the DetailsManager and calculate variables + if (!this->update(tauJet)) return false; + + // update now the tau itself + tauJet.setDetail(TauJetParameters::ptRatioEflowTopo, static_cast<float>(this->float_data[Details::TAU_PTRATIO])); + tauJet.setDetail(TauJetParameters::mEflowTopo, static_cast<float>(this->float_data[Details::TAU_PI0_VISTAU_M])); + tauJet.setDetail(TauJetParameters::etEflowTopo, static_cast<float>(this->float_data[Details::VISTAU_PI0CL_PT])); + //nPi0 saved in TauDetailsManager::setPi0(int nPi0) method + return true; +} + +// Var Getters +const float* TauDetailsManager::getFloatDetailAddress(Details::FloatTauDetail detail) const +{ + return &this->float_data[detail]; +} + +const int* TauDetailsManager::getIntDetailAddress(Details::IntTauDetail detail) const +{ + return &this->int_data[detail]; +} + +const float* TauDetailsManager::getFloatDetailAddress(Details::FloatEventDetail detail) const +{ + return &this->float_event_data[detail]; +} + +const int* TauDetailsManager::getIntDetailAddress(Details::IntEventDetail detail) const +{ + return &this->int_event_data[detail]; +} + +float TauDetailsManager::getFloatDetailValue(Details::FloatTauDetail detail) const +{ + return this->float_data[detail]; +} + +int TauDetailsManager::getIntDetailValue(Details::IntTauDetail detail) const +{ + return this->int_data[detail]; +} + +float TauDetailsManager::getFloatDetailValue(Details::FloatEventDetail detail) const +{ + return this->float_event_data[detail]; +} + +int TauDetailsManager::getIntDetailValue(Details::IntEventDetail detail) const +{ + return this->int_event_data[detail]; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriBuilder.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..01a9407dccfc756e1285c848422bfc27fb517bdb --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriBuilder.cxx @@ -0,0 +1,209 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauDiscriBuilder.cxx +// package: PhysicsAnalysis/TauID/TauDiscriminant +// authors: M. Wolter, A. Kaczmarska, Noel Dawe +// date: 13 March 2008 +//----------------------------------------------------------------------------- + +#include "TauDiscriminant/TauDiscriBuilder.h" +#include "TauDiscriminant/TauDiscriToolBase.h" +#include "TauDiscriminant/FakeTauBits.h" +#include "TauDiscriminant/FakeTauScores.h" + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +#include "xAODTau/TauDefs.h" + +#include "AthenaBaseComps/AthMessaging.h" +#include "GaudiKernel/ListItem.h" +#include "StoreGate/StoreGateSvc.h" + +using namespace xAOD; +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +TauDiscriBuilder::TauDiscriBuilder( const std::string &name, + ISvcLocator * pSvcLocator ) : + AthAlgorithm( name, pSvcLocator ), + tauInputContainerName( "TauContainer" ), + tools( this ), //make tools private + manager(0) +{ + declareProperty( "container", tauInputContainerName ); + declareProperty( "tools", tools, "List of TauDiscriToolBase tools" ); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- +TauDiscriBuilder::~TauDiscriBuilder() +{ +} + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauDiscriBuilder::initialize() +{ + StatusCode sc = StatusCode::SUCCESS; + + this->manager = new TauDetailsManager(&*evtStore()); + + //------------------------------------------------------------------------- + // No tools allocated! + //------------------------------------------------------------------------- + if( this->tools.size() == 0 ) + { + return StatusCode::FAILURE; + } + + //------------------------------------------------------------------------- + // Allocate tools + //------------------------------------------------------------------------- + ToolHandleArray<TauDiscriToolBase>::iterator tool_it(this->tools.begin()); + ToolHandleArray<TauDiscriToolBase>::iterator tool_end(this->tools.end()); + ATH_MSG_INFO("------------------------------------"); + ATH_MSG_INFO("List of tools in execution sequence:"); + unsigned int tool_count(0); + + for(; tool_it != tool_end; ++tool_it ) + { + if( tool_it->retrieve().isFailure() ) + { + ATH_MSG_WARNING("Cannot find tool named <" << *tool_it << ">"); + } + else + { + ++tool_count; + ATH_MSG_INFO(tool_it->name()); + if( (*tool_it)->prepare(*this->manager).isFailure() ) + { + ATH_MSG_FATAL("Initialization failed in tool " << tool_it->name()); + return sc; + } + } + } + ATH_MSG_INFO("------------------------------------"); + + if(tool_count == 0) + { + ATH_MSG_ERROR("Did not allocate any tool!"); + return StatusCode::FAILURE; + } + return sc; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauDiscriBuilder::finalize() +{ + delete this->manager; + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauDiscriBuilder::execute() +{ + xAOD::TauJetContainer *tau_container; + const xAOD::TauJetContainer *const_tau_container; + StatusCode sc = evtStore()->retrieve(const_tau_container, this->tauInputContainerName); + + tau_container = const_cast<TauJetContainer *>(const_tau_container); + + if (sc.isFailure() || ! tau_container) + { + ATH_MSG_WARNING("No input tau container found!"); + sc = StatusCode::SUCCESS; + return sc; + } + ATH_MSG_VERBOSE("Processing input tau Container Name = " << this->tauInputContainerName); + + FakeTauBits* fakeBits(0); + FakeTauBitsContainer* fakeBitsContainer(new FakeTauBitsContainer()); + + FakeTauScores* fakeScores(0); + FakeTauScoresContainer* fakeScoresContainer(new FakeTauScoresContainer()); + + // Update event-based variables + if (!this->manager->updateEvent()) + { + ATH_MSG_WARNING("Updating event-based variables in TauDetailsManager failed! Do not trust discriminant outputs!"); + return StatusCode::SUCCESS; + } + + xAOD::TauJetContainer::iterator tau_it(tau_container->begin()); + xAOD::TauJetContainer::iterator tau_end(tau_container->end()); + + // Loop over tau's: + for (; tau_it != tau_end; ++tau_it) + { + if (!this->manager->update_with_edm(**tau_it)) + { + ATH_MSG_WARNING("Updating tau-based variables in TauDetailsManager failed! Do not trust discriminant outputs!"); + return StatusCode::SUCCESS; + } + + ATH_MSG_VERBOSE(*this->manager); + + fakeBits = new FakeTauBits(*tau_it); + fakeScores = new FakeTauScores(*tau_it); + + //----------------------------------------------------------------- + // Process the candidate + //----------------------------------------------------------------- + ToolHandleArray<TauDiscriToolBase>::iterator tool_it(this->tools.begin()); + ToolHandleArray<TauDiscriToolBase>::iterator tool_end(this->tools.end()); + + //----------------------------------------------------------------- + // Loop stops when Failure indicated by one of the tools + //----------------------------------------------------------------- + for(; tool_it != tool_end; ++tool_it ) + { + ATH_MSG_VERBOSE("Invoking tool " << tool_it->name()); + sc = (*tool_it)->execute( *tau_it, fakeBits, fakeScores); + if( sc.isFailure() ) + { + ATH_MSG_FATAL("Execute failed in tool " << tool_it->name()); + return sc; + } + // TEMPORARY HACK + ATH_MSG_VERBOSE("Tool name: "<<tool_it->name()); + if(tool_it->name() == "TauPi0BDT") + { + ATH_MSG_VERBOSE("HACK FOR NPI0S"); + float Primary = fakeScores->getScore(TauScore::BDT_PI0_PRIMARY); + float Secondary = fakeScores->getScore(TauScore::BDT_PI0_SECONDARY); + int nPi0s = 0; + if (Primary < 0.465) nPi0s += 1; + if (Secondary < 0.565) nPi0s += 1; + + this->manager->setNpi0(**tau_it,nPi0s); + } + ATH_MSG_VERBOSE(*this->manager); + + } + fakeBitsContainer->push_back(fakeBits); + fakeScoresContainer->push_back(fakeScores); + } + + sc = evtStore()->record(fakeBitsContainer, "FakeTauBitsContainer", false); + if (sc.isFailure()) + { + ATH_MSG_WARNING("Could not record FakeTauBitsContainer in StoreGate!"); + return StatusCode::FAILURE; + } + sc = evtStore()->record(fakeScoresContainer, "FakeTauScoresContainer", false); + if (sc.isFailure()) + { + ATH_MSG_WARNING("Could not record FakeTauScoresContainer in StoreGate!"); + } + return sc; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriToolBase.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriToolBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8c2e574a6fea8e99a4ee2895bb4735b5ee7faf60 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauDiscriToolBase.cxx @@ -0,0 +1,14 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauDiscriToolBase.cxx +// package: TauDiscriminant +// authors: M. Wolter, A. Kaczmarska +// date: 13 March 2008 +//----------------------------------------------------------------------------- + +#include "TauDiscriminant/TauDiscriToolBase.h" + + diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauEleBDT.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauEleBDT.cxx new file mode 100644 index 0000000000000000000000000000000000000000..cd9576f04f68126ea9dd536ae40e9f0b5abea99b --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauEleBDT.cxx @@ -0,0 +1,209 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Tool for BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include "TauDiscriminant/TauEleBDT.h" +#include "TH2F.h" +#include <PathResolver/PathResolver.h> + +using namespace xAOD; + +StatusCode TauEleBDT::prepare(const TauDetailsManager& manager) +{ + if (this->eleBDTFile != "") + { + string eleBDTPath = PathResolver::find_file(this->eleBDTFile, "DATAPATH"); + if(eleBDTPath == "") + { + msg(MSG::FATAL) << "File: " << this->eleBDTFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->eleBDT = new MethodBDT("TauBDT:EleBDT"); + this->eleBDT->setDetails(manager); + + if (!this->eleBDT->build(eleBDTPath)) + { + msg(MSG::FATAL) << "Loading electron BDT file " << eleBDTPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + + if (this->eleBitsFile != "") + { + string eleBitsPath = PathResolver::find_file(this->eleBitsFile, "DATAPATH"); + if(eleBitsPath == "") + { + msg(MSG::FATAL) << "File: " << this->eleBitsFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->eleBits = new MethodCuts("TauBDT:EleBits"); + this->eleBits->setDetails(manager); + this->eleBits->addVariable("BDT",&(this->eleScore),'F'); + + if (!this->eleBits->build(eleBitsPath)) + { + msg(MSG::FATAL) << "Loading ele bits file " << eleBitsPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + if(this->eleBitsRootFile != ""){ + string eleBitsRootPath = PathResolver::find_file(this->eleBitsRootFile, "DATAPATH"); + if(eleBitsRootPath == "") + { + msg(MSG::FATAL) << "File: " << this->eleBitsRootFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + + this->cutsFile = new TFile(eleBitsRootPath.c_str()); + if(this->cutsFile){ + this->hloose = (TH2F*)this->cutsFile->Get("h2_BDTEleDecision_pteta_loose"); + this->hmedium = (TH2F*)this->cutsFile->Get("h2_BDTEleDecision_pteta_medium"); + this->htight = (TH2F*)this->cutsFile->Get("h2_BDTEleDecision_pteta_tight"); + } + + } + else + { + msg(MSG::FATAL) << "No BDT bits file was specified!" << endreq; + return StatusCode::FAILURE; + } + + + } + else + { + msg(MSG::FATAL) << "No BDTs were initialized!" << endreq; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode TauEleBDT::execute(xAOD::TauJet *tauJet, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ + +// Analysis::TauPID* tauJetID = tauJet->tauID(); + + // Initialize scores + tauJet->setDiscriminant(TauJetParameters::BDTEleScore, 0.); + + // Initialize bits + tauJet->setIsTau(TauJetParameters::EleBDTLoose, 0); + tauJet->setIsTau(TauJetParameters::EleBDTMedium, 0); + tauJet->setIsTau(TauJetParameters::EleBDTTight, 0); + + // do not assign a meaningful score for tau1P3P-only candidates. return. + + + // Set the response of the electron BDT + if (this->eleBDT) + { + this->eleScore = this->eleBDT->response(); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "BDTEleScore: " << this->eleScore << endreq; + } + if (this->eleScore < 0. || this->eleScore > 1.) + { + msg(MSG::ERROR) << "Error in computing BDTElecScore!" << endreq; + } + tauJet->setDiscriminant(TauJetParameters::BDTEleScore, this->eleScore); + } + + // if (this->eleBDT && this->eleBits) SL: comment out, set bits by hand + if (this->eleBDT) + { + + // SL: set bits by hand, do not use bits file + //tauJetID->setIsTau(TauJetParameters::EleBDTLoose, this->eleBits->response(0)); + //tauJetID->setIsTau(TauJetParameters::EleBDTMedium, this->eleBits->response(1)); + //tauJetID->setIsTau(TauJetParameters::EleBDTTight, this->eleBits->response(2)); + + if (tauJet->nTracks() == 1){ + double eta = fabs(tauJet->track(0)->eta()); + double pt = tauJet->pt(); + + if(!this->cutsFile) { + msg(MSG::ERROR)<<"Cannot open EleBDT cut file"<<endreq; + tauJet->setIsTau(TauJetParameters::EleBDTLoose, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTMedium, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTTight, 0 ); + + return StatusCode::SUCCESS; + } + + if(!hloose || !hmedium || !htight){ + msg(MSG::ERROR)<<"Cannot get EleBDT cut histograms"<<endreq; + tauJet->setIsTau(TauJetParameters::EleBDTLoose, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTMedium, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTTight, 0 ); + + + return StatusCode::SUCCESS; + + } + + if(pt/1000. > 799) pt = 799*1000.0; + if(eta > 2.99) eta = 2.99; + + float score_loose = hloose->GetBinContent(hloose->FindBin(pt/1000.,eta)); + bool failed_loose = this->eleScore < score_loose; + + float score_medium = hmedium->GetBinContent(hmedium->FindBin(pt/1000.,eta)); + bool failed_medium = this->eleScore < score_medium; + + float score_tight = htight->GetBinContent(htight->FindBin(pt/1000.,eta)); + bool failed_tight = this->eleScore < score_tight; + + tauJet->setIsTau(TauJetParameters::EleBDTLoose, failed_loose ); + tauJet->setIsTau(TauJetParameters::EleBDTMedium, failed_medium ); + tauJet->setIsTau(TauJetParameters::EleBDTTight, failed_tight ); + + + + + + + } + else if(tauJet->nTracks() > 1){ + tauJet->setIsTau(TauJetParameters::EleBDTLoose, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTMedium, 0 ); + tauJet->setIsTau(TauJetParameters::EleBDTTight, 0 ); + + + + } + + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "Passes ele loose: " << tauJet->isTau(TauJetParameters::EleBDTLoose) << endreq; + msg(MSG::VERBOSE) << "Passes ele medium: " << tauJet->isTau(TauJetParameters::EleBDTMedium) << endreq; + msg(MSG::VERBOSE) << "Passes ele tight: " << tauJet->isTau(TauJetParameters::EleBDTTight) << endreq; + } + } + + return StatusCode::SUCCESS; +} + +StatusCode TauEleBDT::finalize() +{ + if(this->cutsFile){ + this->cutsFile->Close(); + delete this->cutsFile; + //delete this->hloose; + //delete this->hmedium; + //delete this->htight; + } + + delete this->eleBDT; + delete this->eleBits; + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauJetBDT.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauJetBDT.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d532cab8ed4f434ae6a36adb39ddfdf568c224ed --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauJetBDT.cxx @@ -0,0 +1,245 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Tool for BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include "TauDiscriminant/TauJetBDT.h" + +using namespace xAOD; + +StatusCode TauJetBDT::prepare(const TauDetailsManager& manager) +{ + if (this->jetBDTFile != "") + { + string jetBDTPath = PathResolver::find_file(this->jetBDTFile, "DATAPATH"); + + if(jetBDTPath == "") + { + msg(MSG::FATAL) << "File: " << this->jetBDTFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->jetBDT = new MethodBDT("TauBDT:JetBDT"); + this->jetBDT->setDetails(manager); + + if (!this->jetBDT->build(jetBDTPath)) + { + msg(MSG::FATAL) << "Loading jet BDT file " << jetBDTPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + + if (this->jetSigBitsFile != "") + { + string jetSigBitsPath = PathResolver::find_file(this->jetSigBitsFile, "DATAPATH"); + if(jetSigBitsPath == "") + { + msg(MSG::FATAL) << "File: " << this->jetSigBitsFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->jetSigBits = new MethodCuts("TauBDT:JetSigBits"); + this->jetSigBits->setDetails(manager); + this->jetSigBits->addVariable("BDT",&(this->jetScore),'F'); + + if (!this->jetSigBits->build(jetSigBitsPath)) + { + msg(MSG::FATAL) << "Loading jet bits file " << jetSigBitsPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + + // Flat signal transformed jet score + if (this->jetSigTransFile != "") + { + string jetSigTransPath = PathResolver::find_file(this->jetSigTransFile, "DATAPATH"); + + if(jetSigTransPath == "") + { + msg(MSG::FATAL) << "File: " << this->jetSigTransFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->jetSigTrans = new MethodTransform("TauBDT:JetBDT:SignalTranform"); + this->jetSigTrans->setDetails(manager); + this->jetSigTrans->addVariable("BDT",&(this->jetScore),'F'); + + if (!this->jetSigTrans->build(jetSigTransPath)) + { + msg(MSG::FATAL) << "Loading jet BDT signal transformation file " << jetSigTransPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + + // Flat background transformed jet score + if (this->jetBkgTransFile != "") + { + string jetBkgTransPath = PathResolver::find_file(this->jetBkgTransFile, "DATAPATH"); + + if(jetBkgTransPath == "") + { + msg(MSG::FATAL) << "File: " << this->jetBkgTransFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->jetBkgTrans = new MethodTransform("TauBDT:JetBDT:BackgroundTranform"); + this->jetBkgTrans->setDetails(manager); + this->jetBkgTrans->addVariable("BDT",&(this->jetScore),'F'); + + if (!this->jetBkgTrans->build(jetBkgTransPath)) + { + msg(MSG::FATAL) << "Loading jet BDT background transformation file " << jetBkgTransPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + if (this->jetBkgBitsFile != "") + { + string jetBkgBitsPath = PathResolver::find_file(this->jetBkgBitsFile, "DATAPATH"); + if(jetBkgBitsPath == "") + { + msg(MSG::FATAL) << "File: " << this->jetBkgBitsFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->jetBkgBits = new MethodCuts("TauBDT:JetBkgBits"); + this->jetBkgBits->setDetails(manager); + this->jetBkgBits->addVariable("BDT",&(this->jetScore),'F'); + + if (!this->jetBkgBits->build(jetBkgBitsPath)) + { + msg(MSG::FATAL) << "Loading jet bits file " << jetBkgBitsPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + } + else + { + msg(MSG::FATAL) << "No BDTs were initialized!" << endreq; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode TauJetBDT::execute(xAOD::TauJet *tauJet, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ + +// Analysis::TauPID* tauJetID = tauJet->tauID(); + bool loose, medium, tight; + + // Initialize scores + tauJet->setDiscriminant(TauJetParameters::BDTJetScore, static_cast<float>(0.)); + tauJet->setDiscriminant(TauJetParameters::BDTJetScoreSigTrans, static_cast<float>(0.)); + tauJet->setDiscriminant(TauJetParameters::BDTJetScoreBkgTrans, static_cast<float>(0.)); + + // Initialize bits + tauJet->setIsTau(TauJetParameters::JetBDTSigLoose, false); + tauJet->setIsTau(TauJetParameters::JetBDTSigMedium, false); + tauJet->setIsTau(TauJetParameters::JetBDTSigTight, false); + + tauJet->setIsTau(TauJetParameters::JetBDTBkgLoose, false); + tauJet->setIsTau(TauJetParameters::JetBDTBkgMedium, false); + tauJet->setIsTau(TauJetParameters::JetBDTBkgTight, false); + + // do not assign a meaningful score for tau1P3P-only candidates. return. + + + // Set the response of the jet BDT + if (this->jetBDT) + { + + + this->jetScore = this->jetBDT->response(); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "BDTJetScore: " << this->jetScore << endreq; + } + if (this->jetScore < 0. || this->jetScore > 1.) + { + msg(MSG::ERROR) << "Error in computing BDTJetScore!" << endreq; + } + tauJet->setDiscriminant(TauJetParameters::BDTJetScore, this->jetScore); + } + else + { + tauJet->setDiscriminant(TauJetParameters::BDTJetScore, 0.); + } + + if (this->jetBDT && this->jetSigBits) + { + loose = this->jetSigBits->response(0); + medium = this->jetSigBits->response(1); + tight = this->jetSigBits->response(2); + tauJet->setIsTau(TauJetParameters::JetBDTSigLoose, loose); + tauJet->setIsTau(TauJetParameters::JetBDTSigMedium, medium); + tauJet->setIsTau(TauJetParameters::JetBDTSigTight, tight); + if (msgLvl(MSG::DEBUG)) + { + if (!((!loose && !medium && !tight) || (loose && !medium && !tight) || (loose && medium && !tight) || (loose && medium && tight))) + { + msg(MSG::VERBOSE) << "Bad bits!" << endreq; + } + msg(MSG::DEBUG) << "ET: " << tauJet->pt() << endreq; + msg(MSG::DEBUG) << "jet sig loose: " << tauJet->isTau(TauJetParameters::JetBDTSigLoose) << endreq; + msg(MSG::DEBUG) << "jet sig medium: " << tauJet->isTau(TauJetParameters::JetBDTSigMedium) << endreq; + msg(MSG::DEBUG) << "jet sig tight: " << tauJet->isTau(TauJetParameters::JetBDTSigTight) << endreq; + } + } + + if (this->jetSigTrans) + { + float jetSigTransScore(this->jetSigTrans->response()); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "Signal Transformed BDTJetScore: " << jetSigTransScore << endreq; + } + tauJet->setDiscriminant(TauJetParameters::BDTJetScoreSigTrans, jetSigTransScore); + } + + if (this->jetBkgTrans) + { + float jetBkgTransScore(this->jetBkgTrans->response()); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "Background Transformed BDTJetScore: " << jetBkgTransScore << endreq; + } + tauJet->setDiscriminant(TauJetParameters::BDTJetScoreBkgTrans, jetBkgTransScore); + } + + if (this->jetBDT && this->jetBkgBits) + { + loose = this->jetBkgBits->response(0); + medium = this->jetBkgBits->response(1); + tight = this->jetBkgBits->response(2); + tauJet->setIsTau(TauJetParameters::JetBDTBkgLoose, loose); + tauJet->setIsTau(TauJetParameters::JetBDTBkgMedium, medium); + tauJet->setIsTau(TauJetParameters::JetBDTBkgTight, tight); + if (msgLvl(MSG::VERBOSE)) + { + if (!((!loose && !medium && !tight) || (loose && !medium && !tight) || (loose && medium && !tight) || (loose && medium && tight))) + { + msg(MSG::VERBOSE) << "Bad bits!" << endreq; + } + msg(MSG::VERBOSE) << "ET: " << tauJet->pt() << endreq; + msg(MSG::VERBOSE) << "jet bkg loose: " << tauJet->isTau(TauJetParameters::JetBDTBkgLoose) << endreq; + msg(MSG::VERBOSE) << "jet bkg medium: " << tauJet->isTau(TauJetParameters::JetBDTBkgMedium) << endreq; + msg(MSG::VERBOSE) << "jet bkg tight: " << tauJet->isTau(TauJetParameters::JetBDTBkgTight) << endreq; + } + } + + return StatusCode::SUCCESS; +} + +StatusCode TauJetBDT::finalize() +{ + delete this->jetBDT; + delete this->jetSigBits; + delete this->jetBkgBits; + delete this->jetSigTrans; + delete this->jetBkgTrans; + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauLLH.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauLLH.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3b966a1ce7e24fa215b1db0d25ddabb87457dd18 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauLLH.cxx @@ -0,0 +1,85 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * file: TauLLH.cxx + * + * Author: Martin Flechl (mflechl@cern.ch) + * + */ + +#include "TauDiscriminant/TauLLH.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +// #include "tauEvent/TauPID.h" +// #include "tauEvent/TauJetParameters.h" +#include "xAODTau/TauDefs.h" +#include <PathResolver/PathResolver.h> + +using namespace xAOD; + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauLLH::prepare(const TauDetailsManager& manager) +{ + //defllh cannot be used yet + // m_defllh = new MethodLLH("llhdef"); + m_safellh = new MethodLLH("llhsafe"); + //m_safellh = new MethodLLH("llhsafe",true); + + // m_defllh->setDetails(this->manager); + m_safellh->setDetails(manager); + + std::string jetPDFPath = PathResolver::find_file(m_fileNameJetPDF, "DATAPATH"); + std::string tauPDFPath = PathResolver::find_file(m_fileNameTauPDF, "DATAPATH"); + std::string LMTCutsPath = PathResolver::find_file(m_fileNameLMTCuts, "DATAPATH"); + + + std::string fileNames=tauPDFPath+","+jetPDFPath+","+LMTCutsPath; + if ( !m_safellh->build(fileNames) ) { + ATH_MSG_FATAL("unable to build safe likelihood"); + return StatusCode::FAILURE; + } + + // set trigger flag + m_safellh->setDoTrigger(manager); + + return StatusCode :: SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauLLH :: finalize() +{ + // delete m_defllh; + delete m_safellh; + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauLLH::execute(xAOD::TauJet* tau, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ +// Analysis::TauPID *p_tauid = tau->tauID(); + + bool loose = m_safellh->response(0); + bool medium = m_safellh->response(1); + bool tight = m_safellh->response(2); + float value = m_safellh->response(3); + + //default llh value + tau->setIsTau(TauJetParameters::TauLlhLoose, loose); + tau->setIsTau(TauJetParameters::TauLlhMedium, medium); + tau->setIsTau(TauJetParameters::TauLlhTight, tight); + tau->setDiscriminant(TauJetParameters::Likelihood, value); + tau->setDiscriminant(TauJetParameters::SafeLikelihood, value); + + return StatusCode :: SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauMuonVeto.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauMuonVeto.cxx new file mode 100644 index 0000000000000000000000000000000000000000..845b0b4d866e1828141de98c7c0e766f609953da --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauMuonVeto.cxx @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TauDiscriminant/TauMuonVeto.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJet.h" +// #include "tauEvent/TauCommonDetails.h" +// #include "tauEvent/TauPID.h" +#include "xAODTau/TauDefs.h" +#include "TauDiscriminant/TauDetails.h" +#include <PathResolver/PathResolver.h> + +using namespace xAOD; +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauMuonVeto::prepare(const TauDetailsManager& manager) +{ + this->detailsManager = &manager; + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauMuonVeto::finalize() +{ + return StatusCode::SUCCESS; +} + +bool tauMuonVeto(int ntracks, float EMfrac, float ptEt, float eta) { + + if(ntracks != 1) return false; + if( (eta > -0.1 && eta < 0.1) || (eta > 1.15 && eta < 1.3) ){ + if(EMfrac < 0.15 && ptEt > 0.9) return true; + if(EMfrac > 0.80 && ptEt > 1.0) return true; + } + else { + if(EMfrac < 0.18 && ptEt > 1.9) return true; + if(EMfrac > 0.82 && ptEt < 0.12) return true; + } + return false; + +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauMuonVeto::execute(xAOD::TauJet* tau, FakeTauBits* /*bits*/, FakeTauScores* /*scores*/) +{ + if (!detailsManager) + { + return StatusCode::FAILURE; + } + + float ptEt = detailsManager->getFloatDetailValue(Details::PTLEADTRKOVERET); + float EMfrac = detailsManager->getFloatDetailValue(Details::EMFRACTIONATEMSCALE); + + int ntracks = tau->nTracks(); + float eta = tau->eta(); + + bool muVeto = tauMuonVeto(ntracks, EMfrac, ptEt, eta); + +// Analysis::TauPID *p_tauid = tau->tauID(); + + tau->setIsTau(TauJetParameters::MuonVeto, muVeto); + + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0BDT.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0BDT.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d11b75f17c040d7b4b95c1839d84fdeb80fc4523 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0BDT.cxx @@ -0,0 +1,107 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * Tool for pi0 BDT analysis. + * + * Author: Noel Dawe (Noel%dot%Dawe%at%cern%dot%ch) + */ + +#include "TauDiscriminant/TauPi0BDT.h" + +StatusCode TauPi0BDT::prepare(const TauDetailsManager& manager) +{ + // Primary pi0 BDT preparation + if (this->pi0BDTPrimaryFile != "") + { + string pi0BDTPrimaryPath = PathResolver::find_file(this->pi0BDTPrimaryFile, "DATAPATH"); + if(pi0BDTPrimaryPath == "") + { + msg(MSG::FATAL) << "File: " << this->pi0BDTPrimaryFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->pi0BDTPrimary = new MethodBDT("TauBDT:Pi0BDTPrimary"); + this->pi0BDTPrimary->addVariable("EMPOverTrkSysP", manager.getFloatDetailAddress(Details::EMPOVERTRKSYSP),'F'); + this->pi0BDTPrimary->addVariable("ChPiEMEOverCaloEME", manager.getFloatDetailAddress(Details::CHPIEMEOVERCALOEME),'F'); + this->pi0BDTPrimary->addVariable("PSSFraction", manager.getFloatDetailAddress(Details::PSSFRACTION),'F'); + this->pi0BDTPrimary->addVariable("EtOverPtLeadTrk", manager.getFloatDetailAddress(Details::ETOVERPTLEADTRK),'F'); + //this->pi0BDTPrimary->addVariable("mEflow", manager.getFloatDetailAddress(Details::MEFLOW),'F'); + this->pi0BDTPrimary->addVariable("nStrip", manager.getIntDetailAddress(Details::NSTRIP),'I'); + + + if (!this->pi0BDTPrimary->build(pi0BDTPrimaryPath)) + { + msg(MSG::FATAL) << "Loading primary pi0 BDT file " << pi0BDTPrimaryPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + + // Secondary pi0 BDT preparation + if (this->pi0BDTSecondaryFile != "") + { + string pi0BDTSecondaryPath = PathResolver::find_file(this->pi0BDTSecondaryFile, "DATAPATH"); + if(pi0BDTSecondaryPath == "") + { + msg(MSG::FATAL) << "File: " << this->pi0BDTSecondaryFile << " not found! " << endreq; + return StatusCode::FAILURE; + } + + this->pi0BDTSecondary = new MethodBDT("TauBDT:Pi0BDTSecondary"); + this->pi0BDTSecondary->addVariable("EMPOverTrkSysP", manager.getFloatDetailAddress(Details::EMPOVERTRKSYSP),'F'); + this->pi0BDTSecondary->addVariable("ChPiEMEOverCaloEME", manager.getFloatDetailAddress(Details::CHPIEMEOVERCALOEME),'F'); + this->pi0BDTSecondary->addVariable("PSSFraction", manager.getFloatDetailAddress(Details::PSSFRACTION),'F'); + this->pi0BDTSecondary->addVariable("EtOverPtLeadTrk", manager.getFloatDetailAddress(Details::ETOVERPTLEADTRK),'F'); + //this->pi0BDTSecondary->addVariable("mEflow", manager.getFloatDetailAddress(Details::MEFLOW),'F'); + this->pi0BDTSecondary->addVariable("nStrip", manager.getIntDetailAddress(Details::NSTRIP),'I'); + + if (!this->pi0BDTSecondary->build(pi0BDTSecondaryPath)) + { + msg(MSG::FATAL) << "Loading secondary pi0 BDT file " << pi0BDTSecondaryPath << " failed!" << endreq; + return StatusCode::FAILURE; + } + } + + if (!this->pi0BDTPrimary && !this->pi0BDTSecondary) + { + msg(MSG::FATAL) << "No BDTs were initialized!" << endreq; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BDT::execute(xAOD::TauJet* /*tauJet*/, FakeTauBits* /*bits*/, FakeTauScores* scores) +{ + // Get primary pi0 BDT score + if (this->pi0BDTPrimary && scores) + { + float pi0BDTPrimaryScore(this->pi0BDTPrimary->response()); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "Primary Pi0 BDT score: " << pi0BDTPrimaryScore << endreq; + } + scores->setScore(TauScore::BDT_PI0_PRIMARY, pi0BDTPrimaryScore); + } + + // Get secondary pi0 BDT score + if (this->pi0BDTSecondary && scores) + { + float pi0BDTSecondaryScore(this->pi0BDTSecondary->response()); + if (msgLvl(MSG::VERBOSE)) + { + msg(MSG::VERBOSE) << "Secondary Pi0 BDT score: " << pi0BDTSecondaryScore << endreq; + } + scores->setScore(TauScore::BDT_PI0_SECONDARY, pi0BDTSecondaryScore); + } + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BDT::finalize() +{ + delete this->pi0BDTPrimary; + delete this->pi0BDTSecondary; + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0Clusters.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0Clusters.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b496a1a05877d8fa2e191eeccfdd7017a97dd32f --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/TauPi0Clusters.cxx @@ -0,0 +1,185 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + /** + * file: TauPi0Clusters.cxx + * + * Author: Michel Trottier-McDonald (mtm@cern.ch) + */ + +#include "TauDiscriminant/TauPi0Clusters.h" +#include <utility> + +#include "xAODTau/TauJet.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTracking/TrackParticle.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODCaloEvent/CaloCluster.h" +#include "AnalysisUtils/AnalysisMisc.h" +#include "xAODTracking/VertexContainer.h" +#include "CLHEP/Geometry/Vector3D.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "CaloUtils/CaloVertexedCluster.h" + +#include <TLorentzVector.h> + +#include "math.h" + +//--------------------------------------------------------- +// Constructor +//--------------------------------------------------------- +TauPi0Clusters::TauPi0Clusters(const xAOD::TauJet& tauJet) : m_cl1_Pt(0.), + m_cl1_Eta(0.), + m_cl1_Phi(0.), + m_cl2_Pt(0.), + m_cl2_Eta(0.), + m_cl2_Phi(0.), + m_tau_vis_Pt(0.), + m_tau_vis_Eta(0.), + m_tau_vis_Phi(0.), + m_tau_vis_M(0.) +{ + runPi0Finder(tauJet); +} + + + + +//--------------------------------------------------------- +// run Pi0Finder +//--------------------------------------------------------- +void TauPi0Clusters::runPi0Finder(const xAOD::TauJet& tauJet) +{ + //Get tracks + int nTracks = tauJet.nTracks(); + std::vector<TLorentzVector> tracks; + + for(int i = 0; i < nTracks; ++i) + { + float track_Pt = tauJet.track(i)->pt(); + float track_Eta = tauJet.track(i)->eta(); + float track_Phi = tauJet.track(i)->phi(); + + if(track_Pt > 0.0 and track_Eta < 5.0) + { + TLorentzVector newTrack = TLorentzVector(); + newTrack.SetPtEtaPhiM(track_Pt, track_Eta, track_Phi, 0.0); + tracks.push_back(newTrack); + } + } + + + //Get clusters + + std::vector<const xAOD::CaloCluster*> Clusters; + + const xAOD::Jet* pJetSeed = (*tauJet.jetLink()); + xAOD::JetConstituentVector jcv = pJetSeed->getConstituents(); + + xAOD::JetConstituentVector::const_iterator firstcluster = jcv.begin(); + xAOD::JetConstituentVector::const_iterator lastcluster = jcv.end(); + + for ( ; firstcluster != lastcluster; firstcluster++ ) { + const xAOD::CaloCluster *p_cluster = dynamic_cast<const xAOD::CaloCluster*> ((*firstcluster)->rawConstituent()); //to get to cluster-specific variables + if (!p_cluster) continue; + Clusters.push_back(p_cluster); + } + + + + // now insert clusters into event ordered by energy + // this makes it much faster to recalculate cluster-based + // variables in macros later + + int nClusters = int(Clusters.size()); + + std::vector<TLorentzVector> clusters; + std::vector<float> PSSFs; + std::vector<float> EM2Fs; + std::vector<float> EM3Fs; + + if(nClusters > 0) + { + + AnalysisUtils::Sort::e (&Clusters); + + for(int i = 0; i < nClusters; ++i) + { + const xAOD::CaloCluster *p_cluster = Clusters[i]; + // Simplified Sampling information + float PreSampler = p_cluster->eSample(CaloSampling::PreSamplerB) + p_cluster->eSample(CaloSampling::PreSamplerE); + float EMLayer1 = p_cluster->eSample(CaloSampling::EMB1) + p_cluster->eSample(CaloSampling::EME1); + float EMLayer2 = p_cluster->eSample(CaloSampling::EMB2) + p_cluster->eSample(CaloSampling::EME2); + float EMLayer3 = p_cluster->eSample(CaloSampling::EMB3) + p_cluster->eSample(CaloSampling::EME3); + + float Energy = p_cluster->rawE(); + + float PSSF = (PreSampler + EMLayer1)/Energy; + float EM2F = EMLayer2/Energy; + float EM3F = EMLayer3/Energy; + + if(PSSF < 0.) PSSF = 0.; + if(PSSF > 1.) PSSF = 1.; + + if(EM2F < 0.) EM2F = 0.; + if(EM2F > 1.) EM2F = 1.; + + if(EM3F < 0.) EM3F = 0.; + if(EM3F > 1.) EM3F = 1.; + + xAOD::CaloVertexedCluster* clusterCorr; + if (tauJet.vertexLink()) { + // Corrected cluster direction information (leave as jet constituents on purpose!) + clusterCorr = new xAOD::CaloVertexedCluster(*p_cluster, (*tauJet.vertexLink())->position()); + } + else { + //no correction + clusterCorr = new xAOD::CaloVertexedCluster(*p_cluster); + } + + float cluster_Eta = clusterCorr->eta(); + float cluster_Pt = clusterCorr->e()/cosh(cluster_Eta); + float cluster_Phi = clusterCorr->phi(); + + if(cluster_Pt > 0.0 && cluster_Eta < 5.0) + { + TLorentzVector newCluster = TLorentzVector(); + newCluster.SetPtEtaPhiM(cluster_Pt, cluster_Eta, cluster_Phi, 0.0); + clusters.push_back(newCluster); + PSSFs.push_back(PSSF); + EM2Fs.push_back(EM2F); + EM3Fs.push_back(EM3F); + } + + // clean up corrected cluster + if (clusterCorr) delete clusterCorr; + + } + } + + if(nTracks > 0 && nClusters > 0) + { + + Pi0Finder pi0F = Pi0Finder(tracks, clusters, PSSFs, EM2Fs, EM3Fs); + TLorentzVector cl1 = pi0F.pi0TLV1(); + TLorentzVector cl2 = pi0F.pi0TLV2(); + TLorentzVector tau = pi0F.visTauTLV(); + + m_cl1_Pt = cl1.Pt(); + if(m_cl1_Pt > 0.0) + m_cl1_Eta = cl1.Eta(); + m_cl1_Phi = cl1.Phi(); + + m_cl2_Pt = cl2.Pt(); + if(m_cl2_Pt > 0.0) + m_cl2_Eta = cl2.Eta(); + m_cl2_Phi = cl2.Phi(); + + m_tau_vis_Pt = tau.Pt(); + if(m_tau_vis_Pt > 0.0) + m_tau_vis_Eta = tau.Eta(); + m_tau_vis_Phi = tau.Phi(); + m_tau_vis_M = tau.M(); + } +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_entries.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..a7d37c09dd0470c4425ee394bd30fd98bbbea1c1 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_entries.cxx @@ -0,0 +1,32 @@ +#include "TauDiscriminant/TauDiscriBuilder.h" +#include "TauDiscriminant/TauCutsEleVeto.h" +#include "TauDiscriminant/TauCuts.h" +#include "TauDiscriminant/TauLLH.h" +#include "TauDiscriminant/TauJetBDT.h" +#include "TauDiscriminant/TauEleBDT.h" +#include "TauDiscriminant/TauPi0BDT.h" +#include "TauDiscriminant/TauMuonVeto.h" +#include "GaudiKernel/DeclareFactoryEntries.h" + +DECLARE_ALGORITHM_FACTORY( TauDiscriBuilder ) + +DECLARE_TOOL_FACTORY( TauCutsEleVeto ) +DECLARE_TOOL_FACTORY( TauCuts ) +DECLARE_TOOL_FACTORY( TauLLH ) +DECLARE_TOOL_FACTORY( TauJetBDT ) +DECLARE_TOOL_FACTORY( TauEleBDT ) +DECLARE_TOOL_FACTORY( TauPi0BDT ) +DECLARE_TOOL_FACTORY( TauMuonVeto ) + +DECLARE_FACTORY_ENTRIES(TauDiscriminant) +{ + DECLARE_ALGORITHM( TauDiscriBuilder ) + + DECLARE_TOOL( TauCutsEleVeto ) + DECLARE_TOOL( TauCuts ) + DECLARE_TOOL( TauLLH ) + DECLARE_TOOL( TauJetBDT ) + DECLARE_TOOL( TauEleBDT ) + DECLARE_TOOL( TauPi0BDT ) + DECLARE_TOOL( TauMuonVeto ) +} diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_load.cxx b/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_load.cxx new file mode 100755 index 0000000000000000000000000000000000000000..e4cf8518b62a0cf004f4cfd7fbdd8bebcec77c6b --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/src/components/TauDiscri_load.cxx @@ -0,0 +1,3 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES(TauDiscriminant) diff --git a/PhysicsAnalysis/TauID/TauDiscriminant/svn-authors b/PhysicsAnalysis/TauID/TauDiscriminant/svn-authors new file mode 100644 index 0000000000000000000000000000000000000000..7614aaf23a6fee0db3b66a8d94b026b8d9142293 --- /dev/null +++ b/PhysicsAnalysis/TauID/TauDiscriminant/svn-authors @@ -0,0 +1,22 @@ +alibrari = Atlas Librarian <Atlas.Librarian@cern.ch> +end = Noel Dawe <Noel.Dawe@cern.ch> +felzmann = Ulrich Felzmann <ulif@unimelb.edu.au> +jgodfrey = Jennifer Godfrey <Jennifer.Lynn.Godfrey@cern.ch> +mflechl = Martin Flechl <Martin.Flechl@cern.ch> +reece = Ryan Reece <Ryan.Reece@cern.ch> +slai = Stan Lai <Stan.Lai@cern.ch> +wolter = Marcin Wolter <Marcin.Wolter@cern.ch> +derue = Frederic Derue <Frederic.Derue@cern.ch> +kojin = Koji Nakamura <Koji.Nakamura@cern.ch> +morgens = Marcus Morgenstern <marcus.morgenstern@tu-dresden.de> +felixf = Felix Friedrich <felix.friedrich@cern.ch> +pmalecki = Pawel Malecki <pawel.malecki@cern.ch> +mtm = Michel Trottier-McDonald <mta58@sfu.ca> +kongt = KG <tankg@unimelb.edu.au> +jkeller = John Stakely Keller <john.stakely.keller@cern.ch> +rompotis = Nikolaos Rompotis <nikolaos.rompotis@cern.ch> +sbedikia = Susie Bedikian <susie.bedikian@cern.ch> +simonyan = Margar Simonyan <Margar.Simonyan@cern.ch> +apingel = Almut Pingel <almut.pingel@cern.ch> +wahrmund = Unknown Unknown <Unknown@cern.ch> +droussea = David Rousseau <rousseau@lal.in2p3.fr>