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  if(itime<0 || itime>14) continue;
180 
181  //check if time index is ok and store energy
182  if(itime >= (int)simHitIt->second.hit_info[0].size() ) continue;
183 
184  (simHitIt->second).hit_info[0][itime] += charge;
185  float accCharge=(simHitIt->second).hit_info[0][itime];
186 
187  //time-of-arrival (check how to be used)
188  if(weightToAbyEnergy) (simHitIt->second).hit_info[1][itime] += charge*tof;
189  else if((simHitIt->second).hit_info[1][itime]==0)
190  {
191  if( accCharge>tdcOnset )
192  {
193  //extrapolate linear using previous simhit if it concerns to the same DetId
194  float fireTDC=tof;
195  if(i>0)
196  {
197  uint32_t prev_id = std::get<1>(hitRefs[i-1]);
198  if(prev_id==id)
199  {
200  float prev_toa = std::get<2>(hitRefs[i-1]);
201  float prev_tof(prev_toa-dist2center/refSpeed_+tofDelay_);
202  float deltaQ2TDCOnset = tdcOnset-((simHitIt->second).hit_info[0][itime]-charge);
203  float deltaQ = charge;
204  float deltaT = (tof-prev_tof);
205  fireTDC = deltaT*(deltaQ2TDCOnset/deltaQ)+prev_tof;
206  }
207  }
208 
209  (simHitIt->second).hit_info[1][itime]=fireTDC;
210  }
211  }
212  }
213  hitRefs.clear();
214  }
215 
216  template<class SensorPhysics, class ElectronicsSim>
218  deviceSim_.getEvent(e);
219  electronicsSim_.getEvent(e);
220  }
221 
222  template<class SensorPhysics, class ElectronicsSim>
224  CLHEP::HepRandomEngine* hre) {
225  auto digiCollection = std::make_unique<FTLDigiCollection>();
226 
227  electronicsSim_.run(simHitAccumulator_,*digiCollection);
228 
229  e.put(std::move(digiCollection),digiCollection_);
230 
231  //release memory for next event
232  resetSimHitDataAccumulator();
233  }
234 
235 
236  template<class SensorPhysics, class ElectronicsSim>
238  if ( idealGeomWatcher_.check(es) ) {
240  es.get<IdealGeometryRecord>().get(dddFTL_);
241  { // force scope for the temporary nameless unordered_set
242  std::unordered_set<DetId>().swap(validIds_);
243  }
244  // recalculate valid detids
245  for( int zside = -1; zside <= 1; zside += 2 ) {
246  for( unsigned type = 1; type <= 2; ++type ) {
247  for( unsigned izeta = 0; izeta < 1<<10; ++izeta ) {
248  for( unsigned iphi = 0; iphi < 1<<10; ++iphi ) {
249 
250  if( dddFTL_->isValidXY(type, izeta, iphi) ) {
251  validIds_.emplace( FastTimeDetId( type,
252  izeta,
253  iphi,
254  zside ) );
255  }
256 
257  }
258  }
259  }
260  }
261  validIds_.reserve(validIds_.size());
262  }
263  deviceSim_.getEventSetup(es);
264  electronicsSim_.getEventSetup(es);
265  }
266 }
267 
268 
269 #endif
270 
271 
272 
type
Definition: HCALResponse.h:21
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
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:237
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre) override
Definition: FTLDigitizer.h:223
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:535
Definition: DetId.h:18
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
T get() const
Definition: EventSetup.h:68
void initializeEvent(edm::Event const &e, edm::EventSetup const &c) override
actions at the start/end of event
Definition: FTLDigitizer.h:217
bool orderByDetIdThenTime(const FTLCaloHitTuple_t &a, const FTLCaloHitTuple_t &b)
Definition: FTLDigitizer.h:33
def move(src, dest)
Definition: eostools.py:511
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre) override
handle SimHit accumulation
Definition: FTLDigitizer.h:108