ATLAS Offline Software
Loading...
Searching...
No Matches
LArPhysWavePredictor.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
7#include "GaudiKernel/ToolHandle.h"
9
12
17
20
26
32
35
36#include "LArCalibUtils/LArPhysWaveTool.h" // added by FT
37#include "LArCalibUtils/LArPhysWaveHECTool.h" // added by FT
38
39#include <cstdio>
40#include <fstream>
41#include <iostream>
42#include <memory>
43#include <string>
44
45
47
48LArPhysWavePredictor::LArPhysWavePredictor (const std::string& name, ISvcLocator* pSvcLocator)
49 : AthAlgorithm(name, pSvcLocator),
50 m_groupingType("FeedThrough") // SubDetector, Single, FeedThrough
51{
52 declareProperty("TestMode", m_testmode = false);
53 declareProperty("StoreEmpty", m_storeEmpty = false);
54 declareProperty("isSC", m_isSC = false);
55
56 m_keyCali.clear() ;
57 declareProperty("KeyCaliList", m_keyCali); // Keys of LArCaliWaveContainers
58 declareProperty("KeyPhys", m_keyPhys = "LArPhysWave") ; // Key of LArPhysWaveContainer
59 declareProperty("KeyIdealPhys", m_keyIdealPhys = "LArPhysWaveHECIdeal") ; // added by FT
60 declareProperty("KeyFcal", m_keyFcal = "FCALFromTB") ; // added by FT
61 declareProperty("KeyMphysMcali", m_keyMphysMcali = "LArMphysOverMcal") ; // Key of LArMphysOverMcalComplete
62 declareProperty("DumpMphysMcali", m_dumpMphysMcali = false ) ; // for debugging
63 declareProperty("NormalizeCali", m_normalizeCali = false ) ; // for debugging
64 declareProperty("isHEC", m_isHEC = false ) ;
65
66 //
67 // jobOptions for calibration pulse paramers (Tcali, Fstep)
68 //
69 declareProperty("UseCaliPulseParamsFromJO", m_useJOCaliPulseParams = false );
70 declareProperty("Tcali", m_Tcali = 450. );
71 declareProperty("Fstep", m_Fstep = 0.07 );
72
73 declareProperty("UseDetCellParamsFromJO" , m_useJODetCellParams = false );
74 declareProperty("Omega0", m_Omega0 = 0. ); // Omega0 == 0 will skip injection point correction
75 declareProperty("Taur", m_Taur = 0. );
76
77 //
78 // jobOptions for drift time of predicted pulses (Tdrift)
79 //
80 declareProperty("UseTdriftFromJO", m_useJOTdrift = false );
81 m_Tdrift.clear();
82 double default_Tdrift[4] = { 420 , 475 , 475 , 475 } ;
83 for ( unsigned i=0;i<4;i++) m_Tdrift.push_back(default_Tdrift[i]);
84 declareProperty("Tdrift", m_Tdrift) ;
85 m_Tdrift2.clear();
86 double default_Tdrift2[4] = { 1200. , 1200. , 1200. , 1200. } ;
87 for ( unsigned i=0;i<4;i++) m_Tdrift2.push_back(default_Tdrift2[i]);
88 declareProperty("Tdrift2", m_Tdrift2) ;
89 m_wTriangle2.clear();
90 double default_wTriangle2[4] = { 0.01 , 0.01 , 0.01 , 0.01 } ;
91 for ( unsigned i=0;i<4;i++) m_wTriangle2.push_back(default_wTriangle2[i]);
92 declareProperty("WeightTriangle2", m_wTriangle2) ;
93 declareProperty("UseDoubleTriangle", m_doubleTriangle = false );
94
95 //
96 // jobOptions for time shift of predicted pulses
97 //
98 declareProperty("UseTimeShiftFromJO", m_useJOPhysCaliTdiff = false );
99 declareProperty("TimeShiftByIndex" , m_timeShiftByIndex = 0);
100 declareProperty("TimeShiftByHelper", m_timeShiftByHelper = false);
101 declareProperty("TimeShiftByLayer", m_timeShiftByLayer = false) ;
102 declareProperty("TimeShiftByFEB", m_timeShiftByFEB = false) ;
103 declareProperty("TimeShiftGuardRegion", m_timeShiftGuardRegion = 0 ) ;
104 m_TshiftLayer.clear();
105 unsigned int default_TshiftLayer[4] = { 0 , 0 , 0 , 0 } ;
106 for ( unsigned i=0;i<4;i++) m_TshiftLayer.push_back(default_TshiftLayer[i]);
108
109 // Grouping type
110 declareProperty("GroupingType", m_groupingType);
111}
112
113
115= default;
116
117
119{
120 if ( ! m_doubleTriangle ) {
121 ATH_MSG_INFO( "Using standard triangular ionization pulse" ) ;
122 } else {
123 ATH_MSG_INFO( "Using refined ionization pulse (double triangle)" ) ;
124 }
125
126 StatusCode sc;
127 if ( m_isSC ) {
128 const LArOnline_SuperCellID* ll;
129 ATH_CHECK(detStore()->retrieve(ll, "LArOnline_SuperCellID"));
130 m_onlineHelper = static_cast<const LArOnlineID_Base*>(ll);
131 ATH_MSG_DEBUG("Found the LArOnlineID helper");
132 const CaloCell_SuperCell_ID* scid = nullptr;
133 ATH_CHECK(detStore()->retrieve(scid, "CaloCell_SuperCell_ID" ));
134 m_caloCellId= static_cast<const CaloCell_Base_ID*>(scid);
135
136 } else { // m_isSC
137 const LArOnlineID* ll;
138 ATH_CHECK(detStore()->retrieve(ll, "LArOnlineID") );
139 m_onlineHelper = static_cast<const LArOnlineID_Base*>(ll);
140 ATH_MSG_DEBUG(" Found the LArOnlineID helper. ");
141 const CaloCell_ID* cid;
142 ATH_CHECK(detStore()->retrieve(cid, "CaloCell_ID" ));
143 m_caloCellId= static_cast<const CaloCell_Base_ID*>(cid);
144 }
145
146 ATH_CHECK( m_BCKey.initialize() );
147 ATH_CHECK( m_cablingKey.initialize() );
148 ATH_CHECK( m_cablingKeySC.initialize(m_isSC) );
149 ATH_CHECK( m_bcMask.buildBitMask(m_problemsToMask,msg()));
150
151 return StatusCode::SUCCESS ;
152}
153
154
155namespace {
156struct FileCloser
157{
158 explicit FileCloser (FILE* the_f): f (the_f) {}
159 ~FileCloser() { if (f) fclose(f); }
160 FILE* f;
161
162 FileCloser (const FileCloser&) = delete;
163 FileCloser& operator= (const FileCloser&) = delete;
164};
165} // anonymous namespace
166
168{
169 ATH_MSG_INFO( "... in stop()" ) ;
170
171 LArWaveHelper larWaveHelper;
172
173 // Get access to the Detector Store
174 //StoreGateSvc* detStore;
175 //StatusCode sc = service("DetectorStore",detStore);
176 //if (sc!=StatusCode::SUCCESS) {
177 // ATH_MSG_ERROR( "Cannot get DetectorStore!" );
178 // return sc;
179 //}
180
181 // Retrieve LArPhysWaveTool
182 ToolHandle<LArPhysWaveTool> larPhysWaveTool("LArPhysWaveTool");
183 StatusCode sc=larPhysWaveTool.retrieve();
184 if (sc!=StatusCode::SUCCESS) {
185 ATH_MSG_ERROR( " Can't get LArPhysWaveTool " );
186 return sc;
187 }
188
189 // Retrieve LArPhysWaveHECTool // added by FT
190 ToolHandle<LArPhysWaveHECTool> larPhysWaveHECTool("LArPhysWaveHECTool");
191 if(m_isSC || m_isHEC){
192 sc=larPhysWaveHECTool.retrieve();
193 if (sc!=StatusCode::SUCCESS) {
194 ATH_MSG_ERROR( " Can't get LArPhysWaveHECTool " );
195 return sc;
196 }}
197
198
199 // Retrieve cabling
200 const LArOnOffIdMapping* cabling(nullptr);
201 if( m_isSC ){
203 cabling = {*cablingHdl};
204 if(!cabling) {
205 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKeySC.key());
206 return StatusCode::FAILURE;
207 }
208 }else{
210 cabling = {*cablingHdl};
211 if(!cabling) {
212 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key());
213 return StatusCode::FAILURE;
214 }
215 }
216
217 // Get parameters from detStore (access through abtract interfaces)
218 const ILArCaliPulseParams* larCaliPulseParams = nullptr;
219 const ILArDetCellParams* larDetCellParams = nullptr;
220 const ILArTdrift* larTdrift = nullptr;
221 const ILArPhysCaliTdiff* larPhysCaliTdiff = nullptr;
222
223 if ( !m_useJOCaliPulseParams ) {
224 sc = detStore()->retrieve(larCaliPulseParams);
225 if ( sc == StatusCode::FAILURE ) {
226 ATH_MSG_WARNING( "Cannot retrieve LArCaliPulseParams" ) ;
227 return sc;
228 } else {
229 ATH_MSG_INFO( "LArCaliPulseParams successfully retrieved" ) ;
230 }
231 }
232
233 if ( !m_useJODetCellParams ) {
234 if (!m_isHEC ) {
235 sc = detStore()->retrieve(larDetCellParams);
236 if ( sc == StatusCode::FAILURE ) {
237 ATH_MSG_WARNING( "Cannot retrieve LArDetCellParams" );
238 return sc;
239 }else {
240 ATH_MSG_INFO( "LArDetCellParams successfully retrieved" );
241 }
242 }else{
243 m_useJODetCellParams = true ;
244 }
245 }
246
247 if ( !m_useJOTdrift ) {
248 sc = detStore()->retrieve(larTdrift);
249 if ( sc == StatusCode::FAILURE ) {
250 ATH_MSG_WARNING( "Cannot retrieve LArTdriftComplete" );
251 return sc;
252 }else {
253 ATH_MSG_INFO( "LArTdriftComplete successfully retrieved" );
254 }
255 }
256
257 if ( !m_useJOPhysCaliTdiff ) {
258 sc = detStore()->retrieve(larPhysCaliTdiff);
259 if ( sc == StatusCode::FAILURE ) {
260 ATH_MSG_WARNING( "Cannot retrieve LArPhysCaliTdiff" );
261 return sc;
262 }else {
263 ATH_MSG_INFO( "LArPhysCaliTdiff successfully retrieved" );
264 }
265 }
266
267 const ILArFEBTimeOffset* larFebTshift = nullptr;
268 if ( m_useJOPhysCaliTdiff ) { // no LArPhysCaliTdiffComplete found, or manual time shift selected
269 if ( m_timeShiftByHelper ) {
270 ATH_MSG_INFO( "Will use helper class for start time." );
271 m_timeShiftByIndex = -1 ;
272 m_timeShiftByLayer = false ;
273 m_timeShiftByFEB = false ;
274 }
275 if ( m_timeShiftByIndex != -1 ) {
276 ATH_MSG_INFO( "Manually shifting pulses by time index " << m_timeShiftByIndex );
277 m_timeShiftByLayer = false ;
278 m_timeShiftByFEB = false ;
279 }
280 if ( m_timeShiftByLayer ) {
281 ATH_MSG_INFO( "Manually shifting pulses by *layer-dependent* time indexes." );
282 m_timeShiftByFEB = false ;
283 }
284 if ( m_timeShiftByFEB ) {
285 ATH_MSG_INFO( "Manually shifting pulses by *FEB* time indexes." );
286 sc = detStore()->retrieve(larFebTshift);
287 if (sc.isFailure())
288 larFebTshift = nullptr;
289 }
290 }
291
292 const LArPhysWaveContainer *fcalPhysWaves=nullptr;
293
294 if ( m_isSC ) { //retrieve FCAL phys waves from COOL
295 sc = detStore()->retrieve(fcalPhysWaves, m_keyFcal);
296 if ( sc.isFailure() || !fcalPhysWaves) {
297 ATH_MSG_WARNING( "Cannot retrieve FCAL Phys waves" );
298 return sc;
299 }else {
300 ATH_MSG_INFO( "LArPhysWave fro FCAL successfully retrieved" );
301 }
302 }
303
304 int nchannel = 0 ;
305
306 // Create LArPhysWaveContainer for predicted physics waveforms
307 std::unique_ptr<LArPhysWaveContainer> larPhysWaveContainer = std::make_unique<LArPhysWaveContainer>();
308
309 sc=larPhysWaveContainer->setGroupingType(m_groupingType,msg());
310 if (sc.isFailure()) {
311 ATH_MSG_ERROR( "Failed to set groupingType for LArPhysWaveContainer object" );
312 return sc;
313 }
314
315 sc=larPhysWaveContainer->initialize();
316 if (sc.isFailure()) {
317 ATH_MSG_ERROR( "Failed initialize LArPhysWaveContainer object" );
318 return sc;
319 }
320
321 // Create LArMphysOverMcalComplete for predicted Mphys/Mcali
322 std::unique_ptr<LArMphysOverMcalComplete> MphysOverMcalComplete = std::make_unique<LArMphysOverMcalComplete>();
323 sc=MphysOverMcalComplete->setGroupingType(m_groupingType,msg());
324 if (sc.isFailure()) {
325 ATH_MSG_ERROR( "Failed to set groupingType for LArMphysOverMcalComplete object" );
326 return sc;
327 }
328
329 sc=MphysOverMcalComplete->initialize();
330 if (sc.isFailure()) {
331 ATH_MSG_ERROR( "Failed initialize LArMphysOverMcalComplete object" );
332 return sc;
333 }
334
335 FILE* f = nullptr;
336 if (m_dumpMphysMcali) {
337 f = fopen("MphysOverMcali.dat","w");
338 if (!f) {
339 ATH_MSG_ERROR("Cannot open file `MphysOverMcali.dat' for write");
340 return StatusCode::FAILURE;
341 }
342 fprintf(f,"# Region Layer Eta Phi Gain MphysMcali\n");
343 }
344 FileCloser fcloser (f);
345
346 std::vector<int> nTotal;
347 std::vector<int> noTcali;
348 std::vector<int> noFstep;
349 std::vector<int> noOmega0;
350 std::vector<int> noTaur;
351 std::vector<int> noTdrift;
352 std::vector<int> noTdiff;
353
354 unsigned maxgain = m_isSC ? CaloGain::LARNGAIN : 1;
355 for ( unsigned i=0; i<maxgain; ++i ) {
356 nTotal.push_back(0);
357 noTcali.push_back(0);
358 noFstep.push_back(0);
359 noOmega0.push_back(0);
360 noTaur.push_back(0);
361 noTdrift.push_back(0);
362 noTdiff.push_back(0);
363 }
364
366 // Get current LArPhysWaveContainer
367 const LArPhysWaveContainer* larIdealPhysWaveContainer=nullptr;
368 if(m_isHEC || m_isSC){
369 ATH_CHECK(detStore()->retrieve(larIdealPhysWaveContainer,m_keyIdealPhys));
370 ATH_MSG_INFO("LArPhysWaveContainer with (key = " << m_keyIdealPhys << ") reading from StoreGate" );
371 }
373
374 // get the calibration waveforms from the detector store
375
376 int NPhysWave=0;
377 int NMPMC=0;
378
379 for (const std::string& key : m_keyCali) { // Loop over all LArCaliWave containers that are to be processed
380
381 // Get current LArCaliWaveContainer
382 const LArCaliWaveContainer* caliWaveContainer;
383 sc = detStore()->retrieve(caliWaveContainer,key);
384 if (sc.isFailure()) {
385 //log << MSG::INF0 << "LArCaliWaveContainer (key = " << key << ") not found in StoreGate" );
386 continue;
387 }
388 if ( caliWaveContainer == nullptr ) {
389 ATH_MSG_INFO( "LArCaliWaveContainer (key = " << key << ") is empty" );
390 continue;
391 }
392
393 ATH_MSG_INFO( "Processing LArCaliWaveContainer from StoreGate, key = " << key );
394
395 for ( unsigned gain = CaloGain::LARHIGHGAIN ; gain < CaloGain::LARNGAIN ; ++ gain ) { // loop over gain in the current LArCaliWAveContainer
396
397 ATH_MSG_INFO( "Now processing gain = " << gain << " in LArCaliWaveContainer with key = " << key );
398
399
400 // loop over current cali wave container
402 const_iterator itVec = caliWaveContainer->begin(gain);
403 const_iterator itVec_e = caliWaveContainer->end(gain);
404 for (; itVec != itVec_e; ++itVec) { // loop over channels for a given gain
405
406 for (const LArCaliWave& larCaliWave : *itVec) { // loop over DAC values for a given channel
407
408 ATH_MSG_DEBUG((*itVec).size() << " LArCaliWaves found for channel " << m_onlineHelper->channel_name(itVec.channelId()) << " 0x"
409 << std::hex << itVec.channelId().get_identifier32().get_compact() << std::dec);
410 const HWIdentifier chid = itVec.channelId();
411 //
412 // region and layer information are needed
413 Identifier id;
414 try {
415 id = cabling->cnvToIdentifier(chid);
416 } catch (LArID_Exception & execpt) {
417 ATH_MSG_ERROR( "LArCabling exception caught for channel 0x" << MSG::hex << chid << MSG::dec
418 << ". Skipping channel." ) ;
419 continue ;
420 }
421
422 int region = m_caloCellId->region(id);
423 int layer = m_caloCellId->sampling(id);
424
425 if ( nchannel < 100 || ( nchannel < 1000 && nchannel%100==0 ) || nchannel%1000==0 )
426 ATH_MSG_INFO( "Processing calibration waveform number " << nchannel );
427
428 if(m_onlineHelper->isFCALchannel(chid)) {
429 if(!m_isSC) continue; // Skip if it is FCAL ini standard readout
430 LArPhysWave fcalw;
431 fcalw = fcalPhysWaves->get(chid,0);
432
433 // we need full length phys wave (truncation during merging
434 if(fcalw.getSize()<768) {
435 std::vector<double> amp;
436 amp.resize(768, 0.); // TODO: from where to take this number ? To be fixed later
437 const std::vector<double>& fvec = fcalw.getWave();
438 std::copy(fvec.begin(), fvec.end(), amp.begin());
439 LArPhysWave ptmp(amp, fcalw.getDt(), fcalw.getFlag());
440 larPhysWaveContainer->setPdata(chid,ptmp, gain);
441 } else {
442 larPhysWaveContainer->setPdata(chid,fcalw, gain);
443 }
444
445 continue;
446 } //isFCALchannel
447
448
449 if ( larCaliWave.getFlag() == LArWave::dac0 ) continue ; // skip dac0 waves
450 // TODO: here we should add a DAC selection mechanism for TCM method
451
452 nTotal[gain]++; // counter of processed pulse per gain
453
454 ATH_MSG_VERBOSE("Predicting physics waveform for channel 0x" << MSG::hex << chid << MSG::dec
455 << " (gain = " << gain << " - DAC = " << larCaliWave.getDAC() << ")");
456
457 // calibration pulse copy (working around the const iterator to be able to manipulate it...)
458 LArCaliWave theLArCaliWave = larCaliWave;
459 ++nchannel;
460
461 if ( !cabling->isOnlineConnected(chid) ) { // unconnected channel : skipping ...
462 ATH_MSG_VERBOSE("Unconnected channel 0x" << MSG::hex << chid << MSG::dec
463 << ". Skipping channel.");
464 continue ;
465 }
466
467 // Get the parameters corresponding to current LArCaliWave
468 float Tcali;
469 float Fstep;
470 float Omega0;
471 float Taur;
472 float Tdrift;
473 int Tdiff;
474
475 // LArCaliPulseParams: if not fould, will use jobOptions values
476 if ( !m_useJOCaliPulseParams ) {
477 Tcali = larCaliPulseParams->Tcal(chid,gain) ;
478
479 if ( Tcali <= 1.0+LArCaliPulseParamsComplete::ERRORCODE ) {
480 notFoundMsg(chid,gain,"Tcali");
481 Tcali = m_Tcali;
482 noTcali[gain]++;
483 }
484 Fstep = larCaliPulseParams->Fstep(chid,gain) ;
485 if ( Fstep <= 1.0+LArCaliPulseParamsComplete::ERRORCODE ) {
486 notFoundMsg(chid,gain,"Fstep");
487 Fstep = m_Fstep;
488 noFstep[gain]++;
489 }
490 } else {
491 Tcali = m_Tcali;
492 Fstep = m_Fstep;
493 }
494
495 // LArDetCellParams: if not found, will not apply injection point correction
496 if ( !m_useJODetCellParams ) {
497 Omega0 = larDetCellParams->Omega0(chid,gain) ;
498 if ( Omega0 <= 1.0+LArDetCellParamsComplete::ERRORCODE ) {
499 notFoundMsg(chid,gain,"Omega0");
500 Omega0 = m_Omega0;
501 noOmega0[gain]++;
502 }
503 Taur = larDetCellParams->Taur(chid,gain) ;
504 if ( Taur <= 1.0+LArDetCellParamsComplete::ERRORCODE ) {
505 notFoundMsg(chid,gain,"Taur");
506 Taur = m_Taur;
507 noTaur[gain]++;
508 }
509 } else {
510 Omega0 = m_Omega0;
511 Taur = m_Taur;
512 }
513
514 // LArTdrift: if not found will be set to jobOptions settings (or defaults if none) according to layer
515 if ( !m_useJOTdrift ) {
516 Tdrift = larTdrift->Tdrift(chid) ;
517 if ( Tdrift <= 1.0+LArTdriftComplete::ERRORCODE ) {
518 notFoundMsg(chid,gain,"Tdrift");
519 //ATH_MSG_ERROR( "Cannot access Tdrift for channel 0x" << MSG::hex << chid << MSG::dec
520 // << ". Will use jobOption setting." ) ;
521 if ( layer>=0 && layer<4 )
522 Tdrift = m_Tdrift[layer]; // Set drift time according to layer
523 else
524 Tdrift = 475.; // very crude!
525 noTdrift[gain]++;
526 }
527 } else { // use jobOptions settings
528 if ( layer>=0 && layer<4 )
529 Tdrift = m_Tdrift[layer]; // Set drift time according to layer
530 else
531 Tdrift = 475.; // very crude!
532 }
533
534
535 // LArPhysCaliTdiff: if not found, will use jobOptions settings
536 Tdiff = 0 ; // default value if everything else fails...
537 if ( !m_useJOPhysCaliTdiff ) {
538 Tdiff = (int)larPhysCaliTdiff->Tdiff(chid,gain) ;
539 if ( Tdiff <= 1.0+LArPhysCaliTdiffComplete::ERRORCODE ) {
540 notFoundMsg(chid,gain,"Tdiff");
541 Tdiff = 0 ;
542 m_useJOPhysCaliTdiff = true ;
543 noTdiff[gain]++;
544 }
545 }
546 if ( m_useJOPhysCaliTdiff ) {
547 if ( m_timeShiftByHelper ) {
548 Tdiff = larWaveHelper.getStart(theLArCaliWave) ;
549 Tdiff -= m_timeShiftGuardRegion ;
550 }
551 if ( m_timeShiftByIndex != 0 ) {
552 Tdiff = m_timeShiftByIndex;
553 }
554 if ( m_timeShiftByLayer ) {
555 Tdiff = m_TshiftLayer[layer] ;
556 }
557 if ( m_timeShiftByFEB && larFebTshift ) {
558 const HWIdentifier febid = m_onlineHelper->feb_Id(chid);
559 Tdiff = (int)larFebTshift->TimeOffset(febid);
560 Tdiff -= m_timeShiftGuardRegion ;
561 }
562 }
563
564 // Fill the LArWFParams structure to be used by the LArPhysWaveTool
565 float Tshaper = 15. ;
566 float Amplitude = 1. ;
567 LArWFParams wfParams(Tcali,Fstep,Tdrift,Omega0,Taur,Tshaper,Amplitude);
568 wfParams.setFlag( 0 ) ; // this should contain the method used to find parameters and the gain
569 wfParams.setTdiff(Tdiff);
570
571 ATH_MSG_VERBOSE( "wfParams: " << Tcali << " " <<Fstep<<" " <<Tdrift<<" "<<Omega0<<" "<<Taur<<" "<<Tdiff<<" "<<layer<<" "<<region );
572 // calibration pulse normalization
573 // (should be done here instead than in LArPhysWaveTool to get
574 // the correct Mphys/Mcali in case of double triangle prediction)
575 if ( m_normalizeCali ) {
576 double peak = theLArCaliWave.getSample(larWaveHelper.getMax(theLArCaliWave));
577 ATH_MSG_VERBOSE("Channel 0x" << MSG::hex << chid << MSG::dec << " -> Applying normalisation (CaliWave peak = " << peak << ")");
578 if ( peak <=0 ) {
579 ATH_MSG_WARNING( "Peak value <=0 , cannot normalize!" ) ;
580 } else {
581 theLArCaliWave = LArCaliWave( (theLArCaliWave*(1./peak)).getWave(),
582 theLArCaliWave.getErrors(),
583 theLArCaliWave.getTriggers(),
584 theLArCaliWave.getDt(),
585 theLArCaliWave.getDAC(),
586 theLArCaliWave.getIsPulsedInt(),
587 theLArCaliWave.getFlag() );
588 }
589 }
590
591 //
592 // Predict the Physics Waveform
593 //
594 LArPhysWave larPhysWave;
595 float MphysMcali ;
596 //if(larIdealPhysWaveContainer && m_caloCellId->is_lar_hec(id)) {
597 // decide by online helper, not sure if offline is working for SC
598 if(larIdealPhysWaveContainer && m_onlineHelper->isHECchannel(chid)) {
599 const LArPhysWave& laridealPhysWave = larIdealPhysWaveContainer -> get(chid,gain);
600 int LArWaveFlag=LArWave::predCali; // 111 - for HEC Wave
601 //int LArIdealPhysWaveFlag=LArWave::predCali; // 111 - for HEC Wave
602 ATH_MSG_DEBUG( "Using HEC tool to predict LArPhysWave for channel " << chid.get_identifier32().get_compact());
603
604 sc = larPhysWaveHECTool->makeLArPhysWaveHEC(wfParams,theLArCaliWave,larPhysWave,laridealPhysWave,MphysMcali,chid,gain,LArWaveFlag);
605
606 //laridealPhysWave.setFlag( LArIdealPhysWaveFlag ) ;
607 }
608 else {
609 ATH_MSG_DEBUG( "Using EM tool to predict LArPhysWave for channel 0x" << chid.get_identifier32().get_compact() );
610 sc = larPhysWaveTool->makeLArPhysWave(wfParams,theLArCaliWave,region,layer,larPhysWave,MphysMcali);
611 }
612 if (sc.isFailure()) {
613 ATH_MSG_FATAL( "Cannot predict LArPhysWave for channel " << chid.get_identifier32().get_compact() );
614 continue;
615 }
616 larPhysWave.setFlag( LArWave::predCali ) ;
617
618 if ( m_doubleTriangle ) { // mix of Tdrift ...
619 ATH_MSG_DEBUG("Applying double triangle correction");
620 if ( region==0 && layer>=0 && layer<4 && m_wTriangle2[layer]>0 ) { // EMB: set drift times and weight according to layer
621 LArWFParams wfParams2 = wfParams ;
622 wfParams2.setTdrift(m_Tdrift2[layer]);
623 LArPhysWave larPhysWave2;
624 float MphysMcali2 ;
625 sc = larPhysWaveTool->makeLArPhysWave(wfParams2,theLArCaliWave,region,layer,larPhysWave2,MphysMcali2);
626 if (sc.isFailure()) {
627 ATH_MSG_FATAL( "Cannot predict LArPhysWave for channel 0x" << MSG::hex << chid << MSG::dec << "with double triangle." );
628 continue;
629 }
630 larPhysWave = LArPhysWave ( ( larPhysWave*(1.-m_wTriangle2[layer])+larPhysWave2*m_wTriangle2[layer] ).getWave() ,
631 larPhysWave.getDt(),
632 larPhysWave.getFlag() ) ;
633 // Double-triagle predicion was used, Mphys/Mcali should be recomputed...
634 MphysMcali = larPhysWave.getSample(larWaveHelper.getMax(larPhysWave))/theLArCaliWave.getSample(larWaveHelper.getMax(theLArCaliWave));
635 } else {
636 ATH_MSG_WARNING( "Double triangle implemented only for EMB, skip channel!" ) ;
637 }
638 } // end if 2nd triangle
639
640 // Apply time shift...
641 if ( Tdiff !=0 ) {
642 ATH_MSG_DEBUG("Time shift for channel " << (itVec.channelId()).get_compact() << " is "
643 << Tdiff << " samples (" << Tdiff*larPhysWave.getDt() << " ns)");
644 larPhysWave = LArPhysWave( (larWaveHelper.translate(larPhysWave,-Tdiff,0)).getWave() ,
645 larPhysWave.getDt(),
646 larPhysWave.getFlag() ) ;
647 }
648
649 // Add predicted physics wave to container
650 larPhysWaveContainer->setPdata(chid,larPhysWave,gain);
651 NPhysWave++;
652
653 // Add Mphys/Mcali to container
654 if (MphysMcali<=0.) {
656 }
657 ATH_MSG_VERBOSE("Channel 0x" << MSG::hex << chid << MSG::dec << " -> Mphys/Mcali = " << MphysMcali);
658 MphysOverMcalComplete->set(chid,gain,MphysMcali);
659 NMPMC++;
660 if ( m_dumpMphysMcali ) {
661 int eta = m_caloCellId->eta(id);
662 int phi = m_caloCellId->phi(id);
663 fprintf( f , "%2d %2d %3d %3d %2u %8.3f \n", region, layer, eta, phi, gain, MphysMcali ) ;
664 } //end if m_dumpMphysMcal
665
666 } // end loop over DAC value for a given cell
667 if ( m_testmode && nchannel>=1 ) break;
668 } // end loop over cells for a given gain
669 if ( m_testmode && nchannel>=1 ) break;
670 } // end loop over gains for a give container
671 if ( m_testmode && nchannel>=1 ) break;
672 } // End loop over all CaliWave containers
673
674 //ATH_MSG_INFO( " Summary : Number of cells with a PhysWave values computed : " << larPhysWaveContainer->totalNumberOfConditions() );
675 //ATH_MSG_INFO( " Summary : Number of cells with a MphysOverMcal values computed : " << MphysOverMcalComplete->totalNumberOfConditions() );
676 ATH_MSG_INFO( " Summary : Number of cells with a PhysWave values computed : " << NPhysWave );
677 ATH_MSG_INFO( " Summary : Number of cells with a MphysOverMcal values computed : " << NMPMC );
678 ATH_MSG_INFO( " Summary : Number of Barrel PS cells side A or C (connected+unconnected): 3904+ 192 " );
679 ATH_MSG_INFO( " Summary : Number of Barrel cells side A or C (connected+unconnected): 50944+2304 " );
680 ATH_MSG_INFO( " Summary : Number of EMEC cells side A or C (connected+unconnected): 31872+3456 " );
681 ATH_MSG_INFO( " Summary : Number of HEC cells side A or C (connected+unconnected): 2816+ 256 " );
682 ATH_MSG_INFO( " Summary : Number of FCAL cells side A or C (connected+unconnected): 1762+ 30 " );
683
684 ATH_MSG_DEBUG("LArPhysWaveContainer->totalNumberOfConditions() = " << larPhysWaveContainer->totalNumberOfConditions());
685 ATH_MSG_DEBUG("LArMphysOverMcalComplete->totalNumberOfConditions() = " << MphysOverMcalComplete->totalNumberOfConditions());
686
687 // final report
688 ATH_MSG_INFO( "\n Final report \n" );
689 for ( unsigned theGain = CaloGain::LARHIGHGAIN ; theGain < CaloGain::LARNGAIN ; ++theGain ) {
690
691 ATH_MSG_INFO( " *** Gain = " << theGain << " ***" );
692 if ( !m_useJOCaliPulseParams ) {
693 ATH_MSG_INFO( "\t" << noTcali[theGain] << " / " << nTotal[theGain] << " channel(s) missing Tcali" );
694 ATH_MSG_INFO( "\t" << noFstep[theGain] << " / " << nTotal[theGain] << " channel(s) missing Fstep" );
695 }
696 if ( !m_useJODetCellParams ) {
697 ATH_MSG_INFO( "\t" << noOmega0[theGain] << " / " << nTotal[theGain] << " channel(s) missing Omega0" );
698 ATH_MSG_INFO( "\t" << noTaur[theGain] << " / " << nTotal[theGain] << " channel(s) missing Taur" );
699 }
700 if ( !m_useJOTdrift )
701 ATH_MSG_INFO( "\t" << noTdrift[theGain] << " / " << nTotal[theGain] << " channel(s) missing Tdrift" );
703 ATH_MSG_INFO( "\t" << noTdiff[theGain] << " / " << nTotal[theGain] << " channel(s) missing Tdiff" );
704 }
705 ATH_MSG_INFO( "\n" );
706
707 // Record LArPhysWaveContainer to DetectorStore
708 sc = detStore()->record(std::move(larPhysWaveContainer),m_keyPhys);
709 if (sc.isFailure()) {
710 ATH_MSG_FATAL( "Cannot record LArPhysWaveContainer to StoreGate! key=" << m_keyPhys );
711 return StatusCode::FAILURE;
712 }
713
714 // Record LArMphysOverMcalComplete to DetectorStore
715 sc = detStore()->record(std::move(MphysOverMcalComplete),m_keyMphysMcali);
716 if (sc.isFailure()) {
717 ATH_MSG_FATAL( "Cannot record LArMphysOverMcalComplete to StoreGate! key=" << m_keyMphysMcali );
718 return StatusCode::FAILURE;
719 }
720
721 // Symlink LArMphysOverMcalComplete to ILArMphysOverMcal for further use
722 ATH_MSG_DEBUG("Trying to symlink ILArMphysOverMcal with LArMphysOverMcalComplete...");
724 if (sc.isFailure()) {
725 ATH_MSG_FATAL( "Could not symlink ILArMphysOverMcal with LArMphysOverMcalComplete." );
726 return StatusCode::FAILURE;
727 }
728 ATH_MSG_INFO( "ILArMphysOverMcal symlink with LArMphysOverMcalComplete successfully" ) ;
729
730 ATH_MSG_INFO( "LArPhysWavePredictor finalized!" );
731
732 return StatusCode::SUCCESS;
733}
734
735void LArPhysWavePredictor::notFoundMsg(const HWIdentifier chid, const int gain, const char* value) {
737 const LArBadChannelCont* bcCont{*bcContHdl};
738
739 if (m_bcMask.cellShouldBeMasked(bcCont,chid)) {
740 ATH_MSG_WARNING( "Cannot access " << value << " for known bad channel channel " << m_onlineHelper->channel_name(chid)
741 << ", gain = " << gain << ". Will use jobO setting." ) ;
742 }
743 else {
745 const LArBadChannel bc = bcCont->status(chid);
746 const std::string badChanStatus=packer.stringStatus(bc);
747
748 ATH_MSG_ERROR( "Cannot access " << value << " for channel " << m_onlineHelper->channel_name(chid)
749 << ", gain = " << gain << " BC status=[" << badChanStatus << "]. Will use jobO setting." );
750 }
751 }
752
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helper class for offline supercell identifiers.
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
LArBadXCont< LArBadChannel > LArBadChannelCont
int LArWaveFlag
static Double_t sc
LArPhysWaveContainer::ConstConditionsMapIterator PhysWaveIt
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
MsgStream & msg() const
Helper base class for offline cell identifiers.
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
Helper class for offline supercell identifiers.
virtual const float & Tcal(const HWIdentifier &id, int gain) const =0
virtual const float & Fstep(const HWIdentifier &id, int gain) const =0
virtual const float & Taur(const HWIdentifier &id, int gain) const =0
virtual const float & Omega0(const HWIdentifier &id, int gain) const =0
virtual float TimeOffset(const HWIdentifier fId) const =0
virtual const float & Tdiff(const HWIdentifier &id, int gain) const =0
virtual const float & Tdrift(const HWIdentifier &id) const =0
value_type get_compact() const
Get the compact id.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
Liquid Argon Cumulative Wave Container.
int getIsPulsedInt() const
isPulsed value
int getDAC() const
DAC value.
ConditionsMap::const_iterator ConstConditionsMapIterator
ConstReference get(const HWIdentifier id, unsigned int gain=0) const
get data with online identifier
ConstConditionsMapIterator begin(unsigned int gain) const
get iterator for all channels for a gain
ConstConditionsMapIterator end(unsigned int gain) const
end of all channels for this gain
Exception class for LAr Identifiers.
Helper for the Liquid Argon Calorimeter cell identifiers.
Liquid Argon Physics Wave Container.
LArBadChannelMask m_bcMask
const LArOnlineID_Base * m_onlineHelper
std::vector< double > m_wTriangle2
const CaloCell_Base_ID * m_caloCellId
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKeySC
std::vector< double > m_Tdrift
LArPhysWavePredictor(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< std::vector< std::string > > m_problemsToMask
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
void notFoundMsg(const HWIdentifier chid, const int gain, const char *value)
std::vector< double > m_Tdrift2
std::vector< unsigned int > m_TshiftLayer
SG::ReadCondHandleKey< LArBadChannelCont > m_BCKey
std::vector< std::string > m_keyCali
void setTdrift(double tdrift)
void setFlag(unsigned flag)
void setTdiff(double tdiff)
const std::vector< int > & getTriggers() const
trigger vector
const std::vector< double > & getErrors() const
error vector
LArWave translate(const LArWave &theWave, int nShift, double baseline=0.) const
unsigned int getMax(const LArWave &theWave) const
return index of maximum sample
unsigned getStart(const LArWave &theWave) const
size_t getSize() const
number of time samples
Definition LArWave.h:62
@ predCali
Definition LArWave.h:129
const double & getSample(const unsigned int i) const
Amplitude per time bin.
Definition LArWave.h:53
const std::vector< double > & getWave() const
Wave parameters.
Definition LArWave.h:167
const double & getDt() const
delta time
Definition LArWave.h:50
unsigned getFlag() const
flag: ...
Definition LArWave.h:178
void setFlag(const unsigned flag)
set flag
Definition LArWave.h:199
std::string stringStatus(const LArBadChannel &bc) const
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
@ LARNGAIN
Definition CaloGain.h:19
@ LARHIGHGAIN
Definition CaloGain.h:18