diff --git a/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/python/TrigL1CaloUpgradeConfig.py b/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/python/TrigL1CaloUpgradeConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..ca8b86908093daa9e9df6c7e66bc7ba63d0d97c6 --- /dev/null +++ b/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/python/TrigL1CaloUpgradeConfig.py @@ -0,0 +1,69 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +from AthenaCommon.Logging import logging + +def enableEfexAlgorithms( algSequence, + SuperCellContainer='SCell', + useTDR=False, + doLArFex=False, + doEle=True, + doTau=True, + ApplySCQual=True, + SCBitMask=0x40, + logLevel = logging.INFO): + + log = logging.getLogger( 'TrigT1CaloFexSim.L1Sim.eFEX' ) + log.setLevel(logLevel) + + log.info("Enable eFEX algorithms") + + # the CaloNoiseTool as global tool + from AthenaCommon.AppMgr import ToolSvc + from CaloTools.CaloNoiseToolDefault import CaloNoiseToolDefault + theCaloNoiseTool=CaloNoiseToolDefault() + ToolSvc+=theCaloNoiseTool + + from TrigL1CaloUpgrade.TrigL1CaloUpgradeConf import TrigT1CaloEFex + # eFEX clusters with or without BCID based energy correction + if(useTDR and doEle): + log.debug("Adding TDR version of TrigT1CaloEFex/TrigT1CaloEFexCl to AthAlgSeq") + algSequence += TrigT1CaloEFex( name="TrigT1CaloEFexCl", + CleanCellContainerSkim=ApplySCQual, + QualBitMask = SCBitMask, + OutputClusterName="SClusterCl", + SuperCellContainer=SuperCellContainer, + EnergyWeightedCluster=True) + + elif doEle: + log.debug("Adding new version of TrigT1CaloEFex/TrigT1CaloEFexCl to AthAlgSeq") + algSequence += TrigT1CaloEFex( name="TrigT1CaloEFexCl", + CleanCellContainer=ApplySCQual, + QualBitMask=SCBitMask, + OutputClusterName="SClusterCl", + SuperCellContainer=SuperCellContainer, + ClusterEnergyThreshold=4.0, + ApplyBaseLineSelection=False, + EnergyWeightedCluster=False) + + # Schedule the tau algorihtm + if doTau: + from TrigL1CaloUpgrade.TrigL1CaloUpgradeConf import TrigT1CaloRun3TauFex + algSequence += TrigT1CaloRun3TauFex( name="TrigT1CaloEFexTau", + CleanCellContainer=False,#Not currently properly enabled for Tau's + CleanCellContainerSkim=True,#Should work with new implementation + #EnableMonitoring=True, + SuperCellContainer=SuperCellContainer, + OutputClusterName="SClusterTau" ) + + + # LArFex algorithms for different sigma + if( doLArFex ): + from TrigL1CaloUpgrade.TrigL1CaloUpgradeConf import LArFex + for sigma in [ 1, 2, 3 ]: + log.debug("Adding LArFex/%iSig to AthAlgSeq" % sigma) + algSequence += LArFex( name="%iSig" % sigma, + EtInSigma = 3.0, + CaloNoiseTool = theCaloNoiseTool, + EtInSigmaSelect = sigma, + OutputClusterName = "LArLayer1Vars%iSig" % sigma) + diff --git a/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/src/TrigT1CaloRun3TauFex.cxx b/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/src/TrigT1CaloRun3TauFex.cxx index fd381ef6a29ea4623d262fae53808767f7c16333..ef0b3eab65eac75cfad4cdc4d1b2bc69f24918f3 100644 --- a/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/src/TrigT1CaloRun3TauFex.cxx +++ b/Trigger/TrigL1Upgrade/TrigL1CaloUpgrade/src/TrigT1CaloRun3TauFex.cxx @@ -44,8 +44,6 @@ TrigT1CaloRun3TauFex::TrigT1CaloRun3TauFex( const std::string& name, ISvcLocator */ TrigT1CaloRun3TauFex::~TrigT1CaloRun3TauFex(){ // finish base class - delete acc_clusterET; - delete acc_clusterIso; } StatusCode TrigT1CaloRun3TauFex::initialize(){ @@ -87,6 +85,8 @@ StatusCode TrigT1CaloRun3TauFex::finalize(){ m_histFile->Write(); m_histFile->Close(); } + delete acc_clusterET; + delete acc_clusterIso; return StatusCode::SUCCESS; } diff --git a/Trigger/TrigT1/TrigT1CTP/python/TrigT1CTP_EnableCTPEmulation.py b/Trigger/TrigT1/TrigT1CTP/python/TrigT1CTP_EnableCTPEmulation.py new file mode 100644 index 0000000000000000000000000000000000000000..e46ffdf8d910b7f4fdfca3df2ecb857024e64850 --- /dev/null +++ b/Trigger/TrigT1/TrigT1CTP/python/TrigT1CTP_EnableCTPEmulation.py @@ -0,0 +1,46 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +def enableCTPEmulation(athSequence): + + from RecExConfig.RecFlags import rec + from AthenaCommon.AppMgr import ServiceMgr as svcMgr + import AthenaCommon.CfgMgr as CfgMgr + from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags + + from AthenaCommon.GlobalFlags import globalflags + isData = (globalflags.DataSource == 'data') + + if not hasattr(svcMgr,"THistSvc"): + svcMgr += CfgMgr.THistSvc() + (hStream , hFile) = simflags.OutputHistFile().split('#') # e.g. EXPERT#l1Simulation.root + if not hStream in [entry.split()[0] for entry in svcMgr.THistSvc.Output]: + svcMgr.THistSvc.Output += ["%s DATAFILE='%s' OPT='RECREATE'" % tuple(simflags.OutputHistFile().split('#')) ] + + from TrigT1CTP.TrigT1CTPConf import LVL1CTP__CTPEmulation + ctpEmulation = LVL1CTP__CTPEmulation( name="CTPEmulation", + HistogramStream=hStream, + RDOOutputLocation = "CTP_RDO_L1Run3", + IsData = isData ) + + from AthenaCommon.Constants import DEBUG + if simflags.EnableDebugOutput(): + ctpEmulation.OutputLevel = DEBUG + athSequence += ctpEmulation + + # adding output + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + from AthenaCommon.AlgSequence import AlgSequence + if rec.doRDOTrigger(): + MSMgr.GetStream( "StreamRDO" ).AddItem( getOutputData() ) + + if rec.doWriteESD(): + MSMgr.GetStream( "StreamESD" ).AddItem( getOutputData() ) + + if rec.doWriteAOD(): + MSMgr.GetStream( "StreamAOD" ).AddItem( getOutputData() ) + + +def getOutputData(): + output = [ "CTP_RDO#CTP_RDO", + "CTP_RDO#CTP_RDO_L1Run3" ] + return output diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.cxx b/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.cxx index 617152ee1e12200c5859f3c3a65cee8cb55c6429..d76e580c3e2d72fc1126c71fbd93bc9e24ce6947 100644 --- a/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.cxx +++ b/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.cxx @@ -8,6 +8,7 @@ #include "TrigT1CTP/CTPTriggerThreshold.h" #include "TrigT1CTP/CTPTriggerItem.h" #include "TrigT1CTP/BunchGroupTrigger.h" +#include "TrigT1CTP/CTPUtil.h" #include "TrigT1Result/CTP_RDO.h" #include "TrigT1Interfaces/CTPSLink.h" @@ -17,7 +18,6 @@ #include "TrigT1Interfaces/CPRoIDecoder.h" #include "TrigT1Interfaces/JEPRoIDecoder.h" -#include "TrigT1Interfaces/TrigT1CaloDefs.h" #include "TH2.h" @@ -75,6 +75,10 @@ LVL1CTP::CTPEmulation::CTPEmulation( const std::string& name, ISvcLocator* pSvcL // muon threshold counts from CTP input recorded in data declareProperty( "MuonCTPInput", m_muonCTPLoc, "StoreGate location of Muon inputs" ); + declareProperty( "EmTauCTPLocation", m_emtauCTPLoc, "StoreGate location of EmTau inputs" ); + declareProperty( "JetCTPLocation", m_jetCTPLoc, "StoreGate location of Jet inputs" ); + declareProperty( "EnergyCTPLocation", m_energyCTPLoc, "StoreGate location of Energy inputs" ); + declareProperty( "TopoCTPLocation", m_topoCTPLoc, "StoreGate location of topo inputs" ); // output locations and control declareProperty( "IsData", m_isData, "emulate CTP as part of MC or rerun on data" ); @@ -248,11 +252,11 @@ LVL1CTP::CTPEmulation::bookHists() { // MET histpath = histBasePath() + "/input/MET/"; - CHECK ( m_histSvc->regHist( histpath + "Pufit", new TH1I("MET_Pufit","Missing ET from algorithm pufit", 40, 0, 30)) ); + CHECK ( m_histSvc->regHist( histpath + "Pufit", new TH1I("MET_Pufit","Missing ET from algorithm pufit", 40, 0, 80)) ); CHECK ( m_histSvc->regHist( histpath + "PufitPhi", new TH1I("MET_PufitPhi","Missing ET PUfit phi", 64, -3.2, 3.2)) ); - CHECK ( m_histSvc->regHist( histpath + "Rho", new TH1I("MET_Rho","Missing ET from algorithm rhosub", 40, 0, 30)) ); + CHECK ( m_histSvc->regHist( histpath + "Rho", new TH1I("MET_Rho","Missing ET from algorithm rhosub", 40, 0, 80)) ); CHECK ( m_histSvc->regHist( histpath + "RhoPhi", new TH1I("MET_RhoPhi","Missing ET rhosub phi", 64, -3.2, 3.2)) ); - CHECK ( m_histSvc->regHist( histpath + "JwoJ", new TH1I("MET_JwoJ","Missing ET from algorithm jet without jets", 40, 0, 30)) ); + CHECK ( m_histSvc->regHist( histpath + "JwoJ", new TH1I("MET_JwoJ","Missing ET from algorithm jet without jets", 40, 0, 80)) ); CHECK ( m_histSvc->regHist( histpath + "JwoJPhi", new TH1I("MET_JwoJPhi","Missing ET jet without jet phi", 64, -3.2, 3.2)) ); // cluster @@ -297,6 +301,12 @@ LVL1CTP::CTPEmulation::bookHists() { CHECK ( m_histSvc->regHist( histpath + "eta", new TH1I("eta","TAU ROI eta", 64, -32, 32)) ); CHECK ( m_histSvc->regHist( histpath + "phi", new TH1I("phi","TAU ROI phi", 64, -32, 32)) ); + // MUON ROI + histpath = histBasePath() + "/input/roi/muon/"; + CHECK ( m_histSvc->regHist( histpath + "et", new TH1I("et", "TAU ROI ET ", 40, 0, 40)) ); + CHECK ( m_histSvc->regHist( histpath + "eta", new TH1I("eta","TAU ROI eta", 64, -32, 32)) ); + CHECK ( m_histSvc->regHist( histpath + "phi", new TH1I("phi","TAU ROI phi", 64, -32, 32)) ); + // input counts histpath = histBasePath() + "/input/counts/"; CHECK ( m_histSvc->regHist( histpath + "jJets", new TH1I("jJets","Number of jets (jJ)", 40, 0, 40)) ); @@ -351,6 +361,9 @@ LVL1CTP::CTPEmulation::bookHists() { StatusCode LVL1CTP::CTPEmulation::retrieveCollections() { + // new L1Calo collections + + // met CHECK ( evtStore()->retrieve( m_gFEXMETPufit, m_gFEXMETPufitLoc ) ); ATH_MSG_DEBUG( "Retrieved gFEX MET '" << m_gFEXMETPufitLoc << "'"); @@ -379,9 +392,9 @@ LVL1CTP::CTPEmulation::retrieveCollections() { ATH_MSG_DEBUG( "Retrieved eFEX em tau container '" << m_eFEXTauLoc << "' with size " << m_eFEXTau->size()); - - // run-2 ROIs are contained in the ROIBResult + // Run 2 ROIs if ( m_isData ) { + // they are contained in the ROIBResult when running on data ATH_MSG_DEBUG( "Running on data, going to retrieve ROIBResult" ); CHECK ( evtStore()->retrieve( m_roibResult ) ); @@ -391,14 +404,21 @@ LVL1CTP::CTPEmulation::retrieveCollections() { ATH_MSG_DEBUG( "Created ROIs from ROIBResult" ); } else { - - ATH_MSG_DEBUG( "Running on MC, going to retrieve xAOD collections" ); + ATH_MSG_DEBUG( "Running on MC, going to retrieve simulated L1 objects in CTP format" ); + + CHECK ( evtStore()->retrieve( m_muctpiCTP, m_muonCTPLoc ) ); + CHECK ( evtStore()->retrieve( m_emtauCTP, m_emtauCTPLoc ) ); + CHECK ( evtStore()->retrieve( m_jetCTP, m_jetCTPLoc ) ); + CHECK ( evtStore()->retrieve( m_energyCTP, m_energyCTPLoc ) ); + CHECK ( evtStore()->retrieve( m_topoCTP, m_topoCTPLoc ) ); + + // ATH_MSG_DEBUG( "Running on MC, going to retrieve xAOD collections" ); - CHECK ( evtStore()->retrieve( m_muonRoIs, m_muonRoILoc ) ); - ATH_MSG_DEBUG( "Retrieved Muon ROI container '" << m_muonRoILoc << "' with size " << m_muonRoIs->size()); + // CHECK ( evtStore()->retrieve( m_muonRoIs, m_muonRoILoc ) ); + // ATH_MSG_DEBUG( "Retrieved Muon ROI container '" << m_muonRoILoc << "' with size " << m_muonRoIs->size()); - CHECK ( evtStore()->retrieve( m_lgJetRoIs, m_lgJetRoILoc ) ); - ATH_MSG_DEBUG( "Retrieved LG Jet container '" << m_lgJetRoILoc << "' with size " << m_lgJetRoIs->size()); + // CHECK ( evtStore()->retrieve( m_lgJetRoIs, m_lgJetRoILoc ) ); + // ATH_MSG_DEBUG( "Retrieved LG Jet container '" << m_lgJetRoILoc << "' with size " << m_lgJetRoIs->size()); } @@ -489,7 +509,7 @@ LVL1CTP::CTPEmulation::fillInputHistograms() { h3->Fill(tau->phi()); h4->Fill(tau->emIsol()); h5->Fill(tau->hadIsol()); - h6->Fill(accR3ClET(*tau)); + h6->Fill(accR3ClET(*tau)/1000.); h7->Fill(accR3ClIso(*tau)); } @@ -531,11 +551,8 @@ LVL1CTP::CTPEmulation::fillInputHistograms() { CHECK ( m_histSvc->getHist( histBasePath() + "/input/roi/met/xephi", h2) ); CHECK ( m_histSvc->getHist( histBasePath() + "/input/roi/met/te", h3) ); LVL1::JEPRoIDecoder conv; - unsigned int cc(0); - ATH_MSG_DEBUG("JOERG MET Loop over all JetEnergyResults, there are " << m_roibResult->jetEnergyResult().size() ); for( const ROIB::JetEnergyResult & res : m_roibResult->jetEnergyResult() ) { - ATH_MSG_DEBUG("JOERG MET JetEnergyResult " << cc++ << ", now loop over the ROIs, there are " << res.roIVec().size() ); - for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { + for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { // RoI word uint32_t roIWord = roi.roIWord(); // RoI type @@ -677,47 +694,58 @@ LVL1CTP::CTPEmulation::calculateJetMultiplicity( const TrigConf::TriggerThreshol unsigned int multiplicity = 0; if( confThr->name().find("J") == 0 ) { - // Run-2 threshold - for ( const HLT::JetEnergyRoI & jetROI : m_lvl1Tool->getJetEnergyRoIs() ) { - LVL1::TrigT1CaloDefs::RoIType jettype = m_jetDecoder->roiType( jetROI.lvl1RoI().roIWord() ); + if( m_isData ) { + // Run-2 threshold + for ( const HLT::JetEnergyRoI & jetROI : m_lvl1Tool->getJetEnergyRoIs() ) { - ATH_MSG_DEBUG( "JetEnergyRoI has type @hlt " - << jetROI.type() << " @lvl1 " - << jetROI.lvl1RoI().roIType() << " @decoder" - << m_jetDecoder->roiType( jetROI.lvl1RoI().roIWord() ) ); + LVL1::TrigT1CaloDefs::RoIType jettype = m_jetDecoder->roiType( jetROI.lvl1RoI().roIWord() ); - - if( jettype != LVL1::TrigT1CaloDefs::JetRoIWordType ) continue; // not a jet (likely xe) - - const ROIB::JetEnergyRoI & l1JetROI = jetROI.lvl1RoI(); + ATH_MSG_DEBUG( "JetEnergyRoI has type @hlt " + << jetROI.type() << " @lvl1 " + << jetROI.lvl1RoI().roIType() << " @decoder" + << m_jetDecoder->roiType( jetROI.lvl1RoI().roIWord() ) ); - LVL1::CoordinateRange coordRange = m_jetDecoder->coordinate(l1JetROI.roIWord()); - int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); - int ieta = int(( coordRange.eta() + ((coordRange.eta() > 0.01) ? 0.025 : -0.025)) / 0.1) - 1; - // Adjustment due to irregular geometries - if (ieta > 24) ieta += 2; + + if( jettype != LVL1::TrigT1CaloDefs::JetRoIWordType ) continue; // not a jet (likely xe) - const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); - bool largeWindow = thrV->windowSize()==JetWindowSize::LARGE; - unsigned int et = largeWindow ? l1JetROI.etLarge() : l1JetROI.etSmall(); + const ROIB::JetEnergyRoI & l1JetROI = jetROI.lvl1RoI(); - bool roiPasses = ( et >= thrV->ptcut() ); // need to add cut on isolation and other variables, once available - ATH_MSG_DEBUG( "For threshold " << confThr->name() << " check ROI ieta " << ieta - << " iphi " << iphi - << " et " << et - << " thrV " << thrV->ptcut() - << (roiPasses ? "passes" : "failed") - ); + LVL1::CoordinateRange coordRange = m_jetDecoder->coordinate(l1JetROI.roIWord()); + int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); + int ieta = int(( coordRange.eta() + ((coordRange.eta() > 0.01) ? 0.025 : -0.025)) / 0.1) - 1; + // Adjustment due to irregular geometries + if (ieta > 24) ieta += 2; - multiplicity += roiPasses ? 1 : 0; + const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); + bool largeWindow = thrV->windowSize()==JetWindowSize::LARGE; + unsigned int et = largeWindow ? l1JetROI.etLarge() : l1JetROI.etSmall(); + + bool roiPasses = ( et >= thrV->ptcut() ); // need to add cut on isolation and other variables, once available + ATH_MSG_DEBUG( "For threshold " << confThr->name() << " check ROI ieta " << ieta + << " iphi " << iphi + << " et " << et + << " thrV " << thrV->ptcut() + << (roiPasses ? "passes" : "failed") + ); + + multiplicity += roiPasses ? 1 : 0; + } + } else { + ATH_MSG_DEBUG("Threshold " << confThr->name() << " is on cable " << confThr->cableName() << + " jet cable0=" << m_jetCTP->cableWord0() << " and cable1=" << m_jetCTP->cableWord1() ); + if ( m_jetCTP.isValid() ) { + if ( confThr->cableName() == "JEP1" || confThr->cableName() == "JET1" ) { + multiplicity = CTPUtil::getMult( m_jetCTP->cableWord0(), confThr->cableStart(), confThr->cableEnd() ); + } else if ( confThr->cableName() == "JEP2" || confThr->cableName() == "JET2" ) { + multiplicity = CTPUtil::getMult( m_jetCTP->cableWord1(), confThr->cableStart(), confThr->cableEnd() ); + } + } } } else { // Run-3 threshold - const DataHandle< xAOD::JetRoIContainer > * dh { nullptr }; - if( confThr->name().find("g") == 0 ) { dh = & m_gJet; } else if( confThr->name().find("jL") == 0 ) { @@ -727,7 +755,6 @@ LVL1CTP::CTPEmulation::calculateJetMultiplicity( const TrigConf::TriggerThreshol } else { ATH_MSG_ERROR( "Unexpected threshold name " << confThr->name() << ". Should start with j, jL, g, or J."); } - if ( dh ) { for ( const auto & jet : **dh ) { float eta = jet->eta(); @@ -767,41 +794,52 @@ LVL1CTP::CTPEmulation::calculateEMMultiplicity( const TrigConf::TriggerThreshold } else { // old EM threshold from data - if ( m_roibResult ) { - for( const ROIB::EMTauResult & res : m_roibResult->eMTauResult() ) { - for ( const ROIB::EMTauRoI & roi : res.roIVec() ) { - if( roi.roIType() != LVL1::TrigT1CaloDefs::EMRoIWordType) - continue; - LVL1::CoordinateRange coordRange = m_decoder->coordinate(roi.roIWord()); - int ieta = int ( ( coordRange.etaRange().min() + 0.025) / 0.1) + - ( ( coordRange.etaRange().min() + 0.025 > 0) ? 0 : -1); - int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); - const TrigConf::ClusterThresholdValue * thrV = dynamic_cast ( confThr->triggerThresholdValue( ieta, iphi ) ); - - float scale = thrV->caloInfo().globalEmScale(); - unsigned int etCut = thrV->ptcut(); - unsigned int threshold = etCut * scale; - unsigned int isolMask = thrV->isolationMask(); - //const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); - - // isolation bit interpretation - bool isolationPassed = true; - for (unsigned int bit = 0; bit < LVL1::TrigT1CaloDefs::numOfIsolationBits; ++bit) { - if ((isolMask & (1 << bit)) && !(roi.isolation() & (1 << bit))) // only bits in the mask are checked and - // set isolation to false if isolation bit==1 !! - isolationPassed = false; + if ( m_isData ) { + if ( m_roibResult ) { + for( const ROIB::EMTauResult & res : m_roibResult->eMTauResult() ) { + for ( const ROIB::EMTauRoI & roi : res.roIVec() ) { + if( roi.roIType() != LVL1::TrigT1CaloDefs::EMRoIWordType) + continue; + LVL1::CoordinateRange coordRange = m_decoder->coordinate(roi.roIWord()); + // translate eta and phi from float values to tower indices + // copied from TrigT1Interfaces/RecEmTauRoI.cxx (l117) + int ieta = int ( ( coordRange.etaRange().min() + 0.025) / 0.1) + + ( ( coordRange.etaRange().min() + 0.025 > 0) ? 0 : -1); + int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); + const TrigConf::ClusterThresholdValue * thrV = dynamic_cast ( confThr->triggerThresholdValue( ieta, iphi ) ); + + float scale = thrV->caloInfo().globalEmScale(); + unsigned int etCut = thrV->ptcut(); + unsigned int threshold = etCut * scale; + unsigned int isolMask = thrV->isolationMask(); + //const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); + + // isolation bit interpretation + bool isolationPassed = true; + for (unsigned int bit = 0; bit < LVL1::TrigT1CaloDefs::numOfIsolationBits; ++bit) { + if ((isolMask & (1 << bit)) && !(roi.isolation() & (1 << bit))) // only bits in the mask are checked and + // set isolation to false if isolation bit==1 !! + isolationPassed = false; + } + ATH_MSG_DEBUG("EM " << confThr->name() << " mask=" << isolMask + << "iso=" << roi.isolation() + << " isoPassed=" << (isolationPassed?"yes":"no") ); + bool roiPasses = ( (roi.et() >= threshold) && isolationPassed ); + multiplicity += roiPasses ? 1 : 0; } - ATH_MSG_DEBUG("EM " << confThr->name() << " mask=" << isolMask - << "iso=" << roi.isolation() - << " isoPassed=" << (isolationPassed?"yes":"no") ); - bool roiPasses = ( (roi.et() >= threshold) && isolationPassed ); - multiplicity += roiPasses ? 1 : 0; + } + } + } else { + if ( m_emtauCTP.isValid() ) { + if ( confThr->cableName() == "CP1" || confThr->cableName() == "EM1" ) { + multiplicity = CTPUtil::getMult( m_emtauCTP->cableWord0(), confThr->cableStart(), confThr->cableEnd() ); + } else if ( confThr->cableName() == "CP2" || confThr->cableName() == "EM2" ) { + multiplicity = CTPUtil::getMult( m_emtauCTP->cableWord1(), confThr->cableStart(), confThr->cableEnd() ); } } } } TH1 * h { nullptr }; - //ATH_MSG_DEBUG("JOERG EM MULT calculated mult for threshold " << confThr->name() << " : " << multiplicity); CHECK( m_histSvc->getHist( histBasePath() + "/multi/em", h) ); h->Fill(confThr->mapping(), multiplicity); return multiplicity; @@ -816,7 +854,7 @@ LVL1CTP::CTPEmulation::calculateTauMultiplicity( const TrigConf::TriggerThreshol const static SG::AuxElement::ConstAccessor accR3ClIso ("R3ClusterIso"); if( m_eFEXTau ) { for ( const auto & tau : * m_eFEXTau ) { - float eT = accR3ClET(*tau); + float eT = accR3ClET(*tau)/1000.; // tau eT is in MeV while the cut is in GeV - this is only temporary and needs to be made consistent for all L1Calo //float iso = accR3ClIso(*tau); float eta = tau->eta(); int ieta = int((eta + (eta>0 ? 0.005 : -0.005))/0.1); @@ -827,19 +865,29 @@ LVL1CTP::CTPEmulation::calculateTauMultiplicity( const TrigConf::TriggerThreshol } } } else { - // old TAU threshold from data - if ( m_roibResult ) { - for( const ROIB::EMTauResult & res : m_roibResult->eMTauResult() ) { - for ( const ROIB::EMTauRoI & roi : res.roIVec() ) { - if( roi.roIType() != LVL1::TrigT1CaloDefs::TauRoIWordType) - continue; - LVL1::CoordinateRange coordRange = m_decoder->coordinate(roi.roIWord()); - int ieta = int ( ( coordRange.etaRange().min() + 0.025) / 0.1) + - ( ( coordRange.etaRange().min() + 0.025 > 0) ? 0 : -1); - int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); - const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); - bool roiPasses = ( roi.et() >= thrV->ptcut() ); // need to add cut on isolation and other variables, once available - multiplicity += roiPasses ? 1 : 0; + // old TAU threshold + if ( m_isData ) { + if ( m_roibResult ) { + for( const ROIB::EMTauResult & res : m_roibResult->eMTauResult() ) { + for ( const ROIB::EMTauRoI & roi : res.roIVec() ) { + if( roi.roIType() != LVL1::TrigT1CaloDefs::TauRoIWordType) + continue; + LVL1::CoordinateRange coordRange = m_decoder->coordinate(roi.roIWord()); + int ieta = int ( ( coordRange.etaRange().min() + 0.025) / 0.1) + + ( ( coordRange.etaRange().min() + 0.025 > 0) ? 0 : -1); + int iphi = int(( coordRange.phiRange().min() + 0.025) * 32 / M_PI); + const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( ieta, iphi ); + bool roiPasses = ( roi.et() >= thrV->ptcut() ); // need to add cut on isolation and other variables, once available + multiplicity += roiPasses ? 1 : 0; + } + } + } + } else { + if ( m_emtauCTP.isValid() ) { + if ( confThr->cableName() == "TAU1" ) { + multiplicity = CTPUtil::getMult( m_emtauCTP->cableWord2(), confThr->cableStart(), confThr->cableEnd() ); + } else if ( confThr->cableName() == "TAU2" ) { + multiplicity = CTPUtil::getMult( m_emtauCTP->cableWord3(), confThr->cableStart(), confThr->cableEnd() ); } } } @@ -857,43 +905,63 @@ LVL1CTP::CTPEmulation::calculateMETMultiplicity( const TrigConf::TriggerThreshol if ( confThr->name().find("XE")==0 ) { // old XE - int energyX(0), energyY(0); - if ( m_roibResult ) { - for( const ROIB::JetEnergyResult & res : m_roibResult->jetEnergyResult() ) { - for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { - if( roi.etSumType() == 1 ) // eta-restricted range XE and TE is ignored for the time being - continue; - if( roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) { // eX (XS) - energyX = m_jetDecoder->energyX( roi.roIWord() ); - } else if( roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType1 ) { // eY (TE) - energyY = m_jetDecoder->energyY( roi.roIWord() ); + if( m_isData ) { + int energyX(0), energyY(0); + if ( m_roibResult ) { + for( const ROIB::JetEnergyResult & res : m_roibResult->jetEnergyResult() ) { + for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { + if( roi.etSumType() == 1 ) // eta-restricted range XE and TE is ignored for the time being + continue; + if( roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType0 ) { // eX (XS) + energyX = m_jetDecoder->energyX( roi.roIWord() ); + } else if( roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType1 ) { // eY (TE) + energyY = m_jetDecoder->energyY( roi.roIWord() ); + } } } } + double missingET = sqrt(energyX*energyX + energyY*energyY); + const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( 0, 0 ); + multiplicity = missingET >= thrV->ptcut() ? 1 : 0; + } else { + if ( m_energyCTP.isValid() ) { + if ( confThr->cableName() == "JEP3" || confThr->cableName() == "EN1") { + multiplicity = CTPUtil::getMult( m_energyCTP->cableWord0(), confThr->cableStart(), confThr->cableEnd() ); + } else if ( confThr->cableName() == "EN2") { + multiplicity = CTPUtil::getMult( m_energyCTP->cableWord1(), confThr->cableStart(), confThr->cableEnd() ); + } + } } - double missingET = sqrt(energyX*energyX + energyY*energyY); - const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( 0, 0 ); - multiplicity = missingET >= thrV->ptcut() ? 1 : 0; } else if ( confThr->name().find("TE")==0 ) { // old TE - int energyT(0); - if ( m_roibResult ) { - bool isRestrictedRangeTE = confThr->name().find("24ETA49") != std::string::npos; - for( const ROIB::JetEnergyResult & res : m_roibResult->jetEnergyResult() ) { - for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { - ATH_MSG_DEBUG("JOERG TE " << roi.etSumType() << " " << roi.roIType()); - if( (roi.etSumType() == (isRestrictedRangeTE ? 1 : 0) ) && // pick the correct sumtype 0-all, 1-restricted range - roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType2 ) { // etSum - energyT = m_jetDecoder->energyT( roi.roIWord() ); - ATH_MSG_DEBUG("JOERG TE RR " << energyT); + if( m_isData ) { + int energyT(0); + if ( m_roibResult ) { + bool isRestrictedRangeTE = confThr->name().find("24ETA49") != std::string::npos; + for( const ROIB::JetEnergyResult & res : m_roibResult->jetEnergyResult() ) { + for( const ROIB::JetEnergyRoI & roi : res.roIVec() ) { + ATH_MSG_DEBUG("JOERG TE " << roi.etSumType() << " " << roi.roIType()); + if( (roi.etSumType() == (isRestrictedRangeTE ? 1 : 0) ) && // pick the correct sumtype 0-all, 1-restricted range + roi.roIType() == LVL1::TrigT1CaloDefs::EnergyRoIWordType2 ) { // etSum + energyT = m_jetDecoder->energyT( roi.roIWord() ); + ATH_MSG_DEBUG("JOERG TE RR " << energyT); + } } } } + const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( 25, 0 ); // eta can be any value 24..49 + multiplicity = (energyT >= thrV->ptcut()) ? 1 : 0; + ATH_MSG_DEBUG("TE DECISION " << confThr->name() << " TE=" << energyT << " thr=" << thrV->ptcut() + << " mult=" << multiplicity); + } else { + if ( m_energyCTP.isValid() ) { + if ( confThr->cableName() == "JEP3" || confThr->cableName() == "EN1") { + multiplicity = CTPUtil::getMult( m_energyCTP->cableWord0(), confThr->cableStart(), confThr->cableEnd() ); + } else if ( confThr->cableName() == "EN2") { + multiplicity = CTPUtil::getMult( m_energyCTP->cableWord1(), confThr->cableStart(), confThr->cableEnd() ); + } + } } - const TrigConf::TriggerThresholdValue * thrV = confThr->triggerThresholdValue( 25, 0 ); // eta can be any value 24..49 - multiplicity = (energyT >= thrV->ptcut()) ? 1 : 0; - ATH_MSG_DEBUG("JOERG TE DECISION " << confThr->name() << " TE=" << energyT << " thr=" << thrV->ptcut() - << " mult=" << multiplicity); } else { // new XE // input depends on the name of the threshold @@ -934,8 +1002,8 @@ LVL1CTP::CTPEmulation::calculateMuonMultiplicity( const TrigConf::TriggerThresho multiplicity += (muon.lvl1RoI().pt()>= (unsigned int) confThr->mapping()) ? 1 : 0; // TrigT1Result/MuCTPIRoI } } else { - for ( const auto muon : * m_muonRoIs ) { - multiplicity += (muon->getThrNumber()>= confThr->mapping()) ? 1 : 0; + if ( m_muctpiCTP.isValid() ) { + multiplicity = CTPUtil::getMult( m_muctpiCTP->muCTPIWord(), confThr->cableStart(), confThr->cableEnd() ); } } diff --git a/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.h b/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.h index 810c6cee682de5464ff5321cfca8c952a3e68c92..8d29a05126c717f77209d8b8702122773816e27c 100644 --- a/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.h +++ b/Trigger/TrigT1/TrigT1CTP/src/CTPEmulation.h @@ -15,16 +15,22 @@ #include "TrigInterfaces/IMonitoredAlgo.h" #include "AthenaMonitoring/IMonitorToolBase.h" #include "GaudiKernel/ITHistSvc.h" +#include "TrigT1Interfaces/TrigT1CaloDefs.h" +#include "TrigT1Interfaces/TrigT1StoreGateKeys.h" // data -#include "TrigConfL1Data/L1DataDef.h" -#include "TrigConfL1Data/TriggerThreshold.h" #include "TrigT1Interfaces/MuCTPICTP.h" +#include "TrigT1Interfaces/EmTauCTP.h" +#include "TrigT1Interfaces/JetCTP.h" +#include "TrigT1Interfaces/EnergyCTP.h" +#include "TrigT1Interfaces/FrontPanelCTP.h" #include "xAODTrigger/JetRoIContainer.h" #include "xAODTrigger/EnergySumRoI.h" #include "xAODTrigger/MuonRoIContainer.h" #include "xAODTrigCalo/TrigEMClusterContainer.h" #include "xAODTrigger/EmTauRoIContainer.h" +#include "TrigConfL1Data/L1DataDef.h" +#include "TrigConfL1Data/TriggerThreshold.h" // internal #include "TrigT1CTP/ThresholdMap.h" @@ -124,15 +130,19 @@ namespace LVL1CTP { const DataHandle< xAOD::JetRoIContainer > m_jLJet; //!< large jets from jFEX - // old ROI collections + // Inputs from old L1Calo and L1Muon + // from MC const DataHandle< xAOD::MuonRoIContainer > m_muonRoIs; - const DataHandle< xAOD::JetRoIContainer > m_lgJetRoIs; - - // from BS + const DataHandle< xAOD::JetRoIContainer > m_lgJetRoIs; + const DataHandle< LVL1::MuCTPICTP > m_muctpiCTP; //!< MUCTPI input + const DataHandle< LVL1::EmTauCTP > m_emtauCTP; //!< EmTau input + const DataHandle< LVL1::JetCTP > m_jetCTP; //!< Jet input + const DataHandle< LVL1::EnergyCTP > m_energyCTP; //!< Energy input + const DataHandle< LVL1::FrontPanelCTP > m_topoCTP; //!< Topo input + + // from data const ROIB::RoIBResult * m_roibResult { nullptr }; - // Other inputs to the simulations - const DataHandle< LVL1::MuCTPICTP > m_muctpiCTP; // properties BooleanProperty m_useCTPInput { false }; @@ -155,6 +165,11 @@ namespace LVL1CTP { // name of the CTP input words StringProperty m_muonCTPLoc {""}; + StringProperty m_emtauCTPLoc { LVL1::TrigT1CaloDefs::EmTauCTPLocation }; + StringProperty m_jetCTPLoc { LVL1::TrigT1CaloDefs::JetCTPLocation }; + StringProperty m_energyCTPLoc { LVL1::TrigT1CaloDefs::EnergyCTPLocation }; + StringProperty m_topoCTPLoc { LVL1::DEFAULT_L1TopoCTPLocation }; + // output locations and control BooleanProperty m_isData { false }; diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/TrigT1CaloFexSim/Rho.h b/Trigger/TrigT1/TrigT1CaloFexSim/TrigT1CaloFexSim/Rho.h index 26c81f299e3b7ebe58107753d53667ca8e0518dd..a8a07d9068709036ceae3f1e44c95aae35dc4f1a 100644 --- a/Trigger/TrigT1/TrigT1CaloFexSim/TrigT1CaloFexSim/Rho.h +++ b/Trigger/TrigT1/TrigT1CaloFexSim/TrigT1CaloFexSim/Rho.h @@ -89,7 +89,7 @@ float Rho_bar(std::vector towers, const bool useNegTowers) } } } - float rho_bar = rho/length; + float rho_bar = length > 0 ? rho/length : 0; return rho_bar; } diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationControlFlags.py b/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationControlFlags.py index af443f792412b765ab47d88f4b999e37ff32cbdc..74078712f4fb2682ab1a950b196547ac51694ecf 100644 --- a/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationControlFlags.py +++ b/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationControlFlags.py @@ -17,7 +17,12 @@ _glflags = list() class SCellType(JobProperty): - """ String which contains the chosen approach to supercell creation: Pulse, Emulated, BCID """ + """ String which contains the chosen approach to supercell creation: Pulse, Emulated, BCID + Pulse: Fully simulated supercells, from supercell pulse + BCID: Fully simulated supercells with applied BCID corrections (this is the only kind of supercell where we apply BCID corrections) + Emulated: Supercells reconstructed from the ET sum of the constituent calo cells + (this disables ApplySCQual) + """ statusOn = True allowedType = ['str'] StoredValue = "Pulse" @@ -29,7 +34,10 @@ _caloflags.append(SCellType) class QualBitMask(JobProperty): - """ int bitmask to be used for quality requirements """ + """ int bitmask to be used for quality requirements + 0x40: Corresponds to the peak finder (BCID maximum) approach, implemented per supercell + 0x200: Corresponds to the ET*time requirement, implemented per supercell + """ statusOn = True allowedType = ['int'] StoredValue = 0x200 @@ -45,7 +53,7 @@ _caloflags.append(ComputeEFexClusters) class ApplySCQual(JobProperty): - """ ComputeClusters """ + """ ? """ statusOn = True allowedType = ['bool'] StoredValue = True @@ -73,17 +81,21 @@ _ctpflags.append(RunCTPEmulation) # global class OutputHistFile(JobProperty): - """ Location of output root file """ + """ Location of output root file + If this is changed to a different filename, + then something else than EXPERT should be used, + and some L1 algorithms need to change the hist stream + """ statusOn = True allowedType = ['str'] - StoredValue = "L1Sim#l1simulation.root" + StoredValue = "EXPERT#expert-monitoring.root" _glflags.append(OutputHistFile) class EnableDebugOutput(JobProperty): """ To enable DEBUG or VERBOSE output for specific algorithms """ statusOn = True allowedType = ['bool'] - StoredValue = True + StoredValue = False _glflags.append(EnableDebugOutput) diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationSequence.py b/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationSequence.py new file mode 100644 index 0000000000000000000000000000000000000000..033801126470d78a19ad3bd0c259a6d14cbf2edb --- /dev/null +++ b/Trigger/TrigT1/TrigT1CaloFexSim/python/L1SimulationSequence.py @@ -0,0 +1,159 @@ + + +from AthenaCommon.Include import include # to include old style job options + +def setupRun3L1CaloSimulationSequence(skipCTPEmulation = False): + + ## print some information about the conditions the simulation + ## is running in + + from AthenaCommon.Logging import logging + log = logging.getLogger( 'TrigT1CaloFexSim.L1Sim' ) + log.setLevel(logging.INFO) + + from RecExConfig.RecFlags import rec + from AthenaCommon.GlobalFlags import globalflags, jobproperties + log.info("Begin setup of L1 Calo Run 3 simulation chain") + log.info("rec.read.* : RDO: %s, ESD: %s, AOD: %s" % (rec.readRDO(), rec.readESD(), rec.readAOD()) ) + log.info("rec.do* : RDOTrigger: %s, ESD: %s, AOD: %s" % (rec.doRDOTrigger(), rec.doESD(), rec.doAOD())) + log.info("rec.doWrite.* : ESD: %s, AOD: %s, TAG: %s" % (rec.doWriteESD(), rec.doWriteAOD(), rec.doWriteTAG()) ) + + from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags + log.info(simflags._context_name) + simflags.print_JobProperties('tree&value') + + ## Setup the histogramming, if it does not exist yet + + from AthenaCommon.AppMgr import ServiceMgr as svcMgr + if not hasattr(svcMgr,"THistSvc"): + import AthenaCommon.CfgMgr as CfgMgr + svcMgr += CfgMgr.THistSvc() + (hStream , hFile) = simflags.OutputHistFile().split('#') # e.g. EXPERT#l1Simulation.root + if not hStream in [entry.split()[0] for entry in svcMgr.THistSvc.Output]: + svcMgr.THistSvc.Output += ["%s DATAFILE='%s' OPT='RECREATE'" % tuple(simflags.OutputHistFile().split('#')) ] + + ## The L1 simulation algorithms will be added to a special sequence + ## It will be merged later into the AthAlgSequence + + from AthenaCommon.AlgSequence import AthSequencer, AlgSequence + l1simAlgSeq = AthSequencer("L1Run3SimulationSequence") + topSequence = AlgSequence() + + + ## scheduling eventinfo unless it exists already + from RecExConfig.ObjKeyStore import objKeyStore + if not objKeyStore.isInInput( "xAOD::EventInfo" ): + if not hasattr( topSequence, "xAODMaker::EventInfoCnvAlg" ): + from xAODEventInfoCnv.xAODEventInfoCreator import xAODMaker__EventInfoCnvAlg + topSequence += xAODMaker__EventInfoCnvAlg() + pass + else: + if not hasattr( topSequence, "xAODMaker::EventInfoNonConstCnvAlg" ): + topSequence += CfgMgr.xAODMaker__EventInfoNonConstCnvAlg() + pass + + ## when running on data the ROBDataProviderSvc needs to be setup + if jobproperties.Global.InputFormat() == 'bytestream': + include('TrigT1CaloByteStream/ReadLVL1CaloBSRun2_jobOptions.py') + + ## CaloCells need to be created from LAr and Tile data when running on raw data + ## (when running on ESD, CaloCells should be taken from the file) + doCaloCellCreation = rec.readRDO() + if doCaloCellCreation: + # Setting up the CaloCell creation + # turn off the digits->raw channel reconstruction + from LArROD.LArRODFlags import larRODFlags + from TileRecUtils.TileRecFlags import jobproperties as tileFlags + from CaloRec.CaloCellFlags import jobproperties as caloCellFlags + larRODFlags.readDigits = False + tileFlags.TileRecFlags.readDigits = False + caloCellFlags.CaloCellFlags.doLArCreateMissingCells = False + + log.info("Calling CaloCellGetter to setup creation of calo cells") + # this is a bit ugly but it will make sure the CaloCellGetter gets into the L1Run3SimulationSequence + topSequenceSnapshot = [c for c in topSequence] + from CaloRec.CaloCellGetter import CaloCellGetter + CaloCellGetter() + for alg in topSequence: + if alg not in topSequenceSnapshot: + l1simAlgSeq += alg + topSequence.removeAll() + for alg in topSequenceSnapshot: + topSequence += alg + + + + ## Setup the provider of the SuperCells + if simflags.Calo.SCellType() == "Pulse": + # These are fully simulated supercells, from supercell pulse + # collection is CaloCellContainer#SCell + SCIn="SCell" + elif simflags.Calo.SCellType() == "BCID": + # These are fully simulated supercells with applied BCID corrections + # This is the only kind of supercells where BCID corrections are applied + from TrigT1CaloFexSim.TrigT1CaloFexSimConfig import createSuperCellBCIDAlg + l1simAlgSeq += createSuperCellBCIDAlg() + SCIn="SCellBCID" + elif simflags.Calo.SCellType() == "Emulated": + # Supercells are reconstructed from the ET sum of the constituent calo cells + # This sets simflags.Calo.ApplySCQual to False + from LArL1Sim.LArL1SimConf import LArSCSimpleMaker + l1simAlgSeq += LArSCSimpleMaker( SCellContainer="SimpleSCell" ) + SCIn="SimpleSCell" + else: + SCIn="SCell" # default + + # Schedule towermaker + from TrigT1CaloFexSim.TrigT1CaloFexSimConfig import createJGTowerReader, createJGTowerMaker + l1simAlgSeq += createJGTowerMaker( useSCQuality = simflags.Calo.ApplySCQual(), + useAllCalo = False, + SuperCellType = SCIn, + SuperCellQuality = simflags.Calo.QualBitMask() ) + + + # Schedule fex algorithms + if simflags.Calo.RunFexAlgorithms(): + + # eFEX + from TrigL1CaloUpgrade.TrigL1CaloUpgradeConfig import enableEfexAlgorithms + enableEfexAlgorithms ( l1simAlgSeq, + SuperCellContainer = SCIn, + useTDR = False, + doLArFex = False, + ApplySCQual = simflags.Calo.ApplySCQual(), + SCBitMask = simflags.Calo.QualBitMask() ) + # j/gFEX + l1simAlgSeq += createJGTowerReader(SuperCellType=SCIn) # too much debug output + + # Schedule CTP Simulation + if not skipCTPEmulation and simflags.CTP.RunCTPEmulation(): + from TrigT1CTP.TrigT1CTP_EnableCTPEmulation import enableCTPEmulation + enableCTPEmulation(l1simAlgSeq) + + #algSequence = AthSequencer("AthAlgSeq") + for alg in l1simAlgSeq: + topSequence += alg + l1simAlgSeq.removeAll() + + if simflags.EnableDebugOutput(): + log.debug("Algorithm sequence after L1 simulation setup") + from AthenaCommon.AlgSequence import dumpSequence + dumpSequence(topSequence) + + + ## Configure the output content + if rec.doWriteAOD(): + from TrigT1CaloFexSim.SetupOutput import fillAOD + stream = fillAOD( SuperCellContainer=SCIn, + WriteAllCalo=False) + + if rec.doRDOTrigger(): + from TrigT1CaloFexSim.SetupOutput import fillRDO + stream = fillRDO( SuperCellContainer=SCIn, + WriteAllCalo=False) + + if simflags.EnableDebugOutput(): + from TrigT1CaloFexSim.SetupOutput import printStreamingInfo + printStreamingInfo() + + log.info("Finished setup of L1 Calo Run 3 simulation chain") diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/python/SetupOutput.py b/Trigger/TrigT1/TrigT1CaloFexSim/python/SetupOutput.py new file mode 100644 index 0000000000000000000000000000000000000000..8158a5a4e3086bfb847db481b2bff641ca263c80 --- /dev/null +++ b/Trigger/TrigT1/TrigT1CaloFexSim/python/SetupOutput.py @@ -0,0 +1,73 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +def fillOutStream ( stream, SuperCellContainer="SCellBCID", WriteAllCalo=False ): + + itemList = [] + + itemList += ["CaloCellContainer#%s" % SuperCellContainer] + if WriteAllCalo: + itemList += [ "CaloCellContainer#AllCalo" ] + + # Run 2 towers + itemList += [ "xAOD::TriggerTowerContainer#xAODTriggerTowers", + "xAOD::TriggerTowerAuxContainer#xAODTriggerTowersAux." ] + + # New JTowers and GTowers + for tower in [ "JTower", "GTower" ]: + itemList += [ "xAOD::JGTowerContainer#%s" % tower, + "xAOD::JGTowerAuxContainer#%sAux.*" % tower ] + + # gFEX jets and MET + itemList += [ "xAOD::JetRoIContainer#*", + "xAOD::JetRoIAuxContainer#*", + "xAOD::EnergySumRoI#*", + "xAOD::EnergySumRoIAuxInfo#*" ] + + # eFEX electrons + for cl in [ "SCluster", "SClusterCl", "SClusterSimple", "SClusterBCIDCl", + "LArLayer1Vars1Sig", "LArLayer1Vars2Sig", "LArLayer1Vars3Sig" ]: + itemList += [ "xAOD::TrigEMClusterContainer#%s" % cl, + "xAOD::TrigEMClusterAuxContainer#%sAux." % cl ] + + # eFEX taus + itemList += [ "xAOD::EmTauRoIContainer#SClusterTau", + "xAOD::EmTauRoIAuxContainer#SClusterTauAux.*" ] + + from OutputStreamAthenaPool.MultipleStreamManager import AugmentedPoolStream + if isinstance(stream,AugmentedPoolStream): + stream.AddItem(itemList) + else: + stream.ItemList += itemList + +def fillAOD ( SuperCellContainer="SCellBCID", WriteAllCalo=False ): + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + stream = MSMgr.GetStream( "StreamAOD" ) + fillOutStream( stream, SuperCellContainer, WriteAllCalo ) + return stream + +def fillESD ( SuperCellContainer="SCellBCID", WriteAllCalo=False ): + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + stream = MSMgr.GetStream( "StreamESD" ) + fillOutStream( stream, SuperCellContainer, WriteAllCalo ) + return stream + +def fillRDO ( SuperCellContainer="SCellBCID", WriteAllCalo=False ): + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + stream = MSMgr.GetStream( "StreamRDO" ) + fillOutStream( stream, SuperCellContainer, WriteAllCalo ) + return stream + + +def printStreamingInfo(): + from AthenaCommon.Logging import logging + log = logging.getLogger( 'TrigT1CaloFexSim.SetupOutput.StreamingInfo' ) + log.setLevel(logging.INFO) + + log.info("MultiStreamManager") + from OutputStreamAthenaPool.MultipleStreamManager import MSMgr + + import AthenaCommon.Configurable as Configurable + configLogLevel = Configurable.log.level + Configurable.log.level = logging.INFO # to show more than just the title of the algs + MSMgr.Print() + Configurable.log.level = configLogLevel diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/python/TrigT1CaloFexSimConfig.py b/Trigger/TrigT1/TrigT1CaloFexSim/python/TrigT1CaloFexSimConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..ddc55e29d414a19e00ae4c0da3a9d85ed6280faf --- /dev/null +++ b/Trigger/TrigT1/TrigT1CaloFexSim/python/TrigT1CaloFexSimConfig.py @@ -0,0 +1,111 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +def createJGTowerMaker( SuperCellContainer="SCell", ApplySCQual=True, SCBitMask=0x200, **kwargs ) : + + from TrigT1CaloFexSim.TrigT1CaloFexSimConf import JGTowerMaker + + towerMaker = JGTowerMaker( useSCQuality = ApplySCQual, + useAllCalo = False, + SuperCellType = SuperCellContainer, + SuperCellQuality = SCBitMask ) + + for arg in kwargs: + towerMaker.__setattr__(arg,kwargs[arg]) + + from AthenaCommon.Logging import logging + log = logging.getLogger("TrigT1CaloFexSimConfig") + log.info("Enabling JGTowerMaker %s. It is setup to read SuperCellContainer %s and %sapply SCQuality" % + (towerMaker.name(), towerMaker.SuperCellType, "" if towerMaker.useSCQuality else "not " ) ) + + return towerMaker + + +def createJGTowerReader( SuperCellType = "SCell", **kwargs ) : + + from TrigT1CaloFexSim.TrigT1CaloFexSimConf import JGTowerReader + + towerReader = JGTowerReader( outputNoise = False, + debugJetAlg = False, + SuperCellType = SuperCellType, + noise_file = "Run3L1CaloSimulation/Noise/noise_r10684_MapFixed.root", + plotSeeds = False, + dumpTowerInfo = False, + + makeSquareJets = False, + jJet_seed_size = 0.2, + jJet_r = 0.4, + jJet_max_r = 0.4, + jJet_seed_tower_noise_multiplier = 2.0, + jJet_seed_total_noise_multiplier = 0.0, + jJet_seed_min_ET_MeV = 500, + jJet_jet_tower_noise_multiplier = 2.0, + jJet_jet_total_noise_multiplier = 0.0, + jJet_jet_min_ET_MeV = 500, + + makeRoundJets = True, + jJetRound_seed_size = 0.31, ## seed square of side this. 0.3 for 3x3 towers, but floating point precision + jJetRound_max_r = 0.26, ## distance (in eta and phi, not a radius) + ## within which other seeds will be counted in local max. 0.25 for 5x5 towers, + ## which is what we want, but floating point + jJetRound_r=0.39, ## jet radius. 0.4, but don't want == 0.4 + jJetRound_seed_tower_noise_multiplier = 2.0, + jJetRound_seed_total_noise_multiplier = 0.0, + jJetRound_seed_min_ET_MeV = 500, + jJetRound_jet_tower_noise_multiplier = 2.0, + jJetRound_jet_total_noise_multiplier = 0.0, + jJetRound_jet_min_ET_MeV = 5000, + + makeRoundLargeRJets = True, + jJetRound_LargeR_seed_size = 0.31, # seed square of side this. 0.3 for 3x3 towers + jJetRound_LargeR_max_r = 0.26, # distance (in eta and phi, not a radius) within + # which other seeds will be counted in local max. 0.25 for 5x5 towers, + jJetRound_LargeR_r=0.80, # jet radius. + jJetRound_LargeR_seed_min_ET_MeV = 500, + jJetRound_LargeR_jet_min_ET_MeV = 5000, + + makeJetsFromMap = False, + towerMap = 'Run3L1CaloSimulation/JetMaps/jFexJet_towerMap_2019-02-12_notruncation.txt', + map_seed_tower_noise_multiplier = 2.0, + map_seed_total_noise_multiplier = 0.0, + map_seed_min_ET_MeV = 500, + map_jet_tower_noise_multiplier = 2.0, + map_jet_total_noise_multiplier = 0.0, + map_jet_min_ET_MeV = 500, + + gJet_seed_size=0.2,#Not for gFEX + gJet_max_r=1.0, + gJet_r=1.0, + gJet_seed_tower_noise_multiplier = 0.0, + gJet_seed_min_ET_MeV = 500, + gJet_jet_min_ET_MeV = 5000., + ) + for arg in kwargs: + towerReader.__setattr__(arg,kwargs[arg]) + + from AthenaCommon.Logging import logging + log = logging.getLogger("TrigT1CaloFexSimConfig") + log.info("Enabling JGTowerReader %s. It is setup to create makeSquareJets: %s, makeRoundJets: %s, makeRoundLargeRJets: %s, makeJetsFromMap: %s" % + (towerReader.name(), towerReader.makeSquareJets, towerReader.makeRoundJets, towerReader.makeRoundLargeRJets, towerReader.makeJetsFromMap ) ) + + return towerReader + + +def createSuperCellBCIDAlg(**kwargs): + + from AthenaCommon.AppMgr import ServiceMgr as svcMgr + from LArRecUtils.LArRecUtilsConf import LArFlatConditionSvc; + svcMgr += LArFlatConditionSvc(); + svcMgr.ProxyProviderSvc.ProviderNames += ["LArFlatConditionSvc"]; + svcMgr.LArFlatConditionSvc.DoSuperCells = True; + svcMgr.LArFlatConditionSvc.DoRegularCells = True; + + from CaloTools.CaloLumiBCIDSCToolDefault import CaloLumiBCIDSCToolDefault + svcMgr.ToolSvc += CaloLumiBCIDSCToolDefault() + + # create the algorithm + from TrigL1CaloUpgrade.TrigL1CaloUpgradeConf import SuperCellBCIDAlg + bcidAlg = SuperCellBCIDAlg() + for arg in kwargs: + bcidAlg.__setattr__(arg,kwargs[arg]) + + return bcidAlg diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/ApplyBCIDCorrections.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/ApplyBCIDCorrections.py deleted file mode 100755 index d8a299f550804359eab9dc6bacf410c84c6d71c5..0000000000000000000000000000000000000000 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/ApplyBCIDCorrections.py +++ /dev/null @@ -1,16 +0,0 @@ - -from LArRecUtils.LArRecUtilsConf import LArFlatConditionSvc; -svcMgr+=LArFlatConditionSvc(); -svcMgr.ProxyProviderSvc.ProviderNames+=["LArFlatConditionSvc"]; -svcMgr.LArFlatConditionSvc.DoSuperCells=True; -svcMgr.LArFlatConditionSvc.DoRegularCells=True; - -from CaloTools.CaloLumiBCIDSCToolDefault import CaloLumiBCIDSCToolDefault; -theTool=CaloLumiBCIDSCToolDefault(); -svcMgr.ToolSvc+=theTool; - -from TrigL1CaloUpgrade.TrigL1CaloUpgradeConf import SuperCellBCIDAlg -algseq = CfgMgr.AthSequencer("AthAlgSeq") -algseq += CfgMgr.SuperCellBCIDAlg() - -#StreamAOD.ItemList += ["CaloCellContainer#SCellBCID"] diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableFexAlgorithms.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableFexAlgorithms.py deleted file mode 100644 index ccaaf8066a48409dfdbdc856a73a654c2b23cc48..0000000000000000000000000000000000000000 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableFexAlgorithms.py +++ /dev/null @@ -1,58 +0,0 @@ -def enableJGTowerReader(debug = False, SuperCellType="SCell"): - algseq = CfgMgr.AthSequencer("AthAlgSeq") - - algseq += CfgMgr.JGTowerReader ( - outputNoise = False, - debugJetAlg = debug, - SuperCellType = SuperCellType, - noise_file = "Run3L1CaloSimulation/Noise/noise_r10684_MapFixed.root", - plotSeeds = False, - dumpTowerInfo = False, - - makeSquareJets = False, - jJet_seed_size = 0.2, - jJet_r = 0.4, - jJet_max_r = 0.4, - jJet_seed_tower_noise_multiplier = 2.0, - jJet_seed_total_noise_multiplier = 0.0, - jJet_seed_min_ET_MeV = 500, - jJet_jet_tower_noise_multiplier = 2.0, - jJet_jet_total_noise_multiplier = 0.0, - jJet_jet_min_ET_MeV = 500, - - makeRoundJets = True, - jJetRound_seed_size = 0.31, # seed square of side this. 0.3 for 3x3 towers, but floating point precision - jJetRound_max_r = 0.26, # distance (in eta and phi, not a radius) within which other seeds will be counted in local max. 0.25 for 5x5 towers, which is what we want, but floating point - jJetRound_r=0.39, # jet radius. 0.4, but don't want == 0.4 - jJetRound_seed_tower_noise_multiplier = 2.0, - jJetRound_seed_total_noise_multiplier = 0.0, - jJetRound_seed_min_ET_MeV = 500, - jJetRound_jet_tower_noise_multiplier = 2.0, - jJetRound_jet_total_noise_multiplier = 0.0, - jJetRound_jet_min_ET_MeV = 5000, - - makeRoundLargeRJets = True, - jJetRound_LargeR_seed_size = 0.31, # seed square of side this. 0.3 for 3x3 towers - jJetRound_LargeR_max_r = 0.26, # distance (in eta and phi, not a radius) within which other seeds will be counted in local max. 0.25 for 5x5 towers, - jJetRound_LargeR_r=0.80, # jet radius. - jJetRound_LargeR_seed_min_ET_MeV = 500, - jJetRound_LargeR_jet_min_ET_MeV = 5000, - - makeJetsFromMap = False, - towerMap = 'Run3L1CaloSimulation/JetMaps/jFexJet_towerMap_2019-02-12_notruncation.txt', - #towerMap = 'jFexJet_towerMap_2019-02-15.txt', - map_seed_tower_noise_multiplier = 2.0, - map_seed_total_noise_multiplier = 0.0, - map_seed_min_ET_MeV = 500, - map_jet_tower_noise_multiplier = 2.0, - map_jet_total_noise_multiplier = 0.0, - map_jet_min_ET_MeV = 500, - - gJet_seed_size=0.2,#Not for gFEX - gJet_max_r=1.0, - gJet_r=1.0, - gJet_seed_tower_noise_multiplier = 0.0, - gJet_seed_min_ET_MeV = 500, - gJet_jet_min_ET_MeV = 5000., - ) - diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableJGTowerMaker.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableJGTowerMaker.py deleted file mode 100644 index 07556fc6c13e4737d6b6d4dfecd68c3dbf97a8b6..0000000000000000000000000000000000000000 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/EnableJGTowerMaker.py +++ /dev/null @@ -1,49 +0,0 @@ - - -def enableJGTowerMaker( SuperCellContainer="SCell", ApplySCQual=True, SCBitMask=0x200 ): - - from AthenaCommon.Logging import logging - from AthenaCommon.AppMgr import ServiceMgr as svcMgr - log = logging.getLogger( 'TrigT1CaloFexSim.EnableJGTowerMaker' ) - - log.info("Enabling JGTowerMaker. It is setup to read SuperCellContainer %s and %sapply SCQuality" % (SuperCellContainer, "" if ApplySCQual else "not " ) ) - - global svcMgr - - # Details for tower builder - # svcMgr.IOVDbSvc.dbConnection = "impl=cool;techno=oracle;schema=ATLAS_COOL_LAR;ATLAS_COOLPROD:OFLP130:ATLAS_COOL_LAR_W:" - svcMgr.IOVDbSvc.dbConnection = "sqlite://;schema=gJTowerMap.db;dbname=OFLP200" - if not hasattr(svcMgr,"THistSvc"): - svcMgr += CfgMgr.THistSvc() - svcMgr.THistSvc.Output += ["EXPERT DATAFILE='myOutputFile.root' OPT='RECREATE'"] - - # not sure about this as these variables are not used anywhere - folderlist = [ "/LAR/Identifier/GTowerSCMap", - "/LAR/Identifier/JTowerSCMap" - ] - folderspec = [ ("GTowerSCMap#GTowerSCMapAtlas#%s" % f) for f in folderlist ] - tagspec = [ ("".join(f.split("/"))+"-boohoo") for f in folderlist ] - - - from TrigT1CaloFexSim.TrigT1CaloFexSimConf import JGTowerMaker - - algseq = CfgMgr.AthSequencer("AthAlgSeq") - algseq += CfgMgr.JGTowerMaker( useSCQuality = ApplySCQual, - useAllCalo = False, - SuperCellType = SuperCellContainer, - SuperCellQuality = SCBitMask - ) - - #I've removed CaloCellContainer#SCellBCID CaloCellContainer#SimpleSCell to only save one for now (Ben) - ''' - StreamAOD.ItemList += [ "CaloCellContainer#AllCalo", - "xAOD::TrigEMClusterContainer#SClusterSimple", - "xAOD::TrigEMClusterAuxContainer#SClusterSimpleAux."] - StreamAOD.ItemList += [ "xAOD::TriggerTowerContainer#xAODTriggerTowers", - "xAOD::TriggerTowerAuxContainer#xAODTriggerTowersAux."]#Write out Run 2 towers - StreamAOD.ItemList += [ "xAOD::JGTowerContainer#JTower"] # This and the next 3 might need to be controlled later to avoid increase of AOD size - StreamAOD.ItemList += [ "xAOD::JGTowerAuxContainer#JTowerAux.*"] - StreamAOD.ItemList += [ "xAOD::JGTowerContainer#GTower"] - StreamAOD.ItemList += [ "xAOD::JGTowerAuxContainer#GTowerAux.*"] - ''' - diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/FillAODStream.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/FillAODStream.py index 091b29ad41a97c39a612f451d1547d9ee4b1da6a..f1b442ae29e48b750b79f29cdbe9d1c1d7857d92 100755 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/FillAODStream.py +++ b/Trigger/TrigT1/TrigT1CaloFexSim/share/FillAODStream.py @@ -32,3 +32,4 @@ def fillOutStream ( stream, SuperCellContainer="SCellBCID", WriteAllCalo=False ) def fillAOD ( SuperCellContainer="SCellBCID", WriteAllCalo=False ): fillOutStream( StreamAOD, SuperCellContainer, WriteAllCalo ) + return StreamAOD diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequence.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequence.py index 5a985b75356d0a617e86a4c765ba55a8a4af5cf0..374adfef3d5f32cde95fceb5b86d7fdc7acd7a8e 100644 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequence.py +++ b/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequence.py @@ -1,72 +1,3 @@ -from AthenaCommon.Logging import logging -log = logging.getLogger( 'TrigT1CaloFexSim.L1Sim' ) -log.setLevel(logging.DEBUG) -from RecExConfig.RecFlags import rec -from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags - - -CfgMgr.MessageSvc().setError+=["HepMcParticleLink"]; - -SCIn="SCell" # Initialize to use default supercells from ESD files - -log.debug("dir() = %r" % dir()) - - -log.info("rec.read.* : RDO: %s, ESD: %s, AOD: %s" % (rec.readRDO(), rec.readESD(), rec.readAOD()) ) -log.info("rec.do* : RDOTrigger: %s, ESD: %s, AOD: %s" % (rec.doRDOTrigger(), rec.doESD(), rec.doAOD())) -log.info("rec.doWrite.* : ESD: %s, AOD: %s, TAG: %s" % (rec.doWriteESD(), rec.doWriteAOD(), rec.doWriteTAG()) ) -log.info(simflags._context_name) -simflags.print_JobProperties('tree&value') - - -if rec.doAOD(): - #if ( ("StreamAOD" in dir()) or ("StreamAOD_Augmented" in dir()) ): - - algseq = CfgMgr.AthSequencer("AthAlgSeq") - - # Determine input supercell approach - if simflags.Calo.SCellType() == "Pulse": - SCIn="SCell" - elif simflags.Calo.SCellType() == "BCID": - include("TrigT1CaloFexSim/ApplyBCIDCorrections.py") - SCIn="SCellBCID" - elif simflags.Calo.SCellType() == "Emulated": - algseq += CfgMgr.LArSCSimpleMaker ( - SCellContainer="SimpleSCell" - ) - SCIn="SimpleSCell" - - # Schedule towermaker - include ( "TrigT1CaloFexSim/EnableJGTowerMaker.py" ) - enableJGTowerMaker( SuperCellContainer = SCIn, - ApplySCQual = simflags.Calo.ApplySCQual(), - SCBitMask = simflags.Calo.QualBitMask()) - - # Schedule fex algorithms - if simflags.Calo.RunFexAlgorithms(): - - # eFEX - include ("TrigL1CaloUpgrade/EnableEfexAlgorithms.py") - enableEfexAlgorithms ( SuperCellContainer = SCIn, - useTDR = False, - doLArFex = False, - ApplySCQual = simflags.Calo.ApplySCQual(), - SCBitMask = simflags.Calo.QualBitMask() ) - # j/gFEX - include ( "TrigT1CaloFexSim/EnableFexAlgorithms.py" ) - enableJGTowerReader(debug = False, SuperCellType=SCIn) # too much debug output - - # Schedule CTP Simulation - if simflags.CTP.RunCTPEmulation(): - include ( "TrigT1CTP/TrigT1CTP_EnableCTPEmulation.py" ) - enableCTPEmulation() - - -if rec.doAOD() and rec.doWriteAOD(): - print "ADDING CONTAINERS TO AOD" - include ("TrigT1CaloFexSim/FillAODStream.py") - fillAOD(SuperCellContainer=SCIn, - WriteAllCalo=False) - - +from TrigT1CaloFexSim.L1SimulationSequence import setupRun3L1CaloSimulationSequence +setupRun3L1CaloSimulationSequence() diff --git a/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequenceBS.py b/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequenceBS.py deleted file mode 100644 index 2a497a4201a96af24db6e6490a783eddf1541da5..0000000000000000000000000000000000000000 --- a/Trigger/TrigT1/TrigT1CaloFexSim/share/createL1SimulationSequenceBS.py +++ /dev/null @@ -1,125 +0,0 @@ - -from AthenaCommon.Logging import logging -log = logging.getLogger( 'TrigT1CaloFexSim.L1Sim' ) -log.setLevel(logging.DEBUG) - -from RecExConfig.RecFlags import rec -from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags - -log.debug("dir() = %r" % dir()) - -simflags.Calo.SCellType = "Emulated" -simflags.CTP.RunCTPEmulation = True - -log.info("rec.read.* : RDO: %s, ESD: %s, AOD: %s" % (rec.readRDO(), rec.readESD(), rec.readAOD()) ) -log.info("rec.do* : RDOTrigger: %s, ESD: %s, AOD: %s" % (rec.doRDOTrigger(), rec.doESD(), rec.doAOD())) -log.info("rec.doWrite.* : ESD: %s, AOD: %s, TAG: %s" % (rec.doWriteESD(), rec.doWriteAOD(), rec.doWriteTAG()) ) -log.info(simflags._context_name) -simflags.print_JobProperties('tree&value') - - -if rec.readRDO(): - - # algorithm shuffling - # * at this stage (Modifier.post_exec) the HLT is set up and in sequence TopAlg -> move to HLTAlgSeq - # * CaloCellGetter by default writes to TopAlg -> need to move to AthAlgSeq before everything else is added - # * the rest of the L1simulation is being added to AthAlgSeq - - from AthenaCommon.AlgSequence import AlgSequence - topSeq = AlgSequence() - algSeq = CfgMgr.AthSequencer("AthAlgSeq") - hltSeq = CfgMgr.AthSequencer("HLTSeq") - - for alg in topSeq: - if alg.name() in ['ALFAROBMonitor', 'l1topoWriteValData', 'MuCTPiROBMonitor']: - continue - if alg.name() == 'xAODMaker::EventInfoCnvAlg': - algSeq += alg # event info converter has to come first - continue - hltSeq += alg - topSeq.removeAll() - - # Setting up the CaloCell creation - # turn off the digits->raw channel reconstruction - from LArROD.LArRODFlags import larRODFlags - from TileRecUtils.TileRecFlags import jobproperties as tileFlags - from CaloRec.CaloCellFlags import jobproperties as caloCellFlags - larRODFlags.readDigits=False - tileFlags.TileRecFlags.readDigits=False - caloCellFlags.CaloCellFlags.doLArCreateMissingCells = False - - #from LArConditionsCommon.LArCondFlags import larCondFlags - #larCondFlags.useShape = False - - from CaloRec.CaloCellGetter import CaloCellGetter - log.info("Calling CaloCellGetter to setup creation of calo cells") - CaloCellGetter() - for alg in topSeq: - algSeq += alg - topSeq.removeAll() - - include('TrigT1CaloByteStream/ReadLVL1CaloBSRun2_jobOptions.py') - - # Determine input supercell approach - if simflags.Calo.SCellType() == "Pulse": - SCIn="SCell" - elif simflags.Calo.SCellType() == "BCID": - include("TrigT1CaloFexSim/ApplyBCIDCorrections.py") - SCIn="SCellBCID" - elif simflags.Calo.SCellType() == "Emulated": - algSeq += CfgMgr.LArSCSimpleMaker ( - SCellContainer = "SimpleSCell" - ) - SCIn="SimpleSCell" - - - - # Schedule towermaker - include ( "TrigT1CaloFexSim/EnableJGTowerMaker.py" ) - enableJGTowerMaker( SuperCellContainer = SCIn, - ApplySCQual = simflags.Calo.ApplySCQual(), - SCBitMask = simflags.Calo.QualBitMask()) - - - if simflags.Calo.RunFexAlgorithms(): - - # eFEX - include ("TrigL1CaloUpgrade/EnableEfexAlgorithms.py") - enableEfexAlgorithms ( SuperCellContainer = SCIn, - useTDR = False, - doLArFex = False, - ApplySCQual = simflags.Calo.ApplySCQual(), - SCBitMask = simflags.Calo.QualBitMask() ) - - # j/gFEX - include ( "TrigT1CaloFexSim/EnableFexAlgorithms.py" ) - enableJGTowerReader(debug = False, SuperCellType=SCIn) # too much debug output - - # Schedule CTP Simulation - if simflags.CTP.RunCTPEmulation(): - include ( "TrigT1CTP/TrigT1CTP_EnableCTPEmulation.py" ) - enableCTPEmulation() - - #algSeq.removeAll() - - # now append the HLT to the algorithm sequence - for alg in hltSeq: - algSeq += alg - hltSeq.removeAll() - - if simflags.EnableDebugOutput(): - include( "TrigT1CaloFexSim/enableDebugOutput.py" ) - -if rec.doRDOTrigger(): - print "ADDING CONTAINERS TO RDOTrigger" - include ("TrigT1CaloFexSim/FillAODStream.py") - - # from AthenaCommon.AthenaCommonFlags import athenaCommonFlags - # from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream - # streamRDO = AthenaPoolOutputStream("StreamRDO", athenaCommonFlags.PoolRDOOutput.get_Value(), asAlg=True) - - fillStream( StreamRDO, - SuperCellContainer=SCIn, - WriteAllCalo=False) - - diff --git a/Trigger/TrigValidation/TriggerTest/test/exec_athena_art_trigger_validation.sh b/Trigger/TrigValidation/TriggerTest/test/exec_athena_art_trigger_validation.sh index f668ace5ac83406af40f4f2839999b972da64f94..3c753bac79b7c218d07bc50c55740ff29a9420e3 100755 --- a/Trigger/TrigValidation/TriggerTest/test/exec_athena_art_trigger_validation.sh +++ b/Trigger/TrigValidation/TriggerTest/test/exec_athena_art_trigger_validation.sh @@ -24,7 +24,7 @@ if [ -z ${JOB_LOG} ]; then export JOB_LOG="athena.log" fi -if [ -z ${EXTRA} ]; then +if [ -z "${EXTRA}" ]; then export EXTRA="extraPython=False;" fi diff --git a/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_build.sh b/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_build.sh new file mode 100755 index 0000000000000000000000000000000000000000..4b0631a6e685196e658970f4b8fa6e91db5f0a62 --- /dev/null +++ b/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_build.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# art-description: MC v8 TriggerTest on MC +# art-type: build +# art-include: 21.3/Athena +# art-output: HLTChain.txt +# art-output: HLTTE.txt +# art-output: L1AV.txt +# art-output: HLTconfig*.xml +# art-output: L1Topoconfig*.xml +# art-output: LVL1config*.xml +# art-output: *.log +# art-output: costMonitoring_* +# art-output: *.root +# art-output: ntuple.pmon.gz +# art-output: *perfmon* +# art-output: TotalEventsProcessed.txt +# art-output: *.regtest.new + +export NAME="mc_pp_v8_enableLVL1PhaseI_build" +export MENU="MC_pp_v8" +export EVENTS="5" +export COST_MONITORING="False" +export EXTRA="from TriggerJobOpts.TriggerFlags import TriggerFlags as tf;tf.doLVL1PhaseI.set_Value_and_Lock(True);" + +source exec_athena_art_trigger_validation.sh +source exec_art_triggertest_post.sh diff --git a/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_grid.sh b/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_grid.sh new file mode 100755 index 0000000000000000000000000000000000000000..3e2400b127dd1a7a25b785ea6ed5ce1951ac0508 --- /dev/null +++ b/Trigger/TrigValidation/TriggerTest/test/test_mc_pp_v8_enableLVL1PhaseI_grid.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# art-description: MC v8 TriggerTest on MC +# art-type: grid +# art-include: 21.3/Athena +# art-output: HLTChain.txt +# art-output: HLTTE.txt +# art-output: L1AV.txt +# art-output: HLTconfig*.xml +# art-output: L1Topoconfig*.xml +# art-output: LVL1config*.xml +# art-output: *.log +# art-output: costMonitoring_* +# art-output: *.root +# art-output: ntuple.pmon.gz +# art-output: *perfmon* +# art-output: TotalEventsProcessed.txt +# art-output: *.regtest.new + +export NAME="mc_pp_v8_enableLVL1PhaseI_grid" +export MENU="MC_pp_v8" +export EVENTS="500" +export EXTRA="from TriggerJobOpts.TriggerFlags import TriggerFlags as tf;tf.doLVL1PhaseI.set_Value_and_Lock(True);" + +source exec_athena_art_trigger_validation.sh +source exec_art_triggertest_post.sh diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerGetter.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerGetter.py index fe24e60ea2069c3a8d7019decabcc5648e099695..6434c388e467735ddab5aedab2e144f74e5ce8a1 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerGetter.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerGetter.py @@ -83,6 +83,12 @@ class Lvl1SimulationGetter (Configured): from TrigT1MBTS.TrigT1MBTSConf import LVL1__TrigT1MBTS topSequence += LVL1__TrigT1MBTS() + if TriggerFlags.doLVL1PhaseI(): + log.info("setting up the Run 3 L1 calo simulation") + from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags + simflags.Calo.SCellType = "Emulated" # as we have no SuperCells yet + from TrigT1CaloFexSim.L1SimulationSequence import setupRun3L1CaloSimulationSequence + setupRun3L1CaloSimulationSequence(skipCTPEmulation=True) # schedule simulation if TriggerFlags.doMuon() and (not DetFlags.readRIOPool.LVL1_on() ): @@ -176,9 +182,14 @@ class Lvl1SimulationGetter (Configured): topSequence.L1TopoSimulation.MuonInputProvider.MuonEncoding = 0 - log.info("adding ctp simulation to the topSequence") - from TrigT1CTP.TrigT1CTPConfig import CTPSimulationInReco - topSequence += CTPSimulationInReco("CTPSimulation") + if TriggerFlags.doLVL1PhaseI(): + log.info("adding Run 3 CTP emulation to the topSequence") + from TrigT1CTP.TrigT1CTP_EnableCTPEmulation import enableCTPEmulation + enableCTPEmulation(topSequence) + else: + log.info("adding CTP simulation to the topSequence") + from TrigT1CTP.TrigT1CTPConfig import CTPSimulationInReco + topSequence += CTPSimulationInReco("CTPSimulation") log.info("adding ROIB simulation to the topSequence") from TrigT1RoIB.TrigT1RoIBConf import ROIB__RoIBuilder @@ -256,5 +267,5 @@ class Lvl1SimulationGetter (Configured): # objKeyStore.addManyTypesStreamESD(getLvl1ESDList()) # from TrigEDMConfig.TriggerEDM import getLvl1AODList # objKeyStore.addManyTypesStreamAOD(getLvl1AODList()) - + return True diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerOnlineGetter.py b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerOnlineGetter.py index 6c77e2403e24bdfb2fdd05a7127bb5c070b597b0..c4b9591536680d92ad5e721eb8e06883f663c6c7 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerOnlineGetter.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/Lvl1TriggerOnlineGetter.py @@ -12,8 +12,6 @@ from AthenaCommon.Include import include # to include old style job options from AthenaCommon.AppMgr import theApp if (not TriggerFlags.fakeLVL1()) and TriggerFlags.doLVL1(): - from TrigT1CTP.TrigT1CTPConfig import CTPSimulation - from TrigT1RoIB.TrigT1RoIBConf import ROIB__RoIBuilder import TrigT1RPCRecRoiSvc.TrigT1RPCRecRoiConfig import TrigT1TGCRecRoiSvc.TrigT1TGCRecRoiConfig @@ -25,6 +23,21 @@ if (not TriggerFlags.fakeLVL1()) and TriggerFlags.doLVL1(): from RecExConfig.Configured import Configured +""" +This LvlTriggerOnlineGetter.Lvl1SimulationGetter is primarily called from + TriggerRelease/Trigger_topOptions_standalone.py +which is called primarily from + TriggerRelease/runHLT_standalone.py + +In Trigger_topOptions_standalone.py TriggerFlags.doLVL1 is set to False when running on bytestream. +When running on bytestream, the running of LVL1 is enabled through the rerunLVL1 and rerunLVL1Phase-I modifiers + +However, these modifiers are executed either before or after the full trigger setup, which makes it difficult to +execute the LVL1 simulation setup at the right place + +Therefor, the modifier rerunLVL1PhaseI only sets TriggerFlags.doLVL1PhaseI=True and relies on the work being done +in here. +""" class Lvl1SimulationGetter (Configured): @@ -33,6 +46,11 @@ class Lvl1SimulationGetter (Configured): def configure(self): log = logging.getLogger( "Lvl1TriggerOnlineGetter.py" ) + log.info("TriggerFlags") + log.info(" doLVL1 = %s" % TriggerFlags.doLVL1() ) + log.info(" doLVL1PhaseI = %s" % TriggerFlags.doLVL1PhaseI() ) + log.info(" doL1Topo = %s" % TriggerFlags.doL1Topo() ) + log.info(" fakeLVL1 = %s" % TriggerFlags.fakeLVL1() ) from AthenaServices.AthenaServicesConf import AthenaOutputStream from AthenaCommon.AppMgr import ServiceMgr @@ -49,6 +67,7 @@ class Lvl1SimulationGetter (Configured): log.info( "LVL1ConfigSvc already created. Will ignore configuration from xml file="+TriggerFlags.inputLVL1configFile()\ +" and use file="+ServiceMgr.LVL1ConfigSvc.XMLFile ) + if (not TriggerFlags.fakeLVL1()) and TriggerFlags.doLVL1(): if TriggerFlags.useCaloTTL(): include( "TrigT1CaloSim/TrigT1CaloSimJobOptions_TTL1.py") @@ -56,6 +75,15 @@ class Lvl1SimulationGetter (Configured): include( "TrigT1CaloSim/TrigT1CaloSimJobOptions_Cell.py") topSequence += LVL1__TrigT1MBTS() + if TriggerFlags.doLVL1PhaseI(): + log.info("setting up the Run 3 L1 calo simulation") + from TrigT1CaloFexSim.L1SimulationControlFlags import L1Phase1SimFlags as simflags + simflags.Calo.SCellType = "Emulated" # as we have no SuperCells yet + from TrigT1CaloFexSim.L1SimulationSequence import setupRun3L1CaloSimulationSequence + setupRun3L1CaloSimulationSequence(skipCTPEmulation=True) + + if (not TriggerFlags.fakeLVL1()) and TriggerFlags.doLVL1(): + topSequence += L1Muctpi() if TriggerFlags.doL1Topo(): @@ -82,11 +110,21 @@ class Lvl1SimulationGetter (Configured): log.info("Muon eta/phi encoding with full granularity for data (L1 Simulation) - should be faced out") topSequence.L1TopoSimulation.MuonInputProvider.MuonEncoding = 1 - log.info("adding ctp simulation to the topSequence") - topSequence += CTPSimulation("CTPSimulation") + if not TriggerFlags.doLVL1PhaseI(): + log.info("adding CTP simulation to the topSequence") + from TrigT1CTP.TrigT1CTPConfig import CTPSimulation + topSequence += CTPSimulation("CTPSimulation") + + if TriggerFlags.doLVL1PhaseI(): + log.info("adding Run 3 CTP emulation to the topSequence from with Lvl1TriggerOnlineGetter") + from TrigT1CTP.TrigT1CTP_EnableCTPEmulation import enableCTPEmulation + enableCTPEmulation(topSequence) + if ((not TriggerFlags.fakeLVL1()) and TriggerFlags.doLVL1()) or TriggerFlags.doLVL1PhaseI(): log.info("adding ROIB simulation to the topSequence") + from TrigT1RoIB.TrigT1RoIBConf import ROIB__RoIBuilder topSequence += ROIB__RoIBuilder("RoIBuilder") + topSequence.RoIBuilder.CTPSLinkLocation = '/Event/CTPSLinkLocation_Rerun' return True # end of class Lvl1SimulationGetter diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerFlags.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerFlags.py index e98ba9f325a7a03fce2578987e92168a1d80c76b..17698a1381539c5d436b81f884c3bdd8f0c7b708 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerFlags.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerFlags.py @@ -28,6 +28,14 @@ class doLVL1(JobProperty): _flags.append(doLVL1) +class doLVL1PhaseI(JobProperty): + """ enables the Run 3 simulation for L1 and HLT """ + statusOn=True + allowedType=['bool'] + StoredValue=False + +_flags.append(doLVL1PhaseI) + class doL1Topo(JobProperty): """ Run the L1 Topo simulation (set to FALSE to read the L1 Topo result from BS file) """ statusOn=True diff --git a/Trigger/TriggerCommon/TriggerMenu/python/menu/GenerateMenu.py b/Trigger/TriggerCommon/TriggerMenu/python/menu/GenerateMenu.py index 43a62b67175457d37ee4d74b5c2a84fe36ac0df1..ae371a70450756e7b52a24459ae9d6c3bfa1dc04 100755 --- a/Trigger/TriggerCommon/TriggerMenu/python/menu/GenerateMenu.py +++ b/Trigger/TriggerCommon/TriggerMenu/python/menu/GenerateMenu.py @@ -41,7 +41,7 @@ _func_to_modify_signatures = None class GenerateMenu: def overwriteSignaturesWith(f): - log.info('In overwriteSignaturesWith ') + log.debug('In overwriteSignaturesWith ') global _func_to_modify_signatures if _func_to_modify_signatures != None: log.warning('Updating the function to modify signatures from %s to %s'\ @@ -49,7 +49,7 @@ class GenerateMenu: _func_to_modify_signatures = f def overwriteMenuWith(f): - log.info('In overwriteSignaturesWith ') + log.debug('In overwriteSignaturesWith ') global _func_to_modify_the_menu if _func_to_modify_the_menu != None: log.warning('Updating the function to modify the menu from %s to %s'\ @@ -633,12 +633,11 @@ class GenerateMenu: #Do TOPO on Combined chains if self.doCombinedChains: - log.info('doTopo for combined chain = %s' % str(doTopo)) - log.info(theChainDef) + if doTopo: + log.info('doTopo for combined chain = %s' % str(doTopo)) if doTopo: log.info('run generateCombinedChainDefs') theChainDef = TriggerMenu.combined.generateCombinedChainDefs._addTopoInfo(theChainDef,chainDicts,listOfChainDefs) - log.info(theChainDef) return theChainDef @@ -982,7 +981,7 @@ class GenerateMenu: ( self.trigConfL1.inputFile if self.trigConfL1.inputFile!=None else self.trigConfL1.outputFile, self.triggerPythonConfig.getHLTConfigFile(), "TriggerMenu/menu_check_exceptions.xml") ) - print output + #print output # this does test the triggertype (JS) #for bit in xrange(8): diff --git a/Trigger/TriggerRelease/python/Modifiers.py b/Trigger/TriggerRelease/python/Modifiers.py index 64076f42e4d5248f0e38eefa8951d810fd597cb4..39e83098bd062284d87fbc40c3234e325180579d 100644 --- a/Trigger/TriggerRelease/python/Modifiers.py +++ b/Trigger/TriggerRelease/python/Modifiers.py @@ -796,8 +796,6 @@ class rerunLVL1(_modifier): def preSetup(self): - log.info("JOERG Seeting up rerunLVL1 for Run 2") - if rerunLVL1PhaseI.wasExecuted(): raise RuntimeError("ERROR modifiers 'rerunLVL1PhaseI' and 'rerunLVL1' have both been set, but they are exclusive. Please specify only one") rerunLVL1.__wasExecuted = True @@ -910,18 +908,15 @@ class rerunLVL1PhaseI(_modifier): def wasExecuted(cls): return cls.__wasExecuted - def postSetup(self): + def preSetup(self): if rerunLVL1.wasExecuted(): raise RuntimeError("ERROR modifiers 'rerunLVL1PhaseI' and 'rerunLVL1' have both been set, but they are exclusive. Please specify only one") - rerunLVL1.__wasExecuted = True + rerunLVL1PhaseI.__wasExecuted = True log = logging.getLogger('Modifiers.py:rerunLVL1PhaseI') - log.info("JOERG setting up rerunLVL1 for Run 3") + log.info("enabling L1Calo Phase-I simulation by setting doLVL1PhaseI=True") + TriggerFlags.doLVL1PhaseI.set_Value_and_Lock(True) - from AthenaCommon.Include import include - include("TrigT1CaloFexSim/createL1SimulationSequenceBS.py") - - - # def postSetup(self): + def postSetup(self): svcMgr.ByteStreamAddressProviderSvc.TypeNames += [ "MuCTPI_RIO/MUCTPI_RIO", "CTP_RIO/CTP_RIO"