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