ATLAS Offline Software
EfexInputMonitorAlgorithm.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "TTree.h"
8 #include "TFile.h"
9 
10 EfexInputMonitorAlgorithm::EfexInputMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
11  : AthMonitorAlgorithm(name,pSvcLocator)
12 {
13 }
14 
16 
17  ATH_MSG_DEBUG("EfexInputMonitorAlgorith::initialize");
18  ATH_MSG_DEBUG("Package Name "<< m_packageName);
19  ATH_MSG_DEBUG("m_eFexTowerContainer"<< m_eFexTowerContainerKey);
20 
21  // we initialise all the containers that we need
22  ATH_CHECK( m_eFexTowerContainerKey.initialize() );
23  ATH_CHECK( m_eFexTowerContainerRefKey.initialize() );
24 
25  ATH_CHECK( m_bcContKey.initialize() );
26 
27 
28  // load the scid map
29  if (auto fileName = PathResolverFindCalibFile( "L1CaloFEXByteStream/2023-02-13/scToEfexTowers.root" ); !fileName.empty()) {
30  std::unique_ptr<TFile> f( TFile::Open(fileName.c_str()) );
31  if (f) {
32  TTree* t = f->Get<TTree>("mapping");
33  if(t) {
34  unsigned long long scid = 0;
35  std::pair<int,int> coord = {0,0};
36  std::pair<int,int> slot;
37  t->SetBranchAddress("scid",&scid);
38  t->SetBranchAddress("etaIndex",&coord.first);
39  t->SetBranchAddress("phiIndex",&coord.second);
40  t->SetBranchAddress("slot1",&slot.first);
41  t->SetBranchAddress("slot2",&slot.second);
42  for(Long64_t i=0;i<t->GetEntries();i++) {
43  t->GetEntry(i);
44  m_scMap[std::make_pair(coord,slot.first)].first.insert(scid);
45  m_scMap[std::make_pair(coord,slot.second)].first.insert(scid);
46  }
47  // now convert scid list to list of strings
48  for(auto& [key,scs] : m_scMap) {
49  std::stringstream s;
50  for(auto id : scs.first) {
51  s << (id>>32) << ",";
52  }
53  scs.second = s.str();
54  scs.first.clear(); // not needed any more, so clear it
55  }
56  }
57  }
58  }
59 
60 
61 
62 
64 }
65 
66 StatusCode EfexInputMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
67 
68  ATH_MSG_DEBUG("EfexInputMonitorAlgorithm::fillHistograms");
69 
70  // Access eFex eTower container - should always have a collection, even if empty
72  if(!eFexTowerContainer.isValid()){
73  ATH_MSG_ERROR("No eFex Tower container found in storegate "<< m_eFexTowerContainerKey);
74  return StatusCode::FAILURE;
75  }
76 
77  auto evtNumber = Monitored::Scalar<ULong64_t>("EventNumber",GetEventInfo(ctx)->eventNumber());
78  auto lbnString = Monitored::Scalar<std::string>("LBNString",std::to_string(GetEventInfo(ctx)->lumiBlock()));
79  auto lbn = Monitored::Scalar<int>("LBNS",GetEventInfo(ctx)->lumiBlock());
80 
81  // mismatches can be caused by recent/imminent OTF maskings, so track timings
82  auto timeSince = Monitored::Scalar<int>("timeSince", -1);
83  auto timeUntil = Monitored::Scalar<int>("timeUntil", -1);
84  auto timeUntilCapped = Monitored::Scalar<int>("timeUntilCapped", -1); // capped at 199 for histograms
86  if(larBadChan.isValid()) {
87  timeSince = ctx.eventID().time_stamp() - larBadChan.getRange().start().time_stamp();
88  timeUntil = larBadChan.getRange().stop().time_stamp() - ctx.eventID().time_stamp();
89  timeUntilCapped = std::min(int(timeUntil),199);
90  }
91  auto Decision = Monitored::Scalar<std::string>("Error","");
92 
93  auto TowerId = Monitored::Scalar<int32_t>("TowerId",0);
94  auto Towereta = Monitored::Scalar<float>("TowerEta",0.0);
95  auto Towerphi = Monitored::Scalar<float>("TowerPhi",0.0);
96  auto TowerRefCount = Monitored::Scalar<int>("RefTowerCount",0);
97  auto Toweremstatus = Monitored::Scalar<uint32_t>("TowerEmstatus",0.0);
98  auto Towerhadstatus = Monitored::Scalar<uint32_t>("TowerHadstatus",0.0);
99  auto TowerSlot = Monitored::Scalar<int32_t>("TowerSlot",0);
100  auto TowerCount = Monitored::Scalar<int>("TowerCount",0);
101  auto SlotSCID = Monitored::Scalar<std::string>("SlotSCID","");
102 
103  // first test dataTowers not empty unless prescaled event
104  bool isPrescaled = (((GetEventInfo(ctx)->extendedLevel1ID()&0xffffff) % 200) != 0);
105  if(!isPrescaled && eFexTowerContainer->empty()) {
106  Decision = "MissingDataTowers";
107  fill("errors", Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
108  } else if(isPrescaled && !eFexTowerContainer->empty()) {
109  Decision = "UnexpectedDataTowers";
110  fill("errors", Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
111  }
112 
113 
114 
115  // Access eFexTower ref container, if possible
117  auto etaIndex = [](float eta) { return int( eta*10 ) + ((eta<0) ? -1 : 1); };
118  auto phiIndex = [](float phi) { return int( phi*32./M_PI ) + (phi<0 ? -1 : 1); };
119  std::map<std::pair<int,int>,const xAOD::eFexTower*> refTowers;
120  bool missingLAr = false;
121  if (eFexTowerContainerRef.isValid()) {
122  if(eFexTowerContainerRef->empty()) missingLAr=true;
123  for (auto eTower: *eFexTowerContainerRef) {
124  refTowers[std::pair(etaIndex(eTower->eta() + 0.025), phiIndex(eTower->phi() + 0.025))] = eTower;
125  // fill profile histograms for each layer (ECAL,HCAL) so that we can identify when a layer is being noisy
126  Towereta = eTower->eta(); Towerphi = eTower->phi();
127  std::vector<uint16_t> Toweret_count=eTower->et_count();
128  for(size_t i=0;i<Toweret_count.size();i++) {
129  TowerRefCount = Toweret_count[i];
130  if (TowerRefCount==1025) missingLAr=true; // 1025 comes from eFexTowerBuilder if it had no supercells
131  if(TowerRefCount==1025 || TowerRefCount==1022) TowerRefCount=0; // unavailable or invalid code
132  fill((i<10) ? "ecal" : "hcal",lbn,Towereta,TowerRefCount);
133  }
134  }
135  }
136  if(missingLAr) {
137  Decision = "MissingSCells";
138  fill("errors", Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
139  }
140 
141 
142 
143 
144 
145 
146 
147  std::set<std::pair<std::pair<int,int>,int>> doneCounts; // only fill each count once (there are duplicates in DataTowers readout b.c. of module overlap)
148 
149  for(const xAOD::eFexTower* eTower : *eFexTowerContainer) {
150  TowerId = eTower->id();
151  Towereta=eTower->eta();
152  Towerphi=eTower->phi();
153  if(eTower->em_status()) {
154  Decision="BadEMStatus";
155  fill("errors",Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
156  }
157  if(eTower->had_status()) {
158  Decision="BadHadStatus";
159  fill("errors",Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
160  }
161  std::vector<uint16_t> counts=eTower->et_count();
162  std::vector<uint16_t> refcounts;
163  auto coord = std::pair(etaIndex(eTower->eta() + 0.025), phiIndex(eTower->phi() + 0.025));
164  if(!refTowers.empty()) {
165  if(auto itr = refTowers.find(coord); itr != refTowers.end()) {
166  refcounts = itr->second->et_count();
167  }
168  }
169  for(size_t i=0;i<counts.size();i++) {
170  if (eTower->disconnectedCount(i)) continue; // skip disconnected counts
171  // only do each tower once (skip duplications across modules)
172  if (doneCounts.find(std::pair(coord,i))==doneCounts.end()) {
173  doneCounts.insert(std::pair(coord,i));
174  } else {
175  continue;
176  }
177  bool isLAr = !(i==10 && std::abs(Towereta)<=1.5);
178  TowerSlot = i;
179  TowerCount = counts[i];
180  TowerRefCount = -1;
181  Decision = "";
182  if(!refTowers.empty()) { // only do slot-by-slot comparison if we actually have ref towers
183  if(refcounts.size() != counts.size()) {
184  Decision = "NumSlotMismatch";
185  } else {
186  TowerRefCount = refcounts.at(i);
187  if(isLAr) {
188  if(TowerCount==1022) {
189  Decision = "LArInvalidCode";
190  } else if(!TowerCount && TowerRefCount) {
191  Decision="LArMissingMask";
192  } else if(TowerCount && !TowerRefCount) {
193  Decision="LArExtraMask";
194  } else if(TowerCount != TowerRefCount) {
195  Decision="LArMismatch";
196  }
197  // should we also monitor saturations (code 1023?)
198  } else if(TowerCount != TowerRefCount) {
199  Decision="TileMismatch";
200  }
201  }
202  if(!std::string(Decision).empty()) {
203  if(isLAr) {
204  if (auto itr = m_scMap.find(std::make_pair(coord, i)); itr != m_scMap.end()) {
205  SlotSCID = itr->second.second;
206  }
207  }
208  fill("errors",Decision,timeSince,timeUntil,evtNumber,lbnString,TowerId,Towereta,Towerphi,Toweremstatus,Towerhadstatus,TowerSlot,TowerCount,TowerRefCount,SlotSCID);
209  }
210  }
211  fill((i<10) ? "ecal" : "hcal",lbn,Towereta,TowerCount);
212  }
213  }
214 
215 
216  return StatusCode::SUCCESS;
217 }
218 
219 
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
EfexInputMonitorAlgorithm::m_eFexTowerContainerKey
SG::ReadHandleKey< xAOD::eFexTowerContainer > m_eFexTowerContainerKey
Definition: EfexInputMonitorAlgorithm.h:29
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
xAOD::eFexTower_v1
Class describing input data of a LVL1 eFEX.
Definition: eFexTower_v1.h:22
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
EfexInputMonitorAlgorithm::m_packageName
StringProperty m_packageName
Definition: EfexInputMonitorAlgorithm.h:26
EfexInputMonitorAlgorithm::m_scMap
std::map< std::pair< std::pair< int, int >, int >, std::pair< std::set< unsigned long long >, std::string > > m_scMap
Definition: EfexInputMonitorAlgorithm.h:32
M_PI
#define M_PI
Definition: ActiveFraction.h:11
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
EfexInputMonitorAlgorithm::fillHistograms
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
Definition: EfexInputMonitorAlgorithm.cxx:66
AthMonitorAlgorithm
Base class for Athena Monitoring Algorithms.
Definition: AthMonitorAlgorithm.h:36
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::eFexTowerContainer
eFexTowerContainer_v1 eFexTowerContainer
Define the latest version of the TriggerTower container.
Definition: eFexTowerContainer.h:14
lumiFormat.i
int i
Definition: lumiFormat.py:92
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::eventNumber
eventNumber
Definition: EventInfo_v1.cxx:124
AthMonitorAlgorithm::fill
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &&variables) const
Fills a vector of variables to a group by reference.
AthMonitorAlgorithm::GetEventInfo
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
Definition: AthMonitorAlgorithm.cxx:107
min
#define min(a, b)
Definition: cfImp.cxx:40
PathResolver.h
EfexInputMonitorAlgorithm::m_eFexTowerContainerRefKey
SG::ReadHandleKey< xAOD::eFexTowerContainer > m_eFexTowerContainerRefKey
Definition: EfexInputMonitorAlgorithm.h:30
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
TrigCompositeUtils::Decision
xAOD::TrigComposite Decision
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:20
EfexInputMonitorAlgorithm::m_bcContKey
SG::ReadCondHandleKey< LArBadChannelCont > m_bcContKey
Definition: EfexInputMonitorAlgorithm.h:39
EfexInputMonitorAlgorithm.h
JetVoronoiDiagramHelpers::coord
double coord
Definition: JetVoronoiDiagramHelpers.h:45
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
AthMonitorAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: AthMonitorAlgorithm.cxx:18
eflowRec::phiIndex
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi
Definition: EtaPhiLUT.cxx:23
EfexInputMonitorAlgorithm::EfexInputMonitorAlgorithm
EfexInputMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Definition: EfexInputMonitorAlgorithm.cxx:10
EfexInputMonitorAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: EfexInputMonitorAlgorithm.cxx:15
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
xAOD::lumiBlock
setTeId lumiBlock
Definition: L2StandAloneMuon_v1.cxx:327
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
LB_AnalMapSplitter.lbn
lbn
Definition: LB_AnalMapSplitter.py:28
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37