ATLAS Offline Software
Loading...
Searching...
No Matches
CscDigitToCscRDOTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cassert>
8#include <cmath>
9
11#include "CLHEP/Random/RandFlat.h"
12#include "CLHEP/Random/RandGaussZiggurat.h"
13#include "CLHEP/Random/RandomEngine.h"
14#include "CscRODReadOut.h"
15#include "GaudiKernel/ISvcLocator.h"
16#include "GaudiKernel/StatusCode.h"
20
21const uint16_t MAX_AMPL = 4095; // 12-bit ADC
22
25
26CscDigitToCscRDOTool::CscDigitToCscRDOTool(const std::string& type, const std::string& name, const IInterface* pIID) :
27 base_class(type, name, pIID) {
28 declareProperty("NumSamples", m_numSamples);
29 declareProperty("Latency", m_latency);
30 declareProperty("addNoise", m_addNoise);
31}
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
34
36 ATH_MSG_DEBUG(" in initialize()");
37
38 ATH_CHECK(m_cscCablingSvc.retrieve());
39
40 ATH_CHECK(m_idHelperSvc.retrieve());
41 ATH_MSG_DEBUG(" Found the CscIdHelper. ");
42
44 ATH_CHECK(m_cscCalibTool.retrieve());
45
46 m_startTime = m_cscCalibTool->getTimeOffset(); // StartTime=46.825,
47 ATH_MSG_INFO(" m_startTims is set to be " << m_startTime << "from cscCalibTool->getTimeOffset()");
48
49 // random number initialization
50 ATH_CHECK(m_rndmSvc.retrieve());
51
53 uint16_t samplingTime = static_cast<uint16_t>(m_cscCalibTool->getSamplingTime()); // FIXME
54 m_samplingRate = int(1000 / samplingTime);
55 m_signalWidth = m_cscCalibTool->getSignalWidth();
56
57 m_numberOfIntegration = static_cast<uint16_t>(m_cscCalibTool->getNumberOfIntegration()); // 12
58
59 ATH_CHECK(m_rdoContainerKey.initialize());
60 ATH_CHECK(m_digitContainerKey.initialize());
61
62 return StatusCode::SUCCESS;
63}
64
65StatusCode CscDigitToCscRDOTool::digitize(const EventContext& /*ctx*/) {
66 ATH_MSG_DEBUG("in execute()");
67
68 if (fill_CSCdata().isFailure()) ATH_MSG_ERROR(" CscDigitToCscRdo failed to execute ");
69
70 ATH_MSG_DEBUG("done execute()");
71 return StatusCode::SUCCESS;
72}
73
75 ATH_MSG_DEBUG("fill_CSCdata");
76
77 // according to cosmic data ~33% is phase =1 peak close to 3rd...
78 // but let's start with half and half
79
80 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
81 rngWrapper->setSeed(name(), Gaudi::Hive::currentContext());
82 CLHEP::HepRandomEngine* rndmEngine = *rngWrapper;
83
85 // initialization but it will be updated per channel later 12/03/2009 WP
86 // m_startTime is not related to rodReadOut at all but doesn't matter it's not used....by resetting later...
87
88 rodReadOut.set(&m_idHelperSvc->cscIdHelper());
89 rodReadOut.setChamberBitVaue(1);
90
92 ATH_CHECK(rdoContainer.record(std::make_unique<CscRawDataContainer>()));
93
95 m_cscRdoMap.clear();
96
98 typedef CscDigitContainer::const_iterator collection_iterator;
99 typedef CscDigitCollection::const_iterator digit_iterator;
100
103
105 collection_iterator it_coll = container->begin();
106 collection_iterator it_coll_e = container->end();
107
108 for (; it_coll != it_coll_e; ++it_coll) {
109 const CscDigitCollection* cscCollection = *it_coll;
110
112 int oldLayer = 0;
113
115 uint32_t address = 0x0;
116
118 uint16_t width = 0x0;
119
121 std::vector<uint16_t> samples;
122 samples.clear();
123
125 IdentifierHash cscRawDataOfflineHashId;
126
130 uint16_t spuID = 0x0;
131
133 digit_iterator it_dig = cscCollection->begin();
134 digit_iterator it_dig_e = cscCollection->end();
135
137 int oldStrip = -1;
138 unsigned int count = 0;
139 unsigned int size = cscCollection->size();
140
141 for (; it_dig != it_dig_e; ++it_dig) {
142 const CscDigit* cscDigit = *it_dig;
143
144 bool IsNewEDM = (cscDigit->sampleCharges()).size() != 0;
145
146 count++;
147
148 // There is no difference between online and offline except wheel A(+Z) Phi strips...
149 // Where address is made, onlineId should be used......
150 Identifier offlineChannelId = cscDigit->identify();
151 IdentifierHash cscOfflineChannelHashId;
152 IdContext cscContext = m_idHelperSvc->cscIdHelper().channel_context();
153 if (!m_idHelperSvc->cscIdHelper().get_hash(offlineChannelId, cscOfflineChannelHashId, &cscContext)) {
154 ATH_MSG_DEBUG("HashId for CscDigit (offline) is "
155 << cscOfflineChannelHashId << " for "
156 << m_idHelperSvc->cscIdHelper().show_to_string(offlineChannelId, &cscContext));
157 }
158
159 int currentStrip = m_idHelperSvc->cscIdHelper().strip(offlineChannelId);
160
162 int currentLayer = m_idHelperSvc->cscIdHelper().wireLayer(offlineChannelId);
163 int measuresPhi = m_idHelperSvc->cscIdHelper().measuresPhi(offlineChannelId);
164 int eta = m_idHelperSvc->cscIdHelper().stationEta(offlineChannelId);
165 int phi = m_idHelperSvc->cscIdHelper().stationPhi(offlineChannelId);
166 int stationId = m_idHelperSvc->cscIdHelper().stationName(offlineChannelId);
167 uint16_t subDetectorId = (eta == -1) ? 0x6A : 0x69;
168 uint16_t rodId = 0xFFFF;
169 if (m_cscCablingSvc->nROD() == 16) {
170 if (stationId == 0x32) rodId = (0x10 | (phi - 1));
171 if (stationId == 0x33) rodId = (0x18 | (phi - 1));
172 } else {
173 rodId = uint16_t(phi - 1);
174 }
175 CscRawDataCollection* cscRdoCollection = this->cscRdo(subDetectorId, rodId);
176
177 if (IsNewEDM) {
178 if (cscCollection->samplingPhase()) {
179 ATH_MSG_DEBUG("There is OddPhase DigitCollection");
180 cscRdoCollection->set_samplingPhase();
181 }
182 } else {
183 double flat = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0); // for other particles
184 if (flat < 0.5) cscRdoCollection->set_samplingPhase();
185 }
186
188 uint8_t calLayer = 0x0;
189 bool sparsified = true;
190 bool neutron = false;
191 uint8_t calAmplitude = 0x0;
192 bool enableCal = false;
193
194 uint32_t eventType = (m_numSamples & 0xff) | ((m_latency & 0xff) << 8) | ((calLayer & 0x3f) << 16) | ((sparsified & 1) << 22) |
195 ((neutron & 1) << 23) | ((calAmplitude & 0x3f) << 24) | ((enableCal & 1) << 30) |
196 ((m_samplingRate == 20 ? 0u : 1u) << 31);
197
198 cscRdoCollection->set_eventType(eventType);
199
201 uint16_t collId = cscRdoCollection->identify();
202
205 // if ( oldLayer != currentLayer ) {
206 // oldLayer = currentLayer;
207 //}
208
209 if (currentStrip != (oldStrip + 1) || currentLayer != oldLayer) {
210 if (currentLayer != oldLayer) oldLayer = currentLayer;
211
213 if (width > 0) {
214 int mphi = ((address & 0x00000100) >> 8);
215 int zEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
216
217 if (zEta > 0 && mphi == 1) {
218 int istat = ((address & 0x00010000) >> 16) + 50;
219 int phisector = ((address & 0x0000E000) >> 13) + 1;
220 int chamLayer = ((address & 0x00000800) >> 11) + 1;
221 int wlayer = ((address & 0x00000600) >> 9) + 1;
222
223 int beforestrip = (address & 0x000000FF) + 1;
224 int afterstrip = beforestrip - width + 1;
225
226 Identifier newOnlineChannelId =
227 m_idHelperSvc->cscIdHelper().channelID(istat, zEta, phisector, chamLayer, wlayer, mphi, afterstrip);
228 address = rodReadOut.address(newOnlineChannelId, zEta, phisector);
229 }
230
231 ATH_MSG_DEBUG("At Creation of CscRawData, SPU ID = " << spuID);
232 CscRawData* rawData = new CscRawData(samples, address, collId, spuID, width);
233 uint32_t hashId = static_cast<uint32_t>(cscRawDataOfflineHashId);
234 rawData->setHashID(hashId);
235 cscRdoCollection->push_back(rawData);
236 }
237
239 int stationName = m_idHelperSvc->cscIdHelper().stationName(offlineChannelId);
243 if (measuresPhi == 0)
244 spuID = static_cast<uint16_t>((stationName - 50) * 5 + currentLayer - 1);
245 else
246 spuID = static_cast<uint16_t>(((stationName - 50) + 1) * 5 - 1);
247 ATH_MSG_DEBUG("SPU ID = " << spuID);
248
249 // There is no difference between online and offline except wheel A(+Z) Phi strips...
250 // Where address is made, onlineId should be used......
251 // Let's make online hashId first and then convert it into online identifier....
252 Identifier onlineChannelId = offlineChannelId; // onlineChannelId is only needed to get address....
253 if (eta > 0 && measuresPhi == 1) {
254 int chamberLayer = m_idHelperSvc->cscIdHelper().chamberLayer(offlineChannelId); // Either 1 or 2 (but always 1)
255 int strip = 49 - currentStrip;
256
257 onlineChannelId =
258 m_idHelperSvc->cscIdHelper().channelID(stationName, eta, phi, chamberLayer, currentLayer, measuresPhi, strip);
259 }
260 // this registers the first one...
262 address = rodReadOut.address(onlineChannelId, eta, phi);
263
265 IdContext cscContext = m_idHelperSvc->cscIdHelper().channel_context();
266 if (!m_idHelperSvc->cscIdHelper().get_hash(offlineChannelId, cscRawDataOfflineHashId, &cscContext)) {
267 ATH_MSG_DEBUG("HashId off CscRawData (still offline hashId) is "
268 << cscRawDataOfflineHashId << " for "
269 << m_idHelperSvc->cscIdHelper().show_to_string(offlineChannelId, &cscContext));
270 }
271
273 width = 0x0;
274 samples.clear();
275 }
276
278 ATH_MSG_DEBUG("CSC Digit->RDO: Digit offline info " << m_idHelperSvc->cscIdHelper().show_to_string(offlineChannelId) << " "
279 << cscDigit->charge());
280
281 int zsec = m_idHelperSvc->cscIdHelper().stationEta(offlineChannelId);
282 int phisec = m_idHelperSvc->cscIdHelper().stationPhi(offlineChannelId);
283 int istation = m_idHelperSvc->cscIdHelper().stationName(offlineChannelId) - 49;
284 int sector = zsec * (2 * phisec - istation + 1);
285 int wlay = m_idHelperSvc->cscIdHelper().wireLayer(offlineChannelId);
286 int measphi = m_idHelperSvc->cscIdHelper().measuresPhi(offlineChannelId);
287 int istrip = m_idHelperSvc->cscIdHelper().strip(offlineChannelId);
288
289 // false will return value in ADC counts - true in number of electrons
290 // double noise = m_cscCalibTool->stripNoise( cscOfflineChannelHashId, true );
291 double noiseADC = m_cscCalibTool->stripNoise(cscOfflineChannelHashId, false);
292 // double pedestal = m_cscCalibTool->stripPedestal( cscOfflineChannelHashId, true );
293 double pedestalADC = m_cscCalibTool->stripPedestal(cscOfflineChannelHashId, false);
294 double phaseOffset = (cscRdoCollection->samplingPhase()) ? 25 : 0;
295
296 if (IsNewEDM) {
297 std::vector<float> cscDigitSamples = cscDigit->sampleCharges();
298
299 for (int i = 0; i < m_numSamples; i++) {
300 // double samplingTime = (i+1)*(1000/m_samplingRate) + m_startTime;// considered in CSC_Digitization
301 double theNoise = (m_addNoise) ? CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, noiseADC) : 0.0;
302 double rawAmpl = cscDigitSamples[i];
303 double ampl = rawAmpl;
304 double charge_to_adcCount =
305 m_cscCalibTool->numberOfElectronsToADCCount(cscOfflineChannelHashId, ampl) + theNoise + pedestalADC;
306
307 if (charge_to_adcCount > MAX_AMPL) charge_to_adcCount = MAX_AMPL - 1.0;
308 if (charge_to_adcCount < 0) charge_to_adcCount = 0;
309
310 uint16_t adcCount = (uint16_t)rint(charge_to_adcCount);
311
312 samples.push_back(adcCount);
313
314 ATH_MSG_DEBUG("amplitude :: index = " << (i + 1)
315 // << " NA/sampling time (ns) = " << samplingTime
316 << " charge to ADC = "
317 << charge_to_adcCount
318 // << " amplitude (double) = " << ampl
319 << " raw amplitude (double) = " << rawAmpl << " theNoise (ADC) = " << theNoise);
320 }
321 } else {
322 double charge_to_adcCount = m_cscCalibTool->numberOfElectronsToADCCount(cscOfflineChannelHashId, cscDigit->charge());
323 // if ( charge_to_adcCount > MAX_AMPL/2.0 ) charge_to_adcCount = MAX_AMPL/2.0-1.0;
324
325 rodReadOut.setParams(cscDigit->time() + phaseOffset, m_signalWidth);
326
327 for (int i = 0; i < m_numSamples; i++) {
328 double samplingTime = (i + 1) * (1000 / m_samplingRate) + m_startTime;
329 double theNoise = (m_addNoise) ? CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, noiseADC) : 0.0;
330 double rawAmpl = rodReadOut.signal_amplitude(samplingTime); // FIXME - to be updated still!
331 double ampl = charge_to_adcCount * rawAmpl + theNoise + pedestalADC;
332
333 if (ampl > MAX_AMPL) ampl = MAX_AMPL - 1.0;
334
335 uint16_t adcCount = (uint16_t)rint(ampl);
336
337 samples.push_back(adcCount);
338
339 ATH_MSG_DEBUG("amplitude :: index = " << (i + 1) << " sampling time (ns) = " << samplingTime
340 << " charge to ADC (double) = " << charge_to_adcCount
341 << " amplitude (double) = " << ampl << " raw amplitude (double) = " << rawAmpl
342 << " theNoise (double) = " << theNoise);
343 }
344
345 } // isNewEDM
346
347 ATH_MSG_DEBUG("CSC Digit zsec:phisec:station:sector:measphi:wlay:istrip:charge "
348 << zsec << " " << phisec << " " << istation << " " << sector << " " << measphi << " " << wlay << " " << istrip
349 << " " << samples[0] << " " << samples[1] << " " << samples[2] << " " << samples[3] << " ");
350
352 width++;
353 oldStrip = currentStrip;
354
355 if (count == size) { // digicount in digiCollection equals to size of digicollection...
356
358 ATH_MSG_DEBUG("End of DigitCollection : SPU ID = " << spuID);
359 uint16_t rpuID = 0x0;
360 if (spuID <= 4)
361 rpuID = 5;
362 else if (spuID > 4 && spuID <= 9)
363 rpuID = 11;
364 else
365 ATH_MSG_ERROR("SPU ID out of range " << spuID);
366 cscRdoCollection->addRPU(rpuID);
367 cscRdoCollection->addDataType(0x0);
368 ATH_MSG_DEBUG("RPU id = " << rpuID);
369
370 int mphi = ((address & 0x00000100) >> 8);
371 int zEta = (((address & 0x00001000) >> 12) == 0x0) ? -1 : 1;
372
373 if (zEta > 0 && mphi == 1) {
374 int istat = ((address & 0x00010000) >> 16) + 50;
375 int phisector = ((address & 0x0000E000) >> 13) + 1;
376 int chamLayer = ((address & 0x00000800) >> 11) + 1;
377 int wlayer = ((address & 0x00000600) >> 9) + 1;
378
379 int beforestrip = (address & 0x000000FF) + 1;
380 int afterstrip = beforestrip - width + 1;
381
382 Identifier newOnlineChannelId =
383 m_idHelperSvc->cscIdHelper().channelID(istat, zEta, phisector, chamLayer, wlayer, mphi, afterstrip);
384 address = rodReadOut.address(newOnlineChannelId, zEta, phisector);
385 }
386
388 uint32_t hashId = static_cast<uint32_t>(cscRawDataOfflineHashId);
389 CscRawData* rawData = new CscRawData(samples, address, collId, spuID, width);
390 rawData->setHashID(hashId);
391 cscRdoCollection->push_back(rawData);
392 }
393
394 } // Loop over CscDigit
395 } // Loop over CscDigitCollection...
396
397 ATH_MSG_DEBUG("Adding RDOs to the RdoContainer");
399 std::map<uint16_t, CscRawDataCollection*>::iterator itM = m_cscRdoMap.begin();
400 std::map<uint16_t, CscRawDataCollection*>::iterator itM_e = m_cscRdoMap.end();
401 for (; itM != itM_e; ++itM) {
403 uint16_t clusterCounts[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
404 CscRawDataCollection::const_iterator itD = (itM->second)->begin();
405 CscRawDataCollection::const_iterator itD_e = (itM->second)->end();
406 for (; itD != itD_e; ++itD) {
407 uint16_t spuID = (*itD)->rpuID();
408 clusterCounts[spuID] += 1;
409 }
410 for (unsigned int i = 0; i < 10; ++i) (itM->second)->set_spuCount(i, clusterCounts[i]);
411
413 ATH_CHECK(rdoContainer->addCollection(itM->second, itM->first));
414 }
415 ATH_MSG_DEBUG("Added RDOs to the RdoContainer");
416
417 return StatusCode::SUCCESS;
418}
419
420CscRawDataCollection* CscDigitToCscRDOTool::cscRdo(uint16_t subDetectorId, uint16_t rodId) {
421 ATH_MSG_DEBUG("cscRdo Begin!");
422
423 uint16_t onlineColId = m_cscCablingSvc->collectionId(subDetectorId, rodId);
424 ATH_MSG_DEBUG("This collection online identifier is " << onlineColId);
425
426 // assert (onlineColId <= 15);
427
428 std::map<uint16_t, CscRawDataCollection*>::iterator it = m_cscRdoMap.find(onlineColId);
429 if (it != m_cscRdoMap.end()) { return (*it).second; }
430
432 CscRawDataCollection* rdo = new CscRawDataCollection(onlineColId);
433 m_cscRdoMap[onlineColId] = rdo;
434
436 rdo->setSubDetectorId(subDetectorId);
437 uint16_t onlineRodId = 0x0;
438 bool check = m_cscCablingSvc->onlineId(rodId, onlineRodId);
439 if (!check) ATH_MSG_ERROR("Enable to convert offline ROD Id to online ROD id");
440 ATH_MSG_DEBUG("online ROD id = " << onlineRodId << " offline ROD id " << rodId);
441 assert(m_cscCablingSvc->is_rodId(onlineRodId));
442 rdo->setRodId(onlineRodId);
443
444 return rdo;
445}
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_INFO(x)
#define ATH_MSG_DEBUG(x)
const uint16_t MAX_AMPL
Athena::TPCnvVers::Old Athena::TPCnvVers::Current CscRawDataCollection
const double width
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CscRawDataCollection * cscRdo(uint16_t subDetectorId, uint16_t rodId)
double m_startTime
set during initialize from cscCalibTool
uint16_t m_samplingRate
set during initialize from cscCalibTool
std::map< uint16_t, CscRawDataCollection * > m_cscRdoMap
CscDigitToCscRDOTool(const std::string &type, const std::string &name, const IInterface *pIID)
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service.
SG::WriteHandleKey< CscRawDataContainer > m_rdoContainerKey
virtual StatusCode initialize() override
ToolHandle< ICscCalibTool > m_cscCalibTool
SG::ReadHandleKey< CscDigitContainer > m_digitContainerKey
ServiceHandle< CSCcablingSvc > m_cscCablingSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
uint16_t m_numberOfIntegration
set during initialize from cscCalibTool
double m_signalWidth
set during initialize from cscCalibTool
virtual StatusCode digitize(const EventContext &ctx) override
int charge() const
Return the charge.
Definition CscDigit.h:42
const std::vector< float > & sampleCharges() const
Definition CscDigit.h:48
float time() const
return the time
Definition CscDigit.h:46
void setParams(double timeOffset, double signalWidth)
double signal_amplitude(double samplingTime) const
void set(const CscIdHelper *cscIdHelper)
void setChamberBitVaue(uint32_t value)
uint32_t address(const Identifier &channelId, int &eta, int &phi) const
Collection of CSC Raw Hits, arranged according to CSC Detector Elements Author: Ketevi A.
void set_eventType(const uint32_t eventType)
void setRodId(uint16_t rodId)
set methods - the name should be self-descriptive
void addDataType(const uint8_t dataType)
uint16_t identify() const
access methods
void addRPU(const uint16_t rpuID)
void setSubDetectorId(uint16_t subDetectorId)
Class to hold the electronic output for a single CSC readout channel: n sampling ADC data + the addre...
Definition CscRawData.h:21
void setHashID(uint32_t hash)
Definition CscRawData.h:121
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
Identifier identify() const
Definition MuonDigit.h:30
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146