6#include "GaudiKernel/SystemOfUnits.h"
28 ATH_MSG_ERROR (
"useDB requested but neither Run1DSPThresholdsKey nor Run2DSPThresholdsKey initialized.");
29 return StatusCode::FAILURE;
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 "<<
42 return StatusCode::SUCCESS;
46 return StatusCode::SUCCESS;
55 auto outputContainer = std::make_unique<LArRawChannelContainer>();
72 std::unique_ptr<LArDSPThresholdsFlat> run2DSPThresh;
77 run2DSPThresh = std::make_unique<LArDSPThresholdsFlat>(*dspThrshAttr);
81 return StatusCode::FAILURE;
86 run1DSPThresh = dspThresh.
cptr();
90 return StatusCode::FAILURE;
95 for (
const LArDigit* digit : *inputContainer) {
100 const bool connected=(*cabling)->isOnlineConnected(
id);
105 const std::vector<short>& samples=digit->samples();
106 const int gain=digit->gain();
107 const float p=peds->
pedestal(
id,gain);
112 const auto& ofca=ofcs->
OFC_a(
id,gain);
113 const auto& adc2mev=adc2MeVs->
ADC2MEV(
id,gain);
115 const size_t nOFC=ofca.size();
119 const size_t nSamples=samples.size()-firstSample;
121 ATH_MSG_ERROR(
"effective sample size: "<< nSamples <<
", must be >= OFC_a size: " << ofca.size());
122 return StatusCode::FAILURE;
127 if (!connected)
continue;
129 <<
" gain " << gain);
130 return StatusCode::FAILURE;
134 if (!connected)
continue;
136 <<
" gain " << gain);
137 return StatusCode::FAILURE;
145 bool saturated=
false;
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;
153 for (
size_t i=0;i<nOFC;++i) {
154 A+=
static_cast<double>(samp_no_ped[i])*ofca[i];
158 const float E=adc2mev[0]+
A*adc2mev[1];
160 uint16_t iquaShort=0;
171 ecut = run2DSPThresh->tQThr(
id);
173 else if (run1DSPThresh) {
174 ecut = run1DSPThresh->
tQThr(
id);
178 return StatusCode::FAILURE;
185 ATH_MSG_VERBOSE(
"Channel " <<
m_onlineId->channel_name(
id) <<
" gain " << gain <<
" above threshold for tQ computation");
189 const auto& ofcb=ofcs->
OFC_b(
id,gain);
191 for (
size_t i=0;i<nOFC;++i) {
192 At+=
static_cast<double>(samp_no_ped[i])*ofcb[i];
195 tau=(std::fabs(
A)>0.1) ? At/
A : 0.0;
196 const auto& fullShape=shapes->
Shape(
id,gain);
200 const size_t nSamples=samples.size();
201 if (fullShape.size()>nSamples && nSamples==4 &&
m_firstSample==0) {
208 if (!connected)
continue;
210 <<
" gain " << gain);
211 ATH_MSG_ERROR(
"Got size " << fullShape.size() <<
", expected at least " << nSamples+firstSample);
212 return StatusCode::FAILURE;
215 const float* shape=&*fullShape.begin()+firstSample;
219 const auto& fullshapeDer=shapes->
ShapeDer(
id,gain);
220 if (
ATH_UNLIKELY(fullshapeDer.size()<nOFC+firstSample)) {
222 <<
" gain " << gain);
223 ATH_MSG_ERROR(
"Got size " << fullshapeDer.size() <<
", expected at least " << nOFC+firstSample);
224 return StatusCode::FAILURE;
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);
234 for (
size_t i=0;i<nOFC;++i) {
235 q += std::pow((
A*shape[i]-(samp_no_ped[i])),2);
239 int iqua =
static_cast<int>(q);
240 if (iqua > 0xFFFF) iqua=0xFFFF;
241 iquaShort =
static_cast<uint16_t
>(iqua & 0xFFFF);
244 tau*=(Gaudi::Units::nanosecond/Gaudi::Units::picosecond);
247 outputContainer->emplace_back(
id,
static_cast<int>(std::floor(E+0.5)),
248 static_cast<int>(std::floor(tau+0.5)),
256 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
const ServiceHandle< StoreGateSvc > & detStore() const
virtual OFCRef_t OFC_b(const HWIdentifier &id, int gain, int tbin=0) const =0
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)
virtual float timeOffset(const HWIdentifier &CellID, int gain) const =0
virtual float pedestal(const HWIdentifier &id, int gain) const =0
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
virtual ShapeRef_t ShapeDer(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
float tQThr(const HWIdentifier chid) const
Liquid Argon digit base class.
Gaudi::Property< int > m_firstSample
SG::ReadCondHandleKey< ILArPedestal > m_pedestalKey
SG::ReadHandleKey< LArDigitContainer > m_digitKey
Gaudi::Property< bool > m_useShapeDer
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
SG::ReadCondHandleKey< AthenaAttributeList > m_run2DSPThresholdsKey
SG::ReadCondHandleKey< LArDSPThresholdsComplete > m_run1DSPThresholdsKey
const LArOnlineID * m_onlineId
StatusCode execute(const EventContext &ctx) const override
SG::WriteHandleKey< LArRawChannelContainer > m_rawChannelKey
Gaudi::Property< bool > m_useDBFortQ
Gaudi::Property< bool > m_absECutFortQ
SG::ReadCondHandleKey< LArADC2MeV > m_adc2MeVKey
StatusCode initialize() override
StatusCode finalize() override
SG::ReadCondHandleKey< ILArShape > m_shapeKey
SG::ReadCondHandleKey< ILArOFC > m_ofcKey
Gaudi::Property< float > m_eCutFortQ
const_pointer_type cptr()
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
hold the test vectors and ease the comparison