ATLAS Offline Software
LArRawChannelBuilderAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "GaudiKernel/SystemOfUnits.h"
12 #include <cmath>
13 #include <memory>
14 
15 
26  if (m_useDBFortQ) {
28  ATH_MSG_ERROR ("useDB requested but neither Run1DSPThresholdsKey nor Run2DSPThresholdsKey initialized.");
29  return StatusCode::FAILURE;
30  }
31  }
32 
33 
34  ATH_CHECK(detStore()->retrieve(m_onlineId,"LArOnlineID"));
35 
36 
37  const std::string cutmsg = m_absECutFortQ.value() ? " fabs(E) < " : " E < ";
38  ATH_MSG_INFO("Energy cut for time and quality computation: " << cutmsg <<
39  " taken from COOL folder "<<
40  m_run1DSPThresholdsKey.key() << " (run1) " <<
41  m_run2DSPThresholdsKey.key() << " (run2) ");
42  return StatusCode::SUCCESS;
43 }
44 
46  return StatusCode::SUCCESS;
47 }
48 
49 StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
50 
51  //Get event inputs from read handles:
53 
54  //Write output via write handle
55  auto outputContainer = std::make_unique<LArRawChannelContainer>();
56 
57  //Get Conditions input
59  const ILArPedestal* peds=*pedHdl;
60 
62  const LArADC2MeV* adc2MeVs=*adc2mevHdl;
63 
65  const ILArOFC* ofcs=*ofcHdl;
66 
68  const ILArShape* shapes=*shapeHdl;
69 
71 
72  std::unique_ptr<LArDSPThresholdsFlat> run2DSPThresh;
73  const LArDSPThresholdsComplete* run1DSPThresh = nullptr;
74  if (m_useDBFortQ) {
77  run2DSPThresh = std::make_unique<LArDSPThresholdsFlat>(*dspThrshAttr);
78  if (ATH_UNLIKELY(!run2DSPThresh->good())) {
79  ATH_MSG_ERROR( "Failed to initialize LArDSPThresholdFlat from attribute list loaded from " << m_run2DSPThresholdsKey.key()
80  << ". Aborting." );
81  return StatusCode::FAILURE;
82  }
83  }
84  else if (!m_run1DSPThresholdsKey.empty()) {
86  run1DSPThresh = dspThresh.cptr();
87  }
88  else {
89  ATH_MSG_ERROR( "No DSP threshold configured.");
90  return StatusCode::FAILURE;
91  }
92  }
93 
94  //Loop over digits:
95  for (const LArDigit* digit : *inputContainer) {
96 
97  size_t firstSample=m_firstSample;
98 
99  const HWIdentifier id=digit->hardwareID();
100  const bool connected=(*cabling)->isOnlineConnected(id);
101 
102 
103  ATH_MSG_VERBOSE("Working on channel " << m_onlineId->channel_name(id));
104 
105  const std::vector<short>& samples=digit->samples();
106  const int gain=digit->gain();
107  const float p=peds->pedestal(id,gain);
108 
109 
110 
111  //The following autos will resolve either into vectors or vector-proxies
112  const auto& ofca=ofcs->OFC_a(id,gain);
113  const auto& adc2mev=adc2MeVs->ADC2MEV(id,gain);
114 
115  const size_t nOFC=ofca.size();
116 
117  //Sanity check on input conditions data:
118  // ensure that the size of the samples vector is compatible with ofc_a size when preceeding samples are saved
119  const size_t nSamples=samples.size()-firstSample;
120  if (nSamples<nOFC) {
121  ATH_MSG_ERROR("effective sample size: "<< nSamples << ", must be >= OFC_a size: " << ofca.size());
122  return StatusCode::FAILURE;
123  }
124 
125 
127  if (!connected) continue; //No conditions for disconencted channel, who cares?
128  ATH_MSG_ERROR("No valid pedestal for connected channel " << m_onlineId->channel_name(id)
129  << " gain " << gain);
130  return StatusCode::FAILURE;
131  }
132 
133  if(ATH_UNLIKELY(adc2mev.size()<2)) {
134  if (!connected) continue; //No conditions for disconencted channel, who cares?
135  ATH_MSG_ERROR("No valid ADC2MeV for connected channel " << m_onlineId->channel_name(id)
136  << " gain " << gain);
137  return StatusCode::FAILURE;
138  }
139 
140 
141  //Apply OFCs to get amplitude
142  // Evaluate sums in double-precision to get consistent results
143  // across platforms.
144  double A=0;
145  bool saturated=false;
146 
147  // Check saturation AND discount pedestal
148  std::vector<float> samp_no_ped(nOFC,0.0);
149  for (size_t i=0;i<nOFC;++i) {
150  if (samples[i+firstSample]==4096 || samples[i+firstSample]==0) saturated=true;
151  samp_no_ped[i]=samples[i+firstSample]-p;
152  }
153  for (size_t i=0;i<nOFC;++i) {
154  A+=static_cast<double>(samp_no_ped[i])*ofca[i];
155  }
156 
157  //Apply Ramp
158  const float E=adc2mev[0]+A*adc2mev[1];
159 
160  uint16_t iquaShort=0;
161  float tau=0;
162 
163 
164  uint16_t prov=LArProv::DEFAULTRECO; //Means all constants from DB + OFC
165  if (saturated) prov|=LArProv::SATURATED;
166 
167  const float E1=m_absECutFortQ.value() ? std::fabs(E) : E;
168  float ecut(0.);
169  if (m_useDBFortQ) {
170  if (run2DSPThresh) {
171  ecut = run2DSPThresh->tQThr(id);
172  }
173  else if (run1DSPThresh) {
174  ecut = run1DSPThresh->tQThr(id);
175  }
176  else {
177  ATH_MSG_ERROR ("DSP threshold problem");
178  return StatusCode::FAILURE;
179  }
180  }
181  else {
182  ecut = m_eCutFortQ;
183  }
184  if (E1 > ecut) {
185  ATH_MSG_VERBOSE("Channel " << m_onlineId->channel_name(id) << " gain " << gain << " above threshold for tQ computation");
186  prov|=LArProv::QTPRESENT; // fill bit in provenance that time+quality information are available
187 
188  //Get time by applying OFC-b coefficients:
189  const auto& ofcb=ofcs->OFC_b(id,gain);
190  double At=0;
191  for (size_t i=0;i<nOFC;++i) {
192  At+=static_cast<double>(samp_no_ped[i])*ofcb[i];
193  }
194  //Divide A*t/A to get time
195  tau=(std::fabs(A)>0.1) ? At/A : 0.0;
196  const auto& fullShape=shapes->Shape(id,gain);
197 
198  //Get Q-factor
199  //fixing HEC to move +1 in case of 4 samples and firstSample 0 (copied from old LArRawChannelBuilder)
200  const size_t nSamples=samples.size();
201  if (fullShape.size()>nSamples && nSamples==4 && m_firstSample==0) {
202  if (m_onlineId->isHECchannel(id)) {
203  firstSample=1;
204  }
205  }
206 
207  if (ATH_UNLIKELY(fullShape.size()<nOFC+firstSample)) {
208  if (!connected) continue; //No conditions for disconnected channel, who cares?
209  ATH_MSG_ERROR("No valid shape for channel " << m_onlineId->channel_name(id)
210  << " gain " << gain);
211  ATH_MSG_ERROR("Got size " << fullShape.size() << ", expected at least " << nSamples+firstSample);
212  return StatusCode::FAILURE;
213  }
214 
215  const float* shape=&*fullShape.begin()+firstSample;
216 
217  double q=0;
218  if (m_useShapeDer) {
219  const auto& fullshapeDer=shapes->ShapeDer(id,gain);
220  if (ATH_UNLIKELY(fullshapeDer.size()<nOFC+firstSample)) {
221  ATH_MSG_ERROR("No valid shape derivative for channel " << m_onlineId->channel_name(id)
222  << " gain " << gain);
223  ATH_MSG_ERROR("Got size " << fullshapeDer.size() << ", expected at least " << nOFC+firstSample);
224  return StatusCode::FAILURE;
225  }
226 
227  const float* shapeDer=&*fullshapeDer.begin()+firstSample;
228  for (size_t i=0;i<nOFC;++i) {
229  q += std::pow((A*(shape[i]-tau*shapeDer[i])-(samp_no_ped[i])),2);
230  }
231  }//end if useShapeDer
232  else {
233  //Q-factor w/o shape derivative
234  for (size_t i=0;i<nOFC;++i) {
235  q += std::pow((A*shape[i]-(samp_no_ped[i])),2);
236  }
237  }
238 
239  int iqua = static_cast<int>(q);
240  if (iqua > 0xFFFF) iqua=0xFFFF;
241  iquaShort = static_cast<uint16_t>(iqua & 0xFFFF);
242 
243  tau-=ofcs->timeOffset(id,gain);
244  tau*=(Gaudi::Units::nanosecond/Gaudi::Units::picosecond); //Convert time to ps
245  }//end if above cut
246 
247  outputContainer->emplace_back(id,static_cast<int>(std::floor(E+0.5)),
248  static_cast<int>(std::floor(tau+0.5)),
249  iquaShort,prov,(CaloGain::CaloGain)gain);
250  }
251 
252 
254  ATH_CHECK(outputHandle.record(std::move(outputContainer) ) );
255 
256  return StatusCode::SUCCESS;
257 }
258 
259 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ILArPedestal::pedestal
virtual float pedestal(const HWIdentifier &id, int gain) const =0
LArADC2MeV::ADC2MEV
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
Definition: LArADC2MeV.h:32
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
python.SystemOfUnits.nanosecond
int nanosecond
Definition: SystemOfUnits.py:119
LArRawChannelBuilderAlg::m_onlineId
const LArOnlineID * m_onlineId
Definition: LArRawChannelBuilderAlg.h:69
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LArRawChannelBuilderAlg.h
LArDSPThresholdsComplete
Definition: LArDSPThresholdsComplete.h:21
ILArPedestal
Definition: ILArPedestal.h:12
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
ILArOFC::OFC_b
virtual OFCRef_t OFC_b(const HWIdentifier &id, int gain, int tbin=0) const =0
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
ILArShape::ShapeDer
virtual ShapeRef_t ShapeDer(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
LArDSPThresholdsFlat::good
bool good() const
Definition: LArDSPThresholdsFlat.h:27
LArRawChannelBuilderAlg::m_cablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Definition: LArRawChannelBuilderAlg.h:53
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
LArRawChannelBuilderAlg::m_pedestalKey
SG::ReadCondHandleKey< ILArPedestal > m_pedestalKey
Definition: LArRawChannelBuilderAlg.h:48
LArRawChannelBuilderAlg::m_absECutFortQ
Gaudi::Property< bool > m_absECutFortQ
Definition: LArRawChannelBuilderAlg.h:61
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
HWIdentifier
Definition: HWIdentifier.h:13
LArRawChannelBuilderAlg::m_useShapeDer
Gaudi::Property< bool > m_useShapeDer
Definition: LArRawChannelBuilderAlg.h:62
LArRawChannelBuilderAlg::initialize
StatusCode initialize() override
Definition: LArRawChannelBuilderAlg.cxx:16
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
LArRawChannelBuilderAlg::m_eCutFortQ
Gaudi::Property< float > m_eCutFortQ
Definition: LArRawChannelBuilderAlg.h:59
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
LArRawChannelBuilderAlg::finalize
StatusCode finalize() override
Definition: LArRawChannelBuilderAlg.cxx:45
xAOD::saturated
setScaleOne setStatusOne saturated
Definition: gFexGlobalRoI_v1.cxx:51
LArRawChannelBuilderAlg::m_run1DSPThresholdsKey
SG::ReadCondHandleKey< LArDSPThresholdsComplete > m_run1DSPThresholdsKey
Definition: LArRawChannelBuilderAlg.h:54
ILArOFC::timeOffset
virtual float timeOffset(const HWIdentifier &CellID, int gain) const =0
LArRawChannelBuilderAlg::m_shapeKey
SG::ReadCondHandleKey< ILArShape > m_shapeKey
Definition: LArRawChannelBuilderAlg.h:51
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LArRawChannelBuilderAlg::m_run2DSPThresholdsKey
SG::ReadCondHandleKey< AthenaAttributeList > m_run2DSPThresholdsKey
Definition: LArRawChannelBuilderAlg.h:55
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
LArDSPThresholdsFlat::tQThr
float tQThr(const HWIdentifier &CellID) const
Definition: LArDSPThresholdsFlat.cxx:35
LArDigit
Liquid Argon digit base class.
Definition: LArDigit.h:25
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
01SubmitToGrid.samples
samples
Definition: 01SubmitToGrid.py:58
LArProv::QTPRESENT
@ QTPRESENT
Definition: LArProvenance.h:33
LArRawChannelBuilderAlg::m_useDBFortQ
Gaudi::Property< bool > m_useDBFortQ
Definition: LArRawChannelBuilderAlg.h:64
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
LArProv::DEFAULTRECO
@ DEFAULTRECO
Definition: LArProvenance.h:27
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
ILArPedestal::ERRORCODE
@ ERRORCODE
Definition: ILArPedestal.h:47
LArDSPThresholdsComplete::tQThr
float tQThr(const HWIdentifier chid) const
Definition: LArDSPThresholdsComplete.h:26
LArRawChannelBuilderAlg::m_ofcKey
SG::ReadCondHandleKey< ILArOFC > m_ofcKey
Definition: LArRawChannelBuilderAlg.h:50
LArDSPThresholdsFlat.h
ILArOFC
Definition: ILArOFC.h:14
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
LArDigitContainer.h
CaloGain::CaloGain
CaloGain
Definition: CaloGain.h:11
LArADC2MeV
Definition: LArADC2MeV.h:21
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
LArProvenance.h
LArRawChannelBuilderAlg::m_firstSample
Gaudi::Property< int > m_firstSample
Definition: LArRawChannelBuilderAlg.h:66
LArRawChannelBuilderAlg::m_digitKey
SG::ReadHandleKey< LArDigitContainer > m_digitKey
Definition: LArRawChannelBuilderAlg.h:41
ILArOFC::OFC_a
virtual OFCRef_t OFC_a(const HWIdentifier &id, int gain, int tbin=0) const =0
access to OFCs by online ID, gain, and tbin (!=0 for testbeam)
extractSporadic.q
list q
Definition: extractSporadic.py:98
LArDigits2NtupleDumper.nSamples
nSamples
Definition: LArDigits2NtupleDumper.py:70
LArRawChannelBuilderAlg::m_adc2MeVKey
SG::ReadCondHandleKey< LArADC2MeV > m_adc2MeVKey
Definition: LArRawChannelBuilderAlg.h:49
LArOnlineID::isHECchannel
bool isHECchannel(const HWIdentifier id) const override final
Definition: LArOnlineID.cxx:734
LArOnlineID_Base::channel_name
std::string channel_name(const HWIdentifier id) const
Return a string corresponding to a feedthrough name given an identifier.
Definition: LArOnlineID_Base.cxx:218
ILArShape
Definition: ILArShape.h:13
LArRawChannelBuilderAlg::m_rawChannelKey
SG::WriteHandleKey< LArRawChannelContainer > m_rawChannelKey
Definition: LArRawChannelBuilderAlg.h:44
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
LArRawChannelContainer.h
python.SystemOfUnits.picosecond
int picosecond
Definition: SystemOfUnits.py:123
LArOnlineID.h
LArProv::SATURATED
@ SATURATED
Definition: LArProvenance.h:30
ILArShape::Shape
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
SG::ReadCondHandle::cptr
const_pointer_type cptr()
Definition: ReadCondHandle.h:67
LArRawChannelBuilderAlg::execute
StatusCode execute(const EventContext &ctx) const override
Definition: LArRawChannelBuilderAlg.cxx:49