CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GEMEffByGEMCSCSegmentSource.cc
Go to the documentation of this file.
4 #include <algorithm> // std::clamp
5 
7  : kGEMTokenBeginRun_(esConsumes<edm::Transition::BeginRun>()),
8  kGEMCSCSegmentToken_(
9  consumes<GEMCSCSegmentCollection>(parameter_set.getParameter<edm::InputTag>("gemcscSegmentTag"))),
10  kMuonToken_(consumes<reco::MuonCollection>(parameter_set.getParameter<edm::InputTag>("muonTag"))),
11  kUseMuon_(parameter_set.getUntrackedParameter<bool>("useMuon")),
12  kMinCSCRecHits_(parameter_set.getUntrackedParameter<uint32_t>("minCSCRecHits")),
13  kFolder_(parameter_set.getUntrackedParameter<std::string>("folder")),
14  kLogCategory_(parameter_set.getUntrackedParameter<std::string>("logCategory")) {}
15 
17 
20  desc.add<edm::InputTag>("gemcscSegmentTag", edm::InputTag("gemcscSegments"));
21  desc.add<edm::InputTag>("muonTag", edm::InputTag("muons"));
22  desc.addUntracked<bool>("useMuon", false);
23  desc.addUntracked<uint32_t>("minCSCRecHits", 6u);
24  desc.addUntracked<std::string>("folder", "GEM/Efficiency/GEMCSCSegment");
25  desc.addUntracked<std::string>("logCategory", "GEMEffByGEMCSCSegmentSource");
26  descriptions.addWithDefaultLabel(desc);
27 }
28 
30  edm::Run const&,
31  edm::EventSetup const& setup) {
33  if (not gem.isValid()) {
34  edm::LogError(kLogCategory_) << "invalid GEMGeometry";
35  return;
36  }
37 
38  bookEfficiencyChamber(ibooker, gem);
39  bookMisc(ibooker, gem);
40 }
41 
43  const edm::ESHandle<GEMGeometry>& gem) {
44  ibooker.setCurrentFolder(kFolder_ + "/Efficiency");
45 
46  for (const GEMStation* station : gem->stations()) {
47  const int region_id = station->region();
48  const int station_id = station->station();
49 
50  if (station_id == 1) {
51  // GE11
52  const std::vector<const GEMSuperChamber*> superchambers = station->superChambers();
53  if (not checkRefs(superchambers)) {
54  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs";
55  return;
56  }
57 
58  const int num_chambers = superchambers.size();
59  for (const GEMChamber* chamber : superchambers.at(0)->chambers()) {
60  const int layer_id = chamber->id().layer();
61 
62  const TString name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
63  const TString title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
64  const GEMDetId key = getReStLaKey(chamber->id());
65 
66  me_chamber_[key] = ibooker.book1D("chamber" + name_suffix, title_suffix, num_chambers, 0.5, num_chambers + 0.5);
67  me_chamber_[key]->setAxisTitle("Chamber", 1);
68  for (int binx = 1; binx <= num_chambers; binx++) {
69  me_chamber_[key]->setBinLabel(binx, std::to_string(binx), 1);
70  }
71  me_chamber_matched_[key] = bookNumerator1D(ibooker, me_chamber_[key]);
72 
73  if (kUseMuon_) {
75  ibooker.book1D("muon_chamber" + name_suffix, title_suffix, num_chambers, 0.5, num_chambers + 0.5);
76  me_muon_chamber_[key]->setAxisTitle("Chamber", 1);
77  for (int binx = 1; binx <= num_chambers; binx++) {
78  me_muon_chamber_[key]->setBinLabel(binx, std::to_string(binx), 1);
79  }
81  }
82  } // layer
83 
84  } else {
85  LogDebug(kLogCategory_) << "skip " << station->getName();
86  continue;
87  }
88  } // station
89 }
90 
92  ibooker.setCurrentFolder(kFolder_ + "/Misc");
93 
94  for (const GEMStation* station : gem->stations()) {
95  const int region_id = station->region();
96  const int station_id = station->station();
97 
98  if (station_id == 1) {
99  // GE11
100  const std::vector<const GEMSuperChamber*> superchambers = station->superChambers();
101  if (not checkRefs(superchambers)) {
102  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs";
103  return;
104  }
105 
106  for (const GEMChamber* chamber : superchambers.at(0)->chambers()) {
107  const int layer_id = chamber->id().layer();
108 
109  const TString name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
110  const TString title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
111  const GEMDetId key = getReStLaKey(chamber->id());
112 
113  // num_csc_hits
114  me_num_csc_hits_[key] = ibooker.book1D("num_csc_hits" + name_suffix, title_suffix, 4, 2.5, 6.5);
115  me_num_csc_hits_[key]->setAxisTitle("Number of CSCRecHits", 1);
116 
117  me_num_csc_hits_matched_[key] = bookNumerator1D(ibooker, me_num_csc_hits_[key]);
118 
119  // reduced_chi2
120  me_reduced_chi2_[key] = ibooker.book1D("reduced_chi2" + name_suffix, title_suffix, 30, 0, 3);
121  me_reduced_chi2_[key]->setAxisTitle("#chi^{2} / dof", 1);
122 
124 
125  // CSC chamber type
126  // https://github.com/cms-sw/cmssw/blob/CMSSW_12_3_0_pre5/DataFormats/MuonDetId/interface/CSCDetId.h#L187-L193
127  me_csc_chamber_type_[key] = ibooker.book1D("csc_chamber_type" + name_suffix, title_suffix, 10, 0.5, 10.5);
128  me_csc_chamber_type_[key]->setAxisTitle("CSC chamber type", 1);
129  for (int chamber_type = 1; chamber_type <= 10; chamber_type++) {
130  const std::string label = CSCDetId::chamberName(chamber_type);
131  me_csc_chamber_type_[key]->setBinLabel(chamber_type, label, 1);
132  }
133 
135 
136  } // layer
137 
138  } else {
139  LogDebug(kLogCategory_) << "skip " << station->getName();
140  continue;
141  }
142  } // region-station
143 }
144 
146  MonitorElement* me) {
147  const std::string name = me->getName() + "_matched";
148  TH1F* hist = dynamic_cast<TH1F*>(me->getTH1F()->Clone(name.c_str()));
149  return ibooker.book1D(name, hist);
150 }
151 
154  // get data from Event & EventSetup
155  const GEMCSCSegmentCollection* gemcsc_segment_collection = nullptr;
157  gemcsc_segment_collection = handle.product();
158 
159  } else {
160  edm::LogError(kLogCategory_) << "invalid GEMCSCSegmentCollection";
161  return;
162  }
163 
164  const reco::MuonCollection* muon_collection = nullptr;
165  if (kUseMuon_) {
167  muon_collection = handle.product();
168 
169  } else {
170  edm::LogError(kLogCategory_) << "invalid reco::MuonCollection";
171  return;
172  }
173  }
174 
176  // quick check
177  if (gemcsc_segment_collection->size() < 1) {
178  LogDebug(kLogCategory_) << "empty GEMCSCSegment";
179  return;
180  }
181 
183  //
184  if (kUseMuon_) {
185  findMatchedME11Segments(muon_collection);
186  }
187 
189  // main loop
190  for (edm::OwnVector<GEMCSCSegment>::const_iterator iter = gemcsc_segment_collection->begin();
191  iter != gemcsc_segment_collection->end();
192  iter++) {
193  const GEMCSCSegment& gemcsc_segment = *iter;
194 
195  const CSCDetId csc_id = gemcsc_segment.cscDetId();
196  if (csc_id.isME11()) {
197  analyzeME11GE11Segment(gemcsc_segment);
198 
199  } else {
200  LogDebug(kLogCategory_) << "skip " << csc_id;
201  continue;
202  }
203  } // GEMCSCSegment
204 }
205 
207  const GEMRecHit* ge11_hit_layer1 = nullptr;
208  const GEMRecHit* ge11_hit_layer2 = nullptr;
209 
210  const CSCDetId csc_id = gemcsc_segment.cscDetId();
211  for (const GEMRecHit& gem_hit : gemcsc_segment.gemRecHits()) {
212  const GEMDetId gem_id = gem_hit.gemId();
213 
214  if (not gem_id.isGE11()) {
215  edm::LogWarning(kLogCategory_) << "CSCSegment is in " << csc_id << " but GEMRecHit is in " << gem_id
216  << ". skip this GEMCSCSegment."
217  << "check if RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegAlgoRR.cc has changed.";
218  return;
219  }
220 
221  const int layer = gem_id.layer();
222  if (layer == 1) {
223  ge11_hit_layer1 = &gem_hit;
224 
225  } else if (layer == 2) {
226  ge11_hit_layer2 = &gem_hit;
227 
228  } else {
229  edm::LogError(kLogCategory_) << "isGE11 but got unexpected layer " << gem_id << ". skip this GEMCSCSegment.";
230  return;
231  }
232  } // GEMRecHit
233 
234  checkCoincidenceGE11(ge11_hit_layer1, ge11_hit_layer2, gemcsc_segment);
235  checkCoincidenceGE11(ge11_hit_layer2, ge11_hit_layer1, gemcsc_segment);
236 }
237 
239  const GEMRecHit* detection_layer_hit,
240  const GEMCSCSegment& gemcsc_segment) {
241  if (trigger_layer_hit == nullptr) {
242  LogDebug(kLogCategory_) << "trigger_layer_hit is nullptr";
243  return;
244  }
245 
246  const GEMDetId trigger_layer_id = trigger_layer_hit->gemId();
247  const int detection_layer = trigger_layer_id.layer() == 1 ? 2 : 1;
248  // detection layer key
249  // GEMDetId(int region, int ring, int station, int layer, int chamber, int ieta)
250  const GEMDetId key{trigger_layer_id.region(), 1, trigger_layer_id.station(), detection_layer, 0, 0};
251 
252  const int chamber = trigger_layer_id.chamber();
253  const bool is_matched = kUseMuon_ ? isME11SegmentMatched(gemcsc_segment.cscSegment()) : false;
254 
255  const int num_csc_hits = gemcsc_segment.cscRecHits().size();
256  const double reduced_chi2 = gemcsc_segment.chi2() / gemcsc_segment.degreesOfFreedom();
257  const int csc_chamber_type = gemcsc_segment.cscDetId().iChamberType();
258 
259  // TODO add a method
260  const bool is_good = gemcsc_segment.cscRecHits().size() >= kMinCSCRecHits_;
261 
262  fillME(me_num_csc_hits_, key, num_csc_hits);
263  fillMEWithinLimits(me_reduced_chi2_, key, reduced_chi2);
264  fillME(me_csc_chamber_type_, key, csc_chamber_type);
265  if (detection_layer_hit) {
266  fillME(me_num_csc_hits_matched_, key, num_csc_hits);
268  fillME(me_csc_chamber_type_matched_, key, csc_chamber_type);
269  }
270 
271  if (is_good) {
272  // twofold coincidence rate
273  fillME(me_chamber_, key, chamber);
274  if (is_matched) {
275  fillME(me_muon_chamber_, key, chamber);
276  }
277 
278  // threefold coincidence rate
279  if (detection_layer_hit) {
280  fillME(me_chamber_matched_, key, chamber);
281  if (is_matched) {
283  }
284  }
285  }
286 }
287 
290  for (unsigned int idx = 0; idx < muon_collection->size(); idx++) {
291  const reco::Muon& muon = muon_collection->at(idx);
292 
293  for (const reco::MuonChamberMatch& chamber_match : muon.matches()) {
294  if (chamber_match.detector() != MuonSubdetId::CSC) {
295  continue;
296  }
297 
298  const CSCDetId csc_id{chamber_match.id};
299  if (not csc_id.isME11()) {
300  continue;
301  }
302 
303  for (const reco::MuonSegmentMatch& segment_match : chamber_match.segmentMatches) {
304  if (not segment_match.isMask(reco::MuonSegmentMatch::BestInStationByDR)) {
305  continue;
306  }
307  matched_me11_segment_vector_.push_back(segment_match.cscSegmentRef.get());
308  } // MuonSegmentMatch
309  } // MuonChamberMatch
310  } // MuonCollection
311 }
312 
313 // TODO
315  bool found = false;
316 
317  const CSCDetId csc_id = csc_segment.cscDetId();
318  if (not csc_id.isME11()) {
319  return false;
320  }
321 
322  for (const CSCSegment* matched_segment : matched_me11_segment_vector_) {
323  if (csc_id != matched_segment->cscDetId())
324  continue;
325  if (csc_segment.localPosition().x() != matched_segment->localPosition().x())
326  continue;
327  if (csc_segment.localPosition().y() != matched_segment->localPosition().y())
328  continue;
329  if (csc_segment.localPosition().z() != matched_segment->localPosition().z())
330  continue;
331  if (csc_segment.time() != matched_segment->time())
332  continue;
333 
334  found = true;
335  }
336 
337  return found;
338 }
339 
341  bool has_key = true;
342 
343  if UNLIKELY (me_map.find(key) == me_map.end()) {
344  const std::string hint = me_map.empty() ? "empty" : me_map.begin()->second->getName();
345  edm::LogError(kLogCategory_) << "got an invalid key: " << key << ", hint=" << hint;
346  has_key = false;
347 
348  }
349 
350  return has_key;
351 }
352 
354  if (me) {
355  me->Fill(x);
356 
357  } else {
358  edm::LogError(kLogCategory_) << "MonitorElement is nullptr";
359 
360  }
361 }
362 
363 void GEMEffByGEMCSCSegmentSource::fillME(MEMap& me_map, const GEMDetId& key, const double x) {
364  if (hasMEKey(me_map, key)) {
365  me_map[key]->Fill(x);
366  }
367 }
368 
369 // https://github.com/cms-sw/cmssw/blob/CMSSW_12_0_0_pre3/DQMOffline/L1Trigger/src/L1TFillWithinLimits.cc
371  if (me) {
372  const double xlow = me->getAxisMin(1);
373  const double xup = me->getAxisMax(1) - kEps_;
374  me->Fill(std::clamp(x, xlow, xup));
375 
376  } else {
377  edm::LogError(kLogCategory_) << "MonitorElement is nullptr";
378 
379  }
380 }
381 
383  if (hasMEKey(me_map, key)) {
384  fillMEWithinLimits(me_map[key], x);
385  }
386 }
GEMEffByGEMCSCSegmentSource(const edm::ParameterSet &)
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
void fillME(dqm::impl::MonitorElement *, const double)
const edm::EDGetTokenT< reco::MuonCollection > kMuonToken_
GEMDetId getReStLaKey(const GEMDetId &)
bool hasMEKey(const MEMap &, const GEMDetId &)
LocalPoint localPosition() const override
Definition: CSCSegment.h:39
CSCDetId cscDetId() const
Definition: CSCSegment.h:70
const edm::EDGetTokenT< GEMCSCSegmentCollection > kGEMCSCSegmentToken_
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
TString getSuffixName(Int_t region_id)
CSCSegmentRef cscSegmentRef
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
void checkCoincidenceGE11(const GEMRecHit *, const GEMRecHit *, const GEMCSCSegment &)
virtual double getAxisMin(int axis=1) const
MonitorElement * bookNumerator1D(DQMStore::IBooker &, MonitorElement *)
CSCDetId cscDetId() const
Definition: GEMCSCSegment.h:73
T y() const
Definition: PV3DBase.h:60
const std::string & getName() const
get name of ME
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
static void fillDescriptions(edm::ConfigurationDescriptions &)
int degreesOfFreedom() const override
Degrees of freedom of the segment fit.
Definition: GEMCSCSegment.h:62
Log< level::Error, false > LogError
TString getSuffixTitle(Int_t region_id)
const edm::ESGetToken< GEMGeometry, MuonGeometryRecord > kGEMTokenBeginRun_
static const unsigned int BestInStationByDR
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
const std::vector< GEMRecHit > & gemRecHits() const
Definition: GEMCSCSegment.h:68
constexpr std::array< uint8_t, layerIndexSize > layer
void Fill(long long x)
void findMatchedME11Segments(const reco::MuonCollection *)
char const * label
double chi2() const override
Chi2 of the segment fit.
Definition: GEMCSCSegment.h:58
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:563
bool isME11() const
Definition: CSCDetId.cc:64
void analyzeME11GE11Segment(const GEMCSCSegment &)
constexpr int region() const
Definition: GEMDetId.h:171
T z() const
Definition: PV3DBase.h:61
tuple key
prepare the HTCondor submission files and eventually submit them
tuple handle
Definition: patZpeak.py:23
bool isGE11() const
Definition: GEMDetId.cc:9
Transition
Definition: Transition.h:12
uint16_t const *__restrict__ x
Definition: gpuClustering.h:39
void bookMisc(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
unsigned short iChamberType() const
Definition: CSCDetId.h:96
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool checkRefs(const std::vector< T * > &)
std::map< GEMDetId, dqm::impl::MonitorElement * > MEMap
const std::vector< CSCRecHit2D > & cscRecHits() const
Definition: GEMCSCSegment.h:69
__shared__ Hist hist
std::string chamberName() const
Definition: CSCDetId.cc:92
constexpr int chamber() const
Definition: GEMDetId.h:183
constexpr int layer() const
Definition: GEMDetId.h:190
bool isMask(unsigned int flag=Arbitrated) const
constexpr int station() const
Definition: GEMDetId.h:179
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:145
void bookEfficiencyChamber(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
bool isME11SegmentMatched(const CSCSegment &)
void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override
std::vector< const CSCSegment * > matched_me11_segment_vector_
GEMDetId gemId() const
Return the gemId.
Definition: GEMRecHit.h:65
#define UNLIKELY(x)
Definition: Likely.h:21
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:157
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
bool isValid() const
Definition: ESHandle.h:44
static constexpr int CSC
Definition: MuonSubdetId.h:12
T x() const
Definition: PV3DBase.h:59
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
virtual double getAxisMax(int axis=1) const
float time() const
Definition: CSCSegment.cc:144
const CSCSegment cscSegment() const
Definition: GEMCSCSegment.h:67
Definition: Run.h:45
void fillMEWithinLimits(dqm::impl::MonitorElement *, const double)
#define LogDebug(id)
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)