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