CMS 3D CMS Logo

FWElectronDetailView.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Electrons
4 // Class : FWElectronDetailView
5 //
6 
7 // ROOT includes
8 #include "TLatex.h"
9 #include "TEveCalo.h"
10 #include "TEveStraightLineSet.h"
11 #include "TEvePointSet.h"
12 #include "TEveScene.h"
13 #include "TEveViewer.h"
14 #include "TGLViewer.h"
15 #include "TGLOverlay.h"
16 #include "TCanvas.h"
17 #include "TLegend.h"
18 #include "TEveCaloLegoOverlay.h"
19 #include "TRootEmbeddedCanvas.h"
20 
21 // Fireworks includes
28 
29 // CMSSW includes
30 
33 
34 //
35 // constructors and destructor
36 //
37 FWElectronDetailView::FWElectronDetailView() : m_data(nullptr), m_builder(nullptr), m_legend(nullptr) {}
38 
40  m_eveViewer->GetGLViewer()->DeleteOverlayElements(TGLOverlayElement::kUser);
41 
42  delete m_builder;
43  if (m_data)
44  m_data->DecDenyDestroy();
45 }
46 
47 //
48 // member functions
49 //
50 void FWElectronDetailView::build(const FWModelId &id, const reco::GsfElectron *iElectron) {
51  if (!iElectron)
52  return;
53  // If SuperCluster reference is not stored,
54  // take eta and phi of a Candidate
55  double eta = 0;
56  double phi = 0;
57  if (iElectron->superCluster().isAvailable()) {
58  eta = iElectron->caloPosition().eta();
59  phi = iElectron->caloPosition().phi();
60  } else {
61  eta = iElectron->eta();
62  phi = iElectron->phi();
63  }
64 
65  // build ECAL objects
66  m_builder = new FWECALDetailViewBuilder(id.item()->getEvent(), id.item()->getGeom(), eta, phi, 25);
67 
69  if (iElectron->superCluster().isAvailable())
70  m_builder->showSuperCluster(*(iElectron->superCluster()), kYellow + 1);
71 
72  TEveCaloLego *lego = m_builder->build();
73  m_data = lego->GetData();
74  m_eveScene->AddElement(lego);
75 
76  m_legend = new TLegend(0.01, 0.01, 0.99, 0.99, nullptr, "NDC");
77  m_legend->SetTextSize(0.075);
78  m_legend->SetBorderSize(0);
79  m_legend->SetMargin(0.15);
80  m_legend->SetEntrySeparation(0.05);
81 
82  // add Electron specific details
83  if (false && iElectron->superCluster().isAvailable()) {
84  addTrackPointsInCaloData(iElectron, lego);
85  drawCrossHair(iElectron, lego, m_eveScene);
86  addSceneInfo(iElectron, m_eveScene);
87  }
88 
89  // draw axis at the window corners
90  if (true) {
91  TEveCaloLegoOverlay *overlay = new TEveCaloLegoOverlay();
92  overlay->SetShowPlane(kFALSE);
93  overlay->SetShowPerspective(kFALSE);
94  overlay->SetCaloLego(lego);
95  overlay->SetShowScales(true); // temporary
96  viewerGL()->AddOverlayElement(overlay);
97  }
98  // set event handler and flip camera to top view at beginning
99  viewerGL()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
100  FWGLEventHandler *eh = new FWGLEventHandler((TGWindow *)viewerGL()->GetGLWidget(), (TObject *)viewerGL(), lego);
101  viewerGL()->SetEventHandler(eh);
102  viewerGL()->ResetCamerasAfterNextUpdate();
103  viewerGL()->UpdateScene(kFALSE);
104  gEve->Redraw3D();
105 
106  setTextInfo(id, iElectron);
107 }
108 
110  return electron.deltaEtaSuperClusterTrackAtVtx();
111 }
112 
114  return electron.deltaPhiSuperClusterTrackAtVtx();
115 }
116 
118  m_infoCanvas->cd();
119 
120  float_t x = 0.02;
121  float_t x2 = 0.52;
122  float y = 0.95;
123 
124  TLatex *latex = new TLatex(x, y, "");
125  const double textsize(0.05);
126  latex->SetTextSize(2 * textsize);
127 
128  latex->DrawLatex(x, y, id.item()->modelName(id.index()).c_str());
129  y -= latex->GetTextSize() * 0.6;
130 
131  latex->SetTextSize(textsize);
132  float lineH = latex->GetTextSize() * 0.6;
133 
134  latex->DrawLatex(
135  x, y, Form(" E_{T} = %.1f GeV, #eta = %0.2f, #varphi = %0.2f", electron->et(), electron->eta(), electron->phi()));
136  y -= lineH;
137  // summary
138  if (electron->charge() > 0)
139  latex->DrawLatex(x, y, " charge = +1");
140  else
141  latex->DrawLatex(x, y, " charge = -1");
142  y -= lineH;
143 
144  if (electron->superCluster().isAvailable()) {
145  // delta phi/eta in
146  latex->DrawLatex(x, y, "SuperCluster vs inner state extrapolation");
147  y -= lineH;
148  latex->DrawLatex(x, y, TString::Format(" #Delta#eta_{in} = %.3f", electron->deltaEtaSuperClusterTrackAtVtx()));
149  latex->DrawLatex(x2, y, TString::Format("#Delta#varphi_{in} = %.3f", electron->deltaPhiSuperClusterTrackAtVtx()));
150  y -= lineH;
151 
152  // delta phi/eta out
153  latex->DrawLatex(x, y, "SeedCluster vs outer state extrapolation");
154  y -= lineH;
155 
156  latex->DrawLatex(x, y, TString::Format(" #Delta#eta_{out} = %.3f", electron->deltaEtaSeedClusterTrackAtCalo()));
157  latex->DrawLatex(x2, y, TString::Format(" #Delta#varphi_{out} = %.3f", electron->deltaPhiSeedClusterTrackAtCalo()));
158  y -= 2 * lineH;
159  } else {
160  latex->DrawLatex(x, y, "Ref to SuperCluster is not available");
161  }
162 
163  latex->DrawLatex(x, y, TString::Format(" Tracker driven seed: %s", electron->trackerDrivenSeed() ? "YES" : "NO"));
164  y -= lineH;
165  latex->DrawLatex(x, y, TString::Format(" ECAL driven seed: %s", electron->ecalDrivenSeed() ? "YES" : "NO"));
166  y -= lineH;
167 
168  y = m_builder->makeLegend(0.02, y);
169  y -= lineH;
170 
171  m_legend->SetY2(y);
172  m_legend->Draw();
173  m_legend = nullptr; // Deleted together with TPad.
174 }
175 
176 void FWElectronDetailView::drawCrossHair(const reco::GsfElectron *i, TEveCaloLego *lego, TEveElementList *tList) {
177  double ymax = lego->GetPhiMax();
178  double ymin = lego->GetPhiMin();
179  double xmax = lego->GetEtaMax();
180  double xmin = lego->GetEtaMin();
181 
182  // draw crosshairs for track intersections
183 
184  {
185  const double eta = i->superCluster()->seed()->position().eta() - i->deltaEtaSeedClusterTrackAtCalo();
186  const double phi = i->superCluster()->seed()->position().phi() - i->deltaPhiSeedClusterTrackAtCalo();
187 
188  TEveStraightLineSet *trackpositionAtCalo = new TEveStraightLineSet("sc trackpositionAtCalo");
189  trackpositionAtCalo->SetPickable(kTRUE);
190  trackpositionAtCalo->SetTitle("Track position at Calo propagating from the outermost state");
191 
192  trackpositionAtCalo->AddLine(eta, ymin, 0, eta, ymax, 0);
193  trackpositionAtCalo->AddLine(xmin, phi, 0, xmax, phi, 0);
194 
195  trackpositionAtCalo->SetDepthTest(kFALSE);
196  trackpositionAtCalo->SetLineColor(kBlue);
197  tList->AddElement(trackpositionAtCalo);
198 
199  m_legend->AddEntry(trackpositionAtCalo, "From outermost state", "l");
200  }
201  //
202  // pin position
203  //
204  {
205  TEveStraightLineSet *pinposition = new TEveStraightLineSet("pin position");
206  pinposition->SetPickable(kTRUE);
207  pinposition->SetTitle("Track position at Calo propagating from the innermost state");
208  Double_t eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
209  Double_t phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
210 
211  pinposition->AddLine(eta, ymax, 0, eta, ymin, 0);
212  pinposition->AddLine(xmin, phi, 0, xmax, phi, 0);
213 
214  pinposition->SetDepthTest(kFALSE);
215  pinposition->SetLineColor(kRed);
216  tList->AddElement(pinposition);
217 
218  m_legend->AddEntry(pinposition, "From innermost state", "l");
219  }
220 }
221 
223  Double_t &em, Double_t &eM, Double_t &pm, Double_t &pM, Double_t eta, Double_t phi) {
224  Bool_t changed = kFALSE;
225 
226  //check eta
227  if (eta < em) {
228  em = eta;
229  changed = kTRUE;
230  } else if (eta > eM) {
231  eM = eta;
232  changed = kTRUE;
233  }
234 
235  // check phi
236  if (phi < pm) {
237  pm = phi;
238  changed = kTRUE;
239  } else if (phi > pM) {
240  pM = phi;
241  changed = kTRUE;
242  }
243  return changed;
244 }
245 
247  return;
248  TEveCaloDataVec *data = (TEveCaloDataVec *)lego->GetData();
249  Double_t em, eM, pm, pM;
250  data->GetEtaLimits(em, eM);
251  data->GetPhiLimits(pm, pM);
252  data->IncDenyDestroy();
253  Bool_t changed = kFALSE;
254  // add cells in third layer if necessary
255 
256  // trackpositionAtCalo
257  {
258  double eta = i->superCluster()->seed()->position().eta() - i->deltaEtaSeedClusterTrackAtCalo();
259  double phi = i->superCluster()->seed()->position().phi() - i->deltaPhiSeedClusterTrackAtCalo();
260 
261  if (checkRange(em, eM, pm, pM, eta, phi))
262  changed = kTRUE;
263  }
264  // pinposition
265  {
266  double eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
267  double phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
268 
269  if (checkRange(em, eM, pm, pM, eta, phi))
270  changed = kTRUE;
271  }
272  if (changed) {
273  data->AddTower(em, eM, pm, pM);
274  data->FillSlice(2, 0);
275  data->DataChanged();
276 
277  lego->ComputeBBox();
278  Double_t legoScale = ((eM - em) < (pM - pm)) ? (eM - em) : (pM - pm);
279  lego->InitMainTrans();
280  lego->RefMainTrans().SetScale(legoScale, legoScale, legoScale * 0.5);
281  lego->RefMainTrans().SetPos((eM + em) * 0.5, (pM + pm) * 0.5, 0);
282  lego->ElementChanged(true);
283  }
284 }
285 
286 void FWElectronDetailView::addSceneInfo(const reco::GsfElectron *i, TEveElementList *tList) {
287  // centroids
288  Double_t x(0), y(0), z(0);
289  Double_t delta(0.02);
290 
291  TEveStraightLineSet *scposition = new TEveStraightLineSet("sc position");
292  scposition->SetPickable(kTRUE);
293  scposition->SetTitle("Super cluster centroid");
294 
295  x = i->caloPosition().eta();
296  y = i->caloPosition().phi();
297 
298  scposition->AddLine(x - delta, y, z, x + delta, y, z);
299  scposition->AddLine(x, y - delta, z, x, y + delta, z);
300  scposition->AddLine(x, y, z - delta, x, y, z + delta);
301  scposition->SetLineColor(kBlue);
302  scposition->SetLineWidth(2);
303  scposition->SetDepthTest(kFALSE);
304  tList->AddElement(scposition);
305 
306  scposition->SetMarkerColor(kBlue);
307  scposition->SetMarkerStyle(2);
308  m_legend->AddEntry(scposition, "Super cluster centroid", "p");
309 
310  // seed position
311  TEveStraightLineSet *seedposition = new TEveStraightLineSet("seed position");
312  seedposition->SetTitle("Seed cluster centroid");
313  seedposition->SetPickable(kTRUE);
314 
315  x = i->superCluster()->seed()->position().eta();
316  y = i->superCluster()->seed()->position().phi();
317 
318  seedposition->AddLine(x - delta, y - delta, z, x + delta, y + delta, z);
319  seedposition->AddLine(x - delta, y + delta, z, x + delta, y - delta, z);
320  seedposition->SetLineColor(kRed);
321  seedposition->SetLineWidth(2);
322  seedposition->SetDepthTest(kFALSE);
323  tList->AddElement(seedposition);
324 
325  seedposition->SetMarkerColor(kRed);
326  seedposition->SetMarkerStyle(5);
327  m_legend->AddEntry(seedposition, "Seed cluster centroid", "p");
328 
329  // electron direction (show it if it's within
330  // the area of interest)
331  if (fabs(i->phi() - i->caloPosition().phi()) < 25 * 0.0172 &&
332  fabs(i->eta() - i->caloPosition().eta()) < 25 * 0.0172) {
333  TEveStraightLineSet *eldirection = new TEveStraightLineSet("seed position");
334  eldirection->SetTitle("Electron direction at vertex");
335  eldirection->SetPickable(kTRUE);
336 
337  x = i->eta();
338  y = i->phi();
339  eldirection->AddLine(x - delta, y - delta, z, x + delta, y + delta, z);
340  eldirection->AddLine(x - delta, y + delta, z, x + delta, y - delta, z);
341  eldirection->SetLineColor(kGreen + 1);
342  eldirection->SetDepthTest(kFALSE);
343  tList->AddElement(eldirection);
344 
345  eldirection->SetMarkerColor(kGreen);
346  eldirection->SetMarkerStyle(5);
347  m_legend->AddEntry(eldirection, "Direction at vertex", "p");
348  }
349 }
350 
void showSuperCluster(const reco::SuperCluster &cluster, Color_t color=kYellow)
void setTextInfo(const FWModelId &id, const reco::GsfElectron *) override
math::XYZPoint caloPosition() const
Definition: GsfElectron.h:302
double makeLegend(double x0=0.02, double y0=0.95, Color_t clustered1=kGreen+1, Color_t clustered2=kTeal, Color_t supercluster=kYellow)
const FWEventItem * item()
Bool_t checkRange(Double_t &, Double_t &, Double_t &, Double_t &, Double_t, Double_t)
void build(const FWModelId &id, const reco::GsfElectron *) override
#define REGISTER_FWDETAILVIEW(_classname_, _name_,...)
FWECALDetailViewBuilder * m_builder
def overlay(hists, ytitle, header, addon)
Definition: compare.py:122
bool isAvailable() const
Definition: Ref.h:535
void showSuperClusters(Color_t color1=kGreen+2, Color_t color2=kTeal)
void drawCrossHair(const reco::GsfElectron *, TEveCaloLego *, TEveElementList *)
double deltaEtaSuperClusterTrackAtVtx(const reco::GsfElectron &)
void addSceneInfo(const reco::GsfElectron *i, TEveElementList *tList)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
double deltaPhiSuperClusterTrackAtVtx(const reco::GsfElectron &)
void addTrackPointsInCaloData(const reco::GsfElectron *, TEveCaloLego *)
double phi() const final
momentum azimuthal angle
SuperClusterRef superCluster() const override
reference to a SuperCluster
Definition: GsfElectron.h:155
double eta() const final
momentum pseudorapidity