CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DataMixingSiStripMCDigiWorker.cc
Go to the documentation of this file.
1 // File: DataMixingSiStripMCDigiWorker.cc
2 // Description: see DataMixingSiStripMCDigiWorker.h
3 // Author: Mike Hildreth, University of Notre Dame
4 //
5 //--------------------------------------------
6 
7 #include <map>
8 #include <memory>
19 //
20 //
22 
23 using namespace std;
24 
25 namespace edm
26 {
27 
28  // Virtual constructor
29 
30  DataMixingSiStripMCDigiWorker::DataMixingSiStripMCDigiWorker() { }
31 
32  // Constructor
33  DataMixingSiStripMCDigiWorker::DataMixingSiStripMCDigiWorker(const edm::ParameterSet& ps,
34  edm::ConsumesCollector && iC) :
35  label_(ps.getParameter<std::string>("Label")),
36  gainLabel(ps.getParameter<std::string>("Gain")),
37  peakMode(ps.getParameter<bool>("APVpeakmode")),
38  theThreshold(ps.getParameter<double>("NoiseSigmaThreshold")),
39  theElectronPerADC(ps.getParameter<double>( peakMode ? "electronPerAdcPeak" : "electronPerAdcDec" )),
40  theFedAlgo(ps.getParameter<int>("FedAlgorithm_PM")),
41  geometryType(ps.getParameter<std::string>("GeometryType")),
42  theSiZeroSuppress(new SiStripFedZeroSuppression(theFedAlgo)),
43  theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC, false)) // no premixing
44 
45  {
46 
47  // get the subdetector names
48  // this->getSubdetectorNames(); //something like this may be useful to check what we are supposed to do...
49 
50  // declare the products to produce
51 
52  SistripLabelSig_ = ps.getParameter<edm::InputTag>("SistripLabelSig");
53  SiStripPileInputTag_ = ps.getParameter<edm::InputTag>("SiStripPileInputTag");
54 
55  SiStripDigiCollectionDM_ = ps.getParameter<std::string>("SiStripDigiCollectionDM");
56 
58  // clear local storage for this event
59  SiHitStorage_.clear();
60 
62  if ( ! rng.isAvailable()) {
63  throw cms::Exception("Psiguration")
64  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
65  "which is not present in the psiguration file. You must add the service\n"
66  "in the configuration file or remove the modules that require it.";
67  }
68 
70 
71  // theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo);
72  //theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC));
73 
74  }
75 
76 
77  // Virtual destructor needed.
79  }
80 
82  // initialize individual detectors so we can copy real digitization code:
83 
85 
86  for(auto iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
87  unsigned int detId = (*iu)->geographicalId().rawId();
88  DetId idet=DetId(detId);
89  unsigned int isub=idet.subdetId();
90  if((isub == StripSubdetector::TIB) ||
91  (isub == StripSubdetector::TID) ||
92  (isub == StripSubdetector::TOB) ||
93  (isub == StripSubdetector::TEC)) {
94 
95  auto stripdet = dynamic_cast<StripGeomDetUnit const*>((*iu));
96  assert(stripdet != 0);
97  DMinitializeDetUnit(stripdet, iSetup);
98  }
99  }
100 
101 
102  }
103 
104 
106 
107  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
108  iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
109 
110  unsigned int detId = det->geographicalId().rawId();
111  int numStrips = (det->specificTopology()).nstrips();
112 
113  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
114  //storing the bad strip of the the module. the module is not removed but just signal put to 0
115  std::vector<bool>& badChannels = allBadChannels[detId];
116  badChannels.clear();
117  badChannels.insert(badChannels.begin(), numStrips, false);
118  for(SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
119  SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
120  for(int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) badChannels[strip] = true;
121  }
122  firstChannelsWithSignal[detId] = numStrips;
123  lastChannelsWithSignal[detId]= 0;
124  }
125 
126 
128  // fill in maps of hits
129 
131 
132  if( e.getByLabel(SistripLabelSig_,input) ) {
133  OneDetectorMap LocalMap;
134 
135  //loop on all detsets (detectorIDs) inside the input collection
136  edm::DetSetVector<SiStripDigi>::const_iterator DSViter=input->begin();
137  for (; DSViter!=input->end();DSViter++){
138 
139 #ifdef DEBUG
140  LogDebug("DataMixingSiStripMCDigiWorker") << "Processing DetID " << DSViter->id;
141 #endif
142 
143  LocalMap.clear();
144  LocalMap.reserve((DSViter->data).size());
145  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
146 
147  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
148  }
149 
150  }
151  } // end of addSiStripSignals
152 
153 
154 
155  void DataMixingSiStripMCDigiWorker::addSiStripPileups(const int bcr, const EventPrincipal *ep, unsigned int eventNr,
156  ModuleCallingContext const* mcc) {
157  LogDebug("DataMixingSiStripMCDigiWorker") <<"\n===============> adding pileups from event "<<ep->id()<<" for bunchcrossing "<<bcr;
158 
159  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
160 
161  std::shared_ptr<Wrapper<edm::DetSetVector<SiStripDigi> > const> inputPTR =
162  getProductByTag<edm::DetSetVector<SiStripDigi> >(*ep, SiStripPileInputTag_, mcc);
163 
164  if(inputPTR ) {
165 
166  const edm::DetSetVector<SiStripDigi> *input = const_cast< edm::DetSetVector<SiStripDigi> * >(inputPTR->product());
167 
168  // Handle< edm::DetSetVector<SiStripDigi> > input;
169 
170  // if( e->getByLabel(Sistripdigi_collectionPile_.label(),SistripLabelPile_.label(),input) ) {
171 
172  OneDetectorMap LocalMap;
173 
174  //loop on all detsets (detectorIDs) inside the input collection
176  for (; DSViter!=input->end();DSViter++){
177 
178 #ifdef DEBUG
179  LogDebug("DataMixingSiStripMCDigiWorker") << "Pileups: Processing DetID " << DSViter->id;
180 #endif
181 
182  // find correct local map (or new one) for this detector ID
183 
184  SiGlobalIndex::const_iterator itest;
185 
186  itest = SiHitStorage_.find(DSViter->id);
187 
188  if(itest!=SiHitStorage_.end()) { // this detID already has hits, add to existing map
189 
190  LocalMap = itest->second;
191 
192  // fill in local map with extra channels
193  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
194  std::stable_sort(LocalMap.begin(),LocalMap.end(),DataMixingSiStripMCDigiWorker::StrictWeakOrdering());
195  SiHitStorage_[DSViter->id]=LocalMap;
196 
197  }
198  else{ // fill local storage with this information, put in global collection
199 
200  LocalMap.clear();
201  LocalMap.reserve((DSViter->data).size());
202  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
203 
204  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
205  }
206  }
207  }
208  }
209 
210 
211 
213 
214  // set up machinery to do proper noise adding:
215  edm::ESHandle<SiStripGain> gainHandle;
216  edm::ESHandle<SiStripNoises> noiseHandle;
217  edm::ESHandle<SiStripThreshold> thresholdHandle;
218  edm::ESHandle<SiStripPedestals> pedestalHandle;
219  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
220  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
221  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
222  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
223  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
224 
225  // First, have to convert all ADC counts to raw pulse heights so that values can be added properly
226  // In PreMixing, pulse heights are saved with ADC = sqrt(9.0*PulseHeight) - have to undo.
227 
228  // This is done here because it's the only place we have access to EventSetup
229  // Simultaneously, merge lists of hit channels in each DetId.
230  // Signal Digis are in the list first, have to merge lists of hit strips on the fly,
231  // add signals on duplicates later
232 
233  OneDetectorRawMap LocalRawMap;
234 
235  // Now, loop over hits and add them to the map in the proper sorted order
236  // Note: We are assuming that the hits from the Signal events have been created in
237  // "PreMix" mode, rather than in the standard ADC conversion routines. If not, this
238  // doesn't work at all.
239 
240  // At the moment, both Signal and Reconstituted PU hits have the same compression algorithm.
241  // If this were different, and one needed gains, the conversion back to pulse height can only
242  // be done in this routine. So, yes, there is an extra loop over hits here in the current code,
243  // because, in principle, one could convert to pulse height during the read/store phase.
244 
245  for(SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin();
246  IDet != SiHitStorage_.end(); IDet++) {
247 
248  uint32_t detID = IDet->first;
249 
250  OneDetectorMap LocalMap = IDet->second;
251 
252  //loop over hit strips for this DetId, do conversion to pulse height, store.
253 
254  LocalRawMap.clear();
255 
256  OneDetectorMap::const_iterator iLocal = LocalMap.begin();
257  for(;iLocal != LocalMap.end(); ++iLocal) {
258 
259  uint16_t currentStrip = iLocal->strip();
260  float signal = float(iLocal->adc());
261  if(iLocal->adc() == 1022) signal = 1500.; // average values for overflows
262  if(iLocal->adc() == 1023) signal = 3000.;
263 
264  //convert signals back to raw counts
265 
266  float ReSignal = signal*signal/9.0; // The PreMixing conversion is adc = sqrt(9.0*pulseHeight)
267 
268  RawDigi NewRawDigi = std::make_pair(currentStrip,ReSignal);
269 
270  LocalRawMap.push_back(NewRawDigi);
271 
272  }
273 
274  // save information for this detiD into global map
275  SiRawDigis_.insert( SiGlobalRawIndex::value_type( detID, LocalRawMap ) );
276  }
277 
278  // Ok, done with merging raw signals - now add signals on duplicate strips
279 
280  // collection of Digis to put in the event
281  std::vector< edm::DetSet<SiStripDigi> > vSiStripDigi;
282 
283  // loop through our collection of detectors, merging hits and making a new list of "signal" digis
284 
285  // clear some temporary storage for later digitization:
286 
287  signals_.clear();
288 
289  // big loop over Detector IDs:
290  for(SiGlobalRawIndex::const_iterator IDet = SiRawDigis_.begin();
291  IDet != SiRawDigis_.end(); IDet++) {
292 
293  uint32_t detID = IDet->first;
294 
295  SignalMapType Signals;
296  Signals.clear();
297 
298  OneDetectorRawMap LocalMap = IDet->second;
299 
300  //counter variables
301  int formerStrip = -1;
302  int currentStrip;
303  float ADCSum = 0;
304 
305  //loop over hit strips for this DetId, add duplicates
306 
307  OneDetectorRawMap::const_iterator iLocalchk;
308  OneDetectorRawMap::const_iterator iLocal = LocalMap.begin();
309  for(;iLocal != LocalMap.end(); ++iLocal) {
310 
311  currentStrip = iLocal->first; // strip is first element
312 
313  if (currentStrip == formerStrip) { // we have to add these digis together
314 
315  ADCSum+=iLocal->second ; // raw pulse height is second element.
316  }
317  else{
318  if(formerStrip!=-1){
319  Signals.insert( std::make_pair(formerStrip, ADCSum));
320  }
321  // save pointers for next iteration
322  formerStrip = currentStrip;
323  ADCSum = iLocal->second; // lone ADC
324  }
325 
326  iLocalchk = iLocal;
327  if((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
328 
329  Signals.insert( std::make_pair(formerStrip, ADCSum));
330  }
331  }
332  // save merged map:
333  signals_.insert( std::make_pair( detID, Signals));
334  }
335 
336  //Now, do noise, zero suppression, take into account bad channels, etc.
337  // This section stolen from SiStripDigitizerAlgorithm
338  // must loop over all detIds in the tracker to get all of the noise added properly.
339  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
340 
341  const StripGeomDetUnit* sgd = dynamic_cast<const StripGeomDetUnit*>((*iu));
342  if (sgd != 0){
343 
344  uint32_t detID = sgd->geographicalId().rawId();
345 
346  edm::DetSet<SiStripDigi> SSD(detID); // Make empty collection with this detector ID
347 
348  int numStrips = (sgd->specificTopology()).nstrips();
349 
350  // see if there is some signal on this detector
351 
352  const SignalMapType* theSignal(getSignal(detID));
353 
354  std::vector<float> detAmpl(numStrips, 0.);
355  if(theSignal) {
356  for(const auto& amp : *theSignal) {
357  detAmpl[amp.first] = amp.second;
358  }
359  }
360 
361  //removing signal from the dead (and HIP effected) strips
362  std::vector<bool>& badChannels = allBadChannels[detID];
363  for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
364 
365  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
366  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
367 
368  // Gain conversion is already done during signal adding
369  //convert our signals back to raw counts so that we can add noise properly:
370 
371  /*
372  if(theSignal) {
373  for(unsigned int iv = 0; iv!=detAmpl.size(); iv++) {
374  float signal = detAmpl[iv];
375  if(signal > 0) {
376  float gainValue = gainHandle->getStripGain(iv, detGainRange);
377  signal *= theElectronPerADC/gainValue;
378  detAmpl[iv] = signal;
379  }
380  }
381  }
382  */
383 
384  //SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
385 
386  // -----------------------------------------------------------
387 
388  size_t firstChannelWithSignal = 0;
389  size_t lastChannelWithSignal = numStrips;
390 
391  int RefStrip = int(numStrips/2.);
392  while(RefStrip<numStrips&&badChannels[RefStrip]){ //if the refstrip is bad, I move up to when I don't find it
393  RefStrip++;
394  }
395  if(RefStrip<numStrips){
396  float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
397  float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
399  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
400  theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue,engine);
401  }
402 
403  DigitalVecType digis;
404  theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
405 
406 
407  SSD.data = digis;
408  // if(digis.size() > 0) {
409  // std::cout << " Real SiS Mixed Digi: " << detID << " ADC values ";
410  // for(const auto& iDigi : digis) { std::cout << iDigi.adc() << " " ;}
411  // std::cout << std::endl;
412  //}
413 
414  // stick this into the global vector of detector info
415  vSiStripDigi.push_back(SSD);
416 
417  } // end of loop over one detector
418 
419  } // end of big loop over all detector IDs
420 
421  // put the collection of digis in the event
422  LogInfo("DataMixingSiStripMCDigiWorker") << "total # Merged strips: " << vSiStripDigi.size() ;
423 
424  // make new digi collection
425 
426  std::auto_ptr< edm::DetSetVector<SiStripDigi> > MySiStripDigis(new edm::DetSetVector<SiStripDigi>(vSiStripDigi) );
427 
428  // put collection
429 
430  e.put( MySiStripDigis, SiStripDigiCollectionDM_ );
431 
432  // clear local storage for this event
433  SiHitStorage_.clear();
434  SiRawDigis_.clear();
435  signals_.clear();
436  }
437 
438 } //edm
#define LogDebug(id)
unsigned short range
T getParameter(std::string const &) const
std::map< unsigned int, size_t > firstChannelsWithSignal
void reserve(size_t s)
Definition: DetSetVector.h:150
std::vector< unsigned int >::const_iterator ContainerIterator
assert(m_qm.get())
std::pair< uint16_t, Amplitude > RawDigi
EventID const & id() const
virtual void initializeEvent(const edm::Event &e, edm::EventSetup const &iSetup)
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
static std::string const input
Definition: EdmProvDump.cc:44
SiDigitalConverter::DigitalVecType DigitalVecType
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
void addSiStripPileups(const int bcr, const edm::EventPrincipal *, unsigned int EventId, ModuleCallingContext const *)
bool isAvailable() const
Definition: Service.h:46
std::pair< ContainerIterator, ContainerIterator > Range
void DMinitializeDetUnit(StripGeomDetUnit const *det, const edm::EventSetup &iSetup)
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:77
#define end
Definition: vmac.h:37
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
std::unique_ptr< SiGaussianTailNoiseAdder > theSiNoiseAdder
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:418
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:361
Definition: DetId.h:18
unsigned short firstStrip
const T & get() const
Definition: EventSetup.h:56
const SignalMapType * getSignal(uint32_t detID) const
string const
Definition: compareJSON.py:14
void insert(detset const &s)
Insert the given DetSet.
Definition: DetSetVector.h:235
collection_type data
Definition: DetSet.h:78
std::map< unsigned int, std::vector< bool > > allBadChannels
#define begin
Definition: vmac.h:30
std::pair< ContainerIterator, ContainerIterator > Range
std::unique_ptr< SiTrivialDigitalConverter > theSiDigitalConverter
StreamID streamID() const
Definition: Event.h:80
std::unique_ptr< SiStripFedZeroSuppression > theSiZeroSuppress
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:346
volatile std::atomic< bool > shutdown_flag false
std::map< unsigned int, size_t > lastChannelsWithSignal
std::pair< ContainerIterator, ContainerIterator > Range
Definition: SiStripNoises.h:48
void putSiStrip(edm::Event &e, edm::EventSetup const &iSetup)
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:104