104{
106
107
109 SG::ReadHandle<LArDigitContainer> digitContainer (
m_DataLocation, ctx);
110 ATH_MSG_DEBUG(
"1) LArDigitContainer container size = " << digitContainer->size() );
111
112 ATH_MSG_DEBUG(
"2) LArDigitContainer container size = " << digitContainer->size() );
113 if( digitContainer->empty() ) {
115 return StatusCode::SUCCESS;
116 }
117
118 auto larRawChannelContainer = std::make_unique<LArRawChannelContainer>();
119
120
121 const ILArPedestal* larPedestal=nullptr;
123 if (
detStore()->retrieve(larPedestal).isFailure()) {
124 larPedestal=nullptr;
125 ATH_MSG_DEBUG(
"No pedestal found in database. Use default values." );
126 }
127 }
128
129 SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{
m_cablingKey, ctx};
130 const LArOnOffIdMapping*
cabling{*cablingHdl};
131 if(!cabling) {
133 return StatusCode::FAILURE;
134 }
135
136 const LArADC2MeV* adc2mev = nullptr;
138 SG::ReadCondHandle<LArADC2MeV> adc2mevH (
m_adc2mevKey, ctx);
139 adc2mev = *adc2mevH;
140 }
141
142
143
144
145
146
147
148 int nMinEM(0),nMinHEC(0),nMinFCAL(0);
149 std::vector<float> fSumEM,fSumHEC,fSumFCAL;
150 std::vector<float> *pSum = nullptr;
151
152 fSumEM.resize(0);
153 fSumHEC.resize(0);
154 fSumFCAL.resize(0);
155
156 for(int iloop=0;iloop<2;iloop++) {
157
158
160
161 for (const LArDigit* digit : *digitContainer) {
162
163
164 const std::vector<short>& samples =
digit->samples();
165 unsigned int nSamples = samples.size();
166 const HWIdentifier chid =
digit->channelID();
168
169
170 float thePedestal=-1;
171 if (larPedestal) {
172 float DBpedestal =larPedestal->
pedestal(chid,gain);
174 thePedestal=DBpedestal;
175 }
176 if (thePedestal<0) {
178 ATH_MSG_DEBUG(
"No pedestal found for this cell. Use default value " << thePedestal );
179 }
180
181 std::vector<float> mySamples;
182 mySamples.resize(samples.size());
183
184
185
186
187 for (
unsigned int i=0;
i<samples.size();
i++ )
188 {
189 mySamples[
i] = ((
float)samples[
i]) - thePedestal;
190 }
191
192
193 float GainFactor;
195 GainFactor = 9.8*9.8;
197 GainFactor = 9.8;
199 GainFactor = 1.0;
200 } else {
201 GainFactor = 1.0;
202 ATH_MSG_ERROR(
"Channel " << chid <<
"unknown gain: " << gain );
203 }
204
205
208 ATH_MSG_DEBUG( std::hex <<
" FebID / chid / channel = " << FebID <<
" / " << chid <<
" / " << channel );
209
210
211
213 bool isEM = false;
214 bool isHEC = false;
215 int nMin = 0;
216 unsigned int nAverage = 1;
217 float myScale = 1;
218 try {
219 const Identifier
id =
cabling->cnvToIdentifier(chid);
222 nMin = nMinFCAL;
223 pSum = &fSumFCAL;
226 }
227 else if (
m_emId->is_lar_em(
id)) {
228 isEM = true;
229 nMin = nMinEM;
230 pSum = &fSumEM;
233 }
234 else if (
m_hecId->is_lar_hec(
id)) {
235 isHEC = true;
236 nMin = nMinHEC;
237 pSum = &fSumHEC;
240 }
241 }
242
243 catch (LArID_Exception & execpt) {
245
246
247 continue;
248 }
249
250 if(!pSum) continue;
251
252
253
254
255
256 if ( nAverage > nSamples ) {
258 << nAverage << ") is larger than total number of samples ("
259 << nSamples << ")! adjusting nAverage ... " );
261 }
262
263
264 if ( iloop == 0 ) {
265
266 if ( pSum->empty())
267
268 pSum->resize(nSamples,0);
269
270 for(
unsigned i=0;
i<
nSamples-nAverage+1;
i++ ) {
271 for(
unsigned j=0;
j<nAverage;
j++ ) {
272 (*pSum)[
i] += mySamples[
i+
j];
273 }
274 }
275 }
276 else {
277 float maxADCPeak = 0.;
278 unsigned int iPeakSamp = 0;
279 float averagedADC = 0;
281 if ( maxADCPeak < mySamples[i] )
282 {
283 maxADCPeak = mySamples[
i];
285 }
286 if ( (int)i >= nMin && i < nMin+nAverage )
287 averagedADC += mySamples[
i];
288 }
289 averagedADC /= myScale;
290
291 bool CubicFailed = false;
292 float ADCPeak=0.;
294
295
296
298 {
299 ADCPeak = maxADCPeak;
300 time = ((
float)iPeakSamp) * 25.0 * nanosecond;
301 }
302
303
304
305 else {
306
307
308 if(isFCAL &&
m_mode ==
"CUBIC" &&
310
312
313 unsigned int it0;
314
315 const float invT[3][3]
316 = { { 1, 0, 0 },
317 { -1.5, 2, -0.5 },
318 { 0.5, -1, 0.5 } };
319
320
321 if ( iPeakSamp <= 1 ) {
322 it0 = 1;
323 } else if ( iPeakSamp >= nSamples - 1 ) {
325 } else {
326 it0 = iPeakSamp - 1;
327 }
328
329
330
331 float A[3] = {0, 0, 0};
332 float dtmax = 0.0;
333
334 for (int ia = 0; ia < 3; ia++)
335 for (
int it = 0;
it < 3;
it++)
336 A[ia] += invT[ia][it] * mySamples[it0+it];
337
338
339 if ( not ( CubicFailed = ( A[2] == 0 ) ) ) {
340 dtmax = -1.0 *
A[1] / 2.0 /
A[2];
341 if ( ! ( CubicFailed = ( dtmax < 0 || dtmax > 2 ) ) ) {
342
344 for(int ia = 0; ia < 3; ia++)
345 ADCPeak += A[ia] *
pow(dtmax, ia);
346 }
347 }
348
349
351 float weightSum = 0.;
352 float timeSum = 0.;
353 for(
int it=0;
it<3;
it++) {
354 timeSum +=
float(mySamples[it0+it]) *
float(it);
355 weightSum +=
float(mySamples[it0+it]);
356 }
357 time = (
float(it0) + timeSum / weightSum) * 25.0 * nanosecond;
358
360 CubicFailed = false;
361 }
362
363
364 }
else if(not isFCAL ||
m_mode !=
"CUBIC" ) {
365
366
367 if (
m_mode ==
"PARABOLA" &&
371 try {
372 const Identifier
id =
cabling->cnvToIdentifier(chid);
374 if (
m_emId->is_em_barrel(
id)) {
376 }
377 }
378 catch (LArID_Exception & execpt){
380 << " Cannot get offline identifier from online ID = " << chid );
381 }
382
384 if(peak.size() >1){
385 ADCPeak = peak[0]-thePedestal;
386 if (peak.size()==2)
time = peak[1];
388 }else{
389 ATH_MSG_DEBUG(
"No pic is computed from Parabola. Use scaled average of selected samples" );
390 ADCPeak = averagedADC;
392 }
393 }else{
394 ATH_MSG_FATAL(
"No parabola tool available ! Choose another mode" );
395 }
396 }
397
398
399 else if (
m_mode ==
"CUBIC" &&
401
402 unsigned int it0;
403 const float invT[4][4]
404 = { { 1, 0, 0, 0},
405 { -1.83333, 3, -1.5, 0.333333},
406 { 1, -2.5, 2, -0.5},
407 {-0.166666, 0.5, -0.5, 0.166666} };
408
409
410 if ( iPeakSamp <= 1 ) {
412 } else if ( iPeakSamp >= nSamples - 2 ) {
414 } else {
415 it0 = ( mySamples[iPeakSamp-2] > mySamples[iPeakSamp+2] )
416 ? iPeakSamp - 2
417 : iPeakSamp - 1;
418 }
419
420
421 float A[4] = {0, 0, 0, 0};
422 float dtmax = 0.0;
423 float disc;
424
425 for (int ia = 0; ia < 4; ia++)
426 for (
int it = 0;
it < 4;
it++)
427 A[ia] += invT[ia][it] * mySamples[it0+it];
428
429
430 disc =
A[2]*
A[2] - 3*
A[1]*
A[3];
431 if ( ! ( CubicFailed = ( disc < 0 || A[3] == 0 ) ) ) {
432 dtmax = (-
A[2]-std::sqrt(disc))/(A[3]*3);
433 if ( ! ( CubicFailed = ( dtmax < 0 || dtmax > 3 ) ) ) {
434 time = (
float(it0) + dtmax) * 25.0 * nanosecond;
435 for(int ia = 0; ia < 4; ia++)
436 ADCPeak += A[ia] *
pow(dtmax, ia);
437 }
438 }
439 }
440 }
441 }
442
443
444 if(
m_mode ==
"FIXED" || CubicFailed ) {
445 ADCPeak = averagedADC;
447 }
448
450 << CubicFailed
451 << " Detector: "
452 << (isEM?"EM":(isHEC?"HEC":(isFCAL?"FCAL":"none")))
453 << " Mode: "
455 << " Signal: "
456 << ADCPeak
457 << " Peak: "
458 << maxADCPeak
459 << " PeakSample: "
460 << iPeakSamp
461 );
462
465 float ADCPeakPower=ADCPeak;
466
467 LArVectorProxy ramp = adc2mev->
ADC2MEV(chid,gain);
468
469 if (ramp.size()>1 && ramp[1]<500 && ramp[1]>0) {
471 for (
unsigned i=1;
i<ramp.size();
i++)
473
474 ADCPeakPower*=ADCPeak;
475 }
476 }
477 }
478 if (energy==-9999) {
479 ATH_MSG_DEBUG(
"No Ramp found for this cell. Use default values" );
480
481
482 float ADCtoMeV = 10.0;
483
484
485
486
487
488
489 try {
490 const Identifier
id =
cabling->cnvToIdentifier(chid);
491
493
494 if (
m_emId->is_em_barrel(
id)) {
498 if (layer==2 &&
eta<32)
499 ADCtoMeV=ADCtoMeV*(12./18.);
500 ATH_MSG_DEBUG(
" in EMB s="<< layer <<
", using ADCtoMeV = " << ADCtoMeV );
501 }
else if (
m_emId->is_em_endcap_inner(
id)) {
502
504 ATH_MSG_DEBUG(
" in EMEC inner s="<<
m_emId->sampling(
id)<<
", using ADCtoMeV = " << ADCtoMeV );
505 }
else if (
m_emId->is_em_endcap_outer(
id)) {
506
507
509 ATH_MSG_DEBUG(
" in EMEC outer s="<<
m_emId->sampling(
id)<<
", using ADCtoMeV = " << ADCtoMeV );
510 }
else if (
m_fcalId->is_lar_fcal(
id)) {
511
514 }
else if (
m_hecId->is_lar_hec(
id)) {
515
518 }
519 }
520
521 catch (LArID_Exception & execpt)
522 {
524 ADCtoMeV=1;
525 }
526 energy = ADCPeak * ADCtoMeV * GainFactor;
527 }
530
532
533 LArRawChannel larRawChannel(chid,(int)energy,(int)time,iquality,iprovenance, gain);
534 larRawChannelContainer->add(larRawChannel);
535 }
536 }
537 if ( iloop == 0 ) {
538
540 float tmpSum = 0;
541
542 if ( !fSumEM.empty() ) {
543 for(i=0;
i<fSumEM.size();
i++) {
544 if (i == 0 || fSumEM[i] > tmpSum ) {
547 }
548 }
549 ATH_MSG_DEBUG(
"Found best EM window starting at sample <" << nMinEM <<
">" );
550 }
551
552 for(i=0;
i<fSumHEC.size();
i++) {
553 if (i == 0 || fSumHEC[i] > tmpSum ) {
556 }
557 }
558 if ( !fSumHEC.empty() ) {
559 ATH_MSG_DEBUG(
"Found best HEC window starting at sample <" << nMinHEC <<
">" );
560 }
561
562 for(i=0;
i<fSumFCAL.size();
i++) {
563 if (i == 0 || fSumFCAL[i] > tmpSum ) {
565 tmpSum = fSumFCAL[
i];
566 }
567 }
568 if ( !fSumFCAL.empty() ) {
569 ATH_MSG_DEBUG(
"Found best FCAL window starting at sample <" << nMinFCAL <<
">" );
570 }
571
572 }
573 }
574
576
577
579
580 return StatusCode::SUCCESS;
581}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
const ServiceHandle< StoreGateSvc > & detStore() const
virtual float pedestal(const HWIdentifier &id, int gain) const =0
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
SG::ReadHandleKey< LArDigitContainer > m_DataLocation
SG::ReadCondHandleKey< LArADC2MeV > m_adc2mevKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
SG::WriteHandleKey< LArRawChannelContainer > m_ChannelContainerName
time(flags, cells_name, *args, **kw)
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
bool isFCAL(const xAOD::CaloCluster *cluster)
return true if the cluster (or the majority of its energy) is in the FCAL0