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