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