ATLAS Offline Software
Loading...
Searching...
No Matches
LArLATOMEBuilderAlg.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 "GaudiKernel/SystemOfUnits.h"
19#include <cmath>
20
21
22namespace {
23 inline int pow2(const int x) {return (0x1<<x);}
24};
25
26LArLATOMEBuilderAlg::LArLATOMEBuilderAlg(const std::string& name, ISvcLocator* pSvcLocator):
27 AthReentrantAlgorithm(name, pSvcLocator) {}
28
30
31 ATH_MSG_INFO("LArLATOMEBuilderAlg init");
32
33 ATH_CHECK(m_eventInfoKey.initialize());
34 ATH_CHECK(m_digitKey.initialize());
35 ATH_CHECK(m_larRawSCKey.initialize());
36 ATH_CHECK(m_cablingKey.initialize());
37 ATH_CHECK(m_keyPedestalSC.initialize());
38 ATH_CHECK(m_keyOFCSC.initialize());
39 ATH_CHECK(m_keyRampSC.initialize());
40 ATH_CHECK(m_keyDAC2uASC.initialize());
41 ATH_CHECK(m_keyuA2MeVSC.initialize());
42 ATH_CHECK(m_keyHVScaleCorrSC.initialize());
43 ATH_CHECK(m_keyMphysOverMcalSC.initialize());
44
45 const LArOnline_SuperCellID* ll;
46 ATH_CHECK(detStore()->retrieve(ll,"LArOnline_SuperCellID"));
47 m_onlineId = static_cast<const LArOnlineID_Base*>(ll);
48
49 return StatusCode::SUCCESS;
50}
51
53 return StatusCode::SUCCESS;
54}
55
56StatusCode LArLATOMEBuilderAlg::execute(const EventContext& ctx) const {
57
59 unsigned int event_bcid = thisEvent->bcid();
60
61 //Get event inputs from read handles:
63 //Write output via write handle
65 ATH_CHECK(outputContainerHdl.record(std::make_unique<LArRawSCContainer>()));
66 auto *outputContainer = outputContainerHdl.ptr();
67 outputContainer->clear(SG::VIEW_ELEMENTS);
68 outputContainer->reserve(inputContainer->size());
69 DataPool<LArRawSC> dataItemsPool(ctx);
70 dataItemsPool.reserve(inputContainer->size());
71
72 //Get Conditions input
74 const LArPedestalSC* Peds=dynamic_cast<const LArPedestalSC*>(pedHdl.cptr());
75 if (!Peds) return StatusCode::FAILURE;
76
78 const LArOFCSC* OFCs=dynamic_cast<const LArOFCSC*>(ofcHdl.cptr());
79 if (!OFCs) return StatusCode::FAILURE;
80
82 const LArRampSC* Ramps=dynamic_cast<const LArRampSC*>(rampHdl.cptr());
83 if (!Ramps) return StatusCode::FAILURE;
84
86 const LArDAC2uASC* DAC2uAs=dynamic_cast<const LArDAC2uASC*>(dac2uaHdl.cptr());
87 if (!DAC2uAs) return StatusCode::FAILURE;
88
90 const LAruA2MeVSC* uA2MeVs=dynamic_cast<const LAruA2MeVSC*>(ua2mevHdl.cptr());
91 if (!uA2MeVs) return StatusCode::FAILURE;
92
94 const LArMphysOverMcalSC* MphysOverMcals=dynamic_cast<const LArMphysOverMcalSC*>(mphysHdl.cptr());
95 if (!MphysOverMcals) return StatusCode::FAILURE;
96
98 const LArHVScaleCorrSC* HVScaleCorrs=dynamic_cast<const LArHVScaleCorrSC*>(hvHdl.cptr());
99 if (!HVScaleCorrs) return StatusCode::FAILURE;
100
102
103 unsigned int nEnergies=m_nEnergies;
104
105 //Loop over digits:
106 for (const LArDigit* digit : *inputContainer) {
107
108 const LArSCDigit* digitSC=dynamic_cast<const LArSCDigit*>(digit);
109 if(!digitSC){
110 ATH_MSG_ERROR("container elements not of type LArSCDigit");
111 return StatusCode::FAILURE;
112 }
113 const std::vector<uint16_t>& bcids = digitSC->BCId();
114 const HWIdentifier id=digit->hardwareID();
115 std::flush(std::cout);
116 const std::vector<short>& samples=digit->samples();
117 int gain=digit->gain();
118 float ped=Peds->pedestal(id,gain);
119 LArOFCSC::OFCRef_t ofca=OFCs->OFC_a(id,gain);
120 LArOFCSC::OFCRef_t ofcb=OFCs->OFC_b(id,gain);
121 ILArRamp::RampRef_t ramp=Ramps->ADC2DAC(id,gain);
122 float dac2ua=DAC2uAs->DAC2UA(id);
123 float ua2mev=uA2MeVs->UA2MEV(id);
124 float mphys=MphysOverMcals->MphysOverMcal(id,gain);
125 float hvcorr=HVScaleCorrs->HVScaleCorr(id);
126 float ELSB = 12.5;
127
129 ATH_MSG_ERROR("No valid pedestal for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
130 return StatusCode::FAILURE;
131 }
132 if(ATH_UNLIKELY(!ofca.valid())){
133 ATH_MSG_ERROR("No valid ofca for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
134 return StatusCode::FAILURE;
135 }
136 if(ATH_UNLIKELY(!ofcb.valid())){
137 ATH_MSG_ERROR("No valid ofcb for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
138 return StatusCode::FAILURE;
139 }
140 if(ATH_UNLIKELY(!ramp.valid())){
141 ATH_MSG_ERROR("No valid ramp for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
142 return StatusCode::FAILURE;
143 }
144 if(ATH_UNLIKELY(ramp.size()!=2)){
145 ATH_MSG_ERROR("wrong ramp size for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
146 return StatusCode::FAILURE;
147 }
148 if (ATH_UNLIKELY(dac2ua==ILArDAC2uA::ERRORCODE)) {
149 ATH_MSG_ERROR("No valid dac2ua for connected channel " << id.get_identifier32().get_compact());
150 return StatusCode::FAILURE;
151 }
152 if (ATH_UNLIKELY(ua2mev==ILAruA2MeV::ERRORCODE)) {
153 ATH_MSG_ERROR("No valid ua2mev for connected channel " << id.get_identifier32().get_compact());
154 return StatusCode::FAILURE;
155 }
157 ATH_MSG_ERROR("No valid mphys for connected channel " << id.get_identifier32().get_compact() << " gain " << gain);
158 return StatusCode::FAILURE;
159 }
161 ATH_MSG_ERROR("No valid hvcorr for connected channel " << id.get_identifier32().get_compact());
162 return StatusCode::FAILURE;
163 }
164
166 std::vector<float> ofca_mev(ofca.size());
167 std::vector<float> ofcb_mev(ofca.size());
168 float peda=ped;
169 float pedb=ped;
170 for (unsigned int i = 0; i < ofca.size(); ++i) {
171 ofca_mev[i] = ofca[i] * ramp[1] * dac2ua * ua2mev / ELSB;
172 ofcb_mev[i] = ofcb[i] * ramp[1] * dac2ua * ua2mev / ELSB;
174 ofca_mev[i] /= mphys;
175 ofcb_mev[i] /= mphys;
176 }
178 ofca_mev[i] *= hvcorr;
179 ofcb_mev[i] *= hvcorr;
180 }
181 }
182 if (m_useR0) {
183 float suma=0; for(auto a:ofca)suma+=a;
184 float sumb=0; for(auto b:ofcb)sumb+=b;
185 peda=ped-ramp[0]/ramp[1]*suma;
186 pedb=ped-ramp[0]/ramp[1]*sumb;
187 }
188
189 bool aoverflow=false;
190 bool boverflow=false;
191 bool pedoverflow=false;
192
193 std::vector<int> ofca_int(ofca.size(),0);
194 std::vector<int> ofcb_int(ofca.size(),0);
195 int peda_int=0;
196 int pedb_int=0;
197
198 const int pedHardpoint = 3;
199 const int firLSBdropped = 8;
200 const int satLSBdropped = 6;
201 const int paramBitSize = 18;
202
203 for (unsigned int i = 0; i < ofca.size(); ++i) {
204 if (!floatToInt(ofca_mev[i], ofca_int[i], firLSBdropped - pedHardpoint,
205 paramBitSize)) {
206 aoverflow = true;
207 }
208 if (!floatToInt(ofcb_mev[i], ofcb_int[i], satLSBdropped - pedHardpoint,
209 paramBitSize)) {
210 boverflow = true;
211 }
212 }
213 if(!floatToInt(peda,peda_int,pedHardpoint,paramBitSize))pedoverflow=true;
214 if(!floatToInt(pedb,pedb_int,pedHardpoint,paramBitSize))pedoverflow=true;
215
216 unsigned int nsamples = samples.size();
217 unsigned int firsamples=4;
218 int startSample=-1;
219 for(unsigned int is=0; is<nsamples; ++is){
220 if(bcids[is]==event_bcid) startSample=is;
221 }
222 int maxNenergies = 0;
223 if(startSample<0){
224 ATH_MSG_WARNING("could not find correct BCID for recomputing the energies, event BCID="<<event_bcid<< " first sample BCID " << (nsamples?bcids[0]:-1));
225 }
226 else{
227 maxNenergies=nsamples-firsamples-startSample+1;
228 if(m_startSample) maxNenergies -= m_startSample;
229 }
230 if(maxNenergies<0) {
231 maxNenergies=0;
232 } else {
233 startSample += m_startSample;
234 }
235 if((int)nEnergies>maxNenergies){
236 ATH_MSG_WARNING("requested nEnergies > maxNenergies " << m_nEnergies << ">" <<maxNenergies<<". setting nEnegries to maxNenergies");
237 nEnergies=maxNenergies;
238 }
239
240 std::vector<unsigned short> newBCIDs(nEnergies,0);
241 std::vector<int> newEnergies(nEnergies,0);
242 std::vector<int> tauEnergies(nEnergies,0);
243 std::vector<bool> passSelections(nEnergies,false);
244 std::vector<bool> satur(nEnergies,false);
245 const unsigned int nMaxBitsEnergy=18;
246 const unsigned int nMaxBitsEnergyTau=22;
247
248 for(unsigned int ss=0; ss<nEnergies; ++ss){
249
250 int64_t computedE=0;
251 int64_t computedEtau=0;
252 unsigned short bcid = bcids[startSample+ss];
253 newBCIDs[ss]=bcid;
254 for(unsigned int is=0; is<firsamples; ++is){
255 int sample = samples[startSample + ss + is];
256 if (!m_isADCBas)
257 sample *= std::pow(2, pedHardpoint);
258 computedE += static_cast<int64_t>(sample - peda_int) * ofca_int[is];
259 computedEtau += static_cast<int64_t>(sample - pedb_int) * ofcb_int[is];
260 }
261 computedE=computedE>>firLSBdropped;
262 computedEtau=computedEtau>>satLSBdropped;
263
264 if(std::abs(computedE)>std::pow(2,nMaxBitsEnergy-1)){
265 if (computedE >= 0)
266 computedE = std::pow(2, nMaxBitsEnergy - 1) - 1;
267 else
268 computedE = 0;
269 }
270 if (std::abs(computedEtau) > std::pow(2, nMaxBitsEnergyTau - 1)) {
271 if (computedEtau >= 0)
272 computedEtau = std::pow(2, nMaxBitsEnergyTau - 1) - 1;
273 else
274 computedEtau = -std::pow(2, nMaxBitsEnergyTau - 1) + 1;
275 }
276 newEnergies[ss] = computedE;
277 tauEnergies[ss] = computedEtau;
278 bool passSelection = false;
279 if (computedE < 0 && computedE > -80) {
280 if (computedEtau > 8 * computedE && computedEtau < -8 * computedE)
281 passSelection = true;
282 } else if (computedE < 800) {
283 if (computedEtau > -8 * computedE && computedEtau < 8 * computedE)
284 passSelection = true;
285 } else if (computedE >= 800) {
286 if (computedEtau > -8 * computedE && computedEtau < 16 * computedE)
287 passSelection = true;
288 }
289 passSelections[ss] = passSelection;
290 }
291 LArRawSC* scraw = dataItemsPool.nextElementPtr();
292
293 scraw->setHardwareId(id);
294 scraw->setChannel(digitSC->Channel());
295 scraw->setSourceId(digitSC->SourceId());
296 scraw->setBCIds(std::move(newBCIDs));
297 scraw->setSaturation(std::move(satur));
298 scraw->setEnergies(std::move(newEnergies));
299 scraw->setTauEnergies(std::move(tauEnergies));
300 scraw->setPassTauSelection(std::move(passSelections));
301 scraw->setOFCaOverflow(aoverflow);
302 scraw->setOFCbOverflow(boverflow);
303 scraw->setPedOverflow(pedoverflow);
304
305 outputContainer->push_back(scraw);
306
307 }
308
309
310 return StatusCode::SUCCESS;
311}
312
314bool LArLATOMEBuilderAlg::floatToInt(float val, int &newval, int hardpoint, int size) {
315 if( std::isnan(val) )return false;
316 //int intVal = std::round(val*(0x1<<hardpoint)); //was round(val*pow(2,hardpoint));
317 int intVal=std::round(val*pow2(hardpoint));
318 bool isNeg = (intVal<0);
319 unsigned int posVal = std::abs(intVal);
320 if( (posVal >> (size -1)) != 0 ) return false;
321 newval=posVal;
322 if(isNeg)newval=-posVal;
323 return true;
324
325}
326
#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_UNLIKELY(x)
static Double_t a
static Double_t ss
static const std::map< unsigned int, unsigned int > pow2
#define x
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
a typed memory pool that saves time spent allocation small object.
Definition DataPool.h:63
void reserve(unsigned int size)
Set the desired capacity.
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
LArVectorProxy RampRef_t
This class defines the interface for accessing Ramp @stereotype Interface.
Definition ILArRamp.h:31
virtual const float & DAC2UA(const HWIdentifier &chid) const
access to DAC2UA conversion factor index by Identifier, and gain setting
Liquid Argon digit base class.
Definition LArDigit.h:25
virtual const float & HVScaleCorr(const HWIdentifier &chid) const
SG::ReadCondHandleKey< ILArHVScaleCorr > m_keyHVScaleCorrSC
static bool floatToInt(float val, int &newval, int hardpoint, int size)
reproduce LDPB package computation in https://gitlab.cern.ch/atlas-lar-online/onlinelatomedb/-/blob/m...
SG::ReadCondHandleKey< ILArDAC2uA > m_keyDAC2uASC
SG::WriteHandleKey< LArRawSCContainer > m_larRawSCKey
SG::ReadCondHandleKey< ILArPedestal > m_keyPedestalSC
LArLATOMEBuilderAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_applyHVCorrection
SG::ReadCondHandleKey< ILArMphysOverMcal > m_keyMphysOverMcalSC
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::ReadCondHandleKey< ILAruA2MeV > m_keyuA2MeVSC
StatusCode finalize() override
StatusCode execute(const EventContext &ctx) const override
StatusCode initialize() override
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Gaudi::Property< int > m_nEnergies
SG::ReadCondHandleKey< ILArRamp > m_keyRampSC
SG::ReadCondHandleKey< ILArOFC > m_keyOFCSC
Gaudi::Property< bool > m_useR0
SG::ReadHandleKey< LArDigitContainer > m_digitKey
Gaudi::Property< bool > m_applyMphysOverMcal
Gaudi::Property< bool > m_isADCBas
const LArOnlineID_Base * m_onlineId
Gaudi::Property< int > m_startSample
virtual const float & MphysOverMcal(const HWIdentifier &chid, int gain) const
virtual OFCRef_t OFC_b(const HWIdentifier &CellID, int gain, int tbin=0) const
Definition LArOFCSC.cxx:85
virtual OFCRef_t OFC_a(const HWIdentifier &CellID, int gain, int tbin=0) const
access to OFCs by online ID, gain, and tbin (!=0 for testbeam)
Definition LArOFCSC.cxx:80
ILArOFC::OFCRef_t OFCRef_t
Definition LArOFCSC.h:24
Helper for the Liquid Argon Calorimeter cell identifiers.
virtual float pedestal(const HWIdentifier &CellID, int gain) const
virtual RampRef_t ADC2DAC(const HWIdentifier &CellID, int gain) const
Definition LArRampSC.cxx:26
Liquid Argon SuperCell raw data.
Definition LArRawSC.h:19
void setBCIds(const std::vector< unsigned short > &&bcids)
Set bcids.
Definition LArRawSC.cxx:13
void setSaturation(const std::vector< bool > &&satur)
@set saturation flags
Definition LArRawSC.cxx:40
void setEnergies(const std::vector< int > &&energies)
Set energies .
Definition LArRawSC.cxx:8
void setHardwareId(const HWIdentifier id)
Set identifier.
Definition LArRawSC.cxx:28
void setTauEnergies(const std::vector< int > &&tauEnergies)
Set energies*taus .
Definition LArRawSC.cxx:18
void setPassTauSelection(const std::vector< bool > &&pass)
@set true if passes the tau selection
Definition LArRawSC.cxx:23
void setOFCbOverflow(bool overflow)
@set OFCb Overflow
Definition LArRawSC.h:161
void setOFCaOverflow(bool overflow)
@set OFCa Overflow
Definition LArRawSC.h:158
void setSourceId(const unsigned sourceId)
Set source id.
Definition LArRawSC.cxx:36
void setChannel(const unsigned chan)
Set channel number.
Definition LArRawSC.cxx:32
void setPedOverflow(bool overflow)
@set pedestal Overflow
Definition LArRawSC.h:164
Base class for LArDigits taken by LATOME.
Definition LArSCDigit.h:19
unsigned int SourceId() const
Definition LArSCDigit.h:45
const std::vector< unsigned short > & BCId() const
Definition LArSCDigit.h:48
short Channel() const
Definition LArSCDigit.h:42
bool valid() const
Test to see if the proxy has been initialized.
virtual const float & UA2MEV(const HWIdentifier &chid) const
const_pointer_type cptr()
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts