ATLAS Offline Software
Loading...
Searching...
No Matches
LArCalibDigitsAccumulator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "CLHEP/Units/SystemOfUnits.h"
10#include <cmath>
11#include <cstdint>
12
13using CLHEP::ns;
14
15LArCalibDigitsAccumulator::LArCalibDigitsAccumulator (const std::string& name, ISvcLocator* pSvcLocator):
16 AthAlgorithm(name, pSvcLocator),
17 m_sc2ccMappingTool("CaloSuperCellIDTool"),
18 m_onlineHelper(nullptr),
20{
21 declareProperty("LArAccuCalibDigitContainerName",m_calibAccuDigitContainerName, "LArAccumulatedCalibDigits");
22 declareProperty("KeyList",m_keylist);
23 declareProperty("StepOfTriggers",m_nStepTrigger=1);
24 declareProperty("DelayScale",m_delayScale=1*ns);
25 declareProperty("KeepOnlyPulsed",m_keepPulsed=false);
26 declareProperty("KeepFullyPulsedSC",m_keepFullyPulsedSC=false);
27 declareProperty("DropPercentTrig",m_DropPercentTrig=10);
28 declareProperty("isSC",m_isSC=false);
29 declareProperty("SampleShift",m_sampleShift=0);
30 m_delay=-1;
32}
33
34
36
37 m_eventNb=0;
38 // retrieve online ID helper
39 StatusCode sc;
40 ATH_CHECK( m_cablingKey.initialize() );
41 ATH_CHECK( m_calibMapKey.initialize() );
42
43 if(m_isSC){
44 const LArOnline_SuperCellID *scid;
45 sc = detStore()->retrieve(scid, "LArOnline_SuperCellID");
46 if (sc.isFailure()) {
47 ATH_MSG_ERROR( "Could not get LArOnline_SuperCellID helper !" );
48 return sc;
49 } else {
50 m_onlineHelper = static_cast<const LArOnlineID_Base*>(scid);
51 ATH_MSG_DEBUG("Found the LArOnlineID helper");
52 }
53 ATH_CHECK( m_sc2ccMappingTool.retrieve() );
54 ATH_CHECK( m_cablingKeySC.initialize() );
55 ATH_CHECK( m_calibMapSCKey.initialize() );
56 } else {
57 const LArOnlineID* ll;
58 sc = detStore()->retrieve(ll, "LArOnlineID");
59 if (sc.isFailure()) {
60 ATH_MSG_ERROR( "Could not get LArOnlineID helper !" );
61 return sc;
62 } else {
63 m_onlineHelper = static_cast<const LArOnlineID_Base*>(ll);
64 ATH_MSG_DEBUG(" Found the LArOnlineID helper. ");
65 }
66 } //m_isSC
67
68 return StatusCode::SUCCESS;
69}
70
71
72
74{
75
76 StatusCode sc;
77
78 if ( m_event_counter < 100 || m_event_counter%100==0 )
79 ATH_MSG_INFO( "Processing event " << m_event_counter );
81
82 const LArCalibLineMapping *clcabling = nullptr;
84 clcabling =*clHdl;
85 if(!clcabling) {
86 ATH_MSG_WARNING( "Do not have calib line mapping from key " << m_calibMapKey.key() );
87 return StatusCode::FAILURE;
88 }
89
90 const LArCalibLineMapping *clcablingSC = nullptr;
91 if(m_isSC) {
93 clcablingSC =*clHdl;
94 if(!clcablingSC) {
95 ATH_MSG_WARNING( "Do not have calib line mapping from key " << m_calibMapSCKey.key() );
96 return StatusCode::FAILURE;
97 }
98 }
99
100 // new here ====
101 const LArOnOffIdMapping* cabling(nullptr);
102 const LArOnOffIdMapping* cablingLeg(nullptr);
103 if( m_isSC ){
105 cabling = {*cablingHdl};
106 if(!cabling) {
107 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKeySC.key());
108 return StatusCode::FAILURE;
109 }
110
112 cablingLeg = {*cablingHdlLeg};
113 if(!cablingLeg) {
114 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
115 return StatusCode::FAILURE;
116 }
117 }
118
119 // =============
120
121
122
123 // pointer to input container
124 const LArCalibDigitContainer* calibDigitContainer=nullptr;
125
126 // Event info
127 const xAOD::EventInfo* thisEventInfo = nullptr;
128 ATH_CHECK( evtStore()->retrieve(thisEventInfo) );
129 unsigned eventNb = thisEventInfo->eventNumber();
130 // retrieve calibration settings
131 const LArCalibParams* calibParams;
132 sc=detStore()->retrieve(calibParams,"LArCalibParams");
133 if (sc.isFailure())
134 {ATH_MSG_ERROR( "Cannot load LArCalibParams from DetStore." );
135 return StatusCode::FAILURE;
136 }
137
138 unsigned int sizeSteps = (m_nStepTrigger>1 ? (m_nStepTrigger+1):1);
139
140 // retrieve input calibDigits
141
142 //Loop over all containers that are to be processed (e.g. different gains)
143 for (const std::string& key : m_keylist) {
144
145 sc=evtStore()->retrieve(calibDigitContainer,key);
146 if(sc.isFailure()) {
147 ATH_MSG_ERROR( "Can't retrieve LArCalibDigitContainer with key " << key << "from StoreGate." );
148 return StatusCode::SUCCESS;
149 }else{
150 ATH_MSG_DEBUG( "Retrieved LArCalibDigitContainer with key " << key << " from StoreGate." );
151 }
152
153 if(calibDigitContainer->empty()) {
154 ATH_MSG_DEBUG( "LArCalibDigitContainer with key=" << key << " is empty " );
155 }else{
156 ATH_MSG_DEBUG( "LArCalibDigitContainer with key=" << key << " has size = " << calibDigitContainer->size() );
157 }
158
159 // counter of triggers
160 std::vector<unsigned int> ntrigger, nTriggerPerStep, nStepTrigger, iStepTrigger;
161 // effective number of triggers: per channel
162 ntrigger.resize(calibDigitContainer->size(),0);
163 // asked number of triggers (from calib settings): per FEB
164 nTriggerPerStep.resize(m_onlineHelper->febHashMax(),0);
165 nStepTrigger.resize(m_onlineHelper->febHashMax(),0);
166 iStepTrigger.resize(m_onlineHelper->febHashMax(),0);
167
168 // output container
170 //Loop over all cells
171 for (const LArCalibDigit* digit : *calibDigitContainer) {
172 if(m_keepPulsed && !digit->isPulsed()) continue;
173
174 // identificators
175 HWIdentifier chid=digit->hardwareID();
176 const HWIdentifier febid=m_onlineHelper->feb_Id(chid);
177 const IdentifierHash febhash = m_onlineHelper->feb_Hash(febid);
178 const IdentifierHash hashid = m_onlineHelper->channel_Hash(chid);
179
180
181
183
184 std::vector<Identifier> ccellIds(0);
185 unsigned numPulsedLeg = 0;
186 unsigned numCL = 0;
187 if( m_isSC ){
188
190 bool hasInvalid=false;
191 for(auto s : digit->samples()){
192 if(s<0){
193 hasInvalid=true;
194 break;
195 }
196 }
197 if(hasInvalid) continue;
198
199 Identifier myofflineID = cabling->cnvToIdentifier(digit->hardwareID()) ;
200 ccellIds = m_sc2ccMappingTool->superCellToOfflineID( myofflineID );
201 for (Identifier id : ccellIds) {// loop cells in sc
202 HWIdentifier cellLegHWID = cablingLeg->createSignalChannelID(id);
203 const std::vector<HWIdentifier>& calibLineLeg = clcabling->calibSlotLine(cellLegHWID);
204 numCL += calibLineLeg.size();
205 for (HWIdentifier calibLineHWID : calibLineLeg) {// loop legacy calib lines
206 if ( calibParams->isPulsed(eventNb,calibLineHWID) ){
207 numPulsedLeg += 1;
208 ATH_MSG_DEBUG("SC "<< chid << " constituent cell "<< cellLegHWID << " calib line "<< calibLineHWID<< " not pulsed");
209 }else{
210 if ( digit->isPulsed() ) ATH_MSG_WARNING("SC "<< chid << " constituent cell "<< cellLegHWID << " calib line "<< calibLineHWID<< " not pulsed");}
211 }//end calib line Leg loop
212 }//end legacy cell loop
213 if ( digit->isPulsed() && numPulsedLeg != numCL ){ //(int)(ccellIds.size()) ){
214 ATH_MSG_WARNING("Number of pulsed legacy cells does not equal number of calibration lines "<<chid<<"!! LArParams counter = " << numPulsedLeg << ", SC2CCMappingTool = " << ccellIds.size() << ", num CLs = "<< numCL);
215
216 if(m_keepFullyPulsedSC){ // && numPulsedLeg < (int)(ccellIds.size())){
217 ATH_MSG_WARNING("Discarding this SC ("<<chid<<") as it is not fully pulsed");
218 continue;
219 }
220 }
221 ATH_MSG_DEBUG("SC "<<chid<<" pulsed cells "<< numPulsedLeg <<" or "<< ccellIds.size()<<", "<<numCL<<" calibration lines");
222 } // end m_isSC
223
225
226 // BELOW: DIRTY HACK BECAUSE THERE SEEMS TO BE A BUG IN THE CABLINGSVC CONCERNING THE CALIBLINES.
227 // get calibration settings
228 const std::vector<HWIdentifier>& calibLineID = m_isSC ? clcablingSC->calibSlotLine(chid) : clcabling->calibSlotLine(chid);
229 HWIdentifier calibModuleID;
230 if(!calibLineID.empty()){
231 calibModuleID=m_onlineHelper->calib_module_Id(calibLineID[0]);
232 nTriggerPerStep[febhash] = calibParams->NTrigger(calibModuleID);
233 ATH_MSG_DEBUG( "Ntrigger per step = " << nTriggerPerStep[febhash] );
234 if(nTriggerPerStep[febhash] > 1000) nTriggerPerStep[febhash]=100; // very dirty !!!
235 }else{
236
237 nTriggerPerStep[febhash] = 100; // very dirty !!
238 }
239
240 // cell is pulsed ?
241 bool isPulsed = digit->isPulsed();
242
243 //First cell to be processed, set delay
244 if (m_delay==-1) {
245 m_delay=digit->delay();
246 }
247 else{
248 // next cells: should be the same delay
249 if (m_delay!=digit->delay()) {
250 ATH_MSG_DEBUG( "Delay is changing to " << digit->delay() << " from " << m_delay << ": book a new LArAccumulatedCalibDigitContainer" );
251 m_delay=digit->delay();
252 }
253 }
254
255 std::string patternName = getPatternName(key, isPulsed, m_delay, digit->DAC());
256
257 std::map<std::string, std::vector<LArAccumulated> >::iterator accIter=m_Accumulated_map.find(patternName);
258 if(accIter==m_Accumulated_map.end()){
259 accIter=m_Accumulated_map.insert(std::make_pair(patternName,std::vector<LArAccumulated>(m_onlineHelper->channelHashMax()))).first;
260 }
261
262 CaloGain::CaloGain gain=digit->gain();
263 if (gain<0 || gain>CaloGain::LARNGAIN)
264 {ATH_MSG_ERROR( "Found not-matching gain number ("<< (int)gain <<")" );
265 delete larAccuCalibDigitContainer;
266 return StatusCode::FAILURE;
267 }
268
269 // object to be filled for each cell
270 LArAccumulated& cellAccumulated = accIter->second[hashid];
271 cellAccumulated.m_onlineId=chid.get_identifier32().get_compact();
272
273 // trigger counter for each cell
274 cellAccumulated.m_ntrigger++;
275 ATH_MSG_DEBUG( "chid = " << chid << ", trigger = " << cellAccumulated.m_ntrigger << ", DAC = " << digit->DAC()<<", Delay = "<<digit->delay()<<", isPulsed? "<<digit->isPulsed() );
276
277 // at first trigger, initialize vectors
278 unsigned int sizeSamples = digit->samples().size();
279 ATH_MSG_DEBUG( "sizeSteps = " << sizeSteps << ", # of samples = " << sizeSamples );
280
281 if(cellAccumulated.m_ntrigger==1){
282 cellAccumulated.m_sum.clear();
283 cellAccumulated.m_sum2.clear();
284 cellAccumulated.m_sum.resize(sizeSamples,0);
285 cellAccumulated.m_sum2.resize(sizeSamples,0);
286 }
287
289 for(unsigned int j=0;j<sizeSamples;j++){
290 int digis;
291 if(j-m_sampleShift >= sizeSamples){
292 digis=digit->samples()[sizeSamples-1];
293 cellAccumulated.m_sum[j] += digis;
294 cellAccumulated.m_sum2[j] += digis*digis;
295 }
296 else if((int)j-m_sampleShift<0){
297 digis=digit->samples()[0];
298 cellAccumulated.m_sum[j] += digis;
299 cellAccumulated.m_sum2[j] += digis*digis;
300 } else{
301 digis=digit->samples()[j-m_sampleShift];
302 cellAccumulated.m_sum[j] += digis;
303 cellAccumulated.m_sum2[j] += digis*digis;
304 }
305 }
306
307 // when reached total number of triggers for this step, fill LArAccumulatedCalibDigit and reset number of triggers
308 unsigned int ntrigUsed = nTriggerPerStep[febhash];
309 if ( m_isSC && m_DropPercentTrig != 0 ){
310 ntrigUsed -= ntrigUsed*(m_DropPercentTrig/100);
311 }
312
313 if(cellAccumulated.m_ntrigger==ntrigUsed){
314 ATH_MSG_DEBUG( "filling LArAccumulatedCalibDigit " );
315 ATH_MSG_DEBUG( "chid = " << chid << ", gain = " << gain << ", DAC = " << digit->DAC() << ", isPulsed = " << isPulsed << ", delay = " << m_delay << ", trigPerStep = " << nTriggerPerStep[febhash] << ", istep = " << iStepTrigger[febhash] );
316
317
318 LArAccumulatedCalibDigit* accuCalibDigit;
319 if ( m_isSC ){
320 ATH_MSG_DEBUG("Channel "<<chid<<" DAC "<< digit->DAC()<< " will multiply by "<<numPulsedLeg<< " = "<<digit->DAC()*numPulsedLeg<<" is pulsed??? "<<isPulsed);
321 accuCalibDigit = new LArAccumulatedCalibDigit(chid,gain,sizeSamples,(int32_t)(digit->DAC()*numPulsedLeg),(uint16_t)m_delay,isPulsed,0,0);
322 }else{
323 accuCalibDigit = new LArAccumulatedCalibDigit(chid,gain,sizeSamples,(uint16_t)digit->DAC(),(uint16_t)m_delay,isPulsed,0,0);
324 }
325
326
327 accuCalibDigit->setAddSubStep(cellAccumulated.m_sum,cellAccumulated.m_sum2,ntrigUsed);
328 iStepTrigger[febhash]++;
329
330 std::vector<float> mean = accuCalibDigit->mean();
331 std::vector<float> RMS = accuCalibDigit->RMS();
332
333 for(unsigned int i=0;i<mean.size();i++){
334 ATH_MSG_DEBUG( "mean["<<i<<"] = " << mean[i] );
335 ATH_MSG_DEBUG( "RMS["<<i<<"] = " << RMS[i] );
336 }
337
338 larAccuCalibDigitContainer->push_back(accuCalibDigit);
339
340 cellAccumulated.m_nused = cellAccumulated.m_ntrigger;
341 cellAccumulated.m_ntrigger = 0;
342 }
343
344 }// loop over cells in container
345
346
347 larAccuCalibDigitContainer->setDelayScale(m_delayScale);
348 sc = evtStore()->record(larAccuCalibDigitContainer,key);
349 if (sc!=StatusCode::SUCCESS)
350 {ATH_MSG_WARNING( "Unable to record LArAccumulatedCalibDigitContainer with key " << key << " from DetectorStore. " );
351 }
352 else
353 ATH_MSG_DEBUG( "Recorded succesfully LArAccumulatedCalibDigitContainer with key " << key << " with size " << larAccuCalibDigitContainer->size());
354
355 sc = evtStore()->setConst(larAccuCalibDigitContainer);
356 if (sc.isFailure()) {
357 ATH_MSG_ERROR( " Cannot lock LArAccumulatedCalibDigitContainer " );
358 return(StatusCode::FAILURE);
359 }
360
361
362 } // loop over key container
363 return StatusCode::SUCCESS;
364}
365
366std::string LArCalibDigitsAccumulator::getPatternName(const std::string& gain, bool isPulsed, int delay, int dac){
367 std::ostringstream ss;
368 ss<<gain<<"_"<<isPulsed<<"_"<<delay<<"_"<<dac;
369 return ss.str();
370}
371
372
374
375 if ( !m_isSC ) return StatusCode::SUCCESS;
376 int ntrigUsed = 100 - 100*(m_DropPercentTrig/100);
377 for(auto &acc : m_Accumulated_map){
378 std::string pattern=acc.first;
379 for(auto &sc : acc.second){
380 if(sc.m_onlineId && sc.m_nused != ntrigUsed){
381 ATH_MSG_WARNING("Not enough triggers for pattern " << pattern << " channel OnlineID " << sc.m_onlineId << " ntriggers " << sc.m_ntrigger );
382 }
383 }
384 }
385
386 return StatusCode::SUCCESS;
387
388}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double delay(std::size_t d)
static Double_t ss
static Double_t sc
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
Container class for LArAccumulatedCalibDigit.
void setDelayScale(const double scale)
set the delay Scale
Data class for calibration ADC samples preprocessed by the DSP.
bool setAddSubStep(const std::vector< uint64_t > &sampleSum, const std::vector< uint64_t > &sample2Sum, const uint32_t nTriggerPerStep)
Sum up with another substep.
std::vector< float > RMS() const
Calculates and returns the RMS value of each ADC sample.
std::vector< float > mean() const
Calculates and returns the Mean value of each ADC sample.
Container class for LArCalibDigit.
Base class for LArDigits taken during calibration runs.
const LArOnlineID_Base * m_onlineHelper
bool m_isSC
Tells you whether you run on SuperCells or Cells.
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKeySC
unsigned int m_nStepTrigger
Number of intermediate accumulations (JO property)
double m_delayScale
Set delay scale.
std::string m_calibAccuDigitContainerName
LArAccumulatedCalibDigitContainer name.
bool m_keepFullyPulsedSC
Tells you whether you keep only fully pulsed supercells or all supercells.
bool m_keepPulsed
Tells you whether you keep only pulsed cells or all cells.
double m_DropPercentTrig
Percentage of the used triggers that we will skip over at the end, in order ot ensure that the accumu...
static std::string getPatternName(const std::string &gain, bool isPulsed, int delay, int dac)
SG::ReadCondHandleKey< LArCalibLineMapping > m_calibMapSCKey
LArCalibDigitsAccumulator(const std::string &name, ISvcLocator *pSvcLocator)
int m_sampleShift
Samples to shift by, usually used in the case of SCs.
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
ToolHandle< ICaloSuperCellIDTool > m_sc2ccMappingTool
std::map< std::string, std::vector< LArAccumulated > > m_Accumulated_map
Vector (index=hash ID) of accumulation quantities.
unsigned int m_event_counter
Event counter.
SG::ReadCondHandleKey< LArCalibLineMapping > m_calibMapKey
std::vector< std::string > m_keylist
list of key for input digit container (=gain)
const std::vector< HWIdentifier > & calibSlotLine(const HWIdentifier id) const
bool isPulsed(const unsigned event, const HWIdentifier calibLineID) const
unsigned NTrigger(const HWIdentifier calibModuleID) const
HWIdentifier createSignalChannelID(const Identifier &id) const
create a HWIdentifier from an Identifier (not inline)
Helper for the Liquid Argon Calorimeter cell identifiers.
uint64_t eventNumber() const
The current event's event number.
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
@ LARNGAIN
Definition CaloGain.h:19
EventInfo_v1 EventInfo
Definition of the latest event info version.