CMS 3D CMS Logo

TICLTrackstersEdgesValidation.cc
Go to the documentation of this file.
1 #include <string>
2 #include <unordered_map>
3 #include <numeric>
4 
5 // user include files
9 
12 
14 
18 
21 
22 using namespace ticl;
23 
38  // For the definition of the angles, read http://hgcal.web.cern.ch/hgcal/Reconstruction/Tutorial/
42  std::vector<dqm::reco::MonitorElement*> angle_beta_byLayer_;
43  std::vector<dqm::reco::MonitorElement*> angle_beta_w_byLayer_;
44 };
45 
47  std::unordered_map<unsigned int, Histogram_TICLTrackstersEdgesValidation>;
48 
49 class TICLTrackstersEdgesValidation : public DQMGlobalEDAnalyzer<Histograms_TICLTrackstersEdgesValidation> {
50 public:
53 
54  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
55 
56 private:
58  edm::Run const&,
59  edm::EventSetup const&,
61 
62  void dqmAnalyze(edm::Event const&,
63  edm::EventSetup const&,
64  Histograms_TICLTrackstersEdgesValidation const&) const override;
65  void dqmBeginRun(edm::Run const&, edm::EventSetup const&, Histograms_TICLTrackstersEdgesValidation&) const override;
66 
69  std::vector<std::string> trackstersCollectionsNames_;
70  std::vector<edm::EDGetTokenT<std::vector<Trackster>>> tracksterTokens_;
75 };
76 
78  : caloGeomToken_(esConsumes<CaloGeometry, CaloGeometryRecord>()),
79  folder_(iConfig.getParameter<std::string>("folder")) {
80  tracksterTokens_ = edm::vector_transform(iConfig.getParameter<std::vector<edm::InputTag>>("tracksterCollections"),
81  [this](edm::InputTag const& tag) {
82  trackstersCollectionsNames_.emplace_back(tag.label());
83  return consumes<std::vector<Trackster>>(tag);
84  });
85  layerClustersToken_ = consumes<std::vector<reco::CaloCluster>>(iConfig.getParameter<edm::InputTag>("layerClusters"));
87  consumes<std::vector<TICLSeedingRegion>>(iConfig.getParameter<edm::InputTag>("ticlSeedingGlobal"));
89  consumes<std::vector<TICLSeedingRegion>>(iConfig.getParameter<edm::InputTag>("ticlSeedingTrk"));
90 }
91 
93 
95  edm::EventSetup const& iSetup,
98  iEvent.getByToken(layerClustersToken_, layerClustersH);
99  auto const& layerClusters = *layerClustersH.product();
100 
101  edm::Handle<std::vector<TICLSeedingRegion>> ticlSeedingGlobalH;
102  iEvent.getByToken(ticlSeedingGlobalToken_, ticlSeedingGlobalH);
103  auto const& ticlSeedingGlobal = *ticlSeedingGlobalH.product();
104 
106  iEvent.getByToken(ticlSeedingTrkToken_, ticlSeedingTrkH);
107  auto const& ticlSeedingTrk = *ticlSeedingTrkH.product();
108 
109  for (const auto& trackster_token : tracksterTokens_) {
111  iEvent.getByToken(trackster_token, trackster_h);
112  auto numberOfTracksters = trackster_h->size();
113  //using .at() as [] is not const
114  const auto& histo = histos.at(trackster_token.index());
115  histo.number_->Fill(numberOfTracksters);
116  for (unsigned int i = 0; i < numberOfTracksters; ++i) {
117  const auto& thisTrackster = trackster_h->at(i);
118 
119  // The following plots should be moved to HGVHistoProducerAlgo
120  // when we get rid of the MultiClusters and use only Tracksters
121  histo.raw_energy_->Fill(thisTrackster.raw_energy());
122  histo.regr_energy_->Fill(thisTrackster.regressed_energy());
123  histo.raw_energy_vs_regr_energy_->Fill(thisTrackster.regressed_energy(), thisTrackster.raw_energy());
124  const auto& probs = thisTrackster.id_probabilities();
125  std::vector<int> sorted_probs_idx(probs.size());
126  std::iota(begin(sorted_probs_idx), end(sorted_probs_idx), 0);
127  std::sort(begin(sorted_probs_idx), end(sorted_probs_idx), [&probs](int i, int j) { return probs[i] > probs[j]; });
128  histo.id_prob_->Fill(sorted_probs_idx[0]);
129  if (!thisTrackster.vertices().empty()) {
130  histo.raw_energy_1plusLC_->Fill(thisTrackster.raw_energy());
131  histo.regr_energy_1plusLC_->Fill(thisTrackster.regressed_energy());
132  histo.raw_energy_vs_regr_energy_1plusLC_->Fill(thisTrackster.regressed_energy(), thisTrackster.raw_energy());
133  histo.id_prob_1plusLC_->Fill(sorted_probs_idx[0]);
134  }
135 
136  // Plots on edges
137  for (const auto& edge : thisTrackster.edges()) {
138  auto& ic = layerClusters[edge[0]];
139  auto& oc = layerClusters[edge[1]];
140  auto const& cl_in = ic.hitsAndFractions()[0].first;
141  auto const& cl_out = oc.hitsAndFractions()[0].first;
142  auto const layer_in = rhtools_.getLayerWithOffset(cl_in);
143  auto const layer_out = rhtools_.getLayerWithOffset(cl_out);
144  histo.delta_energy_->Fill(oc.energy() - ic.energy());
145  histo.delta_energy_relative_->Fill((oc.energy() - ic.energy()) / ic.energy());
146  histo.delta_energy_vs_energy_->Fill(oc.energy() - ic.energy(), ic.energy());
147  histo.delta_energy_vs_layer_->Fill(layer_in, oc.energy() - ic.energy());
148  histo.delta_energy_relative_vs_layer_->Fill(layer_in, (oc.energy() - ic.energy()) / ic.energy());
149  histo.delta_layer_->Fill(layer_out - layer_in);
150 
151  // Alpha angles
152  const auto& outer_outer_pos = oc.position();
153  const auto& outer_inner_pos = ic.position();
154  const auto& seed = thisTrackster.seedIndex();
155  auto seedGlobalPos = math::XYZPoint(
156  ticlSeedingGlobal[0].origin.x(), ticlSeedingGlobal[0].origin.y(), ticlSeedingGlobal[0].origin.z());
157  auto seedDirectionPos = outer_inner_pos;
158  if (thisTrackster.seedID().id() != 0) {
159  // Seed to trackster association is, at present, rather convoluted.
160  for (auto const& s : ticlSeedingTrk) {
161  if (s.index == seed) {
162  seedGlobalPos = math::XYZPoint(s.origin.x(), s.origin.y(), s.origin.z());
163  seedDirectionPos =
164  math::XYZPoint(s.directionAtOrigin.x(), s.directionAtOrigin.y(), s.directionAtOrigin.z());
165  break;
166  }
167  }
168  }
169 
170  auto alpha = (outer_inner_pos - seedGlobalPos).Dot(outer_outer_pos - outer_inner_pos) /
171  sqrt((outer_inner_pos - seedGlobalPos).Mag2() * (outer_outer_pos - outer_inner_pos).Mag2());
172  auto alpha_alternative = (outer_outer_pos - seedGlobalPos).Dot(seedDirectionPos) /
173  sqrt((outer_outer_pos - seedGlobalPos).Mag2() * seedDirectionPos.Mag2());
174  histo.angle_alpha_->Fill(alpha);
175  histo.angle_alpha_alternative_->Fill(alpha_alternative);
176 
177  // Beta angle is usually computed using 2 edges. Another inner loop
178  // is therefore needed.
179  std::vector<std::array<unsigned int, 2>> innerDoublets;
180  std::vector<std::array<unsigned int, 2>> outerDoublets;
181  for (const auto& otherEdge : thisTrackster.edges()) {
182  if (otherEdge[1] == edge[0]) {
183  innerDoublets.push_back(otherEdge);
184  }
185  if (edge[1] == otherEdge[0]) {
186  outerDoublets.push_back(otherEdge);
187  }
188  }
189 
190  histo.ingoing_links_vs_layer_->Fill(layer_in, innerDoublets.size());
191  histo.outgoing_links_vs_layer_->Fill(layer_out, outerDoublets.size());
192  for (const auto& inner : innerDoublets) {
193  const auto& inner_ic = layerClusters[inner[0]];
194  const auto& inner_inner_pos = inner_ic.position();
195  auto beta = (outer_inner_pos - inner_inner_pos).Dot(outer_outer_pos - inner_inner_pos) /
196  sqrt((outer_inner_pos - inner_inner_pos).Mag2() * (outer_outer_pos - inner_inner_pos).Mag2());
197  histo.angle_beta_->Fill(beta);
198  histo.angle_beta_byLayer_[layer_in]->Fill(beta);
199  histo.angle_beta_w_byLayer_[layer_in]->Fill(beta, ic.energy());
200  }
201  }
202  }
203  }
204 }
205 
207  edm::Run const& run,
208  edm::EventSetup const& iSetup,
210  float eMin = 0., eThresh = 70., eMax = 500;
211  float eWidth[] = {0.5, 2.};
212  std::vector<float> eBins;
213  float eVal = eMin;
214  while (eVal <= eThresh) {
215  eBins.push_back(eVal);
216  eVal += eWidth[0];
217  }
218  while (eVal < eMax) {
219  eVal += eWidth[1];
220  eBins.push_back(eVal);
221  }
222  int eNBins = eBins.size() - 1;
223 
224  TString onePlusLC[] = {"1plus LC", "for tracksters with at least one LC"};
225  TString trkers = "Tracksters";
226  static const char* particle_kind[] = {
227  "photon", "electron", "muon", "neutral_pion", "charged_hadron", "neutral_hadron", "ambiguous", "unknown"};
228  auto nCategory = sizeof(particle_kind) / sizeof(*particle_kind);
229  int labelIndex = 0;
230  for (const auto& trackster_token : tracksterTokens_) {
231  auto& histo = histos[trackster_token.index()];
232  ibook.setCurrentFolder(folder_ + "HGCalValidator/" + trackstersCollectionsNames_[labelIndex]);
233  histo.number_ = ibook.book1D(
234  "Number of Tracksters per Event", "Number of Tracksters per Event;# Tracksters;Events", 250, 0., 250.);
235  // The following plots should be moved to HGVHistoProducerAlgo
236  // when we get rid of the MultiClusters and use only Tracksters
237  histo.raw_energy_ = ibook.book1D("Raw Energy", "Raw Energy;Raw Energy [GeV];" + trkers, eNBins, &eBins[0]);
238  histo.regr_energy_ =
239  ibook.book1D("Regressed Energy", "Regressed Energy;Regressed Energy [GeV];" + trkers, eNBins, &eBins[0]);
240  histo.raw_energy_vs_regr_energy_ = ibook.book2D("Raw Energy vs Regressed Energy",
241  "Raw vs Regressed Energy;Regressed Energy [GeV];Raw Energy [GeV]",
242  eNBins,
243  &eBins[0],
244  eNBins,
245  &eBins[0]);
246  histo.id_prob_ =
247  ibook.book1D("ID probability", "ID probability;category;Max ID probability", nCategory, 0, nCategory);
248  histo.raw_energy_1plusLC_ = ibook.book1D(
249  "Raw Energy " + onePlusLC[0], "Raw Energy " + onePlusLC[1] + ";Raw Energy [GeV];" + trkers, eNBins, &eBins[0]);
250  histo.regr_energy_1plusLC_ = ibook.book1D("Regressed Energy " + onePlusLC[0],
251  "Regressed Energy " + onePlusLC[1] + ";Regressed Energy [GeV];" + trkers,
252  eNBins,
253  &eBins[0]);
254  histo.raw_energy_vs_regr_energy_1plusLC_ =
255  ibook.book2D("Raw Energy vs Regressed Energy " + onePlusLC[0],
256  "Raw vs Regressed Energy " + onePlusLC[1] + ";Regressed Energy [GeV];Raw Energy [GeV]",
257  eNBins,
258  &eBins[0],
259  eNBins,
260  &eBins[0]);
261  histo.id_prob_1plusLC_ = ibook.book1D("ID probability " + onePlusLC[0],
262  "ID probability " + onePlusLC[1] + ";category;Max ID probability",
263  nCategory,
264  0,
265  nCategory);
266  for (int iBin = 0; iBin < histo.id_prob_->getNbinsX(); iBin++) {
267  histo.id_prob_->setBinLabel(iBin + 1, particle_kind[iBin]);
268  histo.id_prob_1plusLC_->setBinLabel(iBin + 1, particle_kind[iBin]);
269  }
270  // Plots on edges
271  histo.delta_energy_ = ibook.book1D("Delta energy", "Delta Energy (O-I)", 800, -20., 20.);
272  histo.delta_energy_relative_ =
273  ibook.book1D("Relative Delta energy", "Relative Delta Energy (O-I)/I", 200, -10., 10.);
274  histo.delta_energy_vs_energy_ =
275  ibook.book2D("Energy vs Delta Energy", "Energy (I) vs Delta Energy (O-I)", 800, -20., 20., 200, 0., 20.);
276  histo.delta_energy_vs_layer_ = ibook.book2D(
277  "Delta Energy (O-I) vs Layer Number (I)", "Delta Energy (O-I) vs Layer Number (I)", 50, 0., 50., 800, -20., 20.);
278  histo.delta_energy_relative_vs_layer_ = ibook.book2D("Relative Delta Energy (O-I)_I vs Layer Number (I)",
279  "Relative Delta Energy (O-I)_I vs Layer Number (I)",
280  50,
281  0.,
282  50.,
283  200,
284  -10.,
285  10.);
286  histo.ingoing_links_vs_layer_ =
287  ibook.book2D("Ingoing links Layer Number", "Ingoing links vs Layer Number", 50, 0., 50., 40, 0., 40.);
288  histo.outgoing_links_vs_layer_ =
289  ibook.book2D("Outgoing links vs Layer Number", "Outgoing links vs Layer Number", 50, 0., 50., 40, 0., 40.);
290  histo.delta_layer_ = ibook.book1D("Delta Layer", "Delta Layer", 10, 0., 10.);
291  histo.angle_alpha_ = ibook.book1D("cosAngle Alpha", "cosAngle Alpha", 200, -1., 1.);
292  histo.angle_beta_ = ibook.book1D("cosAngle Beta", "cosAngle Beta", 200, -1., 1.);
293  histo.angle_alpha_alternative_ = ibook.book1D("cosAngle Alpha Alternative", "Angle Alpha Alternative", 200, 0., 1.);
294  for (int layer = 0; layer < 50; layer++) {
295  auto layerstr = std::to_string(layer + 1);
296  if (layerstr.length() < 2)
297  layerstr.insert(0, 2 - layerstr.length(), '0');
298  histo.angle_beta_byLayer_.push_back(
299  ibook.book1D("cosAngle Beta on Layer " + layerstr, "cosAngle Beta on Layer " + layerstr, 200, -1., 1.));
300  histo.angle_beta_w_byLayer_.push_back(ibook.book1D(
301  "cosAngle Beta Weighted on Layer " + layerstr, "cosAngle Beta Weighted on Layer " + layerstr, 200, -1., 1.));
302  }
303  labelIndex++;
304  }
305 }
306 
308  edm::EventSetup const& iSetup,
312 }
313 
316  std::vector<edm::InputTag> source_vector{edm::InputTag("ticlTrackstersTrk"),
317  edm::InputTag("ticlTrackstersTrkEM"),
318  edm::InputTag("ticlTrackstersEM"),
319  edm::InputTag("ticlTrackstersHAD"),
320  edm::InputTag("ticlTrackstersMerge")};
321  desc.add<std::vector<edm::InputTag>>("tracksterCollections", source_vector);
322  desc.add<edm::InputTag>("layerClusters", edm::InputTag("hgcalMergeLayerClusters"));
323  desc.add<edm::InputTag>("ticlSeedingGlobal", edm::InputTag("ticlSeedingGlobal"));
324  desc.add<edm::InputTag>("ticlSeedingTrk", edm::InputTag("ticlSeedingTrk"));
325  desc.add<std::string>("folder", "HGCAL/");
326  descriptions.add("ticlTrackstersEdgesValidationDefault", desc);
327 }
328 
edm::EDGetTokenT< std::vector< reco::CaloCluster > > layerClustersToken_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
std::string folder_
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
dqm::reco::MonitorElement * raw_energy_vs_regr_energy_1plusLC_
T const * product() const
Definition: Handle.h:70
void dqmAnalyze(edm::Event const &, edm::EventSetup const &, Histograms_TICLTrackstersEdgesValidation const &) const override
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeomToken_
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &, Histograms_TICLTrackstersEdgesValidation &) const override
static std::string to_string(const XMLCh *ch)
example_stream void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
int iEvent
Definition: GenABIO.cc:224
std::vector< dqm::reco::MonitorElement * > angle_beta_w_byLayer_
TICLTrackstersEdgesValidation(const edm::ParameterSet &)
T sqrt(T t)
Definition: SSEVec.h:23
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
void dqmBeginRun(edm::Run const &, edm::EventSetup const &, Histograms_TICLTrackstersEdgesValidation &) const override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
example_global void dqmAnalyze(edm::Event const &, edm::EventSetup const &, Histograms___class__ const &) const override
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< dqm::reco::MonitorElement * > angle_beta_byLayer_
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:221
edm::EDGetTokenT< std::vector< TICLSeedingRegion > > ticlSeedingGlobalToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void setGeometry(CaloGeometry const &)
Definition: RecHitTools.cc:79
histos
Definition: combine.py:4
std::vector< edm::EDGetTokenT< std::vector< Trackster > > > tracksterTokens_
Definition: Common.h:10
std::unordered_map< unsigned int, Histogram_TICLTrackstersEdgesValidation > Histograms_TICLTrackstersEdgesValidation
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
edm::EDGetTokenT< std::vector< TICLSeedingRegion > > ticlSeedingTrkToken_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< std::string > trackstersCollectionsNames_
Definition: Run.h:45
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:381