CMS 3D CMS Logo

FTLDigitizer.h
Go to the documentation of this file.
1 #ifndef FastTimingSimProducers_FastTimingCommon_FTLDigitizer_h
2 #define FastTimingSimProducers_FastTimingCommon_FTLDigitizer_h
3 
5 
9 
14 
17 
19 
20 #include <vector>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include <memory>
24 #include <tuple>
25 
26 
27 namespace ftl_digitizer {
28 
29  namespace FTLHelpers {
30  // index , det id, time
31  typedef std::tuple<int,uint32_t,float> FTLCaloHitTuple_t;
32 
33  bool orderByDetIdThenTime(const FTLCaloHitTuple_t &a, const FTLCaloHitTuple_t &b)
34  {
35  unsigned int detId_a(std::get<1>(a)), detId_b(std::get<1>(b));
36 
37  if(detId_a<detId_b) return true;
38  if(detId_a>detId_b) return false;
39 
40  double time_a(std::get<2>(a)), time_b(std::get<2>(b));
41  if(time_a<time_b) return true;
42 
43  return false;
44  }
45  }
46 
47  template<class SensorPhysics, class ElectronicsSim>
49  {
50  public:
51 
55  FTLDigitizerBase(config,iC,parent),
56  deviceSim_( config.getParameterSet("DeviceSimulation") ),
57  electronicsSim_( config.getParameterSet("ElectronicsSimulation") ),
58  maxSimHitsAccTime_( config.getParameter< uint32_t >("maxSimHitsAccTime") ),
59  bxTime_( config.getParameter< double >("bxTime") ),
60  tofDelay_( config.getParameter< double >("tofDelay") ) { }
61 
62  ~FTLDigitizer() override { }
63 
67  void accumulate(edm::Event const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override;
68  void accumulate(PileUpEventPrincipal const& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override;
69  void accumulate(edm::Handle<edm::PSimHitContainer> const &hits, int bxCrossing, CLHEP::HepRandomEngine* hre) override;
70 
74  void initializeEvent(edm::Event const& e, edm::EventSetup const& c) override;
75  void finalizeEvent(edm::Event& e, edm::EventSetup const& c, CLHEP::HepRandomEngine* hre) override;
76 
80  void beginRun(const edm::EventSetup & es) override;
81  void endRun() override {}
82 
83  private :
84 
86  FTLSimHitDataAccumulator().swap(simHitAccumulator_);
87  }
88 
89  // implementations
90  SensorPhysics deviceSim_; // processes a given simhit into an entry in a FTLSimHitDataAccumulator
91  ElectronicsSim electronicsSim_; // processes a FTLSimHitDataAccumulator into a FTLDigiCollection
92 
93  //handle sim hits
94  const int maxSimHitsAccTime_;
95  const double bxTime_;
97 
98  //delay to apply after evaluating time of arrival at the sensitive detector
99  const float tofDelay_;
100 
101  //geometries
102  std::unordered_set<DetId> validIds_;
105  };
106 
107  template<class SensorPhysics, class ElectronicsSim>
109  edm::EventSetup const& c,
110  CLHEP::HepRandomEngine* hre) {
112  e.getByLabel(inputSimHits_, simHits);
113  accumulate(simHits,0,hre);
114  }
115 
116  template<class SensorPhysics, class ElectronicsSim>
118  edm::EventSetup const& c,
119  CLHEP::HepRandomEngine* hre){
121  e.getByLabel(inputSimHits_, simHits);
122  accumulate(simHits,e.bunchCrossing(),hre);
123  }
124 
125  template<class SensorPhysics, class ElectronicsSim>
127  int bxCrossing,
128  CLHEP::HepRandomEngine* hre) {
129  using namespace FTLHelpers;
130  //configuration to apply for the computation of time-of-flight
131  bool weightToAbyEnergy(false);
132  float tdcOnset(0.f);
133 
134  //create list of tuples (pos in container, RECO DetId, time) to be sorted first
135  int nchits=(int)hits->size();
136  std::vector< FTLCaloHitTuple_t > hitRefs;
137  hitRefs.reserve(nchits);
138  for(int i=0; i<nchits; ++i) {
139  const auto& the_hit = hits->at(i);
140 
141  DetId id = ( validIds_.count(the_hit.detUnitId()) ? the_hit.detUnitId() : 0 );
142 
143  if (verbosity_>0) {
144  edm::LogInfo("HGCDigitizer") << " i/p " << std::hex << the_hit.detUnitId() << std::dec
145  << " o/p " << id.rawId() << std::endl;
146  }
147 
148  if( 0 != id.rawId() ) {
149  hitRefs.emplace_back( i, id.rawId(), the_hit.tof() );
150  }
151  }
152  std::sort(hitRefs.begin(),hitRefs.end(),FTLHelpers::orderByDetIdThenTime);
153 
154  //loop over sorted hits
155  nchits = hitRefs.size();
156  for(int i=0; i<nchits; ++i) {
157  const int hitidx = std::get<0>(hitRefs[i]);
158  const uint32_t id = std::get<1>(hitRefs[i]);
159 
160  //get the data for this cell, if not available then we skip it
161 
162  if( !validIds_.count(id) ) continue;
163  auto simHitIt = simHitAccumulator_.emplace(id,FTLCellInfo()).first;
164 
165  if(id==0) continue; // to be ignored at RECO level
166 
167  const float toa = std::get<2>(hitRefs[i]);
168  const PSimHit &hit=hits->at( hitidx );
169  const float charge = deviceSim_.getChargeForHit(hit);
170 
171  //distance to the center of the detector
172  const float dist2center( 0.1f*hit.entryPoint().mag() );
173 
174  //hit time: [time()]=ns [centerDist]=cm [refSpeed_]=cm/ns + delay by 1ns
175  //accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples)
176  const float tof = toa-dist2center/refSpeed_+tofDelay_ ;
177  const int itime= std::floor( tof/bxTime_ ) + 9;
178 
179  //no need to add bx crossing - tof comes already corrected from the mixing module
180  //itime += bxCrossing;
181  //itime += 9;
182 
183  if(itime<0 || itime>14) continue;
184 
185  //check if time index is ok and store energy
186  if(itime >= (int)simHitIt->second.hit_info[0].size() ) continue;
187 
188  (simHitIt->second).hit_info[0][itime] += charge;
189  float accCharge=(simHitIt->second).hit_info[0][itime];
190 
191  //time-of-arrival (check how to be used)
192  if(weightToAbyEnergy) (simHitIt->second).hit_info[1][itime] += charge*tof;
193  else if((simHitIt->second).hit_info[1][itime]==0)
194  {
195  if( accCharge>tdcOnset )
196  {
197  //extrapolate linear using previous simhit if it concerns to the same DetId
198  float fireTDC=tof;
199  if(i>0)
200  {
201  uint32_t prev_id = std::get<1>(hitRefs[i-1]);
202  if(prev_id==id)
203  {
204  float prev_toa = std::get<2>(hitRefs[i-1]);
205  float prev_tof(prev_toa-dist2center/refSpeed_+tofDelay_);
206  //float prev_charge = std::get<3>(hitRefs[i-1]);
207  float deltaQ2TDCOnset = tdcOnset-((simHitIt->second).hit_info[0][itime]-charge);
208  float deltaQ = charge;
209  float deltaT = (tof-prev_tof);
210  fireTDC = deltaT*(deltaQ2TDCOnset/deltaQ)+prev_tof;
211  }
212  }
213 
214  (simHitIt->second).hit_info[1][itime]=fireTDC;
215  }
216  }
217  }
218  hitRefs.clear();
219  }
220 
221  template<class SensorPhysics, class ElectronicsSim>
223  deviceSim_.getEvent(e);
224  electronicsSim_.getEvent(e);
225  }
226 
227  template<class SensorPhysics, class ElectronicsSim>
229  CLHEP::HepRandomEngine* hre) {
230  auto digiCollection = std::make_unique<FTLDigiCollection>();
231 
232  electronicsSim_.run(simHitAccumulator_,*digiCollection);
233 
234  e.put(std::move(digiCollection),digiCollection_);
235 
236  //release memory for next event
237  resetSimHitDataAccumulator();
238  }
239 
240 
241  template<class SensorPhysics, class ElectronicsSim>
243  if ( idealGeomWatcher_.check(es) ) {
245  es.get<IdealGeometryRecord>().get(dddFTL_);
246  { // force scope for the temporary nameless unordered_set
247  std::unordered_set<DetId>().swap(validIds_);
248  }
249  // recalculate valid detids
250  for( int zside = -1; zside <= 1; zside += 2 ) {
251  for( unsigned type = 1; type <= 2; ++type ) {
252  for( unsigned izeta = 0; izeta < 1<<10; ++izeta ) {
253  for( unsigned iphi = 0; iphi < 1<<10; ++iphi ) {
254 
255  if( dddFTL_->isValidXY(type, izeta, iphi) ) {
256  validIds_.emplace( FastTimeDetId( type,
257  izeta,
258  iphi,
259  zside ) );
260  }
261 
262  }
263  }
264  }
265  }
266  validIds_.reserve(validIds_.size());
267  }
268  deviceSim_.getEventSetup(es);
269  electronicsSim_.getEventSetup(es);
270  }
271 }
272 
273 
274 #endif
275 
276 
277 
type
Definition: HCALResponse.h:21
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:136
edm::ESHandle< FastTimeDDDConstants > dddFTL_
Definition: FTLDigitizer.h:104
ElectronicsSim electronicsSim_
Definition: FTLDigitizer.h:91
ParameterSet const & getParameterSet(ParameterSetID const &id)
edm::ESWatcher< IdealGeometryRecord > idealGeomWatcher_
Definition: FTLDigitizer.h:103
Definition: config.py:1
int zside(DetId const &)
std::unordered_set< DetId > validIds_
Definition: FTLDigitizer.h:102
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
std::unordered_map< uint32_t, FTLCellInfo > FTLSimHitDataAccumulator
void beginRun(const edm::EventSetup &es) override
actions at the start/end of run
Definition: FTLDigitizer.h:242
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre) override
Definition: FTLDigitizer.h:228
std::tuple< int, uint32_t, float > FTLCaloHitTuple_t
Definition: FTLDigitizer.h:31
double f[11][100]
FTLDigitizer(const edm::ParameterSet &config, edm::ConsumesCollector &iC, edm::ProducerBase &parent)
Definition: FTLDigitizer.h:52
FTLSimHitDataAccumulator simHitAccumulator_
Definition: FTLDigitizer.h:96
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:475
Definition: DetId.h:18
const T & get() const
Definition: EventSetup.h:59
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
actions at the start/end of event
Definition: FTLDigitizer.h:222
bool orderByDetIdThenTime(const FTLCaloHitTuple_t &a, const FTLCaloHitTuple_t &b)
Definition: FTLDigitizer.h:33
def move(src, dest)
Definition: eostools.py:510
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre) override
handle SimHit accumulation
Definition: FTLDigitizer.h:108