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>
18 //
19 //
21 
22 using namespace std;
23 
24 namespace edm
25 {
26 
27  // Virtual constructor
28 
29  DataMixingSiStripMCDigiWorker::DataMixingSiStripMCDigiWorker() { }
30 
31  // Constructor
32  DataMixingSiStripMCDigiWorker::DataMixingSiStripMCDigiWorker(const edm::ParameterSet& ps,
33  edm::ConsumesCollector && iC) :
34  label_(ps.getParameter<std::string>("Label")),
35  gainLabel(ps.getParameter<std::string>("Gain")),
36  peakMode(ps.getParameter<bool>("APVpeakmode")),
37  theThreshold(ps.getParameter<double>("NoiseSigmaThreshold")),
38  theElectronPerADC(ps.getParameter<double>( peakMode ? "electronPerAdcPeak" : "electronPerAdcDec" )),
39  theFedAlgo(ps.getParameter<int>("FedAlgorithm")),
40  geometryType(ps.getParameter<std::string>("GeometryType")),
41  theSiZeroSuppress(new SiStripFedZeroSuppression(theFedAlgo)),
42  theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC))
43 
44  {
45 
46  // get the subdetector names
47  // this->getSubdetectorNames(); //something like this may be useful to check what we are supposed to do...
48 
49  // declare the products to produce
50 
51  SistripLabelSig_ = ps.getParameter<edm::InputTag>("SistripLabelSig");
52  SiStripPileInputTag_ = ps.getParameter<edm::InputTag>("SiStripPileInputTag");
53 
54  SiStripDigiCollectionDM_ = ps.getParameter<std::string>("SiStripDigiCollectionDM");
55 
57  // clear local storage for this event
58  SiHitStorage_.clear();
59 
61  if ( ! rng.isAvailable()) {
62  throw cms::Exception("Psiguration")
63  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
64  "which is not present in the psiguration file. You must add the service\n"
65  "in the configuration file or remove the modules that require it.";
66  }
67 
69  // theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo);
70  //theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC));
71 
72  }
73 
74 
75  // Virtual destructor needed.
77  }
78 
80  // initialize individual detectors so we can copy real digitization code:
81 
83 
84  for(auto iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
85  unsigned int detId = (*iu)->geographicalId().rawId();
86  DetId idet=DetId(detId);
87  unsigned int isub=idet.subdetId();
88  if((isub == StripSubdetector::TIB) ||
89  (isub == StripSubdetector::TID) ||
90  (isub == StripSubdetector::TOB) ||
91  (isub == StripSubdetector::TEC)) {
92  auto stripdet = dynamic_cast<StripGeomDetUnit const*>((*iu));
93  assert(stripdet != 0);
94  DMinitializeDetUnit(stripdet, iSetup);
95  }
96  }
97 
98 
99  }
100 
101 
103 
104  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
105  iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
106 
107  unsigned int detId = det->geographicalId().rawId();
108  int numStrips = (det->specificTopology()).nstrips();
109 
110  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
111  //storing the bad strip of the the module. the module is not removed but just signal put to 0
112  std::vector<bool>& badChannels = allBadChannels[detId];
113  badChannels.clear();
114  badChannels.insert(badChannels.begin(), numStrips, false);
115  for(SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
116  SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
117  for(int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) badChannels[strip] = true;
118  }
119  firstChannelsWithSignal[detId] = numStrips;
120  lastChannelsWithSignal[detId]= 0;
121  }
122 
123 
125  // fill in maps of hits
126 
128 
129  if( e.getByLabel(SistripLabelSig_,input) ) {
130  OneDetectorMap LocalMap;
131 
132  //loop on all detsets (detectorIDs) inside the input collection
133  edm::DetSetVector<SiStripDigi>::const_iterator DSViter=input->begin();
134  for (; DSViter!=input->end();DSViter++){
135 
136 #ifdef DEBUG
137  LogDebug("DataMixingSiStripMCDigiWorker") << "Processing DetID " << DSViter->id;
138 #endif
139 
140  LocalMap.clear();
141  LocalMap.reserve((DSViter->data).size());
142  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
143 
144  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
145  }
146 
147  }
148  } // end of addSiStripSignals
149 
150 
151 
152  void DataMixingSiStripMCDigiWorker::addSiStripPileups(const int bcr, const EventPrincipal *ep, unsigned int eventNr,
153  ModuleCallingContext const* mcc) {
154  LogDebug("DataMixingSiStripMCDigiWorker") <<"\n===============> adding pileups from event "<<ep->id()<<" for bunchcrossing "<<bcr;
155 
156  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
157 
158  boost::shared_ptr<Wrapper<edm::DetSetVector<SiStripDigi> > const> inputPTR =
159  getProductByTag<edm::DetSetVector<SiStripDigi> >(*ep, SiStripPileInputTag_, mcc);
160 
161  if(inputPTR ) {
162 
163  const edm::DetSetVector<SiStripDigi> *input = const_cast< edm::DetSetVector<SiStripDigi> * >(inputPTR->product());
164 
165  // Handle< edm::DetSetVector<SiStripDigi> > input;
166 
167  // if( e->getByLabel(Sistripdigi_collectionPile_.label(),SistripLabelPile_.label(),input) ) {
168 
169  OneDetectorMap LocalMap;
170 
171  //loop on all detsets (detectorIDs) inside the input collection
173  for (; DSViter!=input->end();DSViter++){
174 
175 #ifdef DEBUG
176  LogDebug("DataMixingSiStripMCDigiWorker") << "Pileups: Processing DetID " << DSViter->id;
177 #endif
178 
179  // find correct local map (or new one) for this detector ID
180 
181  SiGlobalIndex::const_iterator itest;
182 
183  itest = SiHitStorage_.find(DSViter->id);
184 
185  if(itest!=SiHitStorage_.end()) { // this detID already has hits, add to existing map
186 
187  LocalMap = itest->second;
188 
189  // fill in local map with extra channels
190  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
191  std::stable_sort(LocalMap.begin(),LocalMap.end(),DataMixingSiStripMCDigiWorker::StrictWeakOrdering());
192  SiHitStorage_[DSViter->id]=LocalMap;
193 
194  }
195  else{ // fill local storage with this information, put in global collection
196 
197  LocalMap.clear();
198  LocalMap.reserve((DSViter->data).size());
199  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
200 
201  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
202  }
203  }
204  }
205  }
206 
207 
208 
210 
211  // set up machinery to do proper noise adding:
212  edm::ESHandle<SiStripGain> gainHandle;
213  edm::ESHandle<SiStripNoises> noiseHandle;
214  edm::ESHandle<SiStripThreshold> thresholdHandle;
215  edm::ESHandle<SiStripPedestals> pedestalHandle;
216  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
217  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
218  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
219  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
220  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
221 
222 
223  // collection of Digis to put in the event
224  std::vector< edm::DetSet<SiStripDigi> > vSiStripDigi;
225 
226  // loop through our collection of detectors, merging hits and making a new list of "signal" digis
227 
228  // clear some temporary storage for later digitization:
229 
230  signals_.clear();
231 
232  // big loop over Detector IDs:
233 
234  for(SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin();
235  IDet != SiHitStorage_.end(); IDet++) {
236 
237  uint32_t detID = IDet->first;
238 
239  SignalMapType Signals;
240  Signals.clear();
241 
242  OneDetectorMap LocalMap = IDet->second;
243 
244  //counter variables
245  int formerStrip = -1;
246  int currentStrip;
247  int ADCSum = 0;
248 
249  //loop over hit strips for this DetId, add duplicates
250 
251  OneDetectorMap::const_iterator iLocalchk;
252  OneDetectorMap::const_iterator iLocal = LocalMap.begin();
253  for(;iLocal != LocalMap.end(); ++iLocal) {
254 
255  currentStrip = iLocal->strip();
256 
257  if (currentStrip == formerStrip) { // we have to add these digis together
258  ADCSum+=iLocal->adc(); // on every element...
259  }
260  else{
261  if(formerStrip!=-1){
262  Signals.insert( std::make_pair(formerStrip, ADCSum));
263 
264  //detAmpl[formerStrip] = ADCSum;
265 
266  //if (ADCSum > 511) ADCSum = 255;
267  //else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
268  //SiStripDigi aHit(formerStrip, ADCSum);
269  //SSD.push_back( aHit );
270  }
271  // save pointers for next iteration
272  formerStrip = currentStrip;
273  ADCSum = iLocal->adc();
274  }
275 
276  iLocalchk = iLocal;
277  if((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
278 
279  Signals.insert( std::make_pair(formerStrip, ADCSum));
280 
281  //detAmpl[formerStrip] = ADCSum;
282 
283  // if (ADCSum > 511) ADCSum = 255;
284  //else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
285  //SSD.push_back( SiStripDigi(formerStrip, ADCSum) );
286  }
287  }
288  // save merged map:
289  signals_.insert( std::make_pair( detID, Signals));
290  }
291 
292  //Now, do noise, zero suppression, take into account bad channels, etc.
293  // This section stolen from SiStripDigitizerAlgorithm
294  // must loop over all detIds in the tracker to get all of the noise added properly.
295  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
296  const StripGeomDetUnit* sgd = dynamic_cast<const StripGeomDetUnit*>((*iu));
297  if (sgd != 0){
298 
299  uint32_t detID = sgd->geographicalId().rawId();
300 
301  edm::DetSet<SiStripDigi> SSD(detID); // Make empty collection with this detector ID
302 
303  int numStrips = (sgd->specificTopology()).nstrips();
304 
305  // see if there is some signal on this detector
306 
307  const SignalMapType* theSignal(getSignal(detID));
308 
309  std::vector<float> detAmpl(numStrips, 0.);
310  if(theSignal) {
311  for(const auto& amp : *theSignal) {
312  detAmpl[amp.first] = amp.second;
313  }
314  }
315 
316  //removing signal from the dead (and HIP effected) strips
317  std::vector<bool>& badChannels = allBadChannels[detID];
318  for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
319 
320  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
321  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
322 
323  //convert our signals back to raw counts so that we can add noise properly:
324 
325  if(theSignal) {
326  for(unsigned int iv = 0; iv!=detAmpl.size(); iv++) {
327  float signal = detAmpl[iv];
328  if(signal > 0) {
329  float gainValue = gainHandle->getStripGain(iv, detGainRange);
330  signal *= theElectronPerADC/gainValue;
331  detAmpl[iv] = signal;
332  }
333  }
334  }
335 
336 
337  //SiStripPedestals::Range detPedestalRange = pedestalHandle->getRange(detID);
338 
339  // -----------------------------------------------------------
340 
341  auto& firstChannelWithSignal = firstChannelsWithSignal[detID];
342  auto& lastChannelWithSignal = lastChannelsWithSignal[detID];
343 
344  int RefStrip = int(numStrips/2.);
345  while(RefStrip<numStrips&&badChannels[RefStrip]){ //if the refstrip is bad, I move up to when I don't find it
346  RefStrip++;
347  }
348  if(RefStrip<numStrips){
349  float noiseRMS = noiseHandle->getNoise(RefStrip,detNoiseRange);
350  float gainValue = gainHandle->getStripGain(RefStrip, detGainRange);
352  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
353  theSiNoiseAdder->addNoise(detAmpl,firstChannelWithSignal,lastChannelWithSignal,numStrips,noiseRMS*theElectronPerADC/gainValue,engine);
354  }
355 
356  DigitalVecType digis;
357  theSiZeroSuppress->suppress(theSiDigitalConverter->convert(detAmpl, gainHandle, detID), digis, detID,noiseHandle,thresholdHandle);
358 
359 
360  SSD.data = digis;
361  // if(digis.size() > 0) {
362  // std::cout << " Real SiS Mixed Digi: " << detID << " ADC values ";
363  // for(const auto& iDigi : digis) { std::cout << iDigi.adc() << " " ;}
364  // std::cout << std::endl;
365  //}
366 
367  // stick this into the global vector of detector info
368  vSiStripDigi.push_back(SSD);
369 
370  } // end of loop over one detector
371 
372  } // end of big loop over all detector IDs
373 
374  // put the collection of digis in the event
375  LogInfo("DataMixingSiStripMCDigiWorker") << "total # Merged strips: " << vSiStripDigi.size() ;
376 
377  // make new digi collection
378 
379  std::auto_ptr< edm::DetSetVector<SiStripDigi> > MySiStripDigis(new edm::DetSetVector<SiStripDigi>(vSiStripDigi) );
380 
381  // put collection
382 
383  e.put( MySiStripDigis, SiStripDigiCollectionDM_ );
384 
385  // clear local storage for this event
386  SiHitStorage_.clear();
387  }
388 
389 } //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:152
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:116
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:72
#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:390
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:363
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:237
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:75
std::unique_ptr< SiStripFedZeroSuppression > theSiZeroSuppress
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:348
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:106