ATLAS Offline Software
Loading...
Searching...
No Matches
CscOverlay.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "CscOverlay.h"
6#include "MuonRDO/CscRawData.h"
11#include "CLHEP/Random/RandomEngine.h"
12#include "CLHEP/Random/RandGaussZiggurat.h"
13//
14#include "Identifier/Identifier.h"
15#include "Identifier/IdContext.h"
16//
17#include <set>
18#include <stdexcept> // for runtime_error
19#include <algorithm> // for max, min, lower_bound
20#include <cmath> // for std::rint
21#include <sstream> // for basic_ostringstream
22
23namespace {
24 constexpr uint16_t MAX_AMPL = 4095; // 12-bit ADC
25}
26
27//================================================================
28CscOverlay::CscOverlay(const std::string &name, ISvcLocator *pSvcLocator) :
29 AthReentrantAlgorithm(name, pSvcLocator) {
30}
31
32//================================================================
34 ATH_MSG_DEBUG("CscOverlay initialized");
35 ATH_CHECK(m_idHelperSvc.retrieve());
36
38 ATH_CHECK(m_cscCalibTool.retrieve());
39
40 // get cscRdoDecoderTool
42
43 //random number initialization
44 ATH_CHECK(m_rndmSvc.retrieve());
45
46 ATH_CHECK( m_bkgInputKey.initialize(!m_bkgInputKey.empty()) );
47 ATH_CHECK( m_signalInputKey.initialize() );
48 ATH_CHECK( m_outputKey.initialize() );
49
50 return StatusCode::SUCCESS;
51}
52
53//================================================================
54StatusCode CscOverlay::execute(const EventContext& ctx) const {
55 ATH_MSG_DEBUG("execute() begin");
56
57 const CscRawDataContainer *bkgContainerPtr = nullptr;
58 if (!m_bkgInputKey.empty()) {
60 if(!bkgContainer.isValid()) {
61 ATH_MSG_ERROR("Could not get background CscRawDataContainer called " << bkgContainer.name() << " from store " << bkgContainer.store());
62 return StatusCode::FAILURE;
63 }
64 ATH_MSG_DEBUG("Found background CscRawDataContainer called " << bkgContainer.name() << " in store " << bkgContainer.store());
65 bkgContainerPtr = bkgContainer.cptr();
66 }
67
69 if(!signalContainer.isValid()) {
70 ATH_MSG_ERROR("Could not get signal CscRawOverlayContainer called " << signalContainer.name() << " from store " << signalContainer.store());
71 return StatusCode::FAILURE;
72 }
73 ATH_MSG_DEBUG("Found signal CscRawOverlayContainer called " << signalContainer.name() << " in store " << signalContainer.store());
74
76 ATH_CHECK(outputContainer.record(std::make_unique<CscRawDataContainer>(signalContainer->size())));
77 if (!outputContainer.isValid()) {
78 ATH_MSG_ERROR("Could not record output CscRawOverlayContainer called " << outputContainer.name() << " to store " << outputContainer.store());
79 return StatusCode::FAILURE;
80 }
81 ATH_MSG_DEBUG("Recorded output CscRawOverlayContainer called " << outputContainer.name() << " in store " << outputContainer.store());
82
83 // now do the overlay
84 ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr()));
85
86
87 ATH_MSG_DEBUG("execute() end");
88 return StatusCode::SUCCESS;
89}
90
91//================================================================
93 const CscRawDataContainer *signalContainer,
94 CscRawDataContainer *outputContainer) const
95{
96 ATH_MSG_DEBUG("overlayContainer() begin");
97
98 // The MC signal container should typically be smaller than bkgContainer,
99 // because the latter contains all the noise, minimum bias and pile up.
100 // Thus we firstly iterate over signal hashes and store them in a map.
101 std::vector < std::pair<IdentifierHash, bool> > overlapMap;
102 overlapMap.reserve(signalContainer->numberOfCollections());
103 for (const auto [hashId, ptr] : signalContainer->GetAllHashPtrPair()) {
104 overlapMap.emplace_back(hashId, false);
105 }
106
107 // Now loop through the background hashes and copy unique ones over
108 for (const auto [hashId, ptr] : bkgContainer->GetAllHashPtrPair()) {
109 auto search = std::lower_bound( overlapMap.begin(), overlapMap.end(), hashId,
110 [](const std::pair<IdentifierHash, bool> &lhs, IdentifierHash rhs) -> bool { return lhs.first < rhs; } );
111 if (search == overlapMap.end() || search->first != hashId) {
112 // Copy the background collection
113 std::unique_ptr<CscRawDataCollection> bkgCollection = copyCollection(ptr);
114
115 if (outputContainer->addCollection(bkgCollection.get(), hashId).isFailure()) {
116 ATH_MSG_ERROR("Adding background Collection with hashId " << hashId << " failed");
117 return StatusCode::FAILURE;
118 } else {
119 (void)bkgCollection.release();
120 }
121 } else {
122 // Flip the overlap flag
123 search->second = true;
124 }
125 }
126
127 // Setup random engine
128 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
129 rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
130 CLHEP::HepRandomEngine *rndmEngine(*rngWrapper);
131
132 // Finally loop through the map and process the signal and overlay if
133 // necessary
134 for (const auto &[hashId, overlap] : overlapMap) {
135 // Retrieve the signal collection
136 const CscRawDataCollection *signalCollection = signalContainer->indexFindPtr(hashId);
137
138 // Output collection
139 std::unique_ptr<CscRawDataCollection> outputCollection{};
140
141 if (overlap) { // Do overlay
142 // Retrieve the background collection
143 const CscRawDataCollection *bkgCollection = bkgContainer->indexFindPtr(hashId);
144
145 // Create the output collection with background collection as a base
146 // TODO: should it be signal collection?
147 outputCollection = copyCollection(bkgCollection, true);
148
149 // Merge the collections
150 mergeCollections(bkgCollection, signalCollection, outputCollection.get(), rndmEngine);
151 } else {
152 // Create the output collection with signal collection as a base
153 outputCollection = copyCollection(signalCollection, true);
154
155 uint16_t numSamples = signalCollection->numSamples();
156
157 for (const CscRawData *data : *signalCollection) {
158 if (!data) {
159 ATH_MSG_WARNING("NULL pointer to Digit!");
160 continue;
161 }
162
163 // Copy the digit and add noise
164 std::vector<uint16_t> samples;
165
166 uint16_t width = data->width();
167 uint32_t hashOffset = data->hashId();
168
169 // Loop over width
170 for (uint16_t j = 0; j < width; ++j) {
171 uint32_t stripHash = hashOffset + j;
172 double stripNoise = m_cscCalibTool->stripNoise(stripHash, false);
173 // Get the samples
174 std::vector<uint16_t> stripSamples;
175 bool extractSamplesStatus = data->samples(j, numSamples, stripSamples);
176 if (!extractSamplesStatus) {
177 ATH_MSG_WARNING("Unable to extract samples for strip " << j
178 << " Online Cluster width = " << width
179 << " for number of Samples = " << numSamples
180 << " continuing ...");
181 } else {
182 for (uint16_t sample : stripSamples) {
183 double sampleNoise = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, stripNoise);
184 float adcCount = sample + sampleNoise;
185 if (adcCount > MAX_AMPL) {
186 ATH_MSG_DEBUG("value out of range (copying over signal): " << adcCount << " "
187 << " Setting it to max value = " << MAX_AMPL
188 << " IdentifierHash is " << stripHash);
189 adcCount = MAX_AMPL;
190 }
191 samples.push_back( (uint16_t) std::rint(adcCount) );
192 }
193 }
194 }
195
196 // Copy over the digit with the updated samples
197 auto rdo = std::make_unique<CscRawData>(samples, data->address(), data->identify(), data->time(), data->rpuID(), data->width(), data->hashId());
198
199 // Perform some checks
200 bool good = true;
201 for (uint16_t j = 0; j < width; ++j) {
202 const Identifier channelId = m_cscRdoDecoderTool->channelIdentifier(rdo.get(), &m_idHelperSvc->cscIdHelper(), j);
203 if (!m_idHelperSvc->cscIdHelper().valid(channelId)) {
204 ATH_MSG_WARNING("Invalid CSC Identifier! - skipping " << channelId);
205 good = false;
206 break;
207 }
208 }
209 if (good) {
210 outputCollection->push_back(rdo.release());
211 }
212 }
213 }
214
215 if (outputContainer->addCollection(outputCollection.get(), hashId).isFailure()) {
216 ATH_MSG_ERROR("Adding overlaid Collection with hashId " << hashId << " failed");
217 return StatusCode::FAILURE;
218 } else {
219 //intentional release, the outputContainer owns it now.
220 //coverity[RESOURCE_LEAK]
221 (void)outputCollection.release();
222 }
223 }
224
225 ATH_MSG_DEBUG("overlayContainer>() end");
226 return StatusCode::SUCCESS;
227}
228
229// Copy CscRawDataCollection
230std::unique_ptr<CscRawDataCollection>
232 bool propertiesOnly) const
233{
234 auto outputCollection = std::make_unique<CscRawDataCollection>(collection->identify());
235
236 // Copy property values to the new collection
237 outputCollection->setIdentifyHash(collection->identifyHash());
238 outputCollection->set_eventType(collection->eventType());
239 outputCollection->setRodId(collection->rodId());
240 outputCollection->setSubDetectorId(collection->subDetectorId());
241 outputCollection->set_samplingPhase(collection->samplingPhase());
242 outputCollection->set_triggerType(collection->triggerType());
243 outputCollection->set_firstBitSummary(collection->firstBitSummary());
244 outputCollection->set_scaAddress(collection->scaAddress());
245 for (uint8_t dataType : collection->dataType()) {
246 outputCollection->addDataType(dataType);
247 }
248
249 // Return if only properties requested
250 if (propertiesOnly) {
251 return outputCollection;
252 }
253
254 for (const CscRawData *existingDatum : *collection) {
255 // Owned by the collection
256 auto *datumCopy = new CscRawData(*existingDatum);
257 outputCollection->push_back(datumCopy);
258 }
259
260 return outputCollection;
261}
262
263void CscOverlay::spuData( const CscRawDataCollection * coll, const uint16_t spuID, std::vector<const CscRawData*>& data) const
264{
265 data.clear(); if ( !coll ) return;
268 for ( ; idata != edata; ++idata ) {
269 if ( (*idata)->rpuID() == spuID ) data.push_back( *idata );
270 }
271 ATH_MSG_DEBUG("spuData(): made data vector of size "<<data.size()<<" for SPU "<<spuID);
272}
273
274bool CscOverlay::needtoflip(const int address) const
275{
276 int measuresPhi = ( (address & 0x00000100) >> 8);
277 if (address<2147483640 && measuresPhi) {
278 int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
279 if (stationEta>0) { return true; }
280 }
281 return false;
282}
283
284
285//================================================================
287 const CscRawDataCollection *signalCollection,
288 CscRawDataCollection *outputCollection,
289 CLHEP::HepRandomEngine *rndmEngine) const
290{
291 ATH_MSG_DEBUG("mergeCollection() begin");
292
293 // number of ADC samples in the both data stream
294 unsigned int nSigSamples = bkgCollection->numSamples();
295 unsigned int nOvlSamples = signalCollection->numSamples();
296
297 // sampling times in both data streams
298 unsigned int dataSamplingTime = bkgCollection->rate();
299 unsigned int ovlSamplingTime = signalCollection->rate();
300
301 if ( dataSamplingTime != ovlSamplingTime ) {
302 ATH_MSG_ERROR("Overlay of inconsistent data - sampling times not the same "
303 << dataSamplingTime << " ns " << ovlSamplingTime << " ns");
304 throw std::runtime_error("mergeCollections(): sampling time mismatch");
305 }
306
307 if ( nSigSamples != nOvlSamples ) {
308 ATH_MSG_ERROR("Overlay of inconsistent data - number of samples not the same "
309 << nSigSamples << " " << nOvlSamples);
310 throw std::runtime_error("mergeCollections(): number of samples mismatch");
311 }
312
315 uint16_t clusterCounts[] = {0,0,0,0,0,0,0,0,0,0};
316 uint16_t rpuCount[] = {0,0};
317 for ( uint16_t spuID=0; spuID<10; ++spuID) {
318
319 std::vector<const CscRawData*> sigData; // real data
320 this->spuData(bkgCollection, spuID, sigData);
321
322 std::vector<const CscRawData*> ovlData; // simulation
323 this->spuData(signalCollection, spuID, ovlData);
324
327 int layer = 0;
328 if ( spuID == 4 || spuID == 9 ) layer=4;
329 for ( int j=0; j<=layer; ++j ) {
330 std::map< int,std::vector<uint16_t> > sigSamples;
331 std::map< int,std::vector<uint16_t> > ovlSamples;
332 uint32_t sigHash;
333 uint32_t ovlHash;
334 uint32_t sigAddress = this->stripData( sigData, nSigSamples, sigSamples, sigHash, spuID, j , m_isDataOverlay); // need to patch in the case of real data
335 uint32_t ovlAddress = this->stripData( ovlData, nOvlSamples, ovlSamples, ovlHash, spuID, j , false); // simulation
336 if (sigSamples.size()==0 && ovlSamples.size()==0) continue;
337
338 uint32_t hash = std::min( sigHash, ovlHash );
339 uint32_t address = std::min( sigAddress, ovlAddress );
340 if (sigSamples.size()!=0 && ovlSamples.size()!=0 && needtoflip(address)){
341 ATH_MSG_DEBUG("Looking for overlap of hashes and addresses within widths because needtoflip");
342 msg() << MSG::VERBOSE ;
343 std::set<int> sig; int lastindex=-1;
344 for (std::map< int,std::vector<uint16_t> >::const_iterator si=sigSamples.begin(); si!=sigSamples.end(); ++si) {
345 if (si!=sigSamples.begin() && si->first-lastindex!=1) break;
346 lastindex=si->first;
347 sig.insert(si->first); msg() << si->first << " ";
348 }
349 msg()<<endmsg;
350 bool overlap=false;
351 msg() <<MSG::VERBOSE ;
352 for (std::map< int,std::vector<uint16_t> >::const_iterator so=ovlSamples.begin(); so!=ovlSamples.end(); ++so) {
353 //add 1 to beginning and end of list because adjacent counts as overlap
354 msg() << (so->first)-1 << " ";
355 if (sig.find((so->first)-1)!=sig.end()) {overlap=true; msg() << "!!";}
356 msg() << (so->first) << " ";
357 if (sig.find((so->first))!=sig.end()) {overlap=true; msg() << "!!";}
358 msg() << (so->first)+1 << " ";
359 if (sig.find((so->first)+1)!=sig.end()) {overlap=true; msg() << "!!";}
360 }
361 msg()<<endmsg;
362 if (!overlap){
363 ATH_MSG_DEBUG("Taking max of hashes and addresses because needtoflip and no overlap");
364 hash = std::max( sigHash, ovlHash );
365 address = std::max( sigAddress, ovlAddress );
366 }
367 }
368
369 //for checks
370 std::set<int> insertedstrips, readstrips;
371 for (std::map< int,std::vector<uint16_t> >::const_iterator s=sigSamples.begin(); s!=sigSamples.end(); ++s){readstrips.insert(s->first);}
372 for (std::map< int,std::vector<uint16_t> >::const_iterator si=ovlSamples.begin(); si!=ovlSamples.end(); ++si){readstrips.insert(si->first);}
373
374 std::vector<CscRawData*> datums = this->overlay(sigSamples, ovlSamples,address, spuID, outputCollection->identify(), hash, rndmEngine);
375 if ( datums.size()==0 ) { ATH_MSG_WARNING("datums is size 0!"); }
376 for (unsigned int di=0; di<datums.size(); ++di){
377 CscRawData* datum=datums[di];
378 hash = datum->hashId();
379 address = datum->address();
380 int stripstart = ( address & 0x000000FF) + 1 + 0;
381 ATH_MSG_DEBUG("Datum in layer="<<j<<" has hash="<<hash<<" address="<<address<<" stripstart="<<stripstart<<", "<< *datum );
382 if (datum->width()==0) {
383 ATH_MSG_WARNING("Datum has 0 width!");
384 continue;
385 }
386
387 //perform some checks
388 int stationName = ( ( address & 0x00010000) >> 16 ) + 50;
389 int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
390 int stationPhi = ( ( address & 0x0000E000) >> 13 ) + 1;
391 Identifier me= m_idHelperSvc->cscIdHelper().elementID(stationName,stationEta,stationPhi);
392 ATH_MSG_VERBOSE("stationName,Eta,Phi="<<stationName<<","<<stationEta<<","<<stationPhi<<" - me="<<me);
393 bool good=true;
394 for (unsigned int j=0; j<datum->width(); ++j) {
395 int chamberLayer = ( (address & 0x00000800) >> 11) + 1;
396 int wireLayer = ( (address & 0x00000600) >> 9) + 1;
397 int measuresPhi = ( (address & 0x00000100) >> 8);
398 int strip = ( address & 0x000000FF) + 1 + j;
399 ATH_MSG_VERBOSE("chamberlayer,wirelayer,measuresphi,strip="<<chamberLayer<<","<<wireLayer<<","<<measuresPhi<<","<<strip);
400 // Added to Online -> Offline id in A side number is opposite bug#56002
401 if (measuresPhi) {
402 int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
403 if (stationEta>0) {
404 ATH_MSG_VERBOSE("FLIP strip. Formerly strip="<<strip<<", now strip="<<49-strip);
405 strip = 49-strip;
406 }
407 }
408 insertedstrips.insert(strip);//for checks
409 Identifier mechan= m_idHelperSvc->cscIdHelper().channelID(me,chamberLayer,wireLayer,measuresPhi,strip);
410 ATH_MSG_VERBOSE("mechan="<<mechan);
411 const Identifier channelId = m_cscRdoDecoderTool->channelIdentifier(datum, &m_idHelperSvc->cscIdHelper(), j);
412 if(!(m_idHelperSvc->cscIdHelper().valid(channelId))) {
413 ATH_MSG_WARNING("Invalid CSC Identifier in merge! - skipping " << channelId );
414 good=false;
415 }
416 else{ATH_MSG_DEBUG("Valid CSC Identifier in merge " << channelId);}
417 }
418 if (good){ outputCollection->push_back(datum); }
419 else{ continue; }
420
421 //keep count
422 if (spuID <10) clusterCounts[spuID] += 1;
423 if ( spuID <= 4 ) rpuCount[0] = 5;
424 else if ( spuID > 4 && spuID <= 9 ) rpuCount[1] = 11;
425 }//loop over datum
426
427 //check
428 if (readstrips!=insertedstrips){
429 ATH_MSG_WARNING("Readstrips != Insertedstrips: ");
430 std::ostringstream readstream;
431 for (std::set<int>::const_iterator i = readstrips.begin(); i!=readstrips.end(); ++i){readstream<<*i<<" ";}
432 ATH_MSG_WARNING(readstream.str());
433 std::ostringstream insertstream;
434 for (std::set<int>::const_iterator i = insertedstrips.begin(); i!=insertedstrips.end(); ++i){insertstream<<*i<<" ";}
435 ATH_MSG_WARNING(insertstream.str());
436 }
437
438 }
439 }
440 for (unsigned int i=0; i<10; ++i) outputCollection->set_spuCount(i,clusterCounts[i]);
441 for (unsigned int i=0; i<2; ++i) { if (rpuCount[i] != 0) outputCollection->addRPU(rpuCount[i]); }
442 // FIXME --- need to be able to reset the dataType - should add a new method to CscRawDataCollection for this
443 ATH_MSG_DEBUG("mergeCollection<>() end ");
444}
445
446uint32_t CscOverlay::stripData ( const std::vector<const CscRawData*>& data,
447 const unsigned int numSamples,
448 std::map< int,std::vector<uint16_t> >& samples,
449 uint32_t& hash,
450 const uint16_t spuID,
451 const int gasLayer, bool isdata) const
452{
453 ATH_MSG_DEBUG("stripData<>() begin: gasLayer="<<gasLayer<<" spuID="<<spuID<<" isdata="<<isdata);
454
455 samples.clear();
456 IdContext context = m_idHelperSvc->cscIdHelper().channel_context();
457
458 uint32_t maxInt = 2147483640;
459 uint32_t address = maxInt;
460 hash = maxInt;
461
463 std::vector<const CscRawData*>::const_iterator idata = data.begin();
464 std::vector<const CscRawData*>::const_iterator edata = data.end();
465 for ( ; idata != edata; ++idata ) {
466 const CscRawData * datum = *idata;
467 uint32_t hashOffset = datum->hashId();
468
470 Identifier stripId;
471 m_idHelperSvc->cscIdHelper().get_id(hashOffset, stripId, &context);
472 unsigned int strip = static_cast<unsigned int> ( m_idHelperSvc->cscIdHelper().strip( stripId ) );
473 int layer = m_idHelperSvc->cscIdHelper().wireLayer( stripId );
474 uint16_t width = datum->width();
475
479 bool non_precision = (gasLayer==layer) && (spuID==4 || spuID==9);
480 bool precision = (gasLayer==0) && (!(spuID==4 || spuID==9));
481 bool check = precision || non_precision;
482 if ( !check ) {
483 //ATH_MSG_DEBUG("Not precision or non_precision, skipping layer="<<layer<<", gasLayer="<<gasLayer<<", spuID="<<spuID);
484 continue;
485 }
486
487 //ACH - move down here after layer continue...
488 unsigned int newaddress = datum->address();
489 //if we're going to later flip the data strip for bug#56002
490 if (isdata && needtoflip(newaddress)) {
491 ATH_MSG_VERBOSE("needtoflip in stripdata, newaddress was = "<<newaddress<<", strip was = "<<strip);
492
493 //old way
494 //newaddress= newaddress- (width-1);//apparently need to shift the address to the highest strip
495
496 //new way
497 uint32_t oldFirstStrip = uint32_t (newaddress & 0x000000FF);
498 uint32_t newFirstStrip = uint32_t (47-oldFirstStrip) - width +1;//starts at 0
499 newaddress=newaddress - oldFirstStrip + newFirstStrip;
500
501 uint32_t oldStrip = uint32_t (strip & 0x000000FF);
502 uint32_t newStrip = uint32_t (49-oldStrip);//starts at 1
503 strip=strip - oldStrip + newStrip;
504
505 ATH_MSG_VERBOSE("needtoflip in stripdata, newaddress now = "<<newaddress<<", strip now = "<<strip);
506 }
507
508 if ( needtoflip(newaddress) ){
509 if (hash == maxInt) hash=0;
510 if (address == maxInt) address=0;
511 if ( hashOffset > hash ) hash = hashOffset;
512 if ( newaddress > address ) address = newaddress;
513 }
514 else{
515 if ( hashOffset < hash ) hash = hashOffset;
516 if ( newaddress < address ) address = newaddress;
517 }
518
519 ATH_MSG_DEBUG("stripData(): width="<<width<<" hashOffset="<<hashOffset<<" datumaddress="<<datum->address()<<" layer="<<layer<<" strip="<<strip<<", hash="<<hash<<" address="<<address);
520
521 for (unsigned int j=0; j<width; ++j) {
522 std::vector<uint16_t> adcs;
523 bool extractSamples = datum->samples(j, numSamples, adcs);
524 if ( !extractSamples ) {
525 ATH_MSG_WARNING("Unable to extract samples for strip " << j
526 << " Online Cluster width = " << width << " for number of Samples = " << numSamples);
527 }
528 else {
529 int newstrip = (strip+j);
530 if (false && isdata && needtoflip(address)){
531 newstrip = strip-j;
532 ATH_MSG_VERBOSE("needtoflip in stripdata, newstrip is "<<newstrip);
533 }
534 samples.insert ( std::make_pair( newstrip, adcs) );
535 }
536 }
537 }
538
539 ATH_MSG_DEBUG("stripData<>() end: hash=" << hash << " address=" << address);
540 return address;
541}
542
543std::vector<CscRawData*> CscOverlay::overlay( const std::map< int,std::vector<uint16_t> >& sigSamples,
544 const std::map< int,std::vector<uint16_t> >& ovlSamples,
545 const uint32_t address,
546 const uint16_t spuID,
547 const uint16_t collId,
548 const uint32_t hash,
549 CLHEP::HepRandomEngine *rndmEngine) const
550{
551 ATH_MSG_DEBUG("overlay<>() begin: hash="<<hash<<" address="<<address);
552 std::vector<CscRawData*> datas;
553 CscRawData * rawData = nullptr;
554 int max = 192;
555 if ( spuID == 4 || spuID == 9 ) max = 48;
556 std::vector<uint16_t> samples;
557 std::map< int,std::vector<uint16_t> >::const_iterator sig;
558 std::map< int,std::vector<uint16_t> >::const_iterator ovl;
559 uint16_t width = 0;
560 int myhash=hash; int myaddress=address;
561
562 max+=1;//go one past the end, to get the clusters ending right
563 for ( int i=1; i<=max; ++i) {
564 sig = sigSamples.find(i);
565 ovl = ovlSamples.find(i);
566 bool used=false;
567
568 if ( sig != sigSamples.end() && ovl == ovlSamples.end() ) { // real data only
569 ATH_MSG_VERBOSE("data only for i="<<i);
570 for ( unsigned int j=0; j<(*sig).second.size(); ++j ) {
571 samples.push_back( (*sig).second.at(j) );
572 assert((*sig).second.at(j)<=MAX_AMPL);
573 }
574 width++; used=true;
575 }
576 else if ( sig == sigSamples.end() && ovl != ovlSamples.end() ) { // simulation only
577 ATH_MSG_VERBOSE("simulation only for i="<<i);
578 int myhashw=myhash+width; if (needtoflip(myaddress)) {myhashw=myhash-width;}
579 double noise = m_cscCalibTool->stripNoise( (myhashw), false );//in ADC counts
580 for ( unsigned int j=0; j<(*ovl).second.size(); ++j ) {
581 double theNoise = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, noise);
582 float adcCount = (*ovl).second.at(j) + theNoise ;//add noise
583 if ( adcCount > MAX_AMPL ) {
584 ATH_MSG_DEBUG("value out of range (adding noise): " << adcCount << " "
585 << " Setting it to max value = " << MAX_AMPL
586 << " IdentifierHash is " << (myhashw));
587 adcCount = MAX_AMPL;
588 }
589 samples.push_back( (uint16_t) rint(adcCount) );
590 }
591 width++; used=true;
592 }
593 else if ( sig != sigSamples.end() && ovl != ovlSamples.end() ) { // real data + MC
594 ATH_MSG_VERBOSE("data and simulation for i="<<i);
595 int myhashw=myhash+width; if (needtoflip(myaddress)) {myhashw=myhash-width;}
596 double pedestal = m_cscCalibTool->stripPedestal( (myhashw), false );//in ADC counts
597 for ( unsigned int j=0; j<(*sig).second.size(); ++j ) {
598 float adcCount = (*sig).second.at(j) + (*ovl).second.at(j) - pedestal ;//subtract pedestal only (data already has noise)
599 if ( adcCount > MAX_AMPL ) {
600 ATH_MSG_DEBUG("value out of range (adding data+MC samples - pedestal): " << adcCount << " "
601 << " Setting it to max value = " << MAX_AMPL
602 << " IdentifierHash is " << (myhashw));
603 adcCount = MAX_AMPL;
604 }
605 samples.push_back( (uint16_t) rint(adcCount) );
606 }
607 width++; used=true;
608 }
609
610 if ( used==false && datas.size()>0 ){
611 if (needtoflip(myaddress)) {myhash-=1; myaddress-=1;}
612 else {myhash+=1; myaddress+=1;}
613 }
614
615 //If a break is detected in the strip cluster, start a new CscRawData object...
616 //and adjust the hash and address, etc.
617 if ( (used==false||i==max) && samples.size()>0){
618 if (datas.size()>0 && needtoflip(myaddress)) {myhash-=width; myaddress-=width;}
619 rawData = new CscRawData( samples, myaddress, collId, spuID, width );
620 rawData->setHashID(myhash);
621 rawData->setTime(0);//ACH - TODO: should be made significantly more clever!
622 datas.push_back(rawData);
623 ATH_MSG_DEBUG("overlay<>() add datum: hash="<<myhash<<" address="<<myaddress<<" width="<<width);
624 samples.clear();
625 if (!needtoflip(myaddress)) {myhash+=width; myaddress+=width;}
626 width=0;
627 }
628
629 }
630 ATH_MSG_DEBUG("overlay<>() end: CscRawDatas size="<<datas.size());
631 return datas;
632}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
const uint16_t MAX_AMPL
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
const double width
#define max(a, b)
Definition cfImp.cxx:41
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
An algorithm that can be simultaneously executed in multiple threads.
void spuData(const CscRawDataCollection *coll, const uint16_t spuID, std::vector< const CscRawData * > &data) const
get the data in one SPU of a chamber
StatusCode overlayContainer(const CscRawDataContainer *bkgContainer, const CscRawDataContainer *signalContainer, CscRawDataContainer *outputContainer) const
Overlay signal on the background container and record to the output one.
ToolHandle< ICscCalibTool > m_cscCalibTool
Definition CscOverlay.h:102
ToolHandle< Muon::ICSC_RDO_Decoder > m_cscRdoDecoderTool
Definition CscOverlay.h:103
std::unique_ptr< CscRawDataCollection > copyCollection(const CscRawDataCollection *collection, bool propertiesOnly=false) const
Copy CscRawDataCollection, optionally only copy properties.
CscOverlay(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< CscRawData * > overlay(const std::map< int, std::vector< uint16_t > > &sigSamples, const std::map< int, std::vector< uint16_t > > &ovlSamples, const uint32_t address, const uint16_t spuID, const uint16_t collId, const uint32_t hash, CLHEP::HepRandomEngine *rndmEngine) const
do the overlay - summing the ADC samples on one plane if there is overlap between zero bias data and ...
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition CscOverlay.h:105
SG::WriteHandleKey< CscRawDataContainer > m_outputKey
Definition CscOverlay.h:98
void mergeCollections(const CscRawDataCollection *bkgCollection, const CscRawDataCollection *signalCollection, CscRawDataCollection *outputCollection, CLHEP::HepRandomEngine *rndmEngine) const
In case of overlap merge signal and background collections.
virtual StatusCode execute(const EventContext &ctx) const override final
uint32_t stripData(const std::vector< const CscRawData * > &data, const unsigned int numSamples, std::map< int, std::vector< uint16_t > > &samples, uint32_t &hash, const uint16_t spuID, const int gasLayer, bool isdata) const
data in one gas lauer
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition CscOverlay.h:101
virtual StatusCode initialize() override final
bool needtoflip(const int address) const
SG::ReadHandleKey< CscRawDataContainer > m_bkgInputKey
Definition CscOverlay.h:96
Gaudi::Property< bool > m_isDataOverlay
Definition CscOverlay.h:100
SG::ReadHandleKey< CscRawDataContainer > m_signalInputKey
Definition CscOverlay.h:97
Collection of CSC Raw Hits, arranged according to CSC Detector Elements Author: Ketevi A.
IdentifierHash identifyHash() const
Returns the OFFLINE identifier hash for this collection.
uint8_t firstBitSummary() const
uint16_t identify() const
access methods
uint16_t subDetectorId() const
const std::vector< uint8_t > & dataType() const
uint8_t rate() const
the rate could be 25 or 50 ns
This container provides access to collections of CSC RDOs and a mechanism for recording them.
Class to hold the electronic output for a single CSC readout channel: n sampling ADC data + the addre...
Definition CscRawData.h:21
uint32_t address() const
Definition CscRawData.h:131
uint32_t hashId() const
Definition CscRawData.h:132
void setHashID(uint32_t hash)
Definition CscRawData.h:121
uint16_t width() const
Definition CscRawData.h:128
const std::vector< uint16_t > & samples() const
Definition CscRawData.h:130
void setTime(uint16_t time)
Definition CscRawData.h:119
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
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.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
virtual size_t numberOfCollections() const override final
return number of collections
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
virtual StatusCode addCollection(const T *coll, IdentifierHash hashId) override final
insert collection into container with id hash if IDC should not take ownership of collection,...
This is a "hash" representation of an Identifier.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
Dereference the pointer.
holding In fact this class is here in order to allow STL container for all features This class is sho...
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition hcg.cxx:739
bool overlay
Definition listroot.cxx:42
setWord1 uint16_t