ATLAS Offline Software
Loading...
Searching...
No Matches
LArDigitOscillationCorrTool.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/MsgStream.h"
8#include "GaudiKernel/IIncidentSvc.h"
9#include "CLHEP/Units/SystemOfUnits.h"
10
15
16#include <sstream>
17#include <iostream>
18#include <fstream>
19#include <iomanip>
20#include <cmath>
21
22
23using CLHEP::hertz;
24using CLHEP::ns;
25
26
28 const std::string& name,
29 const IInterface* parent)
30 : base_class(type, name, parent),
31 m_priority(1400),
32 m_nSigma(3.0),
33 m_eventPhase(0),
34 m_omega(1.024e6*hertz)
35{
36 declareProperty("BeginRunPriority",m_priority);
37 declareProperty("SignalCutInSigma",m_nSigma);
38 declareProperty("Omega",m_omega);
39}
40
42{
43 ATH_MSG_DEBUG ( "LArDigitOscillationCorrTool initialize() begin" );
44
45 ATH_CHECK( detStore()->retrieve(m_lar_on_id,"LArOnlineID") );
46
47 const CaloCell_ID* idHelper = nullptr;
48 ATH_CHECK( detStore()->retrieve (idHelper, "CaloCell_ID") );
49 m_emId = idHelper->em_idHelper();
50 m_fcalId = idHelper->fcal_idHelper();
51 m_hecId = idHelper->hec_idHelper();
52
53 ATH_CHECK( m_cablingKey.initialize() );
54
55 SmartIF<IIncidentSvc> incSvc{Gaudi::svcLocator()->service("IncidentSvc")};
56 ATH_CHECK(incSvc.isValid());
57
58 //start listening to "BeginRun"
59 incSvc->addListener(this, "BeginRun", m_priority);
60
61 ATH_MSG_DEBUG ( "LArDigitOscillationCorrTool initialize() end" );
62 return StatusCode::SUCCESS;
63}
64
66{
67 ATH_MSG_DEBUG ( "In execute: calculate event phase" );
68
69 //Pointer to conditions data objects to get pedetestals
70 ATH_MSG_DEBUG ( "Retrieving pedestal " );
71 const ILArPedestal* larPedestal=nullptr;
72 ATH_CHECK( detStore()->retrieve(larPedestal) );
73
74 //Pointer to conditions data objects to get channel phases
75 ATH_MSG_DEBUG ( "Retrieving channel phases and amplituides " );
76 const ILArH6Oscillation* larH6Oscillations = nullptr;
77 ATH_CHECK( detStore()->retrieve(larH6Oscillations) );
78 unsigned int iHECChan(0);
79 std::vector<std::vector<short> > theSamples;
80 std::vector<float> thePedestals;
81 std::vector<double> theChannelAmplitudes;
82 std::vector<double> theChannelPhases;
83 std::vector<float> theRMSValues;
84
85 //Now all data is available, start loop over Digit Container
86 ATH_MSG_DEBUG ( "Loop over Digit Container with size <" << theDC.size() << ">" );
87
89 const LArOnOffIdMapping* cabling{*cablingHdl};
90 if(!cabling) {
91 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key() );
92 return StatusCode::FAILURE;
93 }
94
95
96 for (unsigned int i=0;i<theDC.size();i++) {
97 //Get data from LArDigit
98 const LArDigit *theDigit = theDC[i];
99 const std::vector<short>& samples = theDigit->samples();
100 const HWIdentifier chid = theDigit->channelID();
101 const CaloGain::CaloGain gain = theDigit->gain();
102
103 // use only HEC channels
104 const Identifier id = cabling->cnvToIdentifier(chid);
105 bool isHEC = false;
106
107 if (m_hecId->is_lar_hec(id)) {
108 isHEC = true;
109 }
110
111 if ( isHEC) {
112 float DBpedestalRMS=larPedestal->pedestalRMS(chid,gain);
113 if (DBpedestalRMS <= (1.0+LArElecCalib::ERRORCODE)) {
114 ATH_MSG_DEBUG ( "No pedestal RMS found for this cell. Exiting ...." );
115 return StatusCode::FAILURE;
116 }
117 const double& DBchannelPhase=larH6Oscillations->channelPhase(chid);
118 const double& DBchannelAmplitude=larH6Oscillations->channelAmplitude(chid);
119
120 if( DBpedestalRMS > 0 && DBchannelAmplitude>0 ) {
121 theRMSValues.push_back(DBpedestalRMS);
122 theSamples.push_back(samples);
123 theChannelPhases.push_back(DBchannelPhase);
124 theChannelAmplitudes.push_back(DBchannelAmplitude);
125 float DBpedestal=larPedestal->pedestal(chid,gain);
126 if (DBpedestal >= (1.0+LArElecCalib::ERRORCODE))
127 thePedestals.push_back(DBpedestal);
128 else {
129 ATH_MSG_DEBUG ( "No valid pedestal found for this cell. Exiting ...." );
130 return StatusCode::FAILURE;
131 }
132 iHECChan++;
133 }
134 }
135 }
136
137 ATH_MSG_DEBUG ( "Start calculating the event phase" );
138 double lchimin = -1;
139 int nTotSamples = 0;
140 for(double myEventPhase = -M_PI; myEventPhase<M_PI; myEventPhase+=0.1) {
141 double lchitest = 0;
142 for (unsigned int i=0;i<iHECChan;i++) {
143 unsigned int nSamples = theSamples[i].size();
144 for(unsigned int j=0;j<nSamples;j++) {
145 // exclude all samples (and the previous and next sample) which
146 //have more than nSigma worth of absolute signal
147 if ( j == 0 || (std::abs(theSamples[i][j] - theSamples[i][0]) <= m_nSigma*theRMSValues[i]
148 && ( j <= 0 || std::abs(theSamples[i][j-1] - theSamples[i][0]) <= m_nSigma*theRMSValues[i])
149 && ( j >= nSamples-1 || std::abs(theSamples[i][j+1] - theSamples[i][0]) <= m_nSigma*theRMSValues[i])) ) {
150
151 if ( lchimin < 0 )
152 nTotSamples ++;
153 lchitest += pow((theSamples[i][j] - thePedestals[i]
154 - theChannelAmplitudes[i]*sin(j*25*ns*m_omega
155 +theChannelPhases[i]+myEventPhase))
156 /theRMSValues[i],2);
157 }
158 }
159 }
160 if ( lchitest < lchimin || lchimin < 0 ) {
161 lchimin = lchitest;
162 m_eventPhase = myEventPhase;
163 }
164 }
165
166 ATH_MSG_DEBUG ( "Ending eventphase calculation. Phase = <" << m_eventPhase << ">, Number of Channels used = <" << iHECChan << ">, Average Number of Samples Used = <"
167 << (iHECChan > 0 ? (double)nTotSamples/iHECChan : 0)
168 << ">" );
169 return StatusCode::SUCCESS;
170}
171
172
174{
175 ATH_MSG_DEBUG ( "In execute: correct LAr Digit" );
176
177 //Pointer to conditions data objects to get channel phases
178 const ILArH6Oscillation* larH6Oscillations = nullptr;
179 ATH_CHECK( detStore()->retrieve(larH6Oscillations) );
180
181 std::vector<double> theChannelAmplitudes;
182 std::vector<double> theChannelPhases;
183
184 //Now all data is available, start loop over Digit Container
185 ATH_MSG_DEBUG ( "Loop over Digit Container " );
186
188 const LArOnOffIdMapping* cabling{*cablingHdl};
189 if(!cabling) {
190 ATH_MSG_ERROR("Do not have mapping object " << m_cablingKey.key() );
191 return StatusCode::FAILURE;
192 }
193
194 for (unsigned int i=0;i<theDC.size();i++) {
195 //Get data from LArDigit
196 LArDigit * theDigit = theDC[i];
197 const std::vector<short>& samples = theDigit->samples();
198 unsigned int nSamples = samples.size();
199 const HWIdentifier chid = theDigit->channelID();
200 const CaloGain::CaloGain gain = theDigit->gain();
201
202 // correct only HEC channels
203 const Identifier id = cabling->cnvToIdentifier(chid);
204 bool isHEC = false;
205
206 if (m_hecId->is_lar_hec(id)) {
207 isHEC = true;
208 }
209
210 if ( isHEC) {
211 const double& DBchannelPhase=larH6Oscillations->channelPhase(chid);
212 const double& DBchannelAmplitude=larH6Oscillations->channelAmplitude(chid);
213 ATH_MSG_DEBUG ( "The HWId is " << chid
214 << ", the offline Id is " << m_hecId->show_to_string(id,nullptr,'/')
215 << ", the ChannelAmplitude is " << DBchannelAmplitude
216 << ", the ChannelPhase is " << DBchannelPhase );
217 ATH_MSG_DEBUG ( "m_omega value is " << m_omega );
218 if( DBchannelAmplitude>0 ) {
219 std::vector<short> new_samples(nSamples);
220 for(unsigned int j=0;j<nSamples;j++)
221 new_samples[j] = (short)(samples[j] + 0.5
222 - DBchannelAmplitude*sin(j*25*ns*m_omega+DBchannelPhase+m_eventPhase));
223 HWIdentifier new_id(chid);
224 CaloGain::CaloGain new_gain(gain);
225 LArDigit * theNewDigit = new LArDigit(new_id,new_gain,new_samples);
226 theDC[i] = theNewDigit;
227 }
228 }
229 }
230 return StatusCode::SUCCESS;
231}
232
233
234void LArDigitOscillationCorrTool::handle(const Incident& /* inc*/ )
235{
236 ATH_MSG_DEBUG ( "LArDigitOscillationCorrTool handle()" );
237
238 this->retrieveDB().ignore();
239}
240
241// *** retrieve subfactors from the DB ***
243{
244 ATH_MSG_DEBUG ( "in retrieveDB() " );
245 return StatusCode::SUCCESS;
246}
247
248
#define M_PI
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
constexpr int pow(int base, int exp) noexcept
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
const LArFCAL_ID * fcal_idHelper() const
access to FCAL idHelper
Definition CaloCell_ID.h:75
const LArEM_ID * em_idHelper() const
access to EM idHelper
Definition CaloCell_ID.h:63
const LArHEC_ID * hec_idHelper() const
access to HEC idHelper
Definition CaloCell_ID.h:69
size_type size() const noexcept
Returns the number of elements in the collection.
virtual const double & channelPhase(const HWIdentifier &id) const =0
virtual const double & channelAmplitude(const HWIdentifier &id) const =0
access to channel amplitude index by Identifier
virtual float pedestal(const HWIdentifier &id, int gain) const =0
virtual float pedestalRMS(const HWIdentifier &id, int gain) const =0
access to RMS of Pedestal index by Identifier, and gain setting
Container class for LArDigit.
StatusCode correctLArDigits(LArDigitContainer &theDC) override
virtual StatusCode initialize() override
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
StatusCode calculateEventPhase(const LArDigitContainer &theDC) override
virtual void handle(const Incident &) override
LArDigitOscillationCorrTool(const std::string &type, const std::string &name, const IInterface *parent)
Liquid Argon digit base class.
Definition LArDigit.h:25
CaloGain::CaloGain gain() const
Definition LArDigit.h:72
const std::vector< short > & samples() const
Definition LArDigit.h:78
const HWIdentifier & channelID() const
Definition LArDigit.h:69