From 494d2cdd7b56f95dc64cc4c33c48911f5f212ba2 Mon Sep 17 00:00:00 2001 From: alja Date: Mon, 1 Apr 2024 06:59:02 -0700 Subject: [PATCH] Add visualization of Candidates with CaloTower purpose --- Makefile | 2 +- UserVsd.py | 27 +++++++++- VsdBase.h | 4 +- VsdProvider.h | 7 ++- VsdProxies.h | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ evd.h | 30 ++++++++--- lego_bins.h | 33 ++++++++++++ 7 files changed, 232 insertions(+), 11 deletions(-) create mode 100644 lego_bins.h diff --git a/Makefile b/Makefile index d39991f..872dcd7 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ evd: UserVsd.root libVsdDict.so root.exe -e 'gSystem->Load("libVsdDict.so")' 'evd.h("UserVsd.root")' service: - c++ ${ROOT_CFLAGS} `root-config --libs` -lROOTEve -lROOTWebDisplay -lGeom -o $@ service.cc VsdTree.cc VsdDict.cc + c++ ${ROOT_CFLAGS} `root-config --libs` -lROOTEve -lROOTWebDisplay -lGeom -o $@ service.cc lego_bins.h VsdTree.cc VsdDict.cc # single: single.cc # c++ ${ROOT_CFLAGS} `root-config --libs` -L. -lVsdDict -Wl,-rpath=. -lROOTEve -lROOTWebDisplay -lGeom -o $@ single.cc diff --git a/UserVsd.py b/UserVsd.py index 655773a..f2dbb4d 100644 --- a/UserVsd.py +++ b/UserVsd.py @@ -7,7 +7,32 @@ Vtree = ROOT.TTree("VSD", "Custom plain VSD tree") pcv = ROOT.std.vector('VsdCandidate')() -Vtree.Branch("PinkCands", pcv) +candBr = Vtree.Branch("PinkCands", pcv) +candCfg = { + "filter" : "i.pt() > 1", + "color" : ROOT.kViolet, + "purpose" : "Candidate" +} +candBr.SetTitle(json.dumps(candCfg)) + +# resue cand vectir for ECAL +ecalBr = Vtree.Branch("ChargedCands", pcv) +ecalCfg = { + "color" : ROOT.kRed, + "filter" : "i.charge() != 0", + "purpose" : "CaloTower" +} +ecalBr.SetTitle(json.dumps(ecalCfg)) +# resue cand vectir for HCAL +hcalBr = Vtree.Branch("NeutralCands", pcv) +hcalCfg = { + "color" : ROOT.kBlue, + "filter" : "i.charge() > 0", + "purpose" : "CaloTower" +} +hcalBr.SetTitle(json.dumps(hcalCfg)) + + gjv = ROOT.std.vector('VsdJet')() Vtree.Branch("GreenJets", gjv) diff --git a/VsdBase.h b/VsdBase.h index ea57549..ac1031d 100644 --- a/VsdBase.h +++ b/VsdBase.h @@ -155,7 +155,9 @@ class VsdEventInfo : public VsdBase class VsdCollection { public: - VsdCollection(const std::string &n, const std::string &p, Color_t c = kBlue, std::string f = "") : m_name(n), m_purpose(p), m_color(c), m_filter(f) {} + VsdCollection(const std::string &n, const std::string &p, Color_t c = kBlue, std::string f = "") : m_name(n), m_type(p), m_color(c), m_filter(f) { + m_purpose = m_type; + } VsdCollection() {} virtual ~VsdCollection() {} diff --git a/VsdProvider.h b/VsdProvider.h index e686c16..1ef1077 100644 --- a/VsdProvider.h +++ b/VsdProvider.h @@ -82,8 +82,8 @@ class VsdProvider printf(" post get entry 0 %s %u\n", br->GetName(), cp->Size()); - std::string purpose = re[1].Data(); - VsdCollection* vc = new VsdCollection(br->GetName(), purpose.substr(3)); + std::string colType = re[1].Data(); + VsdCollection* vc = new VsdCollection(br->GetName(), colType.substr(3)); addCollection(vc); try { @@ -98,6 +98,9 @@ class VsdProvider if (el.key() == "color") { vc->m_color = el.value(); } + if (el.key() == "purpose") { + vc->m_purpose = el.value(); + } } } catch (nlohmann::json::parse_error &ex) diff --git a/VsdProxies.h b/VsdProxies.h index 53450b0..60a2209 100644 --- a/VsdProxies.h +++ b/VsdProxies.h @@ -1,6 +1,8 @@ #include "VsdBase.h" +#include "lego_bins.h" #include "TROOT.h" +#include "TH2.h" #include "ROOT/REveDataCollection.hxx" #include "ROOT/REveDataSimpleProxyBuilderTemplate.hxx" #include "ROOT/REveManager.hxx" @@ -22,6 +24,9 @@ #include "ROOT/REveTrans.hxx" #include "ROOT/REveGeoShape.hxx" #include "ROOT/REveBox.hxx" +#include "ROOT/REveCalo.hxx" +#include "ROOT/REveCaloData.hxx" +#include "ROOT/REveSelection.hxx" #include "TGeoBBox.h" #include "TGeoTube.h" @@ -286,6 +291,7 @@ class METProxyBuilder : public REveDataSimpleProxyBuilderTemplate REveGeoManagerHolder gmgr(REveGeoShape::GetGeoManager()); REveGeoShape *element = getShape("spread", new TGeoTubeSeg(r0 - 2, r0, 1, min_phi * 180 / M_PI, max_phi * 180 / M_PI), 0); element->SetPickable(kTRUE); + element->SetMainTransparency(90); SetupAddElement(element, iItemHolder); } // float value = met.et(); @@ -585,7 +591,141 @@ class JetProxyBuilder : public REveDataSimpleProxyBuilderTemplate }; //============================================================================== +class REveCaloTowerSliceSelector : public REveCaloDataSliceSelector +{ +private: + REveDataCollection* fCollection{nullptr}; + REveCaloDataHist* fCaloData{nullptr}; + +public: + REveCaloTowerSliceSelector(int s, REveDataCollection* c, REveCaloDataHist* h):REveCaloDataSliceSelector(s), fCollection(c), fCaloData(h) {} + + using REveCaloDataSliceSelector::ProcessSelection; + void ProcessSelection(REveCaloData::vCellId_t& sel_cells, UInt_t selectionId, Bool_t multi) override + { + std::set item_set; + REveCaloData::CellData_t cd; + for (auto &cellId : sel_cells) + { + fCaloData->GetCellData(cellId, cd); + + // loop over enire collection and check its eta/phi range + for (int t = 0; t < fCollection->GetNItems(); ++t) + { + VsdCandidate* tower = (VsdCandidate*) fCollection->GetDataPtr(t); + if (tower->m_eta > cd.fEtaMin && tower->m_eta < cd.fEtaMax && + tower->m_phi > cd.fPhiMin && tower->m_phi < cd.fPhiMax) + { + printf("selected item %d ...\n", t); + item_set.insert(t); + } + } + } + REveSelection* sel = (REveSelection*)ROOT::Experimental::gEve->FindElementById(selectionId); + fCollection->GetItemList()->RefSelectedSet() = item_set; + sel->NewElementPicked(fCollection->GetItemList()->GetElementId(), multi, true, item_set); + } + + using REveCaloDataSliceSelector::GetCellsFromSecondaryIndices; + void GetCellsFromSecondaryIndices(const std::set& idcs, REveCaloData::vCellId_t& out) override + { + TH2F* hist = fCaloData->GetHist(GetSliceIndex()); + std::set cbins; + float total = 0; + for( auto &i : idcs ) { + VsdCandidate* tower = (VsdCandidate*)fCollection->GetDataPtr(i); + int bin = hist->FindBin(tower->m_eta, tower->m_phi); + float frac = tower->m_pt/hist->GetBinContent(bin); + bool ex = false; + for (size_t ci = 0; ci < out.size(); ++ci) + { + if (out[ci].fTower == bin && out[ci].fSlice == GetSliceIndex()) + { + float oldv = out[ci].fFraction; + out[ci].fFraction = oldv + frac; + ex = true; + break; + } + } + if (!ex) { + out.push_back(REveCaloData::CellId_t(bin, GetSliceIndex(), frac)); + } + } + } +}; //============================================================================== +class CaloTowerProxyBuilder: public REveDataProxyBuilderBase +{ +private: + REveCaloDataHist* fCaloData {nullptr}; + TH2F* fHist {nullptr}; + int fSliceIndex {-1}; + + void assertSlice() { + if (!fHist) { + Bool_t status = TH1::AddDirectoryStatus(); + + TH1::AddDirectory(kFALSE); //Keeps histogram from going into memory + fHist = new TH2F("caloHist", "caloHist", fw3dlego::xbins_n - 1, fw3dlego::xbins, 72, -M_PI, M_PI); + TH1::AddDirectory(status); + fSliceIndex = fCaloData->AddHistogram(fHist); + + fCaloData->RefSliceInfo(fSliceIndex) + .Setup(Collection()->GetCName(), + 0., + Collection()->GetMainColor(), + Collection()->GetMainTransparency()); + + fCaloData->GetSelector()->AddSliceSelector(std::unique_ptr + (new REveCaloTowerSliceSelector(fSliceIndex, Collection(), fCaloData))); + } + } +public: + CaloTowerProxyBuilder(REveCaloDataHist* cd) : fCaloData(cd) {} + + using REveDataProxyBuilderBase::Build; + void BuildProduct(const REveDataCollection* collection, REveElement* product, const REveViewContext*)override + { + assertSlice(); + fHist->Reset(); + if (collection->GetRnrSelf()) + { + fCaloData->RefSliceInfo(fSliceIndex) + .Setup(Collection()->GetCName(), + 0., + Collection()->GetMainColor(), + Collection()->GetMainTransparency()); + + + for (int h = 0; h < collection->GetNItems(); ++h) + { + VsdCandidate* tower = (VsdCandidate*)collection->GetDataPtr(h); + const REveDataItem* item = Collection()->GetDataItem(h); + + if (!item->GetVisible()) + continue; + fHist->Fill(tower->m_eta, tower->m_phi, tower->m_pt); + } + } + fCaloData->DataChanged(); + } + + using REveDataProxyBuilderBase::FillImpliedSelected; + void FillImpliedSelected(REveElement::Set_t& impSet, const std::set& sec_idcs, Product*) override + { + fCaloData->GetSelector()->SetActiveSlice(fSliceIndex); + impSet.insert(fCaloData); + fCaloData->FillImpliedSelectedSet(impSet, sec_idcs); + } + + using REveDataProxyBuilderBase::ModelChanges; + void ModelChanges(const REveDataCollection::Ids_t& ids, Product* product) override + { + BuildProduct(Collection(), nullptr, nullptr); + } + +}; // CaloTowerProxyBuilder +//..................................................... //============================================================================== diff --git a/evd.h b/evd.h index 60b7088..c8e7c08 100644 --- a/evd.h +++ b/evd.h @@ -1,6 +1,7 @@ #include "VsdBase.h" #include "VsdProxies.h" #include "VsdProvider.h" +#include "lego_bins.h" #include "ROOT/REveDataCollection.hxx" #include "ROOT/REveDataSimpleProxyBuilderTemplate.hxx" @@ -43,7 +44,7 @@ ROOT::Experimental::REveProjectionManager* mngRhoZ; ROOT::Experimental::REveProjectionManager* mngRPhi; ROOT::Experimental::REveViewContext* viewContext; ROOT::Experimental::REveTrackPropagator* muonPropagator_g; - +ROOT::Experimental::REveCaloDataHist* caloData; //============================================================================== //== Selection ================================================================= //============================================================================== @@ -238,6 +239,8 @@ class CollectionManager return new MuonProxyBuilder(); else if (vsdc->m_purpose == "Vertex") return new VertexProxyBuilder(); + else if (vsdc->m_purpose == "CaloTower") + return new CaloTowerProxyBuilder(caloData); std::cout << typeid(vsdc).name() << '\n'; @@ -254,7 +257,7 @@ class CollectionManager { REveDataCollection *collection = new REveDataCollection(vsdc->m_name); m_collections->AddElement(collection); - std::string class_name = "Vsd" + vsdc->m_purpose; // !!! This works beacuse it is a root macro + std::string class_name = "Vsd" + vsdc->m_type; // !!! This works beacuse it is a root macro std::cout << "addCollection class name " << class_name << "\n"; @@ -400,6 +403,7 @@ class EventManager : public REveElement m_event->GotoEvent(id); UpdateTitle(); m_collectionMng->RenewEvent(); + caloData->DataChanged(); } @@ -567,6 +571,20 @@ void createScenesAndViews() viewContext->SetTableViewInfo(tableInfo); + + auto baseHist = new TH2F("dummy", "dummy", fw3dlego::xbins_n - 1, fw3dlego::xbins, 72, -TMath::Pi(), TMath::Pi()); + caloData = new REveCaloDataHist(); + caloData->AddHistogram(baseHist); + auto selector = new REveCaloDataSelector(); + caloData->SetSelector(selector); + eveMng->GetWorld()->AddElement(caloData); + + auto calo3d = new REveCalo3D(caloData); + calo3d->SetBarrelRadius(r); + calo3d->SetEndCapPos(z); + calo3d->SetMaxTowerH(300); + eveMng->GetEventScene()->AddElement(calo3d); + // Geom ry auto b1 = new REveGeoShape("Barrel 1"); b1->SetShape(new TGeoTube(r -2 , r+2, z)); @@ -586,6 +604,7 @@ void createScenesAndViews() auto pgeoScene = eveMng->SpawnNewScene("Projection Geometry"); mngRPhi->ImportElements(b1,pgeoScene ); rPhiView->AddScene(pgeoScene); + mngRPhi->ImportElements(calo3d, rPhiEventScene); } // Projected RhoZ if (1) @@ -600,6 +619,7 @@ void createScenesAndViews() auto pgeoScene = eveMng->SpawnNewScene("Projection Geometry"); mngRhoZ->ImportElements(b1,pgeoScene ); rhoZView->AddScene(pgeoScene); + mngRhoZ->ImportElements(calo3d, rhoZEventScene); } // collections eveMng->SpawnNewScene("Collections", "Collections"); @@ -612,14 +632,12 @@ void createScenesAndViews() tableScene->AddElement(viewContext->GetTableViewInfo()); } - // ((REveViewer*)(eveMng->GetViewers()->FirstChild()))->SetMandatory(false); + ((REveViewer*)(eveMng->GetViewers()->FirstChild()))->SetMandatory(false); } //////////////////////////////////////////////////// //////////////////////////////////////////////////// void evd(const char* data_path) { - - VsdProvider* prov = new VsdProvider(data_path); eveMng = REveManager::Create(); @@ -662,7 +680,7 @@ void evd(const char* data_path) } eventMng->GotoEvent(0); - ((REveViewer*)(ROOT::Experimental::gEve->GetViewers()->FirstChild()))->SetMandatory(false); + //((REveViewer*)(ROOT::Experimental::gEve->GetViewers()->FirstChild()))->SetMandatory(false); gEnv->SetValue("WebEve.DisableShow", 1); eveMng->Show(); diff --git a/lego_bins.h b/lego_bins.h new file mode 100644 index 0000000..c8166b5 --- /dev/null +++ b/lego_bins.h @@ -0,0 +1,33 @@ +#ifndef FireworksWeb_Core_fw3dlego_xbins_h +#define FireworksWeb_Core_fw3dlego_xbins_h +// -*- C++ -*- +// +// Package: Core +// Class : fw3dlego_xbins +// +/**\class fw3dlego_xbins fw3dlego_xbins.h FireworksWeb/Core/interface/fw3dlego_xbins.h + + Description: + + Usage: + + + */ +// +// Original Author: Chris Jones +// Created: Wed Dec 3 13:55:42 EST 2008 +// + +namespace fw3dlego { + const int xbins_n = 83; + const double xbins[xbins_n] = { + -5.191, -4.889, -4.716, -4.538, -4.363, -4.191, -4.013, -3.839, -3.664, -3.489, -3.314, -3.139, -2.964, -2.853, + -2.650, -2.500, -2.322, -2.172, -2.043, -1.930, -1.830, -1.740, -1.653, -1.566, -1.479, -1.392, -1.305, -1.218, + -1.131, -1.044, -0.957, -0.870, -0.783, -0.696, -0.609, -0.522, -0.435, -0.348, -0.261, -0.174, -0.087, 0.000, + 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, 1.218, + 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650, 2.853, + 2.964, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191}; +} // namespace fw3dlego + + +#endif