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.
17 
18 #include <algorithm>
19 #include <boost/foreach.hpp>
20 
21 using namespace hgc_digi;
22 
23 //
26  checkValidDetIds_(true),
27  simHitAccumulator_( new HGCSimHitDataAccumulator ),
28  mySubDet_(ForwardSubdetector::ForwardEmpty),
29  refSpeed_(0.1*CLHEP::c_light) //[CLHEP::c_light]=mm/ns convert to cm/ns
30 {
31  //configure from cfg
32  hitCollection_ = ps.getParameter< std::string >("hitCollection");
33  digiCollection_ = ps.getParameter< std::string >("digiCollection");
34  maxSimHitsAccTime_ = ps.getParameter< uint32_t >("maxSimHitsAccTime");
35  bxTime_ = ps.getParameter< double >("bxTime");
36  digitizationType_ = ps.getParameter< uint32_t >("digitizationType");
37  useAllChannels_ = ps.getParameter< bool >("useAllChannels");
38  verbosity_ = ps.getUntrackedParameter< uint32_t >("verbosity",0);
39  tofDelay_ = ps.getParameter< double >("tofDelay");
40 
41  iC.consumes<std::vector<PCaloHit> >(edm::InputTag("g4SimHits",hitCollection_));
42 
43  if(hitCollection_.find("HitsEE")!=std::string::npos) {
45  theHGCEEDigitizer_=std::unique_ptr<HGCEEDigitizer>(new HGCEEDigitizer(ps) );
46  }
47  if(hitCollection_.find("HitsHEfront")!=std::string::npos)
48  {
50  theHGCHEfrontDigitizer_=std::unique_ptr<HGCHEfrontDigitizer>(new HGCHEfrontDigitizer(ps) );
51  }
52  if(hitCollection_.find("HitsHEback")!=std::string::npos)
53  {
55  theHGCHEbackDigitizer_=std::unique_ptr<HGCHEbackDigitizer>(new HGCHEbackDigitizer(ps) );
56  }
57 }
58 
59 //
61 {
63 }
64 
65 //
66 void HGCDigitizer::finalizeEvent(edm::Event& e, edm::EventSetup const& es, CLHEP::HepRandomEngine* hre)
67 {
68  if( producesEEDigis() )
69  {
70  std::auto_ptr<HGCEEDigiCollection> digiResult(new HGCEEDigiCollection() );
72  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " EE hits";
73  e.put(digiResult,digiCollection());
74  }
76  {
77  std::auto_ptr<HGCHEDigiCollection> digiResult(new HGCHEDigiCollection() );
79  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE front hits";
80  e.put(digiResult,digiCollection());
81  }
82  if( producesHEbackDigis() )
83  {
84  std::auto_ptr<HGCHEDigiCollection> digiResult(new HGCHEDigiCollection() );
86  edm::LogInfo("HGCDigitizer") << " @ finalize event - produced " << digiResult->size() << " HE back hits";
87  e.put(digiResult,digiCollection());
88  }
89 }
90 
91 //
92 void HGCDigitizer::accumulate(edm::Event const& e, edm::EventSetup const& eventSetup, CLHEP::HepRandomEngine* hre) {
93 
94  //get inputs
96  e.getByLabel(edm::InputTag("g4SimHits",hitCollection_),hits);
97  if( !hits.isValid() ){
98  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
99  return;
100  }
101 
102  //get geometry
104  if( producesEEDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalEESensitive" , geom);
105  if( producesHEfrontDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalHESiliconSensitive" , geom);
106  if( producesHEbackDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalHEScintillatorSensitive", geom);
107 
108  //accumulate in-time the main event
109  accumulate(hits, 0, geom, hre);
110 }
111 
112 //
113 void HGCDigitizer::accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& eventSetup, CLHEP::HepRandomEngine* hre) {
114 
115  //get inputs
117  e.getByLabel(edm::InputTag("g4SimHits",hitCollection_),hits);
118  if( !hits.isValid() ){
119  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
120  return;
121  }
122 
123  //get geometry
125  if( producesEEDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalEESensitive" , geom);
126  if( producesHEfrontDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalHESiliconSensitive" , geom);
127  if( producesHEbackDigis() ) eventSetup.get<IdealGeometryRecord>().get("HGCalHEScintillatorSensitive", geom);
128 
129  //accumulate for the simulated bunch crossing
130  accumulate(hits, e.bunchCrossing(), geom, hre);
131 }
132 
133 //
135  int bxCrossing,
137  CLHEP::HepRandomEngine* hre)
138 {
139  if(!geom.isValid()) return;
140  const HGCalTopology &topo=geom->topology();
141  const HGCalDDDConstants &dddConst=topo.dddConstants();
142 
143  //base time samples for each DetId, initialized to 0
144  std::array<HGCSimHitData,2> baseData;
145  baseData[0].fill(0.); //accumulated energy
146  baseData[1].fill(0.); //time-of-flight
147 
148  //configuration to apply for the computation of time-of-flight
149  bool weightToAbyEnergy(false);
150  float tdcOnset(0),keV2fC(0.0);
151  switch( mySubDet_ ) {
153  weightToAbyEnergy = theHGCEEDigitizer_->toaModeByEnergy();
154  tdcOnset = theHGCEEDigitizer_->tdcOnset();
155  keV2fC = theHGCEEDigitizer_->keV2fC();
156  break;
158  weightToAbyEnergy = theHGCHEfrontDigitizer_->toaModeByEnergy();
159  tdcOnset = theHGCHEfrontDigitizer_->tdcOnset();
160  keV2fC = theHGCHEfrontDigitizer_->keV2fC();
161  break;
163  weightToAbyEnergy = theHGCHEbackDigitizer_->toaModeByEnergy();
164  tdcOnset = std::numeric_limits<float>::max();//theHGCHEbackDigitizer_->tdcOnset();
165  keV2fC = theHGCHEbackDigitizer_->keV2fC();
166  break;
167  default:
168  break;
169  }
170 
171  //create list of tuples (pos in container, RECO DetId, time) to be sorted first
172  int nchits=(int)hits->size();
173  std::vector< HGCCaloHitTuple_t > hitRefs(nchits);
174  for(int i=0; i<nchits; i++) {
175  int layer, cell, sec, subsec, zp;
176  uint32_t simId = hits->at(i).id();
177  if (dddConst.geomMode() == HGCalGeometryMode::Square) {
178  HGCalTestNumbering::unpackSquareIndex(simId, zp, layer, sec, subsec, cell);
179  } else {
180  int subdet;
181  HGCalTestNumbering::unpackHexagonIndex(simId, subdet, zp, layer, sec, subsec, cell);
182  mySubDet_ = (ForwardSubdetector)(subdet);
183  //sec is wafer and subsec is celltyp
184  }
185  //skip this hit if after ganging it is not valid
186  std::pair<int,int> recoLayerCell=dddConst.simToReco(cell,layer,sec,topo.detectorType());
187  cell = recoLayerCell.first;
188  layer = recoLayerCell.second;
189  if (layer<0 || cell<0) {
190  hitRefs[i]=std::make_tuple( i, 0, 0.);
191  continue;
192  }
193 
194  //assign the RECO DetId
195  DetId id;
196  if (dddConst.geomMode() == HGCalGeometryMode::Square) {
197  id = (producesEEDigis() ?
198  (uint32_t)HGCEEDetId(mySubDet_,zp,layer,sec,subsec,cell):
199  (uint32_t)HGCHEDetId(mySubDet_,zp,layer,sec,subsec,cell) );
200  } else {
201  id = HGCalDetId(mySubDet_,zp,layer,subsec,sec,cell);
202  }
203 
204  if (verbosity_>0) {
205  if (producesEEDigis())
206  edm::LogInfo("HGCDigitizer") <<" i/p " << std::hex << simId << std::dec << " o/p " << HGCEEDetId(id) << std::endl;
207  else
208  edm::LogInfo("HGCDigitizer") << " i/p " << std::hex << simId << std::dec << " o/p " << HGCHEDetId(id) << std::endl;
209  }
210 
211  hitRefs[i]=std::make_tuple( i,
212  id.rawId(),
213  (float)hits->at(i).time() );
214  }
215  std::sort(hitRefs.begin(),hitRefs.end(),this->orderByDetIdThenTime);
216 
217  //loop over sorted hits
218  for(int i=0; i<nchits; ++i) {
219  const int hitidx = std::get<0>(hitRefs[i]);
220  const uint32_t id = std::get<1>(hitRefs[i]);
221  if(id==0) continue; // to be ignored at RECO level
222 
223  const float toa = std::get<2>(hitRefs[i]);
224  const PCaloHit &hit=hits->at( hitidx );
225  const float charge = hit.energy()*1e6*keV2fC;
226 
227  //distance to the center of the detector
228  const float dist2center( geom->getPosition(id).mag() );
229 
230  //hit time: [time()]=ns [centerDist]=cm [refSpeed_]=cm/ns + delay by 1ns
231  //accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples)
232  const float tof = toa-dist2center/refSpeed_+tofDelay_ ;
233  const int itime= std::floor( tof/bxTime_ ) + 9;
234 
235  //no need to add bx crossing - tof comes already corrected from the mixing module
236  //itime += bxCrossing;
237  //itime += 9;
238 
239  if(itime<0 || itime>14) continue;
240 
241  //check if already existing (perhaps could remove this in the future - 2nd event should have all defined)
242  HGCSimHitDataAccumulator::iterator simHitIt=simHitAccumulator_->find(id);
243  if(simHitIt == simHitAccumulator_->end()) {
244  simHitIt = simHitAccumulator_->insert( std::make_pair(id,baseData) ).first;
245  }
246 
247  //check if time index is ok and store energy
248  if(itime >= (int)simHitIt->second[0].size() ) continue;
249 
250  (simHitIt->second)[0][itime] += charge;
251  float accCharge=(simHitIt->second)[0][itime];
252 
253  //time-of-arrival (check how to be used)
254  if(weightToAbyEnergy) (simHitIt->second)[1][itime] += charge*tof;
255  else if((simHitIt->second)[1][itime]==0)
256  {
257  if( accCharge>tdcOnset)
258  {
259  //extrapolate linear using previous simhit if it concerns to the same DetId
260  float fireTDC=tof;
261  if(i>0)
262  {
263  uint32_t prev_id = std::get<1>(hitRefs[i-1]);
264  if(prev_id==id)
265  {
266  float prev_toa = std::get<2>(hitRefs[i-1]);
267  float prev_tof(prev_toa-dist2center/refSpeed_+tofDelay_);
268  //float prev_charge = std::get<3>(hitRefs[i-1]);
269  float deltaQ2TDCOnset = tdcOnset-((simHitIt->second)[0][itime]-charge);
270  float deltaQ = charge;
271  float deltaT = (tof-prev_tof);
272  fireTDC = deltaT*(deltaQ2TDCOnset/deltaQ)+prev_tof;
273  }
274  }
275 
276  (simHitIt->second)[1][itime]=fireTDC;
277  }
278  }
279  }
280  hitRefs.clear();
281 
282  //add base data for noise simulation
283  if(!checkValidDetIds_) return;
284  if(!geom.isValid()) return;
285  const std::vector<DetId> &validIds=geom->getValidDetIds();
286  int nadded(0);
287  if (useAllChannels_) {
288  for(std::vector<DetId>::const_iterator it=validIds.begin(); it!=validIds.end(); it++) {
289  uint32_t id(it->rawId());
290  simHitAccumulator_->emplace(id, baseData);
291  nadded++;
292  }
293  }
294 
295  if (verbosity_ > 0)
296  edm::LogInfo("HGCDigitizer")
297  << "Added " << nadded << ":" << validIds.size()
298  << " detIds without " << hitCollection_
299  << " in first event processed" << std::endl;
300  checkValidDetIds_=false;
301 }
302 
303 //
305 {
306 }
307 
308 //
310 {
311 }
312 
313 //
315 {
316  for( HGCSimHitDataAccumulator::iterator it = simHitAccumulator_->begin(); it!=simHitAccumulator_->end(); it++)
317  {
318  it->second[0].fill(0.);
319  it->second[1].fill(0.);
320  }
321 }
322 
323 
324 
325 
326 
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
edm::SortedCollection< HGCEEDataFrame > HGCEEDigiCollection
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
Definition: HGCDigitizer.cc:66
ForwardSubdetector mySubDet_
Definition: HGCDigitizer.h:97
int digitizationType_
Definition: HGCDigitizer.h:83
std::string hitCollection_
Definition: HGCDigitizer.h:80
void resetSimHitDataAccumulator()
ProductID id() const
Definition: HandleBase.cc:15
bool useAllChannels_
Definition: HGCDigitizer.h:100
bool checkValidDetIds_
Definition: HGCDigitizer.h:77
void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
actions at the start/end of event
Definition: HGCDigitizer.cc:60
bool detectorType() const
ForwardSubdetector
bool producesEEDigis()
Definition: HGCDigitizer.h:63
std::string digiCollection_
Definition: HGCDigitizer.h:80
std::pair< int, int > simToReco(int cell, int layer, int mod, bool half) const
void beginRun(const edm::EventSetup &es)
actions at the start/end of run
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
HGCalGeometryMode geomMode() const
bool isValid() const
Definition: HandleBase.h:75
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:418
bool producesHEfrontDigis()
Definition: HGCDigitizer.h:64
std::unique_ptr< HGCHEbackDigitizer > theHGCHEbackDigitizer_
Definition: HGCDigitizer.h:93
Definition: DetId.h:18
bool producesHEbackDigis()
Definition: HGCDigitizer.h:65
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:86
std::unique_ptr< HGCHEfrontDigitizer > theHGCHEfrontDigitizer_
Definition: HGCDigitizer.h:94
std::unique_ptr< HGCEEDigitizer > theHGCEEDigitizer_
Definition: HGCDigitizer.h:92
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
handle SimHit accumulation
Definition: HGCDigitizer.cc:92
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
HGCDigitizer(const edm::ParameterSet &ps, edm::ConsumesCollector &iC)
Definition: HGCDigitizer.cc:24
std::unique_ptr< hgc::HGCSimHitDataAccumulator > simHitAccumulator_
Definition: HGCDigitizer.h:88
static bool orderByDetIdThenTime(const HGCCaloHitTuple_t &a, const HGCCaloHitTuple_t &b)
Definition: HGCDigitizer.h:34
bool isValid() const
Definition: ESHandle.h:47
double bxTime_
Definition: HGCDigitizer.h:87
std::unordered_map< uint32_t, std::array< HGCSimHitData, 2 > > HGCSimHitDataAccumulator
std::string digiCollection()
Definition: HGCDigitizer.h:66
edm::SortedCollection< HGCHEDataFrame > HGCHEDigiCollection
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:101