ATLAS Offline Software
Loading...
Searching...
No Matches
TBLArRawChannelBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <cmath>
9
10
11using CLHEP::MeV;
12using CLHEP::nanosecond;
13
14
15TBLArRawChannelBuilder::TBLArRawChannelBuilder (const std::string& name, ISvcLocator* pSvcLocator):
16 AthAlgorithm(name, pSvcLocator),
17 m_emId(0),
18 m_fcalId(0),
19 m_hecId(0),
21 m_DataLocation("FREE"),
22 m_ChannelContainerName("LArRawChannels"),
28 m_iPedestal(0) // jobO ?
29{
30 //m_useIntercept={false,false,false,false};
31 declareProperty("LArRawChannelContainerName",m_ChannelContainerName);
32 declareProperty("DataLocation", m_DataLocation );
33 declareProperty("maxSamp",m_imaxSamp=8);
34 declareProperty("RecoMode",m_mode="CUBIC");
35 declareProperty("CubicAdcCut",m_cubicAdcCut=50.0);
36}
37
39 ATH_MSG_DEBUG ( "In Initialize." );
40
41 const CaloCell_ID* caloId = nullptr;
42 ATH_CHECK( detStore()->retrieve (caloId, "CaloCell_ID") );
43 m_emId=caloId->em_idHelper();
44 m_fcalId=caloId->fcal_idHelper();
45 m_hecId=caloId->hec_idHelper();
46
47 ATH_CHECK( m_cablingKey.initialize() );
48
49 ATH_CHECK( detStore()->retrieve(m_onlineHelper, "LArOnlineID") );
50
51 m_ADCtoMeVFCAL[0] = 87.0 * MeV; // FCAL1 High gain
52 m_ADCtoMeVFCAL[1] = 117.0 * MeV; // FCAL2 High gain
53 m_ADCtoMeVFCAL[2] = 193.0 * MeV; // FCAL3 High gain
54 m_ADCtoMeVHEC[0] = 136.0 / 9.8 * MeV; // HEC 1 Medium gain from Monika. Need / 9.8 ??
55 m_ADCtoMeVHEC[1] = 136.0 / 9.8 * MeV; // HEC 2 Medium gain from Monika. Need / 9.8 ??
56 m_ADCtoMeVEMECInner[0] = 25.22 * MeV; // EMEC High gain from Pascal, approximate
57 m_ADCtoMeVEMECInner[1] = 19.4 * MeV; // EMEC High gain from Pascal, approximate
58 m_ADCtoMeVEMECOuter[0] = 16.0 * MeV; // EMEC High gain from Monika, approximate
59 m_ADCtoMeVEMECOuter[1] = 16.0 * MeV; // EMEC High gain from Monika, approximate
60 m_ADCtoMeVEMB[0] = 15.0 * MeV; // EMB High gain from Isabelle, approximate
61 m_ADCtoMeVEMB[1] = 15.0 * MeV; // EMB High gain from Isabelle, approximate
62
63 return StatusCode::SUCCESS;
64}
65
66
68 ATH_MSG_DEBUG ( "In execute" );
69
71 const LArOnOffIdMapping* cabling{*cablingHdl};
72 if(!cabling) {
73 ATH_MSG_ERROR( "Do not hame cabling mapping from key " << m_cablingKey.key() );
74 return StatusCode::FAILURE;
75 }
76
77 //Pointer to input data container
78 const LArDigitContainer* digitContainer;//Pointer to LArDigitContainer
79
80 //Retrieve Digit Container
81 ATH_CHECK( evtStore()->retrieve(digitContainer,m_DataLocation) );
82 ATH_MSG_DEBUG ( "1) LArDigitContainer container size = " << digitContainer->size() );
83
84 ATH_MSG_DEBUG ( "2) LArDigitContainer container size = " << digitContainer->size() );
85 if( digitContainer->size() < 1 ) {
86 ATH_MSG_INFO ( "Empty LArDigitContainer container." );
87 return StatusCode::SUCCESS;
88 }
89
90 //Prepare LArRawChannelContainer
91 ATH_MSG_DEBUG ( "Making new LArRawChannelContainer " << digitContainer->size() );
92 LArRawChannelContainer* larRawChannelContainer=new LArRawChannelContainer();
93 larRawChannelContainer->reserve(digitContainer->size());
94 ATH_CHECK( evtStore()->record(larRawChannelContainer,m_ChannelContainerName) );
95
96 //Now all data is available, start loop over Digit Container
97 ATH_MSG_DEBUG ( "Loop over Digit Container " );
98
99 for (const LArDigit* digit : *digitContainer) {
100
101 //Get data from LArDigit
102 const std::vector<short>& samples = digit->samples();
103 unsigned int nSamples = samples.size();
104 const HWIdentifier chid = digit->channelID();
105 const CaloGain::CaloGain gain = digit->gain();
106
107 //>>>> PL June 20, 2004: subtract pedestal first, assume first sample ->JO?
108 std::vector<float> mySamples;
109 mySamples.resize(samples.size());
110 // FIXME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! only for 5 leading noise samples!
111 float thePedestal = (float)samples[m_iPedestal];
112 // log << MSG::INFO
113 // << "pedestal " << thePedestal << endmsg;
114 for ( unsigned int i=0; i<samples.size(); i++ )
115 {
116 mySamples[i] = ((float)samples[i]) - thePedestal;
117 }
118 //<<<<
119
120 float GainFactor;
121 if( gain == CaloGain::LARLOWGAIN ) {
122 GainFactor = 9.8*9.8;
123 } else if (gain == CaloGain::LARMEDIUMGAIN ) {
124 GainFactor = 9.8;
125 } else if (gain == CaloGain::LARHIGHGAIN ) {
126 GainFactor = 1.0;
127 } else {
128 GainFactor = 1.0;
129 ATH_MSG_ERROR ( "Channel " << chid << "unknown gain: " << gain );
130 }
131
132 // Find peak time sample
133 float maxADCPeak = 0.;
134 unsigned int iPeakSamp = 0;
135 for( unsigned i=0;i<nSamples;i++ ) {
136 if ( maxADCPeak < mySamples[i] )
137 {
138 maxADCPeak = mySamples[i];
139 iPeakSamp = i;
140 }
141 }
142
143 bool CubicFailed = false;
144 float ADCPeak=0.;
145 float time=-999.;
146
147 // maximum amplitude/variable time slice method
148 if( m_mode == "MAX" )
149 {
150 ADCPeak = maxADCPeak;
151 time = ((float)iPeakSamp+0.5) * 25.0 * nanosecond;
152 }
153
154 // cubic extrapolation for selected channels
155 else if ( m_mode == "CUBIC" &&
156 ! ( CubicFailed = maxADCPeak <= m_cubicAdcCut ) )
157 {
158 // linear extrapolation table
159 unsigned int it0;
160 const float invT[4][4]
161 = { { 1, 0, 0, 0},
162 { -1.83333, 3, -1.5, 0.333333},
163 { 1, -2.5, 2, -0.5},
164 {-0.166666, 0.5, -0.5, 0.166666} };
165
166 // peak slice very early
167 if ( iPeakSamp <= 1 )
168 {
169 it0 = m_iPedestal + 1;
170 }
171 // peak slice very late
172 else if ( iPeakSamp >= nSamples - 2 )
173 {
174 it0 = nSamples - 4;
175 }
176 // peak in safe region
177 else
178 {
179 it0 = ( mySamples[iPeakSamp-2] > mySamples[iPeakSamp+2] )
180 ? iPeakSamp - 2
181 : iPeakSamp - 1;
182 }
183
184 // 4 samples to be used start at 0 <= t0 <= nsamples-4
185 float A[4] = {0, 0, 0, 0};
186 float dtmax = 0.0;
187 float disc;
188 // S = TA -> A = inv(T)S
189 for (int ia = 0; ia < 4; ia++)
190 for (int it = 0; it < 4; it++)
191 A[ia] += invT[ia][it] * mySamples[it0+it];
192
193 // fit parameters
194 disc = A[2]*A[2] - 3*A[1]*A[3];
195 if ( ! ( CubicFailed = ( disc < 0 || A[3] == 0 ) ) )
196 {
197 dtmax = (-A[2]-sqrt(disc))/(3*A[3]);
198 if ( ! ( CubicFailed = ( dtmax < 0 || dtmax > 3 ) ) )
199 {
200 time = (float(it0) + dtmax) * 25.0 * nanosecond; // nsec
201 for(int ia = 0; ia < 4; ia++)
202 ADCPeak += A[ia] * pow(dtmax, ia);
203 }
204 }
205 }
207 ( "Flag: "
208 << CubicFailed
209 << " Mode: "
210 << m_mode
211 << " Signal: "
212 << ADCPeak
213 << " Peak: "
214 << maxADCPeak
215 );
216
217 // fixed time slice or insufficient signal for cubic fit
218 if(m_mode == "FIXED" || CubicFailed )
219 {
220 ADCPeak = mySamples[m_imaxSamp];
221 time = (float(m_imaxSamp)+0.5) * 25.0 * nanosecond;
222 }
223
224
225 // Now must get subdetector ID and feed in here ...
226 float ADCtoMeV = 10.0;
227 const Identifier id = cabling->cnvToIdentifier(chid);
228 if (m_emId->is_em_barrel(id)) {
229 // m_emId->sampling(id);
230 ADCtoMeV = m_ADCtoMeVEMB[0];
231 ATH_MSG_DEBUG ( " in EMB s="<<m_emId->sampling(id)<<", using ADCtoMeV = " << ADCtoMeV );
232 } else if (m_emId->is_em_endcap_inner(id)) {
233 int samp = m_emId->sampling(id);
234 if (samp > 0) {
235 ADCtoMeV = m_ADCtoMeVEMECInner[samp-1];
236 ATH_MSG_DEBUG ( " in EMEC inner s="<<m_emId->sampling(id)<<", using ADCtoMeV = " << ADCtoMeV );
237 }
238 } else if (m_emId->is_em_endcap_outer(id)) {
239 int samp = m_emId->sampling(id);
240 if (samp > 0) {
241 ADCtoMeV = m_ADCtoMeVEMECOuter[samp-1];
242 ATH_MSG_DEBUG ( " in EMEC outer s="<<m_emId->sampling(id)<<", using ADCtoMeV = " << ADCtoMeV );
243 }
244 } else if (m_fcalId->is_lar_fcal(id)) {
245 int module = m_fcalId->module(id);
246 if (module > 0) {
247 ADCtoMeV = m_ADCtoMeVFCAL[module-1];
248 ATH_MSG_DEBUG ( " in FCAL m=" << m_fcalId->module(id)<<", using ADCtoMeV = " << ADCtoMeV );
249 }
250 } else if (m_hecId->is_lar_hec(id)) {
251 // m_layer[m_cellIndex]=m_hecId->sampling(id);
252 ADCtoMeV = m_ADCtoMeVHEC[0];
253 ATH_MSG_DEBUG ( " in HEC s="<<m_hecId->sampling(id)<<", using ADCtoMeV = " << ADCtoMeV );
254 }
255
256 float Energy = ADCPeak * ADCtoMeV * GainFactor;
257 uint16_t quality=0;
258 uint16_t provenance=0x2000;
259
260 //Make LArRawChannel Object with new data
261 LArRawChannel larRawChannel(chid,(int)Energy,(int)time,quality, provenance, gain);
262 larRawChannelContainer->add(larRawChannel); //Add to container
263
264 }// End loop over LArDigits
265
266 ATH_MSG_DEBUG ( "Finished loop over Digit Container " );
267
268 // larRawChannelContainer->print();
269
270 ATH_MSG_DEBUG ( "sorted RawChannelContainer, now lock it " );
271 // lock raw channel container
272 ATH_CHECK( evtStore()->setConst(larRawChannelContainer) );
273
274 return StatusCode::SUCCESS;
275}
276
278{
279 ATH_MSG_INFO ( "TBLArRawChannelBuilder finished." );
280 return StatusCode::SUCCESS;
281}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
std::vector< double > Energy
Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Old LArRawChannelContainer
Definition LArTPCnv.cxx:86
constexpr int pow(int base, int exp) noexcept
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
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.
Container class for LArDigit.
Liquid Argon digit base class.
Definition LArDigit.h:25
Container for LArRawChannel (IDC using LArRawChannelCollection)
void add(const LArRawChannel &rc)
Liquid Argon ROD output object base class.
virtual StatusCode execute() override
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
virtual StatusCode initialize() override
virtual StatusCode finalize() override
TBLArRawChannelBuilder(const std::string &name, ISvcLocator *pSvcLocator)
const LArOnlineID * m_onlineHelper
@ LARMEDIUMGAIN
Definition CaloGain.h:18
@ LARLOWGAIN
Definition CaloGain.h:18
@ LARHIGHGAIN
Definition CaloGain.h:18
hold the test vectors and ease the comparison