CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HGCDigitizer.cc
Go to the documentation of this file.
20 
21 #include <algorithm>
22 #include <boost/foreach.hpp>
23 
24 using namespace hgc_digi;
25 
26 namespace {
27 
28  constexpr std::array<double,3> occupancyGuesses = { { 0.5,0.2,0.2 } };
29 
30  float getPositionDistance(const HGCalGeometry* geom, const DetId& id) {
31  return geom->getPosition(id).mag();
32  }
33 
34  float getPositionDistance(const HcalGeometry* geom, const DetId& id) {
35  return geom->getGeometry(id)->getPosition().mag();
36  }
37 
38  void getValidDetIds(const HGCalGeometry* geom, std::unordered_set<DetId>& valid) {
39  const std::vector<DetId>& ids = geom->getValidDetIds();
40  valid.reserve(ids.size());
41  valid.insert(ids.begin(),ids.end());
42  }
43 
44  void getValidDetIds(const HcalGeometry* geom, std::unordered_set<DetId>& valid) {
45  const std::vector<DetId>& ids = geom->getValidDetIds();
46  for( const auto& id : ids ) {
47  if( HcalEndcap == id.subdetId() &&
48  DetId::Hcal == id.det() )
49  valid.emplace(id);
50  }
51  valid.reserve(valid.size());
52  }
53 
54  DetId simToReco(const HcalGeometry* geom, unsigned simid) {
55  DetId result(0);
56  const auto& topo = geom->topology();
57  const auto& dddConst = topo.dddConstants();
58 
59  int subdet, z, depth0, eta0, phi0, lay;
60  HcalTestNumbering::unpackHcalIndex(simid, subdet, z, depth0, eta0, phi0, lay);
61  int sign = (z==0) ? (-1):(1);
62  HcalDDDRecConstants::HcalID id = dddConst->getHCID(subdet, eta0, phi0, lay, depth0);
63  if (subdet==int(HcalEndcap)) {
64  result = HcalDetId(HcalEndcap,sign*id.eta,id.phi,id.depth);
65  }
66 
67  return result;
68  }
69 
70  DetId simToReco(const HGCalGeometry* geom, unsigned simId) {
71  DetId result(0);
72  const auto& topo = geom->topology();
73  const auto& dddConst = topo.dddConstants();
74 
75  int subdet, layer, cell, sec, subsec, zp;
76 
77  const bool isSqr = (dddConst.geomMode() == HGCalGeometryMode::Square);
78  if (isSqr) {
79  HGCalTestNumbering::unpackSquareIndex(simId, zp, layer, sec, subsec, cell);
80  } else {
81  HGCalTestNumbering::unpackHexagonIndex(simId, subdet, zp, layer, sec, subsec, cell);
82  //sec is wafer and subsec is celltyp
83  }
84  //skip this hit if after ganging it is not valid
85  std::pair<int,int> recoLayerCell=dddConst.simToReco(cell,layer,sec,topo.detectorType());
86  cell = recoLayerCell.first;
87  layer = recoLayerCell.second;
88  if (layer<0 || cell<0) {
89  return result;
90  }
91 
92  //assign the RECO DetId
93  result = HGCalDetId((ForwardSubdetector)subdet,zp,layer,subsec,sec,cell);
94 
95  return result;
96  }
97 }
98 
99 //
102  simHitAccumulator_( new HGCSimHitDataAccumulator() ),
103  mySubDet_(ForwardSubdetector::ForwardEmpty),
104  refSpeed_(0.1*CLHEP::c_light), //[CLHEP::c_light]=mm/ns convert to cm/ns
105  averageOccupancies_(occupancyGuesses),
106  nEvents_(1)
107 {
108  //configure from cfg
109  hitCollection_ = ps.getParameter< std::string >("hitCollection");
110  digiCollection_ = ps.getParameter< std::string >("digiCollection");
111  maxSimHitsAccTime_ = ps.getParameter< uint32_t >("maxSimHitsAccTime");
112  bxTime_ = ps.getParameter< double >("bxTime");
113  digitizationType_ = ps.getParameter< uint32_t >("digitizationType");
114  verbosity_ = ps.getUntrackedParameter< uint32_t >("verbosity",0);
115  tofDelay_ = ps.getParameter< double >("tofDelay");
116 
117  std::unordered_set<DetId>().swap(validIds_);
118 
119  iC.consumes<std::vector<PCaloHit> >(edm::InputTag("g4SimHits",hitCollection_));
120 
121  if(hitCollection_.find("HitsEE")!=std::string::npos) {
123  theHGCEEDigitizer_=std::unique_ptr<HGCEEDigitizer>(new HGCEEDigitizer(ps) );
124  }
125  if(hitCollection_.find("HitsHEfront")!=std::string::npos)
126  {
128  theHGCHEfrontDigitizer_=std::unique_ptr<HGCHEfrontDigitizer>(new HGCHEfrontDigitizer(ps) );
129  }
130  if(hitCollection_.find("HcalHits")!=std::string::npos)
131  {
133  theHGCHEbackDigitizer_=std::unique_ptr<HGCHEbackDigitizer>(new HGCHEbackDigitizer(ps) );
134  }
135 }
136 
137 //
139 {
140  // reserve memory for a full detector
141  unsigned idx = std::numeric_limits<unsigned>::max();
142  switch(mySubDet_) {
144  idx = 0;
145  break;
147  idx = 1;
148  break;
150  idx = 2;
151  break;
152  default:
153  break;
154  }
155  simHitAccumulator_->reserve( averageOccupancies_[idx]*validIds_.size() );
156 }
157 
158 //
159 void HGCDigitizer::finalizeEvent(edm::Event& e, edm::EventSetup const& es, CLHEP::HepRandomEngine* hre)
160 {
161 
162  const CaloSubdetectorGeometry* theGeom = ( nullptr == gHGCal_ ?
163  static_cast<const CaloSubdetectorGeometry*>(gHcal_) :
164  static_cast<const CaloSubdetectorGeometry*>(gHGCal_) );
165 
166  ++nEvents_;
167  unsigned idx = std::numeric_limits<unsigned>::max();
168  switch(mySubDet_) {
170  idx = 0;
171  break;
173  idx = 1;
174  break;
176  idx = 2;
177  break;
178  default:
179  break;
180  }
181  // release memory for unfilled parts of hash table
182  if( validIds_.size()*averageOccupancies_[idx] > simHitAccumulator_->size() ) {
183  simHitAccumulator_->reserve(simHitAccumulator_->size());
184  }
185  //update occupancy guess
186  const double thisOcc = simHitAccumulator_->size()/((double)validIds_.size());
187  averageOccupancies_[idx] = (averageOccupancies_[idx]*(nEvents_-1) + thisOcc)/nEvents_;
188 
189  if( producesEEDigis() )
190  {
191  std::unique_ptr<HGCEEDigiCollection> digiResult(new HGCEEDigiCollection() );
192  theHGCEEDigitizer_->run(digiResult,*simHitAccumulator_,theGeom,validIds_,digitizationType_, hre);
193  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " EE hits";
194  e.put(std::move(digiResult),digiCollection());
195  }
196  if( producesHEfrontDigis())
197  {
198  std::unique_ptr<HGCHEDigiCollection> digiResult(new HGCHEDigiCollection() );
200  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE front hits";
201  e.put(std::move(digiResult),digiCollection());
202  }
203  if( producesHEbackDigis() )
204  {
205  std::unique_ptr<HGCBHDigiCollection> digiResult(new HGCBHDigiCollection() );
207  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE back hits";
208  e.put(std::move(digiResult),digiCollection());
209  }
210 
212 }
213 
214 //
215 void HGCDigitizer::accumulate(edm::Event const& e, edm::EventSetup const& eventSetup, CLHEP::HepRandomEngine* hre) {
216 
217  //get inputs
219  e.getByLabel(edm::InputTag("g4SimHits",hitCollection_),hits);
220  if( !hits.isValid() ){
221  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
222  return;
223  }
224 
225  //accumulate in-time the main event
226  if( nullptr != gHGCal_ ) {
227  accumulate(hits, 0, gHGCal_, hre);
228  } else if( nullptr != gHcal_ ) {
229  accumulate(hits, 0, gHcal_, hre);
230  } else {
231  throw cms::Exception("BadConfiguration")
232  << "HGCDigitizer is not producing EE, FH, or BH digis!";
233  }
234 }
235 
236 //
237 void HGCDigitizer::accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& eventSetup, CLHEP::HepRandomEngine* hre) {
238 
239  //get inputs
241  e.getByLabel(edm::InputTag("g4SimHits",hitCollection_),hits);
242  if( !hits.isValid() ){
243  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
244  return;
245  }
246 
247  //accumulate for the simulated bunch crossing
248  if( nullptr != gHGCal_ ) {
249  accumulate(hits, e.bunchCrossing(), gHGCal_, hre);
250  } else if ( nullptr != gHcal_ ) {
251  accumulate(hits, e.bunchCrossing(), gHcal_, hre);
252  } else {
253  throw cms::Exception("BadConfiguration")
254  << "HGCDigitizer is not producing EE, FH, or BH digis!";
255  }
256 }
257 
258 //
259 template<typename GEOM>
261  int bxCrossing,
262  const GEOM* geom,
263  CLHEP::HepRandomEngine* hre) {
264  if( nullptr == geom ) return;
265 
266 
267 
268  //configuration to apply for the computation of time-of-flight
269  bool weightToAbyEnergy(false);
270  float tdcOnset(0.f),keV2fC(0.f);
271  switch( mySubDet_ ) {
273  weightToAbyEnergy = theHGCEEDigitizer_->toaModeByEnergy();
274  tdcOnset = theHGCEEDigitizer_->tdcOnset();
275  keV2fC = theHGCEEDigitizer_->keV2fC();
276  break;
278  weightToAbyEnergy = theHGCHEfrontDigitizer_->toaModeByEnergy();
279  tdcOnset = theHGCHEfrontDigitizer_->tdcOnset();
280  keV2fC = theHGCHEfrontDigitizer_->keV2fC();
281  break;
283  weightToAbyEnergy = theHGCHEbackDigitizer_->toaModeByEnergy();
284  tdcOnset = theHGCHEbackDigitizer_->tdcOnset();
285  keV2fC = theHGCHEbackDigitizer_->keV2fC();
286  break;
287  default:
288  break;
289  }
290 
291  //create list of tuples (pos in container, RECO DetId, time) to be sorted first
292  int nchits=(int)hits->size();
293  std::vector< HGCCaloHitTuple_t > hitRefs;
294  hitRefs.reserve(nchits);
295  for(int i=0; i<nchits; ++i) {
296  const auto& the_hit = hits->at(i);
297 
298  DetId id = simToReco(geom,the_hit.id());
299 
300  if (verbosity_>0) {
301  if (producesEEDigis())
302  edm::LogInfo("HGCDigitizer") << " i/p " << std::hex << the_hit.id() << std::dec << " o/p " << id.rawId() << std::endl;
303  else
304  edm::LogInfo("HGCDigitizer") << " i/p " << std::hex << the_hit.id() << std::dec << " o/p " << id.rawId() << std::endl;
305  }
306 
307  if( 0 != id.rawId() ) {
308  hitRefs.emplace_back( i, id.rawId(), (float)the_hit.time() );
309  }
310  }
311  std::sort(hitRefs.begin(),hitRefs.end(),this->orderByDetIdThenTime);
312 
313  //loop over sorted hits
314  nchits = hitRefs.size();
315  for(int i=0; i<nchits; ++i) {
316  const int hitidx = std::get<0>(hitRefs[i]);
317  const uint32_t id = std::get<1>(hitRefs[i]);
318 
319  //get the data for this cell, if not available then we skip it
320 
321  if( !validIds_.count(id) ) continue;
322  HGCSimHitDataAccumulator::iterator simHitIt = simHitAccumulator_->emplace(id,HGCCellInfo()).first;
323 
324  if(id==0) continue; // to be ignored at RECO level
325 
326  const float toa = std::get<2>(hitRefs[i]);
327  const PCaloHit &hit=hits->at( hitidx );
328  const float charge = hit.energy()*1e6*keV2fC;
329 
330  //distance to the center of the detector
331  const float dist2center( getPositionDistance(geom,id) );
332 
333  //hit time: [time()]=ns [centerDist]=cm [refSpeed_]=cm/ns + delay by 1ns
334  //accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples)
335  const float tof = toa-dist2center/refSpeed_+tofDelay_ ;
336  const int itime= std::floor( tof/bxTime_ ) + 9;
337 
338  //no need to add bx crossing - tof comes already corrected from the mixing module
339  //itime += bxCrossing;
340  //itime += 9;
341 
342  if(itime<0 || itime>14) continue;
343 
344  //check if time index is ok and store energy
345  if(itime >= (int)simHitIt->second.hit_info[0].size() ) continue;
346 
347  (simHitIt->second).hit_info[0][itime] += charge;
348  float accCharge=(simHitIt->second).hit_info[0][itime];
349 
350  //time-of-arrival (check how to be used)
351  if(weightToAbyEnergy) (simHitIt->second).hit_info[1][itime] += charge*tof;
352  else if((simHitIt->second).hit_info[1][itime]==0) {
353  if( accCharge>tdcOnset)
354  {
355  //extrapolate linear using previous simhit if it concerns to the same DetId
356  float fireTDC=tof;
357  if(i>0)
358  {
359  uint32_t prev_id = std::get<1>(hitRefs[i-1]);
360  if(prev_id==id)
361  {
362  float prev_toa = std::get<2>(hitRefs[i-1]);
363  float prev_tof(prev_toa-dist2center/refSpeed_+tofDelay_);
364  //float prev_charge = std::get<3>(hitRefs[i-1]);
365  float deltaQ2TDCOnset = tdcOnset-((simHitIt->second).hit_info[0][itime]-charge);
366  float deltaQ = charge;
367  float deltaT = (tof-prev_tof);
368  fireTDC = deltaT*(deltaQ2TDCOnset/deltaQ)+prev_tof;
369  }
370  }
371 
372  (simHitIt->second).hit_info[1][itime]=fireTDC;
373  }
374  }
375  }
376  hitRefs.clear();
377 }
378 
379 //
381 {
382  //get geometry
384  es.get<CaloGeometryRecord>().get(geom);
385 
386  gHGCal_ = nullptr;
387  gHcal_ = nullptr;
388 
389  if( producesEEDigis() ) gHGCal_ = dynamic_cast<const HGCalGeometry*>(geom->getSubdetectorGeometry(DetId::Forward, HGCEE));
390  if( producesHEfrontDigis() ) gHGCal_ = dynamic_cast<const HGCalGeometry*>(geom->getSubdetectorGeometry(DetId::Forward, HGCHEF));
391  if( producesHEbackDigis() ) gHcal_ = dynamic_cast<const HcalGeometry*>(geom->getSubdetectorGeometry(DetId::Hcal, HcalEndcap));
392 
393  int nadded(0);
394  //valid ID lists
395  if( nullptr != gHGCal_ ) {
396  getValidDetIds( gHGCal_, validIds_ );
397  } else if( nullptr != gHcal_ ) {
398  getValidDetIds( gHcal_, validIds_ );
399  } else {
400  throw cms::Exception("BadConfiguration")
401  << "HGCDigitizer is not producing EE, FH, or BH digis!";
402  }
403 
404  if (verbosity_ > 0)
405  edm::LogInfo("HGCDigitizer")
406  << "Added " << nadded << ":" << validIds_.size()
407  << " detIds without " << hitCollection_
408  << " in first event processed" << std::endl;
409 }
410 
411 //
413 {
414  std::unordered_set<DetId>().swap(validIds_);
415 }
416 
417 //
419 {
420  for( HGCSimHitDataAccumulator::iterator it = simHitAccumulator_->begin(); it!=simHitAccumulator_->end(); it++)
421  {
422  it->second.hit_info[0].fill(0.);
423  it->second.hit_info[1].fill(0.);
424  }
425 }
426 
427 template void HGCDigitizer::accumulate<HcalGeometry>(edm::Handle<edm::PCaloHitContainer> const &hits, int bxCrossing,const HcalGeometry *geom, CLHEP::HepRandomEngine* hre);
428 template void HGCDigitizer::accumulate<HGCalGeometry>(edm::Handle<edm::PCaloHitContainer> const &hits, int bxCrossing,const HGCalGeometry *geom, CLHEP::HepRandomEngine* hre);
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
uint32_t nEvents_
Definition: HGCDigitizer.h:116
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
const HcalDDDRecConstants * dddConstants() const
Definition: HcalTopology.h:150
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
edm::SortedCollection< HGCEEDataFrame > HGCEEDigiCollection
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
ForwardSubdetector mySubDet_
Definition: HGCDigitizer.h:103
int digitizationType_
Definition: HGCDigitizer.h:84
std::string hitCollection_
Definition: HGCDigitizer.h:81
void resetSimHitDataAccumulator()
double sign(double x)
void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
actions at the start/end of event
GlobalPoint getPosition(const DetId &id) const
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
Definition: HcalGeometry.h:99
ForwardSubdetector
const HGCalGeometry * gHGCal_
Definition: HGCDigitizer.h:99
bool producesEEDigis()
Definition: HGCDigitizer.h:67
#define constexpr
float float float z
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const
Get a list of valid detector ids (for the given subdetector)
Definition: HcalGeometry.cc:70
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
std::string digiCollection_
Definition: HGCDigitizer.h:81
const HcalTopology & topology() const
Definition: HcalGeometry.h:108
tuple result
Definition: mps_fire.py:84
std::unordered_map< uint32_t, HGCCellInfo > HGCSimHitDataAccumulator
T mag() const
Definition: PV3DBase.h:67
edm::SortedCollection< HGCBHDataFrame > HGCBHDigiCollection
void beginRun(const edm::EventSetup &es)
actions at the start/end of run
const HGCalTopology & topology() const
Definition: HGCalGeometry.h:96
virtual const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const override
Get a list of valid detector ids (for the given subdetector)
Definition: HGCalGeometry.h:76
def move
Definition: eostools.py:510
static void unpackHcalIndex(const uint32_t &idx, int &det, int &z, int &depth, int &eta, int &phi, int &lay)
double f[11][100]
std::unordered_set< DetId > validIds_
Definition: HGCDigitizer.h:98
bool isValid() const
Definition: HandleBase.h:75
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:413
bool producesHEfrontDigis()
Definition: HGCDigitizer.h:68
std::unique_ptr< HGCHEbackDigitizer > theHGCHEbackDigitizer_
Definition: HGCDigitizer.h:94
Definition: DetId.h:18
bool producesHEbackDigis()
Definition: HGCDigitizer.h:69
const HGCalDDDConstants & dddConstants() const
static void unpackSquareIndex(const uint32_t &idx, int &z, int &lay, int &sec, int &subsec, int &cell)
const T & get() const
Definition: EventSetup.h:56
int maxSimHitsAccTime_
Definition: HGCDigitizer.h:87
std::unique_ptr< HGCHEfrontDigitizer > theHGCHEfrontDigitizer_
Definition: HGCDigitizer.h:95
std::unique_ptr< HGCEEDigitizer > theHGCEEDigitizer_
Definition: HGCDigitizer.h:93
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
handle SimHit accumulation
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
HGCDigitizer(const edm::ParameterSet &ps, edm::ConsumesCollector &iC)
std::array< double, 3 > averageOccupancies_
Definition: HGCDigitizer.h:115
std::unique_ptr< hgc::HGCSimHitDataAccumulator > simHitAccumulator_
Definition: HGCDigitizer.h:89
static bool orderByDetIdThenTime(const HGCCaloHitTuple_t &a, const HGCCaloHitTuple_t &b)
Definition: HGCDigitizer.h:37
double bxTime_
Definition: HGCDigitizer.h:88
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
std::string digiCollection()
Definition: HGCDigitizer.h:70
edm::SortedCollection< HGCHEDataFrame > HGCHEDigiCollection
const HcalGeometry * gHcal_
Definition: HGCDigitizer.h:100
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
uint32_t verbosity_
Definition: HGCDigitizer.h:106