CMS 3D CMS Logo

DeDxHitInfoProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: DeDxHitInfoProducer
4 // Class: DeDxHitInfoProducer
5 //
13 //
14 // Original Author: loic Quertenmont (querten)
15 // Created: Mon Nov 21 14:09:02 CEST 2014
16 // Modifications: Tamas Almos Vami (2022)
17 
18 // system include files
19 #include <memory>
20 
40 
41 using namespace reco;
42 using namespace std;
43 using namespace edm;
44 
46 public:
47  explicit DeDxHitInfoProducer(const edm::ParameterSet&);
48  ~DeDxHitInfoProducer() override;
49 
50 private:
51  void beginRun(edm::Run const& run, const edm::EventSetup&) override;
52  void produce(edm::Event&, const edm::EventSetup&) override;
53 
54  void makeCalibrationMap(const TrackerGeometry& tkGeom_);
55  void processHit(const TrackingRecHit* recHit,
56  const float trackMomentum,
57  const float cosine,
58  reco::DeDxHitInfo& hitDeDxInfo,
59  const LocalPoint& hitLocalPos);
60 
61  // ----------member data ---------------------------
62  const bool usePixel_;
63  const bool useStrip_;
64  const float theMeVperADCPixel_;
65  const float theMeVperADCStrip_;
66 
67  const unsigned int minTrackHits_;
68  const float minTrackPt_;
69  const float minTrackPtPrescale_;
70  const float maxTrackEta_;
71 
73  const bool useCalibration_;
74  const bool doShapeTest_;
75 
76  const unsigned int lowPtTracksPrescalePass_, lowPtTracksPrescaleFail_;
80 
84 
85  std::vector<std::vector<float>> calibGains_;
86  unsigned int offsetDU_;
87 
89  uint64_t x = state[0];
90  uint64_t const y = state[1];
91  state[0] = y;
92  x ^= x << 23; // a
93  state[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
94  return state[1] + y;
95  }
96 };
97 
99  : usePixel_(iConfig.getParameter<bool>("usePixel")),
100  useStrip_(iConfig.getParameter<bool>("useStrip")),
101  theMeVperADCPixel_(iConfig.getParameter<double>("MeVperADCPixel")),
102  theMeVperADCStrip_(iConfig.getParameter<double>("MeVperADCStrip")),
103  minTrackHits_(iConfig.getParameter<unsigned>("minTrackHits")),
104  minTrackPt_(iConfig.getParameter<double>("minTrackPt")),
105  minTrackPtPrescale_(iConfig.getParameter<double>("minTrackPtPrescale")),
106  maxTrackEta_(iConfig.getParameter<double>("maxTrackEta")),
107  calibrationPath_(iConfig.getParameter<string>("calibrationPath")),
108  useCalibration_(iConfig.getParameter<bool>("useCalibration")),
109  doShapeTest_(iConfig.getParameter<bool>("shapeTest")),
110  lowPtTracksPrescalePass_(iConfig.getParameter<uint32_t>("lowPtTracksPrescalePass")),
111  lowPtTracksPrescaleFail_(iConfig.getParameter<uint32_t>("lowPtTracksPrescaleFail")),
112  lowPtTracksEstimator_(iConfig.getParameter<edm::ParameterSet>("lowPtTracksEstimatorParameters")),
113  lowPtTracksDeDxThreshold_(iConfig.getParameter<double>("lowPtTracksDeDxThreshold")),
114  usePixelForPrescales_(iConfig.getParameter<bool>("usePixelForPrescales")),
115  tracksToken_(consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"))),
117  produces<reco::DeDxHitInfoCollection>();
118  produces<reco::DeDxHitInfoAss>();
119  produces<edm::ValueMap<int>>("prescale");
120 
121  if (!usePixel_ && !useStrip_)
122  edm::LogError("DeDxHitsProducer") << "No Pixel Hits NOR Strip Hits will be saved. Running this module is useless";
123 }
124 
126 
127 // ------------ method called once each job just before starting event loop ------------
128 void DeDxHitInfoProducer::beginRun(edm::Run const& iRun, const edm::EventSetup& iSetup) {
129  tkGeom_ = iSetup.getHandle(tkGeomToken_);
130  if (useCalibration_ && calibGains_.empty()) {
131  offsetDU_ = tkGeom_->offsetDU(GeomDetEnumerators::PixelBarrel); //index start at the first pixel
132 
134  }
135 }
136 
138  edm::Handle<reco::TrackCollection> trackCollectionHandle;
139  iEvent.getByToken(tracksToken_, trackCollectionHandle);
140  const TrackCollection& trackCollection(*trackCollectionHandle.product());
141 
142  // creates the output collection
143  auto resultdedxHitColl = std::make_unique<reco::DeDxHitInfoCollection>();
144 
145  std::vector<int> indices;
146  std::vector<int> prescales;
147  uint64_t state[2] = {iEvent.id().event(), iEvent.id().luminosityBlock()};
148  for (unsigned int j = 0; j < trackCollection.size(); j++) {
150 
151  //track selection
152  bool passPt = (track.pt() >= minTrackPt_), passLowDeDx = false, passHighDeDx = false, pass = passPt;
153  if (!pass && (track.pt() >= minTrackPtPrescale_)) {
154  if (lowPtTracksPrescalePass_ > 0) {
155  passHighDeDx = ((xorshift128p(state) % lowPtTracksPrescalePass_) == 0);
156  }
157  if (lowPtTracksPrescaleFail_ > 0) {
158  passLowDeDx = ((xorshift128p(state) % lowPtTracksPrescaleFail_) == 0);
159  }
160  pass = passHighDeDx || passLowDeDx;
161  }
162  if (!pass || std::abs(track.eta()) > maxTrackEta_ || track.numberOfValidHits() < minTrackHits_) {
163  indices.push_back(-1);
164  continue;
165  }
166 
167  reco::DeDxHitInfo hitDeDxInfo;
168  auto const& trajParams = track.extra()->trajParams();
169  auto hb = track.recHitsBegin();
170  for (unsigned int h = 0; h < track.recHitsSize(); h++) {
171  auto recHit = *(hb + h);
173  continue;
174 
175  auto trackDirection = trajParams[h].direction();
176  float cosine = trackDirection.z() / trackDirection.mag();
177 
178  processHit(recHit, track.p(), cosine, hitDeDxInfo, trajParams[h].position());
179  }
180 
181  if (!passPt) {
182  std::vector<DeDxHit> hits;
183  hits.reserve(hitDeDxInfo.size());
184  for (unsigned int i = 0, n = hitDeDxInfo.size(); i < n; ++i) {
185  if (hitDeDxInfo.detId(i).subdetId() <= 2 && usePixelForPrescales_) {
186  hits.push_back(DeDxHit(hitDeDxInfo.charge(i) / hitDeDxInfo.pathlength(i) * theMeVperADCPixel_, 0, 0, 0));
187  } else if (hitDeDxInfo.detId(i).subdetId() > 2) {
188  if (doShapeTest_ && !deDxTools::shapeSelection(*hitDeDxInfo.stripCluster(i)))
189  continue;
190  hits.push_back(DeDxHit(hitDeDxInfo.charge(i) / hitDeDxInfo.pathlength(i) * theMeVperADCStrip_, 0, 0, 0));
191  }
192  }
193 
194  // In case we have a pixel only track, but usePixelForPrescales_ is false
195  if (hits.empty()) {
196  indices.push_back(-1);
197  continue;
198  }
199  std::sort(hits.begin(), hits.end(), std::less<DeDxHit>());
201  if (passLowDeDx) {
203  } else {
204  indices.push_back(-1);
205  continue;
206  }
207  } else {
208  if (passHighDeDx) {
210  } else {
211  indices.push_back(-1);
212  continue;
213  }
214  }
215  } else {
216  prescales.push_back(1);
217  }
218  indices.push_back(resultdedxHitColl->size());
219  resultdedxHitColl->push_back(hitDeDxInfo);
220  }
222 
223  edm::OrphanHandle<reco::DeDxHitInfoCollection> dedxHitCollHandle = iEvent.put(std::move(resultdedxHitColl));
224 
225  //create map passing the handle to the matched collection
226  auto dedxMatch = std::make_unique<reco::DeDxHitInfoAss>(dedxHitCollHandle);
228  filler.insert(trackCollectionHandle, indices.begin(), indices.end());
229  filler.fill();
230  iEvent.put(std::move(dedxMatch));
231 
232  auto dedxPrescale = std::make_unique<edm::ValueMap<int>>();
233  edm::ValueMap<int>::Filler pfiller(*dedxPrescale);
234  pfiller.insert(dedxHitCollHandle, prescales.begin(), prescales.end());
235  pfiller.fill();
236  iEvent.put(std::move(dedxPrescale), "prescale");
237 }
238 
240  const float trackMomentum,
241  const float cosine,
242  reco::DeDxHitInfo& hitDeDxInfo,
243  const LocalPoint& hitLocalPos) {
244  auto const& thit = static_cast<BaseTrackerRecHit const&>(*recHit);
245  if (!thit.isValid())
246  return;
247 
248  //make sure cosine is not 0
249  float cosineAbs = std::max(0.00000001f, std::abs(cosine));
250 
251  auto const& clus = thit.firstClusterRef();
252  if (!clus.isValid())
253  return;
254 
255  const auto* detUnit = recHit->detUnit();
256  if (detUnit == nullptr) {
257  detUnit = tkGeom_->idToDet(thit.geographicalId());
258  }
259  float pathLen = detUnit->surface().bounds().thickness() / cosineAbs;
260 
261  if (clus.isPixel()) {
262  if (!usePixel_)
263  return;
264 
265  float chargeAbs = clus.pixelCluster().charge();
266  hitDeDxInfo.addHit(chargeAbs, pathLen, thit.geographicalId(), hitLocalPos, clus.pixelCluster());
267  } else if (clus.isStrip() && !thit.isMatched()) {
268  if (!useStrip_)
269  return;
270 
271  int NSaturating = 0;
272  float chargeAbs = deDxTools::getCharge(&(clus.stripCluster()), NSaturating, *detUnit, calibGains_, offsetDU_);
273  hitDeDxInfo.addHit(chargeAbs, pathLen, thit.geographicalId(), hitLocalPos, clus.stripCluster());
274  } else if (clus.isStrip() && thit.isMatched()) {
275  if (!useStrip_)
276  return;
277  const SiStripMatchedRecHit2D* matchedHit = dynamic_cast<const SiStripMatchedRecHit2D*>(recHit);
278  if (!matchedHit)
279  return;
280 
281  const auto* detUnitM = matchedHit->monoHit().detUnit();
282  if (detUnitM == nullptr)
283  detUnitM = tkGeom_->idToDet(matchedHit->monoHit().geographicalId());
284  int NSaturating = 0;
285  auto pathLenM = detUnitM->surface().bounds().thickness() / cosineAbs;
286  float chargeAbs =
287  deDxTools::getCharge(&(matchedHit->monoHit().stripCluster()), NSaturating, *detUnitM, calibGains_, offsetDU_);
288  hitDeDxInfo.addHit(chargeAbs, pathLenM, thit.geographicalId(), hitLocalPos, matchedHit->monoHit().stripCluster());
289 
290  const auto* detUnitS = matchedHit->stereoHit().detUnit();
291  if (detUnitS == nullptr)
292  detUnitS = tkGeom_->idToDet(matchedHit->stereoHit().geographicalId());
293  NSaturating = 0;
294  auto pathLenS = detUnitS->surface().bounds().thickness() / cosineAbs;
295  chargeAbs =
296  deDxTools::getCharge(&(matchedHit->stereoHit().stripCluster()), NSaturating, *detUnitS, calibGains_, offsetDU_);
297  hitDeDxInfo.addHit(chargeAbs, pathLenS, thit.geographicalId(), hitLocalPos, matchedHit->stereoHit().stripCluster());
298  }
299 }
300 
301 //define this as a plug-in
float pathlength(size_t i) const
Definition: DeDxHitInfo.h:43
const unsigned int minTrackHits_
const std::string calibrationPath_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
SiStripRecHit2D stereoHit() const
const GeomDetUnit * detUnit() const override
bool isFromDet(TrackingRecHit const &hit)
unsigned int offsetDU(SubDetector sid) const
T const * product() const
Definition: Handle.h:70
const unsigned int lowPtTracksPrescaleFail_
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
void produce(edm::Event &, const edm::EventSetup &) override
int getCharge(const SiStripCluster *cluster, int &nSatStrip, const GeomDetUnit &detUnit, const std::vector< std::vector< float >> &calibGains, const unsigned int &m_off)
Log< level::Error, false > LogError
const edm::EDGetTokenT< reco::TrackCollection > tracksToken_
virtual float thickness() const =0
int iEvent
Definition: GenABIO.cc:224
const unsigned int lowPtTracksPrescalePass_
DeDxHitInfoProducer(const edm::ParameterSet &)
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomToken_
void processHit(const TrackingRecHit *recHit, const float trackMomentum, const float cosine, reco::DeDxHitInfo &hitDeDxInfo, const LocalPoint &hitLocalPos)
SiStripCluster const & stripCluster() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Transition
Definition: Transition.h:12
const SiStripCluster * stripCluster(size_t i) const
Definition: DeDxHitInfo.h:66
double f[11][100]
void addHit(const float charge, const float pathlength, const DetId &detId, const LocalPoint &pos, const SiStripCluster &stripCluster)
Definition: DeDxHitInfo.h:89
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
edm::ESHandle< TrackerGeometry > tkGeom_
DetId detId(size_t i) const
Definition: DeDxHitInfo.h:44
trackCollection
Definition: JetHT_cfg.py:50
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:151
const TrackerGeomDet * idToDet(DetId) const override
void makeCalibrationMap(const std::string &m_calibrationPath, const TrackerGeometry &tkGeom, std::vector< std::vector< float >> &calibGains, const unsigned int &m_off)
uint64_t xorshift128p(uint64_t state[2])
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
DetId geographicalId() const
unsigned long long uint64_t
Definition: Time.h:13
bool shapeSelection(const SiStripCluster &ampls)
Definition: DeDxTools.cc:13
size_t size() const
Definition: DeDxHitInfo.h:41
~DeDxHitInfoProducer() override
fixed size matrix
HLT enums.
GenericTruncatedAverageDeDxEstimator lowPtTracksEstimator_
float x
SiStripRecHit2D monoHit() const
std::pair< float, float > dedx(const reco::DeDxHitCollection &Hits) override
float charge(size_t i) const
Definition: DeDxHitInfo.h:42
std::vector< std::vector< float > > calibGains_
void beginRun(edm::Run const &run, const edm::EventSetup &) override
const float lowPtTracksDeDxThreshold_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
const Bounds & bounds() const
Definition: Surface.h:87