diff --git a/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h b/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h index 5c7b9f124a658f289d28ba05883237acf2250eb5..ca5f6ba75508286aee71dc93b7c710f7d294aa0e 100644 --- a/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h +++ b/Reconstruction/eflowRec/eflowRec/eflowCaloObject.h @@ -65,7 +65,7 @@ public: /* Link accessor methods */ - std::vector<eflowTrackClusterLink*> efRecLink() { return m_trackClusterLinks; } + std::vector<eflowTrackClusterLink*> efRecLink() const { return m_trackClusterLinks; } void clearLinks() { m_trackClusterLinks.clear(); } /* Sets up static container of CaloClusters. This function does not own the objects, diff --git a/Reconstruction/eflowRec/eflowRec/eflowRecCluster.h b/Reconstruction/eflowRec/eflowRec/eflowRecCluster.h index 15f339d354408ab676c0b02c13b4063a320912ec..2d884ef983143c2ce60166073d02222823ab40d9 100644 --- a/Reconstruction/eflowRec/eflowRec/eflowRecCluster.h +++ b/Reconstruction/eflowRec/eflowRec/eflowRecCluster.h @@ -38,7 +38,8 @@ public: xAOD::CaloCluster* getClusterForModification(xAOD::CaloClusterContainer* container); ElementLink<xAOD::CaloClusterContainer> getClusElementLink() const { return m_clusElementLink; } - + ElementLink<xAOD::CaloClusterContainer> getOriginalClusElementLink() const { return m_originalClusElementLink; } + eflowMatchCluster* getMatchCluster() const { return m_matchCluster.get(); } double getSumExpectedEnergy(); @@ -60,6 +61,7 @@ public: private: int m_clusterId; const xAOD::CaloCluster* m_cluster; + ElementLink<xAOD::CaloClusterContainer> m_originalClusElementLink; ElementLink<xAOD::CaloClusterContainer> m_clusElementLink; bool m_isTouchable; /* 1: ECAL, 2: HCAL */ diff --git a/Reconstruction/eflowRec/share/jetAlgs.py b/Reconstruction/eflowRec/share/jetAlgs.py new file mode 100644 index 0000000000000000000000000000000000000000..8e97510190fde9548a4fc259e09cfbc6e7b67ae1 --- /dev/null +++ b/Reconstruction/eflowRec/share/jetAlgs.py @@ -0,0 +1,5 @@ +#Run PFlow jet finding +from JetRec.JetRecStandard import jtm +jtm.addJetFinder("AntiKt4EMPFlowJets", "AntiKt", 0.4, "empflow", "pflow_ungroomed", ghostArea=0.01, ptmin= 5000, ptminFilter= 10000, calibOpt="arj:pflow") +from JetRec.JetAlgorithm import addJetRecoToAlgSequence +addJetRecoToAlgSequence(eventShapeTools=["empflow"]) diff --git a/Reconstruction/eflowRec/share/run_ESDStandardReco.py b/Reconstruction/eflowRec/share/run_ESDStandardReco.py new file mode 100644 index 0000000000000000000000000000000000000000..edcf729fd3246caffde93f4723c2ca83e868651b --- /dev/null +++ b/Reconstruction/eflowRec/share/run_ESDStandardReco.py @@ -0,0 +1,25 @@ +#This file is to run standard reconstruction + pflow + jet finding on an ESD file + +from AthenaCommon.AthenaCommonFlags import athenaCommonFlags +athenaCommonFlags.FilesInput=["/data/hodgkinson/dataFiles/mc16_13TeV/ESDFiles/mc16_valid.410000.PowhegPythiaEvtGen_P2012_ttbar_hdamp172p5_nonallhad.recon.ESD.e3698_s2995_r8905/ESD.10230993._000008.pool.root.1"] + +doDumpProperties=True + +from RecExConfig.RecAlgsFlags import recAlgs +recAlgs.doEFlow.set_Value_and_Lock(True) + +#change some calo flags +from CaloRec.CaloRecFlags import jobproperties +jobproperties.CaloRecFlags.Enabled.set_Value_and_Lock(True) +jobproperties.CaloRecFlags.doCaloCluster.set_Value_and_Lock(True) +jobproperties.CaloRecFlags.doEmCluster.set_Value_and_Lock(False) +jobproperties.CaloRecFlags.doCaloTopoCluster.set_Value_and_Lock(True) + +#Turn of TAG +rec.doWriteTAG.set_Value_and_Lock(False) + +athenaCommonFlags.EvtMax=1 +#Run pflopw jet finding - this cannot be enabled via reconstruction flags currently! (without enabling other things we don't want) +UserAlgs = ["jetAlgs.py"] +include ("RecExCommon/RecExCommon_topOptions.py") + diff --git a/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx index d8a58e43fda66f42dc4636144826683ec2f3f643..dde38be0878b80445a0f2ad4a8f37b5e37c9238c 100644 --- a/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx +++ b/Reconstruction/eflowRec/src/PFOChargedCreatorAlgorithm.cxx @@ -1,7 +1,12 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + #include "eflowRec/PFOChargedCreatorAlgorithm.h" #include "eflowRec/eflowRecCluster.h" #include "eflowRec/eflowRecTrack.h" +#include "eflowRec/eflowTrackClusterLink.h" #include "xAODPFlow/PFOAuxContainer.h" @@ -26,8 +31,7 @@ void PFOChargedCreatorAlgorithm::execute(const eflowCaloObject& energyFlowCaloOb ATH_MSG_DEBUG("Processing eflowCaloObject"); - if (m_eOverPMode) createChargedPFO(energyFlowCaloObject, true, chargedPFOContainerWriteHandle); - else createChargedPFO(energyFlowCaloObject,false,chargedPFOContainerWriteHandle); + createChargedPFO(energyFlowCaloObject, true, chargedPFOContainerWriteHandle); SG::ReadHandle<xAOD::VertexContainer> vertexContainerReadHandle(m_vertexContainerReadHandleKey); const xAOD::VertexContainer* theVertexContainer = vertexContainerReadHandle.ptr(); @@ -114,13 +118,35 @@ void PFOChargedCreatorAlgorithm::createChargedPFO(const eflowCaloObject& energyF /* Optionally we add the links to clusters to the xAOD::PFO */ if (true == addClusters){ - unsigned int nClusters = energyFlowCaloObject.nClusters(); - for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster){ - eflowRecCluster* thisEfRecCluster = energyFlowCaloObject.efRecCluster(iCluster); - ElementLink<xAOD::CaloClusterContainer> theClusLink = thisEfRecCluster->getClusElementLink(); - bool isSet = thisPFO->addClusterLink(theClusLink); + + std::vector<eflowTrackClusterLink*> trackClusterLinks = energyFlowCaloObject.efRecLink(); + + /* + We need to track which clusters we have added for the following use case: + An eflowCaloObject may have one cluster and N tracks, and then one would have N eflowTrackClusterLink* + for each track-cluster pair, though the cluster is always the same. We only want to add the cluster to + charged PFO once. + */ + std::vector<ElementLink<xAOD::CaloClusterContainer> > usedClusterList; + + for (auto trackClusterLink : trackClusterLinks){ + eflowRecCluster* efRecCluster = trackClusterLink->getCluster(); + ElementLink<xAOD::CaloClusterContainer> theOriginalClusterLink = efRecCluster->getOriginalClusElementLink(); + + bool continueLoop = false; + for (auto tmpLink : usedClusterList){ + if (tmpLink == theOriginalClusterLink){ + continueLoop = true; + } + } + if (true == continueLoop) continue; + else usedClusterList.push_back(theOriginalClusterLink); + + ElementLink<xAOD::CaloClusterContainer> theSisterClusterLink = (*theOriginalClusterLink)->getSisterClusterLink(); + ATH_MSG_DEBUG("PFO with e and eta of " << thisPFO->e() << " and " << thisPFO->eta() << " is adding cluster with e, eta of " << (*theSisterClusterLink)->e() << " and " << (*theSisterClusterLink)->eta() << " an sistser has " << (*theOriginalClusterLink)->e() << " and " << (*theOriginalClusterLink)->eta()); + bool isSet = thisPFO->addClusterLink(theSisterClusterLink); if (!isSet) ATH_MSG_WARNING("Could not set Cluster in PFO"); - }//cluster loop + }//track-cluster link loop }//addClusters is set to true - so we added the clusters to the xAOD::PFO }//loop over the tracks on the eflowCaloObject diff --git a/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx index 3245782062eba98e965f836fe5cecdb20c383878..f23cb5836960a8580273c9200f8e15b2ab1a005d 100644 --- a/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx +++ b/Reconstruction/eflowRec/src/PFONeutralCreatorAlgorithm.cxx @@ -1,7 +1,12 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + #include "eflowRec/PFONeutralCreatorAlgorithm.h" #include "eflowRec/eflowCaloObject.h" #include "eflowRec/eflowRecCluster.h" +#include "eflowRec/eflowTrackClusterLink.h" #include "xAODPFlow/PFOAuxContainer.h" @@ -40,9 +45,10 @@ StatusCode PFONeutralCreatorAlgorithm::finalize(){ return StatusCode::SUCCESS; } void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyFlowCaloObject,SG::WriteHandle<xAOD::PFOContainer>& neutralPFOContainerWriteHandle, SG::WriteHandle<xAOD::PFOContainer>& neutralPFOContainerWriteHandle_nonModified){ unsigned int nClusters = energyFlowCaloObject.nClusters(); + for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster){ eflowRecCluster* thisEfRecCluster = energyFlowCaloObject.efRecCluster(iCluster); - + /* Skip empty clusters (presumably subtraction remnants) */ const CaloClusterCellLink* theCellLink = energyFlowCaloObject.efRecCluster(iCluster)->getCluster()->getCellLinks(); CaloClusterCellLink::const_iterator it=theCellLink->begin(); @@ -66,8 +72,9 @@ void PFONeutralCreatorAlgorithm::createNeutralPFO(const eflowCaloObject& energyF neutralPFOContainerWriteHandle->push_back(thisPFO); } - ElementLink<xAOD::CaloClusterContainer> theClusterLink = thisEfRecCluster->getClusElementLink(); - bool isSet = thisPFO->setClusterLink(theClusterLink); + ElementLink<xAOD::CaloClusterContainer> theOriginalClusterLink = thisEfRecCluster->getOriginalClusElementLink(); + ElementLink<xAOD::CaloClusterContainer> theSisterClusterLink = (*theOriginalClusterLink)->getSisterClusterLink(); + bool isSet = thisPFO->setClusterLink(theSisterClusterLink); if (!isSet) { msg(MSG::WARNING) << "Could not set Cluster in PFO " << endmsg; } const xAOD::CaloCluster* cluster = thisEfRecCluster->getCluster(); diff --git a/Reconstruction/eflowRec/src/eflowRecCluster.cxx b/Reconstruction/eflowRec/src/eflowRecCluster.cxx index d8811e24131e1bd4fae16a91277dfbf2a0660754..d7554219d236260aa896f49c6a976894cf82132d 100644 --- a/Reconstruction/eflowRec/src/eflowRecCluster.cxx +++ b/Reconstruction/eflowRec/src/eflowRecCluster.cxx @@ -15,7 +15,7 @@ #include "xAODCaloEvent/CaloClusterKineHelper.h" eflowRecCluster::eflowRecCluster(const ElementLink<xAOD::CaloClusterContainer>& clusElementLink) : - m_clusterId(-1), m_cluster(*clusElementLink), m_clusElementLink(clusElementLink), m_isTouchable(false), m_type(0), m_matchCluster(nullptr) { + m_clusterId(-1), m_cluster(*clusElementLink),m_originalClusElementLink(clusElementLink), m_clusElementLink(clusElementLink), m_isTouchable(false), m_type(0), m_matchCluster(nullptr) { m_matchCluster = std::make_unique<eflowMatchCluster>(this); } @@ -23,6 +23,7 @@ eflowRecCluster::eflowRecCluster(const eflowRecCluster& originalEflowRecCluster) m_clusterId = originalEflowRecCluster.m_clusterId; m_cluster = originalEflowRecCluster.m_cluster; m_clusElementLink = originalEflowRecCluster.m_clusElementLink; + m_originalClusElementLink = originalEflowRecCluster.m_originalClusElementLink; m_isTouchable = originalEflowRecCluster.m_isTouchable; m_type = originalEflowRecCluster.m_type; m_matchCluster = std::make_unique<eflowMatchCluster>(this); @@ -34,6 +35,7 @@ eflowRecCluster& eflowRecCluster::operator=(const eflowRecCluster& originalEflow else{ m_cluster = originalEflowRecCluster.m_cluster; m_clusElementLink = originalEflowRecCluster.m_clusElementLink; + m_originalClusElementLink = originalEflowRecCluster.m_originalClusElementLink; m_isTouchable = originalEflowRecCluster.m_isTouchable; m_matchCluster = std::make_unique<eflowMatchCluster>(this); return *this;