CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SiStripDigitizer.cc
Go to the documentation of this file.
1 // File: SiStripDigitizerAlgorithm.cc
2 // Description: Class for digitization.
3 
4 // Modified 15/May/2013 mark.grimes@bristol.ac.uk - Modified so that the digi-sim link has the correct
5 // index for the sim hits stored. It was previously always set to zero (I won't mention that it was
6 // me who originally wrote that).
7 
8 // system include files
9 #include <memory>
10 
12 
13 #include "SiStripDigitizer.h"
16 
21 
22 // user include files
25 
28 
32 
34 //needed for the geometry:
44 //needed for the magnetic field:
47 
49 
50 //Data Base infromations
54 
55 //Random Number
59 #include "CLHEP/Random/RandomEngine.h"
60 
62  gainLabel(conf.getParameter<std::string>("Gain")),
63  hitsProducer(conf.getParameter<std::string>("hitsProducer")),
64  trackerContainers(conf.getParameter<std::vector<std::string> >("ROUList")),
65  ZSDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("ZSDigi")),
66  SCDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("SCDigi")),
67  VRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("VRDigi")),
68  PRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("PRDigi")),
69  geometryType(conf.getParameter<std::string>("GeometryType")),
70  useConfFromDB(conf.getParameter<bool>("TrackerConfigurationFromDB")),
71  zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
72  makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false))
73 {
74  const std::string alias("simSiStripDigis");
75 
76  mixMod.produces<edm::DetSetVector<SiStripDigi> >(ZSDigi).setBranchAlias(ZSDigi);
77  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(SCDigi).setBranchAlias(alias + SCDigi);
78  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(VRDigi).setBranchAlias(alias + VRDigi);
79  mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(PRDigi).setBranchAlias(alias + PRDigi);
80  mixMod.produces<edm::DetSetVector<StripDigiSimLink> >().setBranchAlias(alias + "siStripDigiSimLink");
81  for(auto const& trackerContainer : trackerContainers) {
82  edm::InputTag tag(hitsProducer, trackerContainer);
83  iC.consumes<std::vector<PSimHit> >(edm::InputTag(hitsProducer, trackerContainer));
84  }
86  if ( ! rng.isAvailable()) {
87  throw cms::Exception("Configuration")
88  << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
89  "which is not present in the configuration file. You must add the service\n"
90  "in the configuration file or remove the modules that require it.";
91  }
92 
93  rndEngine = &(rng->getEngine());
95 
96 }
97 
98 // Virtual destructor needed.
100 }
101 
102 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit> > hSimHits,
103  const TrackerTopology *tTopo, size_t globalSimHitIndex ) {
104  // globalSimHitIndex is the index the sim hit will have when it is put in a collection
105  // of sim hits for all crossings. This is only used when creating digi-sim links if
106  // configured to do so.
107 
108  if(hSimHits.isValid()) {
109  std::set<unsigned int> detIds;
110  std::vector<PSimHit> const& simHits = *hSimHits.product();
111  for(std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex ) {
112  unsigned int detId = (*it).detUnitId();
113  if(detIds.insert(detId).second) {
114  // The insert succeeded, so this detector element has not yet been processed.
115  unsigned int isub = DetId(detId).subdetId();
116  if((isub == StripSubdetector::TIB) || (isub == StripSubdetector::TID) || (isub == StripSubdetector::TOB) || (isub == StripSubdetector::TEC)) {
117  StripGeomDetUnit* stripdet = detectorUnits[detId];
118  //access to magnetic field in global coordinates
119  GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
120  LogDebug ("Digitizer ") << "B-field(T) at " << stripdet->surface().position() << "(cm): "
121  << pSetup->inTesla(stripdet->surface().position());
122  theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, stripdet, bfield, tTopo);
123  }
124  }
125  } // end of loop over sim hits
126  }
127 }
128 
129 // Functions that gets called by framework every event
130  void
132  //Retrieve tracker topology from geometry
134  iSetup.get<IdealGeometryRecord>().get(tTopoHand);
135  const TrackerTopology *tTopo=tTopoHand.product();
136 
137  // Step A: Get Inputs
138  for(auto const& trackerContainer : trackerContainers) {
140  edm::InputTag tag(hitsProducer, trackerContainer);
141 
142  iEvent.getByLabel(tag, simHits);
144  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
145  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
146  // as though they were on the end of this collection.
147  // Note that this is only used for creating digi-sim links (if configured to do so).
148  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
149  }
150  }
151 
152  void
154 
156  iSetup.get<IdealGeometryRecord>().get(tTopoHand);
157  const TrackerTopology *tTopo=tTopoHand.product();
158 
159  // Step A: Get Inputs
160  for(auto const& trackerContainer : trackerContainers) {
162  edm::InputTag tag(hitsProducer, trackerContainer);
163 
164  iEvent.getByLabel(tag, simHits);
166  // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
167  // the global counter. Next time accumulateStripHits() is called it will count the sim hits
168  // as though they were on the end of this collection.
169  // Note that this is only used for creating digi-sim links (if configured to do so).
170  if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
171  }
172  }
173 
174 
176  // Make sure that the first crossing processed starts indexing the sim hits from zero.
177  // This variable is used so that the sim hits from all crossing frames have sequential
178  // indices used to create the digi-sim link (if configured to do so) rather than starting
179  // from zero for each crossing.
181 
182  // Step A: Get Inputs
183 
184  if(useConfFromDB){
186  iSetup.get<SiStripDetCablingRcd>().get(detCabling);
187  detCabling->addConnected(theDetIdList);
188  }
189 
190  theDigiAlgo->initializeEvent(iSetup);
191 
193  iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
194 
195  // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes. Use ESWatcher to determine this.
196  bool changes = true;
197  if(changes) { // Replace with ESWatcher
198  detectorUnits.clear();
199  }
200  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
201  unsigned int detId = (*iu)->geographicalId().rawId();
202  DetId idet=DetId(detId);
203  unsigned int isub=idet.subdetId();
204  if((isub == StripSubdetector::TIB) ||
205  (isub == StripSubdetector::TID) ||
206  (isub == StripSubdetector::TOB) ||
207  (isub == StripSubdetector::TEC)) {
208  StripGeomDetUnit* stripdet = dynamic_cast<StripGeomDetUnit*>((*iu));
209  assert(stripdet != 0);
210  if(changes) { // Replace with ESWatcher
211  detectorUnits.insert(std::make_pair(detId, stripdet));
212  }
213  theDigiAlgo->initializeDetUnit(stripdet, iSetup);
214  }
215  }
216 }
217 
219  edm::ESHandle<SiStripGain> gainHandle;
220  edm::ESHandle<SiStripNoises> noiseHandle;
221  edm::ESHandle<SiStripThreshold> thresholdHandle;
222  edm::ESHandle<SiStripPedestals> pedestalHandle;
223  iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
224  iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
225  iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
226  iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
227 
228  std::vector<edm::DetSet<SiStripDigi> > theDigiVector;
229  std::vector<edm::DetSet<SiStripRawDigi> > theRawDigiVector;
230  std::auto_ptr< edm::DetSetVector<StripDigiSimLink> > pOutputDigiSimLink( new edm::DetSetVector<StripDigiSimLink> );
231 
232  // Step B: LOOP on StripGeomDetUnit
233  theDigiVector.reserve(10000);
234  theDigiVector.clear();
235 
236  for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
237  if(useConfFromDB){
238  //apply the cable map _before_ digitization: consider only the detis that are connected
239  if(theDetIdList.find((*iu)->geographicalId().rawId())==theDetIdList.end())
240  continue;
241  }
242  StripGeomDetUnit* sgd = dynamic_cast<StripGeomDetUnit*>((*iu));
243  if (sgd != 0){
244  edm::DetSet<SiStripDigi> collectorZS((*iu)->geographicalId().rawId());
245  edm::DetSet<SiStripRawDigi> collectorRaw((*iu)->geographicalId().rawId());
246  edm::DetSet<StripDigiSimLink> collectorLink((*iu)->geographicalId().rawId());
247  theDigiAlgo->digitize(collectorZS,collectorRaw,collectorLink,sgd,
248  gainHandle,thresholdHandle,noiseHandle,pedestalHandle);
249  if(zeroSuppression){
250  if(collectorZS.data.size()>0){
251  theDigiVector.push_back(collectorZS);
252  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
253  }
254  }else{
255  if(collectorRaw.data.size()>0){
256  theRawDigiVector.push_back(collectorRaw);
257  if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
258  }
259  }
260  }
261  }
262 
263  if(zeroSuppression){
264  // Step C: create output collection
265  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
266  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
267  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
268  std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>(theDigiVector) );
269  // Step D: write output to file
270  iEvent.put(output, ZSDigi);
271  iEvent.put(output_scopemode, SCDigi);
272  iEvent.put(output_virginraw, VRDigi);
273  iEvent.put(output_processedraw, PRDigi);
274  if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
275  }else{
276  // Step C: create output collection
277  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
278  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
279  std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
280  std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>() );
281  // Step D: write output to file
282  iEvent.put(output, ZSDigi);
283  iEvent.put(output_scopemode, SCDigi);
284  iEvent.put(output_virginraw, VRDigi);
285  iEvent.put(output_processedraw, PRDigi);
286  if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
287  }
288 }
#define LogDebug(id)
const vstring trackerContainers
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
const std::string ZSDigi
edm::ESHandle< TrackerGeometry > pDD
const bool zeroSuppression
virtual void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
const std::string hitsProducer
virtual void finalizeEvent(edm::Event &e, edm::EventSetup const &c) override
virtual void accumulate(edm::Event const &e, edm::EventSetup const &c) override
const bool useConfFromDB
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
std::string encode() const
Definition: InputTag.cc:164
std::map< uint32_t, std::vector< int > > theDetIdList
virtual ~SiStripDigitizer()
int iEvent
Definition: GenABIO.cc:243
std::map< std::string, size_t > crossingSimHitIndexOffset_
Offset to add to the index of each sim hit to account for which crossing it&#39;s in. ...
std::map< unsigned int, StripGeomDetUnit * > detectorUnits
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
SiStripDigitizer(const edm::ParameterSet &conf, edm::one::EDProducerBase &mixMod, edm::ConsumesCollector &iC)
bool isAvailable() const
Definition: Service.h:46
virtual CLHEP::HepRandomEngine & getEngine() const =0
Use this to get the random number engine, this is the only function most users should call...
bool isValid() const
Definition: HandleBase.h:76
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:390
tuple conf
Definition: dbtoconf.py:185
Definition: DetId.h:18
std::unique_ptr< SiStripDigitizerAlgorithm > theDigiAlgo
void accumulateStripHits(edm::Handle< std::vector< PSimHit > >, const TrackerTopology *tTopo, size_t globalSimHitIndex)
edm::ESHandle< MagneticField > pSetup
const std::string VRDigi
const std::string PRDigi
const T & get() const
Definition: EventSetup.h:55
const std::string geometryType
T const * product() const
Definition: ESHandle.h:62
tuple simHits
Definition: trackerHits.py:16
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
const bool makeDigiSimLinks_
Whether or not to create the association to sim truth collection. Set in configuration.
volatile std::atomic< bool > shutdown_flag false
const PositionType & position() const
const std::string gainLabel
CLHEP::HepRandomEngine * rndEngine
const std::string SCDigi