Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:22

0001 // -*- C++ -*-
0002 //
0003 // Package:     Electrons
0004 // Class  :     FWElectronDetailView
0005 //
0006 
0007 // ROOT includes
0008 #include "TLatex.h"
0009 #include "TEveCalo.h"
0010 #include "TEveStraightLineSet.h"
0011 #include "TEvePointSet.h"
0012 #include "TEveScene.h"
0013 #include "TEveViewer.h"
0014 #include "TGLViewer.h"
0015 #include "TGLOverlay.h"
0016 #include "TCanvas.h"
0017 #include "TLegend.h"
0018 #include "TEveCaloLegoOverlay.h"
0019 #include "TRootEmbeddedCanvas.h"
0020 
0021 // Fireworks includes
0022 #include "Fireworks/Electrons/plugins/FWElectronDetailView.h"
0023 #include "Fireworks/Calo/interface/FWECALDetailViewBuilder.h"
0024 #include "Fireworks/Core/interface/FWColorManager.h"
0025 #include "Fireworks/Core/interface/FWModelId.h"
0026 #include "Fireworks/Core/interface/FWEventItem.h"
0027 #include "Fireworks/Core/interface/FWGLEventHandler.h"
0028 
0029 // CMSSW includes
0030 
0031 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0032 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
0033 
0034 //
0035 // constructors and destructor
0036 //
0037 FWElectronDetailView::FWElectronDetailView() : m_data(nullptr), m_builder(nullptr), m_legend(nullptr) {}
0038 
0039 FWElectronDetailView::~FWElectronDetailView() {
0040   m_eveViewer->GetGLViewer()->DeleteOverlayElements(TGLOverlayElement::kUser);
0041 
0042   delete m_builder;
0043   if (m_data)
0044     m_data->DecDenyDestroy();
0045 }
0046 
0047 //
0048 // member functions
0049 //
0050 void FWElectronDetailView::build(const FWModelId &id, const reco::GsfElectron *iElectron) {
0051   if (!iElectron)
0052     return;
0053   // If SuperCluster reference is not stored,
0054   // take eta and phi of a Candidate
0055   double eta = 0;
0056   double phi = 0;
0057   if (iElectron->superCluster().isAvailable()) {
0058     eta = iElectron->caloPosition().eta();
0059     phi = iElectron->caloPosition().phi();
0060   } else {
0061     eta = iElectron->eta();
0062     phi = iElectron->phi();
0063   }
0064 
0065   // build ECAL objects
0066   m_builder = new FWECALDetailViewBuilder(id.item()->getEvent(), id.item()->getGeom(), eta, phi, 25);
0067 
0068   m_builder->showSuperClusters();
0069   if (iElectron->superCluster().isAvailable())
0070     m_builder->showSuperCluster(*(iElectron->superCluster()), kYellow + 1);
0071 
0072   TEveCaloLego *lego = m_builder->build();
0073   m_data = lego->GetData();
0074   m_eveScene->AddElement(lego);
0075 
0076   m_legend = new TLegend(0.01, 0.01, 0.99, 0.99, nullptr, "NDC");
0077   m_legend->SetTextSize(0.075);
0078   m_legend->SetBorderSize(0);
0079   m_legend->SetMargin(0.15);
0080   m_legend->SetEntrySeparation(0.05);
0081 
0082   // add Electron specific details
0083   if (false && iElectron->superCluster().isAvailable()) {
0084     addTrackPointsInCaloData(iElectron, lego);
0085     drawCrossHair(iElectron, lego, m_eveScene);
0086     addSceneInfo(iElectron, m_eveScene);
0087   }
0088 
0089   // draw axis at the window corners
0090   if (true) {
0091     TEveCaloLegoOverlay *overlay = new TEveCaloLegoOverlay();
0092     overlay->SetShowPlane(kFALSE);
0093     overlay->SetShowPerspective(kFALSE);
0094     overlay->SetCaloLego(lego);
0095     overlay->SetShowScales(true);  // temporary
0096     viewerGL()->AddOverlayElement(overlay);
0097   }
0098   // set event handler and flip camera to top view at beginning
0099   viewerGL()->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
0100   FWGLEventHandler *eh = new FWGLEventHandler((TGWindow *)viewerGL()->GetGLWidget(), (TObject *)viewerGL(), lego);
0101   viewerGL()->SetEventHandler(eh);
0102   viewerGL()->ResetCamerasAfterNextUpdate();
0103   viewerGL()->UpdateScene(kFALSE);
0104   gEve->Redraw3D();
0105 
0106   setTextInfo(id, iElectron);
0107 }
0108 
0109 double FWElectronDetailView::deltaEtaSuperClusterTrackAtVtx(const reco::GsfElectron &electron) {
0110   return electron.deltaEtaSuperClusterTrackAtVtx();
0111 }
0112 
0113 double FWElectronDetailView::deltaPhiSuperClusterTrackAtVtx(const reco::GsfElectron &electron) {
0114   return electron.deltaPhiSuperClusterTrackAtVtx();
0115 }
0116 
0117 void FWElectronDetailView::setTextInfo(const FWModelId &id, const reco::GsfElectron *electron) {
0118   m_infoCanvas->cd();
0119 
0120   float_t x = 0.02;
0121   float_t x2 = 0.52;
0122   float y = 0.95;
0123 
0124   TLatex *latex = new TLatex(x, y, "");
0125   const double textsize(0.05);
0126   latex->SetTextSize(2 * textsize);
0127 
0128   latex->DrawLatex(x, y, id.item()->modelName(id.index()).c_str());
0129   y -= latex->GetTextSize() * 0.6;
0130 
0131   latex->SetTextSize(textsize);
0132   float lineH = latex->GetTextSize() * 0.6;
0133 
0134   latex->DrawLatex(
0135       x, y, Form(" E_{T} = %.1f GeV, #eta = %0.2f, #varphi = %0.2f", electron->et(), electron->eta(), electron->phi()));
0136   y -= lineH;
0137   // summary
0138   if (electron->charge() > 0)
0139     latex->DrawLatex(x, y, " charge = +1");
0140   else
0141     latex->DrawLatex(x, y, " charge = -1");
0142   y -= lineH;
0143 
0144   if (electron->superCluster().isAvailable()) {
0145     // delta phi/eta in
0146     latex->DrawLatex(x, y, "SuperCluster vs inner state extrapolation");
0147     y -= lineH;
0148     latex->DrawLatex(x, y, TString::Format(" #Delta#eta_{in} = %.3f", electron->deltaEtaSuperClusterTrackAtVtx()));
0149     latex->DrawLatex(x2, y, TString::Format("#Delta#varphi_{in} = %.3f", electron->deltaPhiSuperClusterTrackAtVtx()));
0150     y -= lineH;
0151 
0152     // delta phi/eta out
0153     latex->DrawLatex(x, y, "SeedCluster vs outer state extrapolation");
0154     y -= lineH;
0155 
0156     latex->DrawLatex(x, y, TString::Format(" #Delta#eta_{out} = %.3f", electron->deltaEtaSeedClusterTrackAtCalo()));
0157     latex->DrawLatex(x2, y, TString::Format(" #Delta#varphi_{out} = %.3f", electron->deltaPhiSeedClusterTrackAtCalo()));
0158     y -= 2 * lineH;
0159   } else {
0160     latex->DrawLatex(x, y, "Ref to SuperCluster is not available");
0161   }
0162 
0163   latex->DrawLatex(x, y, TString::Format(" Tracker driven seed: %s", electron->trackerDrivenSeed() ? "YES" : "NO"));
0164   y -= lineH;
0165   latex->DrawLatex(x, y, TString::Format(" ECAL driven seed: %s", electron->ecalDrivenSeed() ? "YES" : "NO"));
0166   y -= lineH;
0167 
0168   y = m_builder->makeLegend(0.02, y);
0169   y -= lineH;
0170 
0171   m_legend->SetY2(y);
0172   m_legend->Draw();
0173   m_legend = nullptr;  // Deleted together with TPad.
0174 }
0175 
0176 void FWElectronDetailView::drawCrossHair(const reco::GsfElectron *i, TEveCaloLego *lego, TEveElementList *tList) {
0177   double ymax = lego->GetPhiMax();
0178   double ymin = lego->GetPhiMin();
0179   double xmax = lego->GetEtaMax();
0180   double xmin = lego->GetEtaMin();
0181 
0182   // draw crosshairs for track intersections
0183 
0184   {
0185     const double eta = i->superCluster()->seed()->position().eta() - i->deltaEtaSeedClusterTrackAtCalo();
0186     const double phi = i->superCluster()->seed()->position().phi() - i->deltaPhiSeedClusterTrackAtCalo();
0187 
0188     TEveStraightLineSet *trackpositionAtCalo = new TEveStraightLineSet("sc trackpositionAtCalo");
0189     trackpositionAtCalo->SetPickable(kTRUE);
0190     trackpositionAtCalo->SetTitle("Track position at Calo propagating from the outermost state");
0191 
0192     trackpositionAtCalo->AddLine(eta, ymin, 0, eta, ymax, 0);
0193     trackpositionAtCalo->AddLine(xmin, phi, 0, xmax, phi, 0);
0194 
0195     trackpositionAtCalo->SetDepthTest(kFALSE);
0196     trackpositionAtCalo->SetLineColor(kBlue);
0197     tList->AddElement(trackpositionAtCalo);
0198 
0199     m_legend->AddEntry(trackpositionAtCalo, "From outermost state", "l");
0200   }
0201   //
0202   // pin position
0203   //
0204   {
0205     TEveStraightLineSet *pinposition = new TEveStraightLineSet("pin position");
0206     pinposition->SetPickable(kTRUE);
0207     pinposition->SetTitle("Track position at Calo propagating from the innermost state");
0208     Double_t eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
0209     Double_t phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
0210 
0211     pinposition->AddLine(eta, ymax, 0, eta, ymin, 0);
0212     pinposition->AddLine(xmin, phi, 0, xmax, phi, 0);
0213 
0214     pinposition->SetDepthTest(kFALSE);
0215     pinposition->SetLineColor(kRed);
0216     tList->AddElement(pinposition);
0217 
0218     m_legend->AddEntry(pinposition, "From innermost state", "l");
0219   }
0220 }
0221 
0222 Bool_t FWElectronDetailView::checkRange(
0223     Double_t &em, Double_t &eM, Double_t &pm, Double_t &pM, Double_t eta, Double_t phi) {
0224   Bool_t changed = kFALSE;
0225 
0226   //check eta
0227   if (eta < em) {
0228     em = eta;
0229     changed = kTRUE;
0230   } else if (eta > eM) {
0231     eM = eta;
0232     changed = kTRUE;
0233   }
0234 
0235   // check phi
0236   if (phi < pm) {
0237     pm = phi;
0238     changed = kTRUE;
0239   } else if (phi > pM) {
0240     pM = phi;
0241     changed = kTRUE;
0242   }
0243   return changed;
0244 }
0245 
0246 void FWElectronDetailView::addTrackPointsInCaloData(const reco::GsfElectron *i, TEveCaloLego *lego) {
0247   return;
0248   TEveCaloDataVec *data = (TEveCaloDataVec *)lego->GetData();
0249   Double_t em, eM, pm, pM;
0250   data->GetEtaLimits(em, eM);
0251   data->GetPhiLimits(pm, pM);
0252   data->IncDenyDestroy();
0253   Bool_t changed = kFALSE;
0254   // add cells in third layer if necessary
0255 
0256   //   trackpositionAtCalo
0257   {
0258     double eta = i->superCluster()->seed()->position().eta() - i->deltaEtaSeedClusterTrackAtCalo();
0259     double phi = i->superCluster()->seed()->position().phi() - i->deltaPhiSeedClusterTrackAtCalo();
0260 
0261     if (checkRange(em, eM, pm, pM, eta, phi))
0262       changed = kTRUE;
0263   }
0264   // pinposition
0265   {
0266     double eta = i->caloPosition().eta() - deltaEtaSuperClusterTrackAtVtx(*i);
0267     double phi = i->caloPosition().phi() - deltaPhiSuperClusterTrackAtVtx(*i);
0268 
0269     if (checkRange(em, eM, pm, pM, eta, phi))
0270       changed = kTRUE;
0271   }
0272   if (changed) {
0273     data->AddTower(em, eM, pm, pM);
0274     data->FillSlice(2, 0);
0275     data->DataChanged();
0276 
0277     lego->ComputeBBox();
0278     Double_t legoScale = ((eM - em) < (pM - pm)) ? (eM - em) : (pM - pm);
0279     lego->InitMainTrans();
0280     lego->RefMainTrans().SetScale(legoScale, legoScale, legoScale * 0.5);
0281     lego->RefMainTrans().SetPos((eM + em) * 0.5, (pM + pm) * 0.5, 0);
0282     lego->ElementChanged(true);
0283   }
0284 }
0285 
0286 void FWElectronDetailView::addSceneInfo(const reco::GsfElectron *i, TEveElementList *tList) {
0287   // centroids
0288   Double_t x(0), y(0), z(0);
0289   Double_t delta(0.02);
0290 
0291   TEveStraightLineSet *scposition = new TEveStraightLineSet("sc position");
0292   scposition->SetPickable(kTRUE);
0293   scposition->SetTitle("Super cluster centroid");
0294 
0295   x = i->caloPosition().eta();
0296   y = i->caloPosition().phi();
0297 
0298   scposition->AddLine(x - delta, y, z, x + delta, y, z);
0299   scposition->AddLine(x, y - delta, z, x, y + delta, z);
0300   scposition->AddLine(x, y, z - delta, x, y, z + delta);
0301   scposition->SetLineColor(kBlue);
0302   scposition->SetLineWidth(2);
0303   scposition->SetDepthTest(kFALSE);
0304   tList->AddElement(scposition);
0305 
0306   scposition->SetMarkerColor(kBlue);
0307   scposition->SetMarkerStyle(2);
0308   m_legend->AddEntry(scposition, "Super cluster centroid", "p");
0309 
0310   // seed position
0311   TEveStraightLineSet *seedposition = new TEveStraightLineSet("seed position");
0312   seedposition->SetTitle("Seed cluster centroid");
0313   seedposition->SetPickable(kTRUE);
0314 
0315   x = i->superCluster()->seed()->position().eta();
0316   y = i->superCluster()->seed()->position().phi();
0317 
0318   seedposition->AddLine(x - delta, y - delta, z, x + delta, y + delta, z);
0319   seedposition->AddLine(x - delta, y + delta, z, x + delta, y - delta, z);
0320   seedposition->SetLineColor(kRed);
0321   seedposition->SetLineWidth(2);
0322   seedposition->SetDepthTest(kFALSE);
0323   tList->AddElement(seedposition);
0324 
0325   seedposition->SetMarkerColor(kRed);
0326   seedposition->SetMarkerStyle(5);
0327   m_legend->AddEntry(seedposition, "Seed cluster centroid", "p");
0328 
0329   // electron direction (show it if it's within
0330   // the area of interest)
0331   if (fabs(i->phi() - i->caloPosition().phi()) < 25 * 0.0172 &&
0332       fabs(i->eta() - i->caloPosition().eta()) < 25 * 0.0172) {
0333     TEveStraightLineSet *eldirection = new TEveStraightLineSet("seed position");
0334     eldirection->SetTitle("Electron direction at vertex");
0335     eldirection->SetPickable(kTRUE);
0336 
0337     x = i->eta();
0338     y = i->phi();
0339     eldirection->AddLine(x - delta, y - delta, z, x + delta, y + delta, z);
0340     eldirection->AddLine(x - delta, y + delta, z, x + delta, y - delta, z);
0341     eldirection->SetLineColor(kGreen + 1);
0342     eldirection->SetDepthTest(kFALSE);
0343     tList->AddElement(eldirection);
0344 
0345     eldirection->SetMarkerColor(kGreen);
0346     eldirection->SetMarkerStyle(5);
0347     m_legend->AddEntry(eldirection, "Direction at vertex", "p");
0348   }
0349 }
0350 
0351 REGISTER_FWDETAILVIEW(FWElectronDetailView, Electron, ecalRecHit);
0352 REGISTER_FWDETAILVIEW(FWElectronDetailView, Electron, reducedEcalRecHitsEB);