ATLAS Offline Software
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 
11 using CLHEP::MeV;
12 using CLHEP::nanosecond;
13 
14 
15 TBLArRawChannelBuilder::TBLArRawChannelBuilder (const std::string& name, ISvcLocator* pSvcLocator):
16  AthAlgorithm(name, pSvcLocator),
17  m_emId(0),
18  m_fcalId(0),
19  m_hecId(0),
20  m_onlineHelper(0),
21  m_DataLocation("FREE"),
22  m_ChannelContainerName("LArRawChannels"),
23  m_ADCtoMeVFCAL(),
24  m_ADCtoMeVHEC(),
25  m_ADCtoMeVEMECInner(),
26  m_ADCtoMeVEMECOuter(),
27  m_ADCtoMeVEMB(),
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 
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 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
python.SystemOfUnits.nanosecond
int nanosecond
Definition: SystemOfUnits.py:119
CaloCell_ID::em_idHelper
const LArEM_ID * em_idHelper() const
access to EM idHelper
Definition: CaloCell_ID.h:63
AtlasDetectorID::is_lar_fcal
bool is_lar_fcal(Identifier id) const
Definition: AtlasDetectorID.h:839
TBLArRawChannelBuilder::m_mode
std::string m_mode
Definition: TBLArRawChannelBuilder.h:49
TBLArRawChannelBuilder::execute
virtual StatusCode execute() override
Definition: TBLArRawChannelBuilder.cxx:67
LArEM_Base_ID::is_em_endcap_outer
bool is_em_endcap_outer(const Identifier id) const
test if the id belongs to the EM Endcap outer wheel
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Energy
std::vector< double > Energy
Definition: CalibHitToCaloCell.h:23
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
TBLArRawChannelBuilder::initialize
virtual StatusCode initialize() override
Definition: TBLArRawChannelBuilder.cxx:38
skel.it
it
Definition: skel.GENtoEVGEN.py:396
LArFCAL_Base_ID::module
int module(const Identifier id) const
module [1,3]
LArEM_Base_ID::sampling
int sampling(const Identifier id) const
return sampling according to :
TBLArRawChannelBuilder::m_ADCtoMeVEMECInner
float m_ADCtoMeVEMECInner[2]
Definition: TBLArRawChannelBuilder.h:54
TBLArRawChannelBuilder::m_iPedestal
unsigned int m_iPedestal
Definition: TBLArRawChannelBuilder.h:58
TBLArRawChannelBuilder::finalize
virtual StatusCode finalize() override
Definition: TBLArRawChannelBuilder.cxx:277
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
HWIdentifier
Definition: HWIdentifier.h:13
TBLArRawChannelBuilder::TBLArRawChannelBuilder
TBLArRawChannelBuilder(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TBLArRawChannelBuilder.cxx:15
CaloCell_ID::hec_idHelper
const LArHEC_ID * hec_idHelper() const
access to HEC idHelper
Definition: CaloCell_ID.h:69
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
TBLArRawChannelBuilder::m_ADCtoMeVHEC
float m_ADCtoMeVHEC[2]
Definition: TBLArRawChannelBuilder.h:53
TBLArRawChannelBuilder::m_cubicAdcCut
float m_cubicAdcCut
Definition: TBLArRawChannelBuilder.h:50
python.PyAthena.module
module
Definition: PyAthena.py:131
AthCommonDataStore< AthCommonMsg< Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
A
TBLArRawChannelBuilder::m_ADCtoMeVEMB
float m_ADCtoMeVEMB[2]
Definition: TBLArRawChannelBuilder.h:56
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TBLArRawChannelBuilder::m_imaxSamp
int m_imaxSamp
Definition: TBLArRawChannelBuilder.h:48
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
LArDigit
Liquid Argon digit base class.
Definition: LArDigit.h:25
TBLArRawChannelBuilder::m_ADCtoMeVFCAL
float m_ADCtoMeVFCAL[3]
Definition: TBLArRawChannelBuilder.h:52
LArRawChannelContainer::add
void add(const LArRawChannel &rc)
Definition: LArRawChannelContainer.h:35
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArRawChannel
Liquid Argon ROD output object base class.
Definition: LArRawChannel.h:40
LArRawChannelContainer
Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Old LArRawChannelContainer
Definition: LArTPCnv.cxx:86
TBLArRawChannelBuilder::m_DataLocation
std::string m_DataLocation
Definition: TBLArRawChannelBuilder.h:47
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
TBLArRawChannelBuilder::m_onlineHelper
const LArOnlineID * m_onlineHelper
Definition: TBLArRawChannelBuilder.h:42
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TBLArRawChannelBuilder::m_hecId
const LArHEC_ID * m_hecId
Definition: TBLArRawChannelBuilder.h:41
TBLArRawChannelBuilder.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TBLArRawChannelBuilder::m_ChannelContainerName
std::string m_ChannelContainerName
Definition: TBLArRawChannelBuilder.h:47
AtlasDetectorID::is_lar_hec
bool is_lar_hec(Identifier id) const
Definition: AtlasDetectorID.h:829
CaloCell_ID
Helper class for offline cell identifiers.
Definition: CaloCell_ID.h:34
AthAlgorithm
Definition: AthAlgorithm.h:47
TBLArRawChannelBuilder::m_cablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Definition: TBLArRawChannelBuilder.h:37
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloGain::LARHIGHGAIN
@ LARHIGHGAIN
Definition: CaloGain.h:18
LArEM_Base_ID::is_em_endcap_inner
bool is_em_endcap_inner(const Identifier id) const
test if the id belongs to the EM Endcap inner wheel
CaloGain::CaloGain
CaloGain
Definition: CaloGain.h:11
CaloGain::LARMEDIUMGAIN
@ LARMEDIUMGAIN
Definition: CaloGain.h:18
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
LArEM_Base_ID::is_em_barrel
bool is_em_barrel(const Identifier id) const
test if the id belongs to the EM barrel
LArHEC_Base_ID::sampling
int sampling(const Identifier id) const
return sampling [0,3] (only 0 for supercells)
TBLArRawChannelBuilder::m_ADCtoMeVEMECOuter
float m_ADCtoMeVEMECOuter[2]
Definition: TBLArRawChannelBuilder.h:55
LArDigitContainer
Container class for LArDigit.
Definition: LArDigitContainer.h:24
LArDigits2NtupleDumper.nSamples
nSamples
Definition: LArDigits2NtupleDumper.py:70
CaloGain::LARLOWGAIN
@ LARLOWGAIN
Definition: CaloGain.h:18
TBLArRawChannelBuilder::m_fcalId
const LArFCAL_ID * m_fcalId
Definition: TBLArRawChannelBuilder.h:40
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
readCCLHist.float
float
Definition: readCCLHist.py:83
CaloCell_ID::fcal_idHelper
const LArFCAL_ID * fcal_idHelper() const
access to FCAL idHelper
Definition: CaloCell_ID.h:75
LArOnlineID.h
LArRawChannelContainer
Container for LArRawChannel (IDC using LArRawChannelCollection)
Definition: LArRawChannelContainer.h:26
LArOnOffIdMapping
Definition: LArOnOffIdMapping.h:20
Identifier
Definition: IdentifierFieldParser.cxx:14
TBLArRawChannelBuilder::m_emId
const LArEM_ID * m_emId
Definition: TBLArRawChannelBuilder.h:39