ATLAS Offline Software
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"
8 #include "StoreGate/ReadHandle.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 
23 namespace {
24  constexpr uint16_t MAX_AMPL = 4095; // 12-bit ADC
25 }
26 
27 //================================================================
28 CscOverlay::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
41  ATH_CHECK(m_cscRdoDecoderTool.retrieve());
42 
43  //random number initialization
44  ATH_CHECK(m_rndmSvc.retrieve());
45 
49 
50  return StatusCode::SUCCESS;
51 }
52 
53 //================================================================
54 StatusCode 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  (void)outputCollection.release();
217  }
218  }
219 
220  ATH_MSG_DEBUG("overlayContainer>() end");
221  return StatusCode::SUCCESS;
222 }
223 
224 // Copy CscRawDataCollection
225 std::unique_ptr<CscRawDataCollection>
227  bool propertiesOnly) const
228 {
229  auto outputCollection = std::make_unique<CscRawDataCollection>(collection->identify());
230 
231  // Copy property values to the new collection
232  outputCollection->setIdentifyHash(collection->identifyHash());
233  outputCollection->set_eventType(collection->eventType());
234  outputCollection->setRodId(collection->rodId());
235  outputCollection->setSubDetectorId(collection->subDetectorId());
236  outputCollection->set_samplingPhase(collection->samplingPhase());
237  outputCollection->set_triggerType(collection->triggerType());
238  outputCollection->set_firstBitSummary(collection->firstBitSummary());
239  outputCollection->set_scaAddress(collection->scaAddress());
240  for (uint8_t dataType : collection->dataType()) {
241  outputCollection->addDataType(dataType);
242  }
243 
244  // Return if only properties requested
245  if (propertiesOnly) {
246  return outputCollection;
247  }
248 
249  for (const CscRawData *existingDatum : *collection) {
250  // Owned by the collection
251  auto *datumCopy = new CscRawData(*existingDatum);
252  outputCollection->push_back(datumCopy);
253  }
254 
255  return outputCollection;
256 }
257 
258 void CscOverlay::spuData( const CscRawDataCollection * coll, const uint16_t spuID, std::vector<const CscRawData*>& data) const
259 {
260  data.clear(); if ( !coll ) return;
263  for ( ; idata != edata; ++idata ) {
264  if ( (*idata)->rpuID() == spuID ) data.push_back( *idata );
265  }
266  ATH_MSG_DEBUG("spuData(): made data vector of size "<<data.size()<<" for SPU "<<spuID);
267 }
268 
269 bool CscOverlay::needtoflip(const int address) const
270 {
271  int measuresPhi = ( (address & 0x00000100) >> 8);
272  if (address<2147483640 && measuresPhi) {
273  int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
274  if (stationEta>0) { return true; }
275  }
276  return false;
277 }
278 
279 
280 //================================================================
282  const CscRawDataCollection *signalCollection,
284  CLHEP::HepRandomEngine *rndmEngine) const
285 {
286  ATH_MSG_DEBUG("mergeCollection() begin");
287 
288  // number of ADC samples in the both data stream
289  unsigned int nSigSamples = bkgCollection->numSamples();
290  unsigned int nOvlSamples = signalCollection->numSamples();
291 
292  // sampling times in both data streams
293  unsigned int dataSamplingTime = bkgCollection->rate();
294  unsigned int ovlSamplingTime = signalCollection->rate();
295 
296  if ( dataSamplingTime != ovlSamplingTime ) {
297  ATH_MSG_ERROR("Overlay of inconsistent data - sampling times not the same "
298  << dataSamplingTime << " ns " << ovlSamplingTime << " ns");
299  throw std::runtime_error("mergeCollections(): sampling time mismatch");
300  }
301 
302  if ( nSigSamples != nOvlSamples ) {
303  ATH_MSG_ERROR("Overlay of inconsistent data - number of samples not the same "
304  << nSigSamples << " " << nOvlSamples);
305  throw std::runtime_error("mergeCollections(): number of samples mismatch");
306  }
307 
310  uint16_t clusterCounts[] = {0,0,0,0,0,0,0,0,0,0};
311  uint16_t rpuCount[] = {0,0};
312  for ( uint16_t spuID=0; spuID<10; ++spuID) {
313 
314  std::vector<const CscRawData*> sigData; // real data
315  this->spuData(bkgCollection, spuID, sigData);
316 
317  std::vector<const CscRawData*> ovlData; // simulation
318  this->spuData(signalCollection, spuID, ovlData);
319 
322  int layer = 0;
323  if ( spuID == 4 || spuID == 9 ) layer=4;
324  for ( int j=0; j<=layer; ++j ) {
325  std::map< int,std::vector<uint16_t> > sigSamples;
326  std::map< int,std::vector<uint16_t> > ovlSamples;
327  uint32_t sigHash;
328  uint32_t ovlHash;
329  uint32_t sigAddress = this->stripData( sigData, nSigSamples, sigSamples, sigHash, spuID, j , m_isDataOverlay); // need to patch in the case of real data
330  uint32_t ovlAddress = this->stripData( ovlData, nOvlSamples, ovlSamples, ovlHash, spuID, j , false); // simulation
331  if (sigSamples.size()==0 && ovlSamples.size()==0) continue;
332 
333  uint32_t hash = std::min( sigHash, ovlHash );
334  uint32_t address = std::min( sigAddress, ovlAddress );
335  if (sigSamples.size()!=0 && ovlSamples.size()!=0 && needtoflip(address)){
336  ATH_MSG_DEBUG("Looking for overlap of hashes and addresses within widths because needtoflip");
337  msg() << MSG::VERBOSE ;
338  std::set<int> sig; int lastindex=-1;
339  for (std::map< int,std::vector<uint16_t> >::const_iterator si=sigSamples.begin(); si!=sigSamples.end(); ++si) {
340  if (si!=sigSamples.begin() && si->first-lastindex!=1) break;
341  lastindex=si->first;
342  sig.insert(si->first); msg() << si->first << " ";
343  }
344  msg()<<endmsg;
345  bool overlap=false;
346  msg() <<MSG::VERBOSE ;
347  for (std::map< int,std::vector<uint16_t> >::const_iterator so=ovlSamples.begin(); so!=ovlSamples.end(); ++so) {
348  //add 1 to beginning and end of list because adjacent counts as overlap
349  msg() << (so->first)-1 << " ";
350  if (sig.find((so->first)-1)!=sig.end()) {overlap=true; msg() << "!!";}
351  msg() << (so->first) << " ";
352  if (sig.find((so->first))!=sig.end()) {overlap=true; msg() << "!!";}
353  msg() << (so->first)+1 << " ";
354  if (sig.find((so->first)+1)!=sig.end()) {overlap=true; msg() << "!!";}
355  }
356  msg()<<endmsg;
357  if (!overlap){
358  ATH_MSG_DEBUG("Taking max of hashes and addresses because needtoflip and no overlap");
359  hash = std::max( sigHash, ovlHash );
360  address = std::max( sigAddress, ovlAddress );
361  }
362  }
363 
364  //for checks
365  std::set<int> insertedstrips, readstrips;
366  for (std::map< int,std::vector<uint16_t> >::const_iterator s=sigSamples.begin(); s!=sigSamples.end(); ++s){readstrips.insert(s->first);}
367  for (std::map< int,std::vector<uint16_t> >::const_iterator si=ovlSamples.begin(); si!=ovlSamples.end(); ++si){readstrips.insert(si->first);}
368 
369  std::vector<CscRawData*> datums = this->overlay(sigSamples, ovlSamples,address, spuID, outputCollection->identify(), hash, rndmEngine);
370  if ( datums.size()==0 ) { ATH_MSG_WARNING("datums is size 0!"); }
371  for (unsigned int di=0; di<datums.size(); ++di){
372  CscRawData* datum=datums[di];
373  hash = datum->hashId();
374  address = datum->address();
375  int stripstart = ( address & 0x000000FF) + 1 + 0;
376  ATH_MSG_DEBUG("Datum in layer="<<j<<" has hash="<<hash<<" address="<<address<<" stripstart="<<stripstart<<", "<< *datum );
377  if (datum->width()==0) {
378  ATH_MSG_WARNING("Datum has 0 width!");
379  continue;
380  }
381 
382  //perform some checks
383  int stationName = ( ( address & 0x00010000) >> 16 ) + 50;
384  int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
385  int stationPhi = ( ( address & 0x0000E000) >> 13 ) + 1;
386  Identifier me= m_idHelperSvc->cscIdHelper().elementID(stationName,stationEta,stationPhi);
387  ATH_MSG_VERBOSE("stationName,Eta,Phi="<<stationName<<","<<stationEta<<","<<stationPhi<<" - me="<<me);
388  bool good=true;
389  for (unsigned int j=0; j<datum->width(); ++j) {
390  int chamberLayer = ( (address & 0x00000800) >> 11) + 1;
391  int wireLayer = ( (address & 0x00000600) >> 9) + 1;
392  int measuresPhi = ( (address & 0x00000100) >> 8);
393  int strip = ( address & 0x000000FF) + 1 + j;
394  ATH_MSG_VERBOSE("chamberlayer,wirelayer,measuresphi,strip="<<chamberLayer<<","<<wireLayer<<","<<measuresPhi<<","<<strip);
395  // Added to Online -> Offline id in A side number is opposite bug#56002
396  if (measuresPhi) {
397  int stationEta = ( ((address & 0x00001000) >> 12 ) == 0x0) ? -1 : 1;
398  if (stationEta>0) {
399  ATH_MSG_VERBOSE("FLIP strip. Formerly strip="<<strip<<", now strip="<<49-strip);
400  strip = 49-strip;
401  }
402  }
403  insertedstrips.insert(strip);//for checks
404  Identifier mechan= m_idHelperSvc->cscIdHelper().channelID(me,chamberLayer,wireLayer,measuresPhi,strip);
405  ATH_MSG_VERBOSE("mechan="<<mechan);
406  const Identifier channelId = m_cscRdoDecoderTool->channelIdentifier(datum, &m_idHelperSvc->cscIdHelper(), j);
407  if(!(m_idHelperSvc->cscIdHelper().valid(channelId))) {
408  ATH_MSG_WARNING("Invalid CSC Identifier in merge! - skipping " << channelId );
409  good=false;
410  }
411  else{ATH_MSG_DEBUG("Valid CSC Identifier in merge " << channelId);}
412  }
413  if (good){ outputCollection->push_back(datum); }
414  else{ continue; }
415 
416  //keep count
417  if (spuID <10) clusterCounts[spuID] += 1;
418  if ( spuID <= 4 ) rpuCount[0] = 5;
419  else if ( spuID > 4 && spuID <= 9 ) rpuCount[1] = 11;
420  }//loop over datum
421 
422  //check
423  if (readstrips!=insertedstrips){
424  ATH_MSG_WARNING("Readstrips != Insertedstrips: ");
425  std::ostringstream readstream;
426  for (std::set<int>::const_iterator i = readstrips.begin(); i!=readstrips.end(); ++i){readstream<<*i<<" ";}
427  ATH_MSG_WARNING(readstream.str());
428  std::ostringstream insertstream;
429  for (std::set<int>::const_iterator i = insertedstrips.begin(); i!=insertedstrips.end(); ++i){insertstream<<*i<<" ";}
430  ATH_MSG_WARNING(insertstream.str());
431  }
432 
433  }
434  }
435  for (unsigned int i=0; i<10; ++i) outputCollection->set_spuCount(i,clusterCounts[i]);
436  for (unsigned int i=0; i<2; ++i) { if (rpuCount[i] != 0) outputCollection->addRPU(rpuCount[i]); }
437  // FIXME --- need to be able to reset the dataType - should add a new method to CscRawDataCollection for this
438  ATH_MSG_DEBUG("mergeCollection<>() end ");
439 }
440 
441 uint32_t CscOverlay::stripData ( const std::vector<const CscRawData*>& data,
442  const unsigned int numSamples,
443  std::map< int,std::vector<uint16_t> >& samples,
444  uint32_t& hash,
445  const uint16_t spuID,
446  const int gasLayer, bool isdata) const
447 {
448  ATH_MSG_DEBUG("stripData<>() begin: gasLayer="<<gasLayer<<" spuID="<<spuID<<" isdata="<<isdata);
449 
450  samples.clear();
451  IdContext context = m_idHelperSvc->cscIdHelper().channel_context();
452 
453  uint32_t maxInt = 2147483640;
454  uint32_t address = maxInt;
455  hash = maxInt;
456 
458  std::vector<const CscRawData*>::const_iterator idata = data.begin();
459  std::vector<const CscRawData*>::const_iterator edata = data.end();
460  for ( ; idata != edata; ++idata ) {
461  const CscRawData * datum = *idata;
462  uint32_t hashOffset = datum->hashId();
463 
465  Identifier stripId;
466  m_idHelperSvc->cscIdHelper().get_id(hashOffset, stripId, &context);
467  unsigned int strip = static_cast<unsigned int> ( m_idHelperSvc->cscIdHelper().strip( stripId ) );
468  int layer = m_idHelperSvc->cscIdHelper().wireLayer( stripId );
469  uint16_t width = datum->width();
470 
474  bool non_precision = (gasLayer==layer) && (spuID==4 || spuID==9);
475  bool precision = (gasLayer==0) && (!(spuID==4 || spuID==9));
476  bool check = precision || non_precision;
477  if ( !check ) {
478  //ATH_MSG_DEBUG("Not precision or non_precision, skipping layer="<<layer<<", gasLayer="<<gasLayer<<", spuID="<<spuID);
479  continue;
480  }
481 
482  //ACH - move down here after layer continue...
483  unsigned int newaddress = datum->address();
484  //if we're going to later flip the data strip for bug#56002
485  if (isdata && needtoflip(newaddress)) {
486  ATH_MSG_VERBOSE("needtoflip in stripdata, newaddress was = "<<newaddress<<", strip was = "<<strip);
487 
488  //old way
489  //newaddress= newaddress- (width-1);//apparently need to shift the address to the highest strip
490 
491  //new way
492  uint32_t oldFirstStrip = uint32_t (newaddress & 0x000000FF);
493  uint32_t newFirstStrip = uint32_t (47-oldFirstStrip) - width +1;//starts at 0
494  newaddress=newaddress - oldFirstStrip + newFirstStrip;
495 
496  uint32_t oldStrip = uint32_t (strip & 0x000000FF);
497  uint32_t newStrip = uint32_t (49-oldStrip);//starts at 1
498  strip=strip - oldStrip + newStrip;
499 
500  ATH_MSG_VERBOSE("needtoflip in stripdata, newaddress now = "<<newaddress<<", strip now = "<<strip);
501  }
502 
503  if ( needtoflip(newaddress) ){
504  if (hash == maxInt) hash=0;
505  if (address == maxInt) address=0;
506  if ( hashOffset > hash ) hash = hashOffset;
507  if ( newaddress > address ) address = newaddress;
508  }
509  else{
510  if ( hashOffset < hash ) hash = hashOffset;
511  if ( newaddress < address ) address = newaddress;
512  }
513 
514  ATH_MSG_DEBUG("stripData(): width="<<width<<" hashOffset="<<hashOffset<<" datumaddress="<<datum->address()<<" layer="<<layer<<" strip="<<strip<<", hash="<<hash<<" address="<<address);
515 
516  for (unsigned int j=0; j<width; ++j) {
517  std::vector<uint16_t> adcs;
518  bool extractSamples = datum->samples(j, numSamples, adcs);
519  if ( !extractSamples ) {
520  ATH_MSG_WARNING("Unable to extract samples for strip " << j
521  << " Online Cluster width = " << width << " for number of Samples = " << numSamples);
522  }
523  else {
524  int newstrip = (strip+j);
525  if (false && isdata && needtoflip(address)){
526  newstrip = strip-j;
527  ATH_MSG_VERBOSE("needtoflip in stripdata, newstrip is "<<newstrip);
528  }
529  samples.insert ( std::make_pair( newstrip, adcs) );
530  }
531  }
532  }
533 
534  ATH_MSG_DEBUG("stripData<>() end: hash=" << hash << " address=" << address);
535  return address;
536 }
537 
538 std::vector<CscRawData*> CscOverlay::overlay( const std::map< int,std::vector<uint16_t> >& sigSamples,
539  const std::map< int,std::vector<uint16_t> >& ovlSamples,
540  const uint32_t address,
541  const uint16_t spuID,
542  const uint16_t collId,
543  const uint32_t hash,
544  CLHEP::HepRandomEngine *rndmEngine) const
545 {
546  ATH_MSG_DEBUG("overlay<>() begin: hash="<<hash<<" address="<<address);
547  std::vector<CscRawData*> datas;
548  CscRawData * rawData = nullptr;
549  int max = 192;
550  if ( spuID == 4 || spuID == 9 ) max = 48;
551  std::vector<uint16_t> samples;
552  std::map< int,std::vector<uint16_t> >::const_iterator sig;
553  std::map< int,std::vector<uint16_t> >::const_iterator ovl;
554  uint16_t width = 0;
555  int myhash=hash; int myaddress=address;
556 
557  max+=1;//go one past the end, to get the clusters ending right
558  for ( int i=1; i<=max; ++i) {
559  sig = sigSamples.find(i);
560  ovl = ovlSamples.find(i);
561  bool used=false;
562 
563  if ( sig != sigSamples.end() && ovl == ovlSamples.end() ) { // real data only
564  ATH_MSG_VERBOSE("data only for i="<<i);
565  for ( unsigned int j=0; j<(*sig).second.size(); ++j ) {
566  samples.push_back( (*sig).second.at(j) );
567  assert((*sig).second.at(j)<=MAX_AMPL);
568  }
569  width++; used=true;
570  }
571  else if ( sig == sigSamples.end() && ovl != ovlSamples.end() ) { // simulation only
572  ATH_MSG_VERBOSE("simulation only for i="<<i);
573  int myhashw=myhash+width; if (needtoflip(myaddress)) {myhashw=myhash-width;}
574  double noise = m_cscCalibTool->stripNoise( (myhashw), false );//in ADC counts
575  for ( unsigned int j=0; j<(*ovl).second.size(); ++j ) {
576  double theNoise = CLHEP::RandGaussZiggurat::shoot(rndmEngine, 0.0, noise);
577  float adcCount = (*ovl).second.at(j) + theNoise ;//add noise
578  if ( adcCount > MAX_AMPL ) {
579  ATH_MSG_DEBUG("value out of range (adding noise): " << adcCount << " "
580  << " Setting it to max value = " << MAX_AMPL
581  << " IdentifierHash is " << (myhashw));
582  adcCount = MAX_AMPL;
583  }
584  samples.push_back( (uint16_t) rint(adcCount) );
585  }
586  width++; used=true;
587  }
588  else if ( sig != sigSamples.end() && ovl != ovlSamples.end() ) { // real data + MC
589  ATH_MSG_VERBOSE("data and simulation for i="<<i);
590  int myhashw=myhash+width; if (needtoflip(myaddress)) {myhashw=myhash-width;}
591  double pedestal = m_cscCalibTool->stripPedestal( (myhashw), false );//in ADC counts
592  for ( unsigned int j=0; j<(*sig).second.size(); ++j ) {
593  float adcCount = (*sig).second.at(j) + (*ovl).second.at(j) - pedestal ;//subtract pedestal only (data already has noise)
594  if ( adcCount > MAX_AMPL ) {
595  ATH_MSG_DEBUG("value out of range (adding data+MC samples - pedestal): " << adcCount << " "
596  << " Setting it to max value = " << MAX_AMPL
597  << " IdentifierHash is " << (myhashw));
598  adcCount = MAX_AMPL;
599  }
600  samples.push_back( (uint16_t) rint(adcCount) );
601  }
602  width++; used=true;
603  }
604 
605  if ( used==false && datas.size()>0 ){
606  if (needtoflip(myaddress)) {myhash-=1; myaddress-=1;}
607  else {myhash+=1; myaddress+=1;}
608  }
609 
610  //If a break is detected in the strip cluster, start a new CscRawData object...
611  //and adjust the hash and address, etc.
612  if ( (used==false||i==max) && samples.size()>0){
613  if (datas.size()>0 && needtoflip(myaddress)) {myhash-=width; myaddress-=width;}
614  rawData = new CscRawData( samples, myaddress, collId, spuID, width );
615  rawData->setHashID(myhash);
616  rawData->setTime(0);//ACH - TODO: should be made significantly more clever!
617  datas.push_back(rawData);
618  ATH_MSG_DEBUG("overlay<>() add datum: hash="<<myhash<<" address="<<myaddress<<" width="<<width);
619  samples.clear();
620  if (!needtoflip(myaddress)) {myhash+=width; myaddress+=width;}
621  width=0;
622  }
623 
624  }
625  ATH_MSG_DEBUG("overlay<>() end: CscRawDatas size="<<datas.size());
626  return datas;
627 }
CscIdHelper.h
used
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
Muon::nsw::STGTPSegments::moduleIDBits::stationPhi
constexpr uint8_t stationPhi
station Phi 1 to 8
Definition: NSWSTGTPDecodeBitmaps.h:161
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
CscRawData::address
uint32_t address() const
Definition: CscRawData.h:131
SiliconTech::strip
@ strip
CscRawDataCollection::identify
uint16_t identify() const
access methods
Definition: CscRawDataCollection.h:107
CscOverlay::m_outputKey
SG::WriteHandleKey< CscRawDataContainer > m_outputKey
Definition: CscOverlay.h:98
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
IdentifiableContainerMT::addCollection
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,...
Definition: IdentifiableContainerMT.h:298
CscOverlay::mergeCollections
void mergeCollections(const CscRawDataCollection *bkgCollection, const CscRawDataCollection *signalCollection, CscRawDataCollection *outputCollection, CLHEP::HepRandomEngine *rndmEngine) const
In case of overlap merge signal and background collections.
Definition: CscOverlay.cxx:281
dumpTgcDigiDeadChambers.stationName
dictionary stationName
Definition: dumpTgcDigiDeadChambers.py:30
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
gridSubmitIDTPM.check
check
Definition: gridSubmitIDTPM.py:45
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
CscOverlay::execute
virtual StatusCode execute(const EventContext &ctx) const override final
Definition: CscOverlay.cxx:54
CscOverlay::spuData
void spuData(const CscRawDataCollection *coll, const uint16_t spuID, std::vector< const CscRawData * > &data) const
get the data in one SPU of a chamber
Definition: CscOverlay.cxx:258
IdentifiableContainerMT::size
size_t size() const
Duplicate of fullSize for backwards compatability.
Definition: IdentifiableContainerMT.h:207
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
MAX_AMPL
const uint16_t MAX_AMPL
Definition: CscDigitToCscRDOTool.cxx:21
CscOverlay::CscOverlay
CscOverlay(const std::string &name, ISvcLocator *pSvcLocator)
Definition: CscOverlay.cxx:28
CscRawDataCollection::samplingPhase
bool samplingPhase() const
Definition: CscRawDataCollection.h:117
CscRawData
CscRawData
Definition: MuonEventAthenaPoolTPCnv.cxx:59
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
CscRawDataCollection::eventType
uint32_t eventType() const
Definition: CscRawDataCollection.h:120
CscOverlay::m_cscRdoDecoderTool
ToolHandle< Muon::ICSC_RDO_Decoder > m_cscRdoDecoderTool
Definition: CscOverlay.h:103
search
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:738
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
WriteHandle.h
Handle class for recording to StoreGate.
CscRawDataCollection::triggerType
bool triggerType() const
Definition: CscRawDataCollection.h:118
IdentifiableContainerMT::numberOfCollections
virtual size_t numberOfCollections() const override final
return number of collections
Definition: IdentifiableContainerMT.h:214
CscOverlay::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: CscOverlay.h:101
CscRawDataCollection::identifyHash
IdentifierHash identifyHash() const
Returns the OFFLINE identifier hash for this collection.
Definition: CscRawDataCollection.h:110
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
IdContext.h
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
CscRawDataCollection::dataType
const std::vector< uint8_t > & dataType() const
Definition: CscRawDataCollection.h:116
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:116
lumiFormat.i
int i
Definition: lumiFormat.py:85
CscOverlay::initialize
virtual StatusCode initialize() override final
Definition: CscOverlay.cxx:33
CscRawData::width
uint16_t width() const
Definition: CscRawData.h:128
CscRawDataCollection::firstBitSummary
uint8_t firstBitSummary() const
Definition: CscRawDataCollection.h:119
CscOverlay::m_signalInputKey
SG::ReadHandleKey< CscRawDataContainer > m_signalInputKey
Definition: CscOverlay.h:97
CscRawDataCollection::rodId
uint16_t rodId() const
Definition: CscRawDataCollection.h:112
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
CscRawDataCollection::scaAddress
uint32_t scaAddress() const
Definition: CscRawDataCollection.h:123
SG::VarHandleBase::store
std::string store() const
Return the name of the store holding the object we are proxying.
Definition: StoreGate/src/VarHandleBase.cxx:382
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:237
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CscOverlay::overlayContainer
StatusCode overlayContainer(const CscRawDataContainer *bkgContainer, const CscRawDataContainer *signalContainer, CscRawDataContainer *outputContainer) const
Overlay signal on the background container and record to the output one.
Definition: CscOverlay.cxx:89
CscOverlay.h
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
CscRawData::setHashID
void setHashID(uint32_t hash)
Definition: CscRawData.h:121
CscOverlay::copyCollection
std::unique_ptr< CscRawDataCollection > copyCollection(const CscRawDataCollection *collection, bool propertiesOnly=false) const
Copy CscRawDataCollection, optionally only copy properties.
Definition: CscOverlay.cxx:226
CaloCondBlobAlgs_fillNoiseFromASCII.channelId
channelId
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:121
CscRawDataCollection
Collection of CSC Raw Hits, arranged according to CSC Detector Elements Author: Ketevi A.
Definition: CscRawDataCollection.h:24
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CscRawDataCollection::numSamples
uint16_t numSamples() const
Definition: CscRawDataCollection.cxx:8
postInclude.outputCollection
outputCollection
Definition: postInclude.SortInput.py:27
CscRawData::hashId
uint32_t hashId() const
Definition: CscRawData.h:132
SG::WriteHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
CscRawData::samples
const std::vector< uint16_t > & samples() const
Definition: CscRawData.h:130
CscRawData.h
CscOverlay::stripData
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
Definition: CscOverlay.cxx:441
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
RNGWrapper.h
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
CscOverlay::needtoflip
bool needtoflip(const int address) const
Definition: CscOverlay.cxx:269
IdentifiableContainerMT::indexFindPtr
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,...
Definition: IdentifiableContainerMT.h:290
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
CscRawData
Class to hold the electronic output for a single CSC readout channel: n sampling ADC data + the addre...
Definition: CscRawData.h:21
ReadBchFromCool.good
good
Definition: ReadBchFromCool.py:433
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CscOverlay::m_cscCalibTool
ToolHandle< ICscCalibTool > m_cscCalibTool
Definition: CscOverlay.h:102
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
IdentifiableContainerMT::GetAllHashPtrPair
const std::vector< EventContainers::hashPair< T > > & GetAllHashPtrPair() const
Definition: IdentifiableContainerMT.h:218
CscRawDataContainer
This container provides access to collections of CSC RDOs and a mechanism for recording them.
Definition: CscRawDataContainer.h:23
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
CscOverlay::m_bkgInputKey
SG::ReadHandleKey< CscRawDataContainer > m_bkgInputKey
Definition: CscOverlay.h:96
CscOverlay::overlay
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 ...
Definition: CscOverlay.cxx:538
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
CscOverlay::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Definition: CscOverlay.h:105
ReadHandle.h
Handle class for reading from StoreGate.
Muon::nsw::STGTPSegments::moduleIDBits::stationEta
constexpr uint8_t stationEta
1 to 3
Definition: NSWSTGTPDecodeBitmaps.h:159
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
CscOverlay::m_isDataOverlay
Gaudi::Property< bool > m_isDataOverlay
Definition: CscOverlay.h:100
CscRawData::setTime
void setTime(uint16_t time)
Definition: CscRawData.h:119
IdContext
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition: IdContext.h:26
CscRawDataCollection::subDetectorId
uint16_t subDetectorId() const
Definition: CscRawDataCollection.h:113
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
CscRawDataCollection::rate
uint8_t rate() const
the rate could be 25 or 50 ns
Definition: CscRawDataCollection.cxx:24
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Identifier
Definition: IdentifierFieldParser.cxx:14