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