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))
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  // theSiZeroSuppress = new SiStripFedZeroSuppression(theFedAlgo);
71  //theSiDigitalConverter(new SiTrivialDigitalConverter(theElectronPerADC));
72 
73  }
74 
75 
76  // Virtual destructor needed.
78  }
79 
81  // initialize individual detectors so we can copy real digitization code:
82 
84 
85  for(auto iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
86  unsigned int detId = (*iu)->geographicalId().rawId();
87  DetId idet=DetId(detId);
88  unsigned int isub=idet.subdetId();
89  if((isub == StripSubdetector::TIB) ||
90  (isub == StripSubdetector::TID) ||
91  (isub == StripSubdetector::TOB) ||
92  (isub == StripSubdetector::TEC)) {
93  auto stripdet = dynamic_cast<StripGeomDetUnit const*>((*iu));
94  assert(stripdet != 0);
95  DMinitializeDetUnit(stripdet, iSetup);
96  }
97  }
98 
99 
100  }
101 
102 
104 
105  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
106  iSetup.get<SiStripBadChannelRcd>().get(deadChannelHandle);
107 
108  unsigned int detId = det->geographicalId().rawId();
109  int numStrips = (det->specificTopology()).nstrips();
110 
111  SiStripBadStrip::Range detBadStripRange = deadChannelHandle->getRange(detId);
112  //storing the bad strip of the the module. the module is not removed but just signal put to 0
113  std::vector<bool>& badChannels = allBadChannels[detId];
114  badChannels.clear();
115  badChannels.insert(badChannels.begin(), numStrips, false);
116  for(SiStripBadStrip::ContainerIterator it = detBadStripRange.first; it != detBadStripRange.second; ++it) {
117  SiStripBadStrip::data fs = deadChannelHandle->decode(*it);
118  for(int strip = fs.firstStrip; strip < fs.firstStrip + fs.range; ++strip) badChannels[strip] = true;
119  }
120  firstChannelsWithSignal[detId] = numStrips;
121  lastChannelsWithSignal[detId]= 0;
122  }
123 
124 
126  // fill in maps of hits
127 
129 
130  if( e.getByLabel(SistripLabelSig_,input) ) {
131  OneDetectorMap LocalMap;
132 
133  //loop on all detsets (detectorIDs) inside the input collection
134  edm::DetSetVector<SiStripDigi>::const_iterator DSViter=input->begin();
135  for (; DSViter!=input->end();DSViter++){
136 
137 #ifdef DEBUG
138  LogDebug("DataMixingSiStripMCDigiWorker") << "Processing DetID " << DSViter->id;
139 #endif
140 
141  LocalMap.clear();
142  LocalMap.reserve((DSViter->data).size());
143  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
144 
145  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
146  }
147 
148  }
149  } // end of addSiStripSignals
150 
151 
152 
153  void DataMixingSiStripMCDigiWorker::addSiStripPileups(const int bcr, const EventPrincipal *ep, unsigned int eventNr,
154  ModuleCallingContext const* mcc) {
155  LogDebug("DataMixingSiStripMCDigiWorker") <<"\n===============> adding pileups from event "<<ep->id()<<" for bunchcrossing "<<bcr;
156 
157  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
158 
159  std::shared_ptr<Wrapper<edm::DetSetVector<SiStripDigi> > const> inputPTR =
160  getProductByTag<edm::DetSetVector<SiStripDigi> >(*ep, SiStripPileInputTag_, mcc);
161 
162  if(inputPTR ) {
163 
164  const edm::DetSetVector<SiStripDigi> *input = const_cast< edm::DetSetVector<SiStripDigi> * >(inputPTR->product());
165 
166  // Handle< edm::DetSetVector<SiStripDigi> > input;
167 
168  // if( e->getByLabel(Sistripdigi_collectionPile_.label(),SistripLabelPile_.label(),input) ) {
169 
170  OneDetectorMap LocalMap;
171 
172  //loop on all detsets (detectorIDs) inside the input collection
174  for (; DSViter!=input->end();DSViter++){
175 
176 #ifdef DEBUG
177  LogDebug("DataMixingSiStripMCDigiWorker") << "Pileups: Processing DetID " << DSViter->id;
178 #endif
179 
180  // find correct local map (or new one) for this detector ID
181 
182  SiGlobalIndex::const_iterator itest;
183 
184  itest = SiHitStorage_.find(DSViter->id);
185 
186  if(itest!=SiHitStorage_.end()) { // this detID already has hits, add to existing map
187 
188  LocalMap = itest->second;
189 
190  // fill in local map with extra channels
191  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
192  std::stable_sort(LocalMap.begin(),LocalMap.end(),DataMixingSiStripMCDigiWorker::StrictWeakOrdering());
193  SiHitStorage_[DSViter->id]=LocalMap;
194 
195  }
196  else{ // fill local storage with this information, put in global collection
197 
198  LocalMap.clear();
199  LocalMap.reserve((DSViter->data).size());
200  LocalMap.insert(LocalMap.end(),(DSViter->data).begin(),(DSViter->data).end());
201 
202  SiHitStorage_.insert( SiGlobalIndex::value_type( DSViter->id, LocalMap ) );
203  }
204  }
205  }
206  }
207 
208 
209 
211 
212  // set up machinery to do proper noise adding:
213  edm::ESHandle<SiStripGain> gainHandle;
214  edm::ESHandle<SiStripNoises> noiseHandle;
215  edm::ESHandle<SiStripThreshold> thresholdHandle;
216  edm::ESHandle<SiStripPedestals> pedestalHandle;
217  edm::ESHandle<SiStripBadStrip> deadChannelHandle;
218  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
219  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
220  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
221  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
222 
223 
224  // collection of Digis to put in the event
225  std::vector< edm::DetSet<SiStripDigi> > vSiStripDigi;
226 
227  // loop through our collection of detectors, merging hits and making a new list of "signal" digis
228 
229  // clear some temporary storage for later digitization:
230 
231  signals_.clear();
232 
233  // big loop over Detector IDs:
234 
235  for(SiGlobalIndex::const_iterator IDet = SiHitStorage_.begin();
236  IDet != SiHitStorage_.end(); IDet++) {
237 
238  uint32_t detID = IDet->first;
239 
240  SignalMapType Signals;
241  Signals.clear();
242 
243  OneDetectorMap LocalMap = IDet->second;
244 
245  //counter variables
246  int formerStrip = -1;
247  int currentStrip;
248  int ADCSum = 0;
249 
250  //loop over hit strips for this DetId, add duplicates
251 
252  OneDetectorMap::const_iterator iLocalchk;
253  OneDetectorMap::const_iterator iLocal = LocalMap.begin();
254  for(;iLocal != LocalMap.end(); ++iLocal) {
255 
256  currentStrip = iLocal->strip();
257 
258  if (currentStrip == formerStrip) { // we have to add these digis together
259  ADCSum+=iLocal->adc(); // on every element...
260  }
261  else{
262  if(formerStrip!=-1){
263  Signals.insert( std::make_pair(formerStrip, ADCSum));
264 
265  //detAmpl[formerStrip] = ADCSum;
266 
267  //if (ADCSum > 511) ADCSum = 255;
268  //else if (ADCSum > 253 && ADCSum < 512) ADCSum = 254;
269  //SiStripDigi aHit(formerStrip, ADCSum);
270  //SSD.push_back( aHit );
271  }
272  // save pointers for next iteration
273  formerStrip = currentStrip;
274  ADCSum = iLocal->adc();
275  }
276 
277  iLocalchk = iLocal;
278  if((++iLocalchk) == LocalMap.end()) { //make sure not to lose the last one
279 
280  Signals.insert( std::make_pair(formerStrip, ADCSum));
281 
282  //detAmpl[formerStrip] = ADCSum;
283 
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  const StripGeomDetUnit* sgd = dynamic_cast<const StripGeomDetUnit*>((*iu));
298  if (sgd != 0){
299 
300  uint32_t detID = sgd->geographicalId().rawId();
301 
302  edm::DetSet<SiStripDigi> SSD(detID); // Make empty collection with this detector ID
303 
304  int numStrips = (sgd->specificTopology()).nstrips();
305 
306  // see if there is some signal on this detector
307 
308  const SignalMapType* theSignal(getSignal(detID));
309 
310  std::vector<float> detAmpl(numStrips, 0.);
311  if(theSignal) {
312  for(const auto& amp : *theSignal) {
313  detAmpl[amp.first] = amp.second;
314  }
315  }
316 
317  //removing signal from the dead (and HIP effected) strips
318  std::vector<bool>& badChannels = allBadChannels[detID];
319  for(int strip =0; strip < numStrips; ++strip) if(badChannels[strip]) detAmpl[strip] = 0.;
320 
321  SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
322  SiStripApvGain::Range detGainRange = gainHandle->getRange(detID);
323 
324  //convert our signals back to raw counts so that we can add noise properly:
325 
326  if(theSignal) {
327  for(unsigned int iv = 0; iv!=detAmpl.size(); iv++) {
328  float signal = detAmpl[iv];
329  if(signal > 0) {
330  float gainValue = gainHandle->getStripGain(iv, detGainRange);
331  signal *= theElectronPerADC/gainValue;
332  detAmpl[iv] = signal;
333  }
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
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