diff --git a/Reconstruction/tauRec/cmt/requirements b/Reconstruction/tauRec/cmt/requirements new file mode 100755 index 0000000000000000000000000000000000000000..149e2b92bcc021d1e74f26ed272fffad11048c36 --- /dev/null +++ b/Reconstruction/tauRec/cmt/requirements @@ -0,0 +1,69 @@ +package tauRec + +author S. Rajagopalan <srinir@bnl.gov> + +public +use AtlasPolicy AtlasPolicy-* +use AthenaBaseComps AthenaBaseComps-* Control +use AthenaKernel AthenaKernel-* Control +use CxxUtils CxxUtils-* Control +use AtlasBoost AtlasBoost-* External +use AtlasROOT AtlasROOT-* External +use CaloInterface CaloInterface-* Calorimeter +use CaloUtils CaloUtils-* Calorimeter +use AthLinks AthLinks-* Control +use GaudiInterface GaudiInterface-* External +use ITrackToVertex ITrackToVertex-* Reconstruction/RecoTools +#use JetMomentTools JetMomentTools-* Reconstruction/Jet +use JetEDM JetEDM-* Reconstruction/Jet +use Particle Particle-* Reconstruction +use ParticleEvent ParticleEvent-* PhysicsAnalysis/AnalysisCommon +use tauEvent tauEvent-* Reconstruction +use xAODTau xAODTau-* Event/xAOD +use xAODJet xAODJet-* Event/xAOD +use xAODTracking xAODTracking-* Event/xAOD +use xAODCaloEvent xAODCaloEvent-* Event/xAOD +use xAODPFlow xAODPFlow-* Event/xAOD + +private +use AthContainers AthContainers-* Control +use CaloEvent CaloEvent-* Calorimeter +use EventKernel EventKernel-* Event +use CaloGeoHelpers CaloGeoHelpers-* Calorimeter +use AnalysisUtils AnalysisUtils-* PhysicsAnalysis/AnalysisCommon +use AtlasAIDA AtlasAIDA-* External +use AtlasCLHEP AtlasCLHEP-* External +use AtlasDetDescr AtlasDetDescr-* DetectorDescription +use CaloIdentifier CaloIdentifier-* Calorimeter +use EventInfo EventInfo-* Event +use FourMom FourMom-* Event +use FourMomUtils FourMomUtils-* Event +use NavFourMom NavFourMom-* Event +use InDetRecToolInterfaces InDetRecToolInterfaces-* InnerDetector/InDetRecTools +use JetEvent JetEvent-* Reconstruction/Jet +use PathResolver PathResolver-* Tools +use RecoToolInterfaces RecoToolInterfaces-* Reconstruction/RecoTools +use TrkParameters TrkParameters-* Tracking/TrkEvent +use TrkParticleBase TrkParticleBase-* Tracking/TrkEvent +use TrkTrackSummary TrkTrackSummary-* Tracking/TrkEvent +use TrkVertexFitterInterfaces TrkVertexFitterInterfaces-* Tracking/TrkVertexFitter +use TrkVertexFitters TrkVertexFitters-* Tracking/TrkVertexFitter +use TrkToolInterfaces TrkToolInterfaces-* Tracking/TrkTools +use TrkVxEdmCnv TrkVxEdmCnv-* Tracking/TrkVertexFitter +use TrkLinks TrkLinks-* Tracking/TrkEvent +use VxVertex VxVertex-* Tracking/TrkEvent +end_private + + +public + +#macro_append tauRec_shlibflags "-L$(ROOTSYS)/lib -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lm -ldl -lpthread -rdynamic" +macro_append ROOT_linkopts " -lTMVA" + +apply_pattern dual_use_library files="*.cxx *.c" + +apply_pattern declare_joboptions files="*.txt *.py" + +apply_pattern declare_runtime files="*.root *.dat *.xml" + +apply_pattern declare_python_modules files="*.py" diff --git a/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx new file mode 100644 index 0000000000000000000000000000000000000000..70934763f1a31ec6795fb083b71b7fb905c2edff --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.cxx @@ -0,0 +1,291 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: tau1p3pAddCaloInfo.cxx +// package: Reconstruction/tauRec +// authors: Lukasz Janyst, Anna Kaczmarska +// date: 2005-07-05 +// +// Tool to calculate identification variables (calo + tracking) +// +// MODIFIED: +// 11/09/2006 - (AK) correcting statusCode +// 08/10/2006 - (AK) change of detRCoreCaloCut, detRIsolCaloCut +// input parameters names +// 03/07/2009 - (AK) changing closest*TrkVertCell accessors to the "old-EDM" ones +//----------------------------------------------------------------------------- + +//TODO: revisit StatusCode + +#include <algorithm> +#include <math.h> +#include <sstream> + +#include "GaudiKernel/Property.h" + +#include "FourMom/P4EEtaPhiM.h" + +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloGeoHelpers/CaloSampling.h" + +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauCommonExtraDetails.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TauOriginCorrectionTool.h" + +#include "tauRec/TauEflowAddCaloInfo.h" + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauEflowAddCaloInfo::TauEflowAddCaloInfo(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_detRCoreCaloCut(0.2), +m_detRIsolCaloCut(0.4), +m_ETCellMinCut(100.0), +m_ETStripMinCut(200.0), +m_detaStripCut(0.2), +m_doCellCorrection(false), //FF: don't do cell correction by default +m_tauOriginCorrTool("") { + declareInterface<TauToolBase > (this); + + declareProperty("detRCoreCaloCut", m_detRCoreCaloCut); + declareProperty("detRIsolCaloCut", m_detRIsolCaloCut); + declareProperty("ETCellMinCut", m_ETCellMinCut); + declareProperty("ETStripMinCut", m_ETStripMinCut); + declareProperty("detaStripCut", m_detaStripCut); + declareProperty("CellCorrection", m_doCellCorrection); + declareProperty("OriginCorrectionTool", m_tauOriginCorrTool); + +} + + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauEflowAddCaloInfo::~TauEflowAddCaloInfo() { } + + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- + +StatusCode TauEflowAddCaloInfo::initialize() { + + ATH_MSG_VERBOSE(name() << " RconeTauCut = " << m_detRIsolCaloCut); + ATH_MSG_VERBOSE(name() << " RconeCoreCut = " << m_detRCoreCaloCut); + ATH_MSG_VERBOSE(name() << " ETCellMinCut = " << m_ETCellMinCut); + ATH_MSG_VERBOSE(name() << " ETStripMinCut = " << m_ETStripMinCut); + ATH_MSG_VERBOSE(name() << " detaStripCut = " << m_detaStripCut); + + if (m_tauOriginCorrTool.retrieve().isFailure()) { + ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">"); + return StatusCode::FAILURE; + } + ATH_MSG_VERBOSE("tau Origin Correction Tool <" << m_tauOriginCorrTool << "> retrieved"); + + return StatusCode::SUCCESS; +} + +StatusCode TauEflowAddCaloInfo::eventInitialize(TauCandidateData * /*data*/) +{ + if (m_doCellCorrection) { + // Cell Origin Correction Tool initializeEvent is not called automatically + // -> call from here + return m_tauOriginCorrTool->eventInitialize(); + } + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- + +StatusCode TauEflowAddCaloInfo::execute(TauCandidateData *data) { + + Analysis::TauJet *pTau = data->tau; + Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails); + + if (pTau->numTrack() == 0) { + ATH_MSG_VERBOSE("tau has no tracks -> skip EflowAddCaloInfo"); + return StatusCode::SUCCESS; + } + + if (!pDetails || !pExtraDetails) { + ATH_MSG_ERROR("TauCommon(Extra)Details object not valid"); + return StatusCode::FAILURE; + } + + StatusCode sc; + + + //----------------------------------------------------------------- + // Variable initialization + //----------------------------------------------------------------- + int nStrips = 0; + double sumETR02 = 0; + double sumETR01 = 0; + double sumET012 = 0; + double sumDetET012 = 0; + double stripEta = 0; + double stripEta2 = 0; + double stripET = 0; + double detPhi = 999.; + double detEta = 999.; + double detCell = 999.; + double sumETotherHAD = 0; + double sumETotherEM = 0; + double sumETchrgHAD = 0; + double stripWidth2 = 0; + double Rem = 0; + double fracETR12 = 0; + + //----------------------------------------------------------------- + // Loop on cells placed there by TauEflowTrackMatchCells + //----------------------------------------------------------------- + if (!pTau->cellCluster()) return StatusCode::FAILURE; + + //use tau vertex to correct cell position + if (m_doCellCorrection) { + m_tauOriginCorrTool->setOriginSource(pTau->origin()); + } + + const CaloCluster *pCluster = pTau->cellCluster(); + CaloCluster::cell_iterator cellItr = pCluster->cell_begin(); + CaloCluster::cell_iterator cellItrE = pCluster->cell_end(); + + const CaloCell *pCell; + + //loop on cells connected to object + for (; cellItr != cellItrE; ++cellItr) { + + pCell = (*cellItr); + + // correct cell for tau vertex + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + double cellPhi = pCell->phi(); + double cellEta = pCell->eta(); + double cellET = pCell->et(); + double cellEnergy = pCell->energy(); + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + + if (cellET < m_ETCellMinCut) continue; + + int sampling = pCell->caloDDE()->getSampling(); + if (sampling > 3 && sampling < 8) sampling = sampling - 4; + + int i = 2; + if (sampling < 4) i = sampling; + + const CaloCell* ccEta = pExtraDetails->closestEtaTrkVertCell(0, i); + const CaloCell* ccPhi = pExtraDetails->closestPhiTrkVertCell(0, i); + + if (ccPhi) { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, ccPhi->phi()); + } else { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(0)->phi()); + } + + if (ccEta) { + detEta = Tau1P3PKineUtils::deltaEta(cellEta, ccEta->eta()); + } else { + detEta = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(0)->eta()); + } + + detCell = Tau1P3PKineUtils::deltaR(detPhi, detEta); + + + //------------------------------------------------------------- + // Cuts + //------------------------------------------------------------- + if (detCell > m_detRIsolCaloCut) continue; + + if (detCell > m_detRCoreCaloCut) { + if (sampling > 3) { + sumETotherHAD += cellEnergy / cosh(cellEta); + } else { + sumETotherEM += cellET; + } + } + + if (detCell > m_detRCoreCaloCut) continue; + + if (sampling > 2) sumETchrgHAD += cellET; + + if (sampling == 1 && cellET > m_ETStripMinCut) { + const CaloCell* ccEta1 = *pExtraDetails->closestEtaTrkVertCell()[0][1]; + + detEta = Tau1P3PKineUtils::deltaEta(cellEta, ccEta1->eta()); + + if (std::fabs(detEta) < m_detaStripCut) { + ++nStrips; + } + } + + if (detCell < m_detRCoreCaloCut) sumETR02 += cellET; + + if (detCell < m_detRCoreCaloCut / 2.) sumETR01 += cellET; + + if (sampling > 2) continue; + + sumET012 += cellET; + sumDetET012 += cellET * detCell; + + if (sampling != 1) continue; + + stripEta += cellEta * cellET; + stripEta2 += cellEta * cellEta * cellET; + stripET += cellET; + } // end cell loop + + if (sumET012 > 0) Rem = sumDetET012 / sumET012; + + if (sumETR02 > 0) fracETR12 = (sumETR02 - sumETR01) / sumETR02; + + if (stripET > 0.0) stripWidth2 = (stripEta2 / stripET - stripEta * stripEta / stripET / stripET); + + + //----------------------------------------------------------------- + // Set properties + //----------------------------------------------------------------- + ATH_MSG_VERBOSE(name() << " taurec nStrips " << nStrips); + pDetails->setSeedTrk_nStrip(nStrips); + + ATH_MSG_VERBOSE(name() << " Rem " << Rem); + pDetails->setSeedTrk_EMRadius(Rem); + + ATH_MSG_VERBOSE(name() << " fracETR1 " << fracETR12); + pDetails->setSeedTrk_isolFrac(fracETR12); + + ATH_MSG_VERBOSE(name() << " stripWidth2 " << stripWidth2); + pDetails->setSeedTrk_stripWidth2(stripWidth2); + + ATH_MSG_VERBOSE(name() << " sumETotherHAD " << sumETotherHAD); + pDetails->setSeedTrk_etIsolHad(sumETotherHAD); + + ATH_MSG_VERBOSE(name() << " sumETotherEM " << sumETotherEM); + pDetails->setSeedTrk_etIsolEM(sumETotherEM); + + ATH_MSG_VERBOSE(name() << " sumETchrgHAD " << sumETchrgHAD); + pDetails->setSeedTrk_etChrgHad(sumETchrgHAD); + + return sc; + +} diff --git a/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..ae12b5802f3f12d3e1a97bafacb62034dc089a4b --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowAddCaloInfo.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUEFLOWADDCALOINFO_H +#define TAUREC_TAUEFLOWADDCALOINFO_H + +#include "tauRec/TauToolBase.h" + +class TauOriginCorrectionTool; + +/** + * @brief Calculate calorimeter variables and their distances to the leading tau track. + * + * Use cells placed there by TauEflowTrackMatchCells. + * This tool was formerly named as tau1p3pAddCaloInfo. + * + * @authors Lukasz Janyst, Anna Kaczmarska + * + */ + +class TauEflowAddCaloInfo : public TauToolBase { +public: + + TauEflowAddCaloInfo(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauEflowAddCaloInfo(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventInitialize(TauCandidateData *data); + + +private: + double m_detRCoreCaloCut; + double m_detRIsolCaloCut; + double m_ETCellMinCut; + double m_ETStripMinCut; + double m_detaStripCut; + + /** + * enable cell origin correction + * eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doCellCorrection; + ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool; + +}; + +#endif /* TAUREC_TAUEFLOWADDCALOINFO_H */ + diff --git a/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0df1ab35be2a5d0006da437f975c20504fa690d3 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.cxx @@ -0,0 +1,529 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: tau1p3pTrackMatchCells.cxx +// package: Reconstruction/tauRec +// authors: Tadeusz Szymocha, Anna Kaczmarska +// date: 2005-07-01 +// +// Tool for building CaloCluster of cells associated with +// a given track. +// +// MODIFIED: +// 08/10/2006 - (AK) change of m_RconeTauCut -> m_detRIsolCaloCut +// 18/03/2008 - (AK) changing cone for cell preselection 0.8->0.45 +// 11/04/2008 - (AK) moving select cone size to tool properties +// 30/06/2008 - (AK) (for MW) fix of memory leak +// 16/03/2010 - (AK) initialization of triggerFlag variable +// 17/03/2010 - (AK) change to P4Helpers +// 16/05/2010 - (FF) pointer p_measPer never used (coverity 22628) +//----------------------------------------------------------------------------- + +//TODO: change statuscode failure --> recoverable + +#include "tauRec/TauEflowTrackMatchCells.h" + +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauCommonExtraDetails.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TauOriginCorrectionTool.h" + +#include <CaloEvent/CaloCluster.h> +#include <CaloUtils/CaloClusterStoreHelper.h> +#include "CaloInterface/ICaloNoiseTool.h" +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCell.h" +#include "CaloIdentifier/CaloCell_ID.h" + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" + +#include <GaudiKernel/ListItem.h> +#include <algorithm> + +static void delete_cluster(std::pair<Analysis::TauJet * const, CaloCluster *> &pr) { + pr.first->cellClusterLink().reset(); + delete pr.second; +} + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauEflowTrackMatchCells::TauEflowTrackMatchCells(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_cellsContainerName("AllCalo"), +m_detRIsolCaloCut(0.4), +m_useNoiseSigma(1), +m_AbsNoiseSigma_cut(2), +m_selectConeSize(0.45), +m_doCellCorrection(false), //FF: don't do cell correction by default +m_tauOriginCorrTool("") { + declareInterface<TauToolBase > (this); + + declareProperty("CellsContainerName", m_cellsContainerName); + // declare large fixed cone for creating subcollection of cells (cluster) + declareProperty("detRIsolCaloCut", m_detRIsolCaloCut); + // declare options for noise/weighting + declareProperty("useNoiseSigma", m_useNoiseSigma); + declareProperty("AbsNoiseSigma_cut", m_AbsNoiseSigma_cut); + declareProperty("CaloNoiseTool", m_noiseTool, "Tool Handle for noise tool"); + declareProperty("ClusterContainerName", m_clusterContainerName = "Tau1P3PCellCluster"); + //ak + declareProperty("ClusterEMContainerName", m_clusterEMContainerName = "Tau1P3PCellEM012ClusterContainer"); + declareProperty("selectConeSize", m_selectConeSize); + declareProperty("CellCorrection", m_doCellCorrection); + declareProperty("OriginCorrectionTool", m_tauOriginCorrTool); +} + + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauEflowTrackMatchCells::~TauEflowTrackMatchCells() { +} + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- + +StatusCode TauEflowTrackMatchCells::initialize() { + ATH_MSG_VERBOSE(name() << " CellsContainerName = " << m_cellsContainerName); + ATH_MSG_VERBOSE(name() << " RconeTauCut = " << m_detRIsolCaloCut); + ATH_MSG_VERBOSE(name() << " selectConeSize = " << m_selectConeSize); + + //Create Noise Tools: + if (m_useNoiseSigma != 0) { + // SL changes to retrieval of CaloNoiseTool + if (m_noiseTool.retrieve().isFailure()) { + ATH_MSG_FATAL("Unable to retrieve CaloNoiseTool"); + return StatusCode::FAILURE; + } + } + + if (m_tauOriginCorrTool.retrieve().isFailure()) { + ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">"); + return StatusCode::FAILURE; + } + ATH_MSG_VERBOSE("tau Origin Correction Tool <" << m_tauOriginCorrTool << "> retrieved"); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Event Initializer +//----------------------------------------------------------------------------- + +StatusCode TauEflowTrackMatchCells::eventInitialize(TauCandidateData *) { + m_clusterMap.clear(); + + if (m_doCellCorrection) { + // Cell Origin Correction Tool initializeEvent is not called automatically + // -> call from here + return m_tauOriginCorrTool->eventInitialize(); + } + return StatusCode::SUCCESS; +} + + +//------------------------------------------------------------------------- +// Event Finalizer +//------------------------------------------------------------------------- + +StatusCode TauEflowTrackMatchCells::eventFinalize(TauCandidateData *data) { + + MsgStream rLog(msgSvc(), name()); + + StatusCode sc; + + //---------------------------------------------------------------------- + // Check if we're running in the trigger + //---------------------------------------------------------------------- + bool triggerFlag = false; + sc = data->getObject("InTrigger?", triggerFlag); + if (sc.isSuccess() && triggerFlag) { + //------------------------------------------------------------------ + // Delete all the clusters + //------------------------------------------------------------------ + std::for_each(m_clusterMap.begin(), m_clusterMap.end(), delete_cluster); + + Analysis::TauDetailsContainer *pCont = data->detailsContainer; + Analysis::TauDetailsContainer::iterator it1; + for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) { + Analysis::TauDetails *td = *it1; + Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td); + if (det) { + delete det->cellEM012Cluster(); + det->cellEM012ClusterLink().reset(); + } + } + return StatusCode::SUCCESS; + } + + //---------------------------------------------------------------------- + // Create cluster container + //---------------------------------------------------------------------- + CaloClusterContainer *clusterContainer = new CaloClusterContainer(); + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(), + // clusterContainer, + // m_clusterContainerName, + // rLog); + + //---------------------------------------------------------------------- + // Put all clusters in the container + //---------------------------------------------------------------------- + std::map<Analysis::TauJet *, CaloCluster *> ::iterator it; + for (it = m_clusterMap.begin(); it != m_clusterMap.end(); ++it) + clusterContainer->push_back((*it).second); + + //ak + std::sort(clusterContainer->begin(), clusterContainer->end(), OrderClust()); + + //--------------------------------------------------------------------- + // Record cluster container + //--------------------------------------------------------------------- + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(), + // clusterContainer, + // m_clusterContainerName, + // rLog); + + + //--------------------------------------------------------------------- + // Set up element links + //--------------------------------------------------------------------- + for (it = m_clusterMap.begin(); it != m_clusterMap.end(); ++it) + (*it).first->setCellCluster(clusterContainer, (*it).second); + + //---------------------------------------------------------------------- + // Create EM cluster container + //---------------------------------------------------------------------- + CaloClusterContainer *clusterEMContainer = new CaloClusterContainer(); + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(), + // clusterEMContainer, + // m_clusterEMContainerName, + // rLog); + + //---------------------------------------------------------------------- + // Put all clusters in the container + //---------------------------------------------------------------------- + Analysis::TauDetailsContainer *pCont = data->detailsContainer; + Analysis::TauDetailsContainer::iterator it1; + for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) { + Analysis::TauDetails *td = *it1; + Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td); + if (det) { + if (det->cellEM012Cluster()) { + clusterEMContainer->push_back(const_cast<CaloCluster *> (det->cellEM012Cluster())); + } + } + } + + //--------------------------------------------------------------------- + // Record cluster container + //--------------------------------------------------------------------- + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(), + // clusterEMContainer, + // m_clusterEMContainerName, + // rLog); + + //--------------------------------------------------------------------- + // Set up element links + //--------------------------------------------------------------------- + for (it1 = pCont->begin(); it1 != pCont->end(); ++it1) { + Analysis::TauDetails *td = *it1; + Analysis::TauCommonDetails *det = dynamic_cast<Analysis::TauCommonDetails *> (td); + if (det) { + if (det->cellEM012Cluster()) { + det->setCellEM012Cluster(clusterEMContainer, det->cellEM012Cluster()); + } + } + } + + return sc; +} + +//----------------------------------------------------------------------------- +// Cleanup, in case this candidate was rejected later +//----------------------------------------------------------------------------- + +void TauEflowTrackMatchCells::cleanup(TauCandidateData *data) { + + //------------------------------------------------------------------------- + // Cleanup cluster + //------------------------------------------------------------------------- + Analysis::TauJet *pTau = data->tau; + std::map<Analysis::TauJet *, CaloCluster *> ::iterator it; + it = m_clusterMap.find(pTau); + + if (it != m_clusterMap.end()) { + delete (*it).second; + m_clusterMap.erase(it); + } + + pTau->cellClusterLink().reset(); + + //------------------------------------------------------------------------- + // Cleanup EM012Cluster + //------------------------------------------------------------------------- + Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + if (pDetails) { + delete pDetails->cellEM012Cluster(); + pDetails->cellEM012ClusterLink().reset(); + } +} + + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- + +StatusCode TauEflowTrackMatchCells::execute(TauCandidateData *data) { + + // Analysis::TauJet *pTau = data->tau; + // Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + // Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails); + + // // + // if (pTau->numTrack()==0) { + // ATH_MSG_VERBOSE("tau has no tracks -> skip TrackMatchCells"); + // return StatusCode::SUCCESS; + // } + + // if ( !pDetails || !pExtraDetails) { + // ATH_MSG_ERROR("TauCommon(Extra)Details object not valid"); + // return StatusCode::FAILURE; + // } + + // StatusCode sc; + + + // //--------------------------------------------------------------------- + // // Retrieve CaloCellCollection from StoreGate + // //--------------------------------------------------------------------- + // const CaloCellContainer *pCellContainer; + + // sc = data->getObject("CellContainer", pCellContainer); + // if (sc.isFailure() || !pCellContainer) { + // sc = evtStore()->retrieve(pCellContainer, m_cellsContainerName); + // if (sc.isFailure()) { + // ATH_MSG_INFO("TrackMatchCells: Unable to retrieve " << m_cellsContainerName << " from TES"); + // } + // } + + // xAOD::CaloCluster *pCluster = CaloClusterStoreHelper::makeCluster(); + // xAOD::CaloCluster *pClusterEM = CaloClusterStoreHelper::makeCluster(); + + // //put cluster into object + // pTau->cellClusterLink().reset(); + // pTau->cellClusterLink().setElement(pCluster); + // m_clusterMap[pTau] = pCluster; + + // pDetails->cellEM012ClusterLink().reset(); + // pDetails->cellEM012ClusterLink().setElement(pClusterEM); + + // //--------------------------------------------------------------------- + // // Loop over cells collection and find closest cell at a given layer + // // from track impact point at vertex and propagated in magnetic field + // //--------------------------------------------------------------------- + + // const int nTr = 10; + // const int nSa = 4; + + // double detEtaCellMin[nTr][nSa], detPhiCellMin[nTr][nSa]; + // double detEtaCellMinCh[nTr][nSa], detPhiCellMinCh[nTr][nSa]; + // double detEtaVertMin[nSa], detPhiVertMin[4]; + + // const CaloCell * pTmpEtaCell[nTr][nSa]; + // const CaloCell * pTmpPhiCell[nTr][nSa]; + // const CaloCell * pTmpEtaVertCell[nSa]; + // const CaloCell * pTmpPhiVertCell[nSa]; + + + // for (int i = 0; i < nSa; ++i) { + // detEtaVertMin[i] = 9999.; + // detPhiVertMin[i] = 9999.; + + // pTmpEtaVertCell[i] = 0; + // pTmpPhiVertCell[i] = 0; + + // for (int j = 0; j < nTr; ++j) { + // detEtaCellMin[j][i] = 9999.; + // detPhiCellMin[j][i] = 9999.; + + // detEtaCellMinCh[j][i] = 9999.; + // detPhiCellMinCh[j][i] = 9999.; + + // pTmpEtaCell[j][i] = 0; + // pTmpPhiCell[j][i] = 0; + // } + // } + + // const CaloCell *pCell; + // pCell = 0; + + // /* FF: + // //do cell selection + // CaloCellList *celllist = new CaloCellList(pCellContainer); + // celllist->select(pTau->track(0)->eta(), pTau->track(0)->phi(), m_selectConeSize); + + // if (celllist->ncells() == 0) { + // delete celllist; + // return StatusCode::FAILURE; + // } + + // CaloCellList::list_iterator itr = celllist->begin(); + // CaloCellList::list_iterator itrE = celllist->end(); + // */ + + + // //use tau vertex to correct cell position + // if (m_doCellCorrection) { + // m_tauOriginCorrTool->setOriginSource(pTau->origin()); + // } + + // //FF: use cells already associated to jet seed + // // this is valid until m_selectConeSize is < or about 0.4 + // typedef NavigationToken<CaloCell, NavigationDefaults::DefaultWeight, CaloCellIDFcn> token_t; + // token_t nt; + // pTau->fillToken(nt); + + // token_t::const_iterator itr = nt.begin(); + // token_t::const_iterator itrE = nt.end(); + // // + + // //loop over cells and calculate the variables + // for (; itr != itrE; itr++) { + // pCell = *itr; + + // // correct cell for tau vertex + // if (m_doCellCorrection) { + // m_tauOriginCorrTool->correctCell(pCell); + // } + + // double cellPhi = pCell->phi(); + // double cellEta = pCell->eta(); + // double cellEnergy = pCell->energy(); + + // if (m_doCellCorrection) { + // m_tauOriginCorrTool->resetCell(pCell); + // } + + // double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi); + + // // collect all cells (remove noisy cells ) in a fixed + // // large cone around candidate (at vertex) + // if (detCell > m_detRIsolCaloCut) continue; + + // int isCellAccepted = 1; + + // if (m_useNoiseSigma == 1) { + // double noiseSigma; + // noiseSigma = m_noiseTool->getNoise(*itr, ICalorimeterNoiseTool::ELECTRONICNOISE_HIGHESTGAIN); + // if (fabs(cellEnergy) < m_AbsNoiseSigma_cut * noiseSigma) isCellAccepted = 0; + + // } + + // // add cells above the noise to the associated cluster + // if (isCellAccepted == 1) pCluster->addCell(pCellContainer, pCell, 1.0); + + // // find position nominal position of the closest cell at each layer + // int samp = CaloSampling::getSampling(*pCell); + // if (samp > 3 && samp < 8) samp = samp - 4; + + // //ak + // if (samp < 3 && isCellAccepted == 1) pClusterEM->addCell(pCellContainer, pCell, 1.0); + + // // consider only sampling < 4 + // if (samp >= 4) continue; + + // double detPhiVert = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->phi()); + // double detEtaVert = Tau1P3PKineUtils::deltaEta(cellEta, pTau->eta()); + + // if (detEtaVert < detEtaVertMin[samp]) { + // detEtaVertMin[samp] = detEtaVert; + // pTmpEtaVertCell[samp] = pCell; + // } + + // if (detPhiVert < detPhiVertMin[samp]) { + // detPhiVertMin[samp] = detPhiVert; + // pTmpPhiVertCell[samp] = pCell; + // } + + // //for each track connected to tau object + // for (unsigned itr = 0; itr < pTau->numTrack(); itr++) { + // // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + // if (itr >= 9) break; + + // double detEtaCell[nTr]; + // double detPhiCell[nTr]; + // detEtaCell[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][samp]); + // detPhiCell[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][samp]); + + // //FIX ME! Should we look for different cell in eta and + // //in phi? ot the closest one? + + // if (detEtaCell[itr] < detEtaCellMin[itr][samp]) { + // detEtaCellMin[itr][samp] = detEtaCell[itr]; + // pTmpEtaCell[itr][samp] = pCell; + // } + + // if (detPhiCell[itr] < detPhiCellMin[itr][samp]) { + // detPhiCellMin[itr][samp] = detPhiCell[itr]; + // pTmpPhiCell[itr][samp] = pCell; + // } + + // // for better collection of energy around charged track... + // // correct if possible and consider only + // // cells with really deposited energy + // if (isCellAccepted == 0) continue; + + // if (detEtaCell[itr] < detEtaCellMinCh[itr][samp]) { + // detEtaCellMinCh[itr][samp] = detEtaCell[itr]; + // pTmpEtaCell[itr][samp] = pCell; + // } + + // if (detPhiCell[itr] < detPhiCellMinCh[itr][samp]) { + // detPhiCellMinCh[itr][samp] = detPhiCell[itr]; + // pTmpPhiCell[itr][samp] = pCell; + // } + // } // end track loop + + // } // end cell loop + + // // loop over sampling + // for (int i = 0; i < 4; i++) { + // if (pTmpEtaVertCell[i]) pExtraDetails->setClosestEtaTrkVertCell(pTmpEtaVertCell[i], pCellContainer, 0, i); + // if (pTmpPhiVertCell[i]) pExtraDetails->setClosestPhiTrkVertCell(pTmpPhiVertCell[i], pCellContainer, 0, i); + + // for (unsigned itr = 0; itr < pTau->numTrack(); itr++) { + // // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + // if (itr >= 9) break; + // if (pTmpEtaCell[itr][i]) pExtraDetails->setClosestEtaTrkCell(pTmpEtaCell[itr][i], pCellContainer, itr, i); + // if (pTmpPhiCell[itr][i]) pExtraDetails->setClosestPhiTrkCell(pTmpPhiCell[itr][i], pCellContainer, itr, i); + // } + // } + + // //FF: + // //delete celllist; + + // return sc; + return StatusCode::SUCCESS; +} + + + + diff --git a/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h new file mode 100644 index 0000000000000000000000000000000000000000..824d2883e5e3259c68e27f75bf216e44e0f155dd --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowTrackMatchCells.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUEFLOWTRACKMATCHCELLS_H +#define TAUREC_TAUEFLOWTRACKMATCHCELLS_H + +#include <map> + +#include "GaudiKernel/ToolHandle.h" +#include "CaloInterface/ICalorimeterNoiseTool.h" +#include "CaloEvent/CaloClusterContainer.h" + +#include "tauRec/TauToolBase.h" + +class TauOriginCorrectionTool; + +/** + * @brief Tool for building CaloCluster of cells associated with a given tau. + * + * This tool was formerly named as tau1p3pTrackMatchCells. + * + * @authors Tadeusz Szymocha, Anna Kaczmarska + * + */ + +class TauEflowTrackMatchCells : public TauToolBase +{ + public: + + TauEflowTrackMatchCells(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauEflowTrackMatchCells(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + + virtual void cleanup(TauCandidateData *data); + + private: + std::string m_cellsContainerName; + std::string m_clusterContainerName; + + //! large fixed cone to collect cells around the track + double m_detRIsolCaloCut; + + //! use noise tool to estimate sigma + double m_useNoiseSigma; + + //! threshold to suppress noisy cells + double m_AbsNoiseSigma_cut; + + //! cone for cell pre-selection + double m_selectConeSize; + + //! tool for noise + ToolHandle <ICalorimeterNoiseTool> m_noiseTool; + + std::map<Analysis::TauJet *, CaloCluster *> m_clusterMap; + + std::string m_clusterEMContainerName; + + /** + * enable cell origin correction + * eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doCellCorrection; + ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool; + +}; + +//TODO: same as in CaloClusterVariables! --> move both to KinUtils.h? +//------------------------------------------------------------------------- +//! Descending order by energy +//------------------------------------------------------------------------- + +struct OrderClust +{ + bool operator()(const CaloCluster *t1, const CaloCluster * t2) const { + //FF:: don't need a warning here + //if (t1->et() == t2->et()) { + // std::cout << " tauRec:tau1p3pTrackMatchCells WARNING Found two clusters with the same et ! " << t1->et() << std::endl; + // } + return t1->et() < t2->et(); + } +}; + + +#endif diff --git a/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx b/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d999dd57e6919e29e9242b909b1f6d15938d305e --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowVariables.cxx @@ -0,0 +1,840 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: tau1p3pAddEflowInfo.cxx +// package: Reconstruction/tauRec +// authors: Tadeusz Szymocha, Anna Kaczmarska +// date: 2006-02-09 +// +// This tool builds energy flow quantities. +// +// MODIFIED: +// 07/10/2005 - (LJ) Proper deletion of Pi0 clusters +// 14/09/2006 - (LJ,AK) temporaty solution for removing cells +// from object in order to avoid problems with +// casting CaloCellContainer to +// INavigable4MomentumCollection +// 07/10/2005 - (LJ) Proper deletion of Pi0 clusters +// 08/10/2006 - (AK) change of RconeCoreCut parameter name +// fixing wrong reading of extrapolation point for +// endcap in fillTopoClusterInfo +// 03/11/2006 - (AK) added filling sumEM +// 07/11/2006 - (AK) preselection with cuts on MVisEflow, MTrk3P, ETeflow / ETcalo variables +// 24/11/2006 - (AK) correcting phi barycenter calculation +// 26/11/2006 - (ERW) corrected eflow calculation +// 13/07/2007 - (AK) dynamic allocation of arrays +// 23/04/2007 - (AK) adding writing pi0 container +// 10/07/2007 - (AK) allowing ntrack>3 candidates +// 19/06/2007 - (ERW) removing writting pi0 container -> delegated to tau1p3pCreatePi0Cluster.cxx +// 07/07/2007 - (ERW) removing filling sumEM -> delegated to tau1p3pCreatePi0Cluster.cxx +// 04/01/2008 - (AK) adding low cut on etcalo/etflow +// 10/06/2008 - (AK) fixing floating point exceptions (bug 37635) +// 30/09/2008 - (AK) memory fragmentation fixes (bug 41937) +// 09/10/2009 - (AK) correcting unchecked SC (bug 56754) +// 17/05/2011 - (FF) add initializer for array (line 276) (coverity 20321) +//----------------------------------------------------------------------------- + +//TODO: change statuscode failure to recoverable +//TODO: AllCalo hardcoded + +#include <algorithm> +#include <math.h> +#include <sstream> + +#include "GaudiKernel/Property.h" +#include "GaudiKernel/ListItem.h" +#include "GaudiKernel/IToolSvc.h" + +#include "FourMom/P4EEtaPhiM.h" + +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "CaloGeoHelpers/CaloPhiRange.h" + +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauCommonExtraDetails.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TauOriginCorrectionTool.h" +#include "tauRec/TauEflowVariables.h" + + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauEflowVariables::TauEflowVariables(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_detRCoreCaloCut(0.2), +m_dphiEMCLCut(0.0375), +m_detaEMCLCut(0.0375), +m_dphiEMCLFACCut(2), +m_detaEMCLFACCut(3), +m_dphiChrgEMCut(0.0375), +m_detaChrgEMCut(0.0375), +m_CaloClusterContainerName("EMTopoCluster"), +m_recoTopoClusterETCut(200.0), +m_recoEtaCut(2.5), +m_TrackTopoClusPhi2Cut(0.0375), +m_TrackTopoClusEta1Cut(0.01), +m_MVisEflowCut(10000), +m_MTrk3PCut(10000), +m_ETeflow_ETcaloCut(10.), +m_ETeflow_ETcaloCutMin(0.1), +m_maxClusterEta(4.0), +m_useEMTopoClusters(true), +m_doCellCorrection(false), //FF: don't do cell correction by default +m_tauOriginCorrTool("") { + declareInterface<TauToolBase > (this); + + declareProperty("detRCoreCaloCut", m_detRCoreCaloCut); + declareProperty("dphiEMCLCut", m_dphiEMCLCut); + declareProperty("detaEMCLCut", m_detaEMCLCut); + declareProperty("dphiEMCLFACCut", m_dphiEMCLFACCut); + declareProperty("detaEMCLFACCut", m_detaEMCLFACCut); + declareProperty("dphiChrgEMCut", m_dphiChrgEMCut); + declareProperty("detaChrgEMCut", m_detaChrgEMCut); + declareProperty("CaloClusterContainerName", m_CaloClusterContainerName); + declareProperty("RecoTopoClusterETCut", m_recoTopoClusterETCut); + declareProperty("RecoEtaCut", m_recoEtaCut); + declareProperty("TrackTopoClusPhi2Cut", m_TrackTopoClusPhi2Cut); + declareProperty("TrackTopoClusEta1Cut", m_TrackTopoClusEta1Cut); + declareProperty("MVisEflowCut", m_MVisEflowCut); + declareProperty("MTrk3PCut", m_MTrk3PCut); + declareProperty("ETeflow_ETcaloCut", m_ETeflow_ETcaloCut); + declareProperty("ETeflow_ETcaloCutMin", m_ETeflow_ETcaloCutMin); + declareProperty("MaxClusterEta", m_maxClusterEta); + declareProperty("useEMTopoClusters", m_useEMTopoClusters); + declareProperty("CellCorrection", m_doCellCorrection); + declareProperty("OriginCorrectionTool", m_tauOriginCorrTool); +} + + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauEflowVariables::~TauEflowVariables() { +} + +StatusCode TauEflowVariables::eventFinalize(TauCandidateData *) { + + std::vector<int>().swap(m_isTopoClusQualif); + std::vector<int>().swap(m_closestTopoClusCell); + std::vector<double>().swap(m_TopoClustPhi); + std::vector<double>().swap(m_closestTopoClusCellPhi); + std::vector<double>().swap(m_closestTopoClusCellEta); + std::vector<double>().swap(m_TopoClusPhi); + std::vector<double>().swap(m_TopoClusEta); + + return StatusCode::SUCCESS; +} + + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- + +StatusCode TauEflowVariables::initialize() { + + StatusCode sc; + + ATH_MSG_VERBOSE(name() << " RconeCoreCut = " << m_detRCoreCaloCut); + ATH_MSG_VERBOSE(name() << " ETStripMinCut = " << m_ETStripMinCut); + ATH_MSG_VERBOSE(name() << " detaStripCut = " << m_detaStripCut); + + //--------------------------------------------------------------------- + // Retrieve pointer to ToolSvc + //--------------------------------------------------------------------- + IToolSvc *pToolSvc; + sc = service("ToolSvc", pToolSvc); + if (sc.isFailure()) { + ATH_MSG_FATAL("Unable to retrieve pointer to ToolSvc"); + return sc; + } + if (m_tauOriginCorrTool.retrieve().isFailure()) { + ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode TauEflowVariables::eventInitialize(TauCandidateData * /*data*/) +{ + if (m_doCellCorrection) { + // Cell Origin Correction Tool initializeEvent is not called automatically + // -> call from here + return m_tauOriginCorrTool->eventInitialize(); + } + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- + +StatusCode TauEflowVariables::execute(TauCandidateData *data) { + + Analysis::TauJet *pTau = data->tau; + Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails); + + // + if (pTau->numTrack()==0) { + ATH_MSG_VERBOSE("tau has no tracks -> skip Eflow"); + return StatusCode::SUCCESS; + } + + if ( !pDetails || !pExtraDetails) { + ATH_MSG_ERROR("TauCommon(Extra)Details object not valid"); + return StatusCode::FAILURE; + } + + StatusCode sc; + + const CaloCellContainer *pCellContainer = 0; + + // for tau trigger + sc = data->getObject("CellContainer", pCellContainer); + if (sc.isFailure() || !pCellContainer) { + // retrieve at the normal way + //TODO: AllCalo hardcoded!! + sc = evtStore()->retrieve(pCellContainer, "AllCalo"); + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to find cell container"); + return StatusCode::FAILURE; + } + } + + const int nTr = 10; + double sumETCellsEM01Trk[nTr]; + double sumETCellsChrgEMTrk[nTr]; + double resChrgEMTrk[nTr]; + + for (int i = 0; i < nTr; ++i) { + sumETCellsEM01Trk[i] = 0.; + sumETCellsChrgEMTrk[i] = 0.; + resChrgEMTrk[i] = 0.; + } + + double sumETcalo = 0.0; + double sumETcaloHAD = 0.0; + double sumETcaloEM = 0.0; + double sumETCellsEMCL = 0.0; + double sumETCellsNeuEM = 0.0; + double sumETCellsChrgEM = 0.0; + double sumETCellsChrgHAD = 0.0; + double sumETeflow = 0.0; + double resChrgEM = 0.0; + double resNeuEM = 0.0; + double resChrgEMTrkTot = 0.0; + double pttot = 0.0; + + m_nTopoclust = 0; + + //fill information about EM Clusters + if (m_useEMTopoClusters) { + sc = fillTopoClusterInfo(data); + if (sc.isFailure()) return sc; + } + + //use tau vertex to correct cell position + if (m_doCellCorrection) { + m_tauOriginCorrTool->setOriginSource(pTau->origin()); + } + + //----------------------------------------------------------------- + // Loop on cells stored in object placed there by TauEflowTrackMatchCells + //----------------------------------------------------------------- + xAOD::CaloCluster* EMCLCluster = CaloClusterStoreHelper::makeCluster(pCellContainer); + xAOD::CaloCluster* NeuEMCluster = CaloClusterStoreHelper::makeCluster(pCellContainer); + + const CaloCluster *pCluster = pTau->cellCluster(); + CaloCluster::cell_iterator cellIter = pCluster->cell_begin(); + CaloCluster::cell_iterator cellIterE = pCluster->cell_end(); + + const CaloCell *pCell; + + for (; cellIter != cellIterE; ++cellIter) { + pCell = *cellIter; + + // correct cell for tau vertex + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + + double cellEta = pCell->eta(); + double cellPhi = pCell->phi(); + double cellEt = pCell->et(); + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + + int sampling = pCell->caloDDE()->getSampling(); + if (sampling > 3 && sampling < 8) sampling = sampling - 4; + + double detPhi, detEta, detPhiTrk[nTr] = {0.}, detEtaTrk[nTr] = {0.}; + + int i = 2; + if (sampling < 4) i = sampling; + + if (pExtraDetails->closestPhiTrkVertCell(0, i)) + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->closestPhiTrkVertCell(0, i)->phi()); + else + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(0)->phi()); + + if (pExtraDetails->closestEtaTrkVertCell(0, i)) + detEta = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->closestEtaTrkVertCell(0, i)->eta()); + else + detEta = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(0)->eta()); + + double detCell = Tau1P3PKineUtils::deltaR(detPhi, detEta); + + if (detCell > m_detRCoreCaloCut) continue; + + //for each track connected to object + for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + detPhiTrk[itr] = 0.; + detEtaTrk[itr] = 0.; + + if (pExtraDetails->closestPhiTrkCell(itr, i)) + detPhiTrk[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->closestPhiTrkCell(itr, i)->phi()); + else + detPhiTrk[itr] = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[0][i]); + + if (pExtraDetails->closestEtaTrkCell(itr, i)) + detEtaTrk[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->closestEtaTrkCell(itr, i)->eta()); + else + detEtaTrk[itr] = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[0][i]); + } + + sumETcalo += cellEt; + + if (sampling < 4) sumETcaloEM += cellEt; + else sumETcaloHAD += cellEt; + + int isCellBooked = 0; + + //----------------------------------------------------------------- + // sumETCellsEMCL - first iteration for + //----------------------------------------------------------------- + if (sampling <= 2) { + int kPi0 = -1; + for (int ic = 0; ic < m_nTopoclust; ++ic) { + if (m_isTopoClusQualif[ic] != 1) continue; + + double detPhi, detEta, Rcone; + + detPhi = Tau1P3PKineUtils::deltaPhi(pTau->phi(), m_TopoClusPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(pTau->eta(), m_TopoClusEta[ic]); + Rcone = Tau1P3PKineUtils::deltaR(detPhi, detEta); + if (Rcone > m_detRCoreCaloCut) continue; + + ++kPi0; + + if (m_closestTopoClusCell[ic] != 0) { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_closestTopoClusCellPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_closestTopoClusCellEta[ic]); + } else { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_TopoClusPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_TopoClusEta[ic]); + } + + if (detEta < m_detaEMCLCut && detPhi < m_dphiEMCLCut) { + if (!isCellBooked) { + sumETCellsEMCL += cellEt; + EMCLCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0); + + isCellBooked = 1; + } + } + if (isCellBooked) break; + } // end track loop + } + + if (isCellBooked) continue; // go to next cell + + //----------------------------------------------------------------- + // sumETCellsChrgEM + //----------------------------------------------------------------- + //for each track connected to tau object + for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + if (sampling <= 3 && detEtaTrk[itr] < m_detaChrgEMCut && detPhiTrk[itr] < m_dphiChrgEMCut) { + if (!isCellBooked) { + sumETCellsChrgEM += cellEt; + sumETCellsChrgEMTrk[itr] += cellEt; + if (sampling <= 1) sumETCellsEM01Trk[itr] += cellEt; + isCellBooked = 1; + } + } + if (isCellBooked) break; + } // end track loop + + if (isCellBooked) continue; // go to next cell + + //----------------------------------------------------------------- + // sumETCellsEMCL - second iteration for + //----------------------------------------------------------------- + if (sampling <= 2) { + for (int ic = 0; ic < m_nTopoclust; ++ic) { + if (m_isTopoClusQualif[ic] != 1) continue; + + double detPhi, detEta, Rcone; + + detPhi = Tau1P3PKineUtils::deltaPhi(pTau->phi(), m_TopoClusPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(pTau->eta(), m_TopoClusEta[ic]); + Rcone = Tau1P3PKineUtils::deltaR(detPhi, detEta); + if (Rcone > m_detRCoreCaloCut) continue; + + if (m_closestTopoClusCell[ic] != 0) { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_closestTopoClusCellPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_closestTopoClusCellEta[ic]); + } else { + detPhi = Tau1P3PKineUtils::deltaPhi(cellPhi, m_TopoClusPhi[ic]); + detEta = Tau1P3PKineUtils::deltaEta(cellEta, m_TopoClusEta[ic]); + } + + if (detEta < m_detaEMCLFACCut * m_detaEMCLCut && detPhi < m_dphiEMCLFACCut * m_dphiEMCLCut) { + if (!isCellBooked) { + sumETCellsEMCL += cellEt; + EMCLCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0); + + isCellBooked = 1; + } + } + if (isCellBooked) break; + } // end track loop + } + if (isCellBooked) continue; // go to next cell + + //----------------------------------------------------------------- + // sumETCellsNeuEM - from still not booked cells + //----------------------------------------------------------------- + //erw: layer 3 removed from sumETCellsNeuEM + if (sampling < 3) { + sumETCellsNeuEM += cellEt; + NeuEMCluster->addCell(pCellContainer->findIndex(pCell->caloDDE()->calo_hash()), 1.0); + isCellBooked = 1; + } + if (isCellBooked) continue; // go to next cell + + //----------------------------------------------------------------- + // sumETCellsChrgHAD - from still not booked cells + //----------------------------------------------------------------- + //erw: layer 3 added to sumETCellsChrgHAD + if (sampling >= 3) { + sumETCellsChrgHAD += cellEt; + isCellBooked = 1; + } + + // at this point cell should be booked already, print warning if it is not + if (!isCellBooked) ATH_MSG_WARNING("Please check why cell is not booked"); + } // end cell loop + + //----------------------------------------------------------------- + // calculate energy flow variables + //----------------------------------------------------------------- + //for 1 prong + if (pTau->numTrack() == 1) { + double leadTrkPt = pTau->track(0)->pt(); + + if ((sumETCellsEM01Trk[0] / leadTrkPt) < 0.05) { + resChrgEM = sumETCellsChrgEM - 0.7 * leadTrkPt; + if (resChrgEM < 0.0) resChrgEM = 0.0; + sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM; + } else if ((sumETCellsEM01Trk[0] / leadTrkPt) > 0.05 && (sumETCellsChrgHAD / leadTrkPt) > 0.4) { + resChrgEM = 2.5 * sumETCellsEM01Trk[0]; + + if (resChrgEM > sumETCellsChrgEM) resChrgEM = sumETCellsChrgEM; + sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM; + } else { + resChrgEM = sumETCellsChrgEM - 0.65 * leadTrkPt; + if (resChrgEM < 0.0) resChrgEM = 0.0; + resNeuEM = -0.1 * leadTrkPt; + + if ((resNeuEM + sumETCellsNeuEM) < 0.0) resNeuEM = 0.0; + + sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + leadTrkPt + resChrgEM + resNeuEM; + } + + pExtraDetails->setSumPtTrk(leadTrkPt); + + ATH_MSG_VERBOSE(name() << " sumETCellsEMCL " << sumETCellsEMCL); + pDetails->setSeedTrk_etEMCL(sumETCellsEMCL); + + ATH_MSG_VERBOSE(name() << " sumETCellsNeuEM " << sumETCellsNeuEM); + pDetails->setSeedTrk_etNeuEM(sumETCellsNeuEM); + + ATH_MSG_VERBOSE(name() << " sumETCellsChrgEM " << sumETCellsChrgEM); + pDetails->setSeedTrk_etChrgEM(sumETCellsChrgEM); + + ATH_MSG_VERBOSE(name() << " sumETCellsEM01Trk " << sumETCellsEM01Trk[0] << " " << pDetails->seedTrk_etChrgEM01Trk(0)); + pDetails->addSeedTrk_etChrgEM01Trk(sumETCellsEM01Trk[0]); + + ATH_MSG_VERBOSE(name() << " resChrgEM " << resChrgEM); + pDetails->addSeedTrk_etResChrgEMTrk(resChrgEM); + + ATH_MSG_VERBOSE(name() << " resNeuEM " << resNeuEM); + pDetails->setSeedTrk_etResNeuEM(resNeuEM); + + ATH_MSG_VERBOSE(name() << " sumETcaloEM " << sumETcaloEM); + pDetails->setSeedTrk_etEMAtEMScale(sumETcaloEM); + + ATH_MSG_VERBOSE(name() << " sumETcaloHAD " << sumETcaloHAD); + pDetails->setSeedTrk_etHadAtEMScale(sumETcaloHAD); + } else { + resChrgEMTrkTot = 0.; + double sumETCellsChrgEMTrkTot = 0.; + + for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + double trkPt = pTau->track(itr)->pt(); + + pttot += trkPt; + sumETCellsChrgEMTrkTot += sumETCellsChrgEMTrk[itr]; + + if ((sumETCellsChrgEMTrk[itr] - 0.7 * trkPt) > 0) + resChrgEMTrk[itr] = sumETCellsChrgEMTrk[itr] - 0.7 * trkPt; + + resChrgEMTrkTot += resChrgEMTrk[itr]; + + ATH_MSG_VERBOSE(name() << " 3p resChrgEM: track-> " << itr << " resChrgEMTrk(track) " << resChrgEMTrk[itr]); + pDetails->addSeedTrk_etResChrgEMTrk(resChrgEMTrk[itr]); + + ATH_MSG_VERBOSE("taurec 3p sumETCellsEM01Trk " << itr << " " << sumETCellsEM01Trk[itr] << " " << pDetails->seedTrk_etChrgEM01Trk(itr)); + pDetails->addSeedTrk_etChrgEM01Trk(sumETCellsEM01Trk[itr]); + } // end track loop + + resNeuEM = -0.1 * pttot; + if ((resNeuEM + sumETCellsNeuEM) < 0.0) resNeuEM = -sumETCellsNeuEM; + + sumETeflow = sumETCellsEMCL + sumETCellsNeuEM + pttot + resChrgEMTrkTot + resNeuEM; + + pExtraDetails->setSumPtTrk(pttot); + + ATH_MSG_VERBOSE(name() << " 3p sumETCellsEMCL " << sumETCellsEMCL); + pDetails->setSeedTrk_etEMCL(sumETCellsEMCL); + + ATH_MSG_VERBOSE(name() << " 3p sumETCellsNeuEM " << sumETCellsNeuEM); + pDetails->setSeedTrk_etNeuEM(sumETCellsNeuEM); + + ATH_MSG_VERBOSE(name() << " 3p sumETCellsChrgEM " << sumETCellsChrgEMTrkTot); + pDetails->setSeedTrk_etChrgEM(sumETCellsChrgEMTrkTot); + + ATH_MSG_VERBOSE(name() << " 3p resNeuEM " << resNeuEM); + pDetails->setSeedTrk_etResNeuEM(resNeuEM); + + ATH_MSG_VERBOSE(name() << " 3p sumETcaloEM " << sumETcaloEM); + pDetails->setSeedTrk_etEMAtEMScale(sumETcaloEM); + + ATH_MSG_VERBOSE(name() << " 3p sumETcaloHAD " << sumETcaloHAD); + pDetails->setSeedTrk_etHadAtEMScale(sumETcaloHAD); + } + + // calculate tau visible mass from Eflow + double MVisEflow = 0.; + if (EMCLCluster->et() != 0) { + xAOD::CaloCluster::cell_iterator cellIter = EMCLCluster->cell_begin(); + xAOD::CaloCluster::cell_iterator cellIterE = EMCLCluster->cell_end(); + const CaloCell *pCell; + double sumEMeta = 0; + double sumEMphi = 0; + double resphi = 0; + CaloPhiRange phiRange; + for (; cellIter != cellIterE; ++cellIter) { + pCell = *cellIter; + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + + sumEMeta += pCell->et() * pCell->eta(); + resphi = phiRange.diff(pCell->phi(), pTau->phi()); + sumEMphi += pCell->et() * resphi; + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + } + + double phiPi0 = phiRange.fix((sumEMphi / EMCLCluster->et()) + pTau->phi()); + double etaPi0 = sumEMeta / sumETCellsEMCL; + if (etaPi0 < -1. * m_maxClusterEta) etaPi0 = -1. * m_maxClusterEta; + else if (etaPi0 > m_maxClusterEta) etaPi0 = m_maxClusterEta; + + // correct for vertex position as given by seeding track + // as short-cut assumed that radius is 1600mm + + //TODO: + //should Perigee retrieved wrt tau origin? + //tracks are selected by quality cuts wrt tau origin so code below might be correct too. + + //for 1 prong only + if (pTau->numTrack() == 1) { + double zvert = (pTau->track(0)->measuredPerigee())->parameters()[Trk::z0]; + etaPi0 = asinh(sinh(etaPi0) - zvert / 1600.); + } + + double pxPi0 = (sumETeflow - pttot) * cos(phiPi0); + double pyPi0 = (sumETeflow - pttot) * sin(phiPi0); + double pzPi0 = (sumETeflow - pttot) * sinh(etaPi0); + double ePi0 = (sumETeflow - pttot) * cosh(etaPi0); + double pxPiCh = pttot * cos(pTau->phi()); + double pyPiCh = pttot * sin(pTau->phi()); + double pzPiCh = pttot * sinh(pTau->eta()); + double ePiCh = pttot * cosh(pTau->eta()); + + double mass = (ePi0 + ePiCh) * (ePi0 + ePiCh) - (pxPi0 + pxPiCh) * (pxPi0 + pxPiCh) + - (pyPi0 + pyPiCh) * (pyPi0 + pyPiCh) - (pzPi0 + pzPiCh) * (pzPi0 + pzPiCh); + + if (mass > 0.) MVisEflow = sqrt(mass); + } else if (NeuEMCluster->et() != 0) { + xAOD::CaloCluster::cell_iterator cellIter = NeuEMCluster->cell_begin(); + xAOD::CaloCluster::cell_iterator cellIterE = NeuEMCluster->cell_end(); + const CaloCell *pCell; + double sumEMeta = 0; + double sumEMphi = 0; + double resphi = 0; + CaloPhiRange phiRange; + for (; cellIter != cellIterE; ++cellIter) { + pCell = *cellIter; + + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + + sumEMeta += pCell->et() * pCell->eta(); + resphi = phiRange.diff(pCell->phi(), pTau->phi()); + sumEMphi += pCell->et() * resphi; + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + } + + double phi = phiRange.fix((sumEMphi / NeuEMCluster->et()) + pTau->phi()); + double eta = sumEMeta / sumETCellsNeuEM; + + if (eta < -1. * m_maxClusterEta) eta = -1. * m_maxClusterEta; + else if (eta > m_maxClusterEta) eta = m_maxClusterEta; + + // correct for vertex position as given by seeding track + // as short-cut assumed that radius is 1600mm + + //TODO: + //should Perigee retrieved wrt tau origin? + //tracks are selected by quality cuts wrt tau origin so code below might be correct too. + + //for 1 prong only + if (pTau->numTrack() == 1) { + double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0]; + eta = asinh(sinh(eta) - zvert / 1600.); + } + + double px = (sumETeflow - pttot) * cos(phi); + double py = (sumETeflow - pttot) * sin(phi); + double pz = (sumETeflow - pttot) * sinh(eta); + double e = (sumETeflow - pttot) * cosh(eta); + double pxCh = pttot * cos(pTau->phi()); + double pyCh = pttot * sin(pTau->phi()); + double pzCh = pttot * sinh(pTau->eta()); + double eCh = pttot * cosh(pTau->eta()); + + double mass = (e + eCh) * (e + eCh) - (px + pxCh) * (px + pxCh) + - (py + pyCh) * (py + pyCh) - (pz + pzCh) * (pz + pzCh); + if (mass > 0.) MVisEflow = sqrt(mass); + } + + //add final 4-momentum of tau + //FF: uncommented pTau->setE(sumETeflow / pTau->sinTh()); + pDetails->setEtEflow(sumETeflow); + pDetails->setMEflow(MVisEflow); + ATH_MSG_VERBOSE(name() << " tau mass vis " << pDetails->etEflow() << " tau eflow " << pDetails->etEflow()); + + delete EMCLCluster; + delete NeuEMCluster; + + //Preselection + if ((pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) == 0.) return StatusCode::FAILURE; + + /* + if (MVisEflow > m_MVisEflowCut || + sumETeflow / (pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) > m_ETeflow_ETcaloCut || + sumETeflow / (pDetails->seedCalo_etEMAtEMScale() + pDetails->seedCalo_etHadAtEMScale()) < m_ETeflow_ETcaloCutMin + ) sc = StatusCode::FAILURE; + //TODO: Really FAILURE?? + */ + //adding some discrimination variables to the object + + if (pDetails->seedTrk_etEMAtEMScale() + pDetails->seedTrk_etHadAtEMScale() !=0 ) { + pDetails->setSeedTrk_isolFracWide((pDetails->seedTrk_etIsolEM() + pDetails->seedTrk_etIsolHad()) / (pDetails->seedTrk_etEMAtEMScale() + pDetails->seedTrk_etHadAtEMScale())); + } + + double totpt = 0; + for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + totpt += pTau->track(itr)->pt(); + } + + double etoverpttot = pDetails->seedTrk_etChrgHad() / totpt; + pDetails->setSeedTrk_etChrgHadOverSumTrkPt(etoverpttot); + + return StatusCode::SUCCESS; + +} + + +//------------------------------------------------------------------------- +// fill EM cluster info +// TODO: need clusters and cells here also correction for tau vertex? +// but what is aabout detector crack region cuts? +// they should use uncorrected coordinates, or? +//------------------------------------------------------------------------- + +StatusCode TauEflowVariables::fillTopoClusterInfo(TauCandidateData *data) { + + StatusCode sc; + + Analysis::TauJet *pTau = data->tau; + Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails); + + //--------------------------------------------------------------------- + // Retrieve calo cluster container from StoreGate + //--------------------------------------------------------------------- + const CaloClusterContainer *pTopoContainer; + sc = evtStore()->retrieve(pTopoContainer, m_CaloClusterContainerName); + + if (sc.isFailure()) { + ATH_MSG_WARNING("No " << m_CaloClusterContainerName << " found in TES"); + ATH_MSG_WARNING("will not use information about tau EM topo clusters"); + m_useEMTopoClusters = false; + return StatusCode::RECOVERABLE; + } + + ATH_MSG_VERBOSE(name() << " " << m_CaloClusterContainerName << " found " << pTopoContainer->size()); + + int ntopo = pTopoContainer->size(); + + m_isTopoClusQualif.resize(ntopo); + m_TopoClustPhi.resize(ntopo); + m_closestTopoClusCell.resize(ntopo); + m_closestTopoClusCellPhi.resize(ntopo); + m_closestTopoClusCellEta.resize(ntopo); + m_TopoClusPhi.resize(ntopo); + m_TopoClusEta.resize(ntopo); + + for (int i = 0; i < ntopo; ++i) { + m_isTopoClusQualif[i] = 0; + m_TopoClustPhi[i] = 0.; + m_closestTopoClusCell[i] = 0; + m_closestTopoClusCellPhi[i] = 0; + m_closestTopoClusCellEta[i] = 0; + m_TopoClusPhi[i] = 0.; + m_TopoClusEta[i] = 0.; + } + + //--------------------------------------------------------------------- + // Get pointer to fist and last cluster in the calo cluster container + //--------------------------------------------------------------------- + CaloClusterContainer::const_iterator topoIter = pTopoContainer->begin(); + CaloClusterContainer::const_iterator topoIterE = pTopoContainer->end(); + + const CaloCluster *pTopo; + int iclust = 0; + + for (; topoIter != topoIterE; ++topoIter) { + pTopo = *topoIter; + + //--------------------------------------------------------------------- + // Skip if cluster outside rapidity range or below pT threshold + //--------------------------------------------------------------------- + if (std::fabs(pTopo->eta()) > m_recoEtaCut) continue; + if (pTopo->et() < m_recoTopoClusterETCut) continue; + + //------------------------------------------------------------- + // Look for the closest cluster to tau track(s) + //------------------------------------------------------------- + double detEtaMin1 = 9999.0; + double detPhiMin2 = 9999.0; + double detPhi, detEta, detPhiCrude, detEtaCrude; + m_isTopoClusQualif[iclust] = 1; + + //loop ontracks in object + for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + // very crude treatement of crack region + int isampling = 1; + + detEtaCrude = Tau1P3PKineUtils::deltaEta(pExtraDetails->etaTrkCaloSamp()[itr][isampling], pTopo->eta()); + detEta = Tau1P3PKineUtils::deltaEta(pExtraDetails->etaTrkCaloSamp()[itr][isampling], pTopo->getVariable(CaloVariableType::ETA, CaloSampling::EMB1, true)); + + if (detEtaCrude < detEta) detEta = detEtaCrude; + if (detEta < detEtaMin1) detEtaMin1 = detEta; + + // very crude treatement of crack region + isampling = 2; + + detPhiCrude = Tau1P3PKineUtils::deltaPhi(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->phi()); + detPhi = Tau1P3PKineUtils::deltaPhi(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->getVariable(CaloVariableType::PHI, CaloSampling::EMB2, true)); + + if (detPhiCrude < detPhi) detPhi = detPhiCrude; + if (detPhi < detPhiMin2) detPhiMin2 = detPhi; + } + + if (detPhiMin2 < m_TrackTopoClusPhi2Cut) m_isTopoClusQualif[iclust] = 0; + if (detEtaMin1 < m_TrackTopoClusEta1Cut) m_isTopoClusQualif[iclust] = 0; + + m_TopoClusPhi[iclust] = pTopo->phi(); + m_TopoClusEta[iclust] = pTopo->eta(); + + double detRCellMin = 9999.0; + const CaloCell *pTmpCell = 0; + const CaloCell *pCell; + + CaloCluster::cell_iterator cellItr = pTopo->cell_begin(); + CaloCluster::cell_iterator cellItrE = pTopo->cell_end(); + for (; cellItr != cellItrE; ++cellItr) { + pCell = *cellItr; + if (pCell->caloDDE()->getSampling() == 2) { + double detPhi = Tau1P3PKineUtils::deltaPhi(pCell->phi(), pTopo->phi()); + double detEta = Tau1P3PKineUtils::deltaEta(pCell->eta(), pTopo->eta()); + double detRCell = Tau1P3PKineUtils::deltaR(detPhi, detEta); + + if (detRCell < detRCellMin) { + detRCellMin = detRCell; + pTmpCell = pCell; + } + } + } + if (pTmpCell) { + m_closestTopoClusCell[iclust] = 1; + m_closestTopoClusCellPhi[iclust] = pTmpCell->phi(); + m_closestTopoClusCellEta[iclust] = pTmpCell->eta(); + } + + ++iclust; + } + + m_nTopoclust = iclust; + + return StatusCode::SUCCESS; +} + diff --git a/Reconstruction/tauRec/depreciated/TauEflowVariables.h b/Reconstruction/tauRec/depreciated/TauEflowVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..266a3bb2c780ae672a6191a94f448b5a4b41553e --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauEflowVariables.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUEFLOWVARIABLES_H +#define TAUREC_TAUEFLOWVARIABLES_H + +#include <vector> +#include "EventKernel/INavigable4Momentum.h" +#include "CaloUtils/CaloClusterStoreHelper.h" + +#include "tauRec/TauToolBase.h" + +class TauOriginCorrectionTool; + +/** + * @brief Class for building energy flow quantities. + * + * This tool was formerly named as tau1p3pAddEflowInfo. + * + * @author Tadeusz Szymocha, Anna Kaczmarska + */ + +class TauEflowVariables : public TauToolBase { +public: + TauEflowVariables(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauEflowVariables(); + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + + StatusCode fillTopoClusterInfo(TauCandidateData *data); + + +private: + + std::string m_trackContainerName; + double m_detRCoreCaloCut; + double m_ETCellMinCut; + double m_ETStripMinCut; + double m_detaStripCut; + double m_dphiEMCLCut; + double m_detaEMCLCut; + double m_dphiEMCLFACCut; + double m_detaEMCLFACCut; + double m_dphiChrgEMCut; + double m_detaChrgEMCut; + std::string m_CaloClusterContainerName; + double m_recoTopoClusterETCut; + double m_recoEtaCut; + double m_TrackTopoClusPhi2Cut; + double m_TrackTopoClusEta1Cut; + double m_TopoClusEtha1Cut; + double m_MVisEflowCut; + double m_MTrk3PCut; + double m_ETeflow_ETcaloCut; + double m_ETeflow_ETcaloCutMin; + double m_maxClusterEta; + bool m_useEMTopoClusters; + + int m_nTopoclust; + + std::vector<int> m_isTopoClusQualif; + std::vector<double> m_TopoClustPhi; + std::vector<int> m_closestTopoClusCell; + std::vector<double> m_closestTopoClusCellPhi; + std::vector<double> m_closestTopoClusCellEta; + std::vector<double> m_TopoClusPhi; + std::vector<double> m_TopoClusEta; + + bool m_doCellCorrection; //!< enable cell origin correction + ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool; +}; + + +#endif diff --git a/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..83a9081867efe96980abad89715455e96ece4ad8 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.cxx @@ -0,0 +1,215 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/********************************************************* +NAME: TauOriginCorrectionTool.cxx +PACKAGE: Reconstruction/tauRec +AUTHORS: Felix Friedrich <felix.friedrich@cern.ch> +DATE: May 12, 2011 + +PURPOSE: correct cells and cluster for vertex shift +inspired by Reconstruction/Jet/JetCalibTools/src/JetCaloOrigin.cxx +and +Reconstruction/Jet/JetMomentTools/src/JetOriginCorrectionTool.cxx + + *************************************************************/ + +#include "CaloEvent/CaloCell.h" +#include "CaloEvent/CaloCluster.h" +// This class was removed. If we want to revive this tool we need to switch to the xAOD::CaloVertexedCluster interface +// #include "CaloUtils/CaloClusterVertexCorrection.h" +#include "JetEvent/Jet.h" +#include "CLHEP/Geometry/Vector3D.h" +// #include "VxVertex/VxContainer.h" + +#include "xAODTracking/VertexContainer.h" + +#include "tauRec/TauOriginCorrectionTool.h" + + +TauOriginCorrectionTool::TauOriginCorrectionTool( const std::string& type, const std::string& name, const IInterface* parent ) : + AthAlgTool(type, name, parent), + m_originPosition(3,0), + m_useJVA(false), + m_usePrimaryVertex(false), + m_useBeamSpot(false), + m_evnInitCalled(false), + m_primVtxName("PrimaryVertices"), + // m_primVtxName("VxPrimaryCandidate"), + m_beamConditionsService("BeamCondSvc", name) +{ + declareInterface<TauOriginCorrectionTool>( this ); + + declareProperty("OriginPosition", m_originPosition); + declareProperty("UseJVA", m_useJVA); + declareProperty("UsePrimaryVertex", m_usePrimaryVertex); + declareProperty("UseBeamSpot", m_useBeamSpot); + declareProperty("VertexContainerKey",m_primVtxName = "VxPrimaryCandidate"); + declareProperty("BeamConditionsSvc", m_beamConditionsService); + declareProperty("OriginMomentName", m_OriginMomName = "OriginIndex"); + +} + +//************************************************************************************************* +StatusCode TauOriginCorrectionTool::initialize() +{ + if(m_useBeamSpot) { + if(m_beamConditionsService.retrieve().isFailure() ) { + ATH_MSG_ERROR( "Cannot find service named <" << m_beamConditionsService << ">"); + return StatusCode::FAILURE; + } + } + + return StatusCode::SUCCESS; +} + +//************************************************************************************************* +StatusCode TauOriginCorrectionTool::eventInitialize() +{ + // skip if already called + if (m_evnInitCalled) return StatusCode::SUCCESS; + + // get VxContainer - must be retrieved in eventInitialize + if(m_usePrimaryVertex || m_useJVA) { + StatusCode sc = evtStore()->retrieve(m_vxContainer, m_primVtxName); + if (sc.isFailure()) { + ATH_MSG_DEBUG("Could not retrieve VxContainer <" << m_primVtxName << "> during initialize() " ); + return StatusCode::SUCCESS; + } + m_evnInitCalled = true; + } + return StatusCode::SUCCESS; +} + +//************************************************************************************************* +// set the origin source +// jet is only used if useJVA is enabled +void TauOriginCorrectionTool::setOriginSource(const Jet* jet) { + m_jetOrigin = chooseOrigin(jet); +} + +//************************************************************************************************* +// set the origin source by hand +void TauOriginCorrectionTool::setOriginSource(const Trk::RecVertex* vertex) { + // set origin by hand + if (vertex) { + m_jetOrigin = Amg::Vector3D(vertex->position().x(), vertex->position().y(), vertex->position().z()); + } + else { + m_jetOrigin = Amg::Vector3D(0,0,0); + } +} + +//************************************************************************************************* +// set the origin source by hand +void TauOriginCorrectionTool::setOriginSource(const xAOD::Vertex* vertex) { + // set origin by hand + if (vertex) { + m_jetOrigin = Amg::Vector3D(vertex->position().x(), vertex->position().y(), vertex->position().z()); + } + else { + m_jetOrigin = Amg::Vector3D(0,0,0); + } +} + +//************************************************************************************************* +// set a new cell vertex +void TauOriginCorrectionTool::correctCell(const CaloCell* cell) { + cell->zVertex(&m_jetOrigin); +} + +//************************************************************************************************* +// reset cell +void TauOriginCorrectionTool::resetCell(const CaloCell* cell) { + cell->zVertex(0,true); +} + +//************************************************************************************************* +// set a new cluster vertex +void TauOriginCorrectionTool::correctCluster(const CaloCluster* cluster) { + // CaloClusterVertexCorrection::setVertex(cluster, &m_jetOrigin); +} + +//************************************************************************************************* +// reset cluster vertex +void TauOriginCorrectionTool::resetCluster(const CaloCluster* cluster) { + // CaloClusterVertexCorrection::resetVertex(cluster); +} + +// try to get the origin of the jet +// not not really needed at the moment, because using JVA is switched off by default +Amg::Vector3D TauOriginCorrectionTool::chooseOrigin(const Jet* jet) +{ + // Cascade in order of priority + // If one fails, go to the next approach + + // JetVertexAssociation + if(m_useJVA) { + ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin In useJVA"); + unsigned int originIndex(jet->getMoment(m_OriginMomName)); // No way to know if this has been filled at the moment + ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin Just got originIndex moment "<< originIndex); + if (originIndex > m_vxContainer->size()) { + ATH_MSG_WARNING("Index of jet origin (" << originIndex + << ") is larger than the size of the vertex container (" + << m_vxContainer->size() << "), we return (0,0,0)"); + return Amg::Vector3D (0, 0, 0); + } + ATH_MSG_VERBOSE("TauOriginCorrectionTool::chooseOrigin Just before getting position of vertex"); + Amg::Vector3D primaryVertex = (*(m_vxContainer->at(originIndex))).position(); + ATH_MSG_VERBOSE("Found a primary vertex at (" + << primaryVertex.x() << "," + << primaryVertex.y() << "," + << primaryVertex.z() << ")" + ); + return Amg::Vector3D (primaryVertex.x(), primaryVertex.y(), primaryVertex.z()); + } + + // PrimaryVertex + if(m_usePrimaryVertex) { + if(m_vxContainer) { + // At least 1 vertex + if(m_vxContainer->size()>0) { + // More than 1 track pointing to the vertex + if((*m_vxContainer->begin())->nTrackParticles() > 1) { + Amg::Vector3D primaryVertex = (*(m_vxContainer->begin()))->position(); + + ATH_MSG_VERBOSE("Found a primary vertex at (" + << primaryVertex.x() << "," + << primaryVertex.y() << "," + << primaryVertex.z() << ")" + ); + + return Amg::Vector3D (primaryVertex.x(), primaryVertex.y(), primaryVertex.z()); + } + ATH_MSG_DEBUG("Couldn't find a primary vertex! Try next approach" ); + } + } + } + + // BeamSpot + if(m_useBeamSpot) { + if(m_beamConditionsService) { + if(!m_beamConditionsService.empty()) { + Amg::Vector3D beamSpot = m_beamConditionsService->beamVtx().position(); + + ATH_MSG_VERBOSE("Found a beam spot at (" + << beamSpot.x() << "," + << beamSpot.y() << "," + << beamSpot.z() << ")" + ); + + return Amg::Vector3D (beamSpot.x(), beamSpot.y(), beamSpot.z()); + } + } + ATH_MSG_DEBUG("Couldn't find a beam spot! Try next approach" ); + } + + // Set Vertex Position by Hand + if(m_originPosition.size() == 3) + return Amg::Vector3D (m_originPosition[0], m_originPosition[1], m_originPosition[2]); + + // Last ditch default: (0,0,0) + return Amg::Vector3D (0,0,0); + +} diff --git a/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h new file mode 100644 index 0000000000000000000000000000000000000000..cf9ce2a30d2fa2f858bb58b4a496aeee3fc7e8b5 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauOriginCorrectionTool.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUORIGINCORRECTIONTOOL_H +#define TAUREC_TAUORIGINCORRECTIONTOOL_H + +#include <vector> +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "InDetBeamSpotService/IBeamCondSvc.h" + +#include "xAODTracking/Vertex.h" +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/TrackParticle.h" + +class Jet; +class CaloCell; +class CaloCluster; +//class xAOD::VertexContainer; + +//namespace HepGeom { +// template<class T> class Vector3D; +//} +namespace Trk { + class RecVertex; +} + +static const InterfaceID IID_ITauOriginCorrectionTool("TauOriginCorrectionTool",1,0); + +/** + * @brief Correct cells and cluster for vertex shift. + * + * Inspired by Reconstruction/Jet/JetCalibTools/JetCalibTools/JetCaloOrigin.h + * + * @author Felix Friedrich + */ + +class TauOriginCorrectionTool : public AthAlgTool +{ + public: + TauOriginCorrectionTool( const std::string& type, const std::string& name, const IInterface* parent ) ; + virtual ~TauOriginCorrectionTool(){}; + + static const InterfaceID& interfaceID() { return IID_ITauOriginCorrectionTool; } + + virtual StatusCode initialize() ; + virtual StatusCode eventInitialize() ; + virtual StatusCode finalize() { return StatusCode::SUCCESS; } ; + + virtual void setOriginSource(const Jet* jet); + virtual void setOriginSource(const Trk::RecVertex* vertex); + virtual void setOriginSource(const xAOD::Vertex* vertex); + + virtual void correctCell(const CaloCell* cell); + virtual void resetCell(const CaloCell* cell); + + virtual void correctCluster(const CaloCluster* cluster); + virtual void resetCluster(const CaloCluster* cluster); + + // Return the vertex chosen + Amg::Vector3D chooseOrigin(const Jet* jet_in); + + + private: + + // 3-vector pointing to a default origin + std::vector<double> m_originPosition; + + // Choice of origin: + // Try the JetVertexAssociation + bool m_useJVA; + // Try retrieving primary vertex + bool m_usePrimaryVertex; + // Try retrieving beamspot + bool m_useBeamSpot; + + bool m_evnInitCalled; + + // origin + Amg::Vector3D m_jetOrigin; + + // Vertex Container Name + std::string m_primVtxName; + + //JVA Moment Name + std::string m_OriginMomName; + + // Pointer to the vertex container + const xAOD::VertexContainer* m_vxContainer; + + // Pointer to the beamspot handle + ServiceHandle<IBeamCondSvc> m_beamConditionsService; + +}; +#endif diff --git a/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bb898a340c50a09b50add3438d8f5d645ad8350f --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.cxx @@ -0,0 +1,454 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0CrakowClusterCreator.cxx +// package: Reconstruction/tauRec +// authors: Elzbieta Richter-Was +// date: 19/06/2007 +// +// This tool classifies Pi0 clusters, adapted from tau1P3PCreatePi0Clus.cxx +//----------------------------------------------------------------------------- + +#include <algorithm> +#include <math.h> +#include <sstream> + +#include "GaudiKernel/ListItem.h" +#include "GaudiKernel/IToolSvc.h" +#include "GaudiKernel/Property.h" + +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "CaloGeoHelpers/CaloPhiRange.h" +#include "AnalysisUtils/AnalysisMisc.h" +#include "CaloUtils/CaloClusterStoreHelper.h" + +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauCommonExtraDetails.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TauPi0CrakowClusterCreator.h" + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0CrakowClusterCreator::TauPi0CrakowClusterCreator(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_detRCoreCaloCut(0.2), +m_recoTopoClusterETCut(1000.0), +m_recoEtaCut(2.5), +m_detTrkClusMin(0.0375), +m_fracEM01verEM(0.1), +m_CaloClusterContainerName("EMTopoCluster"), +m_pi0ContainerName("Tau1P3PPi0ClusterContainer") { + declareInterface<TauToolBase > (this); + + declareProperty("detRCoreCaloCut", m_detRCoreCaloCut); + declareProperty("RecoTopoClusterETCut", m_recoTopoClusterETCut); + declareProperty("RecoEtaCut", m_recoEtaCut); + declareProperty("detTrkClusMin", m_detTrkClusMin); + declareProperty("fracEM01verEM", m_fracEM01verEM); + declareProperty("CaloClusterContainerName", m_CaloClusterContainerName); + declareProperty("Pi0ClusterContainer", m_pi0ContainerName); + +} + + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0CrakowClusterCreator::~TauPi0CrakowClusterCreator() { +} + + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- + +StatusCode TauPi0CrakowClusterCreator::initialize() { + + ATH_MSG_VERBOSE(name() << " detRCoreCaloCut = " << m_detRCoreCaloCut); + ATH_MSG_VERBOSE(name() << " RecoTopoClusterETCut = " << m_recoTopoClusterETCut); + ATH_MSG_VERBOSE(name() << " detTrkClusMin = " << m_detTrkClusMin); + ATH_MSG_VERBOSE(name() << " fracEM01verEM = " << m_fracEM01verEM); + + + StatusCode sc; + + //--------------------------------------------------------------------- + // Retrieve pointer to ToolSvc + //--------------------------------------------------------------------- + IToolSvc *pToolSvc; + sc = service("ToolSvc", pToolSvc); + if (sc.isFailure()) { + ATH_MSG_FATAL("Unable to retrieve pointer to ToolSvc"); + return sc; + } + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Delete Pi0 clusters +//----------------------------------------------------------------------------- + +static void do_delete(CaloCluster *cluster) { + delete cluster; +} + + +//------------------------------------------------------------------------- +// Event Initializer +//------------------------------------------------------------------------- + +StatusCode TauPi0CrakowClusterCreator::eventInitialize(TauCandidateData *) { + m_pi0Map.clear(); + return StatusCode::SUCCESS; +} + + + +//------------------------------------------------------------------------- +// Event Finalizer +//------------------------------------------------------------------------- + +StatusCode TauPi0CrakowClusterCreator::eventFinalize(TauCandidateData *) { + + MsgStream rLog(msgSvc(), name()); + + StatusCode sc; + + //--------------------------------------------------------------------- + // Create container for Pi0 + //--------------------------------------------------------------------- + CaloClusterContainer *pPi0Container = new CaloClusterContainer(); + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(), + // pPi0Container, + // m_pi0ContainerName, + // rLog); + + + //--------------------------------------------------------------------- + // Put all clusters into the container + //--------------------------------------------------------------------- + std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > ::iterator it; + std::vector<CaloCluster *> ::iterator clustIt; + + for (it = m_pi0Map.begin(); it != m_pi0Map.end(); ++it) { + for (clustIt = (*it).second.begin(); clustIt != (*it).second.end(); ++clustIt) { + pPi0Container->push_back(*clustIt); + } + AnalysisUtils::Sort::pT(pPi0Container); + } + + //---------------------------------------------------------------------- + // Register cluster container in StoreGate + //---------------------------------------------------------------------- + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(), + // pPi0Container, + // m_pi0ContainerName, + // rLog); + + + //--------------------------------------------------------------------- + // Set element links + //--------------------------------------------------------------------- + for (it = m_pi0Map.begin(); it != m_pi0Map.end(); ++it) { + (*it).first->pi0LinkVec().clear(); + for (clustIt = (*it).second.begin(); clustIt != (*it).second.end(); ++clustIt) { + (*it).first->addPi0(*clustIt, pPi0Container); + } + } + + return sc; +} + + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- + +StatusCode TauPi0CrakowClusterCreator::execute(TauCandidateData *data) { + + // Analysis::TauJet *pTau = data->tau; + // Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + // Analysis::TauCommonExtraDetails *pExtraDetails = dynamic_cast<Analysis::TauCommonExtraDetails *> (data->extraDetails); + + // // + // if (pTau->numTrack()==0) { + // ATH_MSG_VERBOSE("tau has no tracks -> skip CrakowClusterCreator"); + // return StatusCode::SUCCESS; + // } + + // if ( !pDetails || !pExtraDetails) { + // ATH_MSG_ERROR("TauCommon(Extra)Details object not valid"); + // return StatusCode::FAILURE; + // } + + // StatusCode sc; + + // //FIX ME! needed only for cell coping + // const CaloCellContainer *pCellContainer; + + // //for tau trigger + // sc = data->getObject("CellContainer", pCellContainer); + + // if (sc.isFailure() || !pCellContainer) { + // //TODO: AllCalo hardcoded!! + // sc = evtStore()->retrieve(pCellContainer, "AllCalo"); + // if (sc.isFailure()) { + // ATH_MSG_ERROR("Unable to find all calo container"); + // return StatusCode::FAILURE; + // } + // } + + // //--------------------------------------------------------------------- + // // Retrieve calo cluster container from StoreGate + // //--------------------------------------------------------------------- + // const CaloClusterContainer *pTopoContainer = 0; + // sc = evtStore()->retrieve(pTopoContainer, m_CaloClusterContainerName); + + // if (sc.isFailure()) { + // ATH_MSG_FATAL("No " << m_CaloClusterContainerName << " found in TES"); + // return sc; + // } + + + // double resPhiPi0 = 0; + + // CaloPhiRange phiRange; + + // std::vector<CaloCluster *> clusterPi0; + // const CaloCluster *pTopo; + + // //FF: + // //TODO: need cluster to be correct wrt tau origin? + // //Can not oversee impact, so leave everything as it is for the moment + + // //--------------------------------------------------------------------- + // // Start classifying clusters + // //--------------------------------------------------------------------- + // CaloClusterContainer::const_iterator topoIter = pTopoContainer->begin(); + // CaloClusterContainer::const_iterator topoIterE = pTopoContainer->end(); + + // for (; topoIter != topoIterE; ++topoIter) { + + // pTopo = *topoIter; + + // //--------------------------------------------------------------------- + // // Skip if cluster outside rapidity range or below pT threshold + // //--------------------------------------------------------------------- + // if (pTopo->et() < m_recoTopoClusterETCut) continue; + + + // double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0]; + // double etazv = 0; + // if (fabs(pTopo->eta()) < 1.45) { + // double aeta = fabs(pTopo->eta()); + // double r = 1691. - 39.4884 * aeta - 23.556412 * aeta*aeta; // FIXME approximate shower depth in barrel + // double z = r * sinh(pTopo->eta()); + // double x = (z - zvert) / r; + // etazv = logf(x + sqrt(1. + x * x)); + // } else { + // double z = 3920; // FIXME approximate shower depth in emec + // if (pTopo->eta() < 0) z = -3920; + // double r = z / sinh(pTopo->eta()); + // double x = (z - zvert) / r; + // etazv = logf(x + sqrt(1. + x * x)); + // } + + // //--------------------------------------------------------------------- + // // Skip if cluster outside tauCore region + // //--------------------------------------------------------------------- + // double detPhi = phiRange.diff(pTopo->phi(), pTau->phi()); + // double detEta = etazv - pTau->eta(); + + // if (sqrt(detPhi * detPhi + detEta * detEta) > m_detRCoreCaloCut) continue; + + + // //------------------------------------------------------------- + // // Check if cluster separated from track, skip otherwise + // //------------------------------------------------------------- + // int isTopoClusQualif = 1; + + // //loop on tracks in the object + // for (unsigned itr = 0; itr < pTau->numTrack(); ++itr) { + // // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + // if (itr >= 9) break; + + // int isampling = 2; + + // double detEta = fabs(pExtraDetails->etaTrkCaloSamp()[itr][isampling] - etazv); + // double detPhi = fabs(phiRange.diff(pExtraDetails->phiTrkCaloSamp()[itr][isampling], pTopo->phi())); + + // if (sqrt(detPhi * detPhi + detEta * detEta) < m_detTrkClusMin) isTopoClusQualif = 0; + // } + + + // if (isTopoClusQualif == 0) continue; + + + // //------------------------------------------------------------- + // // Check if cluster has energy deposition in EM01, skip otherwise + // //------------------------------------------------------------- + // double e_emb0 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::PreSamplerB, 1); + // double e_emb1 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::EMB1, 1); + // //ak_unused double e_emb2 = (float)pTopo->getVariable(CaloVariableType::ENERGY,CaloSampling::EMB2,1); + // double e_eme0 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::PreSamplerE, 1); + // double e_eme1 = (double) pTopo->getVariable(CaloVariableType::ENERGY, CaloSampling::EME1, 1); + // //ak_unused double e_eme2 = (float)pTopo->getVariable(CaloVariableType::ENERGY,CaloSampling::EME2,1); + + + // if ((e_emb0 + e_eme0 + e_emb1 + e_eme1) < m_fracEM01verEM * pTopo->e()) continue; + + // //------------------------------------------------------------- + // // Cluster accepted, include in bary-center calculation + // //------------------------------------------------------------- + + // // calculate energy weighted (eta,phi) + // double resPhi = phiRange.diff(pTopo->phi(), pTau->phi()); + // resPhiPi0 += resPhi * pTopo->e(); + + // ATH_MSG_VERBOSE(name() << " accepted topoForTaus clusters " + // << " energy " << pTopo->et() + // << " phi " << pTopo->phi() + // << " eta " << pTopo->eta() + // ); + + // //------------------------------------------------------------- + // // Cluster accepted, store in Pi0Cluster collection + // //------------------------------------------------------------- + + // //create temp cluster for cells storing + // xAOD::CaloCluster *pPi0cluster = CaloClusterStoreHelper::makeCluster(pCellContainer); + + // //copy cells from selected cluster into created pi0 cluster + // CaloCluster::cell_iterator cellIter = pTopo->cell_begin(); + // CaloCluster::cell_iterator cellIterE = pTopo->cell_end(); + + // for (; cellIter != cellIterE; ++cellIter) { + // //XXX still need to check this implementation + // pPi0cluster->addCell(cellIter.getElement().index(), 1.0); + // } + + // clusterPi0.push_back(pPi0cluster); + // pDetails->addPi0(pPi0cluster, 0); + // } + + // m_pi0Map[pDetails] = clusterPi0; + + + // /***** FIXME... + // // loop over pi0 clusters correction + // // correct position for zvertex + // // calculate barycentre + // // store as sumEM + // ***********/ + + // if (clusterPi0.empty()) { + // // no cluster found --> leave + // return StatusCode::SUCCESS; + // } + + // //--------------------------------------------------------------------- + // // Calculate and register energy weighted bary-center 4-momenta + // // corrected for the z-vertex position + // //--------------------------------------------------------------------- + + // float sumEMeta = 0; + // float sumEMphi = 0; + // float sumEMet = 0; + // float sumEMe = 0; + + // for (unsigned ipi0 = 0; ipi0 < clusterPi0.size(); ++ipi0) { + // const CaloCluster *pPi0Clus = clusterPi0[ipi0]; + // sumEMeta += pPi0Clus->et() * pPi0Clus->eta(); + // float resphi = phiRange.diff(pPi0Clus->phi(), pTau->phi()); + // sumEMphi += pPi0Clus->et() * resphi; + // sumEMet += pPi0Clus->et(); + // sumEMe += pPi0Clus->e(); + // } + + // float phiPi0 = phiRange.fix(sumEMphi / sumEMet + pTau->phi()); + // float etaPi0 = sumEMeta / sumEMet; + // float ePi0 = sumEMe; + + // //------------------------------------------------------------- + // // Correct for vertex position of the leading track + // //------------------------------------------------------------- + // double zvert = pTau->track(0)->measuredPerigee()->parameters()[Trk::z0]; + // float etaPi0zv; + // if (fabs(etaPi0) < 1.45) { + // double aeta = fabs(etaPi0); + // double r = 1691. - 39.4884 * aeta - 23.556412 * aeta*aeta; // FIXME approximate shower depth in barrel + // double z = r * sinh(etaPi0); + // double x = (z - zvert) / r; + // etaPi0zv = logf(x + sqrt(1. + x * x)); + // } else { + // double z = 3920; // FIXME approximate shower depth in emec + // if (etaPi0 < 0) z = -3920; + // double r = z / sinh(etaPi0); + // double x = (z - zvert) / r; + // etaPi0zv = logf(x + sqrt(1. + x * x)); + // } + + // ATH_MSG_VERBOSE(name() << " final combined Pi0 4-momenta " + // << " energy " << ePi0 + // << " phi " << phiPi0 + // << " etaZV " << etaPi0zv + // ); + + // double pxPi0 = ePi0 / cosh(etaPi0zv) * cos(phiPi0); + // double pyPi0 = ePi0 / cosh(etaPi0zv) * sin(phiPi0); + // double pzPi0 = ePi0 / cosh(etaPi0zv) * sinh(etaPi0zv); + + // // FIXME calculated with mass less hypothesis + // CLHEP::HepLorentzVector sumem(pxPi0, pyPi0, pzPi0, ePi0); + // pDetails->setSumPi0Vec(sumem); + + // ATH_MSG_VERBOSE(name() << " final Pi0 4-momenta (retrieve) " + // << " energy " << pDetails->sumPi0Vec().e() + // << " phi " << pDetails->sumPi0Vec().phi() + // << " etaZV " << pDetails->sumPi0Vec().eta() + // ); + + + return StatusCode::SUCCESS; +} + + + +//----------------------------------------------------------------------------- +// Cleanup, in case this candidate was rejected later +//----------------------------------------------------------------------------- + +void TauPi0CrakowClusterCreator::cleanup(TauCandidateData *data) { + + Analysis::TauCommonDetails *pDetails = dynamic_cast<Analysis::TauCommonDetails *> (data->details); + std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > ::iterator it; + it = m_pi0Map.find(pDetails); + + if (it != m_pi0Map.end()) { + std::for_each((*it).second.begin(), (*it).second.end(), do_delete); + m_pi0Map.erase(it); + } +} + + + + diff --git a/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h new file mode 100644 index 0000000000000000000000000000000000000000..9d47fd0567673b0f36c1b9e64d46ae72bbe2b2f2 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0CrakowClusterCreator.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TauPi0CrakowClusterCreator_H +#define TAUREC_TauPi0CrakowClusterCreator_H + +#include "tauRec/TauToolBase.h" +#include <map> + +namespace Analysis { + class TauCommonDetails; +} +class CaloCluster; + +/** + * @brief Class for creating Pi0 clusters from EMtopoForTaus collection. + * + * @author Elzbieta Richter-Was + * + */ + +class TauPi0CrakowClusterCreator : public TauToolBase { +public: + + TauPi0CrakowClusterCreator(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauPi0CrakowClusterCreator(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + + virtual void cleanup(TauCandidateData *data); + StatusCode fillTopoClusterInfo(TauCandidateData *data); + + +private: + + std::string m_trackContainerName; + double m_detRCoreCaloCut; + double m_recoTopoClusterETCut; + double m_recoEtaCut; + double m_detTrkClusMin; + double m_fracEM01verEM; + std::string m_CaloClusterContainerName; + + int m_nTopoClust; + + std::vector<int> m_isTopoClusQualif; + std::vector<double> m_TopoClustPhi; + std::vector<double> m_TopoClusEta; + + std::string m_pi0ContainerName; + + // CaloCluster with all cells after hypothesis of Pi0 + std::map<Analysis::TauCommonDetails *, std::vector<CaloCluster *> > m_pi0Map; +}; + +#endif /* TauPi0CrakowClusterCreator_H */ + diff --git a/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6508437694e08d89d43a779dfff4efc50d6631f3 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.cxx @@ -0,0 +1,184 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0CreatorChooser.cxx +// package: Reconstruction/tauEvent +// authors: Veit Scharf +// date: 2008-10-23 +//----------------------------------------------------------------------------- + +#include <algorithm> +#include "GaudiKernel/MsgStream.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloUtils/CaloClusterStoreHelper.h" +#include "tauEvent/TauCommonDetails.h" +#include "tauRec/TauPi0CreatorChooser.h" + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0CreatorChooser::TauPi0CreatorChooser(const std::string& type, + const std::string& name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_tau1p3pCreatePi0ClusTool("tau1p3pCreatePi0Clus"), +m_tauCommonCreatePi0ClusTool("TauCommonCreatePi0Clus"), +m_pi0ClusterContainerName("Tau1P3PPi0ClusterContainer") { + declareInterface<TauToolBase > (this); + + declareProperty("Tau1p3pCreatePi0ClusTool", m_tau1p3pCreatePi0ClusTool); + declareProperty("TauCommonCreatePi0ClusTool", m_tauCommonCreatePi0ClusTool); + declareProperty("Pi0ClusterContainer", m_pi0ClusterContainerName); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0CreatorChooser::~TauPi0CreatorChooser() { +} + +StatusCode TauPi0CreatorChooser::initialize() { + + StatusCode sc; + + sc = m_tau1p3pCreatePi0ClusTool.retrieve(); + if (sc.isFailure()) { + ATH_MSG_ERROR("Could not retrieve tau1p3pCreatePi0ClusTool."); + return sc; + } + + sc = m_tauCommonCreatePi0ClusTool.retrieve(); + if (sc.isFailure()) { + ATH_MSG_ERROR("Could not retrieve tauCommonCreatePi0ClusTool."); + return sc; + } + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0CreatorChooser::eventInitialize(TauCandidateData* data) { + + StatusCode sc; + sc = m_tau1p3pCreatePi0ClusTool->eventInitialize(data); + if (sc.isFailure()) { + return sc; + } + + sc = m_tauCommonCreatePi0ClusTool->eventInitialize(data); + if (sc.isFailure()) { + return sc; + } + + m_tauDetails.clear(); + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0CreatorChooser::execute(TauCandidateData* data) { + + StatusCode sc; + + m_tauDetails.push_back(dynamic_cast<Analysis::TauCommonDetails*> (data->details)); + if (data->tau->numTrack() != 1) + sc = m_tau1p3pCreatePi0ClusTool->execute(data); + else + sc = m_tauCommonCreatePi0ClusTool->execute(data); + + return sc; +} + +void TauPi0CreatorChooser::cleanup(TauCandidateData* data) { + if (data->tau->numTrack() != 1) + m_tau1p3pCreatePi0ClusTool->cleanup(data); + else + m_tauCommonCreatePi0ClusTool->cleanup(data); + + std::vector<Analysis::TauCommonDetails*>::iterator i = std::find(m_tauDetails.begin(), + m_tauDetails.end(), + dynamic_cast<Analysis::TauCommonDetails*> (data->details)); + + if (i != m_tauDetails.end()) + m_tauDetails.erase(i); + + return; +} + +StatusCode TauPi0CreatorChooser::eventFinalize(TauCandidateData* /* data */) { + + // Do not call eventFinalize methods of the child tools. They would record + // two CaloClusterContainers with the same name. Instead do the work here. + ATH_MSG_INFO("TauPi0CreatorChooser::eventFinalize"); + + MsgStream rLog(msgSvc(), name()); + + StatusCode sc; + + + + CaloClusterContainer *pPi0ClusterContainer = new CaloClusterContainer(); + + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::recordClusters(&*evtStore(), + // pPi0ClusterContainer, + // m_pi0ClusterContainerName, + // rLog); + + std::vector<Analysis::TauCommonDetails*>::iterator dataIt(m_tauDetails.begin()), + dataItE(m_tauDetails.end()); + + + if (sc.isFailure()) { + ATH_MSG_WARNING("Could not create CaloClusterContainer: " << m_pi0ClusterContainerName << ". No pi0's will be stored."); + + // remove all pi0s if registering the container fails. + for (; dataIt != dataItE; ++dataIt) { + if (*dataIt) (*dataIt)->pi0LinkVec().clear(); + } + + return StatusCode::SUCCESS; + } + + // store clusters in the new container + for (dataIt = m_tauDetails.begin(); dataIt != dataItE; ++dataIt) { + for (unsigned i = 0; i < (*dataIt)->nPi0(); ++i) { + pPi0ClusterContainer->push_back(const_cast<CaloCluster*>((*dataIt)->pi0(i))); + } + } + + //XXX need to check if we need this tool anymore. For now just make it fail all the time + sc = StatusCode::FAILURE; + // sc = CaloClusterStoreHelper::finalizeClusters(&*evtStore(), + // pPi0ClusterContainer, + // m_pi0ClusterContainerName, + // rLog); + + if (sc.isFailure()) { + ATH_MSG_WARNING("Could not finalize CaloClusterContainer " << m_pi0ClusterContainerName << ". No pi0's will be stored."); + // remove all pi0s if registering the container fails. + for (; dataIt != dataItE; ++dataIt) { + if (*dataIt) (*dataIt)->pi0LinkVec().clear(); + } + return StatusCode::SUCCESS; + } + + // update links in Tau1P3PDetails + std::vector<const CaloCluster*> tmp; + for (dataIt = m_tauDetails.begin(); dataIt != dataItE; ++dataIt) { + tmp.clear(); + for (unsigned i = 0; i < (*dataIt)->nPi0(); ++i) { + tmp.push_back((*dataIt)->pi0(i)); + } + (*dataIt)->pi0LinkVec().clear(); + for (unsigned i = 0; i < tmp.size(); ++i) { + (*dataIt)->addPi0(tmp.at(i), pPi0ClusterContainer); + } + } + + return StatusCode::SUCCESS; +} + diff --git a/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h new file mode 100644 index 0000000000000000000000000000000000000000..49fc73ad4ff38136940df7c128db938016b1deaf --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0CreatorChooser.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0CREATERCHOOSER_H +#define TAUREC_TAUPI0CREATERCHOOSER_H + +#include "GaudiKernel/ToolHandle.h" +#include "tauRec/TauToolBase.h" +#include <vector> +#include <string> + +namespace Analysis { + class TauCommonDetails; +} + +/** + * @brief Tool to select the correct Pi0 Finder. + * + * Part of the "Bonn" Pi0 Finder algorithm. + * + * @author Veit Scharf + */ + +class TauPi0CreatorChooser : public TauToolBase { +public: + TauPi0CreatorChooser(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauPi0CreatorChooser(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual void cleanup(TauCandidateData *data); + +private: + + ToolHandle<TauToolBase> m_tau1p3pCreatePi0ClusTool; + ToolHandle<TauToolBase> m_tauCommonCreatePi0ClusTool; + + std::vector<Analysis::TauCommonDetails*> m_tauDetails; + std::string m_pi0ClusterContainerName; +}; + + +#endif /* TAUREC_TAUPI0CREATERCHOOSER_H */ + diff --git a/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ef06f1f6857ff68156f8c4520351e0f158cd226b --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.cxx @@ -0,0 +1,514 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: tau1p3pTrackCreateROI.cxx +// package: Reconstruction/tauRec +// authors: Elzbieta Richter-Was (addapted from tau1p3pTrackMatchCells.cxx) +// date: June2007 +// +// Tool for collecting cells for tauROI +// +// 17/03/2010: AK: change to P4Helpers +// 16/05/2010 - (FF) pointer p_measPer never used (coverity 22627) +//----------------------------------------------------------------------------- + +//TODO: statuscode failure --> recoverable +//TODO: rename! + +#include "GaudiKernel/ListItem.h" + +#include "CaloEvent/CaloCluster.h" +#include "CaloUtils/CaloClusterStoreHelper.h" +#include "CaloInterface/ICaloNoiseTool.h" +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCell.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloEvent/CaloClusterContainer.h" + +#include "tauRec/KineUtils.h" + +#include "tauRec/TauOriginCorrectionTool.h" +#include "tauRec/TauPi0EflowCreateROI.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauPi0EflowCreateROI::TauPi0EflowCreateROI(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_cellsContainerName("AllCalo"), +m_cellsOutputContainerName("TauCells"), +m_detRIsolCaloCut(0.4), +m_detRCoreCaloCut(0.2), +m_useNoiseSigma(1), +m_AbsNoiseSigma_cut(2), +m_detRChrgEMCut(0.0375), +m_removeChrgEM01(0), +m_removeChrgEM2(0), +m_fillCellContainer(false), +m_pCellOutputContainer(0) , +m_doCellCorrection(false), //FF: don't do cell correction by default +m_tauOriginCorrTool("") +{ + declareInterface<TauToolBase > (this); + + declareProperty("CellsContainerName", m_cellsContainerName); + declareProperty("CellsOutputContainerName", m_cellsOutputContainerName); + // declare options for noise/weighting + declareProperty("useNoiseSigma", m_useNoiseSigma); + declareProperty("AbsNoiseSigma_cut", m_AbsNoiseSigma_cut); + declareProperty("CaloNoiseTool", m_noiseTool, "Tool Handle for noise tool"); + // declare large fixed cone for creating subcollection of cells (cluster) + declareProperty("detRCoreCaloCut", m_detRCoreCaloCut); + declareProperty("detRChrgEMCut", m_detRChrgEMCut); + declareProperty("removeChrgEM01", m_removeChrgEM01); + declareProperty("removeChrgEM2", m_removeChrgEM2); + declareProperty("detRIsolCaloCut", m_detRIsolCaloCut); + declareProperty("fillCellContainer", m_fillCellContainer); + declareProperty("CaloCellMakerToolNames", m_caloCellMakerToolNames); + declareProperty("CellCorrection", m_doCellCorrection); + declareProperty("OriginCorrectionTool", m_tauOriginCorrTool); +} + + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauPi0EflowCreateROI::~TauPi0EflowCreateROI() { +} + +//----------------------------------------------------------------------------- +// Event Initializer +//----------------------------------------------------------------------------- + +StatusCode TauPi0EflowCreateROI::eventFinalize(TauCandidateData *) { + + + if (m_fillCellContainer) { + + StatusCode sc; + + std::vector<ICaloCellMakerTool*>::iterator itrTool = m_caloCellMakerTools.begin(); + std::vector<ICaloCellMakerTool*>::iterator endTool = m_caloCellMakerTools.end(); + + unsigned int index = 0; + + ATH_MSG_DEBUG("Order and check container " << m_cellsOutputContainerName << " with " << m_caloCellMakerTools.size() << " tools"); + for (; itrTool != endTool; ++itrTool) { + + ATH_MSG_DEBUG("Calling tool " << m_caloCellMakerToolNames[index]); + + ListItem theItem(m_caloCellMakerToolNames[index]); + + sc = (*itrTool)->process(m_pCellOutputContainer); + + if (sc.isFailure()) { + ATH_MSG_ERROR("Error executing tool " << m_caloCellMakerToolNames[index]); + //TODO: return something? + } + ++index; + } + + ATH_MSG_DEBUG("setConst container " << m_cellsOutputContainerName); + sc = evtStore()->setConst(m_pCellOutputContainer); + if (sc.isFailure()) { + ATH_MSG_ERROR("Error while setting const: " << m_cellsOutputContainerName); + } + } + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Event Initializer +//----------------------------------------------------------------------------- + +StatusCode TauPi0EflowCreateROI::eventInitialize(TauCandidateData *) { + + StatusCode sc; + + const CaloCell_ID* cellID; + sc = detStore()->retrieve(cellID); + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to retrieve caloCell_ID helper from DetectorStore"); + return sc; + } + + //Build bitmap to keep track which cells have been added to CellContainer; + IdentifierHash hashMax; + + // Get hash range + hashMax = cellID->calo_cell_hash_max(); + ATH_MSG_VERBOSE("CaloCell Hash Max: " << hashMax); + m_addedCellsMap.resize(hashMax, false); + for (unsigned i = 0; i < hashMax; i++) { + m_addedCellsMap[i] = false; + } + //ak + m_clusterMap.clear(); + + // output cell container + // record here EMtopocluster + //--------------------------------------------------------------------- + if (m_fillCellContainer) { + m_pCellOutputContainer = new CaloCellContainer(SG::VIEW_ELEMENTS); + ATH_MSG_VERBOSE("record container " << m_cellsOutputContainerName); + sc = evtStore()->record(m_pCellOutputContainer, m_cellsOutputContainerName); + + if (sc.isFailure()) { + ATH_MSG_INFO("Unable to record " << m_cellsOutputContainerName << " to TES"); + } + } + + if (m_doCellCorrection) { + // Cell Origin Correction Tool initializeEvent is not called automatically + // -> call from here + sc = m_tauOriginCorrTool->eventInitialize(); + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to retrieve TauOriginCorrectionTool"); + return sc; + } + } + + return StatusCode::SUCCESS; +} + + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- + +StatusCode TauPi0EflowCreateROI::initialize() { + + ATH_MSG_VERBOSE(name() << " CellsContainerName = " << m_cellsContainerName); + ATH_MSG_VERBOSE(name() << " RconeTauCut = " << m_detRIsolCaloCut); + + //Create Noise Tools: + if (m_useNoiseSigma != 0) { + // SL changes to retrieval of CaloNoiseTool + if (m_noiseTool.retrieve().isFailure()) { + ATH_MSG_FATAL("Unable to find tool for Calorimeter Noise "); + return StatusCode::FAILURE; + } + } + + StatusCode sc; + //--------------------------------------------------------------------- + // Get pointer to Tool Service + //--------------------------------------------------------------------- + IToolSvc *pToolSvc; + sc = service("ToolSvc", pToolSvc); + if (sc.isFailure()) { + ATH_MSG_FATAL("Tool Service not found"); + return StatusCode::FAILURE; + } + + //--------------------------------------------------------------------- + // Need some tools for cells + //--------------------------------------------------------------------- + std::vector<std::string>::const_iterator itrName = m_caloCellMakerToolNames.begin(); + std::vector<std::string>::const_iterator endName = m_caloCellMakerToolNames.end(); + + IAlgTool* algtool; + for (; itrName != endName; ++itrName) { + + ListItem theItem(*itrName); + + ATH_MSG_DEBUG("Retrieving " << *itrName); + sc = pToolSvc->retrieveTool(theItem.type(), theItem.name(), algtool); + + if (sc.isFailure()) { + ATH_MSG_INFO("Unable to find tool for " << (*itrName)); + } else { + ATH_MSG_INFO((*itrName) << " successfully retrieved"); + + m_caloCellMakerTools.push_back(dynamic_cast<ICaloCellMakerTool*> (algtool)); + } + } + + if (m_tauOriginCorrTool.retrieve().isFailure()) { + ATH_MSG_ERROR("Cannot find tool named <" << m_tauOriginCorrTool << ">"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- + +StatusCode TauPi0EflowCreateROI::execute(TauCandidateData *data) { + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau->numTrack()==0) { + ATH_MSG_VERBOSE("tau has no tracks -> skip TrackCreateROI"); + return StatusCode::SUCCESS; + } + + StatusCode sc; + + //--------------------------------------------------------------------- + // Retrieve CaloCellCollection from StoreGate + //--------------------------------------------------------------------- + const CaloCellContainer *pCellContainer; + sc = evtStore()->retrieve(pCellContainer, m_cellsContainerName); + if (sc.isFailure()) { + ATH_MSG_INFO("TrackCreateROI: Unable to retrieve " << m_cellsContainerName << " from TES"); + } else { + ATH_MSG_VERBOSE("TrackCreateROI: Successfully retrieved " << m_cellsContainerName << " from TES"); + } + + + // output cell container + /* + CaloCellContainer *pCellOutputContainer; + if (m_fillCellContainer) { + sc = evtStore()->retrieve(pCellOutputContainer, m_cellsOutputContainerName); + if (sc.isFailure()) { + ATH_MSG_INFO("TrackCreateROI: Unable to retrieve " << m_cellsOutputContainerName << " from TES"); + } else { + ATH_MSG_VERBOSE("TrackCreateROI: Successfully retrieved " << m_cellsOutputContainerName << " from TES with size = " << pCellOutputContainer->size()); + } + } + */ + + //--------------------------------------------------------------------- + // Loop over cells collection and find closest cell at a given layer + // from track impact point at vertex and propagated in magnetic field + //--------------------------------------------------------------------- + + //do cell selection + //TODO: ATTENTION: distance 0.8 is hardcoded!! + CaloCellList *celllist = new CaloCellList(pCellContainer); + celllist->select(pTau->track(0)->eta(), pTau->track(0)->phi(), 0.8); + + if (celllist->ncells() == 0) { + delete celllist; + return StatusCode::FAILURE; + } + + // scan ROI twice: first to classify the case, second time to classify cells + + float sumEM01ChrgTrk = 0; + float sumEM2Chrg = 0; + float sumHADChrg = 0; + + //use tau vertex to correct cell position + if (m_doCellCorrection && pTau->vertexLink()) { + m_tauOriginCorrTool->setOriginSource( ( *pTau->vertexLink() ) ); + } + + const CaloCell *pCell; + pCell = 0; + + CaloCellList::list_iterator itr = celllist->begin(); + CaloCellList::list_iterator itrE = celllist->end(); + for (; itr != itrE; ++itr) { + pCell = *itr; + + //correct cell + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + + double cellPhi = pCell->phi(); + double cellEta = pCell->eta(); + double cellET = pCell->et(); + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + + // XXXXstill need to migrate track extrapolation + double detCell = Tau1P3PKineUtils::deltaR(pTau->track(0)->eta(),pTau->track(0)->phi(), cellEta, cellPhi); + // double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi); + + // collect all cells (remove noisy cells ) in a fixed + // large cone around candidate (at vertex) + if (detCell > m_detRIsolCaloCut) continue; + + // find position nominal position of the closest cell at each layer + int sampling = pCell->caloDDE()->getSampling(); + if (sampling == 4) sampling = 0; + if (sampling == 5) sampling = 1; + if (sampling == 6) sampling = 2; + if (sampling == 7) sampling = 3; + + if (sampling >= 3) sumHADChrg += cellET; + + if (sampling < 4) //ak + { + //for each track connected to tau object + for (unsigned int itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + double detEtaCell; + double detPhiCell; + // detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][sampling]); + // detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][sampling]); + // XXXXstill need to migrate track extrapolation + detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(itr)->eta()); + detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(itr)->phi()); + + //FIX ME! Should we look for different cell in eta and + //in phi? ot the closest one? + double detRCell = sqrt(detEtaCell * detEtaCell + detPhiCell * detPhiCell); + if (detRCell < m_detRChrgEMCut) { + if (sampling == 0 || sampling == 1) sumEM01ChrgTrk += cellET; + if (sampling == 2) sumEM2Chrg += cellET; + } + } + } //ak + } // end cell loop + + float category = 0; + float maxEM2Chrg = 0; + if (sumEM01ChrgTrk < 0.05 * pTau->track(0)->pt()) { + category = 1; + } else if (sumEM01ChrgTrk >= 0.05 * pTau->track(0)->pt() && sumHADChrg > 0.40 * pTau->track(0)->pt()) { + category = 2; + maxEM2Chrg = sumEM2Chrg - 2.5 * sumEM01ChrgTrk; + } + + float maxEMChrg = 0; + if (category == 1 || category == 2) { + maxEMChrg = 0.70 * pTau->track(0)->pt(); + } else { + maxEMChrg = 0.65 * pTau->track(0)->pt(); + } + + // if track was not interacting early, defined by finding 40% of trackPT in EM3+HAD, + // subtract cells only from EM2 + // if energy deposition in EM01, don't subtract in EM2 more then allowing up to + // 2.5*EM01 left in EM2 + + //counting subtracted cells, do not allow for more subtraction than 70% of track pt + unsigned int counter = 0; + + float sumEMChrg = 0; + sumEM2Chrg = 0.; + + itr = celllist->begin(); + for (; itr != itrE; ++itr) { + pCell = *itr; + + //correct cell + if (m_doCellCorrection) { + m_tauOriginCorrTool->correctCell(pCell); + } + + double cellPhi = pCell->phi(); + double cellEta = pCell->eta(); + double cellET = pCell->et(); + double cellEnergy = pCell->energy(); + + if (m_doCellCorrection) { + m_tauOriginCorrTool->resetCell(pCell); + } + + double detCell = Tau1P3PKineUtils::deltaR(pTau->track(0)->eta(),pTau->track(0)->phi(), cellEta, cellPhi); + // double detCell = P4Helpers::deltaR(*pTau->track(0), cellEta, cellPhi); + + // collect all cells (remove noisy cells ) in a fixed + // large cone around candidate (at vertex) + if (detCell > m_detRIsolCaloCut) continue; + + int isCellAccepted = 1; + + if (m_useNoiseSigma == 1) { + double noiseSigma; + noiseSigma = m_noiseTool->getNoise(*itr, ICalorimeterNoiseTool::ELECTRONICNOISE_HIGHESTGAIN); + if (fabs(cellEnergy) < m_AbsNoiseSigma_cut * noiseSigma) isCellAccepted = 0; + } + + // find position nominal position of the closest cell at each layer + int sampling = pCell->caloDDE()->getSampling(); + if (sampling == 4) sampling = 0; + if (sampling == 5) sampling = 1; + if (sampling == 6) sampling = 2; + if (sampling == 7) sampling = 3; + + if (sampling >= 3) isCellAccepted = 0; + + if (isCellAccepted == 0) continue; + + // remove cells in vicinity of the track + //TODO: if not necessary! + if (sampling < 4) //ak + { + //for each track connected to tau object + for (unsigned int itr = 0; itr < pTau->numTrack(); ++itr) { + // don't bother with matching for greater than 10 tracks (space only allocated for 10 tracks) + if (itr >= 9) break; + + double detEtaCell; + double detPhiCell; + // detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pExtraDetails->etaTrkCaloSamp()[itr][sampling]); + // detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pExtraDetails->phiTrkCaloSamp()[itr][sampling]); + // XXXXstill need to migrate track extrapolation + detEtaCell = Tau1P3PKineUtils::deltaEta(cellEta, pTau->track(itr)->eta()); + detPhiCell = Tau1P3PKineUtils::deltaPhi(cellPhi, pTau->track(itr)->phi()); + + //FIX ME! Should we look for different cell in eta and + //in phi? of the closest one? + + double detRCell = sqrt(detEtaCell * detEtaCell + detPhiCell * detPhiCell); + if (detRCell < m_detRChrgEMCut) { + + if (m_removeChrgEM2 == 1 && sampling == 2) { + if (sumEMChrg + cellET < maxEMChrg) { + if (category == 2 && (sumEM2Chrg + cellET < maxEM2Chrg)) { + isCellAccepted = 0; + sumEMChrg += cellET; + sumEM2Chrg += cellET; + } else { + isCellAccepted = 0; + sumEMChrg += cellET; + } + } + } + if (m_removeChrgEM01 == 1 && (sampling == 0 || sampling == 1) && category != 2) { + if (sumEMChrg + cellET < maxEMChrg) { + isCellAccepted = 0; + sumEMChrg += cellET; + } + } + + } + + } + } //ak + + + if (isCellAccepted == 0) continue; + + // add accepted cells to the container + if (m_fillCellContainer && m_pCellOutputContainer != 0) { + //Ask cell for it's hash + const IdentifierHash cellHash = pCell->caloDDE()->calo_hash(); + //Check it this cell is already part of reducedCellContainer + if (!m_addedCellsMap[cellHash]) { + ++counter; + m_pCellOutputContainer->push_back(pCell); + m_addedCellsMap[cellHash] = true; + } else + ATH_MSG_VERBOSE("Cell with hash " << cellHash << "added more than once."); + } + } //end 2nd cell loop + + delete celllist; + + ATH_MSG_DEBUG("Added " << counter << "cells to container " << m_cellsOutputContainerName); + + + return sc; +} diff --git a/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h new file mode 100644 index 0000000000000000000000000000000000000000..ba3f0057dfe7df94b95d6862f5bb934b935ec7f5 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauPi0EflowCreateROI.h @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAU1P3PTRACKCREATEROI_H +#define TAUREC_TAU1P3PTRACKCREATEROI_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "CaloInterface/ICalorimeterNoiseTool.h" +#include "CaloInterface/ICaloCellMakerTool.h" +#include <map> + +class ICaloNoiseTool; +class CaloCellContainer; +class TauOriginCorrectionTool; + +/** + * @brief Class for collecting cells for tau ROI. + * + * This tool was fomerly named as tau1p3pTrackCreateROI. + * + * @author Elzbieta Richter-Was + * + */ + +class TauPi0EflowCreateROI : public TauToolBase { +public: + + TauPi0EflowCreateROI(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauPi0EflowCreateROI(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + + +private: + + std::string m_cellsContainerName; + std::string m_cellsOutputContainerName; + std::string m_clusterContainerName; + + //! large fixed cone to collect cells around the track + double m_detRIsolCaloCut; + + //! large fixed cone to collect cells around the track + double m_detRCoreCaloCut; + + //! use noise tool to estimate sigma + double m_useNoiseSigma; + + //! threshold to suppress noisy cells + double m_AbsNoiseSigma_cut; + + //! threshold to suppress cell from being used for topo clustering + double m_detRChrgEMCut; + + //! threshold to suppress cell from being used for topo clustering + double m_removeChrgEM01; + + //! threshold to suppress cell from being used for topo clustering + double m_removeChrgEM2; + + // ! flag to decide wether we fill an output cell container to be later use for other clustering + bool m_fillCellContainer; + + //! tool for noise + ToolHandle<ICalorimeterNoiseTool> m_noiseTool; + + std::map<Analysis::TauJet *, CaloCluster *> m_clusterMap; + + std::vector<bool> m_addedCellsMap; + + std::vector<std::string> m_caloCellMakerToolNames ; + std::vector<ICaloCellMakerTool*> m_caloCellMakerTools ; + + CaloCellContainer * m_pCellOutputContainer; + + bool m_doCellCorrection; //<! enable cell origin correction + ToolHandle<TauOriginCorrectionTool> m_tauOriginCorrTool; + +}; + + +#endif diff --git a/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx new file mode 100644 index 0000000000000000000000000000000000000000..cf3dea0f39ee85c028c360507f722422f430cd64 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.cxx @@ -0,0 +1,85 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "tauRec/TauCandidateData.h" +#include "tauRec/TauSetTracksAndCharge.h" +#include "tauEvent/TauJetParameters.h" + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- +TauSetTracksAndCharge::TauSetTracksAndCharge(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent), +m_trackContainerName("TrackParticleCandidate") { + declareInterface<TauToolBase > (this); + declareProperty("TrackContainer", m_trackContainerName); +} + + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- +TauSetTracksAndCharge::~TauSetTracksAndCharge() { +} + + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- +StatusCode TauSetTracksAndCharge::initialize() { + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- +StatusCode TauSetTracksAndCharge::execute(TauCandidateData *data) { + + StatusCode sc; + const Rec::TrackParticleContainer *trackContainer; + + //SX changes needed by trigger + sc = data->getObject("TrackContainer", trackContainer); + + if (sc == StatusCode::FAILURE || !trackContainer) { + + ATH_MSG_DEBUG("no TrackParticleContainer for trigger"); + + StatusCode sc = evtStore()->retrieve(trackContainer, m_trackContainerName); + if (sc.isFailure() || !trackContainer) { + ATH_MSG_WARNING("Unable to retrieve track particle container <" << m_trackContainerName << ">!"); + return StatusCode::SUCCESS; + } + } + + Analysis::TauJet *pTau = data->tau; + + double charge = 0; + + for (unsigned int i = 0; i != pTau->seedCalo_numTrack(); ++i) { + + charge += pTau->track(i)->charge(); + + // add tracks to global tau track collection + pTau->addTrack(trackContainer, pTau->track(i)); + } + + ATH_MSG_INFO("seedCalo_numTrack = " << pTau->seedCalo_numTrack()); + ATH_MSG_INFO("numTrack = " << pTau->numTrack()); + + // save charge + ATH_MSG_DEBUG("charge from tracks: " << charge << " will be saved in tau candidate as: " << (int)charge); + pTau->set_charge((int) charge); + + return StatusCode::SUCCESS; +} + + + + diff --git a/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h new file mode 100644 index 0000000000000000000000000000000000000000..deb5f695046da6b735224153e287698475577b29 --- /dev/null +++ b/Reconstruction/tauRec/depreciated/TauSetTracksAndCharge.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUSETTRACKSANDCHARGE_H +#define TAUREC_TAUSETTRACKSANDCHARGE_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" + +class TauCandidateData; + +/** + * @brief Class to set number of tracks and charge of the tau (depreciated!) + * + * @author Felix Friedrich + */ + +class TauSetTracksAndCharge: public TauToolBase +{ + + public: + + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + TauSetTracksAndCharge( const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + virtual ~TauSetTracksAndCharge(); + + virtual StatusCode execute( TauCandidateData *data ); + virtual StatusCode initialize(); + + + private: + std::string m_trackContainerName; +}; + +#endif /* TAUSETTRACKSANDCHARGE_H */ + diff --git a/Reconstruction/tauRec/doc/mainpage.h b/Reconstruction/tauRec/doc/mainpage.h new file mode 100644 index 0000000000000000000000000000000000000000..6191183cd74dcbc445c810ba0f8f170325eb8cb6 --- /dev/null +++ b/Reconstruction/tauRec/doc/mainpage.h @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + +@mainpage tauRec +@author Srini Rajagopalan, Michael Heldmann, Elzbieta Richter-Was, Lukasz Janyst, Stan Lai, Nico Meyer, Anna Kaczmarska, Felix Friedrich + +@section Introduction + +This is the tauRec package. It holds algorithms to reconstruct hadronically decaying tau candidates. The tau reconstruction is using a calorimeter seeded approach. Tracks are collected in a cone around the calorimeter seed and associated to the tau candidate. An own tau energy scale is set. + +Packages used by tauRec are listed here: + +@htmlinclude used_packages.html + +The requirements file for tauRec is shown here: + +@include requirements + + +*/ diff --git a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py new file mode 100644 index 0000000000000000000000000000000000000000..97c802cf7654f5ec200bf84a1ee1e5d0117c8117 --- /dev/null +++ b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py @@ -0,0 +1,879 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +## +#@file TauAlgorithmsHolder.py +# +#@brief All tau algorithms needed for tau reconstruction are configured here. +# +#@author Felix Friedrich <felix.friedrich@cern.ch> +################################################################################ + +from AthenaCommon.SystemOfUnits import * +from AthenaCommon.Constants import * + +cached_instances = {} + +sPrefix = 'tauRec_' +bAODmode = False + +# standard container names +_DefaultVertexContainer = "PrimaryVertices" +_DefaultTrackContainer ="InDetTrackParticles" + +######################################################################## +def setPrefix(prefix): + global sPrefix + sPrefix = prefix + +######################################################################## +def setAODmode(mode): + global bAODmode + bAODmode = mode + + +######################################################################## +# Atlas Extrapolator +def getAtlasExtrapolator(): + _name = sPrefix + 'theAtlasExtrapolator' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + #Configure the extrapolator + from TrkExTools.AtlasExtrapolator import AtlasExtrapolator + theAtlasExtrapolator=AtlasExtrapolator(name = _name) + theAtlasExtrapolator.DoCaloDynamic = False # this turns off dynamic + + ToolSvc += theAtlasExtrapolator + cached_instances[_name] = theAtlasExtrapolator + return theAtlasExtrapolator + +######################################################################## +# JetSeedBuilder +def getJetSeedBuilder(seed_collection_name): + _name = sPrefix + 'JetSeedBuilder' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import JetSeedBuilder + JetSeedBuilder = JetSeedBuilder(name = _name, + JetCollection = seed_collection_name, + maxDist = 0.2, + minPt = 10.*GeV, + SwitchJetsEmScale = False) + + cached_instances[_name] = JetSeedBuilder + return JetSeedBuilder + +######################################################################## +# Tau energy calibration and tau axis direction +def getTauAxis(): + _name = sPrefix + 'TauAxis' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauAxisSetter + TauAxisSetter = TauAxisSetter( name = _name, + ClusterCone = 0.2, + CellCorrection = True) + + cached_instances[_name] = TauAxisSetter + return TauAxisSetter + +######################################################################## +# Tau energy calibration +def getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix=''): + + _name = sPrefix +'EnergyCalibrationLC' + postfix + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauCalibrateLC + TauCalibrateLC = TauCalibrateLC(name = _name, + calibrationFile = "EnergyCalibrationLC2012_retuned.root", + doEnergyCorrection = correctEnergy, + doAxisCorrection = correctAxis) + + cached_instances[_name] = TauCalibrateLC + return TauCalibrateLC + +######################################################################## +# Tau cell variables calculation +def getCellVariables(cellConeSize=0.2, prefix=''): + #if prefix is not given, take global one + if not prefix: + prefix=sPrefix + + _name = prefix + 'CellVariables' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauCellVariables + TauCellVariables = TauCellVariables(name = _name, + CellEthreshold = 0.2*GeV, + StripEthreshold = 0.2*GeV, + EMSumThreshold = 0.5*GeV, + EMSumRadius = 0.2, + CellCone = cellConeSize, + CellCorrection = True) + + cached_instances[_name] = TauCellVariables + return TauCellVariables + +######################################################################## +# ExtrapolateToCaloTool +def getExtrapolateToCaloTool(): + _name = sPrefix + 'ExtrapolateToCaloTool' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + from TrackToCalo.TrackToCaloConf import ExtrapolateToCaloTool + tauExtrapolateToCaloTool=ExtrapolateToCaloTool(name = _name, Extrapolator = getAtlasExtrapolator()) + + ToolSvc += tauExtrapolateToCaloTool + cached_instances[_name] = tauExtrapolateToCaloTool + return tauExtrapolateToCaloTool + + +######################################################################## +# calibrate tau at EM scale +def getEnergyCalibrationEM(): + _name = sPrefix + 'EnergyCalibrationEM' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauCalibrateEM + TauCalibrateEM = TauCalibrateEM(name = _name, response_functions_file = "EMTES_Fits_Oct2010.root") + + cached_instances[_name] = TauCalibrateEM + return TauCalibrateEM + +######################################################################## +######################################################################## +# Tracking Tools +# TODO: rearrange +######################################################################## + + +######################################################################## +# TauFullLinearizedTrackFactory +def getTauFullLinearizedTrackFactory(): + _name = sPrefix + 'TauFullLinearizedTrackFactory' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__FullLinearizedTrackFactory + TauFullLinearizedTrackFactory=Trk__FullLinearizedTrackFactory(name = _name, Extrapolator = getAtlasExtrapolator()) + + ToolSvc += TauFullLinearizedTrackFactory + cached_instances[_name] = TauFullLinearizedTrackFactory + return TauFullLinearizedTrackFactory + +######################################################################## +# TauCrossDistancesSeedFinder +def getTauCrossDistancesSeedFinder(): + _name = 'TauCrossDistancesSeedFinder' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + #first the seed finder utils + from TrkVertexSeedFinderUtils.TrkVertexSeedFinderUtilsConf import Trk__SeedNewtonTrkDistanceFinder + TauNewtonTrkDistanceFinder = Trk__SeedNewtonTrkDistanceFinder( name = sPrefix+'TauSeedNewtonTrkDistanceFinder') + ToolSvc += TauNewtonTrkDistanceFinder + + #then the seed finder tools + from TrkVertexSeedFinderTools.TrkVertexSeedFinderToolsConf import Trk__CrossDistancesSeedFinder + TauCrossDistancesSeedFinder = Trk__CrossDistancesSeedFinder( name = _name, TrkDistanceFinder=TauNewtonTrkDistanceFinder) + + cached_instances[_name] = TauCrossDistancesSeedFinder + ToolSvc +=TauCrossDistancesSeedFinder + return TauCrossDistancesSeedFinder + +######################################################################## +# TauAdaptiveVertexFitter +def getTauAdaptiveVertexFitter(): + _name = sPrefix + 'TauAdaptiveVertexFitter' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + #then the fitter utils + from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__ImpactPoint3dEstimator + TauInDetImpactPoint3dEstimator = Trk__ImpactPoint3dEstimator(name = sPrefix+'TauTrkImpactPoint3dEstimator', Extrapolator = getAtlasExtrapolator()) + ToolSvc += TauInDetImpactPoint3dEstimator + + from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__DetAnnealingMaker + TauDetAnnealingMaker = Trk__DetAnnealingMaker(name = sPrefix+'TauDetAnnealingMaker', SetOfTemperatures = [ 64, 32, 16, 8, 4, 2, 1 ] ) + ToolSvc += TauDetAnnealingMaker + + #then the fitters (smoother + adaptive with smoothing + fast billoir) + from TrkVertexFitters.TrkVertexFittersConf import Trk__SequentialVertexSmoother + TauSequentialVertexSmoother = Trk__SequentialVertexSmoother(name = sPrefix+'TauSequentialVertexSmoother') + ToolSvc += TauSequentialVertexSmoother + + from TrkVertexFitters.TrkVertexFittersConf import Trk__AdaptiveVertexFitter + TauAdaptiveVertexFitter = Trk__AdaptiveVertexFitter(name = _name, + SeedFinder=getTauCrossDistancesSeedFinder(), + ImpactPoint3dEstimator=TauInDetImpactPoint3dEstimator, + VertexSmoother=TauSequentialVertexSmoother, + AnnealingMaker=TauDetAnnealingMaker, + LinearizedTrackFactory=getTauFullLinearizedTrackFactory(), + XAODConverter="Trk::VxCandidateXAODVertex/VertexInternalEdmFactory") + + cached_instances[_name] = TauAdaptiveVertexFitter + ToolSvc +=TauAdaptiveVertexFitter + return TauAdaptiveVertexFitter + +######################################################################## +# TauTrackToVertexIPEstimator +def getTauTrackToVertexIPEstimator(): + _name = sPrefix + 'TauTrackToVertexIPEstimator' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + from TrkVertexFitterUtils.TrkVertexFitterUtilsConf import Trk__TrackToVertexIPEstimator + TauTrackToVertexIPEstimator = Trk__TrackToVertexIPEstimator(name = _name, + Extrapolator=getAtlasExtrapolator(), + LinearizedTrackFactory=getTauFullLinearizedTrackFactory()) + cached_instances[_name] = TauTrackToVertexIPEstimator + ToolSvc += TauTrackToVertexIPEstimator + return TauTrackToVertexIPEstimator + +######################################################################## +# lock tau containers +def getContainerLock(): + _name = sPrefix + 'TauContainerLock' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import LockTauContainers + LockTauContainers = LockTauContainers(name = _name) + + cached_instances[_name] = LockTauContainers + return LockTauContainers + +######################################################################### +# Tau Variables +# TODO: rename + rearrange +def getTauCommonCalcVars(): + _name = sPrefix + 'TauCommonCalcVars' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauCommonCalcVars + TauCommonCalcVars = TauCommonCalcVars(name = _name) + + cached_instances[_name] = TauCommonCalcVars + return TauCommonCalcVars + +######################################################################### +# Tau Test +def getTauTestDump(): + _name = sPrefix + 'TauTestDump' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauTestDump + TauTestDump = TauTestDump(name = _name) + + cached_instances[_name] = TauTestDump + return TauTestDump + +######################################################################### +# Tau Vertex Variables +def getTauVertexVariables(): + _name = sPrefix + 'TauVertexVariables' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecFlags import jobproperties + useOldSeedFinderAPI = jobproperties.tauRecFlags.useOldVertexFitterAPI() + + from tauRec.tauRecConf import TauVertexVariables + TauVertexVariables = TauVertexVariables( name = _name, + PrimaryVertexKey = _DefaultVertexContainer, + TrackToVertexIPEstimator = getTauTrackToVertexIPEstimator(), + VertexFitter = getTauAdaptiveVertexFitter(), + #VertexFitter = "Trk::AdaptiveVertexFitter/InDetAdaptiveVxFitterTool", + SeedFinder = getTauCrossDistancesSeedFinder(), + XAODConverter = "Trk::VxCandidateXAODVertex/VertexInternalEdmFactory", # ATM only needed in case old API is used + TrackParticleContainer = _DefaultTrackContainer, # ATM only needed in case old API is used + useOldSeedFinderAPI = useOldSeedFinderAPI, + #OutputLevel = 2 + ) + + cached_instances[_name] = TauVertexVariables + return TauVertexVariables + +######################################################################### +# Tau Variables +# TODO: rename + rerrange +def getTauSubstructure(): + _name = sPrefix + 'TauSubstructure' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauSubstructureVariables + TauSubstructureVariables = TauSubstructureVariables( name = _name, + # parameters for CaloIsoCorrected variable + maxPileUpCorrection = 4000., #MeV + pileUpAlpha = 1.0, + VertexCorrection = True, + inAODmode = bAODmode) + + cached_instances[_name] = TauSubstructureVariables + return TauSubstructureVariables + +######################################################################### +# ele veto variables +def getElectronVetoVars(): + _name = sPrefix + 'TauElectronVetoVars' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauElectronVetoVariables + TauElectronVetoVariables = TauElectronVetoVariables(name = _name, + CellCorrection = True, + TTCExtrapolator = getExtrapolateToCaloTool()) + + cached_instances[_name] = TauElectronVetoVariables + return TauElectronVetoVariables + + +######################################################################### +# cell weight tool +def getCellWeightTool(): + _name = sPrefix + 'CellWeightTool' + + if _name in cached_instances: + return cached_instances[_name] + + #from CaloClusterCorrection.CaloClusterCorrectionConf import H1WeightToolCSC12Generic + from CaloRec.CaloTopoClusterFlags import jobproperties + # -- auto configure weight tool + finder = jobproperties.CaloTopoClusterFlags.cellWeightRefFinder.get_Value() + size = jobproperties.CaloTopoClusterFlags.cellWeightRefSize.get_Value() + signal = jobproperties.CaloTopoClusterFlags.cellWeightRefSignal.get_Value() + + from CaloClusterCorrection.StandardCellWeightCalib import getCellWeightTool + CaloWeightTool = getCellWeightTool(finder,size,signal) + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += CaloWeightTool + + cached_instances[_name] = CaloWeightTool + return CaloWeightTool + +######################################################################### +# Bonn Pi0 algo +# Cluster finder for Pi0 algo +def getBonnPi0ClusterFinder(): + _name = sPrefix + 'BonnPi0ClusterFinder' + + if _name in cached_instances: + return cached_instances[_name] + + from CaloRec.CaloRecConf import CaloCellContainerFinalizerTool + TauCellContainerFinalizer = CaloCellContainerFinalizerTool(name=sPrefix+'tauPi0CellContainerFinalizer') + + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += TauCellContainerFinalizer + + from tauRec.tauRecConf import TauPi0BonnCreateROI + TauPi0BonnCreateROI = TauPi0BonnCreateROI(name = _name, + CaloWeightTool = getCellWeightTool(), + ExtrapolateToCaloTool = getExtrapolateToCaloTool(), + CellMakerTool = TauCellContainerFinalizer, + #LonParFile = "longitudinal_para.dat", + #LatParFile = "lateral_para.dat", + LatParFile = "lateral_para.root", + #OriginCorrectionTool = getTauCellCorrection(), + ChargedPFOContainerName = 'TauPi0ChargedPFOContainer', + ) + + cached_instances[_name] = TauPi0BonnCreateROI + return TauPi0BonnCreateROI + +##################### +# create Pi0 clusters +def getBonnPi0ClusterCreator(): + _name = sPrefix + 'BonnPi0ClusterCreator' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauPi0BonnClusterCreator + TauPi0BonnClusterCreator = TauPi0BonnClusterCreator(name = _name, + ExtrapolateToCaloTool = getExtrapolateToCaloTool(), + InputPi0ClusterContainerName = 'TauPi0SubtractedClusterContainer', + OutputPi0ClusterContainerName = 'TauPi0ClusterContainer', + NeutralPFOContainerName= 'TauPi0NeutralPFOContainer', + ) + + cached_instances[_name] = TauPi0BonnClusterCreator + return TauPi0BonnClusterCreator + +##################### +# calculate MVA scores of pi0 clusters +def getPi0BonnScoreCalculator(): + _name = sPrefix + 'BonnPi0ScoreCalculator' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauPi0BonnScoreCalculator + TauPi0BonnScoreCalculator = TauPi0BonnScoreCalculator(name = _name, + ReaderOption = 'Silent:!Color', + BDTWeightFile = 'TauPi0BonnBDTWeights.xml', + ) + + cached_instances[_name] = TauPi0BonnScoreCalculator + return TauPi0BonnScoreCalculator + +##################### +# select pi0 clusters +def getPi0BonnSelector(): + _name = sPrefix + 'BonnPi0Selector' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauPi0BonnSelector + TauPi0BonnSelector = TauPi0BonnSelector(name = _name, + ClusterEtCut = (2100.*MeV,2500.*MeV,2600.*MeV,2400.*MeV,1900.*MeV), + ClusterBDTCut_1prong = (0.46,0.39,0.51,0.47,0.54), + ClusterBDTCut_mprong = (0.47,0.52,0.60,0.55,0.50), + ) + + cached_instances[_name] = TauPi0BonnSelector + return TauPi0BonnSelector + + + + +######################################################################### +# Photon Shot Finder algo +def getTauShotFinder(): + _name = sPrefix + 'TauShotFinder' + + if _name in cached_instances: + return cached_instances[_name] + + #from CaloRec.CaloRecConf import CaloCellContainerFinalizerTool + #TauCellContainerFinalizer = CaloCellContainerFinalizerTool(name=sPrefix+'tauShotCellContainerFinalizer') + #from AthenaCommon.AppMgr import ToolSvc + #ToolSvc += TauCellContainerFinalizer + + from tauRec.tauRecConf import TauShotFinder + TauShotFinder = TauShotFinder(name = _name, + CaloWeightTool = getCellWeightTool(), + ReaderOption = "Silent:!Color", + BDTWeightFile_barrel = "TauShotsBDTWeights.xml", + BDTWeightFile_endcap1 = "TauShotsBDTWeights.xml", + BDTWeightFile_endcap2 = "TauShotsBDTWeights.xml", + NCellsInEta = 5, + MinPtCut = (400.*MeV,320.*MeV,9999999.*MeV,350.*MeV,320.*MeV), + AutoDoubleShotCut = (10000.*MeV,10000.*MeV,9999999.*MeV,10000.*MeV,10000.*MeV), + MergedBDTScoreCut = (-9999999.,-9999999.,-9999999.,-9999999.,-9999999.), + ) + cached_instances[_name] = TauShotFinder + return TauShotFinder + + + + + + +######################################################################### +def getInDetTrackSelectorTool(): + _name = sPrefix + 'InDetTrackSelectorTool' + + if _name in cached_instances: + return cached_instances[_name] + + #Configures tau track selector tool (should eventually check whether an existing one is available) + from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetDetailedTrackSelectorTool + InDetTrackSelectorTool = InDet__InDetDetailedTrackSelectorTool(name = _name, + pTMin = 1000., + IPd0Max = 1., + IPz0Max = 1.5, + useTrackSummaryInfo = True, + nHitBLayer = 0, + nHitPix = 2, # PixelHits + PixelDeadSensors + nHitSct = 0, # SCTHits + SCTDeadSensors + nHitSi = 7, # PixelHits + SCTHits + PixelDeadSensors + SCTDeadSensors + nHitTrt = 0, # nTRTHits + useSharedHitInfo = False, + nSharedBLayer = 99999, + nSharedPix = 99999, + nSharedSct = 99999, + nSharedSi = 99999, + useTrackQualityInfo = True, + fitChi2OnNdfMax = 99999, + TrackSummaryTool = None, + Extrapolator = getAtlasExtrapolator()) + + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += InDetTrackSelectorTool + + cached_instances[_name] = InDetTrackSelectorTool + return InDetTrackSelectorTool + + +############################################################################ +# setup up JVA tools +def setupTauJVFTool(): + from AthenaCommon.AppMgr import ToolSvc + + """ + #Configures tau track selector tool for TJVA + from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetDetailedTrackSelectorTool + InDetTrackSelectorToolForTJVA = InDet__InDetDetailedTrackSelectorTool(name = sPrefix + 'InDetTrackSelectorToolForTJVA', + pTMin = 1000., + IPd0Max = 9999.*mm, + IPz0Max = 9999.*mm, + nHitPix = 2, # PixelHits + PixelDeadSensors + nHitSct = 0, # SCTHits + SCTDeadSensors + nHitSi = 7, # PixelHits + SCTHits + PixelDeadSensors + SCTDeadSensors + fitChi2OnNdfMax = 99999, + TrackSummaryTool = None, + Extrapolator = getAtlasExtrapolator()) + + ToolSvc += InDetTrackSelectorToolForTJVA + """ + from JetRec.JetRecConf import JetAlgorithm + jetTrackAlg = JetAlgorithm("JetTrackAlg_forTaus") + + """ + from JetRecTools.JetRecToolsConf import JetTrackSelectionTool + ToolSvc += JetTrackSelectionTool(InputContainer = _DefaultTrackContainer, + OutputContainer="JetSelectedTracks_forTaus", + Selector=InDetTrackSelectorToolForTJVA, + OutputLevel=2 + # what is about ptmin, eta min/max??? + ) + """ + + from JetRecTools.JetRecToolsConf import TrackVertexAssociationTool + ToolSvc += TrackVertexAssociationTool(TrackParticleContainer = _DefaultTrackContainer , + TrackVertexAssociation="JetTrackVtxAssoc_forTaus", + VertexContainer= _DefaultVertexContainer, + MaxTransverseDistance = 2.5 *mm, + MaxLongitudinalDistance = 2 *mm, + #OutputLevel=2 + ) + #jetTrackAlg.Tools = [ToolSvc.JetTrackSelectionTool , ToolSvc.TrackVertexAssociationTool ] + jetTrackAlg.Tools = [ToolSvc.TrackVertexAssociationTool ] + + from AthenaCommon.AlgSequence import AlgSequence + topSequence = AlgSequence() + topSequence+=jetTrackAlg + +######################################################################### +def getTauVertexFinder(doUseTJVA=False): + _name = sPrefix + 'TauVertexFinder' + + if _name in cached_instances: + return cached_instances[_name] + + if doUseTJVA: + setupTauJVFTool() + + # Algorithm that overwrites numTrack() and charge() of all tauJets in the container + from tauRec.tauRecConf import TauVertexFinder + TauVertexFinder = TauVertexFinder(name = _name, + UseTJVA = doUseTJVA, + PrimaryVertexContainer = _DefaultVertexContainer, + AssociatedTracks="GhostTrack", # OK?? + TrackVertexAssociation="JetTrackVtxAssoc_forTaus" + ) + + cached_instances[_name] = TauVertexFinder + return TauVertexFinder + +######################################################################### +def getTrackToVertexTool(): + _name = sPrefix + 'TrackToVertexTool' + + if _name in cached_instances: + return cached_instances[_name] + + from TrackToVertex.TrackToVertexConf import Reco__TrackToVertex + TrackToVertexTool = Reco__TrackToVertex( name = _name, + Extrapolator = getAtlasExtrapolator()) + + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += TrackToVertexTool + + cached_instances[_name] = TrackToVertexTool + return TrackToVertexTool + +######################################################################## +# Tau-Track Association +def getTauTrackFinder(): + _name = sPrefix + 'TauTrackFinder' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauTrackFinder + TauTrackFinder = TauTrackFinder(name = _name, + MaxJetDrTau = 0.2, + MaxJetDrWide = 0.4, + TrackSelectorToolTau = getInDetTrackSelectorTool(), + TrackParticleContainer = _DefaultTrackContainer, + TrackToVertexTool = getTrackToVertexTool(), + TTCExtrapolator = getExtrapolateToCaloTool() + #maxDeltaZ0wrtLeadTrk = 2, #in mm + #removeTracksOutsideZ0wrtLeadTrk = True + ) + + cached_instances[_name] = TauTrackFinder + return TauTrackFinder + +######################################################################## +# TauTrackFilter +def getTauTrackFilter(): + _name = sPrefix + 'TauTrackFilter' + from tauRec.tauRecConf import TauTrackFilter + TauTrackFilter = TauTrackFilter(name = _name, TrackContainerName=_DefaultTrackContainer) + cached_instances[_name] = TauTrackFilter + return TauTrackFilter + +######################################################################## +# TauGenericPi0Cone +def getTauGenericPi0Cone(): + _name = sPrefix + 'TauGenericPi0Cone' + from tauRec.tauRecConf import TauGenericPi0Cone + TauGenericPi0Cone = TauGenericPi0Cone(name = _name) + cached_instances[_name] = TauGenericPi0Cone + return TauGenericPi0Cone + +#end + +""" obsolete methods + +######################################################################## +# Tau Origin Cell Correction Tool +def getTauCellCorrection(): + _name = sPrefix + 'TauCellCorrection' + + from AthenaCommon.AppMgr import ToolSvc + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauOriginCorrectionTool + TauCellCorrectionTool = TauOriginCorrectionTool(name = _name, + UseJVA = False, #not using JetVertexAssociation, b/c JetRec doesn't use it too + UsePrimaryVertex = True, + UseBeamSpot = True, + VertexContainerKey = "PrimaryVertices") + + ToolSvc += TauCellCorrectionTool + cached_instances[_name] = TauCellCorrectionTool + return TauCellCorrectionTool + +######################################################################### +# CaloNoiseTool +def getCaloNoiseTool(): + _name = 'CaloNoiseTool' + + if _name in cached_instances: + return cached_instances[_name] + + from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault + theCaloNoiseTool = CaloNoiseToolDefault() + + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += theCaloNoiseTool + + cached_instances[_name] = theCaloNoiseTool + return theCaloNoiseTool + +######################################################################### +# tau1p3p track match cells +def getTauEflowTrackMatchCells(): + _name = sPrefix + 'EflowTrackMatchCells' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauEflowTrackMatchCells + TauEflowTrackMatchCells = TauEflowTrackMatchCells(name = _name, + detRIsolCaloCut = 0.4, + useNoiseSigma = 1, + AbsNoiseSigma_cut = 2, + CaloNoiseTool = getCaloNoiseTool(), + selectConeSize = 0.45, #not used anymore + CellCorrection = True, + OriginCorrectionTool = getTauCellCorrection()) + + cached_instances[_name] = TauEflowTrackMatchCells + return TauEflowTrackMatchCells + +######################################################################### +# tau1p3p AddCaloInfo +def getTauEflowAddCaloInfo(): + _name = sPrefix + 'EflowAddCaloInfo' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauEflowAddCaloInfo + TauEflowAddCaloInfo = TauEflowAddCaloInfo(name = _name, + detRCoreCaloCut = 0.2, + detRIsolCaloCut = 0.4, + ETCellMinCut = 0.1*GeV, + ETStripMinCut = 0.2*GeV, + detaStripCut = 0.2, + CellCorrection = True, + OriginCorrectionTool = getTauCellCorrection()) + + cached_instances[_name] = TauEflowAddCaloInfo + return TauEflowAddCaloInfo + +######################################################################### +# tau1p3p eflow info +def getTauEflowVariables(): + _name = sPrefix + 'EflowVariables' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauEflowVariables + TauEflowVariables = TauEflowVariables(name = _name, + detRCoreCaloCut = 0.2, + dphiEMCLCut = 0.0375, + detaEMCLCut = 0.0375, + dphiEMCLFACCut = 2, + detaEMCLFACCut = 3, + dphiChrgEMCut = 0.0375, + detaChrgEMCut = 0.0375, + CaloClusterContainerName = "EMTopoForTaus", #TODO: rec.scoping<3 case?? + RecoTopoClusterETCut = 0.2*GeV, + RecoEtaCut = 2.5, + TrackTopoClusPhi2Cut = 0.0375, + TrackTopoClusEta1Cut = 0.01, + MVisEflowCut = 10.*GeV, + MTrk3PCut = 10.*GeV, + ETeflow_ETcaloCut = 10., + ETeflow_ETcaloCutMin = 0.1, + useEMTopoClusters = True, + CellCorrection = True, + OriginCorrectionTool = getTauCellCorrection()) + + cached_instances[_name] = TauEflowVariables + return TauEflowVariables + +##################### +# Pi0 Creator Chooser +def getPi0CreatorChooser(): + _name = sPrefix + 'Pi0CreatorChooser' + + if _name in cached_instances: + return cached_instances[_name] + + from AthenaCommon.AppMgr import ToolSvc + ToolSvc += getBonnPi0ClusterCreator() + ToolSvc += getCrakowPi0ClusterCreator() + + from tauRec.tauRecConf import TauPi0CreatorChooser + TauPi0CreatorChooser = TauPi0CreatorChooser(name = _name, + Tau1p3pCreatePi0ClusTool = getCrakowPi0ClusterCreator(), + TauCommonCreatePi0ClusTool = getBonnPi0ClusterCreator()) + + cached_instances[_name] = TauPi0CreatorChooser + return TauPi0CreatorChooser + +######################################################################### +# Crakow Pi0/eflow algorithm +# Cluster/Cellfinder for Pi0/Eflow algos +def getPi0EflowCreateROI(): + _name = sPrefix + 'TauPi0EflowCreateROI' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauPi0EflowCreateROI + TauPi0EflowCreateROI = TauPi0EflowCreateROI( name = _name, + detRIsolCaloCut = 0.4, + detRCoreCaloCut = 0.2, + useNoiseSigma = 0, + AbsNoiseSigma_cut = 2, + removeChrgEM01 = 1, + removeChrgEM2 = 1, + detRChrgEMCut = 0.0375, + # Added by SL + fillCellContainer = TRUE, + CellsOutputContainerName = "TauCells", + CaloNoiseTool = getCaloNoiseTool(), + CaloCellMakerToolNames = ["CaloCellContainerFinalizerTool/cellfinalizerForTaus","CaloCellContainerCheckerTool/cellcheckForTaus"], + CellCorrection = True, + OriginCorrectionTool = getTauCellCorrection()) + + cached_instances[_name] = TauPi0EflowCreateROI + return TauPi0EflowCreateROI + +################ +# Pi0 Clustering +def getCrakowPi0ClusterCreator(): + _name = sPrefix + 'CrakowPi0ClusterCreator' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauPi0CrakowClusterCreator + TauPi0CrakowClusterCreator = TauPi0CrakowClusterCreator( name = _name, + detRCoreCaloCut = 0.2, + CaloClusterContainerName = "EMTopoForTaus", #TODO: rec.scoping<3 case?? + RecoTopoClusterETCut = 1.0*GeV, + RecoEtaCut = 2.5, + detTrkClusMin = 0.0375, + fracEM01verEM = 0.1) + + cached_instances[_name] = TauPi0CrakowClusterCreator + return TauPi0CrakowClusterCreator + +######################################################################## +# set track infos (charge + global track collection) +def getTauSetTracksAndCharge(): + _name = sPrefix + 'TauSetTracksAndCharge' + + if _name in cached_instances: + return cached_instances[_name] + + from tauRec.tauRecConf import TauSetTracksAndCharge + TauSetTracksAndCharge = TauSetTracksAndCharge(name = _name, TrackContainer = "TrackParticleCandidate") + + cached_instances[_name] = TauSetTracksAndCharge + return TauSetTracksAndCharge + +""" diff --git a/Reconstruction/tauRec/python/TauConversionAlgorithms.py b/Reconstruction/tauRec/python/TauConversionAlgorithms.py new file mode 100644 index 0000000000000000000000000000000000000000..9212a547725dee20e613e15e4c0f83781b66f0f4 --- /dev/null +++ b/Reconstruction/tauRec/python/TauConversionAlgorithms.py @@ -0,0 +1,223 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +## +#@file TauConversionsAlgorithms.py +# +#@brief Algorithms for new ConversionFinder are configured here. +# +# This file contains two functions: +# 1) getTauConversionFinderTool(): +# Returns the TauTool which assigns the conversion tracks to taujets +# 2) getPhotonConversionTool(): +# Returns the TauTool which finds conversion vertices +# Not a standalaone - meant to be used in other job options file +# +# +#@author KG Tan +#@date May 2011 +################################################################################ + + +from tauRec.tauRecFlags import jobproperties + +def getTauConversionFinderTool(): + if jobproperties.tauRecFlags.useVertexBasedConvFinder(): + inputConversionContainerName = "ConversionsVertex_Container" + minEProb = 0.04 + else: + inputConversionContainerName = "ConversionsPID_Container" + minEProb = 0.9 + from tauRec.tauRecConf import TauConversionFinder + TauConversionFinder = TauConversionFinder( + ConversionCandidatesName = inputConversionContainerName, + TrackContainerName = "InDetTrackParticles", + DoNormalTracks = True, + #DoLooseTracks = False, + MinElectronProbability = minEProb, + AdjustTauCharge = False + ) + return TauConversionFinder + +def getPhotonConversionTool(): + + if jobproperties.tauRecFlags.useVertexBasedConvFinder(): + from AthenaCommon.AppMgr import ToolSvc + + name = "_PhotonConversionVertex" + + #Configure the extrapolator + from TrkExTools.AtlasExtrapolator import AtlasExtrapolator + theAtlasExtrapolator=AtlasExtrapolator(name = 'theAtlasExtrapolator'+name) + theAtlasExtrapolator.DoCaloDynamic = False # this turns off dynamic + ToolSvc += theAtlasExtrapolator + + from TrkMagFieldTools.TrkMagFieldToolsConf import Trk__MagneticFieldTool + InDetMagField = Trk__MagneticFieldTool('InDetMagField'+name) + ToolSvc += InDetMagField + + # + # Setup track summary tool + # + from TrkTrackSummaryTool.AtlasTrackSummaryTool import AtlasTrackSummaryTool + MyInDetTrackSummaryTool = AtlasTrackSummaryTool(name = "MyInDetTrackSummaryTool"+name) + ToolSvc += MyInDetTrackSummaryTool + + from TrkVKalVrtFitter.TrkVKalVrtFitterConf import Trk__TrkVKalVrtFitter + InDetConversionVxFitterTool = Trk__TrkVKalVrtFitter(name = "InDetConversionVxFitter"+name, + Extrapolator = theAtlasExtrapolator, + IterationNumber = 30, + MakeExtendedVertex = True, + FirstMeasuredPoint = True, + MagFieldSvc = InDetMagField, + Robustness = 6, + usePhiCnst = False, + useThetaCnst = False, + FirstMeasuredPointLimit = True, + InputParticleMasses = [0.511,0.511], + VertexForConstraint = [0.,0.,0.], + CovVrtForConstraint = [0.015*0.015,0.,0.015*0.015,0.,0.,10000.*10000.]) + ToolSvc += InDetConversionVxFitterTool + print InDetConversionVxFitterTool + + # Distance of minimum approach utility + # + from TrkVertexSeedFinderUtils.TrkVertexSeedFinderUtilsConf import Trk__SeedNewtonTrkDistanceFinder + InDetConversionTrkDistanceFinder = Trk__SeedNewtonTrkDistanceFinder(name = 'InDetConversionTrkDistanceFinder'+name) + ToolSvc += InDetConversionTrkDistanceFinder + print InDetConversionTrkDistanceFinder + + # Straight line propagator needed to clean-up single track conversions + # + from TrkExSlPropagator.TrkExSlPropagatorConf import Trk__StraightLinePropagator as Propagator + InDetConversionPropagator = Propagator(name = 'InDetConversionPropagator'+name) + ToolSvc += InDetConversionPropagator + print InDetConversionPropagator + + # Helper Tool + # + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__ConversionFinderUtils + InDetConversionHelper = InDet__ConversionFinderUtils(name = "InDetConversionFinderUtils"+name) + ToolSvc += InDetConversionHelper + print InDetConversionHelper + + # Track selector tool + # + from InDetTrackSelectorTool.InDetTrackSelectorToolConf import InDet__InDetConversionTrackSelectorTool + InDetConversionTrackSelector = InDet__InDetConversionTrackSelectorTool(name = "InDetConversionTrackSelector"+name, + TrackSummaryTool = MyInDetTrackSummaryTool, + Extrapolator = theAtlasExtrapolator, + maxSiD0 = 10000., #50.0, + maxTrtD0 = 10000., #100., + maxSiZ0 = 10000., #350.0, + maxTrtZ0 = 10000., #1400., + minPt = 300, #InDetNewTrackingCuts.minSecondaryPt() + RatioCut1 = 0.0, #0.5, + RatioCut2 = 0.0, + RatioCut3 = 0.0) + + ToolSvc += InDetConversionTrackSelector + print InDetConversionTrackSelector + + + # Track pairs selector + # + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__TrackPairsSelector + InDetConversionTrackPairsSelector = InDet__TrackPairsSelector(name = "InDetConversionTrackPairsSelector"+name, + ConversionFinderHelperTool = InDetConversionHelper, + DistanceTool = InDetConversionTrkDistanceFinder, + MaxFirstHitRadius = 10000., + MaxEta = [0.12,10000.,10000.], #[0.5,1.0,0.5]) + MaxDistBetweenTracks = [6.6,10000.,10000.], #[6.,80.,30.] + MaxInitDistance = [10000.,10000.,10000.], + MinTrackAngle = 0.) + ToolSvc += InDetConversionTrackPairsSelector + print InDetConversionTrackPairsSelector + + # Vertex point estimator + # + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__VertexPointEstimator + InDetConversionVtxPointEstimator = InDet__VertexPointEstimator(name = "InDetConversionVtxPointEstimator"+name, + MaxTrkXYDiffAtVtx = [10000.,10000.,10000.], + MaxTrkZDiffAtVtx = [10000.,10000.,10000.], + MaxTrkXYValue = [10000.,10000.,10000.], + MinArcLength = [-10000., -10000., -10000.], + MaxArcLength = [10000., 10000., 10000.], + MinDeltaR = [-10000.,-10000.,-10000.], + MaxDeltaR = [10000.,10000.,10000.], + MaxHl = [10000.,10000.,10000.], + MaxPhi = [0.034, 10000., 10000.]) #[0.05, 0.1, 0.1]) + ToolSvc += InDetConversionVtxPointEstimator + print InDetConversionVtxPointEstimator + + # Conversion post selector + # + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__ConversionPostSelector + InDetConversionPostSelector = InDet__ConversionPostSelector(name = "InDetConversionPostSelector"+name, + MaxChi2Vtx = [10000.,10000.,10000.], #[40.,100.,80.], + MaxInvariantMass = [45.,25000.,25000.], #[60.,60.,30.], + MinFitMomentum = [0.,0.,0.], #[2000.,2000.,2000.], + MinRadius = [23.4,-10000.,-10000.], #[30.,35.,250.], + MinPt = 0., + MaxdR = 10000., #-250., + MaxPhiVtxTrk = 0.046) #0.2) + ToolSvc += InDetConversionPostSelector + print InDetConversionPostSelector + + # Single track conversion tool + # + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__SingleTrackConversionTool + InDetSingleTrackConversion = InDet__SingleTrackConversionTool(name = "InDetSingleTrackConversionTool"+name, + ConversionFinderHelperTool = InDetConversionHelper, + TrackSummaryTool = MyInDetTrackSummaryTool, + Extrapolator = theAtlasExtrapolator, + MinInitialHitRadius = 70., + MinRatioOfHLhits = 0.95) + ToolSvc += InDetSingleTrackConversion + print InDetSingleTrackConversion + + from InDetConversionFinderTools.InDetConversionFinderToolsConf import InDet__InDetConversionFinderTools + MyInDetConversionFinderTools = InDet__InDetConversionFinderTools(name = "InDetConversionFinderTools"+name, + VertexFitterTool = InDetConversionVxFitterTool, + TrackSelectorTool = InDetConversionTrackSelector, + TrackPairsSelector = InDetConversionTrackPairsSelector, + ConversionFinderHelperTool = InDetConversionHelper, + VertexPointEstimator = InDetConversionVtxPointEstimator, + PostSelector = InDetConversionPostSelector, + SingleTrackConversionTool = InDetSingleTrackConversion, + Extrapolator = theAtlasExtrapolator, + TrackParticleCollection = "InDetTrackParticles", + RemoveTrtTracks = False, + IsConversion = True) + ToolSvc += MyInDetConversionFinderTools + print MyInDetConversionFinderTools + + from tauRec.tauRecConf import PhotonConversionVertex + photonConv = PhotonConversionVertex(name = "PhotonConversionVertex", + TauRecContainer = "TauRecContainer", + TrackParticleContainer = "InDetTrackParticles", + OutputConversionVertexContainerName = "ConversionsVertex_Container", + MaxTauJetDr = 0.5, + ConversionFinderTool = MyInDetConversionFinderTools) + + return photonConv + + else: + from tauRec.tauRecConf import PhotonConversionPID + photonConv = PhotonConversionPID(ConversionCandidatesName = "ConversionCandidate", + ConversionOutputName = "ConversionsPID_Container", + ElectronProbability = 0.9) + return photonConv + +def getTauConversionTaggerTool(): + if jobproperties.tauRecFlags.useNewPIDBasedConvFinder(): + #Anything we need to do to run the tool + #Handled in TauRecBuilder.py + pass + else: + #Anything we need to do to avoid running the tool goes here + #Handled in TauRecBuilder.py + pass + from tauRec.tauRecConf import TauConversionTagger + TauConversionTagger = TauConversionTagger(ConversionTaggerVersion = 1) + return TauConversionTagger diff --git a/Reconstruction/tauRec/python/TauRecAODBuilder.py b/Reconstruction/tauRec/python/TauRecAODBuilder.py new file mode 100644 index 0000000000000000000000000000000000000000..87afc51c54f4a7e3f1b6c2fd6bdb40148661b89a --- /dev/null +++ b/Reconstruction/tauRec/python/TauRecAODBuilder.py @@ -0,0 +1,119 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +## +#@file TauRecAODBuilder.py +# +#@brief Main steering file to rerun parts of tau reconstruction on AODs. +# +# Only algorithms which don't need cell level informations can be used. +# This is an example of how to run tauRec on AODs and should later be called by AODCalib, AODFix or TauD3PDMaker. +# Copied from TauRecBuilder.py/TauRecBuilder::TauRecVariablesProcessor. +# +# Algorithms schedule here are independent from the standard tauRec chain. +# +#@author Felix Friedrich +# +################################################################################ + + +import os, sys, string + +from AthenaCommon.Logging import logging +from AthenaCommon.SystemOfUnits import * +from AthenaCommon.Constants import * +from AthenaCommon.AlgSequence import AlgSequence +import traceback + +from RecExConfig.Configured import Configured + +################################################################################ +## @class TauRecAODProcessor +# Calculate Tau variables and properties on AODs. +################################################################################ +class TauRecAODProcessor ( Configured ) : + """Calculate remaining Tau variables and properties. Use informations available also in AODs, so no cell level is needed.""" + + _outputType = "Analysis::TauJetContainer" + _outputKey = "TauRecContainer" + _outputDetailsType = "Analysis::TauDetailsContainer" + _outputDetailsKey = "TauRecDetailsContainer" + + def __init__(self, name = "TauProcessorAODTools", inAODmode=True, doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True, sequence = None): + self.name = name + self.doBonnPi0Clus = doBonnPi0Clus + self.msglevel = msglevel + self.AODmode = inAODmode + self.sequence = sequence + if sequence is None: + self.sequence = AlgSequence() + Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject) + + + def configure(self): + mlog = logging.getLogger ('TauRecAODProcessor::configure:') + mlog.info('entering') + + import tauRec.TauAlgorithmsHolder as taualgs + + ######################################################################## + # Tau Modifier Algos + ######################################################################## + try: + from tauRec.tauRecConf import TauProcessor + #TauProcessor.OutputLevel = 2 + self._TauProcessorHandle = TauProcessor( + name = self.name, + TauContainer = self._outputKey, + TauDetailsContainer = self._outputDetailsKey, + runOnAOD = self.AODmode) + + except Exception: + mlog.error("could not get handle to TauProcessor") + print traceback.format_exc() + return False + + + tools = [] + try: + taualgs.setAODmode(True) + ## ATTENTION ################################################################################## + # running these tau tools on AODs will lead to inconsistency with standard tau reconstruction + ############################################################################################### + #tools.append(taualgs.getTauVertexFinder(doUseTJVA=True)) + tools.append(taualgs.getTauAxis()) ##needed to set correct variables for energy calibration + #tools.append(taualgs.getTauTrackFinder()) + tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix='_onlyEnergy')) + + tools.append(taualgs.getTauVertexVariables()) + tools.append(taualgs.getTauCommonCalcVars()) + tools.append(taualgs.getTauSubstructure()) + tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=False, correctAxis=True, postfix='_onlyAxis')) + + # Run the conversion tagger if flagged to do so + import tauRec.TauConversionAlgorithms + from tauRec.tauRecFlags import jobproperties + if jobproperties.tauRecFlags.useNewPIDBasedConvFinder(): + tools.append(tauRec.TauConversionAlgorithms.getTauConversionTaggerTool()) + + # for testing purpose + #tools.append(taualgs.getTauTestDump()) + + self.TauProcessorHandle().Tools = tools + + except Exception: + mlog.error("could not append tools to TauProcessor") + print traceback.format_exc() + return False + + self.sequence += self.TauProcessorHandle() + + return True + + ############################################################################################# + # Helpers + ############################################################################################# + + def TauProcessorHandle(self): + return self._TauProcessorHandle + diff --git a/Reconstruction/tauRec/python/TauRecBuilder.py b/Reconstruction/tauRec/python/TauRecBuilder.py new file mode 100644 index 0000000000000000000000000000000000000000..558fa7ca9a7675ad276f4b5df9ce67f9735da218 --- /dev/null +++ b/Reconstruction/tauRec/python/TauRecBuilder.py @@ -0,0 +1,289 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +## +#@file TauRecBuilder.py +# +#@brief Main steering file to set up the different tau reconstruction steps. +# +#@author N. Meyer +#@author A. Kaczmarska +#@author Felix Friedrich +# +################################################################################ + +import os, sys, string + +from AthenaCommon.Logging import logging +from AthenaCommon.SystemOfUnits import * +from AthenaCommon.Constants import * +from AthenaCommon.BeamFlags import jobproperties +import traceback + +from RecExConfig.Configured import Configured + +# global tauRec config keys +_outputType = "xAOD::TauJetContainer_v1" +_outputKey = "TauRecContainer" +_outputAuxType = "xAOD::TauJetAuxContainer_v1" +_outputAuxKey = "TauRecContainerAux." +_track_collection = "InDetTrackParticles" +_jet_collection = "AntiKt4LCTopoJets" + +################################################################################ +## @class TauRecCoreBuilder +# Build proper tau candidates and associate tracks, vertex and cells +################################################################################ +class TauRecCoreBuilder ( Configured ) : + """Build proper tau candidates and associate tracks, vertex and cells. + Calculate properties based on cell informations. + Find clusters used for Pi0 identification and eflow variables. + PhotonConversion will be run here too. + """ + + _output = { _outputType:_outputKey , _outputAuxType:_outputAuxKey } + + def __init__(self, name = "TauCoreBuilder",doBonnPi0Clus=False, doTJVA=False, msglevel=3, ignoreExistingDataObject=True): + self.name = name + self.doBonnPi0Clus = doBonnPi0Clus + self.do_TJVA = doTJVA + self.msglevel = msglevel + Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject) + + + def configure(self): + mlog = logging.getLogger ('TauCoreBuilder.py::configure:') + mlog.info('entering') + + + from RecExConfig.RecFlags import rec + + # xxx ToDo: still needed? + from RecExConfig.ObjKeyStore import objKeyStore + objKeyStore.addManyTypesStreamESD(self._output) + objKeyStore.addManyTypesStreamAOD(self._output) + + from AthenaCommon.AlgSequence import AlgSequence + topSequence = AlgSequence() + + import tauRec.TauAlgorithmsHolder as taualgs + + ######################################################################## + # TauBuilder + # create the taus + try: + from tauRec.tauRecConf import TauBuilder + self._TauBuilderHandle = TauBuilder( + name = self.name, + SeedContainer = _jet_collection, + TauContainer = _outputKey, + TauAuxContainer = _outputAuxKey, + MaxEta = 2.5, + MinPt = 10.*GeV, + doCreateTauContainers = True) + except Exception: + mlog.error("could not get handle to TauBuilder") + print traceback.format_exc() + return False + + + tools = [] + try: + tools.append(taualgs.getJetSeedBuilder(_jet_collection)) + tools.append(taualgs.getTauVertexFinder(doUseTJVA=self.do_TJVA)) + tools.append(taualgs.getTauAxis()) + tools.append(taualgs.getTauTrackFinder()) + tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=True, correctAxis=False, postfix='_onlyEnergy')) + tools.append(taualgs.getCellVariables()) + tools.append(taualgs.getElectronVetoVars()) + # + tools.append(taualgs.getTauTrackFilter()) + tools.append(taualgs.getTauGenericPi0Cone()) + # + #tools.append(taualgs.getPi0EflowCreateROI()) + tools.append(taualgs.getTauShotFinder()) + if self.doBonnPi0Clus: + tools.append(taualgs.getBonnPi0ClusterFinder()) + + ##################################################################### + ## Tau Conversation Finder (found no one talking here...) + ## TODO: talk with KG about the status of the new PhotonConversionFinder + ## new PhotonConversionFinder is currently disabled (time consumption!) + ## old one is still in use + import tauRec.TauConversionAlgorithms + from tauRec.tauRecFlags import jobproperties + if jobproperties.tauRecFlags.useNewPIDBasedConvFinder(): + #Needs to run alone + tools.append(tauRec.TauConversionAlgorithms.getTauConversionTaggerTool()) + else: + #Need to run together, they will select either PID or vertex based on another flag + tools.append(tauRec.TauConversionAlgorithms.getPhotonConversionTool()) + tools.append(tauRec.TauConversionAlgorithms.getTauConversionFinderTool()) + + #tools.append(taualgs.getContainerLock()) + self.TauBuilderHandle().Tools = tools + + except Exception: + mlog.error("could not append tools to TauBuilder") + print traceback.format_exc() + return False + + # run first part of Tau Builder + topSequence += self.TauBuilderHandle() + + return True + + # Helpers + def TauBuilderHandle(self): + return self._TauBuilderHandle + + def outputKey(self): + return self._output[self._outputType] + + def outputType(self): + return self._outputType + + + +################################################################################ +## @class TauRecPi0EflowProcessor +# Calculate eflow information and run the Pi0 finder algorithms +################################################################################ +class TauRecPi0EflowProcessor ( Configured ) : + """Calculate eflow information and run the Pi0 finder algorithms. + This needs to be done in a separate step, because first special cluster and cell container have to be build. + """ + + def __init__(self, name = "TauProcessorPi0EflowTools",doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True): + self.name = name + self.doBonnPi0Clus = doBonnPi0Clus + self.msglevel = msglevel + Configured.__init__(self,ignoreExistingDataObject=ignoreExistingDataObject) + + def configure(self): + mlog = logging.getLogger ('TauRecPi0EflowProcessor::configure:') + mlog.info('entering') + + + from AthenaCommon.AlgSequence import AlgSequence + topSequence = AlgSequence() + + import tauRec.TauAlgorithmsHolder as taualgs + + ######################################################################## + # Tau Modifier Algos + ######################################################################## + try: + from tauRec.tauRecConf import TauProcessor + self._TauProcessorHandle = TauProcessor( + name = self.name, + TauContainer = _outputKey, + TauAuxContainer = _outputAuxKey, + ) + except Exception: + mlog.error("could not get handle to TauProcessor") + print traceback.format_exc() + return False + + tools = [] + try: + #tools.append(taualgs.getTauEflowTrackMatchCells()) + #tools.append(taualgs.getTauEflowAddCaloInfo()) + #tools.append(taualgs.getTauEflowVariables()) + + if self.doBonnPi0Clus: tools.append(taualgs.getBonnPi0ClusterCreator()) + + self.TauProcessorHandle().Tools = tools + + except Exception: + mlog.error("could not append tools to TauProcessor") + print traceback.format_exc() + return False + + topSequence += self.TauProcessorHandle() + + return True + + # Helpers + def TauProcessorHandle(self): + return self._TauProcessorHandle + + +################################################################################ +## @class TauRecVariablesProcessor +# Calculate remaining Tau variables and properties +################################################################################ +class TauRecVariablesProcessor ( Configured ) : + """Calculate remaining Tau variables and properties. + Use informations available also in AODs, so no cell level is needed. + """ + + def __init__(self, name = "TauRecVariablesProcessor", inAODmode=False, doBonnPi0Clus=False, msglevel=3, ignoreExistingDataObject=True): + self.name = name + self.doBonnPi0Clus = doBonnPi0Clus + self.msglevel = msglevel + self.AODmode = inAODmode + Configured.__init__(self, ignoreExistingDataObject=ignoreExistingDataObject) + + + def configure(self): + mlog = logging.getLogger ('TauRecVariablesProcessor::configure:') + mlog.info('entering') + + + from AthenaCommon.AlgSequence import AlgSequence + topSequence = AlgSequence() + + import tauRec.TauAlgorithmsHolder as taualgs + + ######################################################################## + # Tau Modifier Algos + ######################################################################## + try: + from tauRec.tauRecConf import TauProcessor + self._TauProcessorHandle = TauProcessor( + name = self.name, + TauContainer = _outputKey, + TauAuxContainer = _outputAuxKey, + runOnAOD = self.AODmode) + + except Exception: + mlog.error("could not get handle to TauProcessor") + print traceback.format_exc() + return False + + tools = [] + try: + #tools.append(taualgs.getEnergyCalibrationEM()) + # don't run 2nd vertex finder in case of cosmics + if not jobproperties.Beam.beamType()=="cosmics": + tools.append(taualgs.getTauVertexVariables()) + tools.append(taualgs.getTauCommonCalcVars()) + tools.append(taualgs.getTauSubstructure()) + if self.doBonnPi0Clus: + tools.append(taualgs.getPi0BonnScoreCalculator()) + tools.append(taualgs.getPi0BonnSelector()) + tools.append(taualgs.getEnergyCalibrationLC(correctEnergy=False, correctAxis=True, postfix='_onlyAxis')) + # + ## for testing purpose + #tools.append(taualgs.getTauTestDump()) + # + ## lock tau containers -> must be the last tau tool!! + #tools.append(taualgs.getContainerLock()) + + self.TauProcessorHandle().Tools = tools + + except Exception: + mlog.error("could not append tools to TauProcessor") + print traceback.format_exc() + return False + + topSequence += self.TauProcessorHandle() + + return True + + # Helpers + def TauProcessorHandle(self): + return self._TauProcessorHandle + +#end diff --git a/Reconstruction/tauRec/python/tauRecFlags.py b/Reconstruction/tauRec/python/tauRecFlags.py new file mode 100644 index 0000000000000000000000000000000000000000..055b099e236a9304be83ab18f9db33ff62a5dd38 --- /dev/null +++ b/Reconstruction/tauRec/python/tauRecFlags.py @@ -0,0 +1,123 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +################################################################################ +## +#@file tauRecFlags.py +# +#@brief define some tauRec flags +################################################################################ + +#======================================================================= +# imports +#======================================================================= +from AthenaCommon.JobProperties import JobProperty, JobPropertyContainer +from AthenaCommon.JobProperties import jobproperties + + +class Enabled(JobProperty): + """ if all tau algorithm to be enabled + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True + +class doTauRec(JobProperty): + """ if TauRec to be enabled + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True + def get_Value(self): + return self.statusOn and self.StoredValue and jobproperties.tauRecFlags.Enabled() + + +class doRunTauDiscriminant(JobProperty): + """ switch for TauDiscriminant running + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True + + +class useVertexBasedConvFinder(JobProperty): + """ switch for PhotonConversionVertex.cxx/h conversion veto + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=False + +class useNewPIDBasedConvFinder(JobProperty): + """ switch for TauConversionTagger.cxx/h conversion veto + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True + +class doPanTau(JobProperty): + """ if pantau should run after tauRec + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=True + +class doBonnPi0(JobProperty): + """ switch on new (Bonn) Pi0 Finder + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=False + +class useOldVertexFitterAPI(JobProperty): + """ use the old (AOD-style) API of the AdaptiveVertexFitter. + The AdaptiveVertexFitter is used for finding the tau decay vertex (aka. secondary vertex) and called in TauVertexVariables. + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=False + + +# Defines a sub-container for the algorithm switches +class tauRecFlags(JobPropertyContainer): + """ tau information """ + +# add the tau flags container to the top container +jobproperties.add_Container(tauRecFlags) + +# I want always the following flags in the Rec container +_list_tau=[Enabled,doTauRec,doRunTauDiscriminant,useVertexBasedConvFinder,useNewPIDBasedConvFinder,doPanTau,doBonnPi0,useOldVertexFitterAPI] +for j in _list_tau: + jobproperties.tauRecFlags.add_JobProperty(j) +del _list_tau + + + +################################################# +#### AOD flags ################################## +# # +# only for re-running tau reco on AODs # +# !not for normal reconstruction! # +################################################# + +class doUpdate(JobProperty): + """ update the tau containers (if running in AODmode) + """ + statusOn=True + allowedTypes=['bool'] + StoredValue=False + +class tauRecAODFlags(JobPropertyContainer): + """ tau information if re-running on AODs """ + +# add the tau flags container to the top container +jobproperties.add_Container(tauRecAODFlags) + +# I want always the following flags in the Rec container +_list_tau=[doUpdate] +for j in _list_tau: + jobproperties.tauRecAODFlags.add_JobProperty(j) +del _list_tau + + + +#======================================================================= + diff --git a/Reconstruction/tauRec/python/tauTrackSlimmer.py b/Reconstruction/tauRec/python/tauTrackSlimmer.py new file mode 100644 index 0000000000000000000000000000000000000000..2b357ff9407524a81289a0997c0f9a928bc7a651 --- /dev/null +++ b/Reconstruction/tauRec/python/tauTrackSlimmer.py @@ -0,0 +1,90 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + +# +# AUTHOR: A.Kaczmarska (using egamma example) +# CREATED: July 12 2007 +# + +from AthenaCommon.Logging import logging +from AthenaCommon.SystemOfUnits import * +from AthenaCommon.Constants import * +import traceback +import EventKernel.ParticleDataType + +from RecExConfig.Configured import Configured + +from AthenaCommon.AppMgr import ServiceMgr as svcMgr +from AthenaServices.Configurables import ThinningSvc +if not hasattr(svcMgr, 'ThinningSvc'): + svcMgr += ThinningSvc(OutputLevel=INFO) +svcMgr.ThinningSvc.Streams += ['StreamAOD'] + + +class tauTrackSlimmer ( Configured ) : + #_outputType = "TrackCollection" + #_outputKey = "Tracks" + + #_output = { _outputType: _outputKey } + + def configure(self): + mlog = logging.getLogger ('tauTrackSlimmer.py::configure:') + mlog.info('entering') + + + # configure TauTrackSlimmer here: + try: + from tauRec.tauRecConf import TauTrackSlimmer + theTauTrackSlimmer = TauTrackSlimmer( + "tauTrackSlimmer", + TauContainer="TauRecContainer", + FilterTaus=True, + maxNTrack = 4, + maxCharge = 2, + maxEmRadius = 0.2, + maxIsoFrac = 0.5 + ) + except Exception: + mlog.error("could not get handle to tauTrackSlimmer") + print traceback.format_exc() + return False + self._TauBuilderHandle = theTauTrackSlimmer + + # take care of the slimming Tool + try: + from TrkTrackSlimmingTool.TrkTrackSlimmingToolConf import Trk__TrackSlimmingTool as ConfigurableTrackSlimmingTool + theTrackSlimmer=ConfigurableTrackSlimmingTool( + name = "tauTrackSlimmerTool", + KeepParameters = True, + KeepOutliers = True + ) + except Exception: + mlog.error("could not get handle to tauTrackSlimmer") + print traceback.format_exc() + return False + from AthenaCommon.AppMgr import ToolSvc + ToolSvc+=theTrackSlimmer + + #output: + from RecExConfig.ObjKeyStore import objKeyStore + # output to AOD (cluster container only!): + #DR objKeyStore.addStreamAOD(self.outputType(),self.outputKey()) + + # add to topsequence + mlog.info("now adding to topSequence") + + from AthenaCommon.AlgSequence import AlgSequence + topSequence = AlgSequence() + topSequence += theTauTrackSlimmer + + + return True + +## def tauTrackSlimmerHandle(self): +## return self._tauTrackSlimmerHandle + +## def outputType(self): +## return self._outputType + +## def outputKey(self) : +## return self._outputKey + diff --git a/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root b/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root new file mode 100644 index 0000000000000000000000000000000000000000..ffc5088be80e7cd0204774071ae094d79119e322 Binary files /dev/null and b/Reconstruction/tauRec/share/EMTES_Fits_Oct2010.root differ diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root new file mode 100644 index 0000000000000000000000000000000000000000..ce496c79bb2c8bbbd94c9ebe8a41b0e1747341c1 Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2011.root differ diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root new file mode 100644 index 0000000000000000000000000000000000000000..fd9fb8b7483d558448d5d8387a2d751b6c44ca7e Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2012.root differ diff --git a/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root b/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root new file mode 100644 index 0000000000000000000000000000000000000000..b0413b95b96feadfad36f4ed58cec6071fdf95ff Binary files /dev/null and b/Reconstruction/tauRec/share/EnergyCalibrationLC2012_retuned.root differ diff --git a/Reconstruction/tauRec/share/LCTES_Fits_May2011.root b/Reconstruction/tauRec/share/LCTES_Fits_May2011.root new file mode 100644 index 0000000000000000000000000000000000000000..63a0d6805f4de9ebe5fe2e176b15256eac873edc Binary files /dev/null and b/Reconstruction/tauRec/share/LCTES_Fits_May2011.root differ diff --git a/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py b/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..f49fb74a0b519687cbd449d7e2838d1fd023ba6d --- /dev/null +++ b/Reconstruction/tauRec/share/Pi0ClusterMaker_Bonn_jobOptions.py @@ -0,0 +1,292 @@ +################################################################################ +## +#@file Pi0ClusterMaker_Bonn_jobOptions.py +# +#@brief jobOption to create clusters for the "Bonn" Pi0 Finder. +# +# Use cell container created by TauRecCoreBuilder as an input. +# Most settings copied from /Calorimeter/CaloRec/python/CaloClusterTopoGetter.py +################################################################################ + +from CaloUtils.CaloUtilsConf import CaloLCClassificationTool, CaloLCWeightTool, CaloLCOutOfClusterTool, CaloLCDeadMaterialTool + +from CaloClusterCorrection.CaloClusterCorrectionConf import CaloClusterLocalCalib +#>> new PL May 4, 2009 +from CaloClusterCorrection.CaloClusterCorrectionConf import CaloClusterCellWeightCalib +#<< + +from CaloRec.CaloRecConf import CaloTopoClusterMaker, CaloTopoClusterSplitter, CaloClusterMomentsMaker, CaloClusterMaker +from CaloRec.CaloTopoClusterFlags import jobproperties +from AthenaCommon.SystemOfUnits import deg, GeV, MeV +from AthenaCommon.GlobalFlags import globalflags + + +from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault +theCaloNoiseTool = CaloNoiseToolDefault() + +# configure cell weight calibration +if jobproperties.CaloTopoClusterFlags.doCellWeightCalib(): + from CaloClusterCorrection.CaloClusterCorrectionConf import H1WeightToolCSC12Generic + from CaloClusterCorrection.StandardCellWeightCalib import H1Calibration, getCellWeightTool + CellWeights = CaloClusterCellWeightCalib("CellWeights") + # -- configure weight tool + finder = jobproperties.CaloTopoClusterFlags.cellWeightRefFinder.get_Value() + size = jobproperties.CaloTopoClusterFlags.cellWeightRefSize.get_Value() + signal = jobproperties.CaloTopoClusterFlags.cellWeightRefSignal.get_Value() + WeightTool = getCellWeightTool(finder,size,signal) + # -- connect weight tool + CellWeights.CellSignalWeightTool = WeightTool + CellWeights += WeightTool + #-- default properties + CellWeights.Direction = "AbsSignal" #-- use absolute cell energies for eta/phi calculation + CellWeights.BelowThresholdLikeAll = True #-- treat clusters below thresholds the same as all others + CellWeights.BelowThresholdDirection = "AbsSignal" #-- alternative direction calculation for below threshold clusters, + # ignored if BelowThresholdLikeAll = True + CellWeights.EnergyThreshold = 0.0*MeV #-- threshold for possible change of direction calculation + CellWeights.IgnoreGeoWeights = False #-- ignore geometrical cell signal weights if True + +# now configure local hadronic calibration +if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib(): + # tools used by tools + # EMFrac = EMFracClusterClassificationTool("EMFrac") + # EMFrac.ClassificationKey = "EMFracClassify" + # EMFrac.UseEMFractionSpread = False + # EMFrac.MaxEMFraction = 0.5 + # + # H1Weight = H1ClusterCellWeightTool("H1Weight") + # H1Weight.CorrectionKey = "H1ClusterCellWeights" + # H1Weight.SignalOverNoiseCut = 2.0 + # H1Weight.CaloNoiseTool = theCaloNoiseTool + # + # OOCC = OutOfClusterCorrectionTool("OOCC") + # OOCC.CorrectionKey = "OOCCorrection" + # + # OOCCPi0 = OutOfClusterCorrectionTool("OOCCPi0") + # OOCCPi0.CorrectionKey = "OOCPi0Correction" + + # tools used by tools + LCClassify = CaloLCClassificationTool("LCClassify") + LCClassify.ClassificationKey = "EMFracClassify" + LCClassify.UseSpread = False + LCClassify.MaxProbability = 0.5 + LCClassify.StoreClassificationProbabilityInAOD = True + + LCWeight = CaloLCWeightTool("LCWeight") + LCWeight.CorrectionKey = "H1ClusterCellWeights" + LCWeight.SignalOverNoiseCut = 2.0 + LCWeight.CaloNoiseTool = theCaloNoiseTool + LCWeight.UseHadProbability = True + + LCOut = CaloLCOutOfClusterTool("LCOut") + LCOut.CorrectionKey = "OOCCorrection" + LCOut.UseEmProbability = False + LCOut.UseHadProbability = True + + LCOutPi0 = CaloLCOutOfClusterTool("LCOutPi0") + LCOutPi0.CorrectionKey = "OOCPi0Correction" + LCOutPi0.UseEmProbability = True + LCOutPi0.UseHadProbability = False + + #DMTool = DeadMaterialCorrectionTool2("DMTool") + #DMTool.HadDMCoeffKey = "HadDMCoeff2" + #DMTool.SignalOverNoiseCut = 1.0 + #DMTool.ClusterRecoStatus = 0 + #DMTool.WeightModeDM = 2 + #DMTool.CaloNoiseTool = theCaloNoiseTool + + LCDeadMaterial = CaloLCDeadMaterialTool("LCDeadMaterial") + LCDeadMaterial.HadDMCoeffKey = "HadDMCoeff2" + LCDeadMaterial.ClusterRecoStatus = 0 + LCDeadMaterial.WeightModeDM = 2 + LCDeadMaterial.UseHadProbability = True + + # correction tools using tools + LocalCalib = CaloClusterLocalCalib ("LocalCalibForTaus") + LocalCalib.ClusterClassificationTool = [LCClassify] + #LocalCalib.ClusterRecoStatus = [2] + LocalCalib.ClusterRecoStatus = [1,2] + LocalCalib.LocalCalibTools = [LCWeight] + + LocalCalib += LCClassify + LocalCalib += LCWeight + + OOCCalib = CaloClusterLocalCalib ("OOCCalibForTaus") + #OOCCalib.ClusterRecoStatus = [2] + OOCCalib.ClusterRecoStatus = [1,2] + OOCCalib.LocalCalibTools = [LCOut] + + OOCCalib += LCOut + + OOCPi0Calib = CaloClusterLocalCalib ("OOCPi0CalibForTaus") + #OOCPi0Calib.ClusterRecoStatus = [1] + OOCPi0Calib.ClusterRecoStatus = [1,2] + OOCPi0Calib.LocalCalibTools = [LCOutPi0] + + OOCPi0Calib += LCOutPi0 + + DMCalib = CaloClusterLocalCalib ("DMCalibForTaus") + DMCalib.ClusterRecoStatus = [1,2] + #DMCalib.LocalCalibToolNames = [DMTool.getFullName()] + #DMCalib += DMTool + DMCalib.LocalCalibTools = [LCDeadMaterial] + + DMCalib += LCDeadMaterial + +TopoClusterForTaus = CaloTopoClusterMaker("TauPi0TopoClusterMaker") + +TopoClusterForTaus.CellsName = "TauCommonPi0CellContainer" +TopoClusterForTaus.CalorimeterNames=["LAREM"] +TopoClusterForTaus.SeedSamplingNames = [ + "PreSamplerB", "EMB1", "EMB2", + "PreSamplerE", "EME1", "EME2" + ] +TopoClusterForTaus.CaloNoiseTool = theCaloNoiseTool +TopoClusterForTaus.UseCaloNoiseTool = True +TopoClusterForTaus.UsePileUpNoise = True +TopoClusterForTaus.NeighborOption = "super3D" +TopoClusterForTaus.RestrictHECIWandFCalNeighbors = False +TopoClusterForTaus.CellThresholdOnEorAbsEinSigma = 0.0 +TopoClusterForTaus.NeighborThresholdOnEorAbsEinSigma = 2.0 +TopoClusterForTaus.SeedThresholdOnEorAbsEinSigma = 4.0 +TopoClusterForTaus.SeedCutsInAbsE = True +TopoClusterForTaus.ClusterEtorAbsEtCut = 0.5*GeV +TopoClusterForTaus.TwoGaussianNoise = jobproperties.CaloTopoClusterFlags.doTwoGaussianNoise() + + +TopoSplitterForTaus = CaloTopoClusterSplitter("TauPi0TopoSplitter") +# cells from the following samplings will be able to form local +# maxima. The excluded samplings are PreSamplerB, EMB1, +# PreSamplerE, EME1, all Tile samplings, all HEC samplings and the +# two rear FCal samplings. +TopoSplitterForTaus.SamplingNames = ["EMB2","EME2"] +# cells from the following samplings will also be able to form +# local maxima but only if they are not overlapping in eta and phi +# with local maxima in previous samplings from the primary list. +TopoSplitterForTaus.SecondarySamplingNames = ["EMB1","EME1"] +TopoSplitterForTaus.ShareBorderCells = True +TopoSplitterForTaus.RestrictHECIWandFCalNeighbors = False + +TopoMomentsForTaus = CaloClusterMomentsMaker ("TauPi0TopoMoments") +TopoMomentsForTaus.MaxAxisAngle = 30*deg +TopoMomentsForTaus.OutputLevel = INFO +TopoMomentsForTaus.MomentsNames = [ + "FIRST_PHI" + ,"FIRST_ETA" + ,"SECOND_R" + ,"SECOND_LAMBDA" + ,"DELTA_PHI" + ,"DELTA_THETA" + ,"DELTA_ALPHA" + ,"CENTER_X" + ,"CENTER_Y" + ,"CENTER_Z" + ,"CENTER_MAG" + ,"CENTER_LAMBDA" + ,"LATERAL" + ,"LONGITUDINAL" + ,"ENG_FRAC_EM" + ,"ENG_FRAC_MAX" + ,"ENG_FRAC_CORE" + ,"FIRST_ENG_DENS" + ,"SECOND_ENG_DENS" + ,"ISOLATION" + ] + +#TopoMomentsForTaus.AODMomentsNames = [ +# "FIRST_ETA" +# ,"SECOND_R" +# ,"SECOND_LAMBDA" +# ,"DELTA_PHI" +# ,"DELTA_THETA" +# ,"CENTER_MAG" +# ,"CENTER_LAMBDA" +# ,"LATERAL" +# ,"LONGITUDINAL" +# ,"ENG_FRAC_EM" +# ,"ENG_FRAC_MAX" +# ,"ENG_FRAC_CORE" +# ,"FIRST_ENG_DENS" +# ,"SECOND_ENG_DENS" +# ,"ISOLATION" +# ] + +#if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies() or jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables(): +# LockVariables = CaloClusterLockVars("LockVariables") +# LockVariables.FixBasicEnergy = True +# LockVariables.LockedSamplingVariables = [] +# if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies(): +# LockVariables.LockedSamplingVariables += [ +# "Energy", "Max_Energy"] +# if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables(): +# LockVariables.LockedSamplingVariables += [ +# "Eta", "Phi", "Delta_Eta", +# "Delta_Phi", "Max_Eta", "Max_Phi" +# ] +# +#if jobproperties.CaloTopoClusterFlags.printTopoClusters(): +# PrintCaloCluster = CaloClusterPrinter("PrintCaloCluster") +# PrintCaloCluster.PrintFirstOnly = True +# PrintCaloCluster.PrintFrequency = 1 +# PrintCaloCluster.EnergyUnit = 1.0*GeV + +cluster_container = 'TauPi0SubtractedClusterContainer' +CaloTopoForTausMaker = CaloClusterMaker ("TauPi0BonnSubtractedClusterMaker") +CaloTopoForTausMaker.ClustersOutputName=cluster_container +CaloTopoForTausMaker.ClusterMakerTools=[ + TopoClusterForTaus.getFullName(), + TopoSplitterForTaus.getFullName()] +CaloTopoForTausMaker.ClusterCorrectionTools = [ + TopoMomentsForTaus.getFullName()] + +CaloTopoForTausMaker += TopoClusterForTaus +CaloTopoForTausMaker += TopoSplitterForTaus +CaloTopoForTausMaker += TopoMomentsForTaus + +#if jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingEnergies() or jobproperties.CaloTopoClusterFlags.lockTopoClusterSamplingVariables(): +# CaloTopoForTausMaker.ClusterCorrectionTools += [ +# LockVariables.getFullName()] +# CaloTopoForTausMaker += LockVariables + +if jobproperties.CaloTopoClusterFlags.doCellWeightCalib(): + CaloTopoForTausMaker.ClusterCorrectionTools += [ + CellWeights.getFullName() ] + CaloTopoForTausMaker += CellWeights + +if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib(): + CaloTopoForTausMaker.ClusterCorrectionTools += [ + LocalCalib.getFullName(), + OOCCalib.getFullName(), + OOCPi0Calib.getFullName(), + DMCalib.getFullName()] + CaloTopoForTausMaker.KeepCorrectionToolAndContainerNames += [ + LocalCalib.getFullName(),"CaloTopoForTausMaker"] + # CaloTopoForTausMaker.KeepEachCorrection=True + CaloTopoForTausMaker += LocalCalib + CaloTopoForTausMaker += OOCCalib + CaloTopoForTausMaker += OOCPi0Calib + CaloTopoForTausMaker += DMCalib + +#if jobproperties.CaloTopoClusterFlags.printTopoClusters(): +# CaloTopoForTausMaker.ClusterCorrectionTools += [ +# PrintCaloCluster.getFullName()] +# CaloTopoForTausMaker += PrintCaloCluster + +# +# pool/cool part +# +if jobproperties.CaloTopoClusterFlags.doTopoClusterLocalCalib(): + from CaloRec import CaloClusterTopoCoolFolder + if globalflags.DetDescrVersion().startswith("Rome"): + CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.MaxProbability = 0.85 + CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.UseNormalizedEnergyDensity = False + else: + CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.MaxProbability = 0.50 + CaloTopoForTausMaker.LocalCalibForTaus.LCClassify.UseNormalizedEnergyDensity = True + +#CaloCell2TopoClusterForTausMapper = CaloCell2ClusterMapper("CaloCell2Pi0ClusterForTausMapper") +#CaloCell2TopoClusterForTausMapper.ClustersName = cluster_container +#CaloCell2TopoClusterForTausMapper.MapOutputName = "CaloCell2Pi0ClusterForTaus" + +topSequence += CaloTopoForTausMaker +#topSequence += CaloCell2TopoClusterForTausMapper + diff --git a/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py b/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..d6ab9bd268f7e2bc8e9ba0ca5bc0d62a1a57b18b --- /dev/null +++ b/Reconstruction/tauRec/share/Pi0ClusterMaker_Crakow_jobOptions.py @@ -0,0 +1,106 @@ +################################################################################ +## +#@file Pi0ClusterMaker_Crakow_jobOptions.py +# +#@brief jobOption to create clusters for the "Crakow" Pi0 Finder. +# +# Use cell container created by TauRecCoreBuilder as an input. +################################################################################ +from CaloRec.CaloRecConf import CaloTopoClusterMaker, CaloTopoClusterSplitter, CaloClusterMomentsMaker, CaloClusterMaker, CaloCell2ClusterMapper +from CaloRec.CaloTopoClusterFlags import jobproperties +from AthenaCommon.SystemOfUnits import deg, GeV, MeV +from AthenaCommon.AlgSequence import AlgSequence +from AthenaCommon.GlobalFlags import globalflags + + +from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault +theCaloNoiseTool = CaloNoiseToolDefault() +from AthenaCommon.AppMgr import ToolSvc +ToolSvc += theCaloNoiseTool + +TopoClusterForTaus = CaloTopoClusterMaker("TopoClusterForTaus") + +TopoClusterForTaus.CellsNames = ["TauCells"] +#TopoClusterForTaus.OutputLevel=2 +TopoClusterForTaus.CalorimeterNames=["LAREM"] +TopoClusterForTaus.SeedSamplingNames = [ + "PreSamplerB", "EMB1", "EMB2", + "PreSamplerE", "EME1", "EME2" + ] +TopoClusterForTaus.CaloNoiseTool=theCaloNoiseTool +TopoClusterForTaus.UseCaloNoiseTool=True +TopoClusterForTaus.UsePileUpNoise=True +TopoClusterForTaus.NeighborOption = "super3D" +TopoClusterForTaus.RestrictHECIWandFCalNeighbors = False +TopoClusterForTaus.CellThresholdOnEorAbsEinSigma = 0.0 +TopoClusterForTaus.NeighborThresholdOnEorAbsEinSigma = 2.0 +TopoClusterForTaus.SeedThresholdOnEorAbsEinSigma = 4.0 +TopoClusterForTaus.SeedCutsInAbsE = True +TopoClusterForTaus.ClusterEtorAbsEtCut = 1*GeV + + +TopoSplitterForTaus = CaloTopoClusterSplitter("TopoSplitterForTaus") +# cells from the following samplings will be able to form local +# maxima. The excluded samplings are PreSamplerB, EMB1, +# PreSamplerE, EME1, all Tile samplings, all HEC samplings and the +# two rear FCal samplings. +# +#TopoSplitterForTaus.OutputLevel=2 +TopoSplitterForTaus.SamplingNames = ["EMB2","EME2"] +# cells from the following samplings will also be able to form +# local maxima but only if they are not overlapping in eta and phi +# with local maxima in previous samplings from the primary list. +# +TopoSplitterForTaus.SecondarySamplingNames = ["EMB1","EME1"] +TopoSplitterForTaus.ShareBorderCells = True +TopoSplitterForTaus.RestrictHECIWandFCalNeighbors = False + +TopoMomentsForTaus = CaloClusterMomentsMaker ("TopoMomentsForTaus") +TopoMomentsForTaus.MaxAxisAngle = 30*deg +TopoMomentsForTaus.OutputLevel = INFO +TopoMomentsForTaus.MomentsNames = [ + "FIRST_PHI" + ,"FIRST_ETA" + ,"SECOND_R" + ,"SECOND_LAMBDA" + ,"DELTA_PHI" + ,"DELTA_THETA" + ,"DELTA_ALPHA" + ,"CENTER_X" + ,"CENTER_Y" + ,"CENTER_Z" + ,"CENTER_LAMBDA" + ,"LATERAL" + ,"LONGITUDINAL" + ,"FIRST_ENG_DENS" + ,"ENG_FRAC_EM" + ,"ENG_FRAC_MAX" + ,"ENG_FRAC_CORE" + ,"FIRST_ENG_DENS" + ,"SECOND_ENG_DENS" +] + + +CaloTopoForTausMaker = CaloClusterMaker ("CaloTopoForTausMaker") +CaloTopoForTausMaker.ClustersOutputName="EMTopoForTaus" +CaloTopoForTausMaker.ClusterMakerTools=[ + TopoClusterForTaus.getFullName(), + TopoSplitterForTaus.getFullName()] +CaloTopoForTausMaker.ClusterCorrectionTools = [ + TopoMomentsForTaus.getFullName()] + +CaloTopoForTausMaker += TopoClusterForTaus +CaloTopoForTausMaker += TopoSplitterForTaus +CaloTopoForTausMaker += TopoMomentsForTaus + +CaloCell2TopoClusterForTausMapper = CaloCell2ClusterMapper("CaloCell2TopoClusterForTausMapper") +CaloCell2TopoClusterForTausMapper.ClustersName = "EMTopoForTaus" +CaloCell2TopoClusterForTausMapper.MapOutputName = "CaloCell2TopoClusterForTaus" + + +topSequence += CaloTopoForTausMaker +topSequence += CaloCell2TopoClusterForTausMapper + + + + diff --git a/Reconstruction/tauRec/share/TauAODList.py b/Reconstruction/tauRec/share/TauAODList.py new file mode 100644 index 0000000000000000000000000000000000000000..b6bd7ee829c72cfc83b7b2721b63fdc4f5c974d8 --- /dev/null +++ b/Reconstruction/tauRec/share/TauAODList.py @@ -0,0 +1,86 @@ +################################################################################ +## +#@file TauAODList.py +# +#@brief List AOD output containers. +################################################################################ + +#------------------------------------------------------------------------------ +# AOD output list +#------------------------------------------------------------------------------ +TauAODList = [] + +#------------------------------------------------------------------------------ +# Tau1P3P cell cluster +#------------------------------------------------------------------------------ +#TauAODList += [ "CaloClusterContainer#Tau1P3PCellCluster" ] + +#------------------------------------------------------------------------------ +# TauRec cell cluster +#------------------------------------------------------------------------------ +#TauAODList += [ "CaloClusterContainer#TauRecCellCluster" ] + +#------------------------------------------------------------------------------ +# Tau1P3P Pi0 cluster +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::CaloClusterContainer_v1#TauPi0ClusterContainer" ] +TauAODList += [ "xAOD::CaloClusterAuxContainer_v1#TauPi0ClusterContainerAux." ] + +#------------------------------------------------------------------------------ +# Tau1P3P cell EM012 cluster +#------------------------------------------------------------------------------ +#TauAODList += [ "CaloClusterContainer#Tau1P3PCellEM012ClusterContainer" ] + +#------------------------------------------------------------------------------ +# Tau1P3P main containers +#------------------------------------------------------------------------------ +#TauAODList += [ "Analysis::TauJetContainer#Tau1P3PContainer" ] +#TauAODList += [ "Analysis::TauDetailsContainer#Tau1P3PDetailsContainer" ] + +#------------------------------------------------------------------------------ +# TauRec main containers +#------------------------------------------------------------------------------ +#TauAODList += [ "Analysis::TauJetContainer#TauRecContainer" ] +#TauAODList += [ "Analysis::TauDetailsContainer#TauRecDetailsContainer" ] +#TauAODList += [ "Analysis::TauDetailsContainer#TauPi0CandidateDetailsContainer" ] + +#------------------------------------------------------------------------------ +# TauRec main xAOD containers +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::TauJetContainer_v1#TauRecContainer" ] +TauAODList += [ "xAOD::TauJetAuxContainer_v1#TauRecContainerAux." ] + +#------------------------------------------------------------------------------ +# Secondary Vertex for Tau Decay +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::VertexContainer_v1#TauSecondaryVertexContainer" ] +TauAODList += [ "xAOD::VertexAuxContainer_v1#TauSecondaryVertexContainerAux.-vxTrackAtVertex" ] + +#------------------------------------------------------------------------------ +# Shot PFOs +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::PFOContainer_v1#TauShotPFOContainer" ] +TauAODList += [ "xAOD::PFOAuxContainer_v1#TauShotPFOContainerAux." ] + +#------------------------------------------------------------------------------ +# Cell-based charged PFOs +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::PFOContainer_v1#TauPi0ChargedPFOContainer" ] +TauAODList += [ "xAOD::PFOAuxContainer_v1#TauPi0ChargedPFOContainerAux." ] + +#------------------------------------------------------------------------------ +# Cell-based neutral PFOs +#------------------------------------------------------------------------------ +TauAODList += [ "xAOD::PFOContainer_v1#TauPi0NeutralPFOContainer" ] +TauAODList += [ "xAOD::PFOAuxContainer_v1#TauPi0NeutralPFOContainerAux." ] + +#------------------------------------------------------------------------- +# eflowObjects for tau +#-------------------------------------------------------------------------- +#TauAODList += [ "eflowObjectContainer#eflowObjects_tauMode" ] +TauAODList += [ "xAOD::PFOContainer_v1#neutralTauPFO_eflowRec" ] +TauAODList += [ "xAOD::PFOAuxContainer_v1#neutralTauPFO_eflowRecAux." ] +TauAODList += [ "xAOD::PFOContainer_v1#chargedTauPFO_eflowRec" ] +TauAODList += [ "xAOD::PFOAuxContainer_v1#chargedTauPFO_eflowRecAux." ] + + diff --git a/Reconstruction/tauRec/share/TauESDList.py b/Reconstruction/tauRec/share/TauESDList.py new file mode 100644 index 0000000000000000000000000000000000000000..7dcca4c0e3c838e81f8613656a2eb1423f75430c --- /dev/null +++ b/Reconstruction/tauRec/share/TauESDList.py @@ -0,0 +1,92 @@ +################################################################################ +## +#@file TauESDList.py +# +#@brief List ESD output containers. +################################################################################ + +#------------------------------------------------------------------------------ +# ESD output list +#------------------------------------------------------------------------------ +TauESDList = [] + +#------------------------------------------------------------------------------ +# Tau1P3P cell cluster +#------------------------------------------------------------------------------ +TauESDList += [ "CaloClusterContainer#Tau1P3PCellCluster" ] +TauESDList += [ "CaloCellLinkContainer#Tau1P3PCellCluster_Link" ] +TauESDList += [ "CaloShowerContainer#Tau1P3PCellCluster_Data" ] + +#------------------------------------------------------------------------------ +# TauRec cell cluster +#------------------------------------------------------------------------------ +TauESDList += [ "CaloClusterContainer#TauRecCellCluster" ] +TauESDList += [ "CaloCellLinkContainer#TauRecCellCluster_Link" ] +TauESDList += [ "CaloShowerContainer#TauRecCellCluster_Data" ] + +#------------------------------------------------------------------------------ +# Tau1P3P Pi0 cluster +#------------------------------------------------------------------------------ +TauESDList += [ "CaloClusterContainer#TauPi0ClusterContainer" ] +TauESDList += [ "CaloCellLinkContainer#TauPi0ClusterContainer_Link" ] +TauESDList += [ "CaloShowerContainer#TauPi0ClusterContainer_Data" ] +#TauESDList += [ "CaloCellContainer#TauCommonPi0CellContainer" ] # for studies of the cell-based algorithm + +#------------------------------------------------------------------------------ +# Tau shot clusters +#------------------------------------------------------------------------------ +TauESDList += [ "CaloClusterContainer#TauShotClusterContainer" ] +TauESDList += [ "CaloCellLinkContainer#TauShotClusterContainer_Link" ] +TauESDList += [ "CaloShowerContainer#TauShotClusterContainer_Data" ] + +#------------------------------------------------------------------------------ +# Shot PFOs +#------------------------------------------------------------------------------ +TauESDList += [ "xAOD::PFOContainer_v1#TauShotPFOContainer" ] +TauESDList += [ "xAOD::PFOAuxContainer_v1#TauShotPFOContainerAux." ] + +#------------------------------------------------------------------------------ +# Cell-based charged PFOs +#------------------------------------------------------------------------------ +TauESDList += [ "xAOD::PFOContainer_v1#TauPi0ChargedPFOContainer" ] +TauESDList += [ "xAOD::PFOAuxContainer_v1#TauPi0ChargedPFOContainerAux." ] + +#------------------------------------------------------------------------------ +# Cell-based neutral PFOs +#------------------------------------------------------------------------------ +TauESDList += [ "xAOD::PFOContainer_v1#TauPi0NeutralPFOContainer" ] +TauESDList += [ "xAOD::PFOAuxContainer_v1#TauPi0NeutralPFOContainerAux." ] + +#------------------------------------------------------------------------------ +# Secondary Vertex for Tau Decay +#------------------------------------------------------------------------------ +TauESDList += [ "xAOD::VertexContainer_v1#TauSecondaryVertexContainer" ] +TauESDList += [ "xAOD::VertexAuxContainer_v1#TauSecondaryVertexContainerAux.-vxTrackAtVertex" ] + +#------------------------------------------------------------------------------ +# Tau1P3P cell EM012 cluster +#------------------------------------------------------------------------------ +TauESDList += [ "CaloClusterContainer#Tau1P3PCellEM012ClusterContainer" ] +TauESDList += [ "CaloCellLinkContainer#Tau1P3PCellEM012ClusterContainer_Link" ] +TauESDList += [ "CaloShowerContainer#Tau1P3PCellEM012ClusterContainer_Data" ] + + +#------------------------------------------------------------------------------ +# Tau1P3P main containers +#------------------------------------------------------------------------------ +TauESDList += [ "Analysis::TauJetContainer#Tau1P3PContainer" ] +TauESDList += [ "Analysis::TauDetailsContainer#Tau1P3PDetailsContainer" ] +TauESDList += [ "Analysis::TauDetailsContainer#Tau1P3PExtraDetailsContainer" ] + +#------------------------------------------------------------------------------ +# TauRec main containers +#------------------------------------------------------------------------------ +TauESDList += [ "Analysis::TauJetContainer#TauRecContainer" ] +TauESDList += [ "Analysis::TauDetailsContainer#TauRecDetailsContainer" ] +TauESDList += [ "Analysis::TauDetailsContainer#TauRecExtraDetailsContainer" ] +TauESDList += [ "Analysis::TauDetailsContainer#TauPi0CandidateDetailsContainer" ] + +#------------------------------------------------------------------------- +# eflowObjects for tau +#-------------------------------------------------------------------------- +TauESDList += [ "eflowObjectContainer#eflowObjects_tauMode" ] diff --git a/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py b/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..d1f8d7c42be27397b9957ac03f01eca802bfb663 --- /dev/null +++ b/Reconstruction/tauRec/share/tauMerged_trackslim_jobOptions.py @@ -0,0 +1,7 @@ +from RecExConfig.RecFlags import rec +if rec.ScopingLevel()<=3: + from ParticleBuilderOptions.AODFlags import AODFlags + if AODFlags.TauTrackSlimmer: + from tauRec.tauTrackSlimmer import tauTrackSlimmer + tauTrackSlimmer() + diff --git a/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py b/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..ec6246dca06ed51089551463c0c078efb2127382 --- /dev/null +++ b/Reconstruction/tauRec/share/tauRecAOD_jobOptions.py @@ -0,0 +1,10 @@ +################################################################################ +## +#@file tauRecAOD_jobOptions.py +# +#@brief jobOption to setup parts of the tau reconstruction chain to run on AODs. +# +#@author Felix Friedrich <felix.friedrich@cern.ch> +################################################################################ +from tauRec.TauRecAODBuilder import TauRecAODProcessor +TauRecAODProcessor(inAODmode=True) \ No newline at end of file diff --git a/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py b/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..e0bd3f1054e781e91b4cf532a223b44d093a5721 --- /dev/null +++ b/Reconstruction/tauRec/share/tauRec_RTT_topOptions.py @@ -0,0 +1,62 @@ + +DetDescrVersion="ATLAS-CSC-01-02-00" + + +doESD = True # if false, all algorithms are switched off by defaults +########################### +donewTracking=True +doxKalman=True +doiPatRec=True +doEmCluster=True +doCaloCluster=True +doCaloTopoCluster=True + +doMoore=False +doMuonboy=False +doConversion=False +doBtagging=False +doEgamma=True +doJetRec=True +doTauRec=True +doMuonIDStandAlone=False +doMuonIDCombined=False +doMuidLowPt=False +doMuGirl=False +doStaco=False +doMuTag=False +doTileMuID=False +doMissingET=False +doObjMissingET=False +doEFlow=False +doEFlowJet= False +doTrigger=False +doAtlfast=False +############################ +doWriteESD = False +doWriteTAG = False +doWriteAOD = True +doTrigger = False +doHist = False +doAOD = True +doCBNT=True + +# number of event to process +#EvtMax= 5 +EvtMax=-1 + +if not 'BTaggingFlags' in dir(): + from BTagging.BTaggingFlags import BTaggingFlags + BTaggingFlags.JetFitterTag=False + #BTaggingFlags.OutputLevel=INFO + +#disable atlfast +from ParticleBuilderOptions.AODFlags import AODFlags +AODFlags.FastSimulation=False + +include ("RecExCommon/RecExCommon_flags.py") +#DetFlags.Calo_setOff() +DetFlags.Muon_setOff() + +include ("RecExCommon/RecExCommon_topOptions.py") +#CBNT_TruthParticle.NMaxTruthParticles = 3000 + diff --git a/Reconstruction/tauRec/share/tauRec_config.py b/Reconstruction/tauRec/share/tauRec_config.py new file mode 100644 index 0000000000000000000000000000000000000000..1bb562aecc1ef26481ebd97f47196f3f167cadbb --- /dev/null +++ b/Reconstruction/tauRec/share/tauRec_config.py @@ -0,0 +1,81 @@ +################################################################################ +## +#@file tauRec_config.py +# +#@brief Main RecExCommon entry point for the tau reconstruction chain including run of tau identification algorithms. +# +# This file calls the dedicated main jobOptions of tauRec and TauDiscriminant. +# Checks make sure that detector conditions are valid to run tau reconstruction. +# Tau identification will only be run if tau reconstruction was setup correctly. +# +################################################################################ +from RecExConfig.RecFlags import rec +from tauRec.tauRecFlags import jobproperties +from JetRec.JetRecFlags import jobproperties +from AthenaCommon.BeamFlags import jobproperties + + +#switch off TauDiscriminant for cosmic +if jobproperties.Beam.beamType()=="cosmics": + jobproperties.tauRecFlags.doRunTauDiscriminant=False + +#disable tau in case we run on RDO/RAW and jets are disabled as well: +if jobproperties.tauRecFlags.doTauRec() and rec.readRDO() and not rec.doJetMissingETTag(): + from AthenaCommon.Logging import logging + logTauRecConfig = logging.getLogger( 'tauRec_config' ) + logTauRecConfig.warning("Running on RDO/RAW files but doJetMissingETTag=False. Tau reco need jets --> tau reconstruction disabled!!") + jobproperties.tauRecFlags.doTauRec=False + + +if jobproperties.tauRecFlags.doTauRec() and ( rec.readESD() or ( DetFlags.haveRIO.ID_on() and DetFlags.haveRIO.Calo_on() ) ) : + _tauFail=True + + # the main tau reconstruction part + try: + include( "tauRec/tauRec_jobOptions.py" ) + _tauFail=False + except Exception: + treatException("Could not set up merged tauRec. Switched off !") + + if not _tauFail: + # call eflowRec in tau mode now + if recAlgs.doEFlow(): + try: + include("eflowRec/eflowRec_config_DC14_Tau.py") + except Exception: + treatException("could not setup eflowRec") + + #jobproperties.tauRecFlags.doPanTau=False + # call PanTau now + if jobproperties.tauRecFlags.doPanTau(): + try: + include("PanTauAnalysis/JobOptions_Main_PanTau.py") + except Exception: + treatException("Could not setup PanTau") + jobproperties.tauRecFlags.doPanTau = False + + # call TauDiscriminant + if jobproperties.tauRecFlags.doRunTauDiscriminant(): + try: + include("TauDiscriminant/TauDiscri_jobOptions.py" ) + except Exception: + treatException("Could not set up TauDiscriminant. Switched off !") + + if _tauFail and jobproperties.tauRecFlags.doTauRec(): + jobproperties.tauRecFlags.doTauRec=False + del _tauFail +else: + if jobproperties.tauRecFlags.doTauRec(): + jobproperties.tauRecFlags.doTauRec=False + +#XXX switch this off until xAOD migration is finished +#if rec.doWritexAOD(): +# from AthenaCommon.AlgSequence import AlgSequence +# sequence = AlgSequence() +# # Add the tau converter algorithm: +# outkey = "TauRecContainer" +# from xAODTauCnv.xAODTauCnvConf import xAODMaker__TauJetCnvAlg +# tauAlg = xAODMaker__TauJetCnvAlg() +# #tauAlg.OutputLevel = 1 +# sequence += tauAlg +# diff --git a/Reconstruction/tauRec/share/tauRec_jobOptions.py b/Reconstruction/tauRec/share/tauRec_jobOptions.py new file mode 100644 index 0000000000000000000000000000000000000000..7ab848bf3415719201ebcc643503dc05f4b64d40 --- /dev/null +++ b/Reconstruction/tauRec/share/tauRec_jobOptions.py @@ -0,0 +1,41 @@ +################################################################################ +## +#@file tauRec_jobOptions.py +# +#@brief Main jobOption to setup tau reconstruction chain. +# +#@author Felix Friedrich <felix.friedrich@cern.ch> +################################################################################ + +#TODO: everything needed here? +from RecExConfig.RecFlags import rec +from AthenaCommon.BeamFlags import jobproperties +from AthenaCommon.GlobalFlags import globalflags +import AthenaCommon.SystemOfUnits as Units +from tauRec.tauRecFlags import jobproperties as taujp + +# use Tau Jet Vertex Association Tool +# each Tau candidate gets its own primary vertex +# and the tracks are selected accroding to this vertex +_doTJVA = True + +# Bonn Pi0-finding algorithm +_doBonnPi0Clus = taujp.tauRecFlags.doBonnPi0() #False by default +_doBonnPi0Clus = True + +# the TauCoreBuilder +from tauRec.TauRecBuilder import TauRecCoreBuilder +TauRecCoreBuilder(doBonnPi0Clus=_doBonnPi0Clus, doTJVA=_doTJVA) + + +#include("tauRec/Pi0ClusterMaker_Crakow_jobOptions.py") +if _doBonnPi0Clus: + include("tauRec/Pi0ClusterMaker_Bonn_jobOptions.py") + +from tauRec.TauRecBuilder import TauRecPi0EflowProcessor +TauRecPi0EflowProcessor(doBonnPi0Clus=_doBonnPi0Clus) + +from tauRec.TauRecBuilder import TauRecVariablesProcessor +TauRecVariablesProcessor(doBonnPi0Clus=_doBonnPi0Clus) + + diff --git a/Reconstruction/tauRec/src/CaloClusterVariables.cxx b/Reconstruction/tauRec/src/CaloClusterVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..736e9a40c0a90cf56485f97bf1b43f8fb2dce973 --- /dev/null +++ b/Reconstruction/tauRec/src/CaloClusterVariables.cxx @@ -0,0 +1,203 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "tauRec/CaloClusterVariables.h" +#include "tauEvent/TauJet.h" +#include "boost/foreach.hpp" +#include "math.h" + +const double CaloClusterVariables::DEFAULT = -1111.; + +//**************************************** +// constructor +//**************************************** + +CaloClusterVariables::CaloClusterVariables() : +m_numConstit((int) DEFAULT), +m_effNumConstit_int((int) DEFAULT), +m_effNumConstit(DEFAULT), +m_aveRadius(DEFAULT), +m_aveEffRadius(DEFAULT), +m_totMass(DEFAULT), +m_effMass(DEFAULT), +m_totEnergy(DEFAULT), +m_effEnergy(DEFAULT), +m_numCells(0), +m_doVertexCorrection(false) { +} + +//******************************************* +// update/fill the cluster based variables +//******************************************* + +bool CaloClusterVariables::update(const xAOD::TauJet* pTau) { + + if (!pTau) return false; + const xAOD::Jet* pSeed = *pTau->jetLink(); + if(!pSeed) return false; + + xAOD::JetConstituentVector::const_iterator nav_it = pSeed->getConstituents().begin(); + xAOD::JetConstituentVector::const_iterator nav_itE = pSeed->getConstituents().end(); + const xAOD::CaloCluster* pCluster; + + unsigned int sumCells = 0; + + std::vector<xAOD::CaloVertexedCluster> constituents; + for (; nav_it != nav_itE; ++nav_it) { + pCluster = dynamic_cast<const xAOD::CaloCluster*> ( (*nav_it)->rawConstituent() ); + if (!pCluster) continue; + + // XXX moved the calculation of num cells up because later on we don't have access to the actual clusters anymore + sumCells += pCluster->size(); + + // correct cluster + if (pTau->vertexLink() && m_doVertexCorrection) + constituents.emplace_back (*pCluster, (*pTau->vertexLink())->position()); + else + constituents.emplace_back (*pCluster); + } + + this->m_numConstit = (int) constituents.size(); + + // Order constituents by energy + sort(constituents.begin(), constituents.end(), CaloClusterCompare()); + + //**************************************** + // Looping over all constituents + //**************************************** + + double sum_px = 0; + double sum_py = 0; + double sum_pz = 0; + double sum_e = 0; + double sum_of_E2 = 0; + double sum_radii = 0; + CLHEP::HepLorentzVector centroid = calculateTauCentroid(this->m_numConstit, constituents); + + for (const xAOD::CaloVertexedCluster& c : constituents) { + double energy = c.e(); + sum_of_E2 += energy*energy; + + double px = c.p4().Px(); + double py = c.p4().Py(); + double pz = c.p4().Pz(); + // FF: phi is wrong in case px,py AND pz is negative when using HepLorentzVector(px,py,pz,1) + // because phi = atan(py/px) + // in trigger many clusters have negative energies/momentum + // negative values of px and py are only treated correctly if pz is positive. + // Otherwise px and py must be taken as positive values + // so using cluster eta/phi directly instead of creating a HLV. + //CLHEP::HepLorentzVector constituentHLV(px, py, pz, 1); + //sum_radii += centroid.deltaR(constituentHLV); + double dr = std::sqrt( std::pow(c.eta() - centroid.eta(),2) + std::pow(c.phi() - centroid.phi(),2)); + sum_radii += dr; + sum_e += energy; + sum_px += px; + sum_py += py; + sum_pz += pz; + } + + // Sum up the energy for constituents + this->m_totEnergy = sum_e; + + // Calculate the mass of the constituents + if (this->m_numConstit < 2) this->m_totMass = DEFAULT; + else { + double mass2 = sum_e * sum_e - (sum_px * sum_px + sum_py * sum_py + sum_pz * sum_pz); + this->m_totMass = mass2 > 0 ? sqrt(mass2) : -sqrt(-mass2); + } + + // Calculate the average radius of the constituents wrt the tau centroid + this->m_aveRadius = this->m_numConstit > 0 ? sum_radii / this->m_numConstit : DEFAULT; + + // sum of cells for the tau candidate + this->m_numCells = sumCells; + + // Effective number of constituents + this->m_effNumConstit = sum_of_E2 > 0 ? (sum_e * sum_e) / (sum_of_E2) : DEFAULT; + + this->m_effNumConstit_int = int(ceil(this->m_effNumConstit)); + + // A problem! + if (this->m_effNumConstit_int > this->m_numConstit) return false; + + // Avoid segfault, happens when we try to iterate below if sum_of_E2 was 0 or negative + if (this->m_effNumConstit_int < 0) return false; + + //**************************************** + // Now: Looping over effective constituents + //**************************************** + + sum_px = 0; + sum_py = 0; + sum_pz = 0; + sum_e = 0; + sum_of_E2 = 0; + sum_radii = 0; + centroid = calculateTauCentroid(this->m_effNumConstit_int, constituents); + + int icount = this->m_effNumConstit_int; + for (const xAOD::CaloVertexedCluster& c : constituents) { + if (icount <= 0) break; + --icount; + + double energy = c.e(); + //XXXchange to use tlorentzvector + double px = c.p4().Px(); + double py = c.p4().Py(); + double pz = c.p4().Pz(); + // FF: see comment above + //CLHEP::HepLorentzVector constituentHLV(px, py, pz, 1); + //sum_radii += centroid.deltaR(constituentHLV); + double dr = std::sqrt( std::pow(c.eta() - centroid.eta(),2) + std::pow(c.phi() - centroid.phi(),2)); + sum_radii += dr; + + sum_e += energy; + sum_px += px; + sum_py += py; + sum_pz += pz; + } + + // Sum up the energy for effective constituents + this->m_effEnergy = sum_e; + + // Calculate the mass of the constituents + if (this->m_effNumConstit_int < 2) this->m_effMass = DEFAULT; + else { + double mass2 = sum_e * sum_e - (sum_px * sum_px + sum_py * sum_py + sum_pz * sum_pz); + this->m_effMass = mass2 > 0 ? sqrt(mass2) : -sqrt(-mass2); + } + + // Calculate the average radius of the constituents wrt the tau centroid + this->m_aveEffRadius = this->m_effNumConstit_int > 0 ? sum_radii / this->m_effNumConstit_int : DEFAULT; + + return true; +} + + +//***************************************** +// Calculate the geometrical center of the +// tau constituents +//***************************************** +CLHEP::HepLorentzVector CaloClusterVariables::calculateTauCentroid(int nConst, const std::vector<xAOD::CaloVertexedCluster>& constituents) { + + double px = 0; + double py = 0; + double pz = 0; + double current_px, current_py, current_pz, modulus; + + for (const xAOD::CaloVertexedCluster& c : constituents) { + if (nConst <= 0) break; + --nConst; + current_px = c.p4().Px(); + current_py = c.p4().Py(); + current_pz = c.p4().Pz(); + modulus = sqrt(current_px * current_px + current_py * current_py + current_pz * current_pz); + px += current_px / modulus; + py += current_py / modulus; + pz += current_pz / modulus; + } + CLHEP::HepLorentzVector centroid(px, py, pz, 1); + return centroid; +} diff --git a/Reconstruction/tauRec/src/JetSeedBuilder.cxx b/Reconstruction/tauRec/src/JetSeedBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a9a23826f38b7a2a8d491d61de11c8846ffeee64 --- /dev/null +++ b/Reconstruction/tauRec/src/JetSeedBuilder.cxx @@ -0,0 +1,209 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +NAME: JetSeedBuilder.cxx +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: N. Meyer +CREATED: Nov 27 2007 + +17/03/2010: AK: change to P4Helpers +16/05/2011: FF: fix rare case if no jet_seed found at all (coverity 21744) + Dec 2011: FF: changes for tauRec4 + ********************************************************************/ + +#include "EventKernel/SignalStateHelper.h" +#include "FourMomUtils/P4Helpers.h" + +#include "xAODJet/Jet.h" +#include "xAODJet/JetContainer.h" + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" +#include "xAODTau/TauJet.h" + +#include "tauRec/JetSeedBuilder.h" + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +JetSeedBuilder::JetSeedBuilder(const std::string& type, + const std::string& name, + const IInterface * parent) : + TauToolBase(type, name, parent), + m_jetCollectionName("AntiKt4LCTopoJets"), + m_maxJetdist(0.1), + m_minJetPt(10000.0), + m_switch_jets_em_scale(false) { + declareInterface<TauToolBase > (this); + declareProperty("JetCollection", m_jetCollectionName); + declareProperty("maxDist", m_maxJetdist); + declareProperty("minPt", m_minJetPt); + declareProperty("SwitchJetsEmScale", m_switch_jets_em_scale); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +JetSeedBuilder::~JetSeedBuilder() { +} + +//------------------------------------------------------------------------- +// initialize +//------------------------------------------------------------------------- + +StatusCode JetSeedBuilder::initialize() { + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// Event Finalize +//------------------------------------------------------------------------- + +StatusCode JetSeedBuilder::eventFinalize(TauCandidateData *) { + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// execute +//------------------------------------------------------------------------- + +StatusCode JetSeedBuilder::execute(TauCandidateData * data) { + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + StatusCode sc; + + ATH_MSG_DEBUG("Starting execute"); + + bool inTrigger = false; + if (data->hasObject("InTrigger?")) { + sc = data->getObject("InTrigger?", inTrigger); + } + + if(inTrigger) + ATH_MSG_DEBUG("inTrigger read properly"); + + const xAOD::JetContainer *pJetColl; + + if (sc.isSuccess() && inTrigger) { + // called by Trigger + // retrieve JetCollection for trigger + ATH_MSG_DEBUG("Try to retrieve object from DataContainer"); + //sc = data->getObject("JetCollection", pJetColl); + // Try a different approach: grab it directly + sc = true; + pJetColl = data->seedContainer; + if (sc.isFailure() || !pJetColl) { + ATH_MSG_DEBUG("no JetCollection for trigger available"); + ATH_MSG_DEBUG("retrieve standard JetCollection <" << m_jetCollectionName << ">"); + // retrieve standard jet collection + sc = evtStore()->retrieve(pJetColl, m_jetCollectionName); + if (sc.isFailure()) { + ATH_MSG_WARNING("no JetCollection retrieved"); + return StatusCode::FAILURE; + } + } + } else { + // called by offline tauRec + // retrieve standard jet collection + sc = evtStore()->retrieve(pJetColl, m_jetCollectionName); + if (sc.isFailure()) { + ATH_MSG_WARNING("no JetCollection retrieved"); + return StatusCode::FAILURE; + } + } + + ATH_MSG_DEBUG("Pulling out the seed"); + + const xAOD::Jet* pJetSeed = data->seed; + if (!pJetSeed) { + ATH_MSG_DEBUG("seed is not a jet -> tau will not be reconstructed"); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("Seed extracted"); + ATH_MSG_DEBUG("seed is Jet with" + << " pt=" << pJetSeed->pt() + << " eta=" << pJetSeed->eta() + << " phi=" << pJetSeed->phi() + ); + + xAOD::TauJetContainer::iterator itTau = data->xAODTauContainer->begin(); + xAOD::TauJetContainer::iterator itTauE = data->xAODTauContainer->end(); + + for (; itTau != itTauE; ++itTau) { + if ( (*itTau)->jetLink().isValid() ) { + if ( pJetSeed == ( * (*itTau)->jetLink() ) ) { + ATH_MSG_DEBUG("seed already used"); + return StatusCode::FAILURE; + } + } + } + + ///XXX need to decide whether to remove this, because there's no author flag in xAOD::TauJet + + //*********************************************************************** + // set author to both-seeded because we don't want to break any analysis + // most of the analyses are using author==3 or author==1 + // so setting author=3 should be safe for everybody + // calo seeded tau + // pTau->setAuthor(TauJetParameters::tauRec); + // // track seeded tau + // pTau->setAuthor(TauJetParameters::tau1P3P); + //*********************************************************************** + + // + // ATTENTION: direction will be overwritten later by TauAxis and TauEnergyCalibration + // + if (inTrigger && pJetSeed->e() < 0) { + // SL/SX trigger mode with negative jet_seed - do not set TauJet eta and phi in JetSeedBuilder + ATH_MSG_DEBUG("TauJet eta/phi will be set in Level2 Trigger for negative energy jet"); + + pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta , static_cast<float>( pTau->eta() ) ); + pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi , static_cast<float>( pTau->phi() ) ); + + pTau->setP4(pJetSeed->pt(),pTau->eta(),pTau->phi(),0.0); + + } else { + if (m_switch_jets_em_scale) { + ATH_MSG_INFO("trying to set seed jet signal state to EMSCALE, but this code has not been migrated to xAOD::Jet yet"); + //XXX still need to look up how signal states are handled for the xAOD jets + // SignalStateHelper sigstateH(P4SignalState::JETEMSCALE); + // sigstateH.controlObject(pJetSeed); + } + + pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta , static_cast<float>( pJetSeed->eta() ) ); + pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi , static_cast<float>( pJetSeed->phi() ) ); + if ( pJetSeed->pt() > 1e-7) + pTau->setP4(static_cast<float>( pJetSeed->pt() ) ,static_cast<float>( pJetSeed->eta() ) ,static_cast<float>( pJetSeed->phi() ) ,0.0 ); + else + pTau->setP4(static_cast<float>( pJetSeed->pt() ) ,static_cast<float>( pJetSeed->eta() ) ,static_cast<float>( pJetSeed->phi() ) , 0.0 ); + + //store 4-vector of seed + pTau->setP4( xAOD::TauJetParameters::JetSeed, pJetSeed->pt(), pJetSeed->eta(), pJetSeed->phi(), pJetSeed->m() ); + } + + // set now the link to the jet seed + pTau->setJet(pJetColl, pJetSeed); + + if ( pTau->jetLink().isValid() ) { + ATH_MSG_DEBUG("seed associated with tau is Jet with" + << " pt=" << (*pTau->jetLink())->pt() + << " eta=" << (*pTau->jetLink())->eta() + << " phi=" << (*pTau->jetLink())->phi() + ); + } + + return StatusCode::SUCCESS; +} + + diff --git a/Reconstruction/tauRec/src/LockTauContainers.cxx b/Reconstruction/tauRec/src/LockTauContainers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..528ee0bcca49852506c0a5e51e4a3c00f7cebd00 --- /dev/null +++ b/Reconstruction/tauRec/src/LockTauContainers.cxx @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" + +#include "tauRec/LockTauContainers.h" + +//********************************** +// Constructor +//********************************** + +LockTauContainers::LockTauContainers( + const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); +} + + +//************************************ +// event finalize method +//************************************ + +StatusCode LockTauContainers::eventFinalize(TauCandidateData *data) { + ATH_MSG_VERBOSE("LockTauContainers::eventFinialize"); + + //------------------------------------------------------------------------- + // Lock Containers + //------------------------------------------------------------------------- + + xAOD::TauJetContainer* pContainer = data->xAODTauContainer; + xAOD::TauJetAuxContainer *pAuxContainer = data->tauAuxContainer; + + StatusCode sc; + + if (pContainer) + sc = evtStore()->setConst(pContainer); + if (sc.isFailure()) { + ATH_MSG_ERROR("Cannot set tau container to const"); + return StatusCode::FAILURE; + } + + if (pAuxContainer) + sc = evtStore()->setConst(pAuxContainer); + if (sc.isFailure()) { + ATH_MSG_ERROR("Cannot set tau aux container to const"); + return StatusCode::FAILURE; + } + + ATH_MSG_VERBOSE("all tau containers are now locked"); + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/PhotonConversionPID.cxx b/Reconstruction/tauRec/src/PhotonConversionPID.cxx new file mode 100644 index 0000000000000000000000000000000000000000..362c328ec64b094c4da10f867a224a9acaedbd11 --- /dev/null +++ b/Reconstruction/tauRec/src/PhotonConversionPID.cxx @@ -0,0 +1,151 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +NAME: PhotonConversionPID.cxx +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: Michael Boehler <michael.boehler@desy.de> +CREATED: November 2008 + ********************************************************************/ + +#include "tauRec/PhotonConversionPID.h" + +#include "xAODTracking/VertexContainer.h" +#include "TrkParticleBase/LinkToTrackParticleBase.h" +#include "TrkTrackSummary/TrackSummary.h" +#include "AthContainers/ConstDataVector.h" + +PhotonConversionPID::PhotonConversionPID(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent), +m_ownPolicy(static_cast<int> (SG::VIEW_ELEMENTS)) { + declareInterface<TauToolBase > (this); + + declareProperty("OwnPolicy", m_ownPolicy); + declareProperty("ConversionCandidatesName", m_ConversionCandidatesName = "ConversionCandidate"); + declareProperty("ConversionOutputName", m_ConversionOutputName = "ConversionsPID_Container"); + declareProperty("ElectronProbability", m_eProb_cut = 0.9); +} + +/********************************************************************/ +PhotonConversionPID::~PhotonConversionPID() { +} + +/********************************************************************/ +StatusCode PhotonConversionPID::initialize() { + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode PhotonConversionPID::finalize() { + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode PhotonConversionPID::eventFinalize(TauCandidateData* /*data*/) { + + // ------------------------------------------------------------------ + // Retrieving VxCandidates (conversions) + // ------------------------------------------------------------------ + const xAOD::VertexContainer* ConvContainer; + StatusCode sc = evtStore()->retrieve(ConvContainer, m_ConversionCandidatesName); + + if (sc.isFailure() || !ConvContainer) { + ATH_MSG_DEBUG(" No VxCandidates container found in TDS !!"); + return StatusCode::SUCCESS; + } else { + ATH_MSG_VERBOSE("Processing Conversion Container Name = " << m_ConversionCandidatesName); + } + + ATH_MSG_DEBUG("VxContainer " << m_ConversionCandidatesName << " contains " << ConvContainer->size() << " vertices. "); + + + // ------------------------------------------------------------------------------------------------- + // Create and record the empty container VxCandidates (conversions after PID) + // ------------------------------------------------------------------------------------------------- + ATH_MSG_DEBUG(" Recording identified conversion collection with key: " << m_ConversionOutputName); + + ConstDataVector<xAOD::VertexContainer>* ConversionContainerPID = new ConstDataVector<xAOD::VertexContainer>(static_cast<SG::OwnershipPolicy> (m_ownPolicy)); + + sc = evtStore()->record(ConversionContainerPID, m_ConversionOutputName); + if (sc.isFailure()) { + ATH_MSG_ERROR("execute() : cannot record CaloCellContainer " << m_ConversionOutputName); + return sc; + } + + // Loop over ConversionVertex Container: + xAOD::VertexContainer::const_iterator itr = ConvContainer->begin(); + xAOD::VertexContainer::const_iterator itrE = ConvContainer->end(); + + for (; itr != itrE; ++itr) { + + const xAOD::Vertex* vxcand = (*itr); + + ATH_MSG_VERBOSE("Tracks at vertex: " << vxcand->nTrackParticles()); + + bool isTrk1_Conv = false; + bool isTrk2_Conv = false; + + // loop over all tracks of the vertex + for (unsigned int i = 0; i < vxcand->nTrackParticles(); i++) { + /* + // these lines navigate from a VxCandidate to the track summary of each track at vertex + Trk::VxTrackAtVertex* tmpVxAtVtx = (*trklist)[i]; + Trk::ITrackLink* trkLink = tmpVxAtVtx->trackOrParticleLink(); + Trk::LinkToTrackParticleBase * linkToTrack_part = dynamic_cast<Trk::LinkToTrackParticleBase *> (trkLink); + if (!linkToTrack_part) { + ATH_MSG_WARNING("dynamic_cast of LinkToTrackParticleBase failed"); + continue; + } + + const Trk::TrackParticleBase* TP_Base = linkToTrack_part->cachedElement(); + if (!TP_Base) { + ATH_MSG_WARNING("could not get TrackParticleBase from linkToTrack_part"); + continue; + } + + const Trk::TrackSummary* summary = TP_Base->trackSummary(); + */ + const xAOD::TrackParticle *track = vxcand->trackParticle(i); + float eProbabilityComb; + if (track && track->summaryValue(eProbabilityComb, xAOD::SummaryType::eProbabilityComb)) { + //--------------------------------------------------------------- + // Checks ID of Conversion Candidates (eProb based on TRT PID) + ATH_MSG_VERBOSE("Track " << i + 1 << " PID: " << eProbabilityComb); + + if (eProbabilityComb > m_eProb_cut) { + + // both conv tracks pass PID cut (in case of double track conv) + if (i == 0) { + isTrk1_Conv = true; + } + if (i == 1 || vxcand->nTrackParticles() == 1) { + isTrk2_Conv = true; + } + } + + //------------------------------------------------------------------ + // after both tracks have been tested and passed the PID cut the + // Conversions are stored in the new Conversion Container + if (isTrk1_Conv == true && isTrk2_Conv == true) { + ATH_MSG_VERBOSE(" Conversion accepted"); + ConversionContainerPID->push_back(vxcand); + } + + + } else { + // here a new track summary can be provided (not yet implemented) + ATH_MSG_WARNING("No Track Summary has been found! NO Photon Conversion Identification has been made!!!! "); + } + + } // end track loop + } // end vertex loop + + ATH_MSG_DEBUG("After ID " << ConversionContainerPID->size() << " Conversion are stored in " << m_ConversionOutputName); + + return StatusCode::SUCCESS; +} + +/********************************************************************/ diff --git a/Reconstruction/tauRec/src/PhotonConversionVertex.cxx b/Reconstruction/tauRec/src/PhotonConversionVertex.cxx new file mode 100644 index 0000000000000000000000000000000000000000..df6806e74e25756af01872e404cbf69a2aa9f614 --- /dev/null +++ b/Reconstruction/tauRec/src/PhotonConversionVertex.cxx @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +NAME: PhotonConversionVertex.cxx +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: KG Tan <Kong.Guan.Tan@cern.ch> +CREATED: May 2011 + +This tool identifies conversion candidates in/near (definable) a +tau decay cone by reconstructing the conversion vertices and +applying a set of cuts optimized for tau conversions on the vertex +parameters. + ********************************************************************/ + +#include "tauRec/PhotonConversionVertex.h" + +#include "tauEvent/TauJetContainer.h" +#include "xAODTracking/TrackParticleContainer.h" +#include "xAODTracking/VertexContainer.h" +#include "InDetRecToolInterfaces/IVertexFinder.h" +#include "AthContainers/ConstDataVector.h" + +PhotonConversionVertex::PhotonConversionVertex(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent), +m_vertexFinderTool("InDet::InDetConversionFinderTools") { + declareInterface<TauToolBase > (this); + declareProperty("TauRecContainer", m_inputTauJetContainerName = "TauRecContainer"); + declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles"); + declareProperty("OutputConversionVertexContainerName", m_outputConversionVertexContainerName = "ConversionsVertex_Container"); + declareProperty("MaxTauJetDr", m_maxTauJetDr = 0.5); + declareProperty("ConversionFinderTool", m_vertexFinderTool); +} + +PhotonConversionVertex::~PhotonConversionVertex() { +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode PhotonConversionVertex::initialize() { + // Get the VertexFinderTool + if (!retrieveTool(m_vertexFinderTool)) return StatusCode::FAILURE; + + return StatusCode::SUCCESS; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode PhotonConversionVertex::finalize() { + return StatusCode::SUCCESS; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode PhotonConversionVertex::eventFinalize(TauCandidateData *data) { + // get the jet container from TauCandidateData, or the StoreGate if it can't find it + xAOD::TauJetContainer* tauJetCont = data->xAODTauContainer; + if (!tauJetCont) { + if (!openContainer(tauJetCont, m_inputTauJetContainerName)) + return StatusCode::FAILURE; + } + + // get the track particle container from StoreGate + const xAOD::TrackParticleContainer* trackParticleCont = 0; + if (!openContainer(trackParticleCont, m_inputTrackParticleContainerName)) return StatusCode::FAILURE; + + // Define container to store + xAOD::VertexContainer* conversionCandidatesVxCont = 0; + xAOD::VertexAuxContainer* conversionCandidatesVxContAux = 0; + std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*> convContPair; + + // Redo conversion over the tau seed cones, or over entire region + if (m_maxTauJetDr > 0.) { + + if (tauJetCont->size() > 0) { + + // Create a temporary TrackParticle container that contains tracks within the tau seed cones + ConstDataVector<xAOD::TrackParticleContainer> tempCont (SG::VIEW_ELEMENTS); + for (xAOD::TrackParticleContainer::const_iterator tpcItr = trackParticleCont->begin(); tpcItr != trackParticleCont->end(); ++tpcItr) { + double minTauDr = getMinDrTauDecay(tauJetCont, *tpcItr); + if (minTauDr < m_maxTauJetDr) { + tempCont.push_back(*tpcItr); + } + } + ATH_MSG_VERBOSE("Number of tracks within tau seed cones for conversion finding: " << tempCont.size()); + + // Run the conversion finding algorithm over the tau seed cones + convContPair = m_vertexFinderTool->findVertex(tempCont.asDataVector()); + conversionCandidatesVxCont = convContPair.first; + conversionCandidatesVxContAux = convContPair.second; + } else + conversionCandidatesVxCont = new xAOD::VertexContainer(); // No need to run conversion finding if no tracks are found! + conversionCandidatesVxContAux = new xAOD::VertexAuxContainer(); // No need to run conversion finding if no tracks are found! + + } else { + ATH_MSG_VERBOSE("Running over entire region! Number of tracks: " << trackParticleCont->size()); + + // Run the conversion finding algorithm over the entire region! + convContPair = m_vertexFinderTool->findVertex(trackParticleCont); + conversionCandidatesVxCont = convContPair.first; + conversionCandidatesVxContAux = convContPair.second; + } + + // Perform the storing + ATH_MSG_VERBOSE("Number of conversion vertices found: " << conversionCandidatesVxCont->size()); + conversionCandidatesVxCont->setStore( conversionCandidatesVxContAux ); + if (!saveContainer(conversionCandidatesVxCont, m_outputConversionVertexContainerName)) return StatusCode::FAILURE; + if (!saveContainer(conversionCandidatesVxContAux, m_outputConversionVertexContainerName+"Aux")) return StatusCode::FAILURE; + + return StatusCode::SUCCESS; +} + +template <class T> +bool PhotonConversionVertex::openContainer(T* &container, std::string containerName) { + StatusCode sc = evtStore()->retrieve(container, containerName); + if (!container || sc.isFailure()) + ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate"); + return container; +} + +template <class T> +bool PhotonConversionVertex::saveContainer(T* &container, std::string containerName) { + StatusCode sc = evtStore()->record(container, containerName); + if (!container || sc.isFailure()) + ATH_MSG_FATAL("Container (" << containerName << ") cannot be saved in StoreGate"); + return container; +} + +template <class T> +bool PhotonConversionVertex::retrieveTool(T &tool) { + if (tool.retrieve().isFailure()) { + ATH_MSG_FATAL("Failed to retrieve tool " << tool); + return false; + } else { + ATH_MSG_VERBOSE("Retrieved tool " << tool); + } + return true; +} + +double PhotonConversionVertex::getMinDrTauDecay(const xAOD::TauJetContainer* tauJetCont, const xAOD::TrackParticle *trackParticle) { + double minDR = 99999.; + for (xAOD::TauJetContainer::const_iterator tjcItr = tauJetCont->begin(); tjcItr != tauJetCont->end(); ++tjcItr) { + const xAOD::TauJet *tauJet = *tjcItr; + double dR = trackParticle->p4().DeltaR(tauJet->p4()); + if (dR < minDR) minDR = dR; + } + return minDR; +} diff --git a/Reconstruction/tauRec/src/TauAxisSetter.cxx b/Reconstruction/tauRec/src/TauAxisSetter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..677388c61237d02b5d495948cb43ecd6665a19e7 --- /dev/null +++ b/Reconstruction/tauRec/src/TauAxisSetter.cxx @@ -0,0 +1,161 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "CLHEP/Vector/LorentzVector.h" +#include "CLHEP/Units/SystemOfUnits.h" +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" +#include "JetEvent/Jet.h" +#include "CaloEvent/CaloCluster.h" + +//tau +#include "tauRec/TauCandidateData.h" + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" +#include "xAODTau/TauJet.h" + +#include "CaloUtils/CaloVertexedCluster.h" + +#include "tauRec/TauAxisSetter.h" + +/********************************************************************/ +TauAxisSetter::TauAxisSetter(const std::string& type, + const std::string& name, + const IInterface* parent): +TauToolBase(type, name, parent), +m_clusterCone(0.2), +m_doCellCorrection(false) +{ + declareInterface<TauToolBase > (this); + declareProperty("ClusterCone", m_clusterCone); + declareProperty("tauContainerKey", tauContainerKey = "TauRecContainer"); + declareProperty("CellCorrection", m_doCellCorrection); +} + +/********************************************************************/ +TauAxisSetter::~TauAxisSetter() { } + +/********************************************************************/ +StatusCode TauAxisSetter::initialize() +{ + return StatusCode::SUCCESS; +} + +StatusCode TauAxisSetter::eventInitialize(TauCandidateData * /*data*/) +{ + return StatusCode::SUCCESS; + +} + +/********************************************************************/ +StatusCode TauAxisSetter::execute(TauCandidateData *data) +{ + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + const xAOD::Jet* pJetSeed = (*pTau->jetLink()); + if (!pJetSeed) { + ATH_MSG_WARNING("tau does not have jet seed for LC calibration"); + return StatusCode::SUCCESS; + } + + xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin(); + xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end(); + + /////////////////////////////////////////////////////////////////////////// + //calculate barycenter + TLorentzVector sumAllClusterVector; + TLorentzVector tempClusterVector; + for (; cItr != cItrE; ++cItr) { + tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() ); + + sumAllClusterVector += tempClusterVector; + } + TLorentzVector BaryCenter; + BaryCenter.SetPtEtaPhiM(1., sumAllClusterVector.Eta(), sumAllClusterVector.Phi(), 0.); + + + /////////////////////////////////////////////////////////////////////////// + // calculate detector axis + TLorentzVector tauDetectorAxis; + // count number of constituents in core cone. could be zero! + int nConstituents = 0; + for (cItr = pJetSeed->getConstituents().begin(); cItr != cItrE; ++cItr) { + tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() ); + + ATH_MSG_VERBOSE("cluster in detector axis loop:" << (*cItr)->pt()<< " " << (*cItr)->eta() << " " << (*cItr)->phi() << " " << (*cItr)->e() ); + ATH_MSG_VERBOSE("delta R is " << BaryCenter.DeltaR(tempClusterVector) ); + + if (BaryCenter.DeltaR(tempClusterVector) > m_clusterCone) + continue; + + nConstituents++; + tauDetectorAxis += tempClusterVector; + } + + if (nConstituents == 0) + { + ATH_MSG_WARNING("this tau candidate does not have any constituent clusters! breaking off tau tool chain and not recording this candidate!"); + return StatusCode::FAILURE; + } + + ATH_MSG_VERBOSE("jet axis:" << (*pTau->jetLink())->pt()<< " " << (*pTau->jetLink())->eta() << " " << (*pTau->jetLink())->phi() << " " << (*pTau->jetLink())->e() ); + // save values for detector axis. + // FixMe: consider dropping these details variables as they are duplicated in the detector axis 4 vector + pTau->setDetail(xAOD::TauJetParameters::LC_TES_precalib , static_cast<float>( tauDetectorAxis.Pt() ) ); + pTau->setDetail(xAOD::TauJetParameters::seedCalo_eta, static_cast<float>( tauDetectorAxis.Eta() ) ); + pTau->setDetail(xAOD::TauJetParameters::seedCalo_phi, static_cast<float>( tauDetectorAxis.Phi() ) ); + ATH_MSG_VERBOSE("detector axis:" << tauDetectorAxis.Pt()<< " " << tauDetectorAxis.Eta() << " " << tauDetectorAxis.Phi() << " " << tauDetectorAxis.E() ); + + // detectorAxis (set default) + pTau->setP4(tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), pTau->m()); + // save detectorAxis + pTau->setP4(xAOD::TauJetParameters::DetectorAxis, tauDetectorAxis.Pt(), tauDetectorAxis.Eta(), tauDetectorAxis.Phi(), tauDetectorAxis.M()); + + /////////////////////////////////////////////////////////////////////////// + // calculate tau intermediate axis (corrected for tau vertex) + TLorentzVector tauInterAxis; + + for (cItr = pJetSeed->getConstituents().begin(); cItr != cItrE; ++cItr) { + tempClusterVector.SetPtEtaPhiE( (*cItr)->pt(), (*cItr)->eta(), (*cItr)->phi(), (*cItr)->e() ); + if (BaryCenter.DeltaR(tempClusterVector) > m_clusterCone) + continue; + + const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); + if (!cluster) continue; + + if (pTau->vertexLink()) + tauInterAxis += xAOD::CaloVertexedCluster(*cluster, (*pTau->vertexLink())->position()).p4(); + else + tauInterAxis += xAOD::CaloVertexedCluster(*cluster).p4(); + } + + // save values for tau intermediate axis + // energy will be overwritten by EnergyCalibrationLC (if correctEnergy is enabled) + // direction will be overwritten by EnergyCalibrationLC (if correctAxis is enabled) + + // intermediate axis( set default) + pTau->setP4(tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), pTau->m()); + + ATH_MSG_VERBOSE("tau axis:" << tauInterAxis.Pt()<< " " << tauInterAxis.Eta() << " " << tauInterAxis.Phi() << " " << tauInterAxis.E() ); + + // save intermediateAxis + pTau->setP4(xAOD::TauJetParameters::IntermediateAxis, tauInterAxis.Pt(), tauInterAxis.Eta(), tauInterAxis.Phi(), tauInterAxis.M()); + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalize +//----------------------------------------------------------------------------- +StatusCode TauAxisSetter::finalize() +{ + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauBuilder.cxx b/Reconstruction/tauRec/src/TauBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bab7cd3870c2daf140cd56c1cb8e2a13bb1f3a7f --- /dev/null +++ b/Reconstruction/tauRec/src/TauBuilder.cxx @@ -0,0 +1,373 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauBuilder.cxx +// package: Reconstruction/tauRec +// authors: Srini Rajagopalan, Michael Heldmann, Lukasz Janyst, +// Anna Kaczmarska +// date: 2007-02-13 +// modification: +// 15/04/2008 - (AK) fixing memory leak bug #35463 +// 19/05/2011 - (KG) added EndAthTools to transition between AlgTools and AthAlgTools +// 22/05/2011 - (FF) changed to inherit from AthAlgorithm +// 23/05/2011 - (FF) removed EndAthTools -> transition finished +// 01/12/2011 - (FF) remove track seeded containers +//----------------------------------------------------------------------------- + +#include "tauRec/TauBuilder.h" + +#include "xAODJet/Jet.h" +#include "xAODJet/JetContainer.h" + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" +#include "xAODTau/TauDefs.h" + +#include "GaudiKernel/ListItem.h" +#include "tauRec/TauCandidateData.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauBuilder::TauBuilder(const std::string &name, + ISvcLocator * pSvcLocator) : +AthAlgorithm(name, pSvcLocator), +m_tauContainerName("TauRecContainer"), +m_tauAuxContainerName("TauRecContainerAux."), +m_seedContainerName(""), +m_maxEta(2.5), +m_minPt(10000), +m_doCreateTauContainers(false), +m_tools(this) //make tools private +{ + declareProperty("TauContainer", m_tauContainerName); + declareProperty("TauAuxContainer", m_tauAuxContainerName); + declareProperty("SeedContainer", m_seedContainerName); + declareProperty("MaxEta", m_maxEta); + declareProperty("MinPt", m_minPt); + declareProperty("doCreateTauContainers", m_doCreateTauContainers); + declareProperty("Tools", m_tools, "List of TauToolBase tools"); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauBuilder::~TauBuilder() { +} + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauBuilder::initialize() { + StatusCode sc; + + //ATH_MSG_INFO("FF::TauBuilder :: initialize()"); + + //------------------------------------------------------------------------- + // No tools allocated! + //------------------------------------------------------------------------- + if (m_tools.size() == 0) { + ATH_MSG_ERROR("no tools given!"); + return StatusCode::FAILURE; + } + + //------------------------------------------------------------------------- + // Allocate tools + //------------------------------------------------------------------------- + ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end(); + ATH_MSG_INFO("List of tools in execution sequence:"); + ATH_MSG_INFO("------------------------------------"); + + unsigned int tool_count = 0; + + for (; itT != itTE; ++itT) { + sc = itT->retrieve(); + if (sc.isFailure()) { + ATH_MSG_WARNING("Cannot find tool named <" << *itT << ">"); + } else { + ++tool_count; + ATH_MSG_INFO((*itT)->type() << " - " << (*itT)->name()); + } + } + ATH_MSG_INFO(" "); + ATH_MSG_INFO("------------------------------------"); + + if (tool_count == 0) { + ATH_MSG_ERROR("could not allocate any tool!"); + return StatusCode::FAILURE; + } + + /////////////////////////////////////////////////////////////////////////// + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauBuilder::finalize() { + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- + +StatusCode TauBuilder::execute() { + //ATH_MSG_INFO("FF::TauBuilder :: execute()"); + StatusCode sc; + + TauCandidateData rTauData; + + xAOD::TauJetContainer * pContainer = 0; + xAOD::TauJetAuxContainer* pAuxContainer = 0; + + + + if (m_doCreateTauContainers) { + //------------------------------------------------------------------------- + // Create and Record containers + //------------------------------------------------------------------------- + + pContainer = new xAOD::TauJetContainer(); + sc = evtStore()->record( pContainer, m_tauContainerName ) ; + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to record TauContainer in TDS"); + delete pContainer; + return StatusCode::FAILURE; + } + + pAuxContainer = new xAOD::TauJetAuxContainer(); + sc = evtStore()->record( pAuxContainer, m_tauAuxContainerName ) ; + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to record TauContainer in TDS"); + delete pContainer; + return StatusCode::FAILURE; + } + + pContainer->setStore( pAuxContainer ); + ATH_MSG_DEBUG( "Recorded xAOD tau jets with key: " + << m_tauAuxContainerName ); + + // pExtraDetailsContainer = new Analysis::TauDetailsContainer(); + // sc = evtStore()->record(pExtraDetailsContainer, m_tauExtraDetailsContainerName); + // if (sc.isFailure()) { + // ATH_MSG_ERROR("Unable to record TauDetailsContainer in TDS"); + // delete pExtraDetailsContainer; + // return StatusCode::FAILURE; + // } + + // pPi0CandidateDetailsContainer = new Analysis::TauDetailsContainer(); + // sc = evtStore()->record(pPi0CandidateDetailsContainer, "TauPi0CandidateDetailsContainer"); + // if (sc.isFailure()) { + // ATH_MSG_ERROR("Unable to record TauPi0CandidateDetailsContainer in TDS"); + // delete pPi0CandidateDetailsContainer; + // return StatusCode::FAILURE; + // } + + + } else { + //------------------------------------------------------------------------- + // retrieve Tau Containers from StoreGate + //------------------------------------------------------------------------- + sc = evtStore()->retrieve(pContainer, m_tauContainerName); + if (sc.isFailure()) { + ATH_MSG_FATAL("Failed to retrieve " << m_tauContainerName); + return StatusCode::FAILURE; + } + + sc = evtStore()->retrieve(pAuxContainer, m_tauAuxContainerName); + if (sc.isFailure()) { + ATH_MSG_FATAL("Failed to retrieve " << m_tauAuxContainerName); + return StatusCode::FAILURE; + } + + // sc = evtStore()->retrieve(pExtraDetailsContainer, m_tauExtraDetailsContainerName); + // if (sc.isFailure()) { + // ATH_MSG_FATAL("Failed to retrieve " << m_tauExtraDetailsContainerName); + // return StatusCode::FAILURE; + // } + + // sc = evtStore()->retrieve(pPi0CandidateDetailsContainer, "TauPi0CandidateDetailsContainer"); + // if (sc.isFailure()) { + // ATH_MSG_FATAL("Failed to retrieve " << "TauPi0CandidateDetailsContainer"); + // return StatusCode::FAILURE; + // } + } + + // set TauCandidate properties + rTauData.xAODTau = 0; + rTauData.xAODTauContainer = pContainer; + rTauData.tauAuxContainer = pAuxContainer; + + + //XXX leave this here for now until xAOD migration is completed + /* + rTauData.tauContainer = 0; + rTauData.detailsContainer = 0; + rTauData.extraDetailsContainer = 0; + rTauData.pi0DetailsContainer = 0; + rTauData.tau = 0; + rTauData.details = 0; + rTauData.extraDetails = 0; + rTauData.pi0Details = 0; + */ + rTauData.seed = 0; + rTauData.seedContainer = 0; + + //------------------------------------------------------------------------- + // Initialize tools for this event + //------------------------------------------------------------------------- + ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end(); + for (; itT != itTE; ++itT) { + sc = (*itT)->eventInitialize(&rTauData); + if (sc != StatusCode::SUCCESS) + return StatusCode::FAILURE; + } + + //////////////////////////////////////////////////////// + + + //--------------------------------------------------------------------- + // Retrieve seed Container from TDS, return `failure' if not + // existing + //--------------------------------------------------------------------- + const xAOD::JetContainer * pSeedContainer; + sc = evtStore()->retrieve(pSeedContainer, m_seedContainerName); + // XXX still need to fix this. Currently only handle jets + // const DataHandle<INavigable4MomentumCollection> pSeedContainer; + // sc = evtStore()->retrieve(pSeedContainer, m_seedContainerName); + if (sc.isFailure() || !pSeedContainer) { + ATH_MSG_FATAL("No seed container with key:" << m_seedContainerName); + return StatusCode::FAILURE; + } + + //--------------------------------------------------------------------- + // Loop over seeds + //--------------------------------------------------------------------- + xAOD::JetContainer::const_iterator itS = pSeedContainer->begin(); + xAOD::JetContainer::const_iterator itSE = pSeedContainer->end(); + // XXX still need to fix this. Currently only handle jets + // INavigable4MomentumCollection::const_iterator itS = pSeedContainer->begin(); + // INavigable4MomentumCollection::const_iterator itSE = pSeedContainer->end(); + + ATH_MSG_VERBOSE("Number of seeds in the container: " << pSeedContainer->size()); + + rTauData.seedContainer = pSeedContainer; + + for (; itS != itSE; ++itS) { + const xAOD::Jet *pSeed = (*itS); + ATH_MSG_VERBOSE("Seeds eta:" << pSeed->eta() << ", pt:" << pSeed->pt()); + + if (fabs(pSeed->eta()) > m_maxEta) { + ATH_MSG_VERBOSE("--> Seed rejected, eta out of range!"); + continue; + } + + if (fabs(pSeed->pt()) < m_minPt) { + ATH_MSG_VERBOSE("--> Seed rejected, pt out of range!"); + continue; + } + + rTauData.seed = pSeed; + + //----------------------------------------------------------------- + // Seed passed cuts --> create tau candidate + //----------------------------------------------------------------- + rTauData.xAODTau = new xAOD::TauJet(); + rTauData.xAODTauContainer->push_back( rTauData.xAODTau ); + + //----------------------------------------------------------------- + // Process the candidate + //----------------------------------------------------------------- + ToolHandleArray<TauToolBase>::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase>::iterator itTE = m_tools.end(); + + //----------------------------------------------------------------- + // Loop stops when Failure indicated by one of the tools + //----------------------------------------------------------------- + for (; itT != itTE; ++itT) { + ATH_MSG_VERBOSE("Invoking tool " << (*itT)->name()); + + sc = (*itT)->execute(&rTauData); + + if (sc.isFailure()) + break; + } + + if (sc.isSuccess()) { + + + ATH_MSG_VERBOSE("The tau candidate has been registered"); + + //----------------------------------------------------------------- + // Process the candidate using endTools + //----------------------------------------------------------------- + //keep this here for future use (in case more than one seeding algo exist) + /* + ToolHandleArray<TauToolBase> ::iterator p_itET = m_endTools.begin(); + ToolHandleArray<TauToolBase> ::iterator p_itETE = m_endTools.end(); + for (; p_itET != p_itETE; ++p_itET) { + ATH_MSG_VERBOSE("Invoking endTool " << (*p_itET)->name()); + p_sc = (*p_itET)->execute(&rTauData); + if (p_sc.isFailure()) + break; + } + */ + ////////////////////////////////////////////////////// + + } else if (!sc.isSuccess()) { + //TODO:cleanup of EndTools not necessary?? + //keep this here for future use (in case more than one seeding algo exist) + /* + ToolHandleArray<TauToolBase> ::iterator p_itT1 = m_tools.begin(); + for (; p_itT1 != p_itT; ++p_itT1) + (*p_itT1)->cleanup(&rTauData); + (*p_itT1)->cleanup(&rTauData); + */ + rTauData.xAODTauContainer->pop_back(); + } else + rTauData.xAODTauContainer->pop_back(); + } + + + + //------------------------------------------------------------------------- + // Finalize tools for this event + //------------------------------------------------------------------------- + //TODO: line below necessary? + rTauData.xAODTau = 0; + + itT = m_tools.begin(); + itTE = m_tools.end(); + for (; itT != itTE; ++itT) { + sc = (*itT)->eventFinalize(&rTauData); + if (sc != StatusCode::SUCCESS) + return StatusCode::FAILURE; + } + + //keep this here for future use (in case more than one seeding algo exist) + /* + p_itET = m_endTools.begin(); + p_itETE = m_endTools.end(); + for (; p_itET != p_itETE; ++p_itET) { + p_sc = (*p_itET)->eventFinalize(&rTauData); + if (p_sc != StatusCode::SUCCESS) + return StatusCode::FAILURE; + } + */ + + /////////////////////////////////////////////////////// + + // locking of containers is moved to separate tau tool + + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauCalibrateEM.cxx b/Reconstruction/tauRec/src/TauCalibrateEM.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dd81f02987c6ebeee775eebb47c32f49acc55316 --- /dev/null +++ b/Reconstruction/tauRec/src/TauCalibrateEM.cxx @@ -0,0 +1,197 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TFile.h" +#include "TF1.h" +#include "GaudiKernel/Property.h" +#include <PathResolver/PathResolver.h> +#include "CLHEP/Units/SystemOfUnits.h" +#include "EventKernel/SignalStateHelper.h" +#include "JetEvent/Jet.h" + +#include "xAODTau/TauJet.h" +#include "tauRec/TauCandidateData.h" +#include "tauRec/TauToolBase.h" +#include "tauRec/TauCalibrateEM.h" + +using CLHEP::GeV; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------ + +TauCalibrateEM::TauCalibrateEM(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); + declareProperty("response_functions_file", m_response_functions_file = "EMTES_Fits_Oct2010.root"); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauCalibrateEM::~TauCalibrateEM() { +} + +//------------------------------------------------------------------------- +// initialize +//------------------------------------------------------------------------- + +StatusCode TauCalibrateEM::initialize() { + + std::string response_functions_path = PathResolver::find_file(m_response_functions_file, "DATAPATH"); + TFile* f = TFile::Open(response_functions_path.c_str(), "READ"); + + m_f1_1p_lem = new TF1(*((TF1*) f->Get("OneP_LowEMF_Eta_All"))); + m_f1_1p_hem_barrel = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_0"))); + m_f1_1p_hem_crack = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_1"))); + m_f1_1p_hem_endcap = new TF1(*((TF1*) f->Get("OneP_HighEMF_Eta_2"))); + m_f1_mp_barrel = new TF1(*((TF1*) f->Get("MultiP_Eta_0"))); + m_f1_mp_crack = new TF1(*((TF1*) f->Get("MultiP_Eta_1"))); + m_f1_mp_endcap = new TF1(*((TF1*) f->Get("MultiP_Eta_2"))); + + m_min_1p_lem.first = m_f1_1p_lem->GetMinimumX(1.5, 3.0); + m_min_1p_lem.second = m_f1_1p_lem->Eval(m_min_1p_lem.first); + m_min_1p_hem_barrel.first = m_f1_1p_hem_barrel->GetMinimumX(1.5, 3.0); + m_min_1p_hem_barrel.second = m_f1_1p_hem_barrel->Eval(m_min_1p_hem_barrel.first); + m_min_1p_hem_crack.first = m_f1_1p_hem_crack->GetMinimumX(1.5, 3.0); + m_min_1p_hem_crack.second = m_f1_1p_hem_crack->Eval(m_min_1p_hem_crack.first); + m_min_1p_hem_endcap.first = m_f1_1p_hem_endcap->GetMinimumX(1.5, 3.0); + m_min_1p_hem_endcap.second = m_f1_1p_hem_endcap->Eval(m_min_1p_hem_endcap.first); + m_min_mp_barrel.first = m_f1_mp_barrel->GetMinimumX(2.0, 3.0); + m_min_mp_barrel.second = m_f1_mp_barrel->Eval(m_min_mp_barrel.first); + m_min_mp_crack.first = m_f1_mp_crack->GetMinimumX(2.0, 3.0); + m_min_mp_crack.second = m_f1_mp_crack->Eval(m_min_mp_crack.first); + m_min_mp_endcap.first = m_f1_mp_endcap->GetMinimumX(2.5, 3.5); + m_min_mp_endcap.second = m_f1_mp_endcap->Eval(m_min_mp_endcap.first); + + f->Close(); + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// execute +//------------------------------------------------------------------------- + +StatusCode TauCalibrateEM::execute(TauCandidateData *data) { + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + const xAOD::Jet* pJetSeed = (*pTau->jetLink()); + + // XXX still need to migrate to signalstate handling of xAOD::Jet + // SignalStateHelper sigstateH(P4SignalState::JETEMSCALE); + // sigstateH.controlObject(pJetSeed); + + float emscale_ptEM = 0; + float emscale_ptHad = 0; + + if ( !pTau->detail( xAOD::TauJetParameters::etEMAtEMScale, emscale_ptEM ) ) + { + ATH_MSG_DEBUG("retrieval of tau detail failed. not calculating new em scale pt"); + return StatusCode::SUCCESS; + } + + if ( !pTau->detail( xAOD::TauJetParameters::etHadAtEMScale, emscale_ptHad ) ) + { + ATH_MSG_DEBUG("retrieval of tau detail failed. not calculating new em scale pt"); + return StatusCode::SUCCESS; + } + + double emscale_pt = emscale_ptEM + emscale_ptHad; + double emscale_eta = pJetSeed->eta(); + double emfrac = (emscale_pt != 0) ? emscale_ptEM / emscale_pt : 0.; + + + ATH_MSG_DEBUG("input variables: em_pt " << emscale_pt << " eta " << emscale_eta << " ntrack " << pTau->nTracks() << " emfrac " << emfrac); + + double new_pt = evaluate_new_pt(emscale_pt / GeV, fabs(emscale_eta), pTau->nTracks(), emfrac); + + + // do NOT set TauJet energy, as this will be done in tauCalibrateLC + //tau->setE( new_pt * GeV * cosh( tau->eta() ) ); + + // instead fill place holder in TauCommonDetails + //pDetails->setSeedCalo_etEMCalib(new_pt * GeV); + + pTau->setDetail( xAOD::TauJetParameters::EM_TES_scale, static_cast<float>( new_pt * GeV ) ); + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalize +//----------------------------------------------------------------------------- + +StatusCode TauCalibrateEM::finalize() { + delete m_f1_1p_lem; + delete m_f1_1p_hem_barrel; + delete m_f1_1p_hem_crack; + delete m_f1_1p_hem_endcap; + delete m_f1_mp_barrel; + delete m_f1_mp_crack; + delete m_f1_mp_endcap; + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// calculate new tau pt at EM scale +//----------------------------------------------------------------------------- + +double TauCalibrateEM::evaluate_new_pt(double pt, double eta, int ntrack, double emfrac) { + + if (pt <= 0)return 0; + double ln_pt = log(pt); + if (ln_pt > 8.5) return pt; + + if (ntrack <= 1) { + // corrections for single prong taus + + if (emfrac < 0.15) { + // corrections for low EMF + if (ln_pt < m_min_1p_lem.first) return pt / m_min_1p_lem.second; + else return pt / m_f1_1p_lem->Eval(ln_pt); + } else { + // corrections for high EMF + + if (eta < 1.3) { + if (ln_pt < m_min_1p_hem_barrel.first) return pt / m_min_1p_hem_barrel.second; + else return pt / m_f1_1p_hem_barrel->Eval(ln_pt); + } else if (eta < 1.6) { + if (ln_pt < m_min_1p_hem_crack.first) return pt / m_min_1p_hem_crack.second; + else return pt / m_f1_1p_hem_crack->Eval(ln_pt); + } else { + if (ln_pt < m_min_1p_hem_endcap.first) return pt / m_min_1p_hem_endcap.second; + else return pt / m_f1_1p_hem_endcap->Eval(ln_pt); + } + } + + } else { + // corrections for multi-prong taus + + if (eta < 1.3) { + if (ln_pt < m_min_mp_barrel.first) return pt / m_min_mp_barrel.second; + else return pt / m_f1_mp_barrel->Eval(ln_pt); + } else if (eta < 1.6) { + if (ln_pt < m_min_mp_crack.first) return pt / m_min_mp_crack.second; + else return pt / m_f1_mp_crack->Eval(ln_pt); + } else { + if (ln_pt < m_min_mp_endcap.first) return pt / m_min_mp_endcap.second; + else return pt / m_f1_mp_endcap->Eval(ln_pt); + } + } + + return pt; +} + +// EOF + + diff --git a/Reconstruction/tauRec/src/TauCalibrateLC.cxx b/Reconstruction/tauRec/src/TauCalibrateLC.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dc4cc3f1db3b9cd644d84a15f7f1c75a240f1a20 --- /dev/null +++ b/Reconstruction/tauRec/src/TauCalibrateLC.cxx @@ -0,0 +1,265 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "PathResolver/PathResolver.h" +#include "CLHEP/Vector/LorentzVector.h" +#include "CLHEP/Units/SystemOfUnits.h" + +// root +#include "TFile.h" +#include "TF1.h" +#include "TH1D.h" + +//tau +#include "xAODTau/TauJet.h" +#include "tauRec/TauCandidateData.h" +#include "tauRec/TauCalibrateLC.h" + +using CLHEP::GeV; + +/********************************************************************/ +TauCalibrateLC::TauCalibrateLC(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent), +m_doEnergyCorr(false), +m_doAxisCorr(false), +m_printMissingContainerINFO(true), +m_clusterCone(0.2) //not used +{ + declareInterface<TauToolBase > (this); + declareProperty("tauContainerKey", tauContainerKey = "TauRecContainer"); + declareProperty("calibrationFile", calibrationFile = "EnergyCalibrationLC2012.root"); + declareProperty("vertexContainerKey", vertexContainerKey = "PrimaryVertices"); + declareProperty("doEnergyCorrection", m_doEnergyCorr); + declareProperty("doAxisCorrection", m_doAxisCorr); + declareProperty("ClusterCone", m_clusterCone); //not used +} + +/********************************************************************/ +TauCalibrateLC::~TauCalibrateLC() { +} + +/********************************************************************/ +StatusCode TauCalibrateLC::initialize() { + std::string fullPath = PathResolver::find_file(calibrationFile, "DATAPATH"); + TFile * file = TFile::Open(fullPath.c_str(), "READ"); + + if (!file) { + ATH_MSG_FATAL("Failed to open " << fullPath); + return StatusCode::FAILURE; + } + + // get the histogram defining eta binning + std::string key = "etaBinning"; + TObject * obj = file->Get(key.c_str()); + if (obj) { + etaBinHist = dynamic_cast<TH1 *> (obj); + TH1 * tmp = const_cast<TH1*> (etaBinHist); + tmp->SetDirectory(0); + } else { + ATH_MSG_FATAL("Failed to get an object with key " << key); + return StatusCode::FAILURE; + } + + //retrieve number of eta bins from file + m_nEtaBins = etaBinHist->GetNbinsX(); //member var + if (m_nEtaBins==6) + ATH_MSG_INFO("using 2011 tau energy calibration"); + else if (m_nEtaBins==5) + ATH_MSG_INFO("using 2012 tau energy calibration"); + else { + ATH_MSG_FATAL("Wrong or broken tau energy calibration file"); + return StatusCode::FAILURE; + } + + // get the histogram with eta corrections + key = "etaCorrection"; + obj = file->Get(key.c_str()); + if (obj) { + etaCorrectionHist = dynamic_cast<TH1 *> (obj); + TH1 * tmp = const_cast<TH1*> (etaCorrectionHist); + tmp->SetDirectory(0); + } else { + ATH_MSG_FATAL("Failed to get an object with key " << key); + return StatusCode::FAILURE; + } + + TString tmpSlopKey[nProngBins] = {"slopeNPV1P", "slopeNPV3P"}; + TString tmpFuncBase[nProngBins] = {"OneP_Eta_", "MultiP_Eta_"}; + + for (int i = 0; i < nProngBins; i++) { + obj = file->Get(tmpSlopKey[i]); // get pile-up slope histograms + if (obj) { + slopeNPVHist[i] = dynamic_cast<TH1 *> (obj); + TH1 * tmp = const_cast<TH1*> (slopeNPVHist[i]); + tmp->SetDirectory(0); + } else { + ATH_MSG_FATAL("Failed to get an object with key " << tmpSlopKey[i]); + return StatusCode::FAILURE; + } + + for (int j = 0; j < m_nEtaBins; j++) { + TString key = tmpFuncBase[i]; + key += j; + TObject * obj = file->Get(key); + if (obj) { + calibFunc[i][j] = dynamic_cast<TF1*> (obj); + } else { + ATH_MSG_FATAL("Failed to get an object with key " << key); + return StatusCode::FAILURE; + } + } + } + m_averageNPV = slopeNPVHist[0]->GetBinContent(0); // underflow is the average number of reconstructed primary vertices + m_minNTrackAtVertex = static_cast<unsigned int> (slopeNPVHist[0]->GetBinContent(slopeNPVHist[0]->GetNbinsX() + 1)); //overflow is the minimum number of tracks at vertex + + ATH_MSG_DEBUG("averageNPV = " << m_averageNPV); + ATH_MSG_DEBUG("minimum number of tracks at primary vertex = " << m_minNTrackAtVertex); + + file->Close(); + + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode TauCalibrateLC::execute(TauCandidateData *data) +{ + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + // energy calibration depends on number of tracks - 1p or Mp + int prongBin = 1; //Mp + if (pTau->nTracks() <= 1) prongBin = 0; //1p + + // set tau energy scale + if (m_doEnergyCorr) { + + // get detector axis values + double eta = pTau->etaDetectorAxis(); + double absEta = std::abs(eta); + int etaBin = etaBinHist->GetXaxis()->FindBin(absEta) - 1; + + if (etaBin>=m_nEtaBins) etaBin = m_nEtaBins-1; // correction from last bin should be applied on all taus outside stored eta range + + // get primary vertex container + StatusCode sc; + const xAOD::VertexContainer * vxContainer = 0; + + // for tau trigger + bool inTrigger = false; + if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger); + // FF: March, 2014 + // this is for later purpose. At the moment no offset correction is used in case of tau trigger (see below) + if (sc.isSuccess() && inTrigger) sc = data->getObject("VxPrimaryCandidate", vxContainer); + + if (!inTrigger || !vxContainer || sc.isFailure() ) { + // try standard + if (evtStore()->retrieve(vxContainer, vertexContainerKey).isFailure() || !vxContainer) { + if (m_printMissingContainerINFO) { + ATH_MSG_WARNING(vertexContainerKey << " container not found --> skip TauEnergyCalibrationLC (no further info) "); + m_printMissingContainerINFO=false; + } + return StatusCode::SUCCESS; + } + } + + xAOD::VertexContainer::const_iterator vx_iter = vxContainer->begin(); + xAOD::VertexContainer::const_iterator vx_end = vxContainer->end(); + int nVertex = 0; + for (; vx_iter != vx_end; ++vx_iter) { + if ((*vx_iter)->nTrackParticles() >= m_minNTrackAtVertex) + ++nVertex; + } + + ATH_MSG_DEBUG("calculated nVertex " << nVertex ); + + + // get detector axis energy + // was saved by TauAxisSetter + double energyLC = pTau->p4(xAOD::TauJetParameters::DetectorAxis).E() / GeV; //was sumClusterVector.e() / GeV; + + if (energyLC <= 0) { + ATH_MSG_DEBUG("tau energy at LC scale is " << energyLC << "--> set energy=0.001"); + //TODO: we can not set tau energy to 0 due to bug in P4Helpers during deltaR calculation + //will set it to 0.001 MeV + pTau->setP4(0.001, pTau->eta(), pTau->phi(), pTau->m()); + return StatusCode::SUCCESS; + } + + double slopeNPV = slopeNPVHist[prongBin]->GetBinContent(etaBin + 1); + double offset = slopeNPV * (nVertex - m_averageNPV); + + // FF: March,2014 + // no offset correction for trigger + if (inTrigger) offset = 0.; + + if (energyLC - offset <= 0) { + ATH_MSG_DEBUG("after pile-up correction energy would be = " << energyLC - offset << " --> setting offset=0 now!"); + offset = 0; + } + + // apply offset correction + double energyPileupCorr = energyLC - offset; + + double calibConst = 1.0; + if (energyPileupCorr > 0 and energyPileupCorr < 10000) // from 0 to 10 TeV + { + calibConst = calibFunc[prongBin][etaBin]->Eval(energyPileupCorr); + + if (calibConst <= 0) { + ATH_MSG_DEBUG("calibration constant = " << calibConst); + ATH_MSG_DEBUG("prongBin = " << prongBin); + ATH_MSG_DEBUG("etaBin = " << etaBin); + ATH_MSG_DEBUG("energyPileupCorr = " << energyPileupCorr); + ATH_MSG_DEBUG("energyLC = " << energyLC); + calibConst = 1.0; + } + } + + double energyFinal = energyPileupCorr / calibConst; + + pTau->setP4(energyFinal * GeV / cosh( pTau->eta() ), pTau->eta(), pTau->phi(), pTau->m()); + + pTau->setP4(xAOD::TauJetParameters::TauEnergyScale, pTau->pt(), pTau->eta(), pTau->phi(), pTau->m()); + + pTau->setDetail(xAOD::TauJetParameters::TESCalibConstant, static_cast<float>( calibConst ) ); + pTau->setDetail(xAOD::TauJetParameters::TESOffset, static_cast<float>( offset * GeV ) ); + + ATH_MSG_DEBUG("Energy at LC scale = " << energyLC << " pile-up offset " << offset << " calib. const. = " << calibConst << " final energy = " << energyFinal); + } + + // final tau axis + if (m_doAxisCorr) { + + // get tau intermediate axis values + double eta = pTau->eta(); + double absEta = std::abs(eta); + double etaCorr = eta; + + if (absEta) + etaCorr = (eta / absEta)*(absEta - etaCorrectionHist->GetBinContent(etaCorrectionHist->GetXaxis()->FindBin(absEta))); + + ATH_MSG_DEBUG("eta " << eta << "; corrected eta = " << etaCorr); + + pTau->setP4( pTau->e() / cosh( etaCorr ), etaCorr, pTau->phi(), pTau->m()); + + pTau->setP4(xAOD::TauJetParameters::TauEtaCalib, pTau->pt(), pTau->eta(), pTau->phi(), pTau->m()); + + } + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalize +//----------------------------------------------------------------------------- + +StatusCode TauCalibrateLC::finalize() { + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauCellVariables.cxx b/Reconstruction/tauRec/src/TauCellVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d30423c9d1445e6e546e6a48fad41127e81959a1 --- /dev/null +++ b/Reconstruction/tauRec/src/TauCellVariables.cxx @@ -0,0 +1,402 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +NAME: TauCellVariables.cxx +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: S. Rajagopalan +CREATED: March 15, 2001 + +Aug 2001: Add (e,px,py,pz) for sum of EM cells (FEP) +Veto cell if track is within 0.8*size. Hence 1 cell if track +is in center, more otherwise. + +Sep 2001: Take account of larger cells in third layer + +Nov 2001: Omit third layer of EM calorimeter from EM sums. This layer +can become quite thick in the barrel, so it is more likely to +be hadronic, while photons are mainly contained in the first +two layers. (D. Lissauer suggested this.) + +Dec 2002: Add tau likelihood calculation. +Feb 2003: Fix phi wrapping for et-weighted phi calculation. +Jan 2004: Use CLHEP units. Use phi = (-pi,pi]. +Feb 2004: Fix identifiers, add taucmsdrdR +March 2004: Fix CaloCluster -> CaloEnergyCluster +Jul 2004: force -PI < phi < PI +Jul 2004: move to I4Momentum +Aug 2004: admit arbitrary seeds +23/10/2006 - (AK) fixing some compilation warnings (unused parameter) +18/04/2007 - (AK) fixing some compilation warnings (unused parameter) +18/01/2008 - (NM) use etaCalo/phiCalo for merged algo, set tauJet eta/phi if not set by tau1p3p +16/03/2010 - (AK) use the cell id instead of the pointer +17/03/2010 - (AK) change to P4Helpers +16/05/2011 - (FF) introduce possibility to correct cell origin wrt to primary vertex and beamspot +Jan 2012 - (FF) add cellEnergyRing variables + ********************************************************************/ + +#include <algorithm> +#include <math.h> +#include <vector> +#include <sstream> + +#include "GaudiKernel/Property.h" +#include "CLHEP/Units/SystemOfUnits.h" + +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "CaloEvent/CaloSamplingHelper.h" +#include "CaloUtils/CaloVertexedCell.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "Particle/TrackParticle.h" +#include "FourMom/P4EEtaPhiM.h" + +#include "xAODTau/TauJet.h" +#include "xAODJet/Jet.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TauCellVariables.h" + +using CLHEP::GeV; + +TauCellVariables::TauCellVariables(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent), +m_cellEthr(0.2 * GeV), +m_stripEthr(0.2 * GeV), +m_EMSumThr(0.5 * GeV), +m_EMSumR(0.2), +m_cellCone(0.2), +m_doCellCorrection(false) //FF: don't do cell correction by default +{ + declareInterface<TauToolBase > (this); + + declareProperty("CellEthreshold", m_cellEthr); + declareProperty("StripEthreshold", m_stripEthr); + declareProperty("EMSumThreshold", m_EMSumThr); + declareProperty("EMSumRadius", m_EMSumR); + declareProperty("CellCone", m_cellCone); + declareProperty("CellCorrection", m_doCellCorrection); +} + +TauCellVariables::~TauCellVariables() { +} + +StatusCode TauCellVariables::initialize() { + + ATH_MSG_VERBOSE("TauCellVariables::initialize"); // DEBUG + + StatusCode sc; + + // retrieve all helpers from det store + sc = detStore()->retrieve(m_emid); + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to retrieve LArEM_ID helper from DetectorStore"); + return sc; + } + ATH_MSG_VERBOSE("Storegate retrieved"); // DEBUG + + sc = detStore()->retrieve(m_tileid); + if (sc.isFailure()) { + ATH_MSG_ERROR("Unable to retrieve TileID helper from DetectorStore"); + return sc; + } + ATH_MSG_VERBOSE("TileID from DetectorStore"); // DEBUG + + return StatusCode::SUCCESS; +} + +StatusCode TauCellVariables::eventInitialize(TauCandidateData * /*data*/) { + return StatusCode::SUCCESS; +} + +StatusCode TauCellVariables::execute(TauCandidateData *data) { + + ATH_MSG_VERBOSE("execute"); // DEBUG + + AtlasDetectorID AtlasID; + + int numStripCell = 0; + int numEMCell = 0; + + double sumCellE = 0.; + double sumEMCellE = 0.; + + double eta = 0.; + double phi = 0.; + double stripEta = 0.; + double stripEta2 = 0.; + + double EMRadius = 0.; + + double sumStripET = 0.; + double sumCellET = 0.; + double sumEMCellET = 0.; + double sumCellET12 = 0.; + + double ET1Sum = 0; + + double EMET1Sum = 0; + double EMET4Sum = 0; + + double HadRadius = 0.; + double sumHadCellET = 0.; + + double cellEta, cellPhi, cellET, cellEnergy; + + std::vector<double> vCellRingEnergy(8,0.); //size=8, init with 0. + + /////////////////////////////////////////// + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + /////////////////////////////////////////// + + ATH_MSG_VERBOSE("get cluster position, use for cell loop"); + + ATH_MSG_VERBOSE("position is eta=" << pTau->eta() << " phi=" << pTau->phi() ); + + //use tau vertex to correct cell position + bool applyCellCorrection = false; + if (m_doCellCorrection && pTau->vertexLink()) { + applyCellCorrection = true; + } + + /////////////////////////////////////////////////////////////////////// + // loop over all cells of the tau (placed there by the TauSeedBuilder) + + const xAOD::Jet* pJetSeed = (*pTau->jetLink()); + if (!pJetSeed) { + ATH_MSG_WARNING("tau does not have jet seed for cell variable calculation"); + return StatusCode::SUCCESS; + } + + xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin(); + xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end(); + + unsigned int num_cells = 0; + + std::bitset<200000> cellSeen; + + for (; cItr != cItrE; ++cItr) { + + const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); + + CaloClusterCellLink::const_iterator firstcell = cluster->getCellLinks()->begin(); + CaloClusterCellLink::const_iterator lastcell = cluster->getCellLinks()->end(); + + + // ATH_MSG_VERBOSE( "in loop over clusters and cells : cluster phi= " << cluster->phi() << ", eta= " << cluster->eta()<< ", energy= " << cluster->e() << ", et= " <<cluster->pt() ); + + const CaloCell *cell; + double dR; + + //loop over cells and calculate the variables + for (; firstcell != lastcell; ++firstcell) { + cell = *firstcell; + + + if (cellSeen.test(cell->caloDDE()->calo_hash())) { + //already encountered this cell + continue; + } + else { + //New cell + cellSeen.set(cell->caloDDE()->calo_hash()); + } + ++num_cells; + + // ATH_MSG_VERBOSE( "in loop over clusters and cells : phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() ); + + // correct cell for tau vertex + if (applyCellCorrection) { + //ATH_MSG_INFO( "before cell correction: phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() ); + CaloVertexedCell vxCell (*cell, (*pTau->vertexLink())->position()); + cellPhi = vxCell.phi(); + cellEta = vxCell.eta(); + cellET = vxCell.et(); + cellEnergy = vxCell.energy(); + } + else { + cellPhi = cell->phi(); + cellEta = cell->eta(); + cellET = cell->et(); + cellEnergy = cell->energy(); + } + + CaloSampling::CaloSample calo = cell->caloDDE()->getSampling(); + + // Use cells those are in DR < m_cellCone of eta,phi of tau intermediate axis: + dR = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(),cellEta,cellPhi); + + if (dR < m_cellCone) { + // Global sums + sumCellE += cellEnergy; + + eta += cellEnergy * cellEta; + + // Must handle phi wrapping! Compute relative to cluster phi: + double dphicc = cellPhi - pTau->phi(); + if (dphicc > M_PI) dphicc = dphicc - 2 * M_PI; + if (dphicc < -M_PI) dphicc = dphicc + 2 * M_PI; + + phi += cellEnergy*dphicc; + + // If cell is an EM cell, include in sum for EM radius and for + // total EM (e,px,py,pz) + // Nov 2000: Only include first 2 layers in EM + + if (dR < 0.1) ET1Sum += cellET; + + if ((calo == CaloSampling::PreSamplerB) || + (calo == CaloSampling::PreSamplerE) || + + (calo == CaloSampling::EMB1) || + (calo == CaloSampling::EME1) || + + (calo == CaloSampling::EMB2) || + (calo == CaloSampling::EME2) || + + (calo == CaloSampling::EMB3) || + (calo == CaloSampling::EME3)) { + if (dR < 0.1) EMET1Sum += cellET; + if (dR < m_cellCone) EMET4Sum += cellET; + } + + if ((calo == CaloSampling::PreSamplerB) || + (calo == CaloSampling::PreSamplerE) || + + (calo == CaloSampling::EMB1) || + (calo == CaloSampling::EME1) || + + (calo == CaloSampling::EMB2) || + (calo == CaloSampling::EME2)) { + + sumEMCellE += cellEnergy; + + // If cell is a strip cell, sum for stripET calculation: + if (((calo == CaloSampling::EMB1) || + (calo == CaloSampling::EME1)) // to be investigated + && (fabs(cellEta) < 2.5)) { + sumStripET += cellET; + stripEta += cellEta * cellET; + stripEta2 += pow(cellEta, 2) * cellET; + if (cellEnergy > m_stripEthr) numStripCell += 1; + } // end of strip cells + + EMRadius += dR*cellET; + sumEMCellET += cellET; + if (cellEnergy > m_cellEthr) numEMCell += 1; + + }// end of EM cells + else { // HAD cells + HadRadius += dR*cellET; + sumHadCellET += cellET; + } + + // Sum cells in 0.1 < DR < 0.2 for Econe calculation + sumCellET += cellET; + if (dR > 0.1 && dR < 0.2) sumCellET12 += cellET; + + }// end of dR < m_cellCone + else { + // nothing + } + + // vCellRingEnergy[0] is a dummy value + if (dR < 0.05) vCellRingEnergy[1] += cellET; + if (dR >= 0.05 && dR < 0.075) vCellRingEnergy[2] += cellET; + if (dR >= 0.075 && dR < 0.1) vCellRingEnergy[3] += cellET; + if (dR >= 0.1 && dR < 0.125) vCellRingEnergy[4] += cellET; + if (dR >= 0.125 && dR < 0.15) vCellRingEnergy[5] += cellET; + if (dR >= 0.15 && dR < 0.2) vCellRingEnergy[6] += cellET; + if (dR >= 0.2 && dR < 0.4) vCellRingEnergy[7] += cellET; + + } // end of loop over CaloCells + + }// end of loop over seed jet constituents + + ATH_MSG_DEBUG(num_cells << " cells in seed"); + + ////////////////////////////////////////////////////////////////////////// + // save variables + // keep this here until we know nobody complains that these were removed together with all extra details variables + // pExtraDetails->setSeedCalo_sumCellEnergy(sumCellE); + // pExtraDetails->setSeedCalo_sumEMCellEnergy(sumEMCellE); + // pExtraDetails->setSeedCalo_nEMCell(numEMCell); + // pExtraDetails->setSeedCalo_stripEt(sumStripET); + // + + pTau->setDetail(xAOD::TauJetParameters::nStrip , numStripCell ); + + // if (fabs(EMET4Sum) > 0.000001) + // pExtraDetails->setSeedCalo_EMCentFrac(EMET1Sum / EMET4Sum); + // else + // pExtraDetails->setSeedCalo_EMCentFrac(0); + + if (fabs(sumStripET) > 0.000001) { + stripEta = stripEta / sumStripET; + stripEta2 = stripEta2 / sumStripET; + } else { + stripEta = 0; + stripEta2 = -1.0; + } + + pTau->setDetail(xAOD::TauJetParameters::stripWidth2 , static_cast<float>(stripEta2 - stripEta * stripEta) ); + + if (fabs(sumEMCellET) > 0.000001) { + EMRadius = EMRadius / sumEMCellET; + } else { + EMRadius = -1.0; + } + if (fabs(sumHadCellET) > 0.000001) { + HadRadius = HadRadius / sumHadCellET; + } else { + HadRadius = -1.0; + } + + pTau->setDetail(xAOD::TauJetParameters::EMRadius , static_cast<float>( EMRadius ) ); + pTau->setDetail(xAOD::TauJetParameters::etEMAtEMScale , static_cast<float>( sumEMCellET ) ); + pTau->setDetail(xAOD::TauJetParameters::hadRadius , static_cast<float>( HadRadius ) ); + pTau->setDetail(xAOD::TauJetParameters::etHadAtEMScale , static_cast<float>( sumHadCellET ) ); + + if (fabs(sumCellET) > 0.000001) { + pTau->setDetail(xAOD::TauJetParameters::centFrac , static_cast<float>( ET1Sum / sumCellET ) ); + pTau->setDetail(xAOD::TauJetParameters::isolFrac , static_cast<float>( sumCellET12 / sumCellET ) ); + } else { + pTau->setDetail(xAOD::TauJetParameters::centFrac , static_cast<float>( 0.0 ) ); + pTau->setDetail(xAOD::TauJetParameters::isolFrac , static_cast<float>( -1.0 ) ); + } + + //save cell ring energies + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing1 , static_cast<float>( vCellRingEnergy[1] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing2 , static_cast<float>( vCellRingEnergy[2] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing3 , static_cast<float>( vCellRingEnergy[3] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing4 , static_cast<float>( vCellRingEnergy[4] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing5 , static_cast<float>( vCellRingEnergy[5] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing6 , static_cast<float>( vCellRingEnergy[6] ) ); + + pTau->setDetail(xAOD::TauJetParameters::cellBasedEnergyRing7 , static_cast<float>( vCellRingEnergy[7] ) ); + + return StatusCode::SUCCESS; +} + + + + diff --git a/Reconstruction/tauRec/src/TauCommonCalcVars.cxx b/Reconstruction/tauRec/src/TauCommonCalcVars.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ff2ad3048e02b654837450066d54e1dca5720f1b --- /dev/null +++ b/Reconstruction/tauRec/src/TauCommonCalcVars.cxx @@ -0,0 +1,226 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauCommonCalcVars.cxx +// package: Reconstruction/tauRec +// authors: Stan Lai +// date: 2008-05-18 +// +// This class calculates tau variables after core seed reconstruction +// +// 17/03/2010: (AK) change to P4Helpers +// 16/05/2011: (FF) fix if primaryVertexContainer==NULL (coverity 21734) +// Dez 2011: (FF) switch to full LC calibrated tau 4-vector for some variables +//----------------------------------------------------------------------------- +//TODO: rename + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +#include "tauRec/TauCandidateData.h" + +#include "tauRec/TauCommonCalcVars.h" +#include "tauRec/KineUtils.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauCommonCalcVars::TauCommonCalcVars(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauCommonCalcVars::~TauCommonCalcVars() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauCommonCalcVars::initialize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauCommonCalcVars::finalize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauCommonCalcVars::execute(TauCandidateData *data) { + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + ///////////////////////////////////////////////// + // Calculate variables that are always valid + //////////////////////////////////////////////// + + // Leading track pT and et/pt(lead track) + if (pTau->nTracks() > 0) { + pTau->setDetail( xAOD::TauJetParameters::leadTrkPt, static_cast<float>( pTau->track(0)->pt() ) ); + + float emscale_ptEM = 0; + float emscale_ptHad = 0; + + if ( !pTau->detail( xAOD::TauJetParameters::etEMAtEMScale, emscale_ptEM ) ) + { + ATH_MSG_DEBUG("retrieval of tau detail failed. stopping calculation of further variables"); + return StatusCode::SUCCESS; + } + + if ( !pTau->detail( xAOD::TauJetParameters::etHadAtEMScale, emscale_ptHad ) ) + { + ATH_MSG_DEBUG("retrieval of tau detail failed. stopping calculation of further variables"); + return StatusCode::SUCCESS; + } + + //EM scale + + pTau->setDetail( xAOD::TauJetParameters::etOverPtLeadTrk, static_cast<float>( (emscale_ptEM + emscale_ptHad) / pTau->track(0)->pt() ) ); + + //switch to LC energy scale + //pDetails->setEtOverPtLeadTrk(pDetails->LC_TES_precalib() / fabs(pTau->track(0)->pt())); + } + + // XXX still need to decide whether we want to fill loose track variables anymore + // // Leading loose track pT and et/pt(lead loose track) + // if (pDetails->nLooseTrk() > 0) { + // pDetails->setLeadLooseTrkPt(pDetails->looseTrk(0)->pt()); + // //EM scale + // pDetails->setEtOverPtLeadLooseTrk((pDetails->seedCalo_etHadCalib() + pDetails->seedCalo_etEMCalib()) / fabs(pDetails->looseTrk(0)->pt())); + // //LC scale + // //pDetails->setEtOverPtLeadLooseTrk(pDetails->LC_TES_precalib() / fabs(pDetails->looseTrk(0)->pt())); + // } + + // invariant mass of track system + if ((pTau->nTracks() + pTau->nWideTracks()) > 0) { + + TLorentzVector sumOfTrackVector; + TLorentzVector tempTrackVector; + + for (unsigned int i = 0; i != pTau->nTracks(); ++i) + { + tempTrackVector.SetPtEtaPhiM( pTau->track(i)->pt(), pTau->track(i)->eta(), pTau->track(i)->phi(), pTau->track(i)->m()); + sumOfTrackVector += tempTrackVector; + } + for (unsigned int i = 0; i != pTau->nWideTracks(); ++i) + { + tempTrackVector.SetPtEtaPhiM( pTau->wideTrack(i)->pt(), pTau->wideTrack(i)->eta(), pTau->wideTrack(i)->phi(), pTau->wideTrack(i)->m()); + sumOfTrackVector += tempTrackVector; + } + + pTau->setDetail( xAOD::TauJetParameters::massTrkSys, static_cast<float>( sumOfTrackVector.M() ) ); + float tempfloat = 0; + if ( pTau->detail( xAOD::TauJetParameters::massTrkSys, tempfloat ) ) + ATH_MSG_VERBOSE("set massTrkSys " << tempfloat); + } + + // width of track system squared (trkWidth2) + if (pTau->nTracks() > 1) { + + double leadTrkPhi = pTau->track(0)->phi(); + double leadTrkEta = pTau->track(0)->eta(); + + double ptSum = 0; + double sumWeightedDR = 0; + double sumWeightedDR2 = 0; + + for (unsigned int i = 0; i != pTau->nTracks(); ++i) { + + double deltaR = Tau1P3PKineUtils::deltaR(leadTrkEta, leadTrkPhi, pTau->track(i)->eta(), pTau->track(i)->phi() ); + + ptSum += pTau->track(i)->pt(); + sumWeightedDR += deltaR * (pTau->track(i)->pt()); + sumWeightedDR2 += deltaR * deltaR * (pTau->track(i)->pt()); + } + + for (unsigned int i = 0; i != pTau->nWideTracks(); ++i) { + + double deltaR = Tau1P3PKineUtils::deltaR(leadTrkEta, leadTrkPhi, pTau->wideTrack(i)->eta(), pTau->wideTrack(i)->phi() ); + + ptSum += pTau->wideTrack(i)->pt(); + sumWeightedDR += deltaR * (pTau->wideTrack(i)->pt()); + sumWeightedDR2 += deltaR * deltaR * (pTau->wideTrack(i)->pt()); + } + + double trkWidth2 = sumWeightedDR2 / ptSum - sumWeightedDR * sumWeightedDR / ptSum / ptSum; + + if (trkWidth2 > 0.) pTau->setDetail( xAOD::TauJetParameters::trkWidth2, static_cast<float>( trkWidth2 ) ); + else pTau->setDetail( xAOD::TauJetParameters::trkWidth2, static_cast<float>( 0. ) ); + } + + // Calculation for seedCalo_trkAvgDist and seedCalo_trkRmsDist + + //FF: use now the 4-vector of the tau intermediate axis + //P4EEtaPhiM P4CaloSeed(1., pDetails->seedCalo_eta(), pDetails->seedCalo_phi(), 0.); + + if ((pTau->nWideTracks() + pTau->nTracks()) > 0) { + + double ptSum = 0; + double sumWeightedDR = 0; + double sumWeightedDR2 = 0; + + for (unsigned int i = 0; i != pTau->nTracks(); ++i) { + + double deltaR = Tau1P3PKineUtils::deltaR(pTau->eta(), pTau->phi(), pTau->track(i)->eta(), pTau->track(i)->phi() ); + + ptSum += pTau->track(i)->pt(); + sumWeightedDR += deltaR * (pTau->track(i)->pt()); + sumWeightedDR2 += deltaR * deltaR * (pTau->track(i)->pt()); + } + + for (unsigned int i = 0; i != pTau->nWideTracks(); ++i) { + + double deltaR = Tau1P3PKineUtils::deltaR(pTau->eta(), pTau->phi(), pTau->wideTrack(i)->eta(), pTau->wideTrack(i)->phi() ); + + ptSum += pTau->wideTrack(i)->pt(); + sumWeightedDR += deltaR * (pTau->wideTrack(i)->pt()); + sumWeightedDR2 += deltaR * deltaR * (pTau->wideTrack(i)->pt()); + } + + if (ptSum > 0.0001) { + // seedCalo_trkAvgDist + pTau->setDetail( xAOD::TauJetParameters::trkAvgDist, static_cast<float>( sumWeightedDR / ptSum ) ); + + float tempfloat; + if ( pTau->detail( xAOD::TauJetParameters::trkAvgDist, tempfloat ) ) + ATH_MSG_VERBOSE("set seedCalo_trkAvgDist " << tempfloat ); + + // seedCalo_trkRmsDist + double trkRmsDist2 = sumWeightedDR2 / ptSum - sumWeightedDR * sumWeightedDR / ptSum / ptSum; + if (trkRmsDist2 > 0) { + pTau->setDetail( xAOD::TauJetParameters::trkRmsDist, static_cast<float>( sqrt(trkRmsDist2) ) ); + } else { + pTau->setDetail( xAOD::TauJetParameters::trkRmsDist, static_cast<float>( 0. ) ); + } + if ( pTau->detail( xAOD::TauJetParameters::trkRmsDist, tempfloat ) ) + ATH_MSG_VERBOSE("set seedCalo_trkRmsDist " << tempfloat ); + } + } + + return StatusCode::SUCCESS; +} + + diff --git a/Reconstruction/tauRec/src/TauConversionFinder.cxx b/Reconstruction/tauRec/src/TauConversionFinder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f5636b97b408c362522f38894119611cbdd0999c --- /dev/null +++ b/Reconstruction/tauRec/src/TauConversionFinder.cxx @@ -0,0 +1,153 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +NAME: TauConversionFinder.cxx +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: Michael Boehler <michael.boehler@desy.de> +CREATED: November 2008 + +This tool identifies if a tau track is reconstructed as photon +conversion track too. + ********************************************************************/ + +#include "tauRec/TauConversionFinder.h" + +#include "xAODTracking/VertexContainer.h" +#include "GaudiKernel/IToolSvc.h" +#include "TrkParticleBase/LinkToTrackParticleBase.h" + +/********************************************************************/ +TauConversionFinder::TauConversionFinder(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); + + declareProperty("ConversionCandidatesName", m_ConversionCandidatesName = "ConversionsPID_Container"); //ConversionCandidate + declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles"); + declareProperty("DoNormalTracks", m_do_normal = true); + declareProperty("MinElectronProbability", m_eProb_cut = 0.9); + declareProperty("AdjustTauCharge", m_adjust_tau_charge = false); + +} + +/********************************************************************/ +TauConversionFinder::~TauConversionFinder() { +} + +/********************************************************************/ +StatusCode TauConversionFinder::initialize() { + ATH_MSG_VERBOSE("TauConversionFinder Initialising"); + + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode TauConversionFinder::finalize() { + ATH_MSG_VERBOSE("TauConversionFinder Finalizing"); + + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode TauConversionFinder::eventFinalize(TauCandidateData *data) { + + StatusCode sc; + + const Rec::TrackParticleContainer *trackContainer; + + //TODO: trigger uses getObject + sc = evtStore()->retrieve(trackContainer, m_trackContainerName); + if (sc.isFailure() || !trackContainer) { + ATH_MSG_DEBUG(" No track container found in TDS !!"); + return StatusCode::SUCCESS; + } + + // ------------------------------------------------------------------ + // Retrieving VxCandidates (conversions) + // ------------------------------------------------------------------ + const xAOD::VertexContainer* ConvContainer; + + sc = evtStore()->retrieve(ConvContainer, m_ConversionCandidatesName); + if (sc.isFailure() || !ConvContainer) { + ATH_MSG_DEBUG(" No VxCandidates container found in TDS !!"); + return StatusCode::SUCCESS; + } else { + ATH_MSG_VERBOSE("Processing Conversion Container Name = " << m_ConversionCandidatesName); + } + ATH_MSG_VERBOSE("VxContainer " << m_ConversionCandidatesName << " contains " << ConvContainer->size() << " vertices. "); + + // ------------------------------------------------------------------ + // Check number of Tau Tracks + // ------------------------------------------------------------------ + if (!m_do_normal) { + return StatusCode::SUCCESS; + } + + // running in eventFinalize + // therefore need to loop over all tau candidates + xAOD::TauJetContainer *pTauJetCont = data->xAODTauContainer; + for (xAOD::TauJetContainer::iterator tjcItr = pTauJetCont->begin(); tjcItr != pTauJetCont->end(); ++tjcItr) { + + xAOD::TauJet *pTau = *tjcItr; + if (pTau == NULL) { + ATH_MSG_DEBUG("no candidate given"); + continue; + } + + unsigned int numTracks = pTau->nTracks(); + + m_numProng = numTracks; + + if (m_do_normal) + ATH_MSG_VERBOSE("Number of tau tracks before ConversionFinder (TauJet): " << m_numProng); + + // Loop over Conversion Container placed by TauPhotonConversionFinder + xAOD::VertexContainer::const_iterator itr = ConvContainer->begin(); + xAOD::VertexContainer::const_iterator itrE = ConvContainer->end(); + for (; itr != itrE; ++itr) { + + const xAOD::Vertex* vxcand = (*itr); + + for (unsigned int i = 0; i < vxcand->nTrackParticles(); ++i) { + + const Trk::Track* conv_trk = vxcand->trackParticle(i)->track(); + // just check if the track is reconstructed only by TRT + //-------------------------------------------- + // Find conversion in normal tau tracks + if (m_do_normal) { + for (unsigned int j = 0; j < numTracks; ++j) { + const xAOD::TrackParticle *pTauTrack = pTau->track(j); + const Trk::Track* tau_trk_def = pTauTrack->track(); + + if (conv_trk == tau_trk_def) { + if (conv_trk->trackSummary()->getPID(Trk::eProbabilityComb) > m_eProb_cut) { + bool isConversionTrack = false; + for (unsigned int k = 0; k < pTau->nConversionTracks(); k++) { + if (pTau->conversionTrack(k)->track() == pTau->track(j)->track()) + isConversionTrack = true; + } + if (isConversionTrack) { + pTau->addConversionTrackLink(pTau->conversionTrackLinks().at(j)); + if (m_adjust_tau_charge) + pTau->setCharge(pTau->charge() - pTau->track(j)->charge()); + + m_numProng--; + } + } + } + } + } + }//end of loop over Tracks at vertex + }// end of loop over VxContainer + + if (m_do_normal) + ATH_MSG_VERBOSE("Number of tau tracks after ConversionFinder (TauJet): " << m_numProng); + }// end of loop over TauJetContainer + + return StatusCode::SUCCESS; +} + +/********************************************************************/ diff --git a/Reconstruction/tauRec/src/TauConversionTagger.cxx b/Reconstruction/tauRec/src/TauConversionTagger.cxx new file mode 100644 index 0000000000000000000000000000000000000000..75b705bdfd50e568d2a54965929365f7642168fc --- /dev/null +++ b/Reconstruction/tauRec/src/TauConversionTagger.cxx @@ -0,0 +1,179 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauConversionTagger.cxx +// package: Reconstruction/tauRec +// authors: Dimitris Varouchas +// date: 2013-11-08 +// +// +//----------------------------------------------------------------------------- +//TODO: + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" +#include "CLHEP/Vector/LorentzVector.h" +#include "Particle/TrackParticle.h" + +#include "EventInfo/EventInfo.h" +#include "EventInfo/EventID.h" +#include "TrkParameters/TrackParameters.h" + +#include "tauRec/TauCandidateData.h" +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauJetParameters.h" + +#include "tauRec/TauConversionTagger.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauConversionTagger::TauConversionTagger(const std::string &type, + const std::string &name, + const IInterface *parent) : + TauToolBase(type, name, parent), + m_trackToVertexTool("Reco::TrackToVertex") +{ + declareInterface<TauToolBase > (this); + + declareProperty("ConversionTaggerVersion", m_ConvTaggerVer = 1); + declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles"); + declareProperty("TrackToVertexTool", m_trackToVertexTool); + declareProperty ("TRTRatio", m_doTRTRatio = true); + declareProperty ("FullInfo", m_storeFullSummary = false); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauConversionTagger::~TauConversionTagger() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauConversionTagger::initialize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauConversionTagger::finalize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauConversionTagger::execute(TauCandidateData *data) { + xAOD::TauJet *pTau = data->xAODTau; + + StatusCode sc; + + sc = m_trackToVertexTool.retrieve(); + if(sc.isFailure()) { + ATH_MSG_ERROR("Could not retrieve TrackToVertexTool"); + return StatusCode::FAILURE; + } + + for(unsigned int j=0; j<pTau->nTracks(); j++ ) { + + const xAOD::TrackParticle *TauJetTrack = pTau->track(j); + const Trk::Perigee* perigee = m_trackToVertexTool->perigeeAtVertex(*TauJetTrack, (*pTau->vertexLink())->position()); + + // Declare TrackSummary info + // Note: all must be of type uint8_t for summaryValue filling to work in xAOD + // TODO: check if these default values are sane + uint8_t nBLHits = 0; + uint8_t expectBLayerHit = 0; + uint8_t nTRTHighTHits = 0; + uint8_t nTRTHighTOutliers = 0; + float nTRTHighT_outl = 0.; + uint8_t nTRTXenon = 0; + uint8_t nTRTHits = 0; + uint8_t nTRTOutliers = 0; + + // Fill TrackSummary info + TauJetTrack->summaryValue(nBLHits,xAOD::numberOfBLayerHits); + TauJetTrack->summaryValue(expectBLayerHit,xAOD::expectBLayerHit); + TauJetTrack->summaryValue(nTRTHighTHits,xAOD::numberOfTRTHighThresholdHits); + TauJetTrack->summaryValue(nTRTHighTOutliers,xAOD::numberOfTRTHighThresholdOutliers); + nTRTHighT_outl = nTRTHighTHits + nTRTHighTOutliers; + TauJetTrack->summaryValue(nTRTXenon,xAOD::numberOfTRTXenonHits); + TauJetTrack->summaryValue(nTRTHits,xAOD::numberOfTRTHits); + TauJetTrack->summaryValue(nTRTOutliers,xAOD::numberOfTRTOutliers); + + // TODO: check if default value is sane + m_TRTHighTOutliersRatio = 0.; + if (m_doTRTRatio || m_storeFullSummary) { + if (nTRTXenon > 0) + m_TRTHighTOutliersRatio = nTRTHighT_outl / nTRTXenon; + else if (nTRTHits + nTRTOutliers > 0) + m_TRTHighTOutliersRatio = nTRTHighT_outl / (nTRTHits+nTRTOutliers); + } + + double pt = TauJetTrack->pt(); + double d0 = perigee->parameters()[Trk::d0]; + + + m_TrkIsConv = false; + + float Rconv = sqrt (fabs(d0)*pt/(0.15*2.)); + + if ( m_ConvTaggerVer==0 ) { + + m_a_cut[0][0]=0.0003; m_b_cut[0][0]=0.1725; + m_a_cut[0][1]=0.0003; m_b_cut[0][1]=0.2025; + + if ( nBLHits==0 && expectBLayerHit ){ + if( m_TRTHighTOutliersRatio > -m_a_cut[0][0]*Rconv + m_b_cut[0][0] ) m_TrkIsConv=true; + } + else { + if( m_TRTHighTOutliersRatio > -m_a_cut[0][1]*Rconv + m_b_cut[0][1] ) m_TrkIsConv=true; + } + } + + else if ( m_ConvTaggerVer==1 ) { + + m_a_cut[1][0]=0.0003; m_b_cut[1][0]=0.1725; + m_a_cut[1][1]=0.0003; m_b_cut[1][1]=0.2025; + + + if(nBLHits==0 ){ + if( m_TRTHighTOutliersRatio > -m_a_cut[1][0]*Rconv + m_b_cut[1][0] ) m_TrkIsConv=true; + } + else { + if( m_TRTHighTOutliersRatio > -m_a_cut[1][1]*Rconv + m_b_cut[1][1] ) m_TrkIsConv=true; + } + } + + else { + + ATH_MSG_WARNING("No tau conversion tagger compatible with version "<<m_ConvTaggerVer); + return false; + } + + ATH_MSG_VERBOSE("Is tau track a conversion? : " << m_TrkIsConv); + if (m_TrkIsConv) + pTau->addConversionTrackLink((&pTau->trackLinks())->at(j)); + + delete perigee; //cleanup necessary to prevent mem leak + + } + + return StatusCode::SUCCESS; +} + diff --git a/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx b/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f788db96a049e8c50471b06b7a3a209e54643ef9 --- /dev/null +++ b/Reconstruction/tauRec/src/TauElectronVetoVariables.cxx @@ -0,0 +1,390 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: tau1p3pEleVeto.cxx +// package: Reconstruction/tauRec +// authors: Zofia Czyczula +// date: 2006-09-27 +// +// +// This tool veto electrons. +// +// MODIFIED: +// 02-04-2007 - (AK) protection against missing egamma Collection +// 25-03-2008 - (AK for ZC) upgade of the code +// 28-03-1008 - (AK) fix for protection against missing egamma Collection +// ERROR->WARNING +// 15/04/2008 - (AK) fixing compilation warning bug #35463 +// 03-10-2008 - (ZC) upgarade of the code +// 16/03/2010 - (AK) use the cell id instead of the pointer +//----------------------------------------------------------------------------- + +//// +//TODO: this is cell based and use tracking variables -> can not run on AOD +//TODO: rename +// + +#include <algorithm> +#include <math.h> +#include <sstream> + +#include "GaudiKernel/ListItem.h" +#include "GaudiKernel/IToolSvc.h" +#include "GaudiKernel/Property.h" + +#include "CaloUtils/CaloCellList.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "CaloUtils/CaloVertexedCell.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloGeoHelpers/CaloSampling.h" + +#include "xAODTau/TauJet.h" +#include "xAODJet/Jet.h" +#include "tauRec/KineUtils.h" + +#include "RecoToolInterfaces/IExtrapolateToCaloTool.h" +#include "tauRec/TauElectronVetoVariables.h" + +using CLHEP::GeV; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- +TauElectronVetoVariables::TauElectronVetoVariables(const std::string &type, + const std::string &name, + const IInterface *parent): +TauToolBase(type, name, parent), +m_doCellCorrection(false), //FF: don't do cell correction by default +m_trackToCalo("") +{ + declareInterface<TauToolBase > (this); + + declareProperty("CellCorrection", m_doCellCorrection); + declareProperty("TTCExtrapolator", m_trackToCalo, "public track extrapolator tool to match track with caloseed"); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- +TauElectronVetoVariables::~TauElectronVetoVariables() { } + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- +StatusCode TauElectronVetoVariables::initialize() +{ + if (m_trackToCalo.retrieve().isFailure()) { + ATH_MSG_ERROR("Cannot find tool named <" << m_trackToCalo << ">"); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} +StatusCode TauElectronVetoVariables::eventInitialize(TauCandidateData * /*data*/) +{ + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// Execution +//------------------------------------------------------------------------- +StatusCode TauElectronVetoVariables::execute(TauCandidateData *data) +{ + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + + if (pTau->nTracks() < 1) { + return StatusCode::SUCCESS; + } + + ATH_MSG_VERBOSE(name() << " in execute() ..."); + + float detPhiTrk = 0.; + float detEtaTrk = 0.; + float clEtaTrk = 0.; + float distEtaTrk = 0.; + + float energy_3phi[101] = {0.0}; + float eta[101] = {0.0}; + int max1 = 0; + int max2 = 0; + int max = 0; + int n = 0; + float Emax1 = 0.; + float Emax2 = 0.; + float etamaxcut = 0.158; + float phimaxcut = 0.1; + float signum_eta = 0.; + + signum_eta = pTau->track(0)->eta() / fabs(pTau->track(0)->eta()); + + float sumETCellsLAr = 0.; + float eta0cut = 0.075; + float eta1cut = 0.0475; + float eta2cut = 0.075; + float eta3cut = 1.5; + float phi0cut = 0.3; + float phi1cut = 0.3; + float phi2cut = 0.075; + float phi3cut = 0.075; + float etareg = 0.; + float etacase1 = 1.8; + float etagran1 = 0.00315; + float etagran2 = 0.00415; + float sumETCellsHad1 = 0.; + float etahadcut = 0.2; + float phihadcut = 0.2; + + const CaloCell *pCell; + + //use tau vertex to correct cell position + bool applyCellCorrection = false; + if (m_doCellCorrection && pTau->vertexLink()) { + applyCellCorrection = true; + } + + //--------------------------------------------------------------------- + // Calculate eta, phi impact point of leading track at calorimeter layers EM 0,1,2,3 + //--------------------------------------------------------------------- + const DataVector< const Trk::TrackParameters >* pTrk = m_trackToCalo->getParametersInCalo( ( *pTau->track(0) ) , Trk::pion, Trk::alongMomentum); //FIXME + + const int numOfsampEM = 4; + double eta_extrapol[4]; + double phi_extrapol[4]; + + for (int i = 0; i < numOfsampEM; ++i) { + eta_extrapol[i] = -11111.; + phi_extrapol[i] = -11111.; + } + + + if (pTrk && (*pTrk)[IExtrapolateToCaloTool::PreSampler]) { + eta_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().eta(); + phi_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().phi(); + } + + if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Strips]) { + eta_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta(); + phi_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi(); + } + + if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Middle]) { + eta_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().eta(); + phi_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().phi(); + } + + if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Back]) { + eta_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().eta(); + phi_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().phi(); + } + + + + + for (int i = 0; i < numOfsampEM; ++i) { + if ( eta_extrapol[i] < -11110. || phi_extrapol[i] < -11110. ) + { + ATH_MSG_WARNING("extrapolation of leading track to calo surfaces failed for sampling : " << i ); + return StatusCode::SUCCESS; + } + } + + const xAOD::Jet* pJetSeed = (*pTau->jetLink()); + if (!pJetSeed) { + ATH_MSG_WARNING("tau does not have jet seed for electron veto cell variable calculation"); + return StatusCode::SUCCESS; + } + + xAOD::JetConstituentVector::const_iterator cItr = pJetSeed->getConstituents().begin(); + xAOD::JetConstituentVector::const_iterator cItrE = pJetSeed->getConstituents().end(); + + std::bitset<200000> cellSeen; + + for (; cItr != cItrE; ++cItr) { + + const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>( (*cItr)->rawConstituent() ); + + CaloClusterCellLink::const_iterator pCellIter = cluster->getCellLinks()->begin(); + CaloClusterCellLink::const_iterator pCellIterE = cluster->getCellLinks()->end(); + + + double cellPhi; + double cellEta; + double cellET; + for (; pCellIter != pCellIterE; pCellIter++) { + + pCell = *pCellIter; + + if (cellSeen.test(pCell->caloDDE()->calo_hash())) { + //already encountered this cell + continue; + } + else { + //New cell + cellSeen.set(pCell->caloDDE()->calo_hash()); + } + + + if (applyCellCorrection) { + //ATH_MSG_INFO( "before cell correction: phi= " << cell->phi() << ", eta= " << cell->eta()<< ", energy= " << cell->energy() << ", et= " <<cell->et() ); + CaloVertexedCell vxCell (*pCell, (*pTau->vertexLink())->position()); + cellPhi = vxCell.phi(); + cellEta = vxCell.eta(); + cellET = vxCell.et(); + } + else { + cellPhi = pCell->phi(); + cellEta = pCell->eta(); + cellET = pCell->et(); + } + + int sampling = pCell->caloDDE()->getSampling(); + if (sampling == 4) sampling = 0; + if (sampling == 5) sampling = 1; + if (sampling == 6) sampling = 2; + if (sampling == 7) sampling = 3; + if (sampling == 18) sampling = 12; + if (sampling == 8) sampling = 12; + if (sampling == 15) sampling = 12; + if (sampling == 19) sampling = 13; + if (sampling == 16) sampling = 13; + if (sampling == 20) sampling = 14; + if (sampling == 17) sampling = 14; + + int i = 2; + if (sampling < 4) i = sampling; + if (sampling == 12 || sampling == 13 || sampling == 14) i = 3; + + detPhiTrk = Tau1P3PKineUtils::deltaPhi( cellPhi, phi_extrapol[i] ); + detEtaTrk = std::fabs( cellEta - eta_extrapol[i] ); + clEtaTrk = eta_extrapol[i]; + distEtaTrk = cellEta - eta_extrapol[i]; + + if ((sampling == 0 && detEtaTrk < eta0cut && detPhiTrk < phi0cut) || + (sampling == 1 && detEtaTrk < eta1cut && detPhiTrk < phi1cut) || + (sampling == 2 && detEtaTrk < eta2cut && detPhiTrk < phi2cut) || + (sampling == 3 && detEtaTrk < eta3cut && detPhiTrk < phi3cut)) { + + sumETCellsLAr += cellET; + } + + if (sampling == 12 && detEtaTrk < etahadcut && detPhiTrk < phihadcut) sumETCellsHad1 += cellET; + + if (fabs(cellEta) > 0.8 && fabs(cellEta) <= 1.2 && (sampling == 13 || sampling == 14) && detEtaTrk < etahadcut && detPhiTrk < phihadcut) { + sumETCellsHad1 += cellET; + } + + if (fabs(pTau->track(0)->eta()) <= 1.7) { + if (sampling == 1 && detEtaTrk < etamaxcut && detPhiTrk <= phimaxcut) { + if ((fabs(cellEta) < 1.37 || fabs(cellEta) > 1.52) && fabs(cellEta) < 1.85) { + if (fabs(clEtaTrk) <= etacase1 && fabs(cellEta) <= etacase1) { + n = 50 + int(distEtaTrk / etagran1); + } + if (fabs(clEtaTrk) <= etacase1 && fabs(cellEta) > etacase1) { + n = 50 + int(signum_eta * ((etacase1 - fabs(clEtaTrk)) / etagran1 + (-etacase1 + fabs(cellEta)) / etagran2)); + } + energy_3phi[n] = energy_3phi[n] + cellET / GeV; + eta[n] = signum_eta * (clEtaTrk - cellEta); + } else { + energy_3phi[n] = 0; + eta[n] = 0; + } + } + } else { + energy_3phi[n] = 0; + eta[n] = 0; + } + + if (fabs(cellEta) <= etacase1) { + etareg = 0.00315; + } else { + etareg = 0.00415; + } + + } //end cell loop + + }// end jet constituent loop + + for (int m1 = 0; m1 < 101; m1++) { + if ((energy_3phi[m1] > Emax1)) { + Emax1 = energy_3phi[m1]; + max1 = m1; + } + } + + for (int m2 = 1; m2 < 100; m2++) { + if (m2 == max1) continue; + + if ((energy_3phi[m2] > Emax2) && (energy_3phi[m2] > energy_3phi[m2 - 1]) && (energy_3phi[m2] > energy_3phi[m2 + 1])) { + Emax2 = energy_3phi[m2]; + max2 = m2; + } + } + + if (fabs(eta[max1]) >= etareg) { + max = max1; + } else { + max = max2; + } + + + float TRTratio = -9999.0; + uint8_t TRTHTHits; + uint8_t TRTHTOutliers; + uint8_t TRTHits; + uint8_t TRTOutliers; + + if ( !pTau->track(0)->summaryValue( TRTHits, xAOD::SummaryType::numberOfTRTHits ) ) + { + ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate"); + return StatusCode::SUCCESS; + } + if ( !pTau->track(0)->summaryValue( TRTHTHits, xAOD::SummaryType::numberOfTRTHighThresholdHits ) ) + { + ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate"); + return StatusCode::SUCCESS; + } + if ( !pTau->track(0)->summaryValue( TRTOutliers, xAOD::SummaryType::numberOfTRTOutliers ) ) + { + ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate"); + return StatusCode::SUCCESS; + } + if ( !pTau->track(0)->summaryValue( TRTHTOutliers, xAOD::SummaryType::numberOfTRTHighThresholdOutliers ) ) + { + ATH_MSG_DEBUG("retrieval of track summary value failed. Not filling electron veto variables for this one prong candidate"); + return StatusCode::SUCCESS; + } + + + if (TRTHits + TRTOutliers != 0) { + TRTratio = float( TRTHTHits + TRTHTOutliers) / float( TRTHits + TRTOutliers ); + } else { + TRTratio = 0.0; + } + // } + + pTau->setDetail(xAOD::TauJetParameters::TRT_NHT_OVER_NLT , TRTratio ); + pTau->setDetail(xAOD::TauJetParameters::secMaxStripEt , energy_3phi[max] ); + pTau->setDetail(xAOD::TauJetParameters::hadLeakEt , static_cast<float>( sumETCellsHad1 / ( pTau->track(0)->pt() ) ) ); + pTau->setDetail(xAOD::TauJetParameters::sumEMCellEtOverLeadTrkPt , static_cast<float>( ( sumETCellsLAr / ( pTau->track(0)->pt() ) ) ) ); + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //delete the trackparemeters returned by tracktocalo + if (pTrk) delete pTrk; + + return StatusCode::SUCCESS; +} + + + + diff --git a/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx b/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6dd3de18e22dd01b1ea2e6a77175d1e98e4c2e19 --- /dev/null +++ b/Reconstruction/tauRec/src/TauGenericPi0Cone.cxx @@ -0,0 +1,107 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauGenericPi0Cone.cxx +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-04 +// +// +//----------------------------------------------------------------------------- + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" +#include "Particle/TrackParticle.h" + +#include "tauRec/TauCandidateData.h" +#include "tauEvent/TauCommonDetails.h" +#include "tauEvent/TauJetParameters.h" + +#include "tauRec/TauGenericPi0Cone.h" +#include "tauRec/TauTrackFilterUtils.h" + +#include "TLorentzVector.h" + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauGenericPi0Cone::TauGenericPi0Cone(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); +} + + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauGenericPi0Cone::~TauGenericPi0Cone() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauGenericPi0Cone::initialize() { + ATH_MSG_VERBOSE("TauGenericPi0Cone Initialising"); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauGenericPi0Cone::finalize() { + ATH_MSG_VERBOSE("TauGenericPi0Cone Finalizing"); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauGenericPi0Cone::execute(TauCandidateData *data) { + ATH_MSG_VERBOSE("TauGenericPi0Cone Executing"); + + xAOD::TauJet *pTau = data->xAODTau; + + TLorentzVector tau; + tau.SetPtEtaPhiE(pTau->pt(), + pTau->eta(), + pTau->phi(), + pTau->e()); + + int nProng = pTau->trackFilterProngs(); + int flag = pTau->trackFilterQuality(); + float pi0angle = 0.; //TODO sane default value + + // Get pi0 cone + if(flag != 0){ + int recProng = 0; + if((nProng == 3)||(nProng == 2)) recProng = 3; + if(nProng == 1) recProng = 1; + pi0angle = TauTrackFilterUtils::ComputePi0Cone(recProng,tau); + } + + // Convert to dR. + m_pi0conedr = std::min(pi0angle*cosh(tau.Eta()), 0.2); + + // Store result + pTau->setPi0ConeDR(m_pi0conedr); + + return StatusCode::SUCCESS; +} + diff --git a/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx b/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8843a927e6071220de142fcc04d5a587e9f52a9f --- /dev/null +++ b/Reconstruction/tauRec/src/TauPi0BonnClusterCreator.cxx @@ -0,0 +1,602 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0BonnClusterCreator.cxx +// package: Reconstruction/tauEvent +// authors: Benedict Winter, Will Davey +// date: 2012-10-09 +// +//----------------------------------------------------------------------------- + +#include <vector> + +#include "CaloUtils/CaloClusterStoreHelper.h" +#include "CaloGeoHelpers/CaloSampling.h" +#include "AnalysisUtils/AnalysisMisc.h" +#include "FourMomUtils/P4Helpers.h" + +#include "tauRec/TauPi0BonnClusterCreator.h" + +#include "RecoToolInterfaces/IExtrapolateToCaloTool.h" + +using std::vector; +using std::string; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0BonnClusterCreator::TauPi0BonnClusterCreator( + const string& type, + const string& name, + const IInterface *parent) + + : TauToolBase(type, name, parent) + , m_trackToCaloTool("") + , m_cellContainerName("TauCommonPi0CellContainer") + , m_inputPi0ClusterContainerName("TauPi0BonnSubtractedClusterContainer") + , m_outputPi0ClusterContainerName("TauPi0BonnClusterContainer") + , m_neutralPFOContainerName("TauPi0BonnNeutralPFOContainer") + , m_clusterEtCut(500.) +{ + declareInterface<TauToolBase > (this); + + declareProperty("ExtrapolateToCaloTool", m_trackToCaloTool); + declareProperty("CellContainerName", m_cellContainerName); + declareProperty("InputPi0ClusterContainerName", m_inputPi0ClusterContainerName); + declareProperty("OutputPi0ClusterContainerName", m_outputPi0ClusterContainerName); + declareProperty("NeutralPFOContainerName", m_neutralPFOContainerName); + declareProperty("ClusterEtCut", m_clusterEtCut); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0BonnClusterCreator::~TauPi0BonnClusterCreator() +{ +} + + +StatusCode TauPi0BonnClusterCreator::initialize() +{ + CHECK( m_trackToCaloTool.retrieve() ); + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnClusterCreator::eventInitialize(TauCandidateData * /*data*/) +{ + // create new CaloClusterContainer + // this container will later persistified + // so it will get ownership of the objects + m_pOutputPi0CaloClusterContainer = new xAOD::CaloClusterContainer(SG::OWN_ELEMENTS); + ATH_MSG_VERBOSE("record container " << m_outputPi0ClusterContainerName); + //--------------------------------------------------------------------- + // Create container for Pi0 + //--------------------------------------------------------------------- + m_pOutputPi0CaloClusterContainer = CaloClusterStoreHelper::makeContainer(&*evtStore(), + m_outputPi0ClusterContainerName, + msg() + ); + + //--------------------------------------------------------------------- + // Create neutral PFO container + //--------------------------------------------------------------------- + m_neutralPFOContainer = new xAOD::PFOContainer(); + CHECK( evtStore()->record(m_neutralPFOContainer, m_neutralPFOContainerName ) ); + m_neutralPFOAuxStore = new xAOD::PFOAuxContainer(); + CHECK( evtStore()->record( m_neutralPFOAuxStore, m_neutralPFOContainerName + "Aux." ) ); + m_neutralPFOContainer->setStore(m_neutralPFOAuxStore); + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnClusterCreator::execute(TauCandidateData *data) +{ + xAOD::TauJet *pTau = data->xAODTau; + + //--------------------------------------------------------------------- + // only run shower subtraction on 1-5 prong taus + //--------------------------------------------------------------------- + if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) { + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("ClusterCreator: new tau. \tpt = " << pTau->pt() << "\teta = " << pTau->eta() << "\tphi = " << pTau->phi() << "\tnprongs = " << pTau->nTracks()); + + //--------------------------------------------------------------------- + // get tau tracks + //--------------------------------------------------------------------- + vector<const xAOD::TrackParticle*> tracks; + for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){ + const xAOD::TrackParticle* track = pTau->track(iTrack); + tracks.push_back(track); + } + + //--------------------------------------------------------------------- + // retrieve the CaloClusterContainer created by the CaloClusterMaker + //--------------------------------------------------------------------- + const xAOD::CaloClusterContainer *pPi0ClusterContainer; + CHECK( evtStore()->retrieve(pPi0ClusterContainer, m_inputPi0ClusterContainerName) ); + + //--------------------------------------------------------------------- + // extrapolate track to calo layers + //--------------------------------------------------------------------- + vector<vector<float> > tracksEtaAtSampling; + vector<vector<float> > tracksPhiAtSampling; + for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){ + const xAOD::TrackParticle* track = pTau->track(iTrack); + vector<float> trackEtaAtSampling; + vector<float> trackPhiAtSampling; + this->getExtrapolatedPositions(track,trackEtaAtSampling,trackPhiAtSampling); + tracksEtaAtSampling.push_back(trackEtaAtSampling); + tracksPhiAtSampling.push_back(trackPhiAtSampling); + } + + //--------------------------------------------------------------------- + // TODO: May want to use tau vertex in the future to calculate some cluster moments (DELTA_THETA, etc.). + // Doesn't help now, since all moments are calculated wrt 0.0.0 atm. + //--------------------------------------------------------------------- + + + // Retrieve Ecal1 shots and match them to clusters + //--------------------------------------------------------------------- + std::vector<const xAOD::PFO*> shotVector; + unsigned nShots = pTau->nShot_PFOs(); + for(unsigned iShot=0;iShot<nShots;++iShot){ + const xAOD::PFO* thisShot = pTau->shot_PFO(iShot); + shotVector.push_back( thisShot ); + } + std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap = getClusterToShotMap(shotVector, pPi0ClusterContainer, pTau); + + xAOD::CaloClusterContainer::const_iterator clusterItr (pPi0ClusterContainer->begin()), + clusterItrEnd(pPi0ClusterContainer->end()); + for (; clusterItr != clusterItrEnd; ++clusterItr){ + + // selection + if ((*clusterItr)->pt() < m_clusterEtCut) continue; + // Cluster container has clusters for all taus. + // Only run on clusters that belong to this tau + if ((*clusterItr)->p4().DeltaR(pTau->p4()) > .4) continue; + + // Get shots in this cluster. Need to use (CaloCluster*) (*clusterItr) + // (not a copy!) since the pointer will otherwise be different than in clusterToShotMap + std::vector<unsigned> shotsInCluster = getShotsMatchedToCluster( shotVector, clusterToShotMap, (xAOD::CaloCluster*) (*clusterItr)); + + // Make a copy of the cluster to store in output container. + xAOD::CaloCluster* pPi0Cluster = new xAOD::CaloCluster( *(*clusterItr) ); + + // store pi0 calo cluster in the output container + m_pOutputPi0CaloClusterContainer->push_back(pPi0Cluster); + + // Calculate input variables for fake supression. + // Do this before applying the vertex correction, + // since the position of the cluster in the + // calorimeter is required. + float EM1CoreFrac = getEM1CoreFrac(pPi0Cluster); + float asymmetryInEM1WRTTrk = getAsymmetryInEM1WRTTrk(pPi0Cluster, tracksEtaAtSampling, tracksPhiAtSampling); + int NHitsInEM1 = getNPhotons(shotVector, shotsInCluster); + vector<int> NPosECellsInLayer = getNPosECells(pPi0Cluster); + vector<float> firstEtaWRTClusterPositionInLayer = get1stEtaMomWRTCluster(pPi0Cluster); + vector<float> secondEtaWRTClusterPositionInLayer = get2ndEtaMomWRTCluster(pPi0Cluster); + + // Retrieve cluster moments that are used for fake supression and that are not stored in AOD + // for every cluster. Do this after applying the vertex correction, since the moments + // (especcially DELTA_PHI and DELTA_THETA) must be calculated WRT the tau vertex + double CENTER_MAG = 0.0; + double FIRST_ETA = 0.0; + double SECOND_R = 0.0; + double SECOND_LAMBDA = 0.0; + double DELTA_PHI = 0.0; + double DELTA_THETA = 0.0; + double CENTER_LAMBDA = 0.0; + double LATERAL = 0.0; + double LONGITUDINAL = 0.0; + double ENG_FRAC_EM = 0.0; + double ENG_FRAC_MAX = 0.0; + double ENG_FRAC_CORE = 0.0; + double SECOND_ENG_DENS = 0.0; + + // TODO: Replace numbers by human readable enums + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 404, CENTER_MAG) ) ATH_MSG_WARNING("Couldn't retrieve CENTER_MAG moment. Set it to 0."); + + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 102, FIRST_ETA) ) ATH_MSG_WARNING("Couldn't retrieve FIRST_ETA moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 201, SECOND_R) ) ATH_MSG_WARNING("Couldn't retrieve SECOND_R moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 202, SECOND_LAMBDA) ) ATH_MSG_WARNING("Couldn't retrieve SECOND_LAMBDA moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 301, DELTA_PHI) ) ATH_MSG_WARNING("Couldn't retrieve DELTA_PHI moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 302, DELTA_THETA) ) ATH_MSG_WARNING("Couldn't retrieve DELTA_THETA moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 501, CENTER_LAMBDA) ) ATH_MSG_WARNING("Couldn't retrieve CENTER_LAMBDA moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 601, LATERAL) ) ATH_MSG_WARNING("Couldn't retrieve LATERAL moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 602, LONGITUDINAL) ) ATH_MSG_WARNING("Couldn't retrieve LONGITUDINAL moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 701, ENG_FRAC_EM) ) ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_EM moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 702, ENG_FRAC_MAX) ) ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_MAX moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 703, ENG_FRAC_CORE) ) ATH_MSG_WARNING("Couldn't retrieve ENG_FRAC_CORE moment. Set it to 0."); + if( !pPi0Cluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 805, SECOND_ENG_DENS) ) ATH_MSG_WARNING("Couldn't retrieve SECOND_ENG_DENS moment. Set it to 0."); + + float E_EM1 = pPi0Cluster->eSample(CaloSampling::EMB1) + pPi0Cluster->eSample(CaloSampling::EME1); + float E_EM2 = pPi0Cluster->eSample(CaloSampling::EMB2) + pPi0Cluster->eSample(CaloSampling::EME2); + + // create neutral PFO. Set BDTScore to dummy value <-1. The BDT score is calculated within TauPi0BonnSelector.cxx. + xAOD::PFO* neutralPFO = new xAOD::PFO(); + m_neutralPFOContainer->push_back( neutralPFO ); + + // Create element link from tau to neutral PFO + ElementLink<xAOD::PFOContainer> PFOElementLink; + PFOElementLink.toContainedElement( *m_neutralPFOContainer, neutralPFO ); + pTau->addCellBased_Neutral_PFOLink( PFOElementLink ); + + // Set PFO variables + ElementLink<xAOD::CaloClusterContainer> clusElementLink; + clusElementLink.toContainedElement( *m_pOutputPi0CaloClusterContainer, pPi0Cluster ); + neutralPFO->setClusterLink( clusElementLink ); + + neutralPFO->setP4( (float) pPi0Cluster->pt(), (float) pPi0Cluster->eta(), (float) pPi0Cluster->phi(), (float) pPi0Cluster->m()); + neutralPFO->setBDTPi0Score( (float) -9999. ); + neutralPFO->setCharge( 0. ); + + neutralPFO->setCenterMag( (float) CENTER_MAG); + + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, -1); + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, -1); + + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_FIRST_ETA, (float) FIRST_ETA); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_R, (float) SECOND_R); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_LAMBDA, (float) SECOND_LAMBDA); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_PHI, (float) DELTA_PHI); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_THETA, (float) DELTA_THETA); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_CENTER_LAMBDA, (float) CENTER_LAMBDA); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_LATERAL, (float) LATERAL); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_LONGITUDINAL, (float) LONGITUDINAL); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_EM, (float) ENG_FRAC_EM); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_MAX, (float) ENG_FRAC_MAX); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_CORE, (float) ENG_FRAC_CORE); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_ENG_DENS, (float) SECOND_ENG_DENS); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM1, (float) E_EM1); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM2, (float) E_EM2); + + + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_EM1CoreFrac, EM1CoreFrac); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_asymmetryInEM1WRTTrk, asymmetryInEM1WRTTrk); + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NHitsInEM1, NHitsInEM1); + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_PS, NPosECellsInLayer.at(0)); + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM1, NPosECellsInLayer.at(1)); + neutralPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM2, NPosECellsInLayer.at(2)); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM1, firstEtaWRTClusterPositionInLayer.at(1)); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM2, firstEtaWRTClusterPositionInLayer.at(2)); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM1, secondEtaWRTClusterPositionInLayer.at(1)); + neutralPFO->setAttribute<float>(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM2, secondEtaWRTClusterPositionInLayer.at(2)); + + // Store shot element links in neutral PFO + std::vector<ElementLink<xAOD::IParticleContainer> > shotlinks; + for(unsigned iShot = 0;iShot<shotsInCluster.size();++iShot){ + ElementLink<xAOD::PFOContainer> shotPFOElementLink = pTau->shot_PFOLinks().at(shotsInCluster.at(iShot)); + ElementLink<xAOD::IParticleContainer> shotElementLink; + shotPFOElementLink.toPersistent(); + shotElementLink.resetWithKeyAndIndex( shotPFOElementLink.persKey(), shotPFOElementLink.persIndex() ); + if (!shotElementLink.isValid()) ATH_MSG_WARNING("Created an invalid element link to xAOD track particle"); + shotlinks.push_back(shotElementLink); + } + if(!neutralPFO->setAssociatedParticleLinks( xAOD::PFODetails::TauShot,shotlinks)) + ATH_MSG_WARNING("Couldn't add shot links to neutral PFO!"); + } + return StatusCode::SUCCESS; +} + + +StatusCode TauPi0BonnClusterCreator::eventFinalize(TauCandidateData *) +{ + // pt sort container at the end of the event + // if(m_pOutputPi0CaloClusterContainer->size()) AnalysisUtils::Sort::pT(m_pOutputPi0CaloClusterContainer); + + //---------------------------------------------------------------------- + // Register cluster container in StoreGate + //---------------------------------------------------------------------- + CHECK( CaloClusterStoreHelper::finalizeClusters(&(*evtStore()), + m_pOutputPi0CaloClusterContainer, + m_outputPi0ClusterContainerName, + msg())); + + return StatusCode::SUCCESS; +} + +// Functions used to calculate BDT variables other than those provided by the CaloClusterMomentsMaker +float TauPi0BonnClusterCreator::getEM1CoreFrac( + const xAOD::CaloCluster* pi0Candidate) +{ + float coreEnergy=0.; + float sumEPosCellsEM1=0.; + + const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks(); + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + if(sampling!=1 && sampling!=5) continue; + float cellE = cellInCluster->e() * cellInClusterItr.weight(); + if(cellE<=0) continue; + sumEPosCellsEM1 += cellE; + float cellEtaWRTCluster = cellInCluster->eta()-pi0Candidate->eta(); + float cellPhiWRTCluster = P4Helpers::deltaPhi(cellInCluster->phi(), pi0Candidate->phi()); + if(fabs(cellPhiWRTCluster) > 0.05 || fabs(cellEtaWRTCluster) > 2 * 0.025/8.) continue; + coreEnergy+=cellE; + } + if(sumEPosCellsEM1<=0.) return 0.; + return coreEnergy/sumEPosCellsEM1; +} + +// Function to determine asymmetry with respect to track. For > 1 track give smallest asymmetry. +float TauPi0BonnClusterCreator::getAsymmetryInEM1WRTTrk( + const xAOD::CaloCluster* pi0Candidate, + const vector<vector<float> > tracksEtaAtSampling, + const vector<vector<float> > tracksPhiAtSampling) +{ + float minAsymmetryInEM1WRTTrk=2.; // minimum asymmetryWRT tracks + vector<vector<float> > asymmetriesInEM1WRTTrks; + vector<float> asymmetryInEM1WRTTrk; + asymmetryInEM1WRTTrk.push_back(0.); // here the energy in negative eta direction WRT the track will be stored + asymmetryInEM1WRTTrk.push_back(0.); // here the energy in positive eta direction WRT the track will be stored + asymmetryInEM1WRTTrk.push_back(0.); // here the energy in negative phi direction WRT the track will be stored + asymmetryInEM1WRTTrk.push_back(0.); // here the energy in positive phi direction WRT the track will be stored + for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){ + asymmetriesInEM1WRTTrks.push_back(asymmetryInEM1WRTTrk); + } + + float sumEPosCellsEM1=0.; + const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks(); + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + if(sampling!=1 && sampling!=5) continue; + float cellE = cellInCluster->e() * cellInClusterItr.weight(); + if(cellE<=0) continue; + sumEPosCellsEM1 += cellE; + for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){ + float cellEtaWRTTrack = cellInCluster->eta() - tracksEtaAtSampling.at(iTrack).at(sampling); + float cellPhiWRTTrack = P4Helpers::deltaPhi(cellInCluster->phi(), tracksPhiAtSampling.at(iTrack).at(sampling)); + + if(cellEtaWRTTrack<0) asymmetriesInEM1WRTTrks.at(iTrack).at(0)+=cellE; + else asymmetriesInEM1WRTTrks.at(iTrack).at(1)+=cellE; + if(cellPhiWRTTrack<0) asymmetriesInEM1WRTTrks.at(iTrack).at(2)+=cellE; + else asymmetriesInEM1WRTTrks.at(iTrack).at(3)+=cellE; + } + } + if(sumEPosCellsEM1<=0.) return 0.; // default value for clusters with no energy in EM1 + // calculate asymmetry WRT the tracks and determine minimum asymmetry + for(unsigned iTrack = 0; iTrack<tracksEtaAtSampling.size();++iTrack){ + for(unsigned int iEntry=0;iEntry<asymmetriesInEM1WRTTrks.at(iTrack).size();++iEntry){ + asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)/=sumEPosCellsEM1; + if(asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)>=1.) asymmetriesInEM1WRTTrks.at(iTrack).at(iEntry)=0.999; + } + float asymmetryToThisTrack = fabs((asymmetriesInEM1WRTTrks.at(iTrack).at(1)-asymmetriesInEM1WRTTrks.at(iTrack).at(0))* + (asymmetriesInEM1WRTTrks.at(iTrack).at(3)-asymmetriesInEM1WRTTrks.at(iTrack).at(2))); + if(asymmetryToThisTrack<minAsymmetryInEM1WRTTrk) minAsymmetryInEM1WRTTrk = asymmetryToThisTrack; + } + return minAsymmetryInEM1WRTTrk; +} + + +// Do cluster to shot matching. +// A cluster is matched to a shot if the seed cell of the shot is in the cluster +std::map<unsigned, xAOD::CaloCluster*> TauPi0BonnClusterCreator::getClusterToShotMap( + const std::vector<const xAOD::PFO*> shotVector, + const xAOD::CaloClusterContainer* pPi0ClusterContainer, + xAOD::TauJet *pTau) +{ + std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap; + for(unsigned iShot = 0;iShot<shotVector.size();++iShot){ + int seedHash_int = -1; + if( shotVector.at(iShot)->attribute(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash_int) == false) { + std::cout << "WARNING: Couldn't find seed hash. Set it to -1, no cluster will be associated to shot." << std::endl; + } + const IdentifierHash seedHash = (const IdentifierHash) seedHash_int; + xAOD::CaloClusterContainer::const_iterator clusterItr (pPi0ClusterContainer->begin()), + clusterItrEnd(pPi0ClusterContainer->end()); + float weightInCluster=-1.; + float weightInPreviousCluster=-1; + for (; clusterItr != clusterItrEnd; ++clusterItr){ + xAOD::CaloCluster* cluster = (xAOD::CaloCluster*) (*clusterItr); + weightInCluster=-1.; + if (cluster->p4().Et() < m_clusterEtCut) continue; // Not interested in clusters that fail the Et cut + // Cluster container has clusters for all taus. + // Only run on clusters that belong to this tau + if (cluster->p4().DeltaR(pTau->p4()) > .4) continue; + const CaloClusterCellLink* theCellLink = cluster->getCellLinks(); + CaloClusterCellLink::const_iterator cellItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellItrE = theCellLink->end(); + for(;cellItr!=cellItrE; ++cellItr){ + CaloCell* cellInCluster = (CaloCell*) *cellItr; + // Check if seed cell is in cluster. + if(cellInCluster->caloDDE()->calo_hash()!=seedHash) continue; + weightInCluster = cellItr.weight(); + // found cell, no need to loop over other cells + break; + } + if(weightInCluster<0) continue; + // Check if cell was already found in a previous cluster + if(weightInPreviousCluster<0){ + // Cell not found in a previous cluster. + // Have to check whether cell is shared with other cluster + clusterToShotMap[iShot] = cluster; + weightInPreviousCluster = weightInCluster; + } + else{ + // Cell has been found in a previous cluster + // assign shot to this cluster if it has larger weight for the cell + // otherwise the shots keeps assigned to the previous cluster + if(weightInCluster>weightInPreviousCluster){ + clusterToShotMap[iShot] = cluster; + } + // No need to loop over other clusters as cells can not be shared by more than two clusters + break; + } + } + } + return clusterToShotMap; +} + +std::vector<unsigned> TauPi0BonnClusterCreator::getShotsMatchedToCluster( + const std::vector<const xAOD::PFO*> shotVector, + std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap, + xAOD::CaloCluster* pPi0Cluster) +{ + std::vector<unsigned> shotsMatchedToCluster; + for(unsigned iShot = 0;iShot<shotVector.size();++iShot){ + std::map<unsigned, xAOD::CaloCluster*>::iterator itr = clusterToShotMap.find(iShot); + if(itr==clusterToShotMap.end()) continue; + if(itr->second!=pPi0Cluster) continue; + shotsMatchedToCluster.push_back(iShot); + } + return shotsMatchedToCluster; +} + +int TauPi0BonnClusterCreator::getNPhotons( + const std::vector<const xAOD::PFO*> shotVector, + std::vector<unsigned> shotsInCluster + ) +{ + int nPhotons = 0; + for(unsigned iShot = 0;iShot<shotsInCluster.size();++iShot){ + int curNPhotons=0; + if(shotVector.at(shotsInCluster.at(iShot))->attribute(xAOD::PFODetails::PFOAttributes::tauShots_nPhotons,curNPhotons) == false) + ATH_MSG_WARNING("Can't find NHitsInEM1. Set it to 0."); + nPhotons+=curNPhotons; + } + return nPhotons; +} + +vector<int> TauPi0BonnClusterCreator::getNPosECells( + const xAOD::CaloCluster* pi0Candidate) +{ + vector<int> nPosECellsInLayer(3,0); // 3 layers initialised with 0 +ve cells + + const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks(); + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + + for(;cellInClusterItr!=cellInClusterItrE; ++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + // Get cell layer: PSB and PSE belong to layer 0, + // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. + // Cells in EMB3 and EME3 have already been removed + // during subtraction. + int cellLayer = sampling%4; + if(cellInCluster->e() > 0) nPosECellsInLayer[cellLayer]++; + } + return nPosECellsInLayer; +} + + +vector<float> TauPi0BonnClusterCreator::get1stEtaMomWRTCluster( + const xAOD::CaloCluster* pi0Candidate) +{ + vector<float> firstEtaWRTClusterPositionInLayer (4, 0.); //init with 0. for 0-3 layers + vector<float> sumEInLayer (4, 0.); //init with 0. for 0-3 layers + + const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks(); + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + + for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + // Get cell layer: PSB and PSE belong to layer 0, + // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. + // Cells in EMB3 and EME3 (layer 3) have already been removed + // during subtraction. + int cellLayer = sampling%4; + + float cellEtaWRTClusterPos=cellInCluster->eta()-pi0Candidate->eta(); + float cellE=cellInCluster->e(); + if(cellE<=0) continue; + firstEtaWRTClusterPositionInLayer[cellLayer]+=cellEtaWRTClusterPos*cellE; + sumEInLayer[cellLayer]+=cellE; + } + + for(int iLayer=0;iLayer<4;++iLayer){ + if(sumEInLayer[iLayer]!=0) + firstEtaWRTClusterPositionInLayer[iLayer]/=fabs(sumEInLayer[iLayer]); + else firstEtaWRTClusterPositionInLayer[iLayer]=0.; + } + return firstEtaWRTClusterPositionInLayer; +} + +vector<float> TauPi0BonnClusterCreator::get2ndEtaMomWRTCluster( + const xAOD::CaloCluster* pi0Candidate) +{ + vector<float> secondEtaWRTClusterPositionInLayer (4, 0.); //init with 0. for 0-3 layers + vector<float> sumEInLayer (4, 0.); //init with 0. for 0-3 layers + + const CaloClusterCellLink* theCellLink = pi0Candidate->getCellLinks(); + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + + for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + // Get cell layer: PSB and PSE belong to layer 0, + // EMB1 and EME1 to layer 1, EMB2 and EME2 to layer 2. + // Cells in EMB3 and EME3 (layer 3) have already been removed + // during subtraction. + int cellLayer = sampling%4; + + float cellEtaWRTClusterPos=cellInCluster->eta()-pi0Candidate->eta(); + float cellE=cellInCluster->e(); + if(cellE<=0) continue; + secondEtaWRTClusterPositionInLayer[cellLayer]+=cellEtaWRTClusterPos*cellEtaWRTClusterPos*cellE; + sumEInLayer[cellLayer]+=cellE; + } + + for(int iLayer=0;iLayer<4;++iLayer){ + if(sumEInLayer[iLayer]!=0) + secondEtaWRTClusterPositionInLayer[iLayer]/=fabs(sumEInLayer[iLayer]); + else secondEtaWRTClusterPositionInLayer[iLayer]=0.; + } + return secondEtaWRTClusterPositionInLayer; +} + +void TauPi0BonnClusterCreator::getExtrapolatedPositions( + const xAOD::TrackParticle * track, + vector<float> &trackToCaloEta, + vector<float> &trackToCaloPhi) +{ + for (int layer = 0 ; layer != CaloCell_ID::MINIFCAL0; ++layer) { + // Only need to extrapolate to Ecal1 (samplings 1 and 5) + if(layer!=1 && layer!=5){ + trackToCaloEta.push_back(-99999.); + trackToCaloPhi.push_back(-99999.); + continue; + } + ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << track->pt() << ", eta " << track->eta() << ", phi" << track->phi() << " to layer " << layer); + // extrapolate track to layer + const Trk::TrackParameters* param_at_calo = 0; + param_at_calo = m_trackToCaloTool->extrapolate( + *track, + (CaloCell_ID::CaloSample) layer, + 0.0, Trk::alongMomentum, Trk::pion); + + // store if track extrapolation successful, else use dummy values + if(param_at_calo){ + ATH_MSG_DEBUG( "Extrapolated track with eta=" << track->eta() + << " phi="<<track->phi() + << " to eta=" << param_at_calo->position().eta() + << " phi="<<param_at_calo->position().phi() + ); + trackToCaloEta.push_back(param_at_calo->position().eta()); + trackToCaloPhi.push_back(param_at_calo->position().phi()); + delete param_at_calo; + } + else { + ATH_MSG_DEBUG( "Could not extrapolate track with eta = " << track->eta() + << " phi=" << track->phi() + ); + trackToCaloEta.push_back(-99999.); //Use something huge to flag the + trackToCaloPhi.push_back(-99999.); //track as useless + } + } +} + diff --git a/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx b/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4c824dc37bc4146503ea3fc75d0b144f343e88ae --- /dev/null +++ b/Reconstruction/tauRec/src/TauPi0BonnCreateROI.cxx @@ -0,0 +1,763 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0BonnCreateROI.cxx +// package: Reconstruction/tauEvent +// authors: Will Davey +// date: 2012-10-09 +// +//----------------------------------------------------------------------------- + +#include <TString.h> +#include <TH1.h> + +#include "GaudiKernel/IToolSvc.h" + +#include "PathResolver/PathResolver.h" +#include "CaloEvent/CaloCellContainer.h" +#include "CaloEvent/CaloClusterContainer.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloUtils/CaloCellList.h" +#include "AthContainers/OwnershipPolicy.h" +#include "NavFourMom/INavigable4MomentumCollection.h" + +#include "xAODCaloEvent/CaloCluster.h" + +#include "tauRec/TauPi0BonnCreateROI.h" +#include "tauRec/TauPi0BonnParser.h" + +#include "tauEvent/TauPi0Details.h" +#include "tauEvent/TauShot.h" + +#include "CaloInterface/IHadronicCalibrationTool.h" +#include "RecoToolInterfaces/IExtrapolateToCaloTool.h" +#include "CaloInterface/ICaloCellMakerTool.h" +#include "CaloIdentifier/CaloCell_ID.h" + +using std::max; +using std::min; +using std::vector; +using std::string; +//using xAOD::PFO; // required for subtration in EM1 + + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0BonnCreateROI::TauPi0BonnCreateROI( const string& type, + const string& name, + const IInterface *parent) + : TauToolBase(type, name, parent) + , m_caloWeightTool("H1WeightToolCSC12Generic") + , m_trackToCaloTool("") + , m_cellMakerTool("") + , m_calo_dd_man(NULL) + , m_calo_id(NULL) + , m_latParser(new TauPi0BonnParser()) + , m_caloCellContainerName("AllCalo") + , m_clusterContainerName("CaloCalTopoCluster") + , m_pPi0CellContainer(NULL) + , m_pi0CellContainerName("TauCommonPi0CellContainer") + , m_chargedPFOContainerName("TauPi0BonnChargedPFOContainer") +{ + declareInterface<TauToolBase > (this); + + declareProperty("CaloWeightTool", m_caloWeightTool); + declareProperty("ExtrapolateToCaloTool", m_trackToCaloTool); + declareProperty("CellMakerTool", m_cellMakerTool); + + declareProperty("CaloCellContainerName", m_caloCellContainerName); // TODO: May be replaced using tau clusters + declareProperty("ClusterContainerName", m_clusterContainerName); // TODO: May be replaced using tau clusters + declareProperty("Pi0CellContainerName", m_pi0CellContainerName); + declareProperty("ChargedPFOContainerName", m_chargedPFOContainerName); + + declareProperty("LatParFile", m_latParFile ); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0BonnCreateROI::~TauPi0BonnCreateROI() { +} + +StatusCode TauPi0BonnCreateROI::initialize() { + + // retrieve tools + ATH_MSG_DEBUG( "Retrieving tools" ); + CHECK( m_caloWeightTool.retrieve() ); + CHECK( m_trackToCaloTool.retrieve() ); + CHECK( m_cellMakerTool.retrieve() ); + + // initialize calo cell geo + m_calo_dd_man = CaloDetDescrManager::instance(); + m_calo_id = m_calo_dd_man->getCaloCell_ID(); + + + //////////////////////////////////////////////////////////// + // Load lateral parameterisation + //////////////////////////////////////////////////////////// + // check file given for lateral shower parameteristaion + if( m_latParFile == "" ){ + ATH_MSG_ERROR( "No lateral shower parameterisation given" ); + return StatusCode::FAILURE; + } + // parse lateral config file + m_latParser->parseROOTFile( PathResolver::find_file(m_latParFile, "DATAPATH") ); + + // set addresses of all varaibles that can be used in the para. + m_latParser->setVar( "PT", m_pt ); + m_latParser->setVar( "ABSETA", m_abseta); + m_latParser->setVar( "HADF", m_hadf); + m_latParser->setVar( "SAMP", m_sampling); + + // hadf bot used atm. TODO: REMOVE? + m_hadf = 0.; + + // check that parser loaded correctly, and that the required + // variables are configured + if( !m_latParser->checkInitialisationStatus() ){ + ATH_MSG_ERROR( "Failure loading lateral shower parameterisation" ); + ATH_MSG_ERROR( "Parser stream: " << m_latParser->getStream() ); + return StatusCode::FAILURE; + } + + // Create vector with default values + for (int layer = 0 ; layer != CaloCell_ID::FCAL0; ++layer) { + m_defaultValues.push_back(-10.); + m_defaultValuesZero.push_back(0.); + } + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnCreateROI::eventInitialize(TauCandidateData * /*data*/) { + + + const CaloCell_ID* cellID; + if((detStore()->retrieve(cellID)).isFailure()){ + ATH_MSG_ERROR("Unable to retrieve caloCell_ID helper from DetectorStore"); + return StatusCode::FAILURE; + } + + // Get hash range + IdentifierHash hashMax; + hashMax = cellID->calo_cell_hash_max(); + ATH_MSG_VERBOSE("CaloCell Hash Max: " << hashMax); + + // Reset addedCellsMap + m_addedCellsMap.clear(); + for (unsigned i = 0; i < hashMax; i++) { + m_addedCellsMap.push_back(NULL); + } + + // Reset hist maps + m_trackHistMapBarrel.clear(); + m_trackHistMapEndcap.clear(); + + //--------------------------------------------------------------------- + // Create CustomCellContainer and register in StoreGate + //--------------------------------------------------------------------- + m_pPi0CellContainer = new CaloCellContainer(SG::OWN_ELEMENTS); + CHECK( evtStore()->record(m_pPi0CellContainer, m_pi0CellContainerName) ); + + // symlink as INavigable4MomentumCollection (as in CaloRec/CaloCellMaker) + CHECK(evtStore()->symLink(m_pPi0CellContainer, static_cast<INavigable4MomentumCollection*> (0))); + + //--------------------------------------------------------------------- + // Create charged PFO container + //--------------------------------------------------------------------- + m_chargedPFOContainer = new xAOD::PFOContainer(); + CHECK( evtStore()->record(m_chargedPFOContainer, m_chargedPFOContainerName ) ); + m_chargedPFOAuxStore = new xAOD::PFOAuxContainer(); + CHECK( evtStore()->record( m_chargedPFOAuxStore, m_chargedPFOContainerName + "Aux." ) ); + m_chargedPFOContainer->setStore(m_chargedPFOAuxStore); + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnCreateROI::execute(TauCandidateData *data) { + + xAOD::TauJet *pTau = data->xAODTau; + + // Any tau needs to have PFO vectors. Set empty vectors before nTrack cut + vector<ElementLink<xAOD::PFOContainer> > empty; + pTau->setCellBased_Charged_PFOLinks(empty); + pTau->setCellBased_Neutral_PFOLinks(empty); + pTau->setCellBased_Pi0_PFOLinks(empty); + + // Any tau needs to have PanTauCellBasedProto 4mom. Set it to 0 before nTrack cut + pTau->setP4(xAOD::TauJetParameters::PanTauCellBasedProto, 0.0, 0.0, 0.0, 0.0); + + //--------------------------------------------------------------------- + // only run shower subtraction on 1-5 prong taus + //--------------------------------------------------------------------- + if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) { + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("new tau. \tpt = " << pTau->pt() << "\teta = " << pTau->eta() << "\tphi = " << pTau->phi() << "\tnprongs = " << pTau->nTracks()); + + //--------------------------------------------------------------------- + // get tau tracks + //--------------------------------------------------------------------- + vector<const xAOD::TrackParticle*> tracks; + for(unsigned iTrack = 0; iTrack<pTau->nTracks();++iTrack){ + const xAOD::TrackParticle* track = pTau->track(iTrack); + tracks.push_back(track); + } + + //--------------------------------------------------------------------- + // retrieve cells around tau + //--------------------------------------------------------------------- + + // get all calo cell container + const CaloCellContainer *pCellContainer = NULL; + CHECK( evtStore()->retrieve(pCellContainer, m_caloCellContainerName) ); + + // get only EM cells within dR<0.2 + vector<CaloCell_ID::SUBCALO> emSubCaloBlocks; + emSubCaloBlocks.push_back(CaloCell_ID::LAREM); + boost::scoped_ptr<CaloCellList> pCells(new CaloCellList(pCellContainer,emSubCaloBlocks)); + + // TODO: change hardcoded 0.2 to tau cone variable, (or func. from TauJet?) + pCells->select(pTau->eta(), pTau->phi(), 0.4); + + //--------------------------------------------------------------------- + // prepare extrapolation of tracks to calo layers + //--------------------------------------------------------------------- + // clear vectors related to track extrapolation + // have to do that for each tau so it cannot be done in eventInitialize, + // which is called once per event (and not once per tau) + m_tracksEtaAtSampling.clear(); + m_tracksPhiAtSampling.clear(); + m_extrapolatedSamplings.clear(); + // Fill with default values + for(int layer = 0 ; layer != CaloCell_ID::FCAL0; ++layer) { + m_extrapolatedSamplings.push_back(false); + } + //vector<float> E_sub_track; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + m_tracksEtaAtSampling.push_back( m_defaultValues ); + m_tracksPhiAtSampling.push_back( m_defaultValues ); + //E_sub_track.push_back( 0. ); + } + + //--------------------------------------------------------------------- + // get energy in HCal associated to the different tracks + //--------------------------------------------------------------------- + const xAOD::CaloClusterContainer* clusterContainer = NULL; + CHECK( evtStore()->retrieve( clusterContainer, m_clusterContainerName ) ); + + vector<double> EestInEcal = this->getEstEcalEnergy(tracks,clusterContainer,pTau); + + //Create charged PFOs + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + const xAOD::TrackParticle* track = tracks.at(iTrack); + xAOD::PFO* chargedPFO = new xAOD::PFO(); + m_chargedPFOContainer->push_back(chargedPFO); + ElementLink<xAOD::TrackParticleContainer> myTrackLink = pTau->trackLinks().at(iTrack); + if(!chargedPFO->setTrackLink(myTrackLink)) ATH_MSG_WARNING("Could not add Track to PFO"); + chargedPFO->setCharge(track->charge()); + chargedPFO->setP4(track->pt(),track->eta(),track->phi(),track->m()); + // Create element link from tau to charged PFO + ElementLink<xAOD::PFOContainer> PFOElementLink; + PFOElementLink.toContainedElement( *m_chargedPFOContainer, chargedPFO ); + pTau->addCellBased_Charged_PFOLink( PFOElementLink ); + // Store energy to subtract/subtracted for the track in CenterMag variable. This variables is otherwise never used for charged PFOs + chargedPFO->setCenterMag( (float) EestInEcal.at(iTrack)); + } + + // Optional: Subtraction in EM1 (part 1 of 3) + // FIXME: xAOD migration of subtration in EM1 + /* + //--------------------------------------------------------------------- + // get cells in EM1 associated to the different tracks + //--------------------------------------------------------------------- + std::vector<IdentifierHash> pipmCellHash; + const std::vector<TauShot*> shotVector = pPi0Details->shotVector(); + + for(unsigned iShot = 0;iShot<shotVector.size();++iShot){ + TauShot* currentShot = shotVector.at(iShot); + const CaloCell* seedCell = currentShot->seedCell(); + + int samp = seedCell->caloDDE()->getSampling(); + double seedEta = seedCell->eta(); + + // Don't match shots in crack region. Cells are so large that pi0s are likely to be in the same cell. + if( (samp == 1 && fabs(seedEta)>1.4) || (samp == 5 && fabs(seedEta) < 1.5) ) continue; + + // Subtract 3 cells + double shotPt = currentShot->pt3(); + + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + // Do not match shots to tracks, which have E_est < shotPt + if(EestInEcal.at(iTrack)<shotPt) continue; + + // Do not match shots to tracks that have shotPt > 20% of the track pt. + // The shot is unlikely to come from the charged pion in this case + double maxFrac = 0.20; + if(tracks.at(iTrack)->pt() * maxFrac < shotPt) continue; + + // check if tracks have been extrapolated to this sampling. Do so if this is not the case + if(m_extrapolatedSamplings.at(samp)==false){ + this->getExtrapolatedPositions(tracks,samp); + ATH_MSG_DEBUG("Extr to layer " << samp << "\teta = " << m_tracksEtaAtSampling.at(iTrack).at(samp) << "\tphi = " << m_tracksPhiAtSampling.at(iTrack).at(samp)); + m_extrapolatedSamplings.at(samp)=true; + } + // Check if shot is close to the extrapolated track + double AbsDEta = fabs( seedEta - m_tracksEtaAtSampling.at(iTrack).at(samp)); + double AbsDPhi = fabs( seedCell->phi() - m_tracksPhiAtSampling.at(iTrack).at(samp)); + double cellWidthEta = seedCell->caloDDE()->deta(); + double cellWidthPhi = seedCell->caloDDE()->dphi(); + double allowedDev = 0.001; + if( (AbsDEta > cellWidthEta/2.+allowedDev) || (AbsDPhi > cellWidthPhi/2.+allowedDev) ) continue; + + // Assign shot to track + + // Store shot cells in pipmCellHash + double shotE = 0.; + std::vector<std::vector<const CaloCell*> > shotCells = currentShot->getCellVector(m_calo_id); + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + int windowSize = 3; // must be 1, 3 or 5 + if( windowSize%2!=1 && windowSize > nCells_eta) ATH_MSG_WARNING("Set window size for subtractionin EM1 properly! No energy will be subtracted in EM1"); + for(int iCell = 0; iCell != nCells_eta; ++iCell ){ + if(fabs(iCell-seedIndex)>windowSize/2) continue; + double wtCell0=0.; + double wtCell1=0.; + if(shotCells.at(0).at(iCell) != NULL){ + wtCell0 = m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + shotE+=shotCells.at(0).at(iCell)->e()*wtCell0; + pipmCellHash.push_back(shotCells.at(0).at(iCell)->caloDDE()->calo_hash()); + } + if(shotCells.at(1).at(iCell) != NULL){ + wtCell1 = m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + shotE+=shotCells.at(1).at(iCell)->e()*wtCell1; + pipmCellHash.push_back(shotCells.at(1).at(iCell)->caloDDE()->calo_hash()); + } + } + // Reduce EestInEcal by shot energy. ShotE is slightly more preciese than shotPt*cosh(currentShot->cluster()->eta()) (difference<1MeV) + EestInEcal.at(iTrack) -= shotE; + // Set number of photons in shot to 0. + currentShot->setNPhotons(0); + ATH_MSG_DEBUG("Assigned shot " << iShot << " to track " << iTrack << ". \tshotE = "<< shotE << "\tshotEta = " << seedEta << "\tshotPhi = " << seedCell->phi()); + } + } + */ + + //--------------------------------------------------------------------- + // Start creating output container: + // PS: Don't do subtraction, just put cells in output container + // EM1: Set energies of cells to 0 that have been matched to a track. Put cells in output container. + // EM2: Sum up subtraction weights for each track. Have to normalize and subtract after this loop. + //--------------------------------------------------------------------- + + // Create vectors that will be used in a second loop over EM2 cells, only + // vector of cells + std::vector<const CaloCell*> EM2Cells; + // vector of lateral weights for each cell and each track. Cells are in same order as in EM2Cells vector + std::vector<std::vector<double> > cellSubWeights; + // vector of sum of lateral weights for each track. Will be used for the normalization + std::vector<double> sumCellSubWeights; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + sumCellSubWeights.push_back(0.); + } + + CaloCellList::list_iterator cellItr(pCells->begin()), cellItrE(pCells->end()); + for(; cellItr != cellItrE; ++cellItr) { + const CaloCell* cell = (*cellItr); + + // get cell sampling + int samp = cell->caloDDE()->getSampling(); + + // only keep cells that are in PS, EM1 and EM2. + if(samp>=7 || samp == 3 ) continue; + + if( samp!=2 && samp != 6 ){ // PS and EM1 + // Optional: Subtraction in EM1 (part 2 of 3) + /* + // Check if cell is in EM1 and if it is matched to a track + bool isPipmCell = false; + if(samp == 1 || samp == 5){ + //Ask cell for it's hash + const IdentifierHash cellHash = cell->caloDDE()->calo_hash(); + + for(unsigned iPipmCellHash=0;iPipmCellHash<pipmCellHash.size();++iPipmCellHash){ + if(pipmCellHash.at(iPipmCellHash)==cellHash){ + ATH_MSG_DEBUG("Set cell energy to 0. " << "eta = " << cell->eta() << "\tphi = " << cell->phi() << "\tE = " << cell->e()); + isPipmCell = true; + break; + } + } + } + */ + double subtractedEnergy = 0.; + + // Optional: Subtraction in EM1 (part 3 of 3) + // if(isPipmCell == true) subtractedEnergy = cell->e(); + + // Store cell in output container + storeCell(cell, subtractedEnergy); + } + else{ // EM2 + + // Current procedure in crack region: Linear Interpolation from 1.375 to 1.475 + double interpolationFactorForCrack = 1.; + double crackMax = 1.475; + double crackMin = 1.375; + double crackW = crackMax - crackMin; + if(samp!=0 && samp<4 && fabs(cell->eta())>crackMin) + interpolationFactorForCrack=1.-(fabs(cell->eta())-crackMin)/crackW; + if(samp>3 && fabs(cell->eta())<crackMax) + interpolationFactorForCrack=1.-(crackMax-fabs(cell->eta()))/crackW; + + // Store weights of this cell for each track + vector<double> thisCellSubWeights; + double sumThisCellSubWeights = 0.; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + // Don't need to determine weights if no energy is to be subtracted for this track + if( EestInEcal.at(iTrack)==0. ){ + thisCellSubWeights.push_back(0.); + continue; + } + + // Get info on track + const xAOD::TrackParticle* track = tracks.at(iTrack); + + // check if tracks have been extrapolated to this sampling. Do so if this is not the case + if(m_extrapolatedSamplings.at(samp)==false){ + this->getExtrapolatedPositions(tracks,samp); + ATH_MSG_DEBUG("Extr to layer " << samp << "\teta = " << m_tracksEtaAtSampling.at(iTrack).at(samp) << "\tphi = " << m_tracksPhiAtSampling.at(iTrack).at(samp)); + m_extrapolatedSamplings.at(samp)=true; + } + + // set extrapolated track direction + TLorentzVector extTrack; + + extTrack.SetPtEtaPhiE(track->pt(), m_tracksEtaAtSampling.at(iTrack).at(samp), m_tracksPhiAtSampling.at(iTrack).at(samp), track->e()); + + // get eta/phi distance of cell to track + double deltaEta = extTrack.Eta()-cell->eta(); + double deltaPhi = TVector2::Phi_mpi_pi( extTrack.Phi() - cell->phi()); + + // TODO: + // - Determine lateral weight using TH1 + double cellWidthEta = cell->caloDDE()->deta(); + double cellWidthPhi = cell->caloDDE()->dphi(); + double cellSubWeight = getLatWeight(samp, deltaEta, deltaPhi, cellWidthEta, cellWidthPhi, iTrack, track); + + + // Get final weight by multiplying with interpolationFactorForCrack + cellSubWeight*=interpolationFactorForCrack; + sumCellSubWeights.at(iTrack)+=cellSubWeight; + thisCellSubWeights.push_back(cellSubWeight); + sumThisCellSubWeights+=cellSubWeight; + } + if(sumThisCellSubWeights == 0.){ + // No need to run subtraction in the second loop + storeCell(cell, 0.); + } + else{ + EM2Cells.push_back(cell); + cellSubWeights.push_back(thisCellSubWeights); + } + } + } + // Loop over EM2 cells. Subtract energy assigned to the cell and store it in the output cell container. + for(unsigned iCell=0; iCell!= EM2Cells.size();++iCell){ + const CaloCell* cell = EM2Cells.at(iCell); + + // Get cell weight + double wtCell = m_caloWeightTool->wtCell(cell); + // wtCell=0 (happens very rarely) would cause a FPE later + if( wtCell == 0. ) continue; + + // Determine how much energy to subtract + double subtractedEnergy = 0.; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + if(EestInEcal.at(iTrack)==0. || sumCellSubWeights.at(iTrack)==0.) continue; + subtractedEnergy+=EestInEcal.at(iTrack)*cellSubWeights.at(iCell).at(iTrack)/sumCellSubWeights.at(iTrack); + // E_sub_track.at(iTrack)+=EestInEcal.at(iTrack)*cellSubWeights.at(iCell).at(iTrack)/sumCellSubWeights.at(iTrack); + } + // Store cell in output container + storeCell(cell, subtractedEnergy); + } + // Check if total amount of subtracted energy is correct + /* + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + ATH_MSG_INFO("EestInEcal.at(iTrack) = "<<EestInEcal.at(iTrack)<<"\tE_sub_track.at(iTrack) = "<<E_sub_track.at(iTrack)<<"\tsumCellSubWeights.at(iTrack) = "<<sumCellSubWeights.at(iTrack)); + } + */ + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnCreateROI::eventFinalize(TauCandidateData* /* data */) { + + //--------------------------------------------------------------------- + // use the m_cellMakerTool to finalize the + // custom CaloCellContainer + //--------------------------------------------------------------------- + CHECK( m_cellMakerTool->process(static_cast<CaloCellContainer*> (m_pPi0CellContainer)) ); + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnCreateROI::finalize() { + // delete TH1 from parser + return StatusCode::SUCCESS; +} + +void TauPi0BonnCreateROI::getExtrapolatedPositions( + vector<const xAOD::TrackParticle*> tracks, + int sampling) +{ + for (unsigned iTrack = 0 ; iTrack < tracks.size(); ++iTrack ) { + // extrapolate track to sampling + // FIXME: xAOD migration as soon as tool is available + ATH_MSG_DEBUG( "Try extrapolation of track with pt = " << tracks.at(iTrack)->pt() << ", eta " << tracks.at(iTrack)->eta() << ", phi" << tracks.at(iTrack)->phi() + << " to layer " << sampling); + const Trk::TrackParameters* param_at_calo = 0; + param_at_calo = m_trackToCaloTool->extrapolate( + *tracks.at(iTrack), + (CaloCell_ID::CaloSample) sampling, + 0.0, Trk::alongMomentum, Trk::pion); + + // store if track extrapolation successful, else use dummy values + if(param_at_calo){ + ATH_MSG_DEBUG( "Extrapolated track with eta=" << tracks.at(iTrack)->eta() + << " phi="<<tracks.at(iTrack)->phi() + << " to eta=" << param_at_calo->position().eta() + << " phi="<<param_at_calo->position().phi() + ); + m_tracksEtaAtSampling.at(iTrack).at(sampling)=param_at_calo->position().eta(); + m_tracksPhiAtSampling.at(iTrack).at(sampling)=param_at_calo->position().phi(); + delete param_at_calo; + } + else ATH_MSG_DEBUG("Could not extrapolate track with pt = " << tracks.at(iTrack)->pt() << ", eta " << tracks.at(iTrack)->eta() << ", phi" << tracks.at(iTrack)->phi() + << " to layer " << sampling); + //just keep default values in case extrapolation failed + } +} + +vector<double> TauPi0BonnCreateROI::getEstEcalEnergy( + vector<const xAOD::TrackParticle*> tracks, + const xAOD::CaloClusterContainer* clusterContainer, + const xAOD::TauJet* rtau) +{ + // Vector that stores hadronic energy associated to one track + vector<double> EHcal; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + EHcal.push_back(0.); + } + + ATH_MSG_DEBUG("new tau. eta = " << rtau->eta() << "\t phi = " << rtau->phi() ); + + xAOD::CaloClusterContainer::const_iterator clusterItr = clusterContainer->begin(); + xAOD::CaloClusterContainer::const_iterator clusterItrE = clusterContainer->end(); + + int clusterNumber = -1; + + for(;clusterItr!=clusterItrE;++clusterItr){ + const xAOD::CaloCluster* cluster = (xAOD::CaloCluster*) *clusterItr; + + double deltaEtaToTau = rtau->eta()-cluster->eta(); + double deltaPhiToTau = TVector2::Phi_mpi_pi( rtau->phi() - cluster->phi()); + + // Check deltaR^2<0.2^2 instead of deltaR<0.2, because it is computationally less expensive. + double deltaRToTau_squared = deltaEtaToTau*deltaEtaToTau+deltaPhiToTau*deltaPhiToTau; + if(deltaRToTau_squared>0.04) continue; + + + clusterNumber++; + + ATH_MSG_DEBUG("Cluster number << " << clusterNumber << "\t energy = " << cluster->e() << "\t eta = " << cluster->eta() << "\t phi = " << cluster->phi() << + "\t deltaEtaToTau = " << deltaEtaToTau << "\t deltaPhiToTau = " << deltaPhiToTau << "\t deltaRToTau_squared = " << deltaRToTau_squared ); + + + // Get sample with maximum energy and cluster energy in Hcal + vector<double> energyInSamples=m_defaultValuesZero; + // Get energy in Hcal samplings: Loop over cells + const CaloClusterCellLink* theCellLink = cluster->getCellLinks(); + + CaloClusterCellLink::const_iterator cellInClusterItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellInClusterItrE = theCellLink->end(); + + for(;cellInClusterItr!=cellInClusterItrE;++cellInClusterItr){ + CaloCell* cellInCluster = (CaloCell*) *cellInClusterItr; + int sampling = cellInCluster->caloDDE()->getSampling(); + if(sampling <= 2 || (sampling >=4 && sampling <=6 ) || sampling >= CaloCell_ID::FCAL0) continue; + energyInSamples.at(sampling) += cellInCluster->e()*cellInClusterItr.weight(); + } + + + double cluster_EHcal = 0.; + int maxSample = -1; + double maxESample = 0.; + for(unsigned iSample = 0; iSample < energyInSamples.size(); ++iSample){ + if(iSample == 3 || iSample >= 7 ) cluster_EHcal+=energyInSamples.at(iSample); + if(energyInSamples.at(iSample)<maxESample) continue; + maxSample = iSample; + maxESample = energyInSamples.at(iSample); + } + // Apply cryostat correction + if(energyInSamples.at(3) > 0. && energyInSamples.at(12) > 0.){ + cluster_EHcal += m_caloWeightTool->wtCryo() * sqrt(energyInSamples.at(3)*energyInSamples.at(12)); + } + + + if(cluster_EHcal <= 0.){ + ATH_MSG_DEBUG("cluster_EHcal = " << cluster_EHcal/1000. << "<=0. Skip this cluster for Hcal estimate."); + continue; + } + + // check if tracks have been extrapolated to this sampling. Do so if this is not the case + if(m_extrapolatedSamplings.at(maxSample)==false){ + this->getExtrapolatedPositions(tracks,maxSample); + ATH_MSG_DEBUG("Extrapolate to layer " << maxSample << "\teta = " + << m_tracksEtaAtSampling.at(0).at(maxSample) << "\t phi = " << m_tracksPhiAtSampling.at(0).at(maxSample) ); + m_extrapolatedSamplings.at(maxSample)=true; + } + + // Assign cluster to track + int closestTrack = -1; + //double dEtaClosestTrack = 10; + //double dPhiClosestTrack = 10; + double dRToClosestTrack_squared = 0.16; // XXX can be tuned later + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + const xAOD::TrackParticle* track = tracks.at(iTrack); + + + // set extrapolated track direction + TLorentzVector extTrack; + ATH_MSG_DEBUG("filling extrapolated Track number " << iTrack << ", pt = " << track->pt() << ", eta = " << m_tracksEtaAtSampling.at(iTrack).at(maxSample) << ", phi " << m_tracksPhiAtSampling.at(iTrack).at(maxSample) << ", e = " << track->e() ); + + extTrack.SetPtEtaPhiE(track->pt(), m_tracksEtaAtSampling.at(iTrack).at(maxSample), m_tracksPhiAtSampling.at(iTrack).at(maxSample), track->e()); + + // get eta/phi distance of cell to track + double deltaEta = extTrack.Eta()-cluster->eta(); + double deltaPhi = TVector2::Phi_mpi_pi( extTrack.Phi() - cluster->phi());; + + double deltaRToTrack_squared = deltaEta*deltaEta+deltaPhi*deltaPhi; + ATH_MSG_DEBUG("Track number " << iTrack << ", extTrack.Eta() = " << extTrack.Eta() << ", extTrack.Phi() = " << extTrack.Phi()); + + if(deltaRToTrack_squared>=dRToClosestTrack_squared) continue; + closestTrack = iTrack; + //dEtaClosestTrack = deltaEta; + //dPhiClosestTrack = deltaPhi; + dRToClosestTrack_squared = deltaRToTrack_squared; + } + if(closestTrack == -1 && dRToClosestTrack_squared > 0.04){ + //ATH_MSG_DEBUG("dRToClosestTrack_squared = " << dRToClosestTrack_squared << ", dEta = " << dEtaClosestTrack << ", dPhi = " << dPhiClosestTrack + // << ". Skip cluster for Hcal estimate. \tcluster_EHcal = " << cluster_EHcal/1000.); + continue; // Didn't find a track + } + EHcal.at(closestTrack) += cluster_EHcal; + ATH_MSG_DEBUG("Cluster associated to track " << closestTrack << "\tcluster_EHcal = " << cluster_EHcal/1000.); + } + // Get energy estimate in ECAL + vector<double> E_ests; + for(unsigned iTrack = 0; iTrack<tracks.size();++iTrack){ + double E_est = tracks.at(iTrack)->e()-EHcal.at(iTrack); + // energy cant be less than 0 + if(E_est < 0) E_est = 0.; + // energy cant be more than track momentum + if(E_est > tracks.at(iTrack)->e()) E_est = tracks.at(iTrack)->e(); + E_ests.push_back(E_est); + } + return E_ests; +} + +double TauPi0BonnCreateROI::getLatWeight(int samp, + double deltaEta, + double deltaPhi, + double cellWidthEta, + double cellWidthPhi, + unsigned trackNumber, + const xAOD::TrackParticle* track + ) +{ + // No need to subtract very far away from the track + if(fabs(deltaEta)>0.15 || fabs(deltaPhi)>0.15) return 0.; + + TH1* histo; + + // Store histograms in order to speed up the algorithm + // The + + // Check if TH1 is already in one of the maps + std::map<int, TH1*>::iterator itr; + if( samp==2 ) itr = m_trackHistMapBarrel.find(trackNumber); + else itr = m_trackHistMapEndcap.find(trackNumber); + + if( (samp==2 && itr != m_trackHistMapBarrel.end()) || (samp==6 && itr != m_trackHistMapEndcap.end()) ){ + histo = itr->second; + } + else{ + //--------------------------------------------------------------------- + // Need to get bin key and histogram from parser + // set variables that can be used for parameterisation + // Note: if value outside bin range, parser will choose first or last + // bin + //--------------------------------------------------------------------- + m_pt = track->pt(); + m_abseta = fabs(track->eta()); + // FIXME: Preliminary fix for crack: + if(m_abseta>1.34 && samp==2 ) m_abseta = 1.34; + if(m_abseta<1.56 && samp==6 ) m_abseta = 1.56; + m_sampling = (double) samp; + string key = m_latParser->getBinKey(); + + ATH_MSG_DEBUG("m_pt = " << m_pt << "\tm_abseta = " << m_abseta << "\tm_hadf = " << m_hadf << "\tm_sampling = " << m_sampling << "\tkey = " << key); + + histo = m_latParser->getTH1(); + + if(samp==2) m_trackHistMapBarrel[trackNumber] = histo; + else m_trackHistMapEndcap[trackNumber] = histo; + } + + // Get cell weight from histogram + int bin = histo->FindBin(fabs(deltaEta), deltaPhi*track->charge()); + double cellWeight = histo->GetBinContent(bin); + + // multiply by cell area in order to account for varying cell sizes in the endcap + cellWeight*=cellWidthEta*cellWidthPhi; + + return cellWeight; +} + +void TauPi0BonnCreateROI::storeCell(const CaloCell* cell, + double subtractedEnergy){ + // Store cell in output container if it is a new cell + // Produce a copy of the cell, in order to prevent + // the energy of the original cell to be changed. + // Store unweighted cells, since the cell weights are applied during reclustering + + //Ask cell for it's hash + const IdentifierHash cellHash = cell->caloDDE()->calo_hash(); + //Check if this cell is already part of reducedCellContainer + bool isNewCell = (m_addedCellsMap.at(cellHash)==NULL); + + if(isNewCell){ + CaloCell* copyCell = cell->clone(); + if(subtractedEnergy>0.){ + // Get cell weight + double wtCell = m_caloWeightTool->wtCell(cell); + // wtCell=0 (happens very rarely) would cause a FPE + if( wtCell != 0. ) copyCell->setEnergy( cell->e() - subtractedEnergy/wtCell ); + } + m_pPi0CellContainer->push_back(const_cast<CaloCell*> (copyCell)); + m_addedCellsMap[cellHash] = copyCell; + } + // If the cell has been already stored the energy is subtracted for the already existing copy + else if(subtractedEnergy>0.){ + CaloCell* copyCell = m_addedCellsMap.at(cellHash); + // Get cell weight + double wtCell = m_caloWeightTool->wtCell(cell); + // wtCell=0 (happens very rarely) would cause a FPE + if( wtCell != 0. ) copyCell->setEnergy( cell->e() - subtractedEnergy/wtCell ); + } +} + diff --git a/Reconstruction/tauRec/src/TauPi0BonnParser.cxx b/Reconstruction/tauRec/src/TauPi0BonnParser.cxx new file mode 100644 index 0000000000000000000000000000000000000000..efea376fd4005e28487901e965ae69658c186f08 --- /dev/null +++ b/Reconstruction/tauRec/src/TauPi0BonnParser.cxx @@ -0,0 +1,361 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0BonnParser +// package: Reconstruction/tauEvent +// authors: Will Davey <will.davey@cern.ch> +// date: 2012-09-13 +// +//----------------------------------------------------------------------------- + +#include "tauRec/TauPi0BonnParser.h" + +#include "TFile.h" +#include "TParameter.h" +#include "TVectorF.h" +#include "TObjString.h" +#include "TObjArray.h" + +#include <iostream> +#include <assert.h> +#include <string> +#include <sstream> +#include <fstream> +#include <stdlib.h> + +using namespace std; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +TauPi0BonnParser::TauPi0BonnParser() + : m_max_traceback(1000) +{ +} + +TauPi0BonnParser::~TauPi0BonnParser() +{ + // because we own the pointer of the histograms, we need to delete them here + std::map<std::string,TH1*>::iterator it=m_hist_map.begin(); + for (;it!=m_hist_map.end(); ++it) delete it->second; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void TauPi0BonnParser::setMaxTraceback(int i){ + m_max_traceback = i; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool TauPi0BonnParser::setVar( const string& key, double& val ){ + if(m_curr_val_map.find(key)==m_curr_val_map.end()){ + this->msg( "ERROR: var: "+key+" not in map" ); + return false; + } + m_curr_val_map[key] = &val; + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +TH1* TauPi0BonnParser::getTH1(){ + string key = this->getBinKey(); + return m_hist_map[key]; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +string TauPi0BonnParser::getStream(){ + return m_stream; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void TauPi0BonnParser::msg( const string& str ){ + m_stream += str+"\n"; + int length = m_stream.size(); + if( length>m_max_traceback ) m_stream = m_stream.substr(m_stream.size()-m_max_traceback,m_max_traceback); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// get bin key from a list of bin indices +string TauPi0BonnParser::getBinKey( const vector<int>& bin_indices ){ + string key = ""; + for( unsigned int j=0; j<bin_indices.size();j++) { + if( j!=0 ) key += "_"; + key += m_bin_order.at(j); + key += Form("%d",bin_indices.at(j)); + } + return key; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// get bin key from a list of var values +string TauPi0BonnParser::getBinKey(){ + // get current stored values of input variables + vector<double> vals = this->getCurrentVals(); + // create vector to store bins corresponding to vals of input vars + vector<int> bin_indices; + + for( unsigned int i=0; i<vals.size();i++ ){ + // get variable name and current value + string key = m_bin_order.at(i); + double val = vals.at(i); + + // retrieve binning + vector<double> bin_edges = m_bin_map[key]; + + // determine bin index + int index = 0; + for( unsigned int j=0; j<bin_edges.size()-1; j++ ){ + // return index 0 if before first bin + if( val < bin_edges.front() ) break; + // return last bin (n-2) if after last bin + if( val > bin_edges.back() ){ + index = bin_edges.size()-2; + break; + } + if( val >= bin_edges.at(j) && val < bin_edges.at(j+1) ){ + index = j; + break; + } + } + bin_indices.push_back(index); + } + return this->getBinKey(bin_indices); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +vector<double> TauPi0BonnParser::getCurrentVals(){ + vector<double> current_vals; + vector<string>::iterator itr = m_bin_order.begin(); + for( ; itr!=m_bin_order.end(); itr++ ){ + // dont try to access null pointer if user hasn't configured properly + if ( m_curr_val_map[*itr] == NULL ) { + current_vals.push_back(-9999.); + } + else{ + current_vals.push_back( (*m_curr_val_map[*itr]) ); + } + } + return current_vals; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool TauPi0BonnParser::parseTDirectory( + TDirectory* dir, + vector<int> current_bin_store, + int current_index) +{ + // make sure current_bin_store can accommodate map entries + while( current_bin_store.size()<m_bin_map.size() ) current_bin_store.push_back(0); + + // initialise iterator + if( current_index == -1 ) current_index = 0; + // increment iterator if this is a recursion + else current_index++; + + // get binning for current variable + string key = m_bin_order.at(current_index); + vector<double> bin_edges = m_bin_map[key]; + + // looping over bins for current variable (dont count last bin top edge!) + for( unsigned int i=0; i<bin_edges.size()-1; i++ ){ + // store the iterator for the current variable (is passed in recursion) + current_bin_store.at(current_index) = i; + + // once final variable reached, retrieve info from config file + if( current_index == (int)(m_bin_order.size()-1) ){ + string bin_key = getBinKey( current_bin_store ); + + /* + // attempt to retrieve from file + TVectorF* pvec = (TVectorF*) dir->Get(bin_key.c_str()); + if( !pvec ){ + msg( string("Failed to find ")+bin_key+" in dir."); + dir->ls(); + return false; + } + + // store as std::vector + vector<double> new_vec; + for( int j=0;j<pvec->GetNoElements();j++) new_vec.push_back((*pvec)(j)); + m_hist_map[bin_key]=new_vec; + */ + + TH1* hist = (TH1*) dir->Get(bin_key.c_str()); + if( !hist ){ + msg( string("Failed to find ")+bin_key+" in dir."); + dir->ls(); + return false; + } + + // store as TH1 + hist->SetDirectory(0); + m_hist_map[bin_key]=(TH1*)hist; //no clone in case SetDirectory(0) is used ->Clone(); + + } + else{ + // recursively call to loop through all binning combinations + if( !this->parseTDirectory( + dir, + current_bin_store, + current_index) + ) + { + msg( "ERROR parsing TDirectory" ); + return false; + } + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool TauPi0BonnParser::parseROOTFile( string filename, string directory ){ + + // open input file + TFile* file = TFile::Open( filename.c_str() ); + if( !file ){ + msg( string("cant load file ")+filename ); + return false; + } + + // get directory + TDirectory* dir = file->GetDirectory(directory.c_str()); + if( !dir ){ + msg( string("dir: ")+directory+" not in file: "+filename); + return false; + } + + // number of binning variables + TParameter<int>* NDIM = (TParameter<int>*)dir->Get("NDIM"); + if( !NDIM ){ + msg( "config file invalid format!"); + return false; + } + + // ';' seperated list of binning variable identifiers + TObjString* BIN_VARS = (TObjString*) dir->Get("BIN_VARS"); + if( !BIN_VARS ){ + msg( "config file invalid format!"); + return false; + } + + TString BIN_VARS_ts = BIN_VARS->GetString(); + TIterator* BIN_VARS_itr = BIN_VARS_ts.Tokenize(';')->MakeIterator(); + while( TObject* obj = BIN_VARS_itr->Next() ){ + string key = obj->GetName(); + m_bin_map[key] = vector<double>(); + m_curr_val_map[key] = NULL; + m_bin_order.push_back(key); + //cout << "key: " << key << endl; + } + + // load binning for variables + map<string,vector<double> >::iterator itrMap = m_bin_map.begin(); + for(; itrMap!=m_bin_map.end(); itrMap++ ){ + itrMap->second.clear(); + TVectorF* vec = (TVectorF*) dir->Get(Form("%s_BINS",itrMap->first.c_str())); + //assert(vec); + if (!vec) continue; + // cout << "itrMap->first = " << itrMap->first << endl; + for( int i=0; i<vec->GetNoElements(); i++ ){ + itrMap->second.push_back( (*vec)(i+1) ); + // cout << "bin" << i << ": " << (*vec)(i+1) << endl; + } + } + + // parse all bin combinations in TDirectory + if( !this->parseTDirectory(dir) ){ + msg( "failed parsing bins in TDirectory - invalid format!"); + return false; + } + + file->Close(); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool TauPi0BonnParser::checkConfig( + vector<int> current_bin_store, + int current_index) +{ + // make sure current_bin_store can accommodate map entries + while( current_bin_store.size()<m_bin_map.size() ) current_bin_store.push_back(0); + + // initialise iterator + if( current_index == -1 ) current_index = 0; + // increment iterator if this is a recursion + else current_index++; + + // get binning for current variable + string key = m_bin_order.at(current_index); + vector<double> bin_edges = m_bin_map[key]; + + // looping over bins for current variable (dont count last bin top edge!) + for( unsigned int i=0; i<bin_edges.size()-1; i++ ){ + // store the iterator for the current variable (is passed in recursion) + current_bin_store.at(current_index) = i; + + // once final variable reached, retrieve info from config file + if( current_index == (int)(m_bin_order.size()-1) ){ + string bin_key = getBinKey( current_bin_store ); + + if( m_hist_map.find(bin_key) == m_hist_map.end() ){ + msg( bin_key + " not loaded!" ); + return false; + } + } + else{ + // recursively call to loop through all binning combinations + if( !this->checkConfig( + current_bin_store, + current_index) + ) + { + msg( string("failed checkConfig") ); + return false; + } + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool TauPi0BonnParser::checkInitialisationStatus(){ + + // check at least something loaded + if( m_bin_order.size() <= 0 ){ + msg( "nothing loaded" ); + return false; + } + + + // check addresses set for all corresponding varaibles + map<string,double*>::iterator itr = m_curr_val_map.begin(); + for( ; itr!=m_curr_val_map.end(); itr++ ){ + if( itr->second == NULL ){ + msg( string("Address of ") + itr->first + " not set!" ); + return false; + } + } + + + if( !this->checkConfig() ){ + msg( "Failed loading variables" ); + return false; + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void TauPi0BonnParser::summary(){ + // FIXME: Write new summary function? + /* + map<std::string,TH1*>::iterator itrMap = m_hist_map.begin(); + for( ; itrMap!=m_hist_map.end(); itrMap++ ){ + cout << itrMap->first << ": "; + for( unsigned int k=0; k<itrMap->second.size(); k++) cout << " " << Form( "%.2f",itrMap->second.at(k)); + cout << endl; + } + */ +} + diff --git a/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx b/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c4dbb38b2c7d52a656977cddd711efe9bf0fc2e1 --- /dev/null +++ b/Reconstruction/tauRec/src/TauPi0BonnScoreCalculator.cxx @@ -0,0 +1,244 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0BonnScoreCalculator.cxx +// package: Reconstruction/tauRec +// authors: Benedict Winter, Will Davey +// date: 2012-10-09 +// +//----------------------------------------------------------------------------- + +#include <vector> + +#include "tauRec/TauPi0BonnScoreCalculator.h" +#include "xAODPFlow/PFO.h" + +#include "TMVA/Reader.h" + +#include "PathResolver/PathResolver.h" + +using std::vector; +using std::string; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0BonnScoreCalculator::TauPi0BonnScoreCalculator( + const string& type, + const string& name, + const IInterface *parent) + + : TauToolBase(type, name, parent) + , m_readerOption("Silent:!Color") +{ + declareInterface<TauToolBase > (this); + + declareProperty("ReaderOption", m_readerOption); + declareProperty("BDTWeightFile", m_weightfile); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0BonnScoreCalculator::~TauPi0BonnScoreCalculator() +{ +} + + +StatusCode TauPi0BonnScoreCalculator::initialize() +{ + //--------------------------------------------------------------------- + // Create TMVA reader + //--------------------------------------------------------------------- + m_tmvaReader = new TMVA::Reader(TString(m_readerOption)); + + if (msgLvl(MSG::DEBUG)) m_tmvaReader->SetVerbose(true); + + int spectator = 1.; + m_tmvaReader->AddSpectator( "nTau" ,&spectator); + m_tmvaReader->AddSpectator( "nTau_test : = nTau%5" ,&spectator); + m_tmvaReader->AddSpectator( "Sample" ,&spectator); + m_tmvaReader->AddSpectator( "Pi0Cluster_type" ,&spectator); + m_tmvaReader->AddSpectator( "Pi0Cluster_BDTScore_old" ,&spectator); + m_tmvaReader->AddVariable( "Pi0Cluster_Abs_FIRST_ETA" ,&m_FIRST_ETA); + m_tmvaReader->AddVariable( "Pi0Cluster_SECOND_R" ,&m_SECOND_R); +// m_tmvaReader->AddVariable( "Pi0Cluster_SECOND_LAMBDA" ,&m_SECOND_LAMBDA); +// m_tmvaReader->AddVariable( "Pi0Cluster_Abs_DELTA_PHI" ,&m_Abs_DELTA_PHI); +// m_tmvaReader->AddVariable( "Pi0Cluster_Abs_DELTA_THETA" ,&m_Abs_DELTA_THETA); + m_tmvaReader->AddVariable( "Pi0Cluster_CENTER_LAMBDA_helped" ,&m_CENTER_LAMBDA_helped); +// m_tmvaReader->AddVariable( "Pi0Cluster_LATERAL" ,&m_LATERAL); +// m_tmvaReader->AddVariable( "Pi0Cluster_LONGITUDINAL" ,&m_LONGITUDINAL); + m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_EM" ,&m_ENG_FRAC_EM); +// m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_MAX" ,&m_ENG_FRAC_MAX); + m_tmvaReader->AddVariable( "Pi0Cluster_ENG_FRAC_CORE" ,&m_ENG_FRAC_CORE); + m_tmvaReader->AddVariable( "Pi0Cluster_log_SECOND_ENG_DENS" ,&m_log_SECOND_ENG_DENS); + m_tmvaReader->AddVariable( "Pi0Cluster_EcoreOverEEM1" ,&m_EcoreOverEEM1); + m_tmvaReader->AddVariable( "Pi0Cluster_AsymmetryWRTTrack" ,&m_AsymmetryWRTTrack); +// m_tmvaReader->AddVariable( "Pi0Cluster_NHitsInEM1" ,&m_NHitsInEM1); +// m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_PS" ,&m_NPosCells_PS); + m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_EM1" ,&m_NPosCells_EM1); + m_tmvaReader->AddVariable( "Pi0Cluster_NPosECells_EM2" ,&m_NPosCells_EM2); +// m_tmvaReader->AddVariable( "Pi0Cluster_AbsFirstEtaWRTClusterPosition_EM1" ,&m_firstEtaWRTCluster_EM1); +// m_tmvaReader->AddVariable( "Pi0Cluster_AbsFirstEtaWRTClusterPosition_EM2" ,&m_firstEtaWRTCluster_EM2); + m_tmvaReader->AddVariable( "Pi0Cluster_secondEtaWRTClusterPosition_EM1" ,&m_secondEtaWRTCluster_EM1); + m_tmvaReader->AddVariable( "Pi0Cluster_secondEtaWRTClusterPosition_EM2" ,&m_secondEtaWRTCluster_EM2); +// m_tmvaReader->AddVariable( "Pi0Cluster_energy_EM1" ,&m_energy_EM1); +// m_tmvaReader->AddVariable( "Pi0Cluster_energy_EM2" ,&m_energy_EM2); + + if (bookMethod(m_tmvaReader, "BDT method").isFailure()) return StatusCode::FAILURE; + + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnScoreCalculator::finalize() +{ + StatusCode sc = AlgTool::finalize(); + delete m_tmvaReader; + return sc; +} + + +StatusCode TauPi0BonnScoreCalculator::execute(TauCandidateData *data) +{ + xAOD::TauJet *tauJet = data->xAODTau; + //--------------------------------------------------------------------- + // only run on 1-5 prong taus + //--------------------------------------------------------------------- + if (tauJet->nTracks() == 0 || tauJet->nTracks() >5 ) { + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG("ScoreCalculator: new tau. \tpt = " << tauJet->pt() << "\teta = " << tauJet->eta() << "\tphi = " << tauJet->phi() << "\tnprongs = " << tauJet->nTracks()); + + //--------------------------------------------------------------------- + // retrieve neutral PFOs from tau, calculate BDT scores and store them in PFO + //--------------------------------------------------------------------- + unsigned nNeutPFO = tauJet->nCellBased_Neutral_PFOs(); + for(unsigned int iNeutPFO=0; iNeutPFO<nNeutPFO; iNeutPFO++) { + const xAOD::PFO* curNeutPFO_const = tauJet->cellBased_Neutral_PFO( iNeutPFO ); + float BDTScore = calculateScore(curNeutPFO_const); + xAOD::PFO* curNeutPFO = const_cast<xAOD::PFO*>(curNeutPFO_const); + curNeutPFO->setBDTPi0Score((float) BDTScore); + } + + ATH_MSG_DEBUG("End of TauPi0BonnScoreCalculator::execute"); + + return StatusCode::SUCCESS; +} + + +float TauPi0BonnScoreCalculator::calculateScore(const xAOD::PFO* neutralPFO) +{ + m_FIRST_ETA=0.; + m_SECOND_R=0.; + m_SECOND_LAMBDA=0.; + m_Abs_DELTA_PHI=0.; + m_Abs_DELTA_THETA=0.; + m_CENTER_LAMBDA_helped=0.; + m_LATERAL=0.; + m_LONGITUDINAL=0.; + m_ENG_FRAC_EM=0.; + m_ENG_FRAC_MAX=0.; + m_ENG_FRAC_CORE=0.; + m_log_SECOND_ENG_DENS=0.; + m_EcoreOverEEM1=0.; + m_AsymmetryWRTTrack=0.; + // Need to convert int variables to floats after retrieving them + int NHitsInEM1=0; + int NPosCells_PS=0; + int NPosCells_EM1=0; + int NPosCells_EM2=0; + m_firstEtaWRTCluster_EM1=0.; + m_firstEtaWRTCluster_EM2=0.; + m_secondEtaWRTCluster_EM1=0.; + m_secondEtaWRTCluster_EM2=0.; + m_energy_EM1=0.; + m_energy_EM2=0.; + + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_FIRST_ETA,m_FIRST_ETA) == false) + ATH_MSG_WARNING("Can't find FIRST_ETA. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_R,m_SECOND_R) == false) + ATH_MSG_WARNING("Can't find SECOND_R. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_LAMBDA,m_SECOND_LAMBDA) == false) + ATH_MSG_WARNING("Can't find SECOND_LAMBDA. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_PHI,m_Abs_DELTA_PHI) == false) + ATH_MSG_WARNING("Can't find DELTA_PHI. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_DELTA_THETA,m_Abs_DELTA_THETA) == false) + ATH_MSG_WARNING("Can't find DELTA_THETA. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_CENTER_LAMBDA,m_CENTER_LAMBDA_helped) == false) + ATH_MSG_WARNING("Can't find CENTER_LAMBDA. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_LATERAL,m_LATERAL) == false) + ATH_MSG_WARNING("Can't find LATERAL. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_LONGITUDINAL,m_LONGITUDINAL) == false) + ATH_MSG_WARNING("Can't find LONGITUDINAL. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_EM,m_ENG_FRAC_EM) == false) + ATH_MSG_WARNING("Can't find ENG_FRAC_EM. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_MAX,m_ENG_FRAC_MAX) == false) + ATH_MSG_WARNING("Can't find ENG_FRAC_MAX. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_ENG_FRAC_CORE,m_ENG_FRAC_CORE) == false) + ATH_MSG_WARNING("Can't find ENG_FRAC_CORE. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_SECOND_ENG_DENS,m_log_SECOND_ENG_DENS) == false) + ATH_MSG_WARNING("Can't find SECOND_ENG_DENS. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_EM1CoreFrac,m_EcoreOverEEM1) == false) + ATH_MSG_WARNING("Can't find EM1CoreFrac. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_asymmetryInEM1WRTTrk,m_AsymmetryWRTTrack) == false) + ATH_MSG_WARNING("Can't find asymmetryInEM1WRTTrk. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NHitsInEM1,NHitsInEM1) == false) + ATH_MSG_WARNING("Can't find NHitsInEM1. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_PS,NPosCells_PS) == false) + ATH_MSG_WARNING("Can't find NPosECells_PS. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM1,NPosCells_EM1) == false) + ATH_MSG_WARNING("Can't find NPosECells_EM1. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_NPosECells_EM2,NPosCells_EM2) == false) + ATH_MSG_WARNING("Can't find NPosECells_EM2. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM1,m_firstEtaWRTCluster_EM1) == false) + ATH_MSG_WARNING("Can't find firstEtaWRTClusterPosition_EM1. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_firstEtaWRTClusterPosition_EM2,m_firstEtaWRTCluster_EM2) == false) + ATH_MSG_WARNING("Can't find firstEtaWRTClusterPosition_EM2. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM1,m_secondEtaWRTCluster_EM1) == false) + ATH_MSG_WARNING("Can't find secondEtaWRTClusterPosition_EM1. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_secondEtaWRTClusterPosition_EM2,m_secondEtaWRTCluster_EM2) == false) + ATH_MSG_WARNING("Can't find secondEtaWRTClusterPosition_EM2. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM1,m_energy_EM1) == false) + ATH_MSG_WARNING("Can't find energy_EM1. Set it to 0."); + if(neutralPFO->attribute(xAOD::PFODetails::PFOAttributes::cellBased_energy_EM2,m_energy_EM2) == false) + ATH_MSG_WARNING("Can't find energy_EM2. Set it to 0."); + // Apply variable transformations + m_Abs_DELTA_PHI = fabs(m_Abs_DELTA_PHI); + m_Abs_DELTA_THETA = fabs(m_Abs_DELTA_THETA); + m_CENTER_LAMBDA_helped = fmin(m_CENTER_LAMBDA_helped, 1000.); + if(m_log_SECOND_ENG_DENS==0.) m_log_SECOND_ENG_DENS=-50.; + else m_log_SECOND_ENG_DENS = log(m_log_SECOND_ENG_DENS); + // Convert ints to floats so they can be read by the TMVA reader + m_NHitsInEM1 = (float) NHitsInEM1; + m_NPosCells_PS = (float) NPosCells_PS; + m_NPosCells_EM1 = (float) NPosCells_EM1; + m_NPosCells_EM2 = (float) NPosCells_EM2; + + // Calculate BDT score + float BDTScore = m_tmvaReader->EvaluateMVA( "BDT method" ); + + return BDTScore; +} + +StatusCode TauPi0BonnScoreCalculator::bookMethod(TMVA::Reader *reader, const std::string &methodName) const +{ + if (m_weightfile == ""){ + ATH_MSG_ERROR("No weight file given"); + return StatusCode::FAILURE; + } + std::string resolvedFileName = PathResolver::find_file(m_weightfile, "DATAPATH"); + if (resolvedFileName != "") { + ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName ); + } + else { + ATH_MSG_ERROR( "Parameterisation file " << m_weightfile << " not found" ); + return StatusCode::FAILURE; + } + reader->BookMVA( methodName, resolvedFileName); + return StatusCode::SUCCESS; +} + diff --git a/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx b/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8202b9a183b4cf39d4cef5c6fee3826d4b98c6f8 --- /dev/null +++ b/Reconstruction/tauRec/src/TauPi0BonnSelector.cxx @@ -0,0 +1,148 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauPi0BonnSelector.cxx +// package: Reconstruction/tauRec +// authors: Benedict Winter, Will Davey +// date: 2012-10-09 +// +//----------------------------------------------------------------------------- + +#include <vector> + +#include "tauRec/TauPi0BonnSelector.h" +#include "FourMomUtils/P4Helpers.h" + +#include "CaloUtils/CaloVertexedCluster.h" + + +using std::vector; +using std::string; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauPi0BonnSelector::TauPi0BonnSelector( + const string& type, + const string& name, + const IInterface *parent) + + : TauToolBase(type, name, parent) +{ + declareInterface<TauToolBase > (this); + + declareProperty("ClusterEtCut", m_clusterEtCut); + declareProperty("ClusterBDTCut_1prong", m_clusterBDTCut_1prong); + declareProperty("ClusterBDTCut_mprong", m_clusterBDTCut_mprong); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauPi0BonnSelector::~TauPi0BonnSelector() +{ +} + +StatusCode TauPi0BonnSelector::initialize() +{ + return StatusCode::SUCCESS; +} + +StatusCode TauPi0BonnSelector::execute(TauCandidateData *data) +{ + xAOD::TauJet *tauJet = data->xAODTau; + //--------------------------------------------------------------------- + // only run on 1-5 prong taus + //--------------------------------------------------------------------- + if (tauJet->nTracks() == 0 || tauJet->nTracks() >5 ) { + return StatusCode::SUCCESS; + } + + + //--------------------------------------------------------------------- + // retrieve neutral PFOs from tau. Apply selection and create links to + // Pi0NeutralPFOs + //--------------------------------------------------------------------- + unsigned nNeutPFO = tauJet->nCellBased_Neutral_PFOs(); + for(unsigned int iNeutPFO=0; iNeutPFO<nNeutPFO; iNeutPFO++) { + const xAOD::PFO* curNeutPFO_const = tauJet->cellBased_Neutral_PFO( iNeutPFO ); + + // Get eta bin + int etaBin = getPi0Cluster_etaBin( curNeutPFO_const->p4().Eta() ); + + // Preselection + if(curNeutPFO_const->p4().Et() < m_clusterEtCut.at(etaBin)) continue; + if(tauJet->p4().DeltaR(curNeutPFO_const->p4()) > 0.2) continue; // FIXME replace by shrinking cone + + // BDT Selection + float BDTScore = curNeutPFO_const->bdtPi0Score(); + if( (tauJet->nTracks()==1 && BDTScore < m_clusterBDTCut_1prong.at(etaBin)) || (tauJet->nTracks()>1 && BDTScore < m_clusterBDTCut_mprong.at(etaBin)) ) continue; + + // Set number of pi0s + int nHitsInEM1 = 0; + if(!curNeutPFO_const->attribute(xAOD::PFODetails::cellBased_NHitsInEM1, nHitsInEM1)) ATH_MSG_WARNING("Couldn't retrieve nHitsInEM1. Will set it to 0."); + xAOD::PFO* curNeutPFO = const_cast<xAOD::PFO*>(curNeutPFO_const); + if(nHitsInEM1<3){ + curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, 1); + curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, 1); + } + else{ + curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0, 2); + curNeutPFO->setAttribute<int>(xAOD::PFODetails::PFOAttributes::nPi0Proto, 2); + } + + // Set element link to Pi0tagged PFO + ElementLink<xAOD::PFOContainer> pfoLink = tauJet->cellBased_Neutral_PFOLinks().at(iNeutPFO); + tauJet->addCellBased_Pi0_PFOLink(pfoLink); + } + // Calculate visTau hlv and store it in pPi0Details. + TLorentzVector p4 = getP4(tauJet); + tauJet->setP4(xAOD::TauJetParameters::PanTauCellBasedProto, p4.Pt(),p4.Eta(),p4.Phi(),p4.M()); + // tauJet->setPtPanTauCellBasedProto( p4.Pt()); + // tauJet->setEtaPanTauCellBasedProto(p4.Eta()); + // tauJet->setPhiPanTauCellBasedProto(p4.Phi()); + // tauJet->setEPanTauCellBasedProto( p4.E()); + // tauJet->setMPanTauCellBasedProto( p4.M()); + + return StatusCode::SUCCESS; +} + +int TauPi0BonnSelector::getPi0Cluster_etaBin(double Pi0Cluster_eta){ + int Pi0Cluster_etaBin = -1; + double Pi0Cluster_noCorr_ABSeta = fabs(Pi0Cluster_eta); + + if( Pi0Cluster_noCorr_ABSeta < 0.80 ) Pi0Cluster_etaBin = 0; + else if( Pi0Cluster_noCorr_ABSeta < 1.40 ) Pi0Cluster_etaBin = 1; + else if( Pi0Cluster_noCorr_ABSeta < 1.50 ) Pi0Cluster_etaBin = 2; + else if( Pi0Cluster_noCorr_ABSeta < 1.90 ) Pi0Cluster_etaBin = 3; + else Pi0Cluster_etaBin = 4; + return Pi0Cluster_etaBin; +} + +TLorentzVector TauPi0BonnSelector::getP4(xAOD::TauJet* tauJet) +{ + // Get 4mom of first charged PFO, which is available for all taus that are treated in this algorithm + const xAOD::PFO* firstChargedPFO = tauJet->cellBased_Charged_PFO( 0 ); + TLorentzVector p4 = firstChargedPFO->p4(); + // Add other PFO momenta + unsigned nChargedPFO = tauJet->nCellBased_Charged_PFOs(); + for(unsigned int iChargedPFO=1; iChargedPFO<nChargedPFO; iChargedPFO++){ + const xAOD::PFO* curChargedPFO = tauJet->cellBased_Charged_PFO( iChargedPFO ); + p4+=curChargedPFO->p4(); + } + unsigned nPi0NeutPFO = tauJet->nCellBased_Pi0_PFOs(); + for(unsigned int iPi0NeutPFO=0; iPi0NeutPFO<nPi0NeutPFO; iPi0NeutPFO++){ + const xAOD::PFO* curPi0NeutPFO = tauJet->cellBased_Pi0_PFO( iPi0NeutPFO ); + if (tauJet->vertexLink()) + p4+= xAOD::CaloVertexedCluster(*curPi0NeutPFO->cluster(0) , (*tauJet->vertexLink())->position()).p4(); + else + p4+= xAOD::CaloVertexedCluster(*curPi0NeutPFO->cluster(0)).p4(); + + } + return p4; +} + diff --git a/Reconstruction/tauRec/src/TauProcessor.cxx b/Reconstruction/tauRec/src/TauProcessor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1d47aa9c2b05624e95ffee5e07d574338be94fc6 --- /dev/null +++ b/Reconstruction/tauRec/src/TauProcessor.cxx @@ -0,0 +1,231 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "GaudiKernel/ListItem.h" + +#include "xAODTau/TauJetContainer.h" + +#include "tauRec/TauProcessor.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +TauProcessor::TauProcessor(const std::string &name, + ISvcLocator * pSvcLocator) : +AthAlgorithm(name, pSvcLocator), +m_tauContainerName("TauRecContainer"), +m_tauAuxContainerName("TauRecContainerAux."), +m_AODmode(false), +m_tools(this) //make tools private +{ + declareProperty("TauContainer", m_tauContainerName); + declareProperty("TauAuxContainer", m_tauAuxContainerName); + declareProperty("Tools", m_tools, "List of TauToolBase tools"); + declareProperty("runOnAOD", m_AODmode); //AODS are input file + +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- +TauProcessor::~TauProcessor() { +} + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- +StatusCode TauProcessor::initialize() { + + + //ATH_MSG_INFO("FF::TauProcessor :: initialize()"); + + //------------------------------------------------------------------------- + // No tools allocated! + //------------------------------------------------------------------------- + if (m_tools.size() == 0) { + ATH_MSG_ERROR("no tools given!"); + return StatusCode::FAILURE; + } + + StatusCode sc; + + //------------------------------------------------------------------------- + // Allocate tools + //------------------------------------------------------------------------- + ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end(); + ATH_MSG_INFO("List of tools in execution sequence:"); + ATH_MSG_INFO("------------------------------------"); + + unsigned int tool_count = 0; + + for (; itT != itTE; ++itT) { + sc = itT->retrieve(); + if (sc.isFailure()) { + ATH_MSG_WARNING("Cannot find tool named <" << *itT << ">"); + } else { + ++tool_count; + ATH_MSG_INFO((*itT)->type() << " - " << (*itT)->name()); + } + } + ATH_MSG_INFO(" "); + ATH_MSG_INFO("------------------------------------"); + + if (tool_count == 0) { + ATH_MSG_ERROR("could not allocate any tool!"); + return StatusCode::FAILURE; + } + + /////////////////////////////////////////////////////////////////////////// + + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauProcessor::finalize() { + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauProcessor::execute() { + + StatusCode sc; + + TauCandidateData rTauData; + + const xAOD::TauJetContainer* pContainer = 0; + const xAOD::TauJetAuxContainer* pAuxContainer = 0; + + //------------------------------------------------------------------------- + // retrieve Tau Containers from StoreGate + //------------------------------------------------------------------------- + sc = evtStore()->retrieve(pContainer, m_tauContainerName); + if (sc.isFailure()) { + if (m_AODmode) { + // don't exit Athena if there is no Tau Container in (D)AODs when running in AOD mode + // just exit TauProcessor + // reason: somebody might use slimmed (D)AODs, where not needed containers are not present + ATH_MSG_WARNING("Failed to retrieve " << m_tauContainerName << "! Will exit TauProcessor now!!"); + return StatusCode::SUCCESS; + } + else { + ATH_MSG_FATAL("Failed to retrieve " << m_tauContainerName); + return StatusCode::FAILURE; + } + } + rTauData.xAODTauContainer = const_cast<xAOD::TauJetContainer*>(pContainer); + + sc = evtStore()->retrieve(pAuxContainer, m_tauAuxContainerName); + if (sc.isFailure()) { + if (m_AODmode) { + // don't exit Athena if there is no Tau AuxContainer in (D)AODs when running in AOD mode + // just exit TauProcessor + // reason: somebody might use slimmed (D)AODs, where not needed containers are not present + ATH_MSG_WARNING("Failed to retrieve " << m_tauAuxContainerName << "! Will exit TauProcessor now!!"); + return StatusCode::SUCCESS; + } + else { + ATH_MSG_FATAL("Failed to retrieve " << m_tauAuxContainerName); + return StatusCode::FAILURE; + } + } + rTauData.tauAuxContainer = const_cast<xAOD::TauJetAuxContainer*>(pAuxContainer); + + // set TauCandidate properties + rTauData.xAODTau = 0; + /* + rTauData.tau = 0; + rTauData.details = 0; + rTauData.extraDetails = 0; + rTauData.pi0Details = 0; + */ + rTauData.seed = 0; + rTauData.seedContainer = 0; + + //------------------------------------------------------------------------- + // Initialize tools for this event + //------------------------------------------------------------------------- + ToolHandleArray<TauToolBase> ::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase> ::iterator itTE = m_tools.end(); + for (; itT != itTE; ++itT) { + sc = (*itT)->eventInitialize(&rTauData); + if (sc != StatusCode::SUCCESS) + return StatusCode::FAILURE; + } + + //////////////////////////////////////////////////////// + + //loop over taus + xAOD::TauJetContainer::const_iterator tau_it = pContainer->begin(); + xAOD::TauJetContainer::const_iterator tau_end = pContainer->end(); + + for(; tau_it != tau_end; ++tau_it) { + + //----------------------------------------------------------------- + // set tau candidate data for easy handling + //----------------------------------------------------------------- + rTauData.xAODTau = const_cast<xAOD::TauJet * >( *tau_it); + rTauData.seed = ( *rTauData.xAODTau->jetLink() ); + + //----------------------------------------------------------------- + // Process the candidate + //----------------------------------------------------------------- + ToolHandleArray<TauToolBase>::iterator itT = m_tools.begin(); + ToolHandleArray<TauToolBase>::iterator itTE = m_tools.end(); + + //----------------------------------------------------------------- + // Loop stops when Failure indicated by one of the tools + //----------------------------------------------------------------- + for (; itT != itTE; ++itT) { + ATH_MSG_VERBOSE("Invoking tool " << (*itT)->name()); + + sc = (*itT)->execute(&rTauData); + + if (sc.isFailure()) + break; + } + + if (sc.isSuccess()) { + + ATH_MSG_VERBOSE("The tau candidate has been modified"); + + } else if (!sc.isSuccess()) { + //TODO:cleanup of EndTools not necessary?? + //keep this here for future use (in case more than one seeding algo exist) + /* + ToolHandleArray<TauToolBase> ::iterator p_itT1 = m_tools.begin(); + for (; p_itT1 != p_itT; ++p_itT1) + (*p_itT1)->cleanup(&rTauData); + (*p_itT1)->cleanup(&rTauData); + */ + //delete rTauData.tau; + } else { + //delete rTauData.tau; + } + } + + + + //------------------------------------------------------------------------- + // Finalize tools for this event + //------------------------------------------------------------------------- + + itT = m_tools.begin(); + itTE = m_tools.end(); + for (; itT != itTE; ++itT) { + sc = (*itT)->eventFinalize(&rTauData); + if (sc != StatusCode::SUCCESS) + return StatusCode::FAILURE; + } + + + /////////////////////////////////////////////////////// + // locking of containers is moved to separate tau tool + + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauShotFinder.cxx b/Reconstruction/tauRec/src/TauShotFinder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0075f5b51d0f505b7237ff8583174af6712b7903 --- /dev/null +++ b/Reconstruction/tauRec/src/TauShotFinder.cxx @@ -0,0 +1,554 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauShotFinder.cxx +// package: Reconstruction/tauRec +// authors: Will Davey, Benedict Winter, Stephanie Yuen +// date: 2013-05-22 +// +//----------------------------------------------------------------------------- + +#include <boost/scoped_ptr.hpp> + +#include "GaudiKernel/IToolSvc.h" + +#include "CaloEvent/CaloCellContainer.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODCaloEvent/CaloClusterKineHelper.h" +#include "CaloIdentifier/CaloCell_ID.h" +#include "CaloIdentifier/LArNeighbours.h" +#include "CaloUtils/CaloClusterStoreHelper.h" +#include "CaloUtils/CaloCellList.h" +#include "CaloUtils/CaloCellESort.h" +#include "CaloInterface/IHadronicCalibrationTool.h" +#include "FourMomUtils/P4Helpers.h" +#include "tauRec/TauShotFinder.h" +#include "tauRec/TauShotVariableHelpers.h" +#include "TMVA/Reader.h" +#include "PathResolver/PathResolver.h" +#include "xAODPFlow/PFOContainer.h" +#include "xAODPFlow/PFOAuxContainer.h" +#include "xAODPFlow/PFO.h" + +using std::vector; +using std::string; + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- + +TauShotFinder::TauShotFinder( const string& type, + const string& name, + const IInterface *parent) + : TauToolBase(type, name, parent) + , m_caloWeightTool("H1WeightToolCSC12Generic") + , m_caloCellContainerName("AllCalo") + , m_shotClusterContainer(NULL) + , m_shotClusterContainerName("TauShotClusterContainer") + , m_shotPFOContainerName("TauShotPFOContainer") + , m_calo_dd_man(NULL) + , m_calo_id(NULL) +{ + declareInterface<TauToolBase > (this); + declareProperty("CaloWeightTool", m_caloWeightTool); + declareProperty("CaloCellContainerName", m_caloCellContainerName); + declareProperty("ShotClusterContainerName", m_shotClusterContainerName); + declareProperty("ShotPFOContainerName", m_shotPFOContainerName); + declareProperty("ReaderOption", m_readerOption); + declareProperty("BDTWeightFile_barrel", m_weightfile_barrel); + declareProperty("BDTWeightFile_endcap1", m_weightfile_endcap1); + declareProperty("BDTWeightFile_endcap2", m_weightfile_endcap2); + declareProperty("NCellsInEta", m_nCellsInEta); + declareProperty("MinPtCut", m_minPtCut); + declareProperty("AutoDoubleShotCut", m_autoDoubleShotCut); + declareProperty("MergedBDTScoreCut", m_mergedBDTScoreCut); +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- + +TauShotFinder::~TauShotFinder() { +} + +StatusCode TauShotFinder::initialize() { + + // retrieve tools + ATH_MSG_DEBUG( "Retrieving tools" ); + CHECK( m_caloWeightTool.retrieve() ); + + // initialize calo cell geo + m_calo_dd_man = CaloDetDescrManager::instance(); + m_calo_id = m_calo_dd_man->getCaloCell_ID(); + + //--------------------------------------------------------------------- + // Create TMVA readers + //--------------------------------------------------------------------- + m_tmvaReader_barrel = new TMVA::Reader(TString(m_readerOption)); + if (msgLvl(MSG::DEBUG)) m_tmvaReader_barrel->SetVerbose(true); + m_tmvaReader_barrel->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC); + m_tmvaReader_barrel->AddVariable("shot_stdpt_5" ,&G_STDPT_5 ); + m_tmvaReader_barrel->AddVariable("shot_stdeta_5" ,&G_STDETA_5 ); + m_tmvaReader_barrel->AddVariable("shot_deltapt_min" ,&G_DELTAPT_MIN ); + + m_tmvaReader_endcap1 = new TMVA::Reader(TString(m_readerOption)); + if (msgLvl(MSG::DEBUG)) m_tmvaReader_endcap1->SetVerbose(true); + m_tmvaReader_endcap1->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC); + m_tmvaReader_endcap1->AddVariable("shot_stdpt_5" ,&G_STDPT_5 ); + m_tmvaReader_endcap1->AddVariable("shot_stdeta_5" ,&G_STDETA_5 ); + m_tmvaReader_endcap1->AddVariable("shot_deltapt_min" ,&G_DELTAPT_MIN ); + + m_tmvaReader_endcap2 = new TMVA::Reader(TString(m_readerOption)); + if (msgLvl(MSG::DEBUG)) m_tmvaReader_endcap2->SetVerbose(true); + m_tmvaReader_endcap2->AddVariable("(shot_pt_3-shot_pt)/shot_pt_3",&G_PTFRAC); + m_tmvaReader_endcap2->AddVariable("shot_stdpt_5" ,&G_STDPT_5 ); + m_tmvaReader_endcap2->AddVariable("shot_stdeta_5" ,&G_STDETA_5 ); + m_tmvaReader_endcap2->AddVariable("shot_deltapt_min" ,&G_DELTAPT_MIN ); + + if (bookMethod(m_tmvaReader_barrel, m_tmvaReader_endcap1, m_tmvaReader_endcap2, "BDT method").isFailure()) return StatusCode::FAILURE; + + // setupCuts(); + + return StatusCode::SUCCESS; +} + +StatusCode TauShotFinder::finalize() +{ + StatusCode sc = AlgTool::finalize(); + delete m_tmvaReader_barrel; + delete m_tmvaReader_endcap1; + delete m_tmvaReader_endcap2; + return sc; +} + +StatusCode TauShotFinder::eventInitialize(TauCandidateData * /*data*/) { + + //--------------------------------------------------------------------- + // Create Shot ClusterContainer and register in StoreGate + //--------------------------------------------------------------------- + m_shotClusterContainer = CaloClusterStoreHelper::makeContainer(&*evtStore(), + m_shotClusterContainerName, + msg() + ); + + //--------------------------------------------------------------------- + // Create Shot PFO container + //--------------------------------------------------------------------- + m_PFOShotContainer = new xAOD::PFOContainer(); + CHECK( evtStore()->record(m_PFOShotContainer, m_shotPFOContainerName ) ); + m_PFOShotAuxStore = new xAOD::PFOAuxContainer(); + CHECK( evtStore()->record( m_PFOShotAuxStore, m_shotPFOContainerName + "Aux." ) ); + m_PFOShotContainer->setStore(m_PFOShotAuxStore); + + return StatusCode::SUCCESS; +} + +StatusCode TauShotFinder::execute(TauCandidateData *data) { + + xAOD::TauJet *pTau = data->xAODTau; + + //--------------------------------------------------------------------- + // only run shower subtraction on 1-5 prong taus + //--------------------------------------------------------------------- + if (pTau->nTracks() == 0 || pTau->nTracks() >5 ) { + return StatusCode::SUCCESS; + } + ATH_MSG_DEBUG(""); + ATH_MSG_DEBUG("New tau"); + + //--------------------------------------------------------------------- + // retrieve cells around tau + //--------------------------------------------------------------------- + // get all calo cell container + const CaloCellContainer *pCellContainer = NULL; + CHECK( evtStore()->retrieve(pCellContainer, m_caloCellContainerName) ); + + // get only EM cells within dR<0.2 + // TODO: might be possible to select only EM1 cells, but probbaly wont + // speed things up much anyway + vector<CaloCell_ID::SUBCALO> emSubCaloBlocks; + emSubCaloBlocks.push_back(CaloCell_ID::LAREM); + boost::scoped_ptr<CaloCellList> pCells(new CaloCellList(pCellContainer,emSubCaloBlocks)); + + // TODO: change hardcoded 0.2 to tau cone variable, (or func. from TauJet?) + pCells->select(pTau->eta(), pTau->phi(), 0.4); + + // Dump cells into a std::vector since CaloCellList wont allow sorting + // (maybe this can be done faster at some point). + // Also apply very basic preselection + std::vector<const CaloCell*> cells; + CaloCellList::list_iterator cellItr = pCells->begin(); + for(; cellItr!=pCells->end();++cellItr){ + // require cells above 100 MeV + if( (*cellItr)->pt()*m_caloWeightTool->wtCell(*cellItr) < 100. ) continue; + // require cells in EM1 + int samp = (*cellItr)->caloDDE()->getSampling(); + if( !( samp == CaloCell_ID::EMB1 || samp == CaloCell_ID::EME1 ) ) continue; + cells.push_back(*cellItr); + } + // sort cells in descending pt + std::sort(cells.begin(),cells.end(),ptSort(*this)); + + //--------------------------------------------------------------------- + // shot seeding + //--------------------------------------------------------------------- + // get seed cells + std::vector<const CaloCell*> seedCells; + std::set<IdentifierHash> seedCellHashes; + cellItr = cells.begin(); + for(; cellItr != cells.end(); ++cellItr) { + const CaloCell* cell = (*cellItr); + const IdentifierHash cellHash = cell->caloDDE()->calo_hash(); + + // apply seed selection on nearest neighbours + std::vector<IdentifierHash> nextEta, prevEta; + m_calo_id->get_neighbours(cellHash,LArNeighbours::nextInEta,nextEta); + m_calo_id->get_neighbours(cellHash,LArNeighbours::prevInEta,prevEta); + std::vector<IdentifierHash> neighbours = nextEta; + neighbours.insert(neighbours.end(),prevEta.begin(),prevEta.end()); + bool status = true; + std::vector<IdentifierHash>::iterator hashItr = neighbours.begin(); + for(;hashItr!=neighbours.end();++hashItr){ + // must not be next to seed cell (TODO: maybe this requirement can be removed) + if( seedCellHashes.find(*hashItr) != seedCellHashes.end() ){ + status = false; + break; + } + // must be maximum + const CaloCell* neigCell = pCellContainer->findCell(*hashItr); + if( !neigCell ) continue; + if( neigCell->pt()*m_caloWeightTool->wtCell(neigCell) >= cell->pt()*m_caloWeightTool->wtCell(cell) ){ + status = false; + break; + } + } + if( !status ) continue; + seedCells.push_back(cell); + seedCellHashes.insert(cellHash); + } // preselected cells + ATH_MSG_DEBUG("seedCells.size() = " << seedCells.size()); + + // merge across phi and construct shots + while( seedCells.size() ){ + + const CaloCell* cell = seedCells.front(); + const IdentifierHash seedHash = cell->caloDDE()->calo_hash(); + + // look for match across phi in current seeds + const CaloCell* nextPhi = NULL; + const CaloCell* prevPhi = NULL; + for( cellItr = seedCells.begin(); cellItr!=seedCells.end(); ++cellItr){ + if( (*cellItr) == cell ) continue; + IdentifierHash shotCellHash = (*cellItr)->caloDDE()->calo_hash(); + if( this->isPhiNeighbour(seedHash,shotCellHash,true) ) nextPhi = (*cellItr); + else if( this->isPhiNeighbour(seedHash,shotCellHash,false) ) prevPhi = (*cellItr); + } + + const CaloCell* mergePhi = NULL; + if( nextPhi && prevPhi ){ + // take higest-pt if merged up and down + if( nextPhi->pt()*m_caloWeightTool->wtCell(nextPhi) > prevPhi->pt()*m_caloWeightTool->wtCell(prevPhi) ) mergePhi = nextPhi; + else mergePhi = prevPhi; + } + else if (nextPhi) mergePhi = nextPhi; + else if (prevPhi) mergePhi = prevPhi; + + // get neighbours in 5x1 window + std::vector<const CaloCell*> windowNeighbours = this->getNeighbours(pCellContainer,cell,2); + if( mergePhi ){ + std::vector<const CaloCell*> mergeCells = this->getNeighbours(pCellContainer,mergePhi,2); + windowNeighbours.push_back(mergePhi); + windowNeighbours.insert(windowNeighbours.end(),mergeCells.begin(),mergeCells.end()); + } + + + // create seed cluster + xAOD::CaloCluster* shotCluster = CaloClusterStoreHelper::makeCluster(pCellContainer); + shotCluster->getCellLinks()->reserve(windowNeighbours.size()+1); + shotCluster->addCell(pCellContainer->findIndex(seedHash), 1.); + cellItr = windowNeighbours.begin(); + for( ; cellItr!=windowNeighbours.end(); ++cellItr) + shotCluster->addCell(pCellContainer->findIndex((*cellItr)->caloDDE()->calo_hash()),1.0); + CaloClusterKineHelper::calculateKine(shotCluster,true,true); + m_shotClusterContainer->push_back(shotCluster); + + // create shot PFO and store it in output container + xAOD::PFO* shot = new xAOD::PFO(); + m_PFOShotContainer->push_back( shot ); + + // Create element link from tau to shot + ElementLink<xAOD::PFOContainer> PFOElementLink; + PFOElementLink.toContainedElement( *m_PFOShotContainer, shot ); + pTau->addShot_PFOLink( PFOElementLink ); + + if( mergePhi ){ + // interpolate position + double dPhi = TVector2::Phi_mpi_pi( mergePhi->phi() - cell->phi()); + double ratio = mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi)/(cell->pt()*m_caloWeightTool->wtCell(cell) + mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi)); + float phi = cell->phi()+dPhi*ratio; + float pt = cell->pt()*m_caloWeightTool->wtCell(cell)+mergePhi->pt()*m_caloWeightTool->wtCell(mergePhi); + + shot->setP4( (float) pt, (float) cell->eta(), (float) phi, (float) cell->m()); + } + else shot->setP4( (float) cell->pt()*m_caloWeightTool->wtCell(cell), (float) cell->eta(), (float) cell->phi(), (float) cell->m()); + + shot->setBDTPi0Score( (float) -9999. ); + shot->setCharge( 0. ); + double center_mag = 0.0; + // No need to calculate cluster moments atm. + //if( !shotCluster->retrieveMoment((xAOD::CaloCluster_v1::MomentType) 404, center_mag) ) ATH_MSG_WARNING("Couldn't retrieve CENTER_MAG moment. Set it to 0."); + shot->setCenterMag( (float) center_mag); + + ElementLink<xAOD::CaloClusterContainer> clusElementLink; + clusElementLink.toContainedElement( *m_shotClusterContainer, shotCluster ); + shot->setClusterLink( clusElementLink ); + shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_nCellsInEta, m_nCellsInEta); + shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash); + + // Get cell block for variable calculations + std::vector<std::vector<const CaloCell*> > cellBlock = TauShotVariableHelpers::getCellBlock(shot, m_calo_id); + + // Some DEBUG statements + if (msgLvl(MSG::DEBUG)) { + if(cell->pt()*m_caloWeightTool->wtCell(cell)>300){ + ATH_MSG_DEBUG(""); + ATH_MSG_DEBUG("New shot. \t block size phi = " << cellBlock.size() << " \t block size eta = " << cellBlock.at(0).size() << "\t shot->pt() = " << shot->pt()); + for(unsigned iCellPhi = 0; iCellPhi<cellBlock.size();++iCellPhi){ + for(unsigned iCellEta = 0; iCellEta<cellBlock.at(iCellPhi).size();++iCellEta){ + const CaloCell* cell = cellBlock.at(iCellPhi).at(iCellEta); + if( cell==NULL ) ATH_MSG_DEBUG("Cell" << iCellPhi << iCellEta << ": \t NULL" ); + else ATH_MSG_DEBUG("Cell"<<iCellPhi<<iCellEta<<":\tPt = "<< cell->pt()*m_caloWeightTool->wtCell(cell)<<"\teta = "<<cell->eta()<<"\tphi = "<<cell->phi()); + } + } + } + } + + // set variables used for photon counting + m_pt1=TauShotVariableHelpers::ptWindow(cellBlock,1,m_caloWeightTool); + m_pt3=TauShotVariableHelpers::ptWindow(cellBlock,3,m_caloWeightTool); + m_pt5=TauShotVariableHelpers::ptWindow(cellBlock,5,m_caloWeightTool); + m_ws5=TauShotVariableHelpers::ws5(cellBlock,m_caloWeightTool); + m_sdevEta5_WRTmean=TauShotVariableHelpers::sdevEta_WRTmean(cellBlock,m_caloWeightTool); + m_sdevEta5_WRTmode=TauShotVariableHelpers::sdevEta_WRTmode(cellBlock,m_caloWeightTool); + m_sdevPt5=TauShotVariableHelpers::sdevPt(cellBlock,m_caloWeightTool); + m_deltaPt12_min=TauShotVariableHelpers::deltaPt12_min(cellBlock,m_caloWeightTool); + m_Fside_3not1=TauShotVariableHelpers::Fside(cellBlock,3,1,m_caloWeightTool); + m_Fside_5not1=TauShotVariableHelpers::Fside(cellBlock,5,1,m_caloWeightTool); + m_Fside_5not3=TauShotVariableHelpers::Fside(cellBlock,5,3,m_caloWeightTool); + m_fracSide_3not1=TauShotVariableHelpers::fracSide(cellBlock,3,1,m_caloWeightTool); + m_fracSide_5not1=TauShotVariableHelpers::fracSide(cellBlock,5,1,m_caloWeightTool); + m_fracSide_5not3=TauShotVariableHelpers::fracSide(cellBlock,5,3,m_caloWeightTool); + m_pt1OverPt3=TauShotVariableHelpers::ptWindowFrac(cellBlock,3,1,m_caloWeightTool); + m_pt3OverPt5=TauShotVariableHelpers::ptWindowFrac(cellBlock,5,3,m_caloWeightTool); + + // Same variable names as in Stephanie's private code + G_PTFRAC=m_fracSide_3not1; + G_STDPT_5=m_sdevPt5; + G_STDETA_5=fmin(m_sdevEta5_WRTmean,0.0036); + G_DELTAPT_MIN=fmax(-1000.,fmin(m_deltaPt12_min,2000)); + + // Calculate BDT scores + int etaBin = getEtaBin(cell->eta()); + float mergedBDTScore=getMergedBDTScore(etaBin); + + //////////////////////////////////////////////////////////////////////////////////////////// + // Calculate number of photons in shot + //////////////////////////////////////////////////////////////////////////////////////////// + int nPhotons = getNPhotons(etaBin, mergedBDTScore, m_pt1); + + //////////////////////////////////////////////////////////////////////////////////////////// + // Set variables in shot PFO + //////////////////////////////////////////////////////////////////////////////////////////// + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt1, m_pt1); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt3, m_pt3); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt5, m_pt5); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_ws5, m_ws5); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevEta5_WRTmean, m_sdevEta5_WRTmean); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevEta5_WRTmode, m_sdevEta5_WRTmode); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_sdevPt5, m_sdevPt5); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_deltaPt12_min, m_deltaPt12_min); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_3not1, m_Fside_3not1); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_5not1, m_Fside_5not1); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_Fside_5not3, m_Fside_5not3); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_3not1, m_fracSide_3not1); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_5not1, m_fracSide_5not1); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_fracSide_5not3, m_fracSide_5not3); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt1OverPt3, m_pt1OverPt3); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_pt3OverPt5, m_pt3OverPt5); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_mergedScore, mergedBDTScore); + shot->setAttribute<float>(xAOD::PFODetails::PFOAttributes::tauShots_signalScore, -1.); + shot->setAttribute<int>(xAOD::PFODetails::PFOAttributes::tauShots_nPhotons, nPhotons); + + // remove shot(s) from list + vector<const CaloCell*>::iterator cellItrNonConst; + cellItrNonConst = std::find(seedCells.begin(),seedCells.end(),cell); + seedCells.erase(cellItrNonConst); + if( mergePhi ){ + cellItrNonConst = std::find(seedCells.begin(),seedCells.end(),mergePhi); + seedCells.erase(cellItrNonConst); + } + + /* + ATH_MSG_DEBUG("Storing shot. pt: " << shot->pt() + << ", eta: " << shot->eta() + << ", phi: " << shot->phi() + ); + */ + + } // seed cells + + + return StatusCode::SUCCESS; +} + +void TauShotFinder::cleanup(TauCandidateData* /* data */) { + return; +} + +StatusCode TauShotFinder::eventFinalize(TauCandidateData* /* data */) { + CHECK( CaloClusterStoreHelper::finalizeClusters(&*evtStore(), + m_shotClusterContainer, + m_shotClusterContainerName, + msg()) ); + + return StatusCode::SUCCESS; +} + +std::vector<const CaloCell*> TauShotFinder::getNeighbours(const CaloCellContainer* pCellContainer, + const CaloCell* cell, + int maxDepth) +{ + std::vector<const CaloCell*> cells; + this->addNeighbours(pCellContainer,cell,cells,0,maxDepth,true); //next + this->addNeighbours(pCellContainer,cell,cells,0,maxDepth,false); //prev + return cells; +} + +void TauShotFinder::addNeighbours(const CaloCellContainer* pCellContainer, + const CaloCell* cell, + std::vector<const CaloCell*>& cells, + int depth, + int maxDepth, + bool next) +{ + depth++; + if( depth > maxDepth ) return; + + const IdentifierHash cellHash = cell->caloDDE()->calo_hash(); + std::vector<IdentifierHash> neigHashes; + if( next ) + m_calo_id->get_neighbours(cellHash,LArNeighbours::nextInEta,neigHashes); + else + m_calo_id->get_neighbours(cellHash,LArNeighbours::prevInEta,neigHashes); + + std::vector<IdentifierHash>::iterator hashItr = neigHashes.begin(); + for( ; hashItr!=neigHashes.end(); ++hashItr ){ + const CaloCell* newCell = pCellContainer->findCell(*hashItr); + if(!newCell)continue; + cells.push_back(newCell); + this->addNeighbours(pCellContainer,newCell,cells,depth,maxDepth,next); + // no EM1 cell should have more than one neighbor. Just add this neigbor for now + // FIXME: Check whether it happens that a cell has > 1 neighbors + break; + } +} + +bool TauShotFinder::isPhiNeighbour(IdentifierHash cell1Hash, IdentifierHash cell2Hash, bool next){ + std::vector<IdentifierHash> neigHashes; + if( next ) m_calo_id->get_neighbours(cell1Hash,LArNeighbours::nextInPhi,neigHashes); + else m_calo_id->get_neighbours(cell1Hash,LArNeighbours::prevInPhi,neigHashes); + std::vector<IdentifierHash>::iterator itr = neigHashes.begin(); + for( ; itr!=neigHashes.end(); ++itr ){ + if(cell2Hash == (*itr)) return true; + } + return false; +} + +float TauShotFinder::getEtaBin(float seedEta){ + float absSeedEta=fabs(seedEta); + if(fabs(absSeedEta)<0.80) return 0; // Central Barrel + else if(fabs(absSeedEta)<1.39) return 1; // Outer Barrel + else if(fabs(absSeedEta)<1.51) return 2; // crack + else if(fabs(absSeedEta)<1.80) return 3; // endcap, fine granularity + else return 4; // endcap, coarse granularity +} + +float TauShotFinder::getMergedBDTScore(int etaBin){ + float BDTScore = -1; + if(etaBin==0) BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" ); // barrel1 + else if(etaBin==1) BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" ); // barrel2 + else if(etaBin==2) BDTScore = m_tmvaReader_barrel->EvaluateMVA( "BDT method" ); // just use barrel BDT for now to check how it looks in data + else if(etaBin==3) BDTScore = m_tmvaReader_endcap1->EvaluateMVA( "BDT method" ); // endcap1 + else if(etaBin==4) BDTScore = m_tmvaReader_endcap2->EvaluateMVA( "BDT method" ); // endcap2 + return BDTScore; +} + +float TauShotFinder::getNPhotons(int etaBin, float mergedBDTScore, float seedEnergy){ + if(etaBin==2) return 0; // no photon counting in crack atm + ATH_MSG_DEBUG("etaBin = " << etaBin << ", seedEnergy = " << seedEnergy << ", m_minPtCut.at(etaBin) = " << m_minPtCut.at(etaBin) << "m_autoDoubleShotCut.at(etaBin) = " + << m_autoDoubleShotCut.at(etaBin) << ", mergedBDTScore = " << mergedBDTScore << ", m_mergedBDTScoreCut.at(etaBin) = " << m_mergedBDTScoreCut.at(etaBin) ); + if( seedEnergy < m_minPtCut.at(etaBin) ) return 0; + if( seedEnergy > m_autoDoubleShotCut.at(etaBin) ) return 2; + if( mergedBDTScore < m_mergedBDTScoreCut.at(etaBin) ) return 2; + return 1; +} + +// some really slick c++ way of doing sort (since we need to use the member m_caloWeightTool) +// how about learing a thing or two from python... +TauShotFinder::ptSort::ptSort( const TauShotFinder& info ) : m_info(info) { } +bool TauShotFinder::ptSort::operator()( const CaloCell* c1, const CaloCell* c2 ){ + return c1->pt()*m_info.m_caloWeightTool->wtCell(c1) > c2->pt()*m_info.m_caloWeightTool->wtCell(c2); +} + +StatusCode TauShotFinder::bookMethod(TMVA::Reader *reader_barrel, + TMVA::Reader *reader_endcap1, + TMVA::Reader *reader_endcap2, + const std::string &methodName) const +{ + if (m_weightfile_barrel == ""){ + ATH_MSG_ERROR("No weight m_weightfile_barrel given"); + return StatusCode::FAILURE; + } + if (m_weightfile_endcap1 == ""){ + ATH_MSG_ERROR("No weight m_weightfile_endcap1 given"); + return StatusCode::FAILURE; + } + if (m_weightfile_endcap2 == ""){ + ATH_MSG_ERROR("No weight m_weightfile_endcap2 given"); + return StatusCode::FAILURE; + } + std::string resolvedFileName = PathResolver::find_file(m_weightfile_barrel, "DATAPATH"); + if (resolvedFileName != ""){ + ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName ); + } + else { + ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_barrel << " not found" ); + return StatusCode::FAILURE; + } + reader_barrel->BookMVA( methodName, resolvedFileName); + + resolvedFileName = PathResolver::find_file(m_weightfile_endcap1, "DATAPATH"); + if (resolvedFileName != ""){ + ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName ); + } + else { + ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_endcap1 << " not found" ); + return StatusCode::FAILURE; + } + reader_endcap1->BookMVA( methodName, resolvedFileName); + + resolvedFileName = PathResolver::find_file(m_weightfile_endcap2, "DATAPATH"); + if (resolvedFileName != ""){ + ATH_MSG_DEBUG( "Parameterisation file found: " << resolvedFileName ); + } + else { + ATH_MSG_ERROR( "Parameterisation file " << m_weightfile_endcap2 << " not found" ); + return StatusCode::FAILURE; + } + reader_endcap2->BookMVA( methodName, resolvedFileName); + return StatusCode::SUCCESS; +} + +// EOF diff --git a/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx b/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..203437ef846dd03a802030ac19499975502a95fe --- /dev/null +++ b/Reconstruction/tauRec/src/TauShotVariableHelpers.cxx @@ -0,0 +1,357 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @brief implementation of photon shot variable calculation + * + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + * @author Stephanie Yuen <stephanie.yuen@cern.ch> + */ + +#include "tauRec/TauShotVariableHelpers.h" + +using xAOD::PFO; +using std::vector; + +namespace TauShotVariableHelpers { + std::vector<std::vector<const CaloCell*> > getCellBlock(xAOD::PFO* shot, const CaloCell_ID* calo_id){ + std::vector<std::vector<const CaloCell*> > cellVector; + std::vector<const CaloCell*> oneEtaLayer; + int nCellsInEta = 0; + if( shot->attribute(xAOD::PFODetails::PFOAttributes::tauShots_nCellsInEta, nCellsInEta) == false) { + std::cout << "WARNING: Couldn't find nCellsInEta. Return empty cell block." << std::endl; + return cellVector; + } + int seedHash = 0; + if( shot->attribute(xAOD::PFODetails::PFOAttributes::tauShots_seedHash, seedHash) == false) { + std::cout << "WARNING: Couldn't find seed hash. Return empty cell block." << std::endl; + return cellVector; + } + for(int iCell=0;iCell<nCellsInEta;++iCell) oneEtaLayer.push_back(NULL); + // have two layers in phi + cellVector.push_back(oneEtaLayer); + cellVector.push_back(oneEtaLayer); + // get cluster from shot + const xAOD::CaloCluster* cluster = shot->cluster(0); + const CaloClusterCellLink* theCellLink = cluster->getCellLinks(); + CaloClusterCellLink::const_iterator cellItr = theCellLink->begin(); + CaloClusterCellLink::const_iterator cellItrE = theCellLink->end(); + + // get seed cell from shot cluster + const CaloCell* seedCell=NULL; + for(;cellItr!=cellItrE;++cellItr){ + if((*cellItr)->caloDDE()->calo_hash()!=(unsigned) seedHash) continue; + seedCell = *cellItr; + break; + } + if(seedCell==NULL){ + std::cout << "WARNING: Couldn't find seed cell in shot cluster. Return empty cell block." << std::endl; + } + + // get merged cell in phi. Keep NULL if shot is not merged across phi + const CaloCell* mergedCell = NULL; + std::vector<IdentifierHash> nextInPhi; + std::vector<IdentifierHash> prevInPhi; + calo_id->get_neighbours(seedCell->caloDDE()->calo_hash(),LArNeighbours::nextInPhi,nextInPhi); + calo_id->get_neighbours(seedCell->caloDDE()->calo_hash(),LArNeighbours::prevInPhi,prevInPhi); + for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){ + std::vector<IdentifierHash>::iterator itr = nextInPhi.begin(); + for( ; itr!=nextInPhi.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + mergedCell = (*cellItr); + break; + } + if(mergedCell!=NULL) break; + itr = prevInPhi.begin(); + for( ; itr!=prevInPhi.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + mergedCell = (*cellItr); + break; + } + if(mergedCell!=NULL) break; + } + // store cells in the eta layer, which contains the seed cell + int nCellsFromSeed = 1; + const CaloCell* lastCell = seedCell; + cellVector.at(0).at(nCellsInEta/2) = seedCell; // store seed cell + std::vector<IdentifierHash> next; + while(lastCell!=NULL && nCellsFromSeed<nCellsInEta/2+1){ + calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::nextInEta,next); + lastCell = NULL; + for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){ + std::vector<IdentifierHash>::iterator itr = next.begin(); + for( ; itr!=next.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + cellVector.at(0).at(nCellsInEta/2+nCellsFromSeed) = (*cellItr); + lastCell = (*cellItr); + } + } + nCellsFromSeed++; + } + nCellsFromSeed = 1; + lastCell = seedCell; + while(lastCell!=NULL && nCellsFromSeed<nCellsInEta/2+1){ + calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::prevInEta,next); + lastCell = NULL; + for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){ + std::vector<IdentifierHash>::iterator itr = next.begin(); + for( ; itr!=next.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + cellVector.at(0).at(nCellsInEta/2-nCellsFromSeed) = (*cellItr); + lastCell = (*cellItr); + } + } + nCellsFromSeed++; + } + // store cells in the eta layer, which contains the merged cell + int nCellsFromMerged = 1; + lastCell = mergedCell; // is NULL if shot is not merged + cellVector.at(1).at(nCellsInEta/2) = mergedCell; // store merged cell + while(lastCell!=NULL && nCellsFromMerged<nCellsInEta/2+1){ + calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::nextInEta,next); + lastCell = NULL; + for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){ + std::vector<IdentifierHash>::iterator itr = next.begin(); + for( ; itr!=next.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + cellVector.at(1).at(nCellsInEta/2+nCellsFromMerged) = (*cellItr); + lastCell = (*cellItr); + } + } + nCellsFromMerged++; + } + nCellsFromMerged = 1; + lastCell = mergedCell; + while(lastCell!=NULL && nCellsFromMerged<nCellsInEta/2+1){ + calo_id->get_neighbours(lastCell->caloDDE()->calo_hash(),LArNeighbours::prevInEta,next); + lastCell = NULL; + for(cellItr=theCellLink->begin();cellItr!=cellItrE;++cellItr){ + std::vector<IdentifierHash>::iterator itr = next.begin(); + for( ; itr!=next.end(); ++itr ){ + if((*cellItr)->caloDDE()->calo_hash() != (*itr)) continue; + cellVector.at(1).at(nCellsInEta/2-nCellsFromMerged) = (*cellItr); + lastCell = (*cellItr); + } + } + nCellsFromMerged++; + } + return cellVector; + + } + + + float mean_eta(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + float sumEta=0.; + float sumWeight=0.; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + vector<const CaloCell*>::iterator itrEta = itrPhi->begin(); + for( ; itrEta!=itrPhi->end(); ++itrEta ){ + if((*itrEta) == NULL) continue; + sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta); + sumEta += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * (*itrEta)->eta(); + } + } + if(sumWeight<=0.) return -99999.; + return sumEta/sumWeight; + } + + float mean_pt(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + float sumPt=0.; + int nCells = 0; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + vector<const CaloCell*>::iterator itrEta = itrPhi->begin(); + for( ; itrEta!=itrPhi->end(); ++itrEta ){ + if((*itrEta) == NULL) continue; + sumPt += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta); + nCells ++; + } + } + if(nCells==0) return -99999.; + return sumPt/nCells; + } + + float ptWindow(vector<vector<const CaloCell*> > shotCells, int windowSize, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + // window size should be odd and noti be larger than eta window of shotCells + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + if( windowSize%2!=1 ) return 0.; + if( windowSize > nCells_eta) return 0.; + float ptWindow = 0.; + for(int iCell = 0; iCell != nCells_eta; ++iCell ){ + if(fabs(iCell-seedIndex)>windowSize/2) continue; + if(shotCells.at(0).at(iCell) != NULL) ptWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell) != NULL) ptWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + } + return ptWindow; + } + + float ws5(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + float sumWeight=0.; + float sumDev2=0.; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + for(unsigned iCell = 0; iCell != itrPhi->size(); ++iCell ){ + if(itrPhi->at(iCell) == NULL) continue; + sumWeight += itrPhi->at(iCell)->pt()*m_caloWeightTool->wtCell(itrPhi->at(iCell)); + sumDev2 += itrPhi->at(iCell)->pt()*m_caloWeightTool->wtCell(itrPhi->at(iCell)) * pow(iCell-seedIndex,2); + } + } + if(sumWeight<=0. || sumDev2 <0.) return -99999.; + return sqrt( sumDev2 / sumWeight ); + } + + float sdevEta_WRTmean(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + float mean = mean_eta(shotCells, m_caloWeightTool); + float sumWeight=0.; + float sumDev2=0.; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + vector<const CaloCell*>::iterator itrEta = itrPhi->begin(); + for( ; itrEta!=itrPhi->end(); ++itrEta ){ + if((*itrEta) == NULL) continue; + sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta); + sumDev2 += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * pow((*itrEta)->eta() - mean,2); + } + } + if(sumWeight<=0. || sumDev2 <0.) return -99999.; + return sqrt( sumDev2 / sumWeight ); + } + + float sdevEta_WRTmode(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + float mode = shotCells.at(0).at(seedIndex)->eta(); + float sumWeight=0.; + float sumDev2=0.; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + vector<const CaloCell*>::iterator itrEta = itrPhi->begin(); + for( ; itrEta!=itrPhi->end(); ++itrEta ){ + if((*itrEta) == NULL) continue; + sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta); + sumDev2 += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) * pow((*itrEta)->eta() - mode,2); + } + } + if(sumWeight<=0. || sumDev2 <0.) return -99999.; + return sqrt( sumDev2 / sumWeight ); + } + + float sdevPt(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + float mean = mean_pt(shotCells, m_caloWeightTool); + float sumWeight=0.; + float sumDev2=0.; + vector<vector<const CaloCell*> >::iterator itrPhi = shotCells.begin(); + for( ; itrPhi!=shotCells.end(); ++itrPhi ){ + vector<const CaloCell*>::iterator itrEta = itrPhi->begin(); + for( ; itrEta!=itrPhi->end(); ++itrEta ){ + if((*itrEta) == NULL) continue; + sumWeight += (*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta); + sumDev2 += pow((*itrEta)->pt()*m_caloWeightTool->wtCell(*itrEta) - mean,2); + } + } + if(sumWeight<=0. || sumDev2 <0.) return -99999.; + return sqrt(sumDev2)/sumWeight; + } + + float deltaPt12_min(vector<vector<const CaloCell*> > shotCells, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + bool haveLeft = false; + bool haveRight = false; + float deltaPt_left = 0.; + float deltaPt_right = 0.; + if(shotCells.at(0).at(seedIndex-1)!=NULL && shotCells.at(0).at(seedIndex-2)!=NULL){ + haveLeft = true; + deltaPt_left = shotCells.at(0).at(seedIndex-1)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex-1)) + -shotCells.at(0).at(seedIndex-2)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex-2)); + if(shotCells.at(1).at(seedIndex-1)!=NULL && shotCells.at(1).at(seedIndex-2)!=NULL){ + deltaPt_left += shotCells.at(1).at(seedIndex-1)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex-1)) + -shotCells.at(1).at(seedIndex-2)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex-2)); + } + } + if(shotCells.at(0).at(seedIndex+1)!=NULL && shotCells.at(0).at(seedIndex+2)!=NULL){ + haveRight = true; + deltaPt_right = shotCells.at(0).at(seedIndex+1)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex+1)) + -shotCells.at(0).at(seedIndex+2)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(seedIndex+2)); + if(shotCells.at(1).at(seedIndex+1)!=NULL && shotCells.at(1).at(seedIndex+2)!=NULL){ + deltaPt_right += shotCells.at(1).at(seedIndex+1)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex+1)) + -shotCells.at(1).at(seedIndex+2)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(seedIndex+1)); + } + } + if(haveLeft && haveRight) return fmin(deltaPt_left,deltaPt_right); + if(haveLeft) return deltaPt_left; + if(haveRight) return deltaPt_right; + else return -1.; + } + + + float Fside(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + // window sizes should be odd and windows should be not larger than eta window of shotCells + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.; + if( largerWindow <= smallerWindow) return 0.; + if( largerWindow > nCells_eta) return 0.; + float pt_largerWindow = 0.; + float pt_smallerWindow = 0.; + for(int iCell = 0; iCell != nCells_eta; ++iCell ){ + if(fabs(iCell-seedIndex)>largerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + if(fabs(iCell-seedIndex)>smallerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + } + if(pt_smallerWindow==0.) return -99999.; + return (pt_largerWindow-pt_smallerWindow)/pt_smallerWindow; + } + + float fracSide(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + // window sizes should be odd and windows should be not larger than eta window of shotCells + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.; + if( largerWindow <= smallerWindow) return 0.; + if( largerWindow > nCells_eta) return 0.; + float pt_largerWindow = 0.; + float pt_smallerWindow = 0.; + for(int iCell = 0; iCell != nCells_eta; ++iCell ){ + if(fabs(iCell-seedIndex)>largerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + if(fabs(iCell-seedIndex)>smallerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + } + if(pt_largerWindow==0.) return -99999.; + return (pt_largerWindow-pt_smallerWindow)/pt_largerWindow; + } + + float ptWindowFrac(vector<vector<const CaloCell*> > shotCells, int largerWindow, int smallerWindow, ToolHandle<IHadronicCalibrationTool>& m_caloWeightTool){ + // window sizes should be odd and windows should be not larger than eta window of shotCells + int nCells_eta = shotCells.at(0).size(); + int seedIndex = nCells_eta/2; + if( largerWindow%2!=1 || smallerWindow%2!=1) return 0.; + if( largerWindow <= smallerWindow) return 0.; + if( largerWindow > nCells_eta) return 0.; + float pt_largerWindow = 0.; + float pt_smallerWindow = 0.; + for(int iCell = 0; iCell != nCells_eta; ++iCell ){ + if(fabs(iCell-seedIndex)>largerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_largerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + if(fabs(iCell-seedIndex)>smallerWindow/2) continue; + if(shotCells.at(0).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(0).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(0).at(iCell)); + if(shotCells.at(1).at(iCell)!=NULL) pt_smallerWindow+=shotCells.at(1).at(iCell)->pt()*m_caloWeightTool->wtCell(shotCells.at(1).at(iCell)); + } + if(pt_largerWindow==0.) return -99999.; + return pt_smallerWindow/pt_largerWindow; + } +} + diff --git a/Reconstruction/tauRec/src/TauSubstructureVariables.cxx b/Reconstruction/tauRec/src/TauSubstructureVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..30dd7035112353b5a268a473424b6946234bb9be --- /dev/null +++ b/Reconstruction/tauRec/src/TauSubstructureVariables.cxx @@ -0,0 +1,352 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//********************************************************************// +// NAME: TauSubstructureVariables.cxx // +// PACKAGE: offline/Reconstruction/tauRec // +// AUTHORS: M. Trottier-McDonald // +// CREATED: January 11 2010 // +//********************************************************************// + +#include <algorithm> +#include <math.h> +#include <sstream> + +#include "GaudiKernel/Property.h" +#include "FourMomUtils/P4Helpers.h" + +#include "AnalysisUtils/AnalysisMisc.h" + +#include "xAODJet/Jet.h" +#include "xAODTau/TauJet.h" + +#include "tauRec/CaloClusterVariables.h" +#include "tauRec/TauSubstructureVariables.h" + +#include "tauRec/KineUtils.h" +#include "CaloUtils/CaloVertexedCluster.h" +//#include "CaloEvent/CaloVertexedCluster.h" + +using CLHEP::GeV; + +const double TauSubstructureVariables::DEFAULT = -1111.; + +//********************************** +// Constructor +//********************************** + +TauSubstructureVariables::TauSubstructureVariables( + const std::string& type, + const std::string& name, + const IInterface* parent) : + TauToolBase(type, name, parent), + m_maxPileUpCorrection(4 * GeV), + m_pileUpAlpha(1.0), + m_doVertexCorrection(false), //FF: don't do cell correction by default + m_inAODmode(false) { + declareInterface<TauToolBase > (this); + declareProperty("maxPileUpCorrection", m_maxPileUpCorrection); + declareProperty("pileUpAlpha", m_pileUpAlpha); + declareProperty("VertexCorrection", m_doVertexCorrection); + declareProperty("inAODmode", m_inAODmode); +} + + +//********************************** +// Destructor +//********************************** + +TauSubstructureVariables::~TauSubstructureVariables() { +} + + +//*********************************** +// Initialize method +//*********************************** + +StatusCode TauSubstructureVariables::initialize() { + return StatusCode::SUCCESS; +} + +StatusCode TauSubstructureVariables::eventInitialize(TauCandidateData * /*data*/) { + return StatusCode::SUCCESS; +} + + +//************************************ +// Execute method +//************************************ + +StatusCode TauSubstructureVariables::execute(TauCandidateData *data) { + // Getting our hands on the TauJet object + //---------------------------------------- + xAOD::TauJet* pTau = data->xAODTau; + + // Getting the jet seed + // By asking taujet instead of TauCandidateData->seed, we take advantage of the machinery already + // in place to retrieve a jet seed for track only candidates. + //------------------------------------------------------------------------------------------------ + const xAOD::Jet* taujetseed = (*pTau->jetLink()); + + //***************************************************** + // calculate some tau substructure variables + //***************************************************** + + CaloClusterVariables CaloClusterVariablesTool; + CaloClusterVariablesTool.setVertexCorrection(m_doVertexCorrection); + + bool isFilled = CaloClusterVariablesTool.update(pTau); + + if (!isFilled) { + if (!taujetseed) ATH_MSG_DEBUG("Taujet->jet() pointer is NULL: calo cluster variables will be set to -1111"); + else ATH_MSG_DEBUG("problem in calculating calo cluster variables -> will be set to -1111"); + + pTau->setDetail(xAOD::TauJetParameters::numCells , static_cast<int>(0) ); + pTau->setDetail(xAOD::TauJetParameters::numTopoClusters , static_cast<int>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::numEffTopoClusters , static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::topoInvMass, static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::effTopoInvMass, static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::topoMeanDeltaR, static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::effTopoMeanDeltaR, static_cast<float>(DEFAULT) ); + + } else { + // Getting the variables + //----------------------- + double TopoInvMass = CaloClusterVariablesTool.totalMass(); + double EffTopoInvMass = CaloClusterVariablesTool.effectiveMass(); + unsigned int NumTopoClusters = CaloClusterVariablesTool.numConstituents(); + double NumEffTopoClusters = CaloClusterVariablesTool.effectiveNumConstituents(); + double TopoMeanDeltaR = CaloClusterVariablesTool.averageRadius(); + double EffTopoMeanDeltaR = CaloClusterVariablesTool.averageEffectiveRadius(); + unsigned int Ncells = CaloClusterVariablesTool.numCells(); + + ATH_MSG_VERBOSE(" Substructure variables: "); + ATH_MSG_VERBOSE("-------------------------"); + ATH_MSG_VERBOSE(" TopoInvMass: " << TopoInvMass); + ATH_MSG_VERBOSE(" EffTopoInvMass: " << EffTopoInvMass); + ATH_MSG_VERBOSE(" NumTopoClusters: " << NumTopoClusters); + ATH_MSG_VERBOSE("NumEffTopoClusters: " << NumEffTopoClusters); + ATH_MSG_VERBOSE(" TopoMeanDeltaR: " << TopoMeanDeltaR); + ATH_MSG_VERBOSE(" EffTopoMeanDeltaR: " << EffTopoMeanDeltaR); + ATH_MSG_VERBOSE(" NumCells: " << Ncells); + + //Record the variables + //--------------------- + + if (!m_inAODmode) pTau->setDetail(xAOD::TauJetParameters::numCells , static_cast<int> (Ncells) ); + pTau->setDetail(xAOD::TauJetParameters::numTopoClusters , static_cast<int> (NumTopoClusters) ); + pTau->setDetail(xAOD::TauJetParameters::numEffTopoClusters , static_cast<float>(NumEffTopoClusters) ); + pTau->setDetail(xAOD::TauJetParameters::topoInvMass , static_cast<float>(TopoInvMass) ); + pTau->setDetail(xAOD::TauJetParameters::effTopoInvMass , static_cast<float>(EffTopoInvMass) ); + pTau->setDetail(xAOD::TauJetParameters::topoMeanDeltaR , static_cast<float>(TopoMeanDeltaR) ); + pTau->setDetail(xAOD::TauJetParameters::effTopoMeanDeltaR , static_cast<float>(EffTopoMeanDeltaR) ); + + } + + //***************************************************** + // calculate some new cluster based ID variables + //***************************************************** + + if (taujetseed == NULL) { + + // No jet seed? Warning! Fill variables with dummy values + //-------------------------------------------------------- + + ATH_MSG_DEBUG("Taujet->jet() pointer is NULL: substructure variables will be set to -1111"); + + pTau->setDetail(xAOD::TauJetParameters::lead2ClusterEOverAllClusterE, static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::lead3ClusterEOverAllClusterE, static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::caloIso , static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::caloIsoCorrected , static_cast<float>(DEFAULT) ); + pTau->setDetail(xAOD::TauJetParameters::dRmax , static_cast<float>(DEFAULT) ); + + return StatusCode::SUCCESS; + } + + // New cluster-based variables + float totalEnergy(0.); + float calo_iso(0.); + float dr(0.); + + unsigned int num_clusters(0); + const xAOD::CaloCluster* incluster; + std::vector<const xAOD::CaloCluster*> vClusters; + + // loop over all clusters of the jet seed + xAOD::JetConstituentVector jcv = taujetseed->getConstituents(); + xAOD::JetConstituentVector::const_iterator nav_it = jcv.begin(); + xAOD::JetConstituentVector::const_iterator nav_itE = jcv.end(); + for (; nav_it != nav_itE; ++nav_it) { + ++num_clusters; + + incluster = dynamic_cast<const xAOD::CaloCluster*>( (*nav_it)->rawConstituent() ); + if (!incluster) continue; + + // save all clusters of jet seed + vClusters.push_back(incluster); + + // calc total energy + totalEnergy += incluster->e(); + + //apply Vertex correction on a temporary + TLorentzVector tempclusvec; + if (m_doVertexCorrection && pTau->vertexLink()) + tempclusvec = xAOD::CaloVertexedCluster(*incluster, (*pTau->vertexLink())->position()).p4(); + else + tempclusvec = xAOD::CaloVertexedCluster(*incluster).p4(); + + dr = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(), tempclusvec.Eta(), tempclusvec.Phi()); + if (0.2 <= dr && dr < 0.4) { + calo_iso += tempclusvec.Et(); + } + } + + // now sort cluster by energy + AnalysisUtils::Sort::e(&vClusters); + + // determine energy sum of leading 2 and leading 3 clusters + float sum2LeadClusterE(0.); + float sum3LeadClusterE(0.); + std::vector<const xAOD::CaloCluster*>::const_iterator icluster(vClusters.begin()); + std::vector<const xAOD::CaloCluster*>::const_iterator icluster_end(vClusters.end()); + + for (; icluster != icluster_end && icluster != vClusters.begin() + 3; ++icluster) { + if (icluster < vClusters.begin() + 2) { + sum2LeadClusterE += (*icluster)->e(); + } + sum3LeadClusterE += (*icluster)->e(); + } + + //record variables + if (totalEnergy != 0) { + ATH_MSG_VERBOSE(" lead2ClusterEOverAllClusterE: " << sum2LeadClusterE / totalEnergy); + ATH_MSG_VERBOSE(" lead3ClusterEOverAllClusterE: " << sum3LeadClusterE / totalEnergy); + + pTau->setDetail(xAOD::TauJetParameters::lead2ClusterEOverAllClusterE, static_cast<float>(sum2LeadClusterE / totalEnergy) ); + pTau->setDetail(xAOD::TauJetParameters::lead3ClusterEOverAllClusterE, static_cast<float>(sum3LeadClusterE / totalEnergy) ); + } + + ATH_MSG_VERBOSE(" caloIso: " << calo_iso); + pTau->setDetail(xAOD::TauJetParameters::caloIso, static_cast<float>(calo_iso) ); + + + // calculate calorimeter energies in different layers + float PSSEnergy(0.); + float EMEnergy(0.); + float HADEnergy(0.); + icluster = vClusters.begin(); + for (; icluster != icluster_end; ++icluster) { + float clEnergy = (*icluster)->e(); + + //Calculate the fractions of energy in different calorimeter layers + const xAOD::CaloCluster *cl = *icluster; + float PreSampler = cl->eSample(CaloSampling::PreSamplerB) + cl->eSample(CaloSampling::PreSamplerE); + float EMLayer1 = cl->eSample(CaloSampling::EMB1) + cl->eSample(CaloSampling::EME1); + float EMLayer2 = cl->eSample(CaloSampling::EMB2) + cl->eSample(CaloSampling::EME2); + + float Energy = cl->rawE(); + float PSSF = Energy != 0 ? (PreSampler + EMLayer1) / Energy : 0; + float EM2F = Energy != 0 ? EMLayer2 / Energy : 0; + float EMF = PSSF + EM2F; + + PSSEnergy += PSSF * clEnergy; + EMEnergy += EMF * clEnergy; + HADEnergy += (Energy != 0) ? (1 - EMF) * clEnergy : 0; + } + + // calculate trk momentum + float trkSysMomentum(0.); + for (unsigned int i(0); i < pTau->nTracks(); ++i) { + trkSysMomentum += pTau->track(i)->pt() * cosh(pTau->track(i)->eta()); + } + + float fPSSFraction = (totalEnergy != 0) ? PSSEnergy / totalEnergy : DEFAULT; + float fChPIEMEOverCaloEME = (EMEnergy != 0) ? (trkSysMomentum - HADEnergy) / EMEnergy : DEFAULT; + float fEMPOverTrkSysP = DEFAULT; + if (pTau->nTracks() > 0) fEMPOverTrkSysP = (trkSysMomentum != 0) ? EMEnergy / trkSysMomentum : DEFAULT; + + pTau->setDetail(xAOD::TauJetParameters::PSSFraction, static_cast<float>(fPSSFraction)); + pTau->setDetail(xAOD::TauJetParameters::ChPiEMEOverCaloEME, static_cast<float>(fChPIEMEOverCaloEME)); + pTau->setDetail(xAOD::TauJetParameters::EMPOverTrkSysP, static_cast<float>(fEMPOverTrkSysP)); + + + // get primary vertex container + // CALO_ISO_CORRECTED + // JVF and PT_PILEUP + // 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 + + float jvf(0.0); + float sumPtTrk(0.0); + + // for tau trigger: JVF and sumPtTrack are not available + bool inTrigger = false; + StatusCode sc; + if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger); + + if (!sc.isSuccess() || !inTrigger) + { + std::vector<float> sumPtTrkvec; + std::vector<float> jvfvec; + + // ToDo still need to check if the 500MeV threshold is correct + taujetseed->getAttribute(xAOD::JetAttribute::SumPtTrkPt500, sumPtTrkvec); + taujetseed->getAttribute(xAOD::JetAttribute::JVF, jvfvec); + + 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 { + ATH_MSG_WARNING("jvf value vector and/or sumPtTrk vector returned from seed jet is empty!"); + } + } + + float pt_pileup = (1.0 - jvf) * sumPtTrk; + + const float max_pileup_correction = m_maxPileUpCorrection; + const float alpha = m_pileUpAlpha; + float pileup_correction = alpha * pt_pileup; + + ATH_MSG_VERBOSE(" --------------------------------------"); + ATH_MSG_VERBOSE(" Pile-up correction parameter"); + ATH_MSG_VERBOSE(" -> sumPtTrk: " << sumPtTrk); + ATH_MSG_VERBOSE(" -> jvf: " << jvf); + ATH_MSG_VERBOSE(" -> pt_pileup: " << pt_pileup); + ATH_MSG_VERBOSE(" -> alpha: " << alpha); + ATH_MSG_VERBOSE(" -> max pileup corr: " << max_pileup_correction); + + if (pileup_correction > max_pileup_correction) { + pileup_correction = max_pileup_correction; + } + const float calo_iso_corrected = calo_iso - pileup_correction; + + ATH_MSG_VERBOSE(" -> pileup corr: " << pileup_correction); + ATH_MSG_VERBOSE(" --------------------------------------"); + + //record variable + ATH_MSG_VERBOSE(" caloIsoCorrected: " << calo_iso_corrected); + pTau->setDetail(xAOD::TauJetParameters::caloIsoCorrected, static_cast<float>(calo_iso_corrected) ); + + // calculate dRMax + unsigned int numTrack(pTau->nTracks()); + if (numTrack > 0) { + float dRmin = -1 * -1111; + float dRmax = -1111; + float dR; + + for (unsigned int i(0); i < numTrack; ++i) { + if (pTau->track(i) == 0) continue; + dR = Tau1P3PKineUtils::deltaR( pTau->track(i)->eta(), pTau->track(i)->phi(), pTau->eta(), pTau->phi() ); + if (dRmin > dR) dRmin = dR; + if (dRmax < dR) dRmax = dR; + } + //record variable + ATH_MSG_VERBOSE(" dRmax: " << dRmax); + pTau->setDetail(xAOD::TauJetParameters::dRmax, static_cast<float>(dRmax) ); + } + + return StatusCode::SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauTestDump.cxx b/Reconstruction/tauRec/src/TauTestDump.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fd1748b3ec26318babb4b8509a56a091649ee1e7 --- /dev/null +++ b/Reconstruction/tauRec/src/TauTestDump.cxx @@ -0,0 +1,127 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTestDump.cxx +// package: Reconstruction/tauRec +// authors: Felix Friedrich +// date: 2012-11-05 +// +//----------------------------------------------------------------------------- + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" +#include "CLHEP/Vector/LorentzVector.h" +#include "Particle/TrackParticle.h" + + +#include "tauRec/TauCandidateData.h" +//#include "tauEvent/TauCommonDetails.h" +//#include "tauEvent/TauPi0Details.h" +//#include "tauEvent/TauPi0Cluster.h" +#include "xAODTau/TauJet.h" + +//#include "tauEvent/TauJetParameters.h" + +#include "tauRec/TauTestDump.h" + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauTestDump::TauTestDump(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauTestDump::~TauTestDump() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauTestDump::initialize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauTestDump::finalize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauTestDump::execute(TauCandidateData *data) { + + ATH_MSG_INFO("=== TAU TEST DUMP BEGIN ==================== "); + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + ATH_MSG_INFO("Tau recorded with: pt="<< pTau->pt() <<", eta=" <<pTau->eta()<<", phi="<<pTau->phi()); + float tfFlightPathSig; + float ipSigLeadTrk; + pTau->detail(xAOD::TauJetParameters::ipSigLeadTrk, ipSigLeadTrk); + pTau->detail(xAOD::TauJetParameters::trFlightPathSig,tfFlightPathSig ); + ATH_MSG_INFO(" numTrack="<<pTau->nTracks() << ", tfFlightPathSig=" << tfFlightPathSig <<", ipSigLeadTrk=" << ipSigLeadTrk ); + + //stop here + return StatusCode::SUCCESS; + + if (pTau->nTracks() != 1) { + // Bonn Pi0 calculated only for 1p taus --> leave test case + ATH_MSG_INFO("Bonn Pi0 calculated only for 1p taus --> leave test case"); + return StatusCode::SUCCESS; + } + + // Default PFO pi0 + ATH_MSG_INFO("dumping pi0 standard"); + if (pTau->nPi0_PFOs()>0) { + for (unsigned int i=0; i<pTau->nPi0_PFOs();++i) ATH_MSG_INFO(pTau->pi0_PFO(i)->e()<< " "); + } + else ATH_MSG_INFO("no pi0 cand"); + + // Cell-based PFO pi0 + ATH_MSG_INFO("dumping pi0 cell-based"); + if (pTau->nCellBased_Pi0_PFOs()>0) { + for (unsigned int i=0; i<pTau->nCellBased_Pi0_PFOs();++i) ATH_MSG_INFO(pTau->cellBased_Pi0_PFO(i)->e()<< " "); + } + else ATH_MSG_INFO("no pi0 cand"); + + // EFlow PF0 pi0 + ATH_MSG_INFO("dumping pi0 eflow"); + if (pTau->nEflowRec_Pi0_PFOs()>0) { + for (unsigned int i=0; i<pTau->nEflowRec_Pi0_PFOs();++i) ATH_MSG_INFO(pTau->eflowRec_Pi0_PFO(i)->e()<< " "); + } + else ATH_MSG_INFO("no pi0 cand"); + + ATH_MSG_INFO("end dumping pi0"); + + ATH_MSG_INFO("=== TAU TEST DUMP END ==================== "); + + return StatusCode::SUCCESS; +} + + diff --git a/Reconstruction/tauRec/src/TauToolBase.cxx b/Reconstruction/tauRec/src/TauToolBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8ce8a56656b38981bf7e09510a2508f85cf16e48 --- /dev/null +++ b/Reconstruction/tauRec/src/TauToolBase.cxx @@ -0,0 +1,111 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauBuilderHelper.cxx +// package: Reconstruction/tauEvent +// authors: Lukasz Janyst +// date: 2007-02-13 +// +// MODIFICATIONS +// 2008-04-22: (nicom) moved setObject()/getObject() to TauCandidateData +//----------------------------------------------------------------------------- + +#include "tauRec/TauToolBase.h" + +static const InterfaceID TauToolBaseID( "TauToolBase", 1, 0 ); + +const InterfaceID& TauToolBase::interfaceID() { + return TauToolBaseID; +} + + +//------------------------------------------------------------------------- +// Constructor +//------------------------------------------------------------------------- +TauToolBase :: TauToolBase( const std::string &type, + const std::string &name, + const IInterface *parent ): + AthAlgTool(type, name, parent) +{ +} + +//------------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------------- +TauToolBase :: ~TauToolBase() +{ +} + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- +StatusCode TauToolBase :: initialize() +{ + return StatusCode :: SUCCESS; +} + +//------------------------------------------------------------------------- +// Initializer +//------------------------------------------------------------------------- +StatusCode TauToolBase :: eventInitialize( TauCandidateData *) +{ + return StatusCode :: SUCCESS; +} + +//------------------------------------------------------------------------- +// Execute +//------------------------------------------------------------------------- +StatusCode TauToolBase :: execute( TauCandidateData * ) +{ + return StatusCode :: SUCCESS; +} + +//------------------------------------------------------------------------- +// Cleanup +//------------------------------------------------------------------------- +void TauToolBase :: cleanup( TauCandidateData * ) +{ +} + +//------------------------------------------------------------------------- +// Finalizer +//------------------------------------------------------------------------- +StatusCode TauToolBase :: eventFinalize( TauCandidateData * ) +{ + return StatusCode :: SUCCESS; +} + +//------------------------------------------------------------------------- +// Finalizer +//------------------------------------------------------------------------- +StatusCode TauToolBase :: finalize() +{ + return StatusCode :: SUCCESS; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Helpers +template <class T> +bool TauToolBase::openContainer(T* &container, std::string containerName, bool printFATAL) { + StatusCode sc = evtStore()->retrieve(container, containerName); + if (sc.isFailure() || !container) { + if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate"); + return 0; + } + return container; +} + +template <class T> +bool TauToolBase::retrieveTool(T & tool) { + if (tool.retrieve().isFailure()) { + ATH_MSG_FATAL("Failed to retrieve tool " << tool); + return false; + } else { + ATH_MSG_VERBOSE("Retrieved tool " << tool); + } + return true; +} + diff --git a/Reconstruction/tauRec/src/TauTrackFilter.cxx b/Reconstruction/tauRec/src/TauTrackFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..acf573be1b86830228ac233cd96bae928cd0f003 --- /dev/null +++ b/Reconstruction/tauRec/src/TauTrackFilter.cxx @@ -0,0 +1,359 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTrackFilter.cxx +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-04 +// +// +//----------------------------------------------------------------------------- + +#include <GaudiKernel/IToolSvc.h> +#include <GaudiKernel/ListItem.h> + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" + +#include "tauRec/TauCandidateData.h" + +#include "tauRec/TauTrackFilter.h" +#include "tauRec/TauTrackFilterUtils.h" + +#include "xAODTracking/TrackParticleContainer.h" + +#include "TLorentzVector.h" + +void TrackFilterAlg(TLorentzVector tau, + std::vector<TLorentzVector>* inputtracks20, + std::vector<int>* inputtracks20charge, + std::vector<TLorentzVector>* inputtracks40, + std::vector<int>* inputtracks40charge, + std::vector<TLorentzVector>* outputtracksgood, + std::vector<int>* outputtracksgoodcharge, + std::vector<TLorentzVector>* outputtracksbad, + std::vector<int>* outputtracksbadcharge, + int& nProng, + int& flag); + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauTrackFilter::TauTrackFilter(const std::string &type, + const std::string &name, + const IInterface *parent) : +TauToolBase(type, name, parent) { + declareInterface<TauToolBase > (this); + + declareProperty("TrackContainerName", m_trackContainerName = "InDetTrackParticles"); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauTrackFilter::~TauTrackFilter() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauTrackFilter::initialize() { + ATH_MSG_VERBOSE("TauTrackFilter Initialising"); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- + +StatusCode TauTrackFilter::finalize() { + ATH_MSG_VERBOSE("TauTrackFilter Finalizing"); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauTrackFilter::execute(TauCandidateData *data) { + ATH_MSG_VERBOSE("TauTrackFilter Executing"); + + xAOD::TauJet *pTau = data->xAODTau; + + StatusCode sc; + + const xAOD::TrackParticleContainer *trackContainer; + + //TODO: trigger uses getObject + sc = evtStore()->retrieve(trackContainer, m_trackContainerName); + if (sc.isFailure() || !trackContainer) { + ATH_MSG_DEBUG(" No track container found in TDS !!"); + return StatusCode::SUCCESS; + } + + TLorentzVector tau; + tau.SetPtEtaPhiE(pTau->pt(), + pTau->eta(), + pTau->phi(), + pTau->e()); + + std::vector<TLorentzVector>* inputtracks20 = new std::vector<TLorentzVector>; + std::vector<TLorentzVector>* inputtracks40 = new std::vector<TLorentzVector>; + std::vector<int>* inputtracks20charge = new std::vector<int>; + std::vector<int>* inputtracks40charge = new std::vector<int>; + std::vector<TLorentzVector>* outputtracksgood = new std::vector<TLorentzVector>; + std::vector<TLorentzVector>* outputtracksbad = new std::vector<TLorentzVector>; + std::vector<int>* outputtracksgoodcharge = new std::vector<int>; + std::vector<int>* outputtracksbadcharge = new std::vector<int>; + int nProng = 0; + int flag = 0; + + std::vector<unsigned int> inputtracks20index; + std::vector<unsigned int> inputtracks40index; + + m_TrkPass.clear(); + + for(unsigned int j=0; j<pTau->nTracks(); j++ ) { + const xAOD::TrackParticle *TauJetTrack = pTau->track(j); + TLorentzVector inputTrack; + inputTrack.SetPtEtaPhiE(TauJetTrack->pt(), + TauJetTrack->eta(), + TauJetTrack->phi(), + TauJetTrack->e()); // TODO Assume track has charged pion mass? + //TODO dR cut to put only correct tracks in inputtracks20 and inputtracks40 + float dR = tau.DeltaR(inputTrack); + if (dR < 0.2) { + inputtracks20->push_back(inputTrack); + inputtracks20charge->push_back(TauJetTrack->charge()); + inputtracks20index.push_back(j); + } + else if (dR < 0.4) { + inputtracks40->push_back(inputTrack); + inputtracks40charge->push_back(TauJetTrack->charge()); + inputtracks40index.push_back(j); + } + + // Add default status to track pass/fail member. + m_TrkPass.push_back(false); + } + + // Run the main algorithm + TrackFilterAlg(tau, + inputtracks20, + inputtracks20charge, + inputtracks40, + inputtracks40charge, + outputtracksgood, + outputtracksgoodcharge, + outputtracksbad, + outputtracksbadcharge, + nProng, + flag); + + // Store results + for (unsigned int j=0; j<outputtracksgood->size(); j++ ) { + for (unsigned int k=0; k<inputtracks20->size(); k++ ) { + if (outputtracksgood->at(j) == inputtracks20->at(k)) { + m_TrkPass.at(inputtracks20index.at(k)) = true; + } + } + for (unsigned int k=0; k<inputtracks40->size(); k++ ) { + if (outputtracksgood->at(j) == inputtracks40->at(k)) { + m_TrkPass.at(inputtracks40index.at(k)) = true; + } + } + } + m_nProng = nProng; + m_flag = flag; + + // Cleanup + delete inputtracks20; + delete inputtracks20charge; + delete inputtracks40; + delete inputtracks40charge; + delete outputtracksgood; + delete outputtracksbad; + delete outputtracksgoodcharge; + delete outputtracksbadcharge; + + // Set values in EDM + for (unsigned int numTrack=0; numTrack<m_TrkPass.size(); numTrack++) { + pTau->setTrackFilterPass(numTrack, m_TrkPass.at(numTrack)); + } + pTau->setTrackFilterProngs(m_nProng); + pTau->setTrackFilterQuality(m_flag); + + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Main algorithm +//----------------------------------------------------------------------------- +void TrackFilterAlg(TLorentzVector tau, + std::vector<TLorentzVector>* inputtracks20, + std::vector<int>* inputtracks20charge, + std::vector<TLorentzVector>* inputtracks40, + std::vector<int>* inputtracks40charge, + std::vector<TLorentzVector>* outputtracksgood, + std::vector<int>* outputtracksgoodcharge, + std::vector<TLorentzVector>* outputtracksbad, + std::vector<int>* outputtracksbadcharge, + int& nProng, + int& flag) { + + std::vector<TauTrackFilterUtils::TrackInfo> unsorted,tracks,SScombination; + TauTrackFilterUtils::TrackInfo track; + unsigned int tracknum = inputtracks20->size(); + unsigned int widetracknum = inputtracks40->size(); + for(unsigned int i=0;i<tracknum;i++){ + track.p4 = (*inputtracks20)[i]; + track.charge = (*inputtracks20charge)[i]; + unsorted.push_back(track); + } + while (unsorted.size() > 0){ + float trackP = unsorted[0].p4.P(); + int index = 0; + for(unsigned int i=1;i<unsorted.size();i++){ + if(unsorted[i].p4.P() > trackP){ + index = i; + trackP = unsorted[i].p4.P(); + } + } + tracks.push_back(unsorted[index]); + tracks[tracks.size()-1].index = tracks.size()-1; + unsorted.erase(unsorted.begin()+index); + } +//Step 2: Test 3 Prong Hypothesis +//Step 2a: Arrange combinations of tracks for testing + + bool test3prong = true, test2prong = true, test1prong = true; + for(unsigned int i=0;i<widetracknum;i++){ + outputtracksbad->push_back((*inputtracks40)[i]); + outputtracksbadcharge->push_back((*inputtracks40charge)[i]); + } + if(tracknum > 4){ //Anything with more than 4 tracks is a fake. + flag = 0; + test3prong = false; + test2prong = false; + test1prong = false; + } + if(tracknum < 3) test3prong = false; //Don't test 3 prong if fewer than 3 tracks + if(tracknum < 2) test2prong = false; //Don't test 2 prong if fewer than 2 tracks + if(tracknum < 1){ + flag = 0; + test1prong = false; //Don't test 1 prong if no tracks within dR < 0.2 of tau + } + if(test3prong){ + //Test 3 Highest pT Tracks + bool isSS = false; + std::vector<TauTrackFilterUtils::TrackInfo> combination; + int charge = 0; TLorentzVector threetrack; + for(unsigned int i=0;i<3;i++){ + combination.push_back(tracks[i]); //Only Care about 3 Highest pT Tracks + charge+=tracks[i].charge; + threetrack+=tracks[i].p4; + } + if((tracknum == 3) && (abs(charge)!=1)) isSS = true; //Reject all same-sign combinations +//Step 2b: Check kinematics of track combinations against shrinking cones and mass boundaries +// for(unsigned int i=0;i<combinations.size();i++){ + bool goodcombo = false; + if(tracknum == 4){ + char eqn[] = "pol2"; + float a[] = {1.51673, -0.000150534, 2.64226e-06}; + float mass99 = TauTrackFilterUtils::Compute1dim(tau.P(),a,3,eqn); + if((threetrack.M() < mass99)&&(TauTrackFilterUtils::pass3prong(combination,tau))){ + goodcombo=true; + flag = 2; + } + else flag = 0; + test1prong=false; + test2prong=false; + } + else if(TauTrackFilterUtils::pass3prong(combination, tau)){ + goodcombo=true; + flag = 1; + } + if(goodcombo){ //A Combination is found which passes 3prong hypothesis + for(unsigned int i=0;i<combination.size();i++){ + if (isSS) SScombination.push_back(combination[i]); + outputtracksgood->push_back(combination[i].p4); + outputtracksgoodcharge->push_back(combination[i].charge); + } + if(isSS) flag = 0; + else flag = 1; + nProng = 3; + test1prong = false; + test2prong = false; + if(!test1prong){ //Fill Bad Track in the Case of 4 trk taus + if(tracknum == 4){ + outputtracksbad->push_back(tracks[3].p4); + outputtracksbadcharge->push_back(tracks[3].charge); + } + } + } + }//End 3 Prong Test Conditional + if (test2prong){ + std::vector<TauTrackFilterUtils::TrackInfo> pair; + for(unsigned int i=0;i<2;i++) pair.push_back(tracks[i]); + if(TauTrackFilterUtils::pass2prong(pair,tau)){ + nProng = 2; + for(unsigned int i=0;i<pair.size();i++){ //Fill Good Tracks + outputtracksgood->push_back(pair[i].p4); + outputtracksgoodcharge->push_back(pair[i].charge); + } + test1prong = false; + if(tracknum == 3){ + flag = 2; + outputtracksbad->push_back(tracks[2].p4); //Fill Bad Track in Case of 3 trk Taus + outputtracksbadcharge->push_back(tracks[2].charge); + } + else flag = 1; //Good 2 Prong if only 2 trks + } + }//End 2 Prong Test Conditional +//Step 4: Check tracks that don't pass 2 prong hypothesis against 1 prong hypothesis + if (test1prong){ + char eqn[] = "([0]*exp([1]*x))*pol6(2)+[9]"; + float a[10]; + a[0] = 0.079586; + a[1] = -0.0289929; + a[2] = 7.06684; + a[3] = -0.158835; + a[4] = 0.000607181; + a[5] = 6.8445e-05; + a[6] = -6.79205e-07; + a[7] = 2.13158e-09; + a[8] = -5.11643e-13; + a[9] = 0.030376; + float ratio10 = TauTrackFilterUtils::Compute1dim(tau.P(),a,10,eqn); + bool goodcase = false; + if(tracknum == 1) goodcase = true; + if(tracknum == 2){ + if(tracks[1].p4.Pt()/tracks[0].p4.Pt() < ratio10) goodcase = true; //Test 2trk taus most likely to actually be 1pngs + } + if((TauTrackFilterUtils::pass1prong(tracks[0].p4,tau))&&(goodcase)){ //A track is found which passes 1prong hypothesis + outputtracksgood->push_back(tracks[0].p4); + outputtracksgoodcharge->push_back(tracks[0].charge); + nProng = 1; + if (tracknum == 2){ + flag = 2; + outputtracksbad->push_back(tracks[1].p4); //Fill Bad Track in Case of 3 trk Taus + outputtracksbadcharge->push_back(tracks[1].charge); + } + else flag = 1; + } + else flag = 0; //Fake Tau + }//End 1 Prong Test Conditional + + return; +} + diff --git a/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx b/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx new file mode 100644 index 0000000000000000000000000000000000000000..24a9d1ccac98e8bd4057fde6d066252133181a26 --- /dev/null +++ b/Reconstruction/tauRec/src/TauTrackFilterUtils.cxx @@ -0,0 +1,266 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTrackFilterUtils.cxx +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-13 +// +// +//----------------------------------------------------------------------------- + +#include "TF1.h" +#include "TLorentzVector.h" +#include "tauRec/TauTrackFilterUtils.h" +#include <vector> +#include <iostream> +#include <string> + +using namespace TauTrackFilterUtils; + +bool TauTrackFilterUtils::pass3prong(std::vector<TauTrackFilterUtils::TrackInfo> combination,TLorentzVector tau){ + + //Step 1: calculate angles + TauTrackFilterUtils::TrackPair lp, lm, sp, ls, ms, mp; + + lm.angle = fabs(combination[0].p4.Angle(combination[1].p4.Vect())); + lm.mass = (combination[0].p4+combination[1].p4).M(); + lm.charge = combination[0].charge*combination[1].charge; + ls.angle = fabs(combination[0].p4.Angle(combination[2].p4.Vect())); + ls.mass = (combination[0].p4+combination[2].p4).M(); + ls.charge = combination[0].charge*combination[2].charge; + ms.angle = fabs(combination[1].p4.Angle(combination[2].p4.Vect())); + ms.mass = (combination[1].p4+combination[2].p4).M(); + ms.charge = combination[1].charge*combination[2].charge; + + lp = lm; + if(ls.angle > lp.angle){ + mp = lp; + lp = ls; + } + else mp = ls; + if(ms.angle > lp.angle){ + sp = mp; + mp = lp; + lp = ms; + } + else if(ms.angle > mp.angle){ + sp = mp; + mp = ms; + } + else sp = ms; + + //if (lp.angle < mp.angle) ATH_MSG_WARNING("Largest angle is smaller than medium angle!"); + //if (lp.angle < sp.angle) ATH_MSG_WARNING("Largest angle is smaller than smallest angle!"); + //if (mp.angle < sp.angle) ATH_MSG_WARNING("Medium angle is smaller than smallest angle!"); + + //Step 3: calculate 99% angles + float lp99 = 0, sp99 = 0, lm99 = 0, ls99 = 0; + float p = tau.P(), eta = fabs(tau.Eta()); + + float a[9][4]; + int npar = 4, npol = 3; + +a[0][0] = 0.179041; a[1][0] = -0.0531058; a[2][0] = 0; +a[0][1] = -0.0146875; a[1][1] = 0.00414247; a[2][1] = -0.000612045; +a[0][2] = 0.0188939; a[1][2] = -0.00452375; a[2][2] = 0.00120015; +a[0][3] = 58.3066; a[1][3] = -48.2594; a[2][3] = 26.8864; + lp99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.0741985; a[1][0] = -0.0181941; a[2][0] = 0; +a[0][1] = -0.0149252; a[1][1] = 0.00512965; a[2][1] = -0.00125462; +a[0][2] = 0.00802004; a[1][2] = -0.00252272; a[2][2] = 0.000761022; +a[0][3] = 25.0145; a[1][3] = 0; a[2][3] = 0; + sp99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.102084; a[1][0] = -0.0256446; a[2][0] = 0; +a[0][1] = -0.014259; a[1][1] = 0.00465467; a[2][1] = -0.00122856; +a[0][2] = 0.010552; a[1][2] = -0.00176856; a[2][2] = 0.000446776; +a[0][3] = 36.0848; a[1][3] = -16.1489; a[2][3] = 10.2994; + lm99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.152783; a[1][0] = -0.0390978; a[2][0] = 0; +a[0][1] = -0.0139914; a[1][1] = 0.00352551; a[2][1] = -0.000624039; +a[0][2] = 0.0159925; a[1][2] = -0.00332104; a[2][2] = 0.00100568; +a[0][3] = 43.5804; a[1][3] = -18.681; a[2][3] = 6.29988; + ls99 = ComputeAngle(p,eta,a,npar,npol); + + //Step 4: compare angles and track masses, pass if all pass, fail otherwise + if((lp.angle > lp99)||(sp.angle > sp99)||(lm.angle > lm99)||(ls.angle > ls99)) return false; //One or more of the angles has failed - not a three prong tau + return true; //Track combination is a 3prong candidate! +} //End pass3prong (efficiency studies) + +bool TauTrackFilterUtils::pass2prong(std::vector<TauTrackFilterUtils::TrackInfo> pair,TLorentzVector tau){ + float angle = fabs(pair[0].p4.Angle(pair[1].p4.Vect())); + int charge = pair[0].charge*pair[1].charge; + + // Used to have more vars, but some were unused. + //float lt99 = 0, mt99 = 0, st99 = 0, ct99 = 0, lp99 = 0, mp99 = 0, sp99 = 0, los99 = 0, sos99 = 0, ss99 = 0, lm99 = 0, ls99 = 0, ms99 = 0; + float lp99 = 0, mp99 = 0, sp99 = 0, los99 = 0, sos99 = 0, ss99 = 0, lm99 = 0; + float p = tau.P(), eta = fabs(tau.Eta()); + + float a[9][4]; + int npar = 4, npol = 9; + + a[0][0] = 0.0584232; a[1][0] = -0.0177642; a[2][0] = 0; a[3][0] = 0; a[4][0] = 0; a[5][0] = 0; a[6][0] = 0; a[7][0] = 0; a[8][0] = 0; + a[0][1] = 0.0447435; a[1][1] = -0.659295; a[2][1] = 2.99202; a[3][1] = -6.10742; a[4][1] = 6.34017; a[5][1] = -3.49095; a[6][1] = 0.972228; a[7][1] = -0.107807; a[8][1] = 0; + a[0][2] = -0.249078; a[1][2] = 3.75779; a[2][2] = -18.9563; a[3][2] = 45.4474; a[4][2] = -59.333; a[5][2] = 44.722; a[6][2] = -19.4586; a[7][2] = 4.54039; a[8][2] = -0.4399; + a[0][3] = 124.481; a[1][3] = -1129.76; a[2][3] = 5198.92; a[3][3] = -10538.1; a[4][3] = 10741.4; a[5][3] = -5757; a[6][3] = 1548.86; a[7][3] = -164.644; a[8][3] = 0; + //lt99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.057286; a[1][0] = -0.0168061; a[2][0] = 0; a[3][0] = 0; a[4][0] = 0; a[5][0] = 0; a[6][0] = 0; a[7][0] = 0; a[8][0] = 0; +a[0][1] = 0.0640448; a[1][1] = -0.922493; a[2][1] = 4.10239; a[3][1] = -8.19704; a[4][1] = 8.35619; a[5][1] = -4.52961; a[6][1] = 1.24415; a[7][1] = -0.136244; a[8][1] = 0; +a[0][2] = -0.222389; a[1][2] = 3.34829; a[2][2] = -16.8256; a[3][2] = 40.1156; a[4][2] = -52.0129; a[5][2] = 38.9152; a[6][2] = -16.8076; a[7][2] = 3.89426; a[8][2] = -0.374831; +a[0][3] = 97.8443; a[1][3] = -804.025; a[2][3] = 3412.76; a[3][3] = -6058.05; a[4][3] = 5028.88; a[5][3] = -1940.87; a[6][3] = 281.19; a[7][3] = 0; a[8][3] = 0; + //ct99 = ComputeAngle(p,eta,a,npar,npol); + npol = 3; +a[0][0] = 0.0665222; a[1][0] = 0; a[2][0] = 0; +a[0][1] = -0.018755; a[1][1] = 0.00258183; a[2][1] = 0; +a[0][2] = 0.045607; a[1][2] = -0.0234824; a[2][2] = 0.00375319; +a[0][3] = 43.8011; a[1][3] = -10.0462; a[2][3] = 0; + //mt99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.156972; a[1][0] = -0.0333305; a[2][0] = 0; +a[0][1] = -0.0231364; a[1][1] = 0.0120482; a[2][1] = -0.00289192; +a[0][2] = 0.0490898; a[1][2] = -0.0273084; a[2][2] = 0.00547379; +a[0][3] = 33.1651; a[1][3] = 0; a[2][3] = 0; + //st99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.179041; a[1][0] = -0.0531058; a[2][0] = 0; +a[0][1] = -0.0146875; a[1][1] = 0.00414247; a[2][1] = -0.000612045; +a[0][2] = 0.0188939; a[1][2] = -0.00452375; a[2][2] = 0.00120015; +a[0][3] = 58.3066; a[1][3] = -48.2594; a[2][3] = 26.8864; + lp99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.142962; a[1][0] = -0.0397119; a[2][0] = 0; +a[0][1] = -0.014084; a[1][1] = 0.00437622; a[2][1] = -0.000992845; +a[0][2] = 0.0145659; a[1][2] = -0.00270987; a[2][2] = 0.00079432; +a[0][3] = 42.4831; a[1][3] = -25.893; a[2][3] = 13.6075; + mp99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.0741985; a[1][0] = -0.0181941; a[2][0] = 0; +a[0][1] = -0.0149252; a[1][1] = 0.00512965; a[2][1] = -0.00125462; +a[0][2] = 0.00802004; a[1][2] = -0.00252272; a[2][2] = 0.000761022; +a[0][3] = 25.0145; a[1][3] = 0; a[2][3] = 0; + sp99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.177021; a[1][0] = -0.0800858; a[2][0] = 0.017266; +a[0][1] = -0.0145132; a[1][1] = 0.00508756; a[2][1] = -0.00133994; +a[0][2] = 0.0174059; a[1][2] = -0.00407948; a[2][2] = 0.00130897; +a[0][3] = 59.5959; a[1][3] = -51.819; a[2][3] = 28.742; + los99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.126153; a[1][0] = -0.0504026; a[2][0] = 0.0100601; +a[0][1] = -0.01373; a[1][1] = 0.0040825; a[2][1] = -0.00103933; +a[0][2] = 0.0121626; a[1][2] = -0.00239224; a[2][2] = 0.000832398; +a[0][3] = 43.6455; a[1][3] = -34.4061; a[2][3] = 17.558; + sos99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.159394; a[1][0] = -0.0461081; a[2][0] = 0; +a[0][1] = -0.0148102; a[1][1] = 0.00429109; a[2][1] = -0.000670516; +a[0][2] = 0.0167114; a[1][2] = -0.00539364; a[2][2] = 0.00175181; +a[0][3] = 48.371; a[1][3] = -35.9336; a[2][3] = 19.3991; + ss99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.102084; a[1][0] = -0.0256446; a[2][0] = 0; +a[0][1] = -0.014259; a[1][1] = 0.00465467; a[2][1] = -0.00122856; +a[0][2] = 0.010552; a[1][2] = -0.00176856; a[2][2] = 0.000446776; +a[0][3] = 36.0848; a[1][3] = -16.1489; a[2][3] = 10.2994; + lm99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.152783; a[1][0] = -0.0390978; a[2][0] = 0; +a[0][1] = -0.0139914; a[1][1] = 0.00352551; a[2][1] = -0.000624039; +a[0][2] = 0.0159925; a[1][2] = -0.00332104; a[2][2] = 0.00100568; +a[0][3] = 43.5804; a[1][3] = -18.681; a[2][3] = 6.29988; + //ls99 = ComputeAngle(p,eta,a,npar,npol); +a[0][0] = 0.160615; a[1][0] = -0.0284831; a[2][0] = -0.00879631; +a[0][1] = -0.0140811; a[1][1] = 0.00344844; a[2][1] = -0.000421752; +a[0][2] = 0.0173056; a[1][2] = -0.00371573; a[2][2] = 0.00112158; +a[0][3] = 59.28; a[1][3] = -48.2821; a[2][3] = 26.3103; + //ms99 = ComputeAngle(p,eta,a,npar,npol); + + if ((angle < lm99)&&((angle < lp99)||(angle < mp99)||(angle < sp99))){ + if((charge == -1)&&((angle < los99)||(angle < sos99))) return true; + else if((charge == 1)&&(angle < ss99)) return true; + else return false; + } + else return false; +} //End pass2prong + +bool TauTrackFilterUtils::pass1prong(TLorentzVector track,TLorentzVector tau){ + //Step 1: Compute Angle Between Track and Tau + float angle = fabs(track.Angle(tau.Vect())); + //Step 2: Compute 99% angle + float p = tau.P(), eta = fabs(tau.Eta()); + + int npar = 4, npol = 3; + float a[3][4]; + + a[0][0] = 0.120777; a[1][0] = -0.0261681; a[2][0] = 0; + a[0][1] = -0.0307174; a[1][1] = 0.0170112; a[2][1] = -0.00381298; + a[0][2] = 0.0662689; a[1][2] = -0.0402811; a[2][2] = 0.00760013; + a[0][3] = 24.512; a[1][3] = 0; a[2][3] = 0; + float angle99 = ComputeAngle(p,eta,a,npar,npol); + + //Step 3: compare angles and return decision + if(angle > angle99) return false; //Track angle exceeds kinematic boundary + else return true; +} //End pass1prong + +float TauTrackFilterUtils::ComputePi0Cone(int recProngs,TLorentzVector tau){ + float angle = -1; + float atrue = 0, arec = 0; + float p = tau.P(), eta = fabs(tau.Eta()); + int npar = 4, npol = 9; + float a[9][4]; + switch(recProngs){ + case 3: //3 Prong Case + npol = 7; + a[0][0] = 0.0457602; a[1][0] = 1.80062; a[2][0] = -6.82921; a[3][0] = 10.8605; a[4][0] = -8.52901; a[5][0] = 3.24106; a[6][0] = -0.473647; + a[0][1] = -0.017874; a[1][1] = -0.0502181; a[2][1] = 0.162668; a[3][1] = -0.172266; a[4][1] = 0.0783324; a[5][1] = -0.013098; a[6][1] = 0; + a[0][2] = 0.0266511; a[1][2] = -0.013319; a[2][2] = 0.00289217; a[3][2] = 0; a[4][2] = 0; a[5][2] = 0; a[6][2] = 0; + a[0][3] = 237.828; a[1][3] = -2836.67; a[2][3] = 11074.1; a[3][3] = -18578.5; a[4][3] = 15086.9; a[5][3] = -5828.12; a[6][3] = 856.684; + atrue = ComputeAngle(p,eta,a,npar,npol); + npar = 3; + npol = 5; + a[0][0] = 0.178252; a[1][0] = 0.057474; a[2][0] = -0.256742; a[3][0] = 0.156772; a[4][0] = -0.0283407; + a[0][1] = -0.00950538; a[1][1] = 0.00363589; a[2][1] = -0.00157984; a[3][1] = 0; a[4][1] = 0; + a[0][2] = 0.0227538; a[1][2] = -0.0642722; a[2][2] = 0.121818; a[3][2] = -0.0679845; a[4][2] = 0.0115837; + arec = ComputeAngle(p,eta,a,npar,npol,(char*)"[0]*exp([1]*x)+[2]"); + break; + case 1: //1 Prong Case + npol = 6; + a[0][0] = 0.203158; a[1][0] = 0.269746; a[2][0] = -1.22961; a[3][0] = 1.41234; a[4][0] = -0.670384; a[5][0] = 0.114524; + a[0][1] = -0.0300622; a[1][1] = -0.0115786; a[2][1] = 0.07541; a[3][1] = -0.0782728; a[4][1] = 0.0334031; a[5][1] = -0.0052381; + a[0][2] = 0.0423083; a[1][2] = -0.0284378; a[2][2] = 0.0237394; a[3][2] = -0.0168315; a[4][2] = 0.0040657; a[5][2] = 0; + a[0][3] = 45.0612; a[1][3] = -458.353; a[2][3] = 1521.8; a[3][3] = -1895.88; a[4][3] = 1000.72; a[5][3] = -187.091; + atrue = ComputeAngle(p,eta,a,npar,npol); + a[0][0] = 0.168639; a[1][0] = -0.325194; a[2][0] = 1.4594; a[3][0] = -3.20592; a[4][0] = 3.50676; a[5][0] = -2.0571; a[6][0] = 0.621729; a[7][0] = -0.0758951; a[8][0] = 0; + a[0][1] = -0.0103477; a[1][1] = 0; a[2][1] = 0; a[3][1] = 0; a[4][1] = 0; a[5][1] = 0; a[6][1] = 0; a[7][1] = 0; a[8][1] = 0; + a[0][2] = 0.0325721; a[1][2] = -0.0496515; a[2][2] = 0.0773747; a[3][2] = -0.0396844; a[4][2] = 0.00615314; a[5][2] = 0; a[6][2] = 0; a[7][2] = 0; a[8][2] = 0; + arec = ComputeAngle(p,eta,a,npar,npol,(char*)"[0]*exp([1]*x)+[2]"); + break; + default: + //ATH_MSG_WARNING("Incorrect number of prongs!"); + return angle; + } + if (atrue > arec) angle = atrue; + else angle = arec; + return angle; +} //End ComputePi0Cone + +float TauTrackFilterUtils::ComputeAngle(float p, float eta, float a[9][4], int npar, int npol, char eqn[]){ + char name[10]; + char poleqn[10]; + + //TF1* etacoeff[npar]; //FIXME variable length array, use something like: = new TF1[npar]; + std::vector<TF1> etacoeff; + TF1* pcone = new TF1("pcone",eqn); + for(int i=0;i<npar;i++){ + sprintf(name,"p%i",i); + sprintf(poleqn,"pol%i",npol); + etacoeff.push_back(TF1(name,poleqn)); + for(int j=0;j<npol;j++) etacoeff.at(i).SetParameter(j,a[j][i]); + pcone->SetParameter(i,etacoeff.at(i).Eval(eta)); + } + float angle = pcone->Eval(p); + delete pcone; + return angle; +} + +float TauTrackFilterUtils::Compute1dim(float p, float a[10], int npar, char eqn[]){ + TF1* pcone = new TF1("pcone",eqn); + for(int i=0;i<npar;i++) pcone->SetParameter(i,a[i]); + float angle = pcone->Eval(p); + delete pcone; + return angle; +} diff --git a/Reconstruction/tauRec/src/TauTrackFinder.cxx b/Reconstruction/tauRec/src/TauTrackFinder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c022555997ee5391d38fea2f63dda16f2db69672 --- /dev/null +++ b/Reconstruction/tauRec/src/TauTrackFinder.cxx @@ -0,0 +1,607 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "RecoToolInterfaces/IExtrapolateToCaloTool.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" + +#include "xAODTau/TauJet.h" +#include "xAODTau/TauJetContainer.h" + +#include "tauRec/TauTrackFinder.h" +#include "tauRec/KineUtils.h" +#include "tauRec/TrackSort.h" + + +TauTrackFinder::TauTrackFinder(const std::string& type, + const std::string& name, + const IInterface* parent) : + TauToolBase(type, name, parent), + m_trackToCalo(""), + m_trackSelectorTool_tau(""), + m_trackToVertexTool("Reco::TrackToVertex"), + m_z0maxDelta(1000), + m_applyZ0cut(false), + m_storeInOtherTrks(true) +{ + declareInterface<TauToolBase > (this); + declareProperty("MaxJetDrTau", m_maxJetDr_tau = 0.2); + declareProperty("MaxJetDrWide", m_maxJetDr_wide = 0.4); + declareProperty("TrackSelectorToolTau", m_trackSelectorTool_tau); + declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles"); + declareProperty("TTCExtrapolator", m_trackToCalo, "public track extrapolator tool to match track with caloseed"); + declareProperty("TrackToVertexTool",m_trackToVertexTool); + declareProperty("maxDeltaZ0wrtLeadTrk", m_z0maxDelta); + declareProperty("removeTracksOutsideZ0wrtLeadTrk", m_applyZ0cut); + declareProperty("StoreRemovedCoreWideTracksInOtherTracks", m_storeInOtherTrks = true); +} + +TauTrackFinder::~TauTrackFinder() { +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::initialize() { + + // Get the TrackSelectorTool + if (!retrieveTool(m_trackSelectorTool_tau)) return StatusCode::FAILURE; + + // Get the TJVA + if (!retrieveTool(m_trackToVertexTool)) return StatusCode::FAILURE; + if (!retrieveTool(m_trackToCalo)) return StatusCode::FAILURE; + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::finalize() { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::eventInitialize(TauCandidateData*) { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::eventFinalize(TauCandidateData*) { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::execute(TauCandidateData * data) { + + ATH_MSG_VERBOSE("TauTrackFinder Executing"); + + xAOD::TauJet *pTau = data->xAODTau; + + StatusCode sc; + // get the track particle container from StoreGate + const xAOD::TrackParticleContainer* trackParticleCont = 0; + + //for tau trigger + bool inTrigger = false; + if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger); + if (sc.isSuccess() && inTrigger) sc = data->getObject( "TrackContainer", trackParticleCont ); + + if( !inTrigger || !trackParticleCont || sc.isFailure() ) { + // try standard + if (!openContainer(trackParticleCont, m_inputTrackParticleContainerName)) { + if (!inTrigger) return StatusCode::FAILURE; // in offline we don't reconstruct tau candidates without having a track container + else return StatusCode::SUCCESS; // we don't want stop trigger if there is no track container + } + } + + std::vector<const xAOD::TrackParticle*> tauTracks; + std::vector<const xAOD::TrackParticle*> wideTracks; + std::vector<const xAOD::TrackParticle*> otherTracks; + + const xAOD::Vertex* pVertex = pTau->vertexLink()!=0 ? (*pTau->vertexLink()) : NULL; + // retrieve tracks wrt a vertex + // as a vertex is used: tau origin / PV / beamspot / 0,0,0 (in this order, depending on availability) + getTauTracksFromPV(pTau, trackParticleCont, pVertex, tauTracks, wideTracks, otherTracks); + + + this->resetDeltaZ0Cache(); + // remove core and wide tracks outside a maximal delta z0 wrt lead core track + if (m_applyZ0cut) { + this->removeOffsideTracksWrtLeadTrk(tauTracks, wideTracks, otherTracks, pVertex, m_z0maxDelta); + } + + //clear tracks first (needed for "rerun mode" if called on AODs again) + pTau->clearTrackLinks(); + pTau->clearWideTrackLinks(); + pTau->clearOtherTrackLinks(); + + bool alreadyUsed = false; + //check for tracks used in multiple taus + for (std::vector<const xAOD::TrackParticle*>::iterator track_it = tauTracks.begin(); track_it != tauTracks.end() ;) + { + alreadyUsed = false; + + //loop over all up-to-now reconstructed tau candidates + xAOD::TauJetContainer::const_iterator tau_it = data->xAODTauContainer->begin(); + xAOD::TauJetContainer::const_iterator tau_end = data->xAODTauContainer->end(); + for( ; tau_it != tau_end; tau_it++ ) + { + //loop over core tracks + for (unsigned int j = 0; j < (*tau_it)->nTracks(); ++j) + { + if ((*track_it) == (*tau_it)->track(j)) + { + ATH_MSG_WARNING("Found a track that is identical with a track already associated to another tau. Will not add this track to more than one tau candidate"); + alreadyUsed = true; + } + } + } + + //if this track has already been used by another tau, don't associate it to this new one + if (alreadyUsed) track_it = tauTracks.erase(track_it); + else ++track_it; + } + + + // associated track to tau candidate and calculate charge + float charge = 0; + for (unsigned int i = 0; i < tauTracks.size(); ++i) { + const xAOD::TrackParticle* trackParticle = tauTracks.at(i); + + ATH_MSG_VERBOSE(name() << " adding core track nr: " << i + << " eta " << trackParticle->eta() + << " phi " << trackParticle->phi() + ); + charge += trackParticle->charge(); + ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle; + linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle); + pTau->addTrackLink(linkToTrackParticle); + ATH_MSG_VERBOSE(name() << " added core track nr: " << i + << " eta " << pTau->track(i)->eta() + << " phi " << pTau->track(i)->phi() + ); + } + // set the charge, which is defined by the core tau tracks only + pTau->setCharge(charge); + + /// FIXME hide the logic to create element links inside xAODTau + /// was + // for (unsigned int i = 0; i < wideTracks.size(); ++i) + // details->addSeedCalo_wideTrk(trackParticleCont, wideTracks.at(i)); + for (unsigned int i = 0; i < wideTracks.size(); ++i) { + const xAOD::TrackParticle* trackParticle = wideTracks.at(i); + + ATH_MSG_VERBOSE(name() << " adding wide track nr: " << i + << " eta " << trackParticle->eta() + << " phi " << trackParticle->phi() + ); + ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle; + linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle); + pTau->addWideTrackLink(linkToTrackParticle); + ATH_MSG_VERBOSE(name() << " added wide track nr: " << i + << " eta " << pTau->wideTrack(i)->eta() + << " phi " << pTau->wideTrack(i)->phi() + ); + } + + /// was + // for (unsigned int i = 0; i < otherTracks.size(); ++i) + // details->addOtherTrk(trackParticleCont, otherTracks.at(i)); + for (unsigned int i = 0; i < otherTracks.size(); ++i) { + const xAOD::TrackParticle* trackParticle = otherTracks.at(i); + + ATH_MSG_VERBOSE(name() << " adding other track nr: " << i + << " eta " << trackParticle->eta() + << " phi " << trackParticle->phi() + ); + ElementLink<xAOD::TrackParticleContainer> linkToTrackParticle; + linkToTrackParticle.toContainedElement(*trackParticleCont, trackParticle); + pTau->addOtherTrackLink(linkToTrackParticle); + ATH_MSG_VERBOSE(name() << " added other track nr: " << i + << " eta " << pTau->otherTrack(i)->eta() + << " phi " << pTau->otherTrack(i)->phi() + ); + } + + + ATH_MSG_DEBUG("numTrack: " << "/" << pTau->nTracks()); + ATH_MSG_DEBUG("charge: " << "/" << pTau->charge()); + + // extrapolate core tracks to calorimeter surface + // store information only in ExtraDetailsContainer + sc = extrapolateToCaloSurface(data); + if (sc.isFailure() && !sc.isRecoverable()) { + ATH_MSG_ERROR("couldn't extrapolate tracks to calo surface"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +TauTrackFinder::TauTrackType TauTrackFinder::tauTrackType( const xAOD::TauJet* pTau, + const xAOD::TrackParticle* trackParticle, + const xAOD::Vertex* primaryVertex) +{ + //ATH_MSG_VERBOSE("tau axis:" << pTau->hlv().perp()<< " " << pTau->hlv().eta() << " " << pTau->hlv().phi() << " " << pTau->hlv().e() ); + double dR = Tau1P3PKineUtils::deltaR(pTau->eta(),pTau->phi(),trackParticle->eta(),trackParticle->phi()); + + if (dR > m_maxJetDr_wide) return NotTauTrack; + + if (m_trackSelectorTool_tau->decision(*trackParticle, primaryVertex)) { + if (dR > m_maxJetDr_tau) + return TauTrackWide; + else + return TauTrackCore; + } else + return TauTrackOther; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void TauTrackFinder::getTauTracksFromPV( const xAOD::TauJet* pTau, + const xAOD::TrackParticleContainer* trackParticleCont, + const xAOD::Vertex* primaryVertex, + std::vector<const xAOD::TrackParticle*> &tauTracks, + std::vector<const xAOD::TrackParticle*> &wideTracks, + std::vector<const xAOD::TrackParticle*> &otherTracks) +{ + for (xAOD::TrackParticleContainer::const_iterator tpcItr = trackParticleCont->begin(); tpcItr != trackParticleCont->end(); ++tpcItr) { + const xAOD::TrackParticle *trackParticle = *tpcItr; + + TauTrackType type = tauTrackType(pTau, trackParticle, primaryVertex); + + if (type == TauTrackCore) + tauTracks.push_back(trackParticle); + else if (type == TauTrackWide) + wideTracks.push_back(trackParticle); + else if (type == TauTrackOther) + otherTracks.push_back(trackParticle); + + } + std::sort(tauTracks.begin(), tauTracks.end(), TrackSort()); + std::sort(wideTracks.begin(), wideTracks.end(), TrackSort()); + std::sort(otherTracks.begin(), otherTracks.end(), TrackSort()); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauTrackFinder::extrapolateToCaloSurface(TauCandidateData *data) { + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + const int numOfsampEM = 4; + + for (unsigned int itr = 0; itr < 10 && itr < pTau->nTracks(); ++itr) { + + const xAOD::TrackParticle *orgTrack = pTau->track(itr); + + //--------------------------------------------------------------------- + // Extrapolate to all layers + //--------------------------------------------------------------------- + const DataVector< const Trk::TrackParameters >* pTrk = m_trackToCalo->getParametersInCalo(*orgTrack, Trk::pion, Trk::alongMomentum); //FIXME + + //--------------------------------------------------------------------- + // Calculate eta, phi impact point at calorimeter layers EM 0,1,2,3 + //--------------------------------------------------------------------- + double eta_extrapol[4]; + double phi_extrapol[4]; + + for (int i = 0; i < numOfsampEM; ++i) { + eta_extrapol[i] = -11111.; + phi_extrapol[i] = -11111.; + } + + // XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet + // if (pTrk && (*pTrk)[IExtrapolateToCaloTool::PreSampler]) { + // eta_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().eta(); + // phi_extrapol[0] = (*pTrk)[IExtrapolateToCaloTool::PreSampler]->position().phi(); + // } + + if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Strips]) { + eta_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta(); + phi_extrapol[1] = (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi(); + + if (msgLvl(MSG::VERBOSE)) + { //only if desired msg level is requested + ATH_MSG_VERBOSE(name() << " extrapolation in strip layer : " + << " track nr " << itr + << " impact point eta " << eta_extrapol[1] + << " impact point phi " << phi_extrapol[1] + ); + } + + pTau->setTrackEtaStrip( itr, (*pTrk)[IExtrapolateToCaloTool::Strips]->position().eta() ); + pTau->setTrackPhiStrip( itr, (*pTrk)[IExtrapolateToCaloTool::Strips]->position().phi() ); + + if (msgLvl(MSG::VERBOSE)) + { //only if desired msg level is requested + ATH_MSG_VERBOSE(name() << " extrapolation in strip layer stored in tau : " + << " track nr " << itr + << " impact point eta " << pTau->trackEtaStrip(itr) + << " impact point phi " << pTau->trackPhiStrip(itr) + ); + } + + } + + // XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet + // if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Middle]) { + // eta_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().eta(); + // phi_extrapol[2] = (*pTrk)[IExtrapolateToCaloTool::Middle]->position().phi(); + // } + + // if (pTrk && (*pTrk)[IExtrapolateToCaloTool::Back]) { + // eta_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().eta(); + // phi_extrapol[3] = (*pTrk)[IExtrapolateToCaloTool::Back]->position().phi(); + // } + + + // for (int i = 0; i < numOfsampEM; ++i) { + // pExtraDetails->etaLooseTrkCaloSamp()[itr][i] = eta_extrapol[i]; + // pExtraDetails->phiLooseTrkCaloSamp()[itr][i] = phi_extrapol[i]; + // } + + // // in the past this was filled by tau1P3PTrackMatchCalo + // for (int i = 0; i < numOfsampEM; ++i) { + // pExtraDetails->etaTrkCaloSamp()[itr][i] = eta_extrapol[i]; + // pExtraDetails->phiTrkCaloSamp()[itr][i] = phi_extrapol[i]; + // } + + if (pTrk) delete pTrk; + + // XXX commenting this out as long as it's not clear whether these variables will be stored in xAOD::TauJet + // if (msgLvl(MSG::VERBOSE)) { //only if desired msg level is requested + // for (int i = 0; i < numOfsampEM; ++i) { + // ATH_MSG_VERBOSE(name() << " extrapolation for loose trk in samp : " << i + // << " track nr " << itr + // << " impact point eta " << pExtraDetails->etaLooseTrkCaloSamp()[itr][i] + // << " impact point phi " << pExtraDetails->phiLooseTrkCaloSamp()[itr][i] + // ); + // ATH_MSG_VERBOSE(name() << " extrapolation in samp : " << i + // << " track nr " << itr + // << " impact point eta " << pExtraDetails->etaTrkCaloSamp()[itr][i] + // << " impact point phi " << pExtraDetails->phiTrkCaloSamp()[itr][i] + // ); + // } + // } + + } + + return StatusCode::SUCCESS; + +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void TauTrackFinder::removeOffsideTracksWrtLeadTrk(std::vector<const Rec::TrackParticle*> &tauTracks, + std::vector<const Rec::TrackParticle*> &wideTracks, + std::vector<const Rec::TrackParticle*> &otherTracks, + const Trk::RecVertex* tauOrigin, + double maxDeltaZ0) +{ + float MAX=1e5; + this->resetDeltaZ0Cache(); + + // need at least one core track to have a leading trk to compare with + if (tauTracks.size()<1) return; + + //check if position is available for origin + /** FIXME: This causes compilation error after eigen migration + if (tauOrigin) + if (!tauOrigin->position()) + tauOrigin = 0; + */ + + // get lead trk parameters + const Rec::TrackParticle *leadTrack = tauTracks.at(0); + float z0_leadTrk = getZ0(leadTrack, tauOrigin); + + if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing + + ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size()); + + std::vector<const Rec::TrackParticle*>::iterator itr; + + // check core tracks + // skip leading track, because it is the reference + itr = tauTracks.begin()+1; + while (itr!=tauTracks.end()) { + float z0 = getZ0(*itr, tauOrigin); + float deltaZ0=z0 - z0_leadTrk; + + ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0); + m_vDeltaZ0coreTrks.push_back(deltaZ0); + + if ( fabs(deltaZ0) < maxDeltaZ0 ) {++itr;} + else { + if (m_storeInOtherTrks) otherTracks.push_back(*itr); + itr = tauTracks.erase(itr); //remove from core track collection + } + } + + // check wide tracks + itr = wideTracks.begin(); + while (itr!=wideTracks.end()) { + float z0 = getZ0(*itr, tauOrigin); + float deltaZ0=z0 - z0_leadTrk; + + ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0); + m_vDeltaZ0wideTrks.push_back(deltaZ0); + + if ( fabs(deltaZ0) < maxDeltaZ0 ) { ++itr; } + else { + if (m_storeInOtherTrks) otherTracks.push_back(*itr); + itr = wideTracks.erase(itr); //remove from wide track collection + } + } + + ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size()); + + // sort again + std::sort(tauTracks.begin(), tauTracks.end(), TrackSort()); + std::sort(wideTracks.begin(), wideTracks.end(), TrackSort()); + std::sort(otherTracks.begin(), otherTracks.end(), TrackSort()); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void TauTrackFinder::removeOffsideTracksWrtLeadTrk(std::vector<const xAOD::TrackParticle*> &tauTracks, + std::vector<const xAOD::TrackParticle*> &wideTracks, + std::vector<const xAOD::TrackParticle*> &otherTracks, + const xAOD::Vertex* tauOrigin, + double maxDeltaZ0) +{ + float MAX=1e5; + this->resetDeltaZ0Cache(); + + // need at least one core track to have a leading trk to compare with + if (tauTracks.size()<1) return; + + //check if position is available for origin + /** FIXME: This causes compilation error after eigen migration + if (tauOrigin) + if (!tauOrigin->position()) + tauOrigin = 0; + */ + + // get lead trk parameters + const xAOD::TrackParticle *leadTrack = tauTracks.at(0); + float z0_leadTrk = getZ0(leadTrack, tauOrigin); + + if (z0_leadTrk > MAX-1) return; // bad lead trk -> do nothing + + ATH_MSG_VERBOSE("before z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size()); + + std::vector<const xAOD::TrackParticle*>::iterator itr; + + // check core tracks + // skip leading track, because it is the reference + itr = tauTracks.begin()+1; + while (itr!=tauTracks.end()) { + float z0 = getZ0(*itr, tauOrigin); + float deltaZ0=z0 - z0_leadTrk; + + ATH_MSG_VERBOSE("core Trks: deltaZ0= " << deltaZ0); + m_vDeltaZ0coreTrks.push_back(deltaZ0); + + if ( fabs(deltaZ0) < maxDeltaZ0 ) {++itr;} + else { + if (m_storeInOtherTrks) otherTracks.push_back(*itr); + itr = tauTracks.erase(itr); //remove from core track collection + } + } + + // check wide tracks + itr = wideTracks.begin(); + while (itr!=wideTracks.end()) { + float z0 = getZ0(*itr, tauOrigin); + float deltaZ0=z0 - z0_leadTrk; + + ATH_MSG_VERBOSE("wide Trks: deltaZ0= " << deltaZ0); + m_vDeltaZ0wideTrks.push_back(deltaZ0); + + if ( fabs(deltaZ0) < maxDeltaZ0 ) { ++itr; } + else { + if (m_storeInOtherTrks) otherTracks.push_back(*itr); + itr = wideTracks.erase(itr); //remove from wide track collection + } + } + + ATH_MSG_VERBOSE("after z0 cut: #coreTracks=" << tauTracks.size() << ", #wideTracks=" << wideTracks.size() << ", #otherTracks=" << otherTracks.size()); + + // sort again + std::sort(tauTracks.begin(), tauTracks.end(), TrackSort()); + std::sort(wideTracks.begin(), wideTracks.end(), TrackSort()); + std::sort(otherTracks.begin(), otherTracks.end(), TrackSort()); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +float TauTrackFinder::getZ0(const Rec::TrackParticle* track, const Trk::RecVertex* vertex) +{ + float MAX=1e5; + + if (!track) return MAX; + if (!track->measuredPerigee()->covariance()) { + ATH_MSG_WARNING("Bad track; can't find perigee at vertex."); + return MAX; + } + + const Trk::Perigee* perigee = 0; + if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(*track, vertex->position()); + else perigee = m_trackToVertexTool->perigeeAtVertex(*track); //will use beamspot or 0,0,0 instead + + if (!perigee) { + ATH_MSG_WARNING("Bad track; can't find perigee at vertex."); + return MAX; + } + + float z0 = perigee->parameters()[Trk::z0]; + + delete perigee; //cleanup necessary to prevent mem leak + + return z0; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +float TauTrackFinder::getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex) +{ + float MAX=1e5; + + if (!track) return MAX; + + const Trk::Perigee* perigee = 0; + if (vertex) perigee = m_trackToVertexTool->perigeeAtVertex(*track, vertex->position()); + else perigee = m_trackToVertexTool->perigeeAtVertex(*track); //will use beamspot or 0,0,0 instead + + if (!perigee) { + ATH_MSG_WARNING("Bad track; can't find perigee at vertex."); + return MAX; + } + + float z0 = perigee->parameters()[Trk::z0]; + + delete perigee; //cleanup necessary to prevent mem leak + + return z0; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void TauTrackFinder::getDeltaZ0Values(std::vector<float>& vDeltaZ0coreTrks, std::vector<float>& vDeltaZ0wideTrks) +{ + vDeltaZ0coreTrks.clear(); + vDeltaZ0coreTrks = m_vDeltaZ0coreTrks; + + vDeltaZ0wideTrks.clear(); + vDeltaZ0wideTrks = m_vDeltaZ0wideTrks; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void TauTrackFinder::resetDeltaZ0Cache() +{ + m_vDeltaZ0coreTrks.clear(); + m_vDeltaZ0wideTrks.clear(); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Helpers +template <class T> +bool TauTrackFinder::openContainer(T* &container, std::string containerName, bool printFATAL) { + StatusCode sc = evtStore()->retrieve(container, containerName); + if (sc.isFailure() || !container) { + if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate"); + return 0; + } + return container; +} + +template <class T> +bool TauTrackFinder::retrieveTool(T & tool) { + if (tool.retrieve().isFailure()) { + ATH_MSG_FATAL("Failed to retrieve tool " << tool); + return false; + } else { + ATH_MSG_VERBOSE("Retrieved tool " << tool); + } + return true; +} diff --git a/Reconstruction/tauRec/src/TauTrackSlimmer.cxx b/Reconstruction/tauRec/src/TauTrackSlimmer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5ae7b16855724ac3eb8e7a9e86f32af8c8010183 --- /dev/null +++ b/Reconstruction/tauRec/src/TauTrackSlimmer.cxx @@ -0,0 +1,177 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTrackSlimmer.cxx +// package: Reconstruction/tauRec +// authors: Anna Kaczmarska, Lukasz Janyst +// +// This class builds Slim Track objects for taus in the AOD +// +// date: 2008-01-17 +// 15/04/2008 - (AK) fixing compilation warning bug #35463 +// 25/02/2009 - (AK) adding declareProperty thinSvc +// 22/01/2010 - (AK) adding protection against size 0 track collection +//----------------------------------------------------------------------------- + +#include "tauRec/TauTrackSlimmer.h" + +#include "tauEvent/TauJetContainer.h" +#include "tauEvent/TauJet.h" +#include "tauEvent/TauCommonDetails.h" + +#include "GaudiKernel/ListItem.h" +#include <cmath> + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +TauTrackSlimmer::TauTrackSlimmer( const std::string &name, + ISvcLocator * pSvcLocator ) : + AthAlgorithm( name, pSvcLocator ), + m_thinningSvc( "ThinningSvc", name ), + m_filterTaus(false), + m_maxNTrack(4), + m_maxCharge(2), + m_maxEmRadius(0.2), + m_maxIsoFrac(0.5) +{ + // Name of the thinningSvc + declareProperty( "thinSvc", m_thinningSvc, "Name of the thinningSvc" ); + declareProperty( "TauContainer", m_tauContainerName ); + declareProperty( "FilterTaus", m_filterTaus ); + declareProperty( "maxNTrack", m_maxNTrack ); + declareProperty( "maxCharge", m_maxCharge ); + declareProperty( "maxEmRadius", m_maxEmRadius ); + declareProperty( "maxIsoFrac", m_maxIsoFrac ); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- +TauTrackSlimmer::~TauTrackSlimmer() +{ +} + +//----------------------------------------------------------------------------- +// Initialiezer +//----------------------------------------------------------------------------- +StatusCode TauTrackSlimmer::initialize() +{ + + ATH_MSG_VERBOSE( "TauTrackSlimmer :: initialize()" ); + + /* + sc = service( "StoreGateSvc", evtStore() ); + if( sc.isFailure() ) + { + log << MSG :: ERROR; + log << "Unable to retrieve pointer to StoreGateSvc"; + log ); + return StatusCode :: FAILURE; + } + */ + if ( m_thinningSvc.retrieve().isFailure() ) + { + ATH_MSG_ERROR( "Unable to retrieve pointer to IThinningSvc" ); + return StatusCode :: FAILURE; + } + return StatusCode :: SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauTrackSlimmer :: finalize() +{ + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauTrackSlimmer::execute() +{ + using namespace Analysis; + + StatusCode sc; + + //--------------------------------------------------------------------------- + // Retrieve tau jet container + //--------------------------------------------------------------------------- + const Analysis::TauJetContainer *tauContainer; + sc = evtStore()->retrieve( tauContainer, m_tauContainerName ); + + if( sc.isFailure() || ! tauContainer ) + { + ATH_MSG_DEBUG( "No tau container found!" ); + return StatusCode :: SUCCESS; + } + + //--------------------------------------------------------------------------- + // Retrieve track container + //--------------------------------------------------------------------------- + const TrackCollection* tracks = 0; + sc = evtStore()->retrieve( tracks, "Tracks" ); + + if( sc.isFailure() || !tracks ){ + ATH_MSG_WARNING( "No track container found in TDS" ); + return StatusCode :: SUCCESS; + } + + if(tracks->size() == 0){ + ATH_MSG_DEBUG( "empty track container found in TDS" ); + return StatusCode :: SUCCESS; + } + + //--------------------------------------------------------------------------- + // Initialize vector of bools + //--------------------------------------------------------------------------- + std::vector<bool> selected; + selected.resize( tracks->size(), false ); + + //--------------------------------------------------------------------------- + // Initialize iterators + //--------------------------------------------------------------------------- + Analysis::TauJetContainer :: const_iterator ftau = tauContainer->begin(); + Analysis::TauJetContainer :: const_iterator etau = tauContainer->end(); + + //--------------------------------------------------------------------------- + // Loop over taus + //--------------------------------------------------------------------------- + + for(; ftau != etau; ++ftau ) + { + + const Analysis::TauCommonDetails* p_taudetails = (*ftau)->details<const Analysis::TauCommonDetails>(); + + if (m_filterTaus) { + + if ((*ftau)->numTrack() > m_maxNTrack) continue; + if (std::abs((*ftau)->charge()) > m_maxCharge) continue; + if ( p_taudetails) { + if (p_taudetails->seedCalo_EMRadius() > m_maxEmRadius) continue; + if (p_taudetails->seedCalo_isolFrac() > m_maxIsoFrac) continue; + } + + } + + for( unsigned itr = 0; itr < (*ftau)->numTrack(); ++itr ) + selected[(*ftau)->track(itr)->trackElementLink()->index()] = true; + } + + + + //--------------------------------------------------------------------------- + // Invoke the thinning service + //--------------------------------------------------------------------------- + sc = m_thinningSvc->filter( *tracks, selected, IThinningSvc :: Operator :: Or ); + if( sc.isFailure() ) + { + ATH_MSG_ERROR( "Failed to thin Tracks associated to taus" ); + return StatusCode :: SUCCESS; + } + + return StatusCode :: SUCCESS; +} diff --git a/Reconstruction/tauRec/src/TauVertexFinder.cxx b/Reconstruction/tauRec/src/TauVertexFinder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ae95c3f03674dd8e0ca631571bdcca3ed2fef006 --- /dev/null +++ b/Reconstruction/tauRec/src/TauVertexFinder.cxx @@ -0,0 +1,216 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "tauRec/TauVertexFinder.h" + +#include "VxVertex/RecVertex.h" +#include "VxVertex/VxCandidate.h" + +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/Vertex.h" + +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" +#include "xAODTau/TauJet.h" + +TauVertexFinder::TauVertexFinder(const std::string& type, + const std::string& name, + const IInterface* parent) : +TauToolBase(type, name, parent), +m_printMissingContainerINFO(true), +m_maxJVF(-100.), +m_assocTracksName(""), +m_trackVertexAssocName("") +{ + declareInterface<TauToolBase > (this); + declareProperty("UseTJVA", m_useTJVA=true); + declareProperty("PrimaryVertexContainer", m_inputPrimaryVertexContainerName = "PrimaryVertices"); + declareProperty("AssociatedTracks",m_assocTracksName); + declareProperty("TrackVertexAssociation",m_trackVertexAssocName); +} + +TauVertexFinder::~TauVertexFinder() { +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauVertexFinder::initialize() { + if (m_useTJVA) ATH_MSG_INFO("using TJVA to determine tau vertex"); + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauVertexFinder::finalize() { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauVertexFinder::eventInitialize(TauCandidateData*) { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauVertexFinder::eventFinalize(TauCandidateData*) { + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +StatusCode TauVertexFinder::execute(TauCandidateData * data) { + + xAOD::TauJet *tauJet = data->xAODTau; + + // get the primary vertex container from StoreGate + //do it here because of tau trigger + const xAOD::VertexContainer* vxContainer = 0; + const xAOD::Vertex* primaryVertex = 0; + + StatusCode sc; + //for tau trigger + sc = data->getObject("VxPrimaryCandidate", vxContainer); + + if (sc.isFailure() || !vxContainer) { //not in trigger mode or no vxContainer was set by trigger + ATH_MSG_DEBUG("no VxPrimaryCandidateContainer for trigger -> try standard way"); + if (!openContainer(vxContainer, m_inputPrimaryVertexContainerName)) { + if (m_printMissingContainerINFO) { + ATH_MSG_INFO(m_inputPrimaryVertexContainerName << " container not found --> skip TauVertexFinder (no further info)"); + m_printMissingContainerINFO=false; + } + return StatusCode::SUCCESS; + } + + // find default PrimaryVertex (needed if TJVA is switched off or fails) + // see: https://twiki.cern.ch/twiki/bin/viewauth/AtlasProtected/VertexReselectionOnAOD + // code adapted from + // https://svnweb.cern.ch/trac/atlasoff/browser/Tracking/TrkEvent/VxVertex/trunk/VxVertex/PrimaryVertexSelector.h + if (vxContainer->size()>0) { + // simple loop through and get the primary vertex + xAOD::VertexContainer::const_iterator vxIter = vxContainer->begin(); + xAOD::VertexContainer::const_iterator vxIterEnd = vxContainer->end(); + for ( size_t ivtx = 0; vxIter != vxIterEnd; ++vxIter, ++ivtx ){ + // the first and only primary vertex candidate is picked + if ( (*vxIter)->vertexType() == xAOD::VxType::PriVtx){ + primaryVertex = (*vxIter); + break; + } + } + } + } + else { // trigger mode + // find default PrimaryVertex (highest sum pt^2) + if (vxContainer->size()>0) primaryVertex = (*vxContainer)[0]; + } + + ATH_MSG_VERBOSE("size of VxPrimaryContainer is: " << vxContainer->size() ); + + // associate vertex to tau + if (primaryVertex) tauJet->setVertex(vxContainer, primaryVertex); + + //stop here if TJVA is disabled or vertex container is empty + if (!m_useTJVA || vxContainer->size()==0) return StatusCode::SUCCESS; + + // try to find new PV with TJVA + ATH_MSG_DEBUG("TJVA enabled -> try to find new PV for the tau candidate"); + + ElementLink<xAOD::VertexContainer> newPrimaryVertexLink = getPV_TJVA(tauJet, vxContainer ); + if (newPrimaryVertexLink.isValid()) { + // set new primary vertex + // will overwrite default one which was set above + tauJet->setVertexLink(newPrimaryVertexLink); + // save highest JVF value + tauJet->setDetail(xAOD::TauJetParameters::TauJetVtxFraction,static_cast<float>(m_maxJVF)); + ATH_MSG_DEBUG("TJVA vertex found and set"); + } + else { + ATH_MSG_DEBUG("couldn't find new PV for TJVA"); + } + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +ElementLink<xAOD::VertexContainer> TauVertexFinder::getPV_TJVA(const xAOD::TauJet* pTau, const xAOD::VertexContainer* vertices) +{ + const xAOD::Jet* pJetSeed = (*pTau->jetLink()); + + // the implementation follows closely the example given in modifyJet(...) in https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/Jet/JetMomentTools/trunk/Root/JetVertexFractionTool.cxx#15 + + // Get the tracks associated to the jet + std::vector<const xAOD::TrackParticle*> assocTracks; + if (! pJetSeed->getAssociatedObjects(m_assocTracksName, assocTracks)) { + ATH_MSG_ERROR("Could not retrieve the AssociatedObjects named \""<< m_assocTracksName <<"\" from jet"); + return ElementLink<xAOD::VertexContainer>(); + } + + // Get the TVA object + const jet::TrackVertexAssociation* tva = NULL; + if (evtStore()->retrieve(tva,m_trackVertexAssocName).isFailure()) { + ATH_MSG_ERROR("Could not retrieve the TrackVertexAssociation from evtStore: " << m_trackVertexAssocName); + return ElementLink<xAOD::VertexContainer>(); + } + + // Calculate Jet Vertex Fraction + std::vector<float> jvf; + jvf.resize(vertices->size()); + for (size_t iVertex = 0; iVertex < vertices->size(); ++iVertex) { + jvf.at(iVertex) = getJetVertexFraction(vertices->at(iVertex),assocTracks,tva); + } + + // Get the highest JVF vertex and store maxJVF for later use + // Note: the official JetMomentTools/JetVertexFractionTool doesn't provide any possibility to access the JVF value, but just the vertex. + m_maxJVF=-100.; + size_t maxIndex = 0; + for (size_t iVertex = 0; iVertex < jvf.size(); ++iVertex) { + if (jvf.at(iVertex) > m_maxJVF) { + m_maxJVF = jvf.at(iVertex); + maxIndex = iVertex; + } + } + + // Set the highest JVF vertex + ElementLink<xAOD::VertexContainer> vtxlink = ElementLink<xAOD::VertexContainer>(*vertices,vertices->at(maxIndex)->index()); + + return vtxlink; +} + +// reimplementation of JetVertexFractionTool::getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const +// avoid to call this specific tool only for this easy purpose +// see https://svnweb.cern.ch/trac/atlasoff/browser/Reconstruction/Jet/JetMomentTools/trunk/Root/JetVertexFractionTool.cxx +float TauVertexFinder::getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const +{ + float sumTrackPV = 0; + float sumTrackAll = 0; + for (size_t iTrack = 0; iTrack < tracks.size(); ++iTrack) + { + const xAOD::TrackParticle* track = tracks.at(iTrack); + const xAOD::Vertex* ptvtx = tva->associatedVertex(track); + if (ptvtx != nullptr) { // C++11 feature + if (ptvtx->index() == vertex->index()) sumTrackPV += track->pt(); + } + sumTrackAll += track->pt(); + + } + return sumTrackAll!=0 ? sumTrackPV/sumTrackAll : 0; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Helpers +template <class T> +bool TauVertexFinder::openContainer(T* &container, std::string containerName, bool printFATAL) { + StatusCode sc = evtStore()->retrieve(container, containerName); + if (sc.isFailure() || !container) { + if (printFATAL) ATH_MSG_FATAL("Container (" << containerName << ") not found in StoreGate"); + return 0; + } + return container; +} + +template <class T> +bool TauVertexFinder::retrieveTool(T & tool) { + if (tool.retrieve().isFailure()) { + ATH_MSG_FATAL("Failed to retrieve tool " << tool); + return false; + } else { + ATH_MSG_VERBOSE("Retrieved tool " << tool); + } + return true; +} diff --git a/Reconstruction/tauRec/src/TauVertexVariables.cxx b/Reconstruction/tauRec/src/TauVertexVariables.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c0235b1b7b98e34c8f9612a686994d5409863a62 --- /dev/null +++ b/Reconstruction/tauRec/src/TauVertexVariables.cxx @@ -0,0 +1,327 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +#include "Particle/TrackParticle.h" +#include "Particle/TrackParticleContainer.h" +#include "TrkParameters/TrackParameters.h" + +#include "xAODTracking/TrackParticleContainer.h" + +#include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h" +#include "TrkVertexFitterInterfaces/IVertexFitter.h" +#include "TrkVertexFitterInterfaces/IVertexSeedFinder.h" +#include "TrkVertexFitters/AdaptiveVertexFitter.h" +#include "TrkVxEdmCnv/IVxCandidateXAODVertex.h" +#include "TrkLinks/LinkToXAODTrackParticle.h" + +#include "tauRec/TauCandidateData.h" +#include "tauRec/TauVertexVariables.h" + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- + +TauVertexVariables::TauVertexVariables(const std::string &type, + const std::string &name, + const IInterface *parent) : + TauToolBase(type, name, parent), + m_primaryVertexKey("PrimaryVertices"), + m_useOldSeedFinderAPI(false), + m_fitTool("Trk::AdaptiveVertexFitter"), + m_SeedFinder("Trk::CrossDistancesSeedFinder"), + m_xaodConverter("Trk::VxCandidateXAODVertex"), + m_pSecVtxContainer(0), + m_pSecVtxAuxContainer(0){ + declareInterface<TauToolBase > (this); + declareProperty("PrimaryVertexKey", m_primaryVertexKey); + declareProperty("TrackParticleContainer", m_inputTrackParticleContainerName = "InDetTrackParticles"); + declareProperty("TrackToVertexIPEstimator", m_trackToVertexIPEstimator); + declareProperty("VertexFitter", m_fitTool); + declareProperty("SeedFinder", m_SeedFinder); + declareProperty("XAODConverter",m_xaodConverter); + declareProperty("useOldSeedFinderAPI",m_useOldSeedFinderAPI); +} + +//----------------------------------------------------------------------------- +// Destructor +//----------------------------------------------------------------------------- + +TauVertexVariables::~TauVertexVariables() { +} + + +//----------------------------------------------------------------------------- +// Initializer +//----------------------------------------------------------------------------- + +StatusCode TauVertexVariables::initialize() { + CHECK( m_trackToVertexIPEstimator.retrieve() ); + CHECK( m_fitTool.retrieve() ); + CHECK( m_SeedFinder.retrieve() ); + if (m_useOldSeedFinderAPI) CHECK( m_xaodConverter.retrieve() ); + + if (m_useOldSeedFinderAPI) { + ATH_MSG_INFO("using AOD-style API of the AdaptiveVertexFitter"); + } + else { + ATH_MSG_INFO("using new xAOD-style API of the AdaptiveVertexFitter"); + } + + return StatusCode::SUCCESS; +} + +StatusCode TauVertexVariables::eventInitialize(TauCandidateData * data) { + + StatusCode sc; + bool inTrigger = false; + if (data->hasObject("InTrigger?")) + sc = data->getObject("InTrigger?", inTrigger); + + // Only store the vertex containers if we are offline? + if(!sc.isSuccess() || !inTrigger) + { + // Secondary Vertex Container for tau decay vertex + m_pSecVtxContainer = new xAOD::VertexContainer(); + m_pSecVtxAuxContainer = new xAOD::VertexAuxContainer(); + m_pSecVtxContainer->setStore( m_pSecVtxAuxContainer ); + + CHECK( evtStore()->record( m_pSecVtxContainer, "TauSecondaryVertexContainer" ) ); + CHECK( evtStore()->record( m_pSecVtxAuxContainer, "TauSecondaryVertexContainerAux." ) ); + } + + return StatusCode::SUCCESS; +} + + + +//----------------------------------------------------------------------------- +// Finalizer +//----------------------------------------------------------------------------- +StatusCode TauVertexVariables::finalize() { + return StatusCode::SUCCESS; +} + + +//----------------------------------------------------------------------------- +// Execution +//----------------------------------------------------------------------------- +StatusCode TauVertexVariables::execute(TauCandidateData *data) { + + ATH_MSG_DEBUG("executing TauVertexVariables"); + + xAOD::TauJet *pTau = data->xAODTau; + + if (pTau == NULL) { + ATH_MSG_ERROR("no candidate given"); + return StatusCode::FAILURE; + } + + // impact parameter variables for standard tracks + if (pTau->nTracks() > 0) { + const Trk::ImpactParametersAndSigma * myIPandSigma(0); + + if (pTau->vertexLink()) { + const xAOD::Vertex* vxcand = *(pTau->vertexLink()) ; + //check if vertex has a valid type (skip if vertex has type NoVtx) + if (vxcand->vertexType() > 0) { + myIPandSigma = m_trackToVertexIPEstimator->estimate(pTau->track(0), *pTau->vertexLink()); + } + } + + if (myIPandSigma != 0) { + pTau->setDetail(xAOD::TauJetParameters::ipSigLeadTrk, (float)( myIPandSigma->IPd0 / myIPandSigma->sigmad0 )); + pTau->setDetail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, (float)( myIPandSigma->IPz0SinTheta / myIPandSigma->sigmaz0SinTheta )); + } else { + ATH_MSG_DEBUG("trackToVertexIPestimator failed for a standard track!"); + pTau->setDetail(xAOD::TauJetParameters::ipSigLeadTrk, (float)(-999.)); + pTau->setDetail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, (float)(-999.)); + } + delete myIPandSigma; + } + + float ipSigLeadTrk; + float ipZ0SinThetaSigLeadTrk; + + if (pTau->detail(xAOD::TauJetParameters::ipSigLeadTrk, ipSigLeadTrk)) + ATH_MSG_VERBOSE("IP significance lead track " << ipSigLeadTrk); + if (pTau->detail(xAOD::TauJetParameters::ipZ0SinThetaSigLeadTrk, ipZ0SinThetaSigLeadTrk)) + ATH_MSG_VERBOSE("IP Z0 significance lead track " << ipZ0SinThetaSigLeadTrk); + + //try to find secondary vertex + //look for secondary vertex if more than 1 track + pTau->setDetail(xAOD::TauJetParameters::trFlightPathSig, (float)(-1111.)); + if (pTau->nTracks() < 2) { + return StatusCode::SUCCESS; + } + + // for tau trigger + bool inTrigger = false; + StatusCode sc; + if (data->hasObject("InTrigger?")) sc = data->getObject("InTrigger?", inTrigger); + + const xAOD::VertexContainer* vxContainer = 0; + if (sc.isSuccess() && inTrigger) sc = data->getObject("VxPrimaryCandidate", vxContainer); + // retrieve vertex container, exit if not found + else sc = evtStore()->retrieve(vxContainer, m_primaryVertexKey); + + if (sc.isFailure() || !vxContainer) { + ATH_MSG_WARNING("No vertex container found. Skipping secondary vertex fitting."); + return StatusCode::SUCCESS; + } + + const xAOD::TrackParticleContainer* trackParticleCont = 0; + if (inTrigger) sc = data->getObject( "TrackContainer", trackParticleCont ); + // retrieve track particle container, exit if not found + else sc = evtStore()->retrieve(trackParticleCont, m_inputTrackParticleContainerName); + if (sc.isFailure() || !trackParticleCont) { + ATH_MSG_WARNING("No track particle container found. Skipping secondary vertex fitting."); + return StatusCode::SUCCESS; + } + + // get xAOD TrackParticles and Trk::Tracks + std::vector<const xAOD::TrackParticle*> xaodTracks; + std::vector<const Trk::Track*> origTracks; + for (unsigned i = 0; i < pTau->nTracks(); ++i) { + xaodTracks.push_back(pTau->track(i)); + ATH_MSG_VERBOSE("xAOD::TrackParticle " <<i<<": "<< pTau->track(i)->pt() << " " << pTau->track(i)->eta() << " " << pTau->track(i)->phi()); + if (pTau->track(i)->track()) { + origTracks.push_back(pTau->track(i)->track()); + + // for debugging + /* + ATH_MSG_DEBUG("Trk::Track " <<i<<": "<< (*pTau->track(i)->track())->pt() << " " << (*pTau->track(i)->track())->eta() << " " << (*pTau->track(i)->track())->phi()); + const Trk::TrackParameters * tmpMeasPer = (*pTau->track(i)->track())->perigeeParameters(); + const AmgSymMatrix(5)* cov = tmpMeasPer->covariance(); + ATH_MSG_DEBUG(" TrackParameters: pT="<< tmpMeasPer->pT() << ", eta=" << tmpMeasPer->eta() << ", x=" << tmpMeasPer->position().x() << ", y="<< tmpMeasPer->position().y() <<", z="<< tmpMeasPer->position().z()); + ATH_MSG_DEBUG(" covariance ="<< *cov); + */ + // for debugging + } + else { + ATH_MSG_WARNING("no Trk::Track for xAOD::TrackParticle"); + } + } + + // get the starting point for the fit using Trk::Tracks + Trk::Vertex* seedPoint = new Trk::Vertex(m_SeedFinder->findSeed(origTracks)); + ATH_MSG_VERBOSE("seedPoint x/y/perp=" << seedPoint->position().x() << " "<< seedPoint->position().y() << " "<< seedPoint->position().perp()); + if (!seedPoint) { + ATH_MSG_WARNING("no seedPoint: Can not calculate secondary vertex!"); + return StatusCode::SUCCESS; + } + + // fitting the vertex itself + xAOD::Vertex* xAODvertex(0); + if (!m_useOldSeedFinderAPI) { // use new xAOD API of VertexFitter + xAODvertex = m_fitTool->fit(xaodTracks, *seedPoint); + if (xAODvertex && !inTrigger) { + ATH_MSG_VERBOSE("using new xAOD API: Secondary Vertex found and recorded! x="<<xAODvertex->position().x()<< ", y="<<xAODvertex->position().y()<<", perp="<<xAODvertex->position().perp()); + m_pSecVtxContainer->push_back(xAODvertex); + } + } + else { // use standard AOD-style API of VertexFitter + Trk::VxCandidate* tmpVxCandidate = m_fitTool->fit(origTracks, *seedPoint); + if (tmpVxCandidate) { + ATH_MSG_VERBOSE("using old AOD API:Secondary Vertex found and recorded! x="<<tmpVxCandidate->recVertex().position().x()<< ", y="<<tmpVxCandidate->recVertex().position().y()<<", perp="<<tmpVxCandidate->recVertex().position().perp()); + + //****************************************************************** + // convert VxCandidate to xAOD::Vertex + //****************************************************************** + + // assigning the input xAOD tracks to the fitted vertex + // this means: after that procedure the Trk::VxCandidate knows already the links to the xAOD tracks (which have to be identical with the Trk:Tracks used in the VertexFitter!) + // this is needed for the converting, otherwise the new xAODVertex don't have the track links + if(tmpVxCandidate->vxTrackAtVertex() != 0 && tmpVxCandidate->vxTrackAtVertex()->size() !=0) { + for(unsigned int i = 0; i <xaodTracks.size(); ++i) { + Trk::LinkToXAODTrackParticle * linkTT = new Trk::LinkToXAODTrackParticle; + linkTT->setElement(xaodTracks[i]); + linkTT->setStorableObject(*trackParticleCont); + // vxtrackatvertex takes ownership! + (*(tmpVxCandidate->vxTrackAtVertex()))[i]->setOrigTrack(linkTT); + } + } + + xAODvertex = new xAOD::Vertex(); + if (!inTrigger) m_pSecVtxContainer->push_back(xAODvertex); + // perform the final converting now + if( m_xaodConverter->createXAODVertex(*tmpVxCandidate,xAODvertex).isFailure() ) { + ATH_MSG_ERROR("Failed to create xAODVertex for VxCandidate. Don't set any secondary vertex for tau!"); + return StatusCode::SUCCESS; + } + delete tmpVxCandidate; + } + } + delete seedPoint; + + if (!xAODvertex) { + ATH_MSG_WARNING("no secondary vertex found!"); + return StatusCode::SUCCESS; + } + + // get the transverse flight path significance + float trFlightPS = trFlightPathSig(data, xAODvertex); + pTau->setDetail(xAOD::TauJetParameters::trFlightPathSig, (float)(trFlightPS)); + ATH_MSG_VERBOSE("transverse flight path significance="<<trFlightPS); + + // Note, we only attach the 2nd vertex if at offline, otherwise, break the trigger persistency + if (!inTrigger) { + pTau->setSecondaryVertex(m_pSecVtxContainer, xAODvertex); // set the link to the vertex + } + else { + delete xAODvertex; // delete the vertex when in trigger mode, because we can not save it + } + + return StatusCode::SUCCESS; +} + +//------------------------------------------------------------------------- +// calculate the transverse flight path significance +//------------------------------------------------------------------------- +double TauVertexVariables::trFlightPathSig(TauCandidateData *data, const xAOD::Vertex *secVertex) { + + const xAOD::TauJet *pTau = data->xAODTau; + + if (!secVertex) { + ATH_MSG_WARNING("No secondary vertex information for calculation of transverse flight path significance"); + return -11111.; + } + + const xAOD::Vertex* pVertex = 0; + if (pTau->vertexLink()) pVertex = *pTau->vertexLink(); + if (!pVertex) { + ATH_MSG_WARNING("No primary vertex information for calculation of transverse flight path significance"); + return -11111.; + } + + double fpx = secVertex->position().x() - pVertex->position().x(); + double fpy = secVertex->position().y() - pVertex->position().y(); + double fpt = (secVertex->position() - pVertex->position()).perp(); + + if (fpt == 0) { + ATH_MSG_WARNING("delta pt of (secVtx - priVtx) is 0!"); + return -11111.; + } + + double sigma_fpt2 = (fpx * fpx * secVertex->covariancePosition()(Trk::x, Trk::x) + + fpx * fpy * secVertex->covariancePosition()(Trk::x, Trk::y) + + fpy * fpx * secVertex->covariancePosition()(Trk::y, Trk::x) + + fpy * fpy * secVertex->covariancePosition()(Trk::y, Trk::y)) / (fpt * fpt); + + if (sigma_fpt2 <= 0) { + ATH_MSG_WARNING("sigma delta pt of (secVtx - priVtx) is 0!"); + return -11111.; + } + + double sigma_fpt = sqrt(sigma_fpt2); + double sign = 0; + + if (fpx * pTau->p4().Px() + fpy * pTau->p4().Py() > 0.) sign = 1.; + else sign = -1.; + + //ATH_MSG_INFO(sign << " " <<fpt << " " << sigma_fpt << " " << sign * fpt / sigma_fpt); + return sign * fpt / sigma_fpt; +} + diff --git a/Reconstruction/tauRec/src/components/tauRec_entries.cxx b/Reconstruction/tauRec/src/components/tauRec_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..e4171128090922acc63ac2e1d75e911af9b15b15 --- /dev/null +++ b/Reconstruction/tauRec/src/components/tauRec_entries.cxx @@ -0,0 +1,116 @@ +#include "tauRec/TauBuilder.h" +#include "tauRec/JetSeedBuilder.h" +#include "tauRec/LockTauContainers.h" +#include "tauRec/TauAxisSetter.h" +#include "tauRec/TauCalibrateEM.h" +#include "tauRec/TauCalibrateLC.h" +#include "tauRec/TauCellVariables.h" +//#include "tauRec/TauOriginCorrectionTool.h" +#include "tauRec/TauProcessor.h" +#include "tauRec/TauTrackFinder.h" +#include "tauRec/TauVertexFinder.h" +#include "tauRec/TauElectronVetoVariables.h" +//#include "tauRec/TauPi0EflowCreateROI.h" +#include "tauRec/TauCommonCalcVars.h" +//#include "tauRec/TauEflowAddCaloInfo.h" +//#include "tauRec/TauEflowTrackMatchCells.h" +//#include "tauRec/TauEflowVariables.h" +#include "tauRec/TauShotFinder.h" +#include "tauRec/TauPi0BonnClusterCreator.h" +#include "tauRec/TauPi0BonnCreateROI.h" +#include "tauRec/TauPi0BonnScoreCalculator.h" +#include "tauRec/TauPi0BonnSelector.h" +//#include "tauRec/TauPi0CrakowClusterCreator.h" +//#include "tauRec/TauPi0CreatorChooser.h" +#include "tauRec/TauSubstructureVariables.h" +#include "tauRec/TauConversionFinder.h" +#include "tauRec/PhotonConversionPID.h" +#include "tauRec/PhotonConversionVertex.h" +#include "tauRec/TauConversionTagger.h" +#include "tauRec/TauVertexVariables.h" +#include "tauRec/tauCalibrateWeightTool.h" //for trigger +#include "tauRec/TauTrackSlimmer.h" +#include "tauRec/TauTrackFilter.h" +#include "tauRec/TauGenericPi0Cone.h" +#include "tauRec/TauTestDump.h" + + + +#include "GaudiKernel/DeclareFactoryEntries.h" + +DECLARE_ALGORITHM_FACTORY( TauBuilder ) +DECLARE_ALGORITHM_FACTORY( TauProcessor ) +DECLARE_TOOL_FACTORY( JetSeedBuilder ) +DECLARE_TOOL_FACTORY( LockTauContainers ) +DECLARE_TOOL_FACTORY( TauAxisSetter ) +DECLARE_TOOL_FACTORY( TauCalibrateEM ) +DECLARE_TOOL_FACTORY( TauCalibrateLC ) +DECLARE_TOOL_FACTORY( TauCellVariables ) +//DECLARE_TOOL_FACTORY( TauOriginCorrectionTool ) +DECLARE_TOOL_FACTORY( TauTrackFinder ) +DECLARE_TOOL_FACTORY( TauVertexFinder ) +DECLARE_TOOL_FACTORY( TauElectronVetoVariables ) +//DECLARE_TOOL_FACTORY( TauPi0EflowCreateROI ) +DECLARE_TOOL_FACTORY( TauCommonCalcVars ) +//DECLARE_TOOL_FACTORY( TauEflowAddCaloInfo ) +//DECLARE_TOOL_FACTORY( TauEflowTrackMatchCells ) +//DECLARE_TOOL_FACTORY( TauEflowVariables ) +DECLARE_TOOL_FACTORY( TauShotFinder ) +DECLARE_TOOL_FACTORY( TauPi0BonnClusterCreator ) +DECLARE_TOOL_FACTORY( TauPi0BonnCreateROI ) +DECLARE_TOOL_FACTORY( TauPi0BonnScoreCalculator ) +DECLARE_TOOL_FACTORY( TauPi0BonnSelector ) +//DECLARE_TOOL_FACTORY( TauPi0CrakowClusterCreator ) +//DECLARE_TOOL_FACTORY( TauPi0CreatorChooser ) +DECLARE_TOOL_FACTORY( TauSubstructureVariables ) +DECLARE_TOOL_FACTORY( PhotonConversionPID ) +DECLARE_TOOL_FACTORY( PhotonConversionVertex ) +DECLARE_TOOL_FACTORY( TauConversionFinder ) +DECLARE_TOOL_FACTORY( TauConversionTagger ) +DECLARE_TOOL_FACTORY( TauVertexVariables ) +DECLARE_TOOL_FACTORY( tauCalibrateWeightTool ) +DECLARE_TOOL_FACTORY( TauTrackFilter ) +DECLARE_TOOL_FACTORY( TauGenericPi0Cone ) +DECLARE_TOOL_FACTORY( TauTestDump ) +DECLARE_ALGORITHM_FACTORY( TauTrackSlimmer ) + + +DECLARE_FACTORY_ENTRIES(tauRec) { + DECLARE_ALGORITHM(TauBuilder) + DECLARE_ALGORITHM(TauProcessor) + DECLARE_TOOL(JetSeedBuilder) + DECLARE_TOOL(LockTauContainers) + DECLARE_TOOL(TauAxisSetter) + DECLARE_TOOL(TauCalibrateEM) + DECLARE_TOOL(TauCalibrateLC) + DECLARE_TOOL(TauCellVariables) + //DECLARE_TOOL(TauOriginCorrectionTool) + DECLARE_TOOL(TauTrackFinder) + DECLARE_TOOL(TauVertexFinder) + DECLARE_TOOL( TauElectronVetoVariables ) + //DECLARE_TOOL( TauPi0EflowCreateROI ) + DECLARE_TOOL( TauCommonCalcVars ) + //DECLARE_TOOL( TauEflowAddCaloInfo ) + //DECLARE_TOOL( TauEflowTrackMatchCells ) + //DECLARE_TOOL( TauEflowVariables ) + DECLARE_TOOL( TauShotFinder ) + DECLARE_TOOL( TauPi0BonnClusterCreator ) + DECLARE_TOOL( TauPi0BonnCreateROI ) + DECLARE_TOOL( TauPi0BonnScoreCalculator ) + DECLARE_TOOL( TauPi0BonnSelector ) + //DECLARE_TOOL( TauPi0CrakowClusterCreator ) + //DECLARE_TOOL( TauPi0CreatorChooser ) + DECLARE_TOOL( TauSubstructureVariables ) + DECLARE_TOOL( PhotonConversionPID ) + DECLARE_TOOL( PhotonConversionVertex ) + DECLARE_TOOL( TauConversionFinder ) + DECLARE_TOOL( TauConversionTagger ) + DECLARE_TOOL( TauVertexVariables ) + DECLARE_TOOL( tauCalibrateWeightTool ) + DECLARE_TOOL( TauTestDump ) + DECLARE_ALGORITHM( TauTrackSlimmer ) +/* + DECLARE_ALGORITHM( TauTrackSlimmer ) + DECLARE_ALGORITHM( TauAODDetailsCleaner ) + */ +} diff --git a/Reconstruction/tauRec/src/components/tauRec_load.cxx b/Reconstruction/tauRec/src/components/tauRec_load.cxx new file mode 100755 index 0000000000000000000000000000000000000000..84f141f229697d96091655254891da3c42d3baed --- /dev/null +++ b/Reconstruction/tauRec/src/components/tauRec_load.cxx @@ -0,0 +1,6 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES(tauRec) + + + diff --git a/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx b/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c3dff174ba0052771a5f11f32f294a3cdf290629 --- /dev/null +++ b/Reconstruction/tauRec/src/tauCalibrateWeightTool.cxx @@ -0,0 +1,395 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/******************************************************************** +(depreciated!) + +NAME: tauCalibrateWeightTool.cxx +PACKAGE: offline/Reconstruction/tauRec + +AUTHORS: M.Heldmann +CREATED: March 22, 2005 +MODIFIED: July 15, 2005 ( Include pT dependent correction ) +23/10/2006 - (AK) fixing some compilation warnings (unused parameter) +18/04/2007 - (AK) fixing some compilation warnings (unused parameter) +29/06/2007 - (SL) fixing some compilation warnings +13/12/2008 - (AK) change to extrapolation of TP instead of Track+code cleaning +16/03/2010 - (AK) use the cell id instead of the pointer +17/03/2010 - (AK) change to P4Helpers +14/12/2011 - (FF) change to use tau axis and numTrack (not seedCalo_) + ********************************************************************/ +#include "tauRec/TauCandidateData.h" +#include "tauEvent/TauCommonDetails.h" +#include "CaloEvent/CaloCluster.h" +#include "CaloEvent/CaloCell.h" +#include "AtlasDetDescr/AtlasDetectorID.h" +#include "CaloIdentifier/CaloID.h" +#include "CaloGeoHelpers/CaloSampling.h" + +#include "CLHEP/Units/SystemOfUnits.h" + +// INCLUDE GAUDI HEADER FILES: +#include "GaudiKernel/Property.h" +#include "AIDA/IHistogram1D.h" + +#include <algorithm> +#include <math.h> + +#include "FourMomUtils/P4Helpers.h" +#include "FourMom/P4EEtaPhiM.h" + +#include "CaloInterface/IHadronicCalibrationTool.h" +#include "TF1.h" + +#include "tauRec/tauCalibrateWeightTool.h" +/********************************************************************/ + +tauCalibrateWeightTool::tauCalibrateWeightTool(const std::string& type, + const std::string& name, + const IInterface* parent): + TauToolBase( type, name, parent ), + m_calibrateType( tauCalibrateWeightTool::calCells ), + m_caloWeightTool(this), + m_cellWeightTool("CellWeightTool2004"), + m_applyCellWeightEM(true), + m_applyCellWeightHad(true), + m_applyPtEtaCorrFactors(true), + m_validCaloWeightTool(true), + m_doEtaInterpolation(false), + m_cellCone(0.4) +{ + declareInterface<TauToolBase>( this ); + + declareProperty( "calibrateType", m_calibrateType ); + // Calibration Tool + declareProperty("CellWeightTool",m_cellWeightTool); + declareProperty("ApplyCellWeightEM", m_applyCellWeightEM); + declareProperty("ApplyCellWeightHad", m_applyCellWeightHad); + declareProperty("ApplyPtEtaCorrFactors", m_applyPtEtaCorrFactors); + declareProperty("pTNumberOfBins", m_nptbins ); + declareProperty("etaNumberOfBins", m_netabins ); + + declareProperty("pTPoints",m_ptpoints=std::vector<float>(10,0)); + declareProperty("etaPoints",m_etapoints=std::vector<float>(10,0)); + declareProperty("pTetaCorrectionsNtr1",m_ptetacorrectionsntr1=std::vector<float>(100,0)); + declareProperty("pTetaCorrectionsNtr23",m_ptetacorrectionsntr23=std::vector<float>(100,0)); + + declareProperty("FudgeFactor",m_fudge=1); + declareProperty("DoEtaInterpolation", m_doEtaInterpolation); + declareProperty("CellCone",m_cellCone); + declareProperty("CaloWeightTool",m_caloWeightTool); +} + +tauCalibrateWeightTool::~tauCalibrateWeightTool() +{ +} + +StatusCode tauCalibrateWeightTool::initialize() +{ + StatusCode sc; + ATH_MSG_INFO( "Calibrating using fitted weights. " ); + + // retrieve all helpers from det store + sc = detStore()->retrieve(m_emid); + if (sc.isFailure()) { + ATH_MSG_ERROR( "Unable to retrieve LArEM_ID helper from DetectorStore" ); + return sc; + } + + sc = detStore()->retrieve(m_tileid); + if (sc.isFailure()) { + ATH_MSG_ERROR( "Unable to retrieve TileID helper from DetectorStore" ); + return sc; + } + + // Tool service + IToolSvc* myToolSvc; + sc = service("ToolSvc",myToolSvc); + if ( sc.isFailure() ) { + ATH_MSG_FATAL( "Tool Service not found" ); + return StatusCode::FAILURE; + } + + // Fetch cell weight tool + sc = m_caloWeightTool.retrieve(); + if ( sc.isFailure() ) { + ATH_MSG_ERROR( "Cannot find tool named <" << m_cellWeightTool << ">" ); + m_validCaloWeightTool = false; + + return StatusCode::FAILURE; + } + else { + if( m_caloWeightTool != 0 ) { + ATH_MSG_INFO( "Will use the CaloWeightTool named: " << m_cellWeightTool ); + m_validCaloWeightTool = true; + } + } + + if ( (int)m_ptpoints.size() != m_nptbins || (int)m_etapoints.size() != m_netabins ) { + ATH_MSG_FATAL( "wrong number of points for interpolation" ); + return StatusCode::FAILURE; + } + + for ( int i = 0; i < m_nptbins - 1; ++i ) { + if ( m_ptpoints[i] >= m_ptpoints[i+1]) { + ATH_MSG_FATAL( "Correction factor coordinates must be ordered in Pt and unique" ); + return StatusCode::FAILURE; + } + } + m_ptpoints.push_back(0); //makes the boundary conditions easyer to handle + + for ( int i = 0; i < m_netabins - 1; ++i ) { + if ( m_etapoints[i] >= m_etapoints[i+1]) { + ATH_MSG_FATAL( "Correction factor coordinates must be ordered in eta and unique" ); + return StatusCode::FAILURE; + } + } + m_etapoints.push_back(0); + + if ( (int)m_ptetacorrectionsntr1.size() != (m_nptbins * m_netabins) ) { + ATH_MSG_FATAL( "Wrong number of correction factors for 1 Track" ); + return StatusCode::FAILURE; + } + + if ( (int)m_ptetacorrectionsntr23.size() != (m_nptbins * m_netabins) ) { + ATH_MSG_FATAL( "Wrong number of correction factors for 2 and 3 Tracks" ); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +/********************************************************************/ +StatusCode tauCalibrateWeightTool::execute( TauCandidateData */*data*/ ) +{ + /* + * FF: March 2014 + * This Tool is not migrated yet to xAOD. Unclear if still needed. Only client was TauTrigger. + * FF will investigate. + * + * + Analysis :: TauJet *tau = data->tau; + Analysis :: TauCommonDetails *details = dynamic_cast<Analysis :: TauCommonDetails *>(data->details); + + // Detector identifiers + AtlasDetectorID AtlasID; + + // Variables for sums + double sumEM = 0; + double sumE = 0; + double sumAccb3 = 0; + double sumHad = 0; + double sumTile1 = 0; + + double sumScint = 0; + double sumGap = 0; + + double dR; + + // loop over all cells of the tau (placed there by the tauSeedBuilder) + typedef NavigationToken<CaloCell,NavigationDefaults::DefaultWeight,CaloCellIDFcn> token_t; + token_t nt; + + tau->fillToken( nt ); + + token_t::const_iterator nt_iter = nt.begin(); + token_t::const_iterator nt_end = nt.end(); + + const CaloCell *cell; + + double etaSeed = tau->eta(); //FF details->seedCalo_eta(); + double phiSeed = tau->phi(); //FF details->seedCalo_phi(); + + P4EEtaPhiM P4Seed( 1., etaSeed, phiSeed, 0. ); + + for ( ; nt_iter != nt_end; nt_iter++ ) { + cell = (*nt_iter); + + // Cell ET and index for ET range + // This is made symmetric around zero so that noise (not yet included) + // does not produce a shift. + double cellET = cell->et(); + + CaloSampling::CaloSample calo = cell->caloDDE()->getSampling(); + + // Use cells that are in DR < m_cellCone of eta,phi of jet: + dR = P4Helpers::deltaR( P4Seed, cell->eta(), cell->phi() ); + + if ( dR < m_cellCone ) { + double calWeight = 1.; + + // Check which kind of calib tools have been selected + // and Get calibration weight + + if (m_validCaloWeightTool) calWeight = m_caloWeightTool->wtCell( cell ); + + sumE += cell->e(); + + switch ( calo ) { + case CaloSampling::PreSamplerB: + case CaloSampling::PreSamplerE: + case CaloSampling::EMB1: + case CaloSampling::EME1: + case CaloSampling::EMB2: + case CaloSampling::EME2: + sumEM += (m_applyCellWeightEM ? calWeight*cellET : cellET); + break; + case CaloSampling::EMB3: + sumAccb3 += cellET; + + case CaloSampling::EME3: + // Only include first two EM layers in EM sum; add third to HAD + // Keep track of ACCB3 for cryostat correction below + sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET); + break; + + case CaloSampling::TileBar0: + sumTile1 += cellET; + + case CaloSampling::TileBar1: + case CaloSampling::TileBar2: + sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET); + break; + case CaloSampling::TileExt0: + case CaloSampling::TileExt1: + case CaloSampling::TileExt2: + sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET); + break; + case CaloSampling::TileGap1: + // scintillator ? + // Gap Scintillator is included in Gap + // Hence do NOT add it separately + // MH I don't know what's it like now .... but I guess its seperated + sumScint += cellET; + case CaloSampling::TileGap2: + case CaloSampling::TileGap3: + sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET); + sumGap += cellET; + break; + case CaloSampling::HEC0: + case CaloSampling::HEC1: + case CaloSampling::HEC2: + case CaloSampling::HEC3: + sumHad += (m_applyCellWeightHad ? calWeight*cellET : cellET); + break; + case CaloSampling::FCAL0: + case CaloSampling::FCAL1: + case CaloSampling::FCAL2: + case CaloSampling::MINIFCAL0: + case CaloSampling::MINIFCAL1: + case CaloSampling::MINIFCAL2: + case CaloSampling::MINIFCAL3: + case CaloSampling::Unknown: + break; + } + } // end dR cut + else + { + ATH_MSG_VERBOSE( "cell with energy " << cell->e() << " outside of cell cone" ); + } + + } // end cell loop + + // Cryostat correction uses geometric mean of last layer of EM and + // first layer of tile: + + if(sumAccb3<0.) sumAccb3=0.; + if(sumTile1<0.) sumTile1=0.; + + double wtCryo = 1.; + + if (m_validCaloWeightTool) wtCryo = m_caloWeightTool->wtCryo(); + double sumCryo = (m_applyCellWeightHad ? wtCryo*sqrt(sumAccb3*sumTile1) : sqrt(sumAccb3*sumTile1)); + + // Weight fudge factor. The H1 weights are taken to be independent of + // eta. This factor is applied to the hadronic energy to produce a + // more uniform response. + + details->setSeedCalo_etEMCalib(sumEM); + details->setSeedCalo_etHadCalib((sumHad+sumCryo)); + + double et = details->seedCalo_etEMCalib()+details->seedCalo_etHadCalib(); + double eta = fabs( etaSeed ); + double corr = 1; + + if (m_applyPtEtaCorrFactors) { + + ATH_MSG_VERBOSE( "energy: " << details->seedCalo_etEMCalib() << " " <<details->seedCalo_etHadCalib() << " " << sumEM <<" "<<sumHad<<" "<<sumCryo ); + + int lowpt_idx = 0; + int loweta_idx = 0; + + double lowpt_frac = 0; + double loweta_frac = 0; + + while ( lowpt_idx < m_nptbins-1 && et > m_ptpoints[lowpt_idx+1] ) + lowpt_idx++; + + lowpt_frac = ( m_ptpoints[lowpt_idx+1] - et ) / ( m_ptpoints[lowpt_idx+1] - m_ptpoints[lowpt_idx] ); // will be >1 if et is out of bounds + + if ( lowpt_frac > 1 ) + lowpt_frac = 1; + if( lowpt_frac < 0 ) { //should never happen, only if ptNumberOfBins is set wrong (which is checked now) + ATH_MSG_ERROR( "FIXME: lowpt_frac < 0 !!" ); + } + + while ( loweta_idx < m_netabins-1 && eta > m_etapoints[loweta_idx+1] ) + loweta_idx++; + + if(m_doEtaInterpolation) + loweta_frac = ( m_etapoints[loweta_idx+1] - eta ) / ( m_etapoints[loweta_idx+1] - m_etapoints[loweta_idx] ); // will be >1 if eta is out of bounds, + else + loweta_frac = 1; + + if ( loweta_frac > 1) + loweta_frac = 1; + if( loweta_frac < 0 ) { //should never happen, only if etaNumberOfBins is set wrong + ATH_MSG_ERROR( "FIXME: loweta_frac < 0 !!" ); + } + + double coeff_matrix[2][2] = { {0, 0}, {0, 0} }; + + //FF changed from seeddCalo_numTrack to numTrack + if ( tau->numTrack() <= 1 ) { + coeff_matrix[0][0] = m_ptetacorrectionsntr1[lowpt_idx*m_netabins+loweta_idx]; + if( lowpt_idx < m_nptbins-1 ) + coeff_matrix[1][0] = m_ptetacorrectionsntr1[(lowpt_idx+1)*m_netabins+loweta_idx]; + if( loweta_idx < m_netabins-1 ) + coeff_matrix[0][1] = m_ptetacorrectionsntr1[lowpt_idx*m_netabins+(loweta_idx+1)]; + if( lowpt_idx < m_nptbins-1 && loweta_idx < m_netabins-1 ) + coeff_matrix[1][1] = m_ptetacorrectionsntr1[(lowpt_idx+1)*m_netabins+(loweta_idx+1)]; + } else { + coeff_matrix[0][0] = m_ptetacorrectionsntr23[lowpt_idx*m_netabins+loweta_idx]; + if( lowpt_idx < m_nptbins-1 ) + coeff_matrix[1][0] = m_ptetacorrectionsntr23[(lowpt_idx+1)*m_netabins+loweta_idx]; + if( loweta_idx < m_netabins-1 ) + coeff_matrix[0][1] = m_ptetacorrectionsntr23[lowpt_idx*m_netabins+(loweta_idx+1)]; + if( lowpt_idx < m_nptbins-1 && loweta_idx < m_netabins-1 ) + coeff_matrix[1][1] = m_ptetacorrectionsntr23[(lowpt_idx+1)*m_netabins+(loweta_idx+1)]; + } + + corr = ( coeff_matrix[0][0] * lowpt_frac * loweta_frac ) + ( coeff_matrix[1][0] * (1-lowpt_frac) * loweta_frac ); + corr += ( coeff_matrix[0][1] * lowpt_frac * (1-loweta_frac) ) + ( coeff_matrix[1][1] * (1-lowpt_frac) * (1-loweta_frac) ); + + } // end if (m_applyPtEtaCorrFactors) + + ATH_MSG_VERBOSE( "corrected energy: " << et << "*" << corr << "=" << et*corr ); + + + //tau->setE( et*cosh( details->seedCalo_eta() )*corr*m_fudge ); + */ + + //return StatusCode::SUCCESS; + // print error so that everybody knows this tool isn't working in case it is called. + ATH_MSG_ERROR( "This Tool is not yet migrated to xAOD!" ); + return StatusCode::SUCCESS; +} + +//----------------------------------------------------------------------------- +// Finalize +//----------------------------------------------------------------------------- +StatusCode tauCalibrateWeightTool :: finalize() +{ + return StatusCode :: SUCCESS; +} diff --git a/Reconstruction/tauRec/tauRec/CaloClusterVariables.h b/Reconstruction/tauRec/tauRec/CaloClusterVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..9b34c1b6d99c4daea16185379721b974fa8007c1 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/CaloClusterVariables.h @@ -0,0 +1,81 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef CALOCLUSTERVARIABLES_H +#define CALOCLUSTERVARIABLES_H + +#include <vector> +#include "CaloUtils/CaloVertexedCluster.h" +//#include "CaloEvent/CaloVertexedCluster.h" +#include "CxxUtils/fpcompare.h" +#include "xAODTau/TauJet.h" + +/** Provide calculations of cluster based variables using the clusters associated to the jet seed of the tau candidate. */ +class CaloClusterVariables { +public: + + static const double DEFAULT; + + CaloClusterVariables(); + + ~CaloClusterVariables() { + } + + bool update(const xAOD::TauJet* tau); //!< update the internal variables for the given tau + + void setVertexCorrection(bool flag) {m_doVertexCorrection=flag;} + + // ID Variables + unsigned int numConstituents() { return (unsigned int) m_numConstit; } + + double totalMass() { return m_totMass; } + double effectiveMass() { return m_effMass; } + + double effectiveNumConstituents() { return m_effNumConstit; } + int effectiveNumConstituents_int() { return m_effNumConstit_int; } + + double averageEffectiveRadius() { return m_aveEffRadius; } + double averageRadius() { return m_aveRadius; } + + // Energy Variables + double totalEnergy() { return m_totEnergy; } + double effectiveEnergy() { return m_effEnergy; } + + //cells + unsigned int numCells() { return m_numCells; } + +private: + int m_numConstit; + int m_effNumConstit_int; + double m_effNumConstit; + double m_aveRadius; + double m_aveEffRadius; + double m_totMass; + double m_effMass; + double m_totEnergy; + double m_effEnergy; + unsigned int m_numCells; + + /** Calculate the geometrical center of the tau constituents */ + CLHEP::HepLorentzVector calculateTauCentroid(int nConst, const std::vector<xAOD::CaloVertexedCluster>& constituents); + + /** + * Enable cell origin correction. + * Eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doVertexCorrection; +}; + +//------------------------------------------------------------------------- +//! Descending order by energy +//------------------------------------------------------------------------- +struct CaloClusterCompare { + bool operator()(const xAOD::CaloVertexedCluster& left, const xAOD::CaloVertexedCluster& right) { + //volatile double leftE = left.e(); + //volatile double rightE = right.e(); + return CxxUtils::fpcompare::greater (left.e(),right.e()); + } +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/JetSeedBuilder.h b/Reconstruction/tauRec/tauRec/JetSeedBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..1f9cec13fcbd379dcbb62493dd3766e43c0284f1 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/JetSeedBuilder.h @@ -0,0 +1,54 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_JETSEEDBUILDER_H +#define TAUREC_JETSEEDBUILDER_H + +#include "tauRec/TauToolBase.h" + + +/** + * @brief Class to build tauRec seeds from topojets. + * + * Sets the jet ElementLink and basic kinematic variables in TauJet by searching a matching jet to the tau direction. + * Also the mass of the tau is set to 0. + * With tauRec4 the JetSeedBuilder method is the only one to search for a tau candidates. + * The author of the tau candidate is set 1 (former calo-only seeded) and 3 (former calo+track-seeded) to keep backwards compatibility. + * + * @author N.Meyer <nicom@cern.ch> + * @author Felix Friedrich +*/ + +class JetSeedBuilder : public TauToolBase { +public: + + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + JetSeedBuilder(const std::string& type, + const std::string& name, + const IInterface * parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + virtual ~JetSeedBuilder(); + + virtual StatusCode initialize(); + + virtual StatusCode execute(TauCandidateData * data); + + virtual StatusCode eventFinalize(TauCandidateData *data); + + virtual void cleanup(TauCandidateData *) { } + +private: + std::string m_jetCollectionName; + float m_maxJetdist; + float m_minJetPt; + bool m_switch_jets_em_scale; +}; + +#endif /* JETSEEDBUILDER_H */ + diff --git a/Reconstruction/tauRec/tauRec/KineUtils.h b/Reconstruction/tauRec/tauRec/KineUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..28d5e0bf25734cf82cbdb1f5d5c1e94bc585fd6f --- /dev/null +++ b/Reconstruction/tauRec/tauRec/KineUtils.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_KINEUTILS_H +#define TAUREC_KINEUTILS_H + + +#include <string> +#include "TVector2.h" + +//static const double kPI = 3.1415927; +//static const double k2PI = 2*3.1415927; + +//! +//! @class Tau1P3PKineUtils +//! @brief Provides methods for simple kinematical calculations +//! +//! Provides methods for simple kinematical calculations: absolute value +//! of difference in pseudorapidity, in phi position, half-opening angle +//! in ( eta, phi ) space +//! + +class Tau1P3PKineUtils +{ + public: + //! + //! Calculates absolute value for difference in eta position + //! + //! @param x eta position of object 1 + //! @param y eta position of object 2 + //! + static double deltaEta(double eta1, double eta2) { return std::fabs( eta1 - eta2);} + + //! + //! Calculates absolute value for difference in phi position, + //! corrected for 2pi symmetry + //! + //! @param x phi position of object 1 + //! @param y phi position of object 2 + //! + + /* + static double deltaPhi(double phi1, double phi2) + { + + double dphi = std :: fabs( phi1 - phi2 ); + if( dphi > kPI ) dphi -= k2PI; + return std :: fabs( dphi ); + } + */ + static double deltaPhi(double phi1, double phi2) + { + return TVector2::Phi_mpi_pi(phi1-phi2); + } + + //! + //! Calculates half-opening angle in (eta,phi) space + //! + //! @param x detphi of two objects + //! @param y deteta of two objects + //! + static double deltaR(double de,double dp) { return std::sqrt(de*de+dp*dp); } + static double deltaR(double eta1, double phi1, double eta2, double phi2) { + return std::sqrt(deltaEta(eta1,eta2)*deltaEta(eta1,eta2)+deltaPhi(phi1,phi2)*deltaPhi(phi1,phi2)); + } + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/LockTauContainers.h b/Reconstruction/tauRec/tauRec/LockTauContainers.h new file mode 100644 index 0000000000000000000000000000000000000000..917b2f379110e4dfe344d9eec4bfc494b296bb41 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/LockTauContainers.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_LOCKTAUCONTAINERS_H +#define TAUREC_LOCKTAUCONTAINERS_H + +#include "tauRec/TauToolBase.h" + +/** + * @brief Set tau containers to const to prevent downstream modification. + * + * @author Felix Friedrich + */ + +class LockTauContainers : public TauToolBase +{ + public: + LockTauContainers(const std::string& type, + const std::string& name, + const IInterface* parent); + + ~LockTauContainers() { } + + virtual StatusCode initialize() { return StatusCode::SUCCESS; } + virtual StatusCode execute( TauCandidateData* ) { return StatusCode::SUCCESS; } + virtual StatusCode eventFinalize( TauCandidateData *data ); +}; + +#endif /* TAUREC_LOCKTAUCONTAINERS_H */ + diff --git a/Reconstruction/tauRec/tauRec/PhotonConversionPID.h b/Reconstruction/tauRec/tauRec/PhotonConversionPID.h new file mode 100644 index 0000000000000000000000000000000000000000..961274b1dff118f52165465bd15abbe68390bb94 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/PhotonConversionPID.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_PHOTONCONVERSIONPID_H +#define TAUREC_PHOTONCONVERSIONPID_H + +#include "tauRec/TauToolBase.h" + +/** + * @brief This tool identifies Conversion Candidates via a cut on the electron probability provided by the TRT PID Tool. + * + * Such Photon Conversions are needed e.g. to find Photon Conversions within the tau decay cone. + * + * @author M. Boehler + */ + +class PhotonConversionPID : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + + PhotonConversionPID(const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + ~PhotonConversionPID(); + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode eventFinalize(TauCandidateData *data); + +private: + int m_ownPolicy; + + std::string m_ConversionCandidatesName; + std::string m_ConversionOutputName; + + double m_eProb_cut; +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h b/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h new file mode 100644 index 0000000000000000000000000000000000000000..b07abfa376cb6655b1dd996ff81cf5cc257d5855 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/PhotonConversionVertex.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_PHOTONCONVERSIONVERTEX_H +#define TAUREC_PHOTONCONVERSIONVERTEX_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" + +namespace Analysis { + class TauJetContainer; +} + +namespace Rec { + class TrackParticle; +} + +namespace InDet { + class IVertexFinder; +} + +/** + * @brief Class that runs the tau conversion finding algorithm + * + * This tool identifies conversion candidates + * in/near (definable) a tau decay cone by reconstructing the conversion vertices + * and applying a set of cuts optimized for tau conversions on the vertex parameters. + * + * @author KG Tan <Kong.Guan.Tan@cern.ch> + * + */ + +class PhotonConversionVertex : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor and Destructor + //------------------------------------------------------------- + PhotonConversionVertex(const std::string& type, + const std::string& name, + const IInterface* parent); + ~PhotonConversionVertex(); + + //------------------------------------------------------------- + //! Algorithm functions + //------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode eventFinalize(TauCandidateData *data); + +private: + //------------------------------------------------------------- + //! Convenience functions to handle storegate objects + //------------------------------------------------------------- + template <class T> + bool openContainer(T* &container, std::string containerName); + + template <class T> + bool saveContainer(T* &container, std::string containerName); + + template <class T> + bool retrieveTool(T &tool); + + //------------------------------------------------------------- + //! Gets the minimum dR between a particle and a set of taus + //------------------------------------------------------------- + double getMinDrTauDecay(const xAOD::TauJetContainer* tauJetCont, const xAOD::TrackParticle *trackParticle); + +private: + //------------------------------------------------------------- + //! Storegate names of input containers and output containers + //------------------------------------------------------------- + std::string m_inputTauJetContainerName; + std::string m_inputTrackParticleContainerName; + std::string m_outputConversionVertexContainerName; + + //------------------------------------------------------------- + //! Input parameters for conversion finding + //------------------------------------------------------------- + double m_maxTauJetDr; + + //------------------------------------------------------------- + //! Tool used by conversion finding, initialised in job options + //------------------------------------------------------------- + ToolHandle<InDet::IVertexFinder> m_vertexFinderTool; +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauAxisSetter.h b/Reconstruction/tauRec/tauRec/TauAxisSetter.h new file mode 100644 index 0000000000000000000000000000000000000000..0608e5a0dca95341537c1478700ff0046f6c7a77 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauAxisSetter.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUAXISSETTER_H +#define TAUREC_TAUAXISSETTER_H + +#include "tauRec/TauToolBase.h" + + +/** + * @brief Set Tau "Detector Axis" and "Intermediate Axis". + * + * Note that both axes starts from the barycenter of the cluster associated to the jet seed. + * Then only the 4-vectors of clusters in a cone of dR around these barycenter are summed up, forming the new axis. + * For the "Intermediate Axis" the clusters are correct wrt tau vertex in this step (barycenter remains the same). + * Using this procedure, the axes are different from the original jet seed axis. + * + * @author Margar Simonyan + * @author Felix Friedrich + * + */ + +class TauAxisSetter : public TauToolBase { +public: + + TauAxisSetter(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauAxisSetter(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData * data); + virtual StatusCode finalize(); + virtual StatusCode execute(TauCandidateData *data); + +private: + std::string tauContainerKey; + + double m_clusterCone; + /** + * enable cell origin correction + * eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doCellCorrection; +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauBuilder.h b/Reconstruction/tauRec/tauRec/TauBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..8b46391c97c312129f012aaefd251a46b66f5f3d --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauBuilder.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUBUILDER_H +#define TAUREC_TAUBUILDER_H + +#include "GaudiKernel/ToolHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" + +#include "tauRec/TauToolBase.h" + +/** + * @brief Main class for tau candidate building and processing. + * + * This class loop over seeds from the seed container, + * creates a new tau candidate if seed is passing the given cuts, + * and run the given tau tools on the created tau candidate. + * If a tool fails the tau candidate will be removed. + * + * @authors Srini Rajagopalan, Michael Heldmann, Lukasz Janyst, Anna Kaczmarska, Felix Friedrich + */ + +class TauBuilder : public AthAlgorithm +{ + public: + //----------------------------------------------------------------- + // Constructor and destructor + //----------------------------------------------------------------- + TauBuilder(const std::string &name, ISvcLocator *pSvcLocator); + ~TauBuilder(); + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + + private: + std::string m_tauContainerName; //!< tau output container + std::string m_tauAuxContainerName; //!< tau output aux store container + std::string m_seedContainerName; //!< seed input container + double m_maxEta; //!< only build taus with eta_seed < m_maxeta + double m_minPt; //!< only build taus with pt_seed > m_minpt + + /** switch to create tau containers, + * if false tau containers will be updated only + */ + bool m_doCreateTauContainers; + + ToolHandleArray<TauToolBase> m_tools; //!< tools to process tau candidates +} ; + +#endif // TAUREC_TAUBUILDER_H diff --git a/Reconstruction/tauRec/tauRec/TauCalibrateEM.h b/Reconstruction/tauRec/tauRec/TauCalibrateEM.h new file mode 100644 index 0000000000000000000000000000000000000000..a3921820407648a8d7b20c229b5f52f87f89a55e --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauCalibrateEM.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCALIBRATEEM_H +#define TAUREC_TAUCALIBRATEEM_H + +#include <string> +#include <tauRec/TauToolBase.h> + +class TF1; + +/** implementation of tau EM energy scale (depreciated) */ +class TauCalibrateEM : public TauToolBase { +public: + TauCalibrateEM(const std::string& type, const std::string& name, const IInterface* parent); + ~TauCalibrateEM(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + // private methods + double evaluate_new_pt(double pt, double eta, int ntrack, double emfrac); + + // configurables + std::string m_response_functions_file; + + // private data + TF1* m_f1_1p_lem; + TF1* m_f1_1p_hem_barrel; + TF1* m_f1_1p_hem_crack; + TF1* m_f1_1p_hem_endcap; + TF1* m_f1_mp_barrel; + TF1* m_f1_mp_crack; + TF1* m_f1_mp_endcap; + + std::pair<double, double> m_min_1p_lem; + std::pair<double, double> m_min_1p_hem_barrel; + std::pair<double, double> m_min_1p_hem_crack; + std::pair<double, double> m_min_1p_hem_endcap; + std::pair<double, double> m_min_mp_barrel; + std::pair<double, double> m_min_mp_crack; + std::pair<double, double> m_min_mp_endcap; + +}; + +#endif /* TAUCALIBRATEEM_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauCalibrateLC.h b/Reconstruction/tauRec/tauRec/TauCalibrateLC.h new file mode 100644 index 0000000000000000000000000000000000000000..4b3f11c3462f0d3c8bbe495a5bdcc2c9d5e1afba --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauCalibrateLC.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCALIBRATELC_H +#define TAUREC_TAUCALIBRATELC_H + +#include "tauRec/TauToolBase.h" + +class TH1; +class TF1; + +/** + * @brief Implementation of tau energy scale (TES) with eta and pile-up correction. + * + * The energy and eta (direction) correction are done separatly and steered by flags. + * + * @author Margar Simonyan + * @author Felix Friedrich + * + */ + +class TauCalibrateLC : public TauToolBase { +public: + + TauCalibrateLC(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauCalibrateLC(); + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode execute(TauCandidateData *data); + +private: + std::string tauContainerKey; + std::string vertexContainerKey; + std::string calibrationFile; //!< energy calibration file + + static const int nProngBins = 2; + + const TF1 * calibFunc[nProngBins][10]; //maximum 10 eta bins; might not be used on the whole + const TH1 * slopeNPVHist[nProngBins]; + const TH1 * etaBinHist; + const TH1 * etaCorrectionHist; + + unsigned int m_minNTrackAtVertex; + int m_nEtaBins; + double m_averageNPV; + + bool m_doEnergyCorr; //!< switch for energy correction + bool m_doAxisCorr; //!< switch for eta correction + bool m_printMissingContainerINFO; + + double m_clusterCone; //obsolete +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauCandidateData.h b/Reconstruction/tauRec/tauRec/TauCandidateData.h new file mode 100644 index 0000000000000000000000000000000000000000..7498f6a32d77c199cd9c499a9c3ecce25b44d747 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauCandidateData.h @@ -0,0 +1,106 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_CANDIDATE_DATA_H +#define TAUREC_CANDIDATE_DATA_H +//----------------------------------------------------------------------------- +// file: TauCandidateData.h +// package: Reconstruction/tauEvent +// authors: Lukasz Janyst +// date: 2007-02-13 +// +// MODIFICATIONS +// 2008-04-22 nicom: moved setObject()/getObject() to TauCandidateData +// +//----------------------------------------------------------------------------- + +#include <string> +#include <map> +#include <boost/any.hpp> + +#include "tauEvent/TauJet.h" +#include "tauEvent/TauJetContainer.h" +#include "tauEvent/TauDetails.h" +#include "tauEvent/TauDetailsContainer.h" + + +#include "xAODTau/TauJet.h" +#include "xAODTau/TauJetContainer.h" +#include "xAODTau/TauJetAuxContainer.h" +#include "xAODJet/Jet.h" + + +/** + * @brief The tau candidate object. + * + * Holds all containers and information needed for the tau reconstruction process. + * + * @authors Lukasz Janyst + */ + +struct TauCandidateData +{ + //----------------------------------------------------------------- + //! Associate some object to a key - this is meant to be used by + //! TrigTauRec to pass container pointers to tauRec tools + //----------------------------------------------------------------- + template <typename P> + void setObject( std :: string key, P ptr ); + + //----------------------------------------------------------------- + //! Check if something has been associated with given key + //----------------------------------------------------------------- + bool hasObject( std :: string key ) const; + + //----------------------------------------------------------------- + //! Get the pointer associated with given key, if types don't + //! match boost :: bad_any_cast exception is thrown + //----------------------------------------------------------------- + template <typename P> + StatusCode getObject( std :: string key, P &ptr ); + + xAOD::TauJet *xAODTau; + xAOD::TauJetContainer* xAODTauContainer; + xAOD::TauJetAuxContainer *tauAuxContainer; + //think about changing this to IParticle + const xAOD::Jet *seed; + const xAOD::JetContainer *seedContainer; + unsigned int detailsNum; + + std :: map<std :: string, boost :: any> m_ptrMap; +}; + +//------------------------------------------------------------------------- +// Set pointer +//------------------------------------------------------------------------- + template <typename P> +inline void TauCandidateData :: setObject( std :: string key, P ptr ) +{ + m_ptrMap[key] = ptr; +} + +//------------------------------------------------------------------------- +// Get pointer +//------------------------------------------------------------------------- + template <typename P> +inline StatusCode TauCandidateData :: getObject( std :: string key, P &ptr ) +{ + std :: map< std :: string, boost :: any> :: iterator p_it; + p_it = m_ptrMap.find( key ); + if( p_it == m_ptrMap.end() ) + return StatusCode :: FAILURE; + + ptr = boost :: any_cast<P>( (*p_it).second ); + return StatusCode :: SUCCESS; +} + +//------------------------------------------------------------------------- +// Test if any pointer has been associated with given key +//------------------------------------------------------------------------- +inline bool TauCandidateData :: hasObject( std :: string key ) const +{ + return m_ptrMap.find( key ) != m_ptrMap.end(); +} + +#endif // TAU_CANDIDATE_DATA diff --git a/Reconstruction/tauRec/tauRec/TauCellVariables.h b/Reconstruction/tauRec/tauRec/TauCellVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..dae7f12d5b417f135f4d3d8440006444e63ac6d9 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauCellVariables.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCELLVARIABLES_H +#define TAUREC_TAUCELLVARIABLES_H + +#include "tauRec/TauToolBase.h" + +class LArEM_ID; +class TileID; + +/** + * @brief Calculate tau calorimeter variables from cell information. + * + * @authors Srini Rajagopalan, Anna Kaczmarska, Felix Friedrich + */ + +class TauCellVariables : public TauToolBase { + +public: + TauCellVariables(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauCellVariables(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + +private: + double m_cellEthr; //!< EM cell E threshold + double m_stripEthr; //!< cell E threshold for strips + double m_EMSumThr; //!< threshold for 4-vector EM sum + double m_EMSumR; //!< radius for 4-vector EM sum + double m_cellCone; //!< outer cone for cells used in calculations + + const LArEM_ID* m_emid; + const TileID* m_tileid; + + /** + * enable cell origin correction + * eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doCellCorrection; +}; + +#endif /* TAUREC_TAUCELLVARIABLES_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h b/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h new file mode 100644 index 0000000000000000000000000000000000000000..71e548d15c15923b56f8af69d4e9ce3782fd2eb2 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauCommonCalcVars.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCOMMONCALCVARS_H +#define TAUREC_TAUCOMMONCALCVARS_H + +#include "tauRec/TauToolBase.h" + + +/** + * @brief Calculate variables which rely on tracks and precalculated cell/cluster information. + * + * All variables here can be recalculated using AODs. + * + * @author Stan Lai + * @author Felix Friedrich + */ + +class TauCommonCalcVars : public TauToolBase { +public: + //----------------------------------------------------------------- + // Constructor and destructor + //----------------------------------------------------------------- + TauCommonCalcVars(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauCommonCalcVars(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +}; + +#endif // TAUREC_TAUCOMMONCALCVARS_H diff --git a/Reconstruction/tauRec/tauRec/TauConversionFinder.h b/Reconstruction/tauRec/tauRec/TauConversionFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..5166e7cf9e1752dd0d4f7161367bc49291e2937d --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauConversionFinder.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCONVERSIONFINDER_H +#define TAUREC_TAUCONVERSIONFINDER_H + +#include <tauRec/TauToolBase.h> + +/** + * @brief This tool identifies if a tau track is reconstructed as photon conversion track too. + * + * @author M. Boehler + */ + +class TauConversionFinder : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + TauConversionFinder(const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + ~TauConversionFinder(); + + virtual StatusCode initialize(); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + std::string m_vxCandidatesName; + std::string m_trackContainerName; + std::string m_ConversionCandidatesName; + + bool m_do_normal; + double m_eProb_cut; + bool m_adjust_tau_charge; + + int m_numLooseProng; + int m_numProng; + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauConversionTagger.h b/Reconstruction/tauRec/tauRec/TauConversionTagger.h new file mode 100644 index 0000000000000000000000000000000000000000..4cfc2806603b624b6d3ea356b90f11b4583d6100 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauConversionTagger.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCONVERSIONTAGGER_H +#define TAUREC_TAUCONVERSIONTAGGER_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "ITrackToVertex/ITrackToVertex.h" + +/** + * @brief This tool identifies if a tau track originates from a photon conversion track. + * + * @author D. Varouchas + */ + + +class TauConversionTagger : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + TauConversionTagger(const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + ~TauConversionTagger(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + + std::string m_trackContainerName; + + int m_ConvTaggerVer; + bool m_TrkIsConv; + bool m_storeFullSummary; + bool m_doTRTRatio; + float m_a_cut[2][2], m_b_cut[2][2]; + float m_TRTHighTOutliersRatio; + ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool; + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h b/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..f3f41c8fbae181c708d1a98e805391d700d67fa5 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauElectronVetoVariables.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAU1P3PELEVETO_H +#define TAUREC_TAU1P3PELEVETO_H + +#include "tauRec/TauToolBase.h" + +class IExtrapolateToCaloTool; + +/** + * @brief Calculate variables sensitive on electrons. + * + * The variables are mainly used by the electron veto in the TauDiscriminant package. + * + * @author Zofia Czyczula + */ + +class TauElectronVetoVariables : public TauToolBase { +public: + + TauElectronVetoVariables(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual ~TauElectronVetoVariables(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + + bool m_doCellCorrection; //!< enable cell origin correction + ToolHandle<IExtrapolateToCaloTool> m_trackToCalo; +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h b/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h new file mode 100644 index 0000000000000000000000000000000000000000..47afcbe32829fd6d538bfe712d76d106648f7c38 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauGenericPi0Cone.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauGenericPi0Cone.h +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-04 +// +// +//----------------------------------------------------------------------------- + +#ifndef TAUREC_TAUGENERICPI0CONE_H +#define TAUREC_TAUGENERICPI0CONE_H + +#include "tauRec/TauToolBase.h" + +class TauGenericPi0Cone : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + TauGenericPi0Cone(const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + ~TauGenericPi0Cone(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + + float m_pi0conedr; + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h b/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h new file mode 100644 index 0000000000000000000000000000000000000000..d22cb783839d6566551e385f05760433d762454d --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauPi0BonnClusterCreator.h @@ -0,0 +1,109 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0BONNCLUSTERCREATOR_H +#define TAUREC_TAUPI0BONNCLUSTERCREATOR_H + +#include <string> +#include <vector> +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "tauRec/TauToolBase.h" +#include "xAODPFlow/PFOAuxContainer.h" + +using std::vector; + +class IExtrapolateToCaloTool; + +/** + * @brief Creates Pi0 clusters ("Bonn" Pi0 Finder). + * + * @author Veit Scharf + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + */ + +class TauPi0BonnClusterCreator : public TauToolBase { +public: + TauPi0BonnClusterCreator(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauPi0BonnClusterCreator(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + +private: + + + /** @brief fraction of cluster enegry in central EM1 cells */ + float getEM1CoreFrac( const xAOD::CaloCluster* /*pi0Candidate*/); + + /** @brief asymmetry of cluster energy distribution in EM1 w.r.t. the tracks */ + float getAsymmetryInEM1WRTTrk( const xAOD::CaloCluster* /*pi0Candidate*/, + const vector<vector<float> > /*tracksEtaAtSampling*/, + const vector<vector<float> > /*tracksPhiAtSampling*/); + + + /** @brief number of cells from cluster with positive energy in PS, EM1 and EM2 */ + vector<int> getNPosECells( const xAOD::CaloCluster* /*pi0Candidate*/); + + std::map<unsigned, xAOD::CaloCluster*> getClusterToShotMap( + const std::vector<const xAOD::PFO*> shotVector, + const xAOD::CaloClusterContainer* pPi0ClusterContainer, + xAOD::TauJet *pTau); + + std::vector<unsigned> getShotsMatchedToCluster( + const std::vector<const xAOD::PFO*> shotVector, + std::map<unsigned, xAOD::CaloCluster*> clusterToShotMap, + xAOD::CaloCluster* pPi0Cluster); + + int getNPhotons( const std::vector<const xAOD::PFO*> /*shotVector*/, + std::vector<unsigned> /*shotsInCluster*/); + + /** @brief first eta moment in PS, EM1 and EM2 w.r.t cluster eta: (eta_i - eta_cluster) */ + vector<float> get1stEtaMomWRTCluster( const xAOD::CaloCluster* /*pi0Candidate*/); + + /** @brief second eta moment in PS, EM1 and EM2 w.r.t cluster eta: (eta_i - eta_cluster)^2 */ + vector<float> get2ndEtaMomWRTCluster(const xAOD::CaloCluster* /*pi0Candidate*/); + + /** @brief get extrapolated track position at each layer */ + void getExtrapolatedPositions( const xAOD::TrackParticle* /*track*/, + vector<float>& /*trackToCaloEta*/, + vector<float>& /*trackToCaloPhi*/); + + + + /** @brief tool handles */ + ToolHandle<IExtrapolateToCaloTool> m_trackToCaloTool; + + /** @brief all calo cell container name */ + std::string m_cellContainerName; + + /** @brief input cluster container of pi0 candidates */ + // TODO: input cluster container name + std::string m_inputPi0ClusterContainerName; + + /** @brief output cluster container of pi0 candidates */ + // TODO: output cluster container name + std::string m_outputPi0ClusterContainerName; + + /** @brief new neutral PFO container and name */ + xAOD::PFOContainer* m_neutralPFOContainer; + std::string m_neutralPFOContainerName; + xAOD::PFOAuxContainer* m_neutralPFOAuxStore; + + + /** @brief pt threshold for pi0 candidate clusters */ + double m_clusterEtCut; + + /** @brief output cluster container */ + xAOD::CaloClusterContainer* m_pOutputPi0CaloClusterContainer; + +}; + +#endif /* TAUPI0BONNCLUSTERCREATOR_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h b/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h new file mode 100644 index 0000000000000000000000000000000000000000..0e168202660506455cfcfbb8c6df4bd96bae59e2 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauPi0BonnCreateROI.h @@ -0,0 +1,127 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0BONNCREATEROI_H +#define TAUREC_TAUPI0BONNCREATEROI_H + +#include <string> +#include <vector> +#include <boost/scoped_ptr.hpp> +#include <map> + +#include "GaudiKernel/ToolHandle.h" +#include "tauRec/TauToolBase.h" + +#include "xAODPFlow/PFOAuxContainer.h" +#include "xAODCaloEvent/CaloClusterContainer.h" +#include "xAODTau/TauJet.h" + + + +class IHadronicCalibrationTool; +class IExtrapolateToCaloTool; +class ICaloCellMakerTool; +class TauOriginCorrectionTool; +class TauPi0BonnParser; +/** + * @brief Create ROIs for the "Bonn" Pi0 Finder. + * + * @author Veit Scharf + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + */ + +class TauPi0BonnCreateROI : public TauToolBase { +public: + TauPi0BonnCreateROI(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauPi0BonnCreateROI(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + + /** @brief get extrapolated track position at each layer */ + void getExtrapolatedPositions( std::vector<const xAOD::TrackParticle*>, + int sampling); + + + /** @brief get hadronic energy associated to the tracks */ + std::vector<double> getEstEcalEnergy( std::vector<const xAOD::TrackParticle*>, + const xAOD::CaloClusterContainer*, + const xAOD::TauJet*); + + /** @brief get cell weight from lateral shape */ + double getLatWeight( int /* samp */, + double /* deltaEta */, + double /* deltaPhi */, + double /* cellWidthEta */, + double /* cellWidthPhi */, + unsigned /* trackNumber */, + const xAOD::TrackParticle* /* track */ + ); + + /** @brief store cell in output container */ + void storeCell(const CaloCell* /* cell*/, + double /* subtractedEnergy */); + + + /** @brief tool handles */ + ToolHandle<IHadronicCalibrationTool> m_caloWeightTool; + ToolHandle<IExtrapolateToCaloTool> m_trackToCaloTool; + ToolHandle<ICaloCellMakerTool> m_cellMakerTool; + + /** @brief calo cell navigation */ + const CaloDetDescrManager* m_calo_dd_man; + const CaloCell_ID* m_calo_id; + + /** @brief lateral shower parameteristaion parser */ + boost::scoped_ptr<TauPi0BonnParser> m_latParser; + std::string m_latParFile; + + + /** @brief all calo cell container name */ + std::string m_caloCellContainerName; // TODO: replace with tau clusters? + + /** @brief all cluster container name */ + std::string m_clusterContainerName; // TODO: replace with tau clusters? + + /** @brief output cell container and name*/ + CaloCellContainer *m_pPi0CellContainer; + std::string m_pi0CellContainerName; + + /** @brief new charged PFO container and name */ + xAOD::PFOContainer* m_chargedPFOContainer; + std::string m_chargedPFOContainerName; + xAOD::PFOAuxContainer* m_chargedPFOAuxStore; + + /** @brief map of tracks to normalization factors*/ + std::map<int, TH1*> m_trackHistMapBarrel; + std::map<int, TH1*> m_trackHistMapEndcap; + + /** @brief variables used for shower parameteristaion */ + double m_pt; + double m_abseta; + double m_hadf; + double m_sampling; // its really an int but just use double + // should function correctly in parser + + /** @brief hash map in order to keep track, which cells have been added to output cell container*/ + std::vector<CaloCell*> m_addedCellsMap; + + /** @brief extrapolated position of tracks and vector of bools to keep track for which sampleings this has already been done */ + std::vector<std::vector<double> > m_tracksEtaAtSampling; + std::vector<std::vector<double> > m_tracksPhiAtSampling; + std::vector<bool> m_extrapolatedSamplings; + std::vector<double> m_defaultValues; + std::vector<double> m_defaultValuesZero; +}; + +#endif /* TAUPI0BONNCREATEROI_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h b/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h new file mode 100644 index 0000000000000000000000000000000000000000..dce779fc024b81f35165883f581c39ed4f49fb4e --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauPi0BonnParser.h @@ -0,0 +1,92 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0BONNPARSER_H +#define TAUREC_TAUPI0BONNPARSER_H + +#include <string> +#include <map> +#include <vector> +#include <fstream> +#include "TH1.h" +class TDirectory; + +/** + * @brief Parser to read in shower parameterisations for BonnPi0CreateROI + * + * @author Will Davey <will.davey@cern.ch> + */ + + +class TauPi0BonnParser { + + public: + /** constructor */ + TauPi0BonnParser(); + /** destructor */ + ~TauPi0BonnParser(); + + /** parse input ROOT file */ + bool parseROOTFile(std::string config_file, std::string directory = ""); + + /** set the address of an input variable */ + bool setVar( const std::string& key, double& val); + + /** get vector of input parameters */ + TH1* getTH1(); + + /** get multi-dimensional bin key using stored vals */ + std::string getBinKey(); + + /** summary of config */ + void summary(); + + /** get status of initialisation */ + bool checkInitialisationStatus(); + + /** get string stream (filled incase of errors) */ + std::string getStream(); + + /** set maximum length of the stream buffer */ + void setMaxTraceback(int); + + private: + + /** get multi-dimensional bin key from list of bin indices */ + std::string getBinKey( const std::vector<int>& bin_indices ); + + /** get vector of current values of input parameters */ + std::vector<double> getCurrentVals(); + + /** parse TDirectory */ + bool parseTDirectory( TDirectory*, + std::vector<int> current_bin_store = std::vector<int>(), + int current_index = -1 + ); + + /** check m_par_map is filled with correct keys, given input var binning */ + bool checkConfig( std::vector<int> current_bin_store = std::vector<int>(), + int current_index = -1 + ); + + /** set the stream */ + void msg( const std::string& theMessage ); + + private: + /** maintain parsed bin order */ + std::vector<std::string> m_bin_order; + /** map var names to bin edges */ + std::map<std::string,std::vector<double> > m_bin_map; + /** map multi-dimensional bin key to input vectors */ + std::map<std::string,TH1*> m_hist_map; + /** map var names to current values */ + std::map<std::string,double*> m_curr_val_map; + /** error stream */ + std::string m_stream; + /** maximum length of the error stream buffer */ + int m_max_traceback; +}; + + +#endif /* TAUPI0BONNPARSER_H */ diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h b/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h new file mode 100644 index 0000000000000000000000000000000000000000..cd99b1a7e0c1d01a79ee23c9f8644252f3ecb164 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauPi0BonnScoreCalculator.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0BONNSCORECALCULATOR_H +#define TAUREC_TAUPI0BONNSCORECALCULATOR_H + +#include <string> +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "xAODPFlow/PFO.h" + +namespace TMVA{ + class Reader; +} + +/** + * @brief Selectes pi0Candidates ("Bonn" Pi0 Finder). + * + * @author Veit Scharf + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + */ + +class TauPi0BonnScoreCalculator : public TauToolBase { +public: + TauPi0BonnScoreCalculator(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauPi0BonnScoreCalculator(); + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode execute(TauCandidateData *data); + +private: + + std::string m_readerOption; + TMVA::Reader *m_tmvaReader; + + std::string m_weightfile; + + float m_FIRST_ETA; + float m_SECOND_R; + float m_SECOND_LAMBDA; + float m_Abs_DELTA_PHI; + float m_Abs_DELTA_THETA; + float m_CENTER_LAMBDA_helped; + float m_LATERAL; + float m_LONGITUDINAL; + float m_ENG_FRAC_EM; + float m_ENG_FRAC_MAX; + float m_ENG_FRAC_CORE; + float m_log_SECOND_ENG_DENS; + float m_EcoreOverEEM1; + float m_AsymmetryWRTTrack; + float m_NHitsInEM1; + float m_NPosCells_PS; + float m_NPosCells_EM1; + float m_NPosCells_EM2; + float m_firstEtaWRTCluster_EM1; + float m_firstEtaWRTCluster_EM2; + float m_secondEtaWRTCluster_EM1; + float m_secondEtaWRTCluster_EM2; + float m_energy_EM1; + float m_energy_EM2; + + /** @brief function used to calculate BDT score */ + float calculateScore(const xAOD::PFO* neutralPFO); + + /** @brief Book TMVA methods. */ + StatusCode bookMethod(TMVA::Reader *reader, const std::string &methodName) const; + +}; + +#endif /* TAUPI0BONNSCORECALCULATOR_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h b/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..67a4766f3e0564f01f7fece61e5ac888e8dc44a8 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauPi0BonnSelector.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPI0BONNSELECTOR_H +#define TAUREC_TAUPI0BONNSELECTOR_H + +#include <string> +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" + +class CaloCluster; +namespace Analysis { + class TauCommonDetails; + class TauPi0Details; +} + +/** + * @brief Selectes pi0Candidates ("Bonn" Pi0 Finder). + * + * @author Veit Scharf + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + */ + +class TauPi0BonnSelector : public TauToolBase { +public: + TauPi0BonnSelector(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauPi0BonnSelector(); + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + +private: + + std::vector<float> m_clusterEtCut; + std::vector<float> m_clusterBDTCut_1prong; + std::vector<float> m_clusterBDTCut_mprong; + /** @brief function used to get eta bin of Pi0Cluster */ + int getPi0Cluster_etaBin(double Pi0Cluster_eta); + /** @brief function used to calculate the visible tau 4 momentum */ + TLorentzVector getP4(xAOD::TauJet* tauJet); +}; + +#endif /* TAUPI0BONNSELECTOR_H */ diff --git a/Reconstruction/tauRec/tauRec/TauProcessor.h b/Reconstruction/tauRec/tauRec/TauProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..be77ee5ae866f80d933ef7c05576a5a0539cbca2 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauProcessor.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUPROCESSOR_H +#define TAUREC_TAUPROCESSOR_H + +#include "GaudiKernel/ToolHandle.h" +#include "AthenaBaseComps/AthAlgorithm.h" + +#include "tauRec/TauToolBase.h" + +/** + * @brief Main class for tau candidate building and processing. + * + * This class loop over tau candidates in the tau container placed there by the TauBuilder + * and runs the given tau tools on the tau candidates. The tau objects are !!modified!!. + * If a tool fails, the tau reconstruction will be aborted. + * This algorithm has an AOD mode to skip TauExtraDetailsContainer, that is not available in AODs. + * + * (This algorithm was inspired by TauBuilder.) + * + * @authors Felix Friedrich + */ + +class TauProcessor: public AthAlgorithm +{ + public: + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauProcessor( const std::string &name, ISvcLocator *pSvcLocator ); + ~TauProcessor(); + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + + private: + std :: string m_tauContainerName; + std :: string m_tauAuxContainerName; + bool m_AODmode; + ToolHandleArray<TauToolBase> m_tools; +}; + +#endif // TAUREC_TAUPROCESSOR_H diff --git a/Reconstruction/tauRec/tauRec/TauShotFinder.h b/Reconstruction/tauRec/tauRec/TauShotFinder.h new file mode 100755 index 0000000000000000000000000000000000000000..95511c0b0a5b7822d5ed31c44c924ab544755118 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauShotFinder.h @@ -0,0 +1,158 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUSHOTFINDER_H +#define TAUREC_TAUSHOTFINDER_H + +//#include <string> +//#include <vector> +//#include <map> + +#include "GaudiKernel/ToolHandle.h" +#include "tauRec/TauToolBase.h" +#include "xAODPFlow/PFOAuxContainer.h" +#include "xAODCaloEvent/CaloClusterAuxContainer.h" + +//#include "CaloIdentifier/CaloCell_ID.h" + +class CaloDetDescrManager; +class CaloCell_ID; +class IHadronicCalibrationTool; + +namespace TMVA{ + class Reader; +} + +/** + * @brief Find photon shots in the EM1 strip layer. + * + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + * @author Stephanie Yuen <stephanie.yuen@cern.ch> + */ + +class TauShotFinder : public TauToolBase { +public: + TauShotFinder(const std::string& type, + const std::string& name, + const IInterface *parent); + virtual ~TauShotFinder(); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual StatusCode finalize(); + + virtual void cleanup(TauCandidateData *data); + + + +private: + + /** @brief tool handles */ + ToolHandle<IHadronicCalibrationTool> m_caloWeightTool; + + /** @brief all calo cell container name */ + std::string m_caloCellContainerName; + /** @brief new shot cluster container and name */ + xAOD::CaloClusterContainer* m_shotClusterContainer; + std::string m_shotClusterContainerName; + xAOD::CaloClusterAuxContainer* m_shotClusterAuxStore; + + /** @brief new shot PFO container and name */ + xAOD::PFOContainer* m_PFOShotContainer; + std::string m_shotPFOContainerName; + xAOD::PFOAuxContainer* m_PFOShotAuxStore; + + + /** @brief calo cell navigation */ + const CaloDetDescrManager* m_calo_dd_man; + const CaloCell_ID* m_calo_id; + + /** @brief readers */ + std::string m_readerOption; + + TMVA::Reader *m_tmvaReader_barrel; + std::string m_weightfile_barrel; + + TMVA::Reader *m_tmvaReader_endcap1; + std::string m_weightfile_endcap1; + + TMVA::Reader *m_tmvaReader_endcap2; + std::string m_weightfile_endcap2; + + /** @brief Thanks C++ for ruining my day */ + struct ptSort + { + ptSort( const TauShotFinder& info ); + const TauShotFinder& m_info; + bool operator()( const CaloCell* c1, const CaloCell* c2 ); + }; + + /** @brief get neighbour cells */ + std::vector<const CaloCell*> getNeighbours(const CaloCellContainer*,const CaloCell*,int /*maxDepth*/); + + void addNeighbours(const CaloCellContainer*, + const CaloCell* cell, + std::vector<const CaloCell*>& cells, + int depth, + int maxDepth, + bool next); + + bool isPhiNeighbour(IdentifierHash cell1Hash, IdentifierHash cell2Hash, bool next); + + /** @brief get eta bin */ + float getEtaBin(float /*seedEta*/); + + /** @brief get merged BDTscore */ + float getMergedBDTScore(int /*etaBin*/); + + /** @brief get NPhotons in shot */ + float getNPhotons(int /*etaBin*/, + float /*mergedBDTScore*/, + float /*seedEnergy*/); + + /** @brief Book TMVA methods. */ + StatusCode bookMethod(TMVA::Reader *reader_barrel, + TMVA::Reader *reader_endcap1, + TMVA::Reader *reader_endcap2, + const std::string &methodName) const; + + // number of cells in eta + int m_nCellsInEta; + + // cut values + std::vector<float> m_minPtCut; + std::vector<float> m_autoDoubleShotCut; + std::vector<float> m_mergedBDTScoreCut; + + // BDT input variables + float m_pt1; + float m_pt3; + float m_pt5; + float m_ws5; + float m_sdevEta5_WRTmean; + float m_sdevEta5_WRTmode; + float m_sdevPt5; + float m_deltaPt12_min; + float m_Fside_3not1; + float m_Fside_5not1; + float m_Fside_5not3; + float m_fracSide_3not1; + float m_fracSide_5not1; + float m_fracSide_5not3; + float m_pt1OverPt3; + float m_pt3OverPt5; + + // FIXME: same variable names as in Stephanie's private code atm + float G_PTFRAC; + float G_STDPT_5; + float G_STDETA_5; + float G_DELTAPT_MIN; + +}; + +#endif /* TAUSHOTFINDER_H */ + diff --git a/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h b/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..e2e9b76f8d4ad315c4b9bb865265230825274f4c --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauShotVariableHelpers.h @@ -0,0 +1,79 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @brief implementation of photon shot variable calculation + * + * @author Will Davey <will.davey@cern.ch> + * @author Benedict Winter <benedict.tobias.winter@cern.ch> + * @author Stephanie Yuen <stephanie.yuen@cern.ch> + */ + +#ifndef TAUSHOTVARIABLEHELPERS_H +#define TAUSHOTVARIABLEHELPERS_H + +#include "xAODPFlow/PFO.h" +#include "GaudiKernel/ToolHandle.h" +#include "CaloInterface/IHadronicCalibrationTool.h" + +namespace TauShotVariableHelpers { + + /** @brief get cell block with (currently) 5x2 cells in correct order for variable calculations */ + std::vector<std::vector<const CaloCell*> > getCellBlock(xAOD::PFO* shot, + const CaloCell_ID* calo_id); + + /** @brief mean eta, used by other functions */ + float mean_eta(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief mean pt, used by other functions */ + float mean_pt(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief pt in windows */ + float ptWindow(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + int /*windowSize*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief ws5 variable (egamma) */ + float ws5(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief standard deviation in eta WRT mean */ + float sdevEta_WRTmean(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief standard deviation in eta WRT mode */ + float sdevEta_WRTmode(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief normalized standard deviation in pt */ + float sdevPt(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief pT diff b/w lead and sub-lead cell */ + float deltaPt12_min(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief Fside variable (egamma) */ + float Fside(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + int /*largerWindow*/, + int /*smallerWindow*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief similar than Fside but in unit of eta instead of number of cells */ + float fracSide(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + int /*largerWindow*/, + int /*smallerWindow*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); + + /** @brief pt window fraction */ + float ptWindowFrac(std::vector<std::vector<const CaloCell*> > /*shotCells*/, + int /*largerWindow*/, + int /*smallerWindow*/, + ToolHandle<IHadronicCalibrationTool>& /*m_caloWeightTool*/); +} + +#endif // TAUSHOTVARIABLEHELPERS_H + diff --git a/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h b/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..f6482faaa45c73a841e069023abdaeaa5fd8eda4 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauSubstructureVariables.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUSUBSTRUCTUREBUILDER_H +#define TAUREC_TAUSUBSTRUCTUREBUILDER_H + +#include "tauRec/TauToolBase.h" + +/** + * @brief Calculate variables from the tau substructure. + * + * @author M. Trottier-McDonald + * @author Felix Friedrich + * + */ + +class TauSubstructureVariables : public TauToolBase +{ + public: + + static const double DEFAULT; + + TauSubstructureVariables(const std::string& type, + const std::string& name, + const IInterface* parent); + + ~TauSubstructureVariables(); + + virtual StatusCode execute( TauCandidateData *data ); + + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + + private: + /** Maximal pile up correction in GeV for a tau candidate. + * Used for the caloIso corrected variable. + */ + double m_maxPileUpCorrection; + double m_pileUpAlpha; //!< slope of the pileup correction + + /** + * enable cell origin correction + * eta and phi of the cells are corrected wrt to the origin of the tau vertex + */ + bool m_doVertexCorrection; + bool m_inAODmode; //!< don't update everything if running on AODs +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauTestDump.h b/Reconstruction/tauRec/tauRec/TauTestDump.h new file mode 100644 index 0000000000000000000000000000000000000000..d42af44f555003858cf43376f8b0d96843b3a997 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauTestDump.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUTESTDUMP_H +#define TAUREC_TAUTESTDUMP_H + +#include "tauRec/TauToolBase.h" + + +/** + * @brief Tau Tool for developing, testing and debugging + * + * + * + * @author Felix Friedrich + */ + +class TauTestDump : public TauToolBase { +public: + //----------------------------------------------------------------- + // Constructor and destructor + //----------------------------------------------------------------- + TauTestDump(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauTestDump(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +}; + +#endif // TAUREC_TAUTESTDUMP_H diff --git a/Reconstruction/tauRec/tauRec/TauToolBase.h b/Reconstruction/tauRec/tauRec/TauToolBase.h new file mode 100644 index 0000000000000000000000000000000000000000..8be96fe86e7495be3a775fc0484f6da502df406c --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauToolBase.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TOOLBASE_TAU_H +#define TOOLBASE_TAU_H + +#include <string> + +#include "AthenaBaseComps/AthAlgTool.h" +#include "tauRec/TauCandidateData.h" + +/** + * @brief The base class for all tau tools. + * + * @author Lukasz Janyst + */ + +class TauToolBase: public AthAlgTool +{ + public: + TauToolBase( const std::string &type, + const std::string &name, + const IInterface *parent ); + virtual ~TauToolBase(); + + //----------------------------------------------------------------- + //! InterfaceID implementation needed for ToolHandle + //----------------------------------------------------------------- + static const InterfaceID& interfaceID(); + + //----------------------------------------------------------------- + //! Tool initializer + //----------------------------------------------------------------- + virtual StatusCode initialize(); + + //----------------------------------------------------------------- + //! Event initializer - called at the beginning of each event + //----------------------------------------------------------------- + virtual StatusCode eventInitialize( TauCandidateData *data ); + + //----------------------------------------------------------------- + //! Execute - called for each tau candidate + //----------------------------------------------------------------- + virtual StatusCode execute( TauCandidateData *data ); + + //----------------------------------------------------------------- + //! Cleanup - called for each tau rejected candidate + //----------------------------------------------------------------- + virtual void cleanup( TauCandidateData *data ); + + //----------------------------------------------------------------- + //! Event finalizer - called at the end of each event + //----------------------------------------------------------------- + virtual StatusCode eventFinalize( TauCandidateData *data ); + + //----------------------------------------------------------------- + //! Finalizer + //----------------------------------------------------------------- + virtual StatusCode finalize(); + + //------------------------------------------------------------- + //! Convenience functions to handle storegate objects + //------------------------------------------------------------- + template <class T> + bool openContainer(T* &container, std::string containerName, bool printFATAL=false); + + template <class T> + bool retrieveTool(T &tool); + +}; + +#endif // TOOLBASE_TAU_H diff --git a/Reconstruction/tauRec/tauRec/TauTrackFilter.h b/Reconstruction/tauRec/tauRec/TauTrackFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..4a20fe3f3b4f34568e02a3372450cbbbf33409cc --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauTrackFilter.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTrackFilter.h +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-04 +// +// +//----------------------------------------------------------------------------- + +#ifndef TAUREC_TAUTRACKFILTER_H +#define TAUREC_TAUTRACKFILTER_H + +#include "tauRec/TauToolBase.h" + +class TauTrackFilter : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor + //------------------------------------------------------------- + TauTrackFilter(const std::string& type, + const std::string& name, + const IInterface* parent); + + //------------------------------------------------------------- + //! Destructor + //------------------------------------------------------------- + ~TauTrackFilter(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode finalize(); + +private: + + std::string m_trackContainerName; + std::vector<bool> m_TrkPass; + int m_nProng; + int m_flag; + //TODO some of this probably need to be public to be useful... + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h b/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..443f965f46cd9f53e9f8b1d01344793507c35ff3 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauTrackFilterUtils.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//----------------------------------------------------------------------------- +// file: TauTrackFilterUtils.h +// package: Reconstruction/tauRec +// authors: Robert Clarke, Blake Burghgrave +// date: 2014-01-13 +// +// +//----------------------------------------------------------------------------- + +#ifndef TAUREC_TAUTRACKFILTERUTILS_H +#define TAUREC_TAUTRACKFILTERUTILS_H + +#include "TF1.h" +#include "TLorentzVector.h" +#include <vector> +#include <iostream> +#include <string> + +namespace TauTrackFilterUtils { + + struct TrackInfo{ + TLorentzVector p4; + int charge; + int index; + }; + + struct TrackPair{ + float angle; + float mass; + int charge; + }; + + bool pass3prong(std::vector<TauTrackFilterUtils::TrackInfo> combination,TLorentzVector tau); + bool pass2prong(std::vector<TauTrackFilterUtils::TrackInfo> pair,TLorentzVector tau); + bool pass1prong(TLorentzVector track,TLorentzVector tau); + float ComputePi0Cone(int recProngs,TLorentzVector tau); + float ComputeAngle(float p, float eta, float a[9][4], int npar, int npol, char eqn[] = (char*)"[0]*exp([1]*x)+[2]+[3]/(x*x)"); + float Compute1dim(float p, float a[10], int npar, char eqn[]); + +} + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauTrackFinder.h b/Reconstruction/tauRec/tauRec/TauTrackFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..3281f4b0937aa6b6870212f166aff3b43e2644e5 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauTrackFinder.h @@ -0,0 +1,142 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUTRACKFINDER_H +#define TAUREC_TAUTRACKFINDER_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "ITrackToVertex/ITrackToVertex.h" + +#include "xAODTracking/Vertex.h" +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/TrackParticleContainer.h" + +class IExtrapolateToCaloTool; +namespace Trk { + class ITrackSelectorTool; +} + +///////////////////////////////////////////////////////////////////////////// + +/** + * @brief Associate tracks to the tau candidate. + * + * The tracks have to pass dedicated quality criteria and have to + * match to a primary vertex consistent with the tau origin. + * + * @author KG Tan <Kong.Guan.Tan@cern.ch> + * @author Felix Friedrich + */ + +class TauTrackFinder : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor and Destructor + //------------------------------------------------------------- + TauTrackFinder(const std::string& type, const std::string& name, const IInterface* parent); + ~TauTrackFinder(); + + //------------------------------------------------------------- + //! Enumerator defining type of tau track + //------------------------------------------------------------- + enum TauTrackType + { + TauTrackCore = 0, + TauTrackWide = 1, + TauTrackOther = 2, + NotTauTrack = 3 + }; + + //------------------------------------------------------------- + //! Algorithm functions + //------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual StatusCode finalize(); + + //------------------------------------------------------------- + //! Extrapolate track eta and phi to the calorimeter middle surface + //------------------------------------------------------------- + StatusCode extrapolateToCaloSurface(TauCandidateData *data); + + TauTrackType tauTrackType( const xAOD::TauJet* tauJet, + const xAOD::TrackParticle* trackParticle, + const xAOD::Vertex* primaryVertex); + + void getTauTracksFromPV( const xAOD::TauJet* tauJet, + const xAOD::TrackParticleContainer* trackParticleCont, + const xAOD::Vertex* primaryVertex, + std::vector<const xAOD::TrackParticle*> &tauTracks, + std::vector<const xAOD::TrackParticle*> &wideTracks, + std::vector<const xAOD::TrackParticle*> &otherTracks); + + // old style AOD version + void removeOffsideTracksWrtLeadTrk(std::vector<const Rec::TrackParticle*> &tauTracks, + std::vector<const Rec::TrackParticle*> &wideTracks, + std::vector<const Rec::TrackParticle*> &otherTracks, + const Trk::RecVertex* tauOrigin, + double maxDeltaZ0); + + // new xAOD version + void removeOffsideTracksWrtLeadTrk(std::vector<const xAOD::TrackParticle*> &tauTracks, + std::vector<const xAOD::TrackParticle*> &wideTracks, + std::vector<const xAOD::TrackParticle*> &otherTracks, + const xAOD::Vertex* tauOrigin, + double maxDeltaZ0); + + void getDeltaZ0Values(std::vector<float>& vDeltaZ0coreTrks, std::vector<float>& vDeltaZ0wideTrks); + void resetDeltaZ0Cache(); + +private: + //------------------------------------------------------------- + //! Some internally used functions + //------------------------------------------------------------- + float getZ0(const Rec::TrackParticle* track, const Trk::RecVertex* vertex); //AOD version + float getZ0(const xAOD::TrackParticle* track, const xAOD::Vertex* vertex); //xAOD version + +private: + //------------------------------------------------------------- + //! Storegate names of input containers and output containers + //------------------------------------------------------------- + std::string m_inputTauJetContainerName; + std::string m_inputTrackParticleContainerName; + std::string m_inputPrimaryVertexContainerName; + + //------------------------------------------------------------- + //! tools + //------------------------------------------------------------- + ToolHandle<IExtrapolateToCaloTool> m_trackToCalo; + ToolHandle<Trk::ITrackSelectorTool> m_trackSelectorTool_tau; + ToolHandle<Reco::ITrackToVertex> m_trackToVertexTool; + + //------------------------------------------------------------- + //! Input parameters for algorithm + //------------------------------------------------------------- + double m_maxJetDr_tau; + double m_maxJetDr_wide; + + //------------------------------------------------------------- + // z0 cuts + //------------------------------------------------------------- + float m_z0maxDelta; + bool m_applyZ0cut; + bool m_storeInOtherTrks; + std::vector<float> m_vDeltaZ0coreTrks; + std::vector<float> m_vDeltaZ0wideTrks; + + //------------------------------------------------------------- + //! Convenience functions to handle storegate objects + //------------------------------------------------------------- + template <class T> + bool openContainer(T* &container, std::string containerName, bool printFATAL=false); + + template <class T> + bool retrieveTool(T &tool); + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h b/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h new file mode 100644 index 0000000000000000000000000000000000000000..26ab2eb6194fc3d7b832ed93a8018e73a352f67f --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauTrackSlimmer.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TRACKSLIMMER_TAU_H +#define TAUREC_TRACKSLIMMER_TAU_H + +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaKernel/IThinningSvc.h" +#include "ParticleEvent/ParticleBase.h" +#include <string> + +class StoreGateSvc; + +/** + * @brief Class for tau tracks slimming. + * + * @author Anna Kaczmarska, Lukasz Janyst + */ + +class TauTrackSlimmer: public AthAlgorithm +{ + public: + + //----------------------------------------------------------------- + // Contructor and destructor + //----------------------------------------------------------------- + TauTrackSlimmer( const std::string &name, ISvcLocator *pSvcLocator ); + ~TauTrackSlimmer(); + + //----------------------------------------------------------------- + // Gaudi algorithm hooks + //----------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode execute(); + virtual StatusCode finalize(); + + private: + std :: string m_tauContainerName; + ServiceHandle<IThinningSvc> m_thinningSvc; + bool m_filterTaus; + unsigned m_maxNTrack; + ChargeType m_maxCharge; + double m_maxEmRadius; + double m_maxIsoFrac; + + +}; + +#endif // TAUREC_TRACKSLIMMER_TAU_H diff --git a/Reconstruction/tauRec/tauRec/TauVertexFinder.h b/Reconstruction/tauRec/tauRec/TauVertexFinder.h new file mode 100644 index 0000000000000000000000000000000000000000..3a8ea5dccf5345823cd55e6aa908ee2a7bb98aeb --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauVertexFinder.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUVERTEXFINDER_H +#define TAUREC_TAUVERTEXFNIDER_H + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" +#include "xAODTracking/VertexContainer.h" +#include "JetEDM/TrackVertexAssociation.h" + +///////////////////////////////////////////////////////////////////////////// + +/** + * @brief Associate a vertex (origin) to the tau candidate. + * + * The vertex has to be consistent with the origin of tau jet seed. + * The vertex is determined in the following order: TJVA -> first PV in vertex container -> 0 + * Attention: all downstream tau variables will be calculated to the vertex set here! + * + * @author KG Tan <Kong.Guan.Tan@cern.ch> + * @author Felix Friedrich <Felix.Friedrich@cern.ch> + */ + +class TauVertexFinder : public TauToolBase { +public: + //------------------------------------------------------------- + //! Constructor and Destructor + //------------------------------------------------------------- + TauVertexFinder(const std::string& type, const std::string& name, const IInterface* parent); + ~TauVertexFinder(); + + //------------------------------------------------------------- + //! Algorithm functions + //------------------------------------------------------------- + virtual StatusCode initialize(); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventFinalize(TauCandidateData *data); + virtual StatusCode finalize(); + + ElementLink<xAOD::VertexContainer> getPV_TJVA(const xAOD::TauJet* tauJet, const xAOD::VertexContainer* vertices); + +private: + float getJetVertexFraction(const xAOD::Vertex* vertex, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const; + + //------------------------------------------------------------- + //! Convenience functions to handle storegate objects + //------------------------------------------------------------- + template <class T> + bool openContainer(T* &container, std::string containerName, bool printFATAL=false); + + template <class T> + bool retrieveTool(T &tool); + +private: + bool m_printMissingContainerINFO; + float m_maxJVF; + + //------------------------------------------------------------- + //! Configureables + //------------------------------------------------------------- + bool m_useTJVA; + std::string m_inputPrimaryVertexContainerName; + std::string m_assocTracksName; + std::string m_trackVertexAssocName; +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/TauVertexVariables.h b/Reconstruction/tauRec/tauRec/TauVertexVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..eb830c5ea95adac6c89e42c2660c7b1806580e1e --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TauVertexVariables.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUVERTEXVARIABLES_H +#define TAUREC_TAUVERTEXVARIABLES_H + +#include "xAODTracking/VertexContainer.h" +#include "xAODTracking/VertexAuxContainer.h" +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" + +// forwards +class TauCandidateData; +namespace Trk { + class ITrackToVertexIPEstimator; + class IVertexFitter; + class IVertexSeedFinder; + class IVxCandidateXAODVertex; +} + +/** + * + * @brief Class for calculating vertex variables. + * + * @authors Stan Lai, Felix Friedrich + */ + +class TauVertexVariables : public TauToolBase { +public: + //----------------------------------------------------------------- + // Constructor and destructor + //----------------------------------------------------------------- + TauVertexVariables(const std::string& type, + const std::string& name, + const IInterface* parent); + ~TauVertexVariables(); + + virtual StatusCode initialize(); + virtual StatusCode execute(TauCandidateData *data); + virtual StatusCode eventInitialize(TauCandidateData *data); + virtual StatusCode finalize(); + + //------------------------------------------------------------- + //! determines the transverse flight path significance from + //! the primary vertex and the secondary vertex of tau candidate + //------------------------------------------------------------- + double trFlightPathSig(TauCandidateData *data, const xAOD::Vertex *secVertex); + +private: + std::string m_primaryVertexKey; + std::string m_inputTrackParticleContainerName; + bool m_useOldSeedFinderAPI; + ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimator; + ToolHandle< Trk::IVertexFitter > m_fitTool; //!< Pointer to the base class of the fit algtools + ToolHandle< Trk::IVertexSeedFinder > m_SeedFinder; + ToolHandle< Trk::IVxCandidateXAODVertex > m_xaodConverter; // necessary to convert VxCandidate to xAOD::Vertex in case old API is used + + xAOD::VertexContainer* m_pSecVtxContainer; + xAOD::VertexAuxContainer* m_pSecVtxAuxContainer; +}; + +#endif /* TAUREC_TAUVERTEXVARIABLES_H */ + diff --git a/Reconstruction/tauRec/tauRec/TrackSort.h b/Reconstruction/tauRec/tauRec/TrackSort.h new file mode 100644 index 0000000000000000000000000000000000000000..0952a84161d9cae68e396e0d55fb7542f73cbba7 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/TrackSort.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TRACKSORT_H +#define TAUREC_TRACKSORT_H + +#include "Particle/TrackParticle.h" +#include "Particle/TrackParticleContainer.h" +#include "xAODTracking/TrackParticle.h" +#include "AthLinks/ElementLink.h" + +/** + * @brief Helper method to sort tracks + * + * Usage: + * sort(track_begin, track_end, tauTrackSort); + * We want pt0 > pt1 > ..., so the test on ptInvVert is < . + * + */ + +class TrackSort { + + public: + TrackSort(){ }; + + bool operator() (const ElementLink<Rec::TrackParticleContainer>& t1, const ElementLink<Rec::TrackParticleContainer> &t2) const + { + return fabs( (*t1)->pt() ) > fabs( (*t2)->pt() ); + }; + + bool operator() ( const Rec::TrackParticle *t1, const Rec::TrackParticle *t2 ) const + { + return fabs( t1->pt() ) > fabs( t2->pt() ); + }; + + bool operator() ( const xAOD::TrackParticle *t1, const xAOD::TrackParticle *t2 ) const + { + return fabs( t1->pt() ) > fabs( t2->pt() ); + }; + +}; + +#endif diff --git a/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h b/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h new file mode 100644 index 0000000000000000000000000000000000000000..c73088aad2affda80be2727e3da35ea57b277970 --- /dev/null +++ b/Reconstruction/tauRec/tauRec/tauCalibrateWeightTool.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TAUREC_TAUCALIBRATEWEIGHTTOOL_H +#define TAUREC_TAUCALIBRATEWEIGHTTOOL_H +/******************************************************************** +(depreciated!) + +NAME: tauCalibrateWeightTool.h +PACKAGE: offline/Reconstruction/tauRec +AUTHORS: M.Heldmann +CREATED: March 15, 2005 + +See comments in tauCalibrateWeightTool.cxx. + +13/12/2008 - (AK) change to extrapolation of TP instead of Track+code cleaning + ********************************************************************/ + +#include "tauRec/TauToolBase.h" +#include "GaudiKernel/ToolHandle.h" + + +class TauCandidateData; +class LArEM_ID; +class TileID; +class IHistogram1D; +class IHadronicCalibrationTool; + +//------------------------------------------------------------- +//! Class for applying H1-weighting on calorimeter cells and fudge factor for tau energy +//------------------------------------------------------------- +class tauCalibrateWeightTool : public TauToolBase +{ + public: + enum calibrateType { calCells = 0, calJets, calTracks, calCluster, calTopocluster }; + + tauCalibrateWeightTool(const std::string& type, + const std::string& name, + const IInterface* parent); + ~tauCalibrateWeightTool(); + + virtual StatusCode initialize(); + virtual StatusCode finalize(); + virtual StatusCode execute( TauCandidateData *data ); + + // Accessor methods: + + private: + int m_calibrateType; + ToolHandle<IHadronicCalibrationTool> m_caloWeightTool; + + const LArEM_ID* m_emid; + const TileID* m_tileid; + + std::string m_cellWeightTool; + std::vector<float> m_poly; + + bool m_applyCellWeightEM; + bool m_applyCellWeightHad; + bool m_applyPtEtaCorrFactors; + bool m_validCaloWeightTool; + bool m_doEtaInterpolation; + + float m_fudge; + double m_cellCone; + + int m_nptbins; + int m_netabins; + + std::vector<float> m_ptpoints; + std::vector<float> m_etapoints; + std::vector<float> m_ptetacorrectionsntr1; + std::vector<float> m_ptetacorrectionsntr23; +}; + +#endif