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")),
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 
226  // collection of Digis to put in the event
227  std::vector< edm::DetSet<SiStripDigi> > vSiStripDigi;
228 
229  // loop through our collection of detectors, merging hits and making a new list of "signal" digis
230 
231  // clear some temporary storage for later digitization:
232 
233  signals_.clear();
234 
235  // big loop over Detector IDs:
236 
237  for(SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin();
238  IDet != SiHitStorage_.end(); IDet++) {
239 
240  uint32_t detID = IDet->first;
241 
242  SignalMapType Signals;
243  Signals.clear();
244 
245  OneDetectorMap LocalMap = IDet->second;
246 
247  //counter variables
248  int formerStrip = -1;
249  int currentStrip;
250  int ADCSum = 0;
251 
252  //loop over hit strips for this DetId, add duplicates
253 
254  OneDetectorMap::const_iterator iLocalchk;
255  OneDetectorMap::const_iterator iLocal = LocalMap.begin();
256  for(;iLocal != LocalMap.end(); ++iLocal) {
257 
258  currentStrip = iLocal->strip();
259 
260  if (currentStrip == formerStrip) { // we have to add these digis together
261  ADCSum+=iLocal->adc(); // on every element...
262  }
263  else{
264  if(formerStrip!=-1){
265  Signals.insert( std::make_pair(formerStrip, ADCSum));
266 
267  //detAmpl[formerStrip] = ADCSum;
268  //if (ADCSum > 511) ADCSum = 255;
269  //else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
270  //SiStripDigi aHit(formerStrip, ADCSum);
271  //SSD.push_back( aHit );
272  }
273  // save pointers for next iteration
274  formerStrip = currentStrip;
275  ADCSum = iLocal->adc();
276  }
277 
278  iLocalchk = iLocal;
279  if((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
280 
281  Signals.insert( std::make_pair(formerStrip, ADCSum));
282 
283  //detAmpl[formerStrip] = ADCSum;
284  // if (ADCSum > 511) ADCSum = 255;
285  //else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
286  //SSD.push_back( SiStripDigi(formerStrip, ADCSum) );
287  }
288  }
289  // save merged map:
290  signals_.insert( std::make_pair( detID, Signals));
291  }
292 
293  //Now, do noise, zero suppression, take into account bad channels, etc.
294  // This section stolen from SiStripDigitizerAlgorithm
295  // must loop over all detIds in the tracker to get all of the noise added properly.
296  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
297 
298  const StripGeomDetUnit* sgd = dynamic_cast<const StripGeomDetUnit*>((*iu));
299  if (sgd != 0){
300 
301  uint32_t detID = sgd->geographicalId().rawId();
302 
303  edm::DetSet<SiStripDigi> SSD(detID); // Make empty collection with this detector ID
304 
305  int numStrips = (sgd->specificTopology()).nstrips();
306 
307  // see if there is some signal on this detector
308 
309  const SignalMapType* theSignal(getSignal(detID));
310 
311  std::vector<float> detAmpl(numStrips, 0.);
312  if(theSignal) {
313  for(const auto& amp : *theSignal) {
314  detAmpl[amp.first] = amp.second;
315  }
316  }
317 
318  //removing signal from the dead (and HIP effected) strips
319  std::vector<bool>& badChannels = allBadChannels[detID];
320  for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
321 
322  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
323  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
324 
325  //convert our signals back to raw counts so that we can add noise properly:
326 
327  if(theSignal) {
328  for(unsigned int iv = 0; iv!=detAmpl.size(); iv++) {
329  float signal = detAmpl[iv];
330  if(signal > 0) {
331  float gainValue = gainHandle->getStripGain(iv, detGainRange);
332  signal *= theElectronPerADC/gainValue;
333  detAmpl[iv] = signal;
334  }
335  }
336  }
337 
338  //SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
339 
340  // -----------------------------------------------------------
341 
342  auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
343  auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
344 
345  int RefStrip = int(numStrips/2.);
346  while(RefStrip<numStrips&&badChannels[RefStrip]){ //if the refstrip is bad, I move up to when I don't find it
347  RefStrip++;
348  }
349  if(RefStrip<numStrips){
350  float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
351  float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
353  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
354  theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue,engine);
355  }
356 
357  DigitalVecType digis;
358  theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
359 
360 
361  SSD.data = digis;
362  // if(digis.size() > 0) {
363  // std::cout << " Real SiS Mixed Digi: " << detID << " ADC values ";
364  // for(const auto& iDigi : digis) { std::cout << iDigi.adc() << " " ;}
365  // std::cout << std::endl;
366  //}
367 
368  // stick this into the global vector of detector info
369  vSiStripDigi.push_back(SSD);
370 
371  } // end of loop over one detector
372 
373  } // end of big loop over all detector IDs
374 
375  // put the collection of digis in the event
376  LogInfo("DataMixingSiStripMCDigiWorker") << "total # Merged strips: " << vSiStripDigi.size() ;
377 
378  // make new digi collection
379 
380  std::auto_ptr< edm::DetSetVector<SiStripDigi> > MySiStripDigis(new edm::DetSetVector<SiStripDigi>(vSiStripDigi) );
381 
382  // put collection
383 
384  e.put( MySiStripDigis, SiStripDigiCollectionDM_ );
385 
386  // clear local storage for this event
387  SiHitStorage_.clear();
388  }
389 
390 } //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:154
std::vector< unsigned int >::const_iterator ContainerIterator
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.
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:113
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
Container::value_type value_type
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:402
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:365
Definition: DetId.h:18
unsigned short firstStrip
const T & get() const
Definition: EventSetup.h:55
const SignalMapType * getSignal(uint32_t detID) const
string const
Definition: compareJSON.py:14
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &) const =0
Use this engine in event methods.
void insert(detset const &s)
Insert the given DetSet.
Definition: DetSetVector.h:239
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:72
std::unique_ptr< SiStripFedZeroSuppression > theSiZeroSuppress
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:350
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:108