text: 
  #include "TGLViewer.h"  // access to over-all bounding box
  #include "TEveCalo.h"   // workaround for TEveCalo3D bounding box
  #include "TGLFontManager.h"
  #include "TEveScene.h"
  #include "TEveManager.h"
  #include "TEveStraightLineSet.h"
  #include "TEveTrack.h"
  #include "TEveTrackPropagator.h"
  #include "TEveTrans.h"
  #include "TEveText.h"
  #include "TEveGeoShape.h"
  #include "TGSlider.h"
  #include "TGButton.h"
  #include "TGLabel.h"
  #include "TCanvas.h"
  #include "TLatex.h"
  #include "TLegend.h"
  #include "TG3DLine.h"
  #include "TEveCaloData.h"
  
  // CMSSW includes
  #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
  #include "DataFormats/TrackReco/interface/Track.h"
  #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
  #include "DataFormats/MuonDetId/interface/DTChamberId.h"
  
  // Fireworks includes
  #include "Fireworks/Core/interface/FWModelId.h"
  #include "Fireworks/Core/interface/FWColorManager.h"
  #include "Fireworks/Core/interface/FWGeometry.h"
  #include "Fireworks/Core/interface/FWEventItem.h"
  #include "Fireworks/Core/interface/CSGAction.h"
  #include "Fireworks/Core/interface/FWMagField.h"
  #include "Fireworks/Core/interface/FWBeamSpot.h"
  #include "Fireworks/Core/interface/fwLog.h"
  #include "Fireworks/Calo/interface/FWECALCaloDataDetailViewBuilder.h"
  
  #include "Fireworks/Electrons/plugins/FWConvTrackHitsDetailView.h"
  #include "DataFormats/EgammaCandidates/interface/Conversion.h"
  #include "Fireworks/Tracks/interface/TrackUtils.h"
  
  namespace {
    void (FWConvTrackHitsDetailView::*foo)();
  }
  
  FWConvTrackHitsDetailView::FWConvTrackHitsDetailView()
      : m_modules(nullptr), m_moduleLabels(nullptr), m_hits(nullptr), m_legend(nullptr), m_orthographic(false) {}
  
  FWConvTrackHitsDetailView::~FWConvTrackHitsDetailView() {}
  
  namespace {
    void setCameraInit(
        TGLViewer* v, TGLViewer::ECameraType type, const TEveVectorD b1, TEveVectorD b3, TEveVector center) {
      TGLCamera& cam = v->RefCamera(type);
      TGLMatrix& trans = cam.RefCamBase();
  
      trans.Set(trans.GetTranslation(), b3.Arr(), b1.Arr());
      cam.Setup(v->RefOverallBoundingBox(), kTRUE);
  
      cam.SetExternalCenter(true);
      cam.SetCenterVec(center.fX, center.fY, center.fZ);
    }
  
    /*
      // alternative to setCameraInit
  void setCamera(TGLViewer* v, TGLViewer::ECameraType type, const TEveVectorD b1, TEveVectorD b2,  TEveVectorD b3, TEveVector center )
  {
     // b1 = fwd, b2 = lft, b3 = up
  
     TGLCamera& cam = v->RefCamera(type); 
     TGLMatrix& trans = cam.RefCamBase();
     
     trans.SetBaseVec(1, b1.Arr());
     trans.SetBaseVec(2, b2.Arr());
     trans.SetBaseVec(3, b3.Arr());
  
     cam.SetExternalCenter(true);
     cam.SetCenterVec(center.fX, center.fY, center.fZ);
  }
      */
  }  // namespace
  void FWConvTrackHitsDetailView::build(const FWModelId& id, const reco::Conversion* conv) {
    if (conv->nTracks() < 2)
      return;
    const reco::Track* track0 = conv->tracks().at(0).get();
    const reco::Track* track1 = conv->tracks().at(1).get();
  
    m_guiFrame->AddFrame(new TGLabel(m_guiFrame, "Camera Views:"), new TGLayoutHints(kLHintsLeft, 2, 2, 2, 2));
  
    {
      TGHorizontalFrame* f = new TGHorizontalFrame(m_guiFrame);
      m_guiFrame->AddFrame(f, new TGLayoutHints(kLHintsExpandX, 2, 0, 0, 0));
      {
        CSGAction* action = new CSGAction(this, "Top");
        TGTextButton* b = new TGTextButton(f, action->getName().c_str());
        f->AddFrame(b, new TGLayoutHints(kLHintsExpandX));
        TQObject::Connect(b, "Clicked()", "CSGAction", action, "activate()");
        b->SetToolTipText("plane normal: track0 x track1");
        action->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::camera1Callback));
      }
  
      {
        CSGAction* action = new CSGAction(this, "Side");
        TGTextButton* b = new TGTextButton(f, action->getName().c_str());
        f->AddFrame(b, new TGLayoutHints(kLHintsExpandX));
        TQObject::Connect(b, "Clicked()", "CSGAction", action, "activate()");
        b->SetToolTipText("left fir: track1");
        action->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::camera2Callback));
      }
      {
        CSGAction* action = new CSGAction(this, "Front");
        TGTextButton* b = new TGTextButton(f, action->getName().c_str());
        f->AddFrame(b, new TGLayoutHints(kLHintsExpandX));
        TQObject::Connect(b, "Clicked()", "CSGAction", action, "activate()");
        action->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::camera3Callback));
        b->SetToolTipText("plane normal: track1 ");
      }
    }
  
    {
      m_camTypeAction = new CSGAction(this, " Set Ortographic Projection ");
      m_camTypeAction->createTextButton(m_guiFrame, new TGLayoutHints(kLHintsExpandX, 2, 0, 1, 4));
      m_camTypeAction->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::switchProjection));
    }
    {
      CSGAction* action = new CSGAction(this, "Draw Module");
      TGCheckButton* b = new TGCheckButton(m_guiFrame, action->getName().c_str());
      b->SetState(kButtonDown, false);
      m_guiFrame->AddFrame(b, new TGLayoutHints(kLHintsNormal, 2, 3, 1, 4));
      TQObject::Connect(b, "Clicked()", "CSGAction", action, "activate()");
      action->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::rnrModules));
    }
    {
      CSGAction* action = new CSGAction(this, "Draw Hits");
      TGCheckButton* b = new TGCheckButton(m_guiFrame, action->getName().c_str());
      b->SetState(kButtonDown, false);
      m_guiFrame->AddFrame(b, new TGLayoutHints(kLHintsNormal, 2, 3, 1, 4));
      TQObject::Connect(b, "Clicked()", "CSGAction", action, "activate()");
      action->activated.connect(sigc::mem_fun(*this, &FWConvTrackHitsDetailView::rnrHits));
    }
  
    TGCompositeFrame* p = (TGCompositeFrame*)m_guiFrame->GetParent();
    p->MapSubwindows();
    p->Layout();
  
    m_modules = new TEveElementList("Modules");
    m_eveScene->AddElement(m_modules);
    m_moduleLabels = new TEveElementList("Modules");
    m_eveScene->AddElement(m_moduleLabels);
    m_hits = new TEveElementList("Hits");
    m_eveScene->AddElement(m_hits);
    if (track1->extra().isAvailable()) {
      addModules(*track1, id.item(), m_modules, true);
      addHits(*track1, id.item(), m_hits, true);
    }
    if (track0->extra().isAvailable()) {
      addModules(*track0, id.item(), m_modules, true);
      addHits(*track0, id.item(), m_hits, true);
    }
    for (TEveElement::List_i i = m_modules->BeginChildren(), end = m_modules->EndChildren(); i != end; ++i) {
      TEveGeoShape* gs = dynamic_cast<TEveGeoShape*>(*i);
      const auto& rhs = *(*(i));
      if (gs == nullptr && (*i != nullptr)) {
        std::cerr << "Got a " << typeid(rhs).name() << ", expecting TEveGeoShape. ignoring (it must be the clusters)."
                  << std::endl;
        continue;
      }
      // gs->SetMainTransparency(75);
      // gs->SetPickable(kFALSE);
  
      TString name = gs->GetElementTitle();
      if (!name.Contains("BAD") && !name.Contains("INACTIVE") && !name.Contains("LOST")) {
        gs->SetMainColor(kBlue);
      }
      TEveText* text = new TEveText(name.Data());
      text->PtrMainTrans()->SetFrom(gs->RefMainTrans().Array());
      text->SetFontMode(TGLFont::kPixmap);
      text->SetFontSize(12);
      m_moduleLabels->AddElement(text);
    }
    m_moduleLabels->SetRnrChildren(false);
  
    TEveTrackPropagator* prop = new TEveTrackPropagator();
    prop->SetMagFieldObj(item()->context().getField(), false);
    prop->SetStepper(TEveTrackPropagator::kRungeKutta);
    prop->SetMaxR(123);
    prop->SetMaxZ(300);
    prop->SetMaxStep(1);
    prop->SetRnrDaughters(kTRUE);
    prop->SetRnrReferences(kTRUE);
    prop->SetRnrDecay(kTRUE);
  
    // first-vertex style
    prop->SetRnrFV(kTRUE);
    prop->RefFVAtt().SetMarkerColor(id.item()->defaultDisplayProperties().color());
    prop->RefFVAtt().SetMarkerSize(0.8);
  
    // path-mark style
    prop->RefPMAtt().SetMarkerSize(0.5);
    prop->RefPMAtt().SetMarkerColor(id.item()->defaultDisplayProperties().color());
  
    TEveTrack* trk1 = fireworks::prepareTrack(*track1, prop);
    trk1->MakeTrack();
    trk1->SetLineWidth(2);
    trk1->SetTitle("Track 1 and its ref states");
    trk1->SetMainColor(id.item()->defaultDisplayProperties().color());
    trk1->SetLineStyle(7);
    m_eveScene->AddElement(trk1);
  
    TEveTrack* trk0 = fireworks::prepareTrack(*track0, prop);
    trk0->MakeTrack();
    trk0->SetLineWidth(2);
    trk0->SetTitle("Track 0 and its ref states");
    trk0->SetMainColor(id.item()->defaultDisplayProperties().color());
    m_eveScene->AddElement(trk0);
  
    // create TEveCalo3D object, fix bounding box
    {
      float phi = conv->pairMomentum().phi();
      float eta = conv->pairMomentum().eta();
  
      FWECALCaloDataDetailViewBuilder caloBld(id.item()->getEvent(), id.item()->getGeom(), eta, phi, 30);
      TEveCaloData* data = caloBld.buildCaloData(false);
      // AMT!!! this is memory leak, check why it needs to be added
      TEveCalo3D* calo3d = new TEveCalo3D(data);
      gEve->AddElement(data);
      calo3d->SetBarrelRadius(129.00);
      calo3d->SetEndCapPos(268.36);
  
      float theta = TEveCaloData::EtaToTheta(eta);
      float ext = data->GetMaxVal(true) * calo3d->GetValToHeight();
      if (TMath::Abs(eta) < calo3d->GetTransitionEta()) {
        // printf("barrel\n");
        float x = calo3d->GetBarrelRadius() * TMath::Cos(phi);
        float y = calo3d->GetBarrelRadius() * TMath::Sin(phi);
        float z = calo3d->GetBarrelRadius() / TMath::Tan(theta);
  
        calo3d->SetupBBoxCube(ext, x, y, z);
      } else {
        // printf("endcap\n");
        float z = TMath::Sign(calo3d->GetEndCapPos(), eta);
        float r = z * TMath::Tan(theta);
        calo3d->SetupBBoxCube(ext, r * TMath::Cos(phi), r * TMath::Sin(phi), z);
      }
      m_eveScene->AddElement(calo3d);
    }
  
    //  base vectors
    TEveVectorD fwd = trk1->GetMomentum().Cross(trk0->GetMomentum());
    fwd.Normalize();
    TEveVectorD lft = trk1->GetMomentum();
    lft.Normalize();
    TEveVectorD up = lft.Cross(fwd);
  
    TEveVectorD c = (trk1->GetVertex() + trk0->GetVertex()) * 0.5;
    if (true) {
      setCameraInit(viewerGL(), TGLViewer::kCameraPerspXOZ, fwd, up, c);  //default
      setCameraInit(viewerGL(), TGLViewer::kCameraPerspYOZ, up, lft, c);
      setCameraInit(viewerGL(), TGLViewer::kCameraPerspXOY, lft, fwd, c);
  
      setCameraInit(viewerGL(), TGLViewer::kCameraOrthoXOY, fwd, up, c);
      setCameraInit(viewerGL(), TGLViewer::kCameraOrthoXOZ, up, lft, c);
      setCameraInit(viewerGL(), TGLViewer::kCameraOrthoZOY, lft, fwd, c);
    }
    {
      Float_t sfac = 100;
      fwd *= sfac;
      lft *= sfac;
      up *= sfac;
      int transp = 90;
      {
        TEveStraightLineSet* bls = new TEveStraightLineSet("base1");
        bls->AddLine(c, fwd + c);
        bls->SetMainColor(kBlue);
        bls->SetMainTransparency(transp);
        bls->SetPickable(false);
        m_eveScene->AddElement(bls);
      }
  
      {
        TEveStraightLineSet* bls = new TEveStraightLineSet("base2");
        bls->AddLine(c, lft + c);
        bls->SetMainColor(kBlue);
        bls->SetMainTransparency(transp);
        bls->SetPickable(false);
        m_eveScene->AddElement(bls);
      }
  
      {
        TEveStraightLineSet* bls = new TEveStraightLineSet("base3");
        bls->AddLine(c, up + c);
        bls->SetMainColor(kBlue);
        bls->SetMainTransparency(transp);
        bls->SetPickable(false);
        m_eveScene->AddElement(bls);
      }
    }
    {
      TEveStraightLineSet* bls = new TEveStraightLineSet("Photon", "Photon");
      FWBeamSpot* bs = context().getBeamSpot();
      bls->AddLine(c.fX, c.fY, c.fZ, bs->x0(), bs->y0(), bs->z0());
      bls->SetMainColor(id.item()->defaultDisplayProperties().color());
      bls->SetLineStyle(3);
      m_eveScene->AddElement(bls);
    }
  
    viewerGL()->SetStyle(TGLRnrCtx::kOutline);
    viewerGL()->ResetCamerasAfterNextUpdate();
    viewerGL()->UpdateScene(kFALSE);
    gEve->Redraw3D();
  
    setTextInfo(id, conv);
    foo = &FWConvTrackHitsDetailView::camera1Callback;
  }
  
  void FWConvTrackHitsDetailView::setTextInfo(const FWModelId& id, const reco::Conversion* conv) {
    m_infoCanvas->cd();
  
    float_t x = 0.02;
    float y = 0.95;
  
    TLatex* latex = new TLatex(x, y, "");
    const double textsize(0.07);
    latex->SetTextSize(2 * textsize);
  
    latex->DrawLatex(x, y, id.item()->modelName(id.index()).c_str());
    y -= latex->GetTextSize() * 0.6;
  
    latex->SetTextSize(textsize);
    float lineH = latex->GetTextSize() * 0.6;
  
    latex->DrawLatex(x,
                     y,
                     Form("p_{T}=%.1f GeV, #eta=%0.2f, #varphi=%0.2f",
                          sqrt(conv->pairMomentum().Perp2()),
                          conv->pairMomentum().eta(),
                          conv->pairMomentum().phi()));
    y -= lineH;
    latex->DrawLatex(x,
                     y,
                     Form("vtx=(%.1f, %.1f, %.1f) r=%.1f [cm]",
                          conv->conversionVertex().x(),
                          conv->conversionVertex().y(),
                          conv->conversionVertex().z(),
                          conv->conversionVertex().position().rho()));
    y -= lineH;
    latex->DrawLatex(x, y, Form("#Deltactg#theta=%.3f", conv->pairCotThetaSeparation()));
    y -= lineH;
    latex->DrawLatex(x, y, Form("#Delta#phi_{vtx}=%.3f", conv->dPhiTracksAtVtx()));
    y -= lineH;
    latex->DrawLatex(x, y, Form("dist. min. app.=%.3f cm", conv->distOfMinimumApproach()));
    y -= lineH;
    y -= lineH;
  
    const reco::Track* track0 = conv->tracks().at(0).get();
    latex->DrawLatex(x, y, Form("Trk0 q=%i", track0->charge()));
    y -= lineH;
    latex->DrawLatex(x, y, Form("p_{T}=%.1f GeV, #eta=%0.2f, #varphi=%0.2f", track0->pt(), track0->eta(), track0->phi()));
    y -= lineH;
    const reco::HitPattern& hp0 = track0->hitPattern();
    int nvalid_tk0 = 0, ninvalid_tk0 = 0, npix_tk0 = 0, nstrip_tk0 = 0;
    for (int i_tk0 = 0; i_tk0 < hp0.numberOfAllHits(reco::HitPattern::TRACK_HITS); i_tk0++) {
      uint32_t hit = hp0.getHitPattern(reco::HitPattern::TRACK_HITS, i_tk0);
      if (reco::HitPattern::validHitFilter(hit)) {
        nvalid_tk0++;
        if (reco::HitPattern::pixelHitFilter(hit))
          npix_tk0++;
        else if (reco::HitPattern::stripHitFilter(hit))
          nstrip_tk0++;
      } else
        ninvalid_tk0++;
    }
    latex->DrawLatex(x, y, Form("valid hits: %i (pix. %i, str. %i)", nvalid_tk0, npix_tk0, nstrip_tk0));
    y -= lineH;
    latex->DrawLatex(x, y, Form("invalid: %i", ninvalid_tk0));
    y -= lineH;
  
    int npix_mhi_tk0 = 0, nstrip_mhi_tk0 = 0;
    for (int i_mhi_tk0 = 0; i_mhi_tk0 < hp0.numberOfAllHits(reco::HitPattern::MISSING_INNER_HITS); i_mhi_tk0++) {
      uint32_t hit = hp0.getHitPattern(reco::HitPattern::MISSING_INNER_HITS, i_mhi_tk0);
      if (reco::HitPattern::pixelHitFilter(hit))
        npix_mhi_tk0++;
      else if (reco::HitPattern::stripHitFilter(hit))
        nstrip_mhi_tk0++;
    }
    latex->DrawLatex(x, y, Form("miss. inner hits: pix. %i, str. %i", npix_mhi_tk0, nstrip_mhi_tk0));
  
    y -= lineH;
    y -= lineH;
    const reco::Track* track1 = conv->tracks().at(1).get();
    latex->DrawLatex(x, y, Form("Trk1 q=%i", track1->charge()));
    y -= lineH;
    latex->DrawLatex(x, y, Form("p_{T}=%.1f GeV, #eta=%0.2f, #varphi=%0.2f", track1->pt(), track1->eta(), track1->phi()));
    y -= lineH;
  
    const reco::HitPattern& hp1 = track1->hitPattern();
    int nvalid_tk1 = 0, ninvalid_tk1 = 0, npix_tk1 = 0, nstrip_tk1 = 0;
    for (int i_tk1 = 0; i_tk1 < hp1.numberOfAllHits(reco::HitPattern::TRACK_HITS); i_tk1++) {
      uint32_t hit = hp1.getHitPattern(reco::HitPattern::TRACK_HITS, i_tk1);
      if (reco::HitPattern::validHitFilter(hit)) {
        nvalid_tk1++;
        if (reco::HitPattern::pixelHitFilter(hit))
          npix_tk1++;
        else if (reco::HitPattern::stripHitFilter(hit))
          nstrip_tk1++;
      } else
        ninvalid_tk1++;
    }
    latex->DrawLatex(x, y, Form("valid hits: %i (pix. %i, str. %i)", nvalid_tk1, npix_tk1, nstrip_tk1));
    y -= lineH;
    latex->DrawLatex(x, y, Form("invalid: %i", ninvalid_tk1));
    y -= lineH;
  
    int npix_mhi_tk1 = 0, nstrip_mhi_tk1 = 0;
    for (int i_mhi_tk1 = 0; i_mhi_tk1 < hp1.numberOfAllHits(reco::HitPattern::MISSING_INNER_HITS); i_mhi_tk1++) {
      uint32_t hit = hp1.getHitPattern(reco::HitPattern::MISSING_INNER_HITS, i_mhi_tk1);
      if (reco::HitPattern::pixelHitFilter(hit))
        npix_mhi_tk1++;
      else if (reco::HitPattern::stripHitFilter(hit))
        nstrip_mhi_tk1++;
    }
    latex->DrawLatex(x, y, Form("miss. inner hits: pix. %i, str. %i", npix_mhi_tk1, nstrip_mhi_tk1));
    y -= lineH;
    y -= lineH;
  }
  
  void FWConvTrackHitsDetailView::addTrackerHits3D(std::vector<TVector3>& points,
                                                   class TEveElementList* tList,
                                                   Color_t color,
                                                   int size) {
    // !AMT this is  detail view specific, should move to track hits
    // detail view
  
    TEvePointSet* pointSet = new TEvePointSet();
    pointSet->SetMarkerSize(size);
    pointSet->SetMarkerStyle(4);
    pointSet->SetPickable(kTRUE);
    pointSet->SetTitle("Pixel Hits");
    pointSet->SetMarkerColor(color);
  
    for (std::vector<TVector3>::const_iterator it = points.begin(), itEnd = points.end(); it != itEnd; ++it) {
      pointSet->SetNextPoint(it->x(), it->y(), it->z());
    }
    tList->AddElement(pointSet);
  }
  
  void FWConvTrackHitsDetailView::addHits(const reco::Track& track,
                                          const FWEventItem* iItem,
                                          TEveElement* trkList,
                                          bool addNearbyHits) {
    std::vector<TVector3> pixelPoints;
    fireworks::pushPixelHits(pixelPoints, *iItem, track);
    TEveElementList* pixels = new TEveElementList("Pixels");
    trkList->AddElement(pixels);
    if (addNearbyHits) {
      // get the extra hits
      std::vector<TVector3> pixelExtraPoints;
      fireworks::pushNearbyPixelHits(pixelExtraPoints, *iItem, track);
      // draw first the others
      addTrackerHits3D(pixelExtraPoints, pixels, kRed, 1);
      // then the good ones, so they're on top
      addTrackerHits3D(pixelPoints, pixels, kGreen, 1);
    } else {
      // just add those points with the default color
      addTrackerHits3D(pixelPoints, pixels, iItem->defaultDisplayProperties().color(), 1);
    }
  
    // strips
    TEveElementList* strips = new TEveElementList("Strips");
    trkList->AddElement(strips);
    fireworks::addSiStripClusters(iItem, track, strips, addNearbyHits, false);
  }
  
  //______________________________________________________________________________
  
  void FWConvTrackHitsDetailView::addModules(const reco::Track& track,
                                             const FWEventItem* iItem,
                                             TEveElement* trkList,
                                             bool addLostHits) {
    std::set<unsigned int> ids;
    for (trackingRecHit_iterator recIt = track.recHitsBegin(), recItEnd = track.recHitsEnd(); recIt != recItEnd;
         ++recIt) {
      DetId detid = (*recIt)->geographicalId();
      if (!addLostHits && !(*recIt)->isValid())
        continue;
      if (detid.rawId() != 0) {
        TString name("");
        switch (detid.det()) {
          case DetId::Tracker:
            switch (detid.subdetId()) {
              case SiStripDetId::TIB:
                name = "TIB ";
                break;
              case SiStripDetId::TOB:
                name = "TOB ";
                break;
              case SiStripDetId::TID:
                name = "TID ";
                break;
              case SiStripDetId::TEC:
                name = "TEC ";
                break;
              case PixelSubdetector::PixelBarrel:
                name = "Pixel Barrel ";
                break;
              case PixelSubdetector::PixelEndcap:
                name = "Pixel Endcap ";
              default:
                break;
            }
            break;
  
          case DetId::Muon:
            switch (detid.subdetId()) {
              case MuonSubdetId::DT:
                name = "DT";
                detid = DetId(DTChamberId(detid));  // get rid of layer bits
                break;
              case MuonSubdetId::CSC:
                name = "CSC";
                break;
              case MuonSubdetId::RPC:
                name = "RPC";
                break;
              default:
                break;
            }
            break;
          default:
            break;
        }
        if (!ids.insert(detid.rawId()).second)
          continue;
        if (iItem->getGeom()) {
          TEveGeoShape* shape = iItem->getGeom()->getEveShape(detid);
          if (nullptr != shape) {
            shape->SetMainTransparency(65);
            shape->SetPickable(kTRUE);
            switch ((*recIt)->type()) {
              case TrackingRecHit::valid:
                shape->SetMainColor(iItem->defaultDisplayProperties().color());
                break;
              case TrackingRecHit::missing:
              case TrackingRecHit::missing_inner:
              case TrackingRecHit::missing_outer:
                name += "LOST ";
                shape->SetMainColor(kRed);
                break;
              case TrackingRecHit::inactive_inner:
              case TrackingRecHit::inactive_outer:
              case TrackingRecHit::inactive:
                name += "INACTIVE ";
                shape->SetMainColor(28);
                break;
              case TrackingRecHit::bad:
                name += "BAD ";
                shape->SetMainColor(218);
                break;
            }
            shape->SetTitle(name + ULong_t(detid.rawId()));
            trkList->AddElement(shape);
          } else {
            fwLog(fwlog::kInfo) << "Failed to get shape extract for a tracking rec hit: "
                                << "\n"
                                << fireworks::info(detid) << std::endl;
          }
        }
      }
    }
  }
  
  //______________________________________________________________________________
  void FWConvTrackHitsDetailView::pickCameraCenter() {
    viewerGL()->PickCameraCenter();
    viewerGL()->SetDrawCameraCenter(kTRUE);
  }
  
  void FWConvTrackHitsDetailView::switchProjection() {
    m_orthographic = !m_orthographic;
    m_camTypeAction->setName(m_orthographic ? "Set Perspective Projection" : "Set Orthographic Projection");
  
    (this->*foo)();
    //printf("current isOrthographic : %d \n",  viewerGL()->CurrentCamera().IsOrthographic());
  }
  
  void FWConvTrackHitsDetailView::rnrLabels() {
    m_moduleLabels->SetRnrChildren(!m_moduleLabels->GetRnrChildren());
    gEve->Redraw3D();
  }
  
  void FWConvTrackHitsDetailView::rnrModules() {
    m_modules->SetRnrChildren(!m_modules->GetRnrChildren());
    gEve->Redraw3D();
  }
  
  void FWConvTrackHitsDetailView::rnrHits() {
    m_hits->SetRnrChildren(!m_hits->GetRnrChildren());
    gEve->Redraw3D();
  }
  
  void FWConvTrackHitsDetailView::camera1Callback() {
    foo = &FWConvTrackHitsDetailView::camera1Callback;
  
    viewerGL()->SetCurrentCamera(m_orthographic ? TGLViewer::kCameraOrthoXOY : TGLViewer::kCameraPerspXOZ);
    viewerGL()->ResetCurrentCamera();
    viewerGL()->RequestDraw();
  }
  
  void FWConvTrackHitsDetailView::camera2Callback() {
    foo = &FWConvTrackHitsDetailView::camera2Callback;
  
    viewerGL()->SetCurrentCamera(m_orthographic ? TGLViewer::kCameraOrthoXOZ : TGLViewer::kCameraPerspYOZ);
    viewerGL()->ResetCurrentCamera();
    viewerGL()->RequestDraw();
  }
  
  void FWConvTrackHitsDetailView::camera3Callback() {
    foo = &FWConvTrackHitsDetailView::camera3Callback;
  
    viewerGL()->SetCurrentCamera(m_orthographic ? TGLViewer::kCameraOrthoZOY : TGLViewer::kCameraPerspXOY);
    viewerGL()->ResetCurrentCamera();
    viewerGL()->RequestDraw();
  }
  
  REGISTER_FWDETAILVIEW(FWConvTrackHitsDetailView, Conversion);
  /*
  REGISTER_FWDETAILVIEW(FWConvTrackHitsDetailView, Conversion, ecalRecHit);
  REGISTER_FWDETAILVIEW(FWConvTrackHitsDetailView, Conversion, reducedEcalRecHitsEB);
  REGISTER_FWDETAILVIEW(FWConvTrackHitsDetailView, Conversion, reducedEGamma);
  */
  