Belle II Software development
DisplayModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <display/modules/display/DisplayModule.h>
9
10#include <framework/dataobjects/DisplayData.h>
11#include <display/DisplayUI.h>
12#include <display/EVEVisualization.h>
13#include <display/EveGeometry.h>
14#include <mdst/dataobjects/Track.h>
15#include <mdst/dataobjects/TrackFitResult.h>
16#include <simulation/dataobjects/MCParticleTrajectory.h>
17#include <trg/cdc/dataobjects/CDCTriggerTrack.h>
18#include <trg/cdc/dataobjects/CDCTrigger3DHTrack.h>
19
20#include <framework/datastore/StoreArray.h>
21#include <framework/datastore/StoreObjPtr.h>
22#include <framework/gearbox/Gearbox.h>
23#include <framework/core/Path.h>
24
25#include <tracking/dataobjects/RecoTrack.h>
26#include <tracking/dataobjects/RecoHitInformation.h>
27#include <genfit/GFRaveVertex.h>
28
29#include <TApplication.h>
30#include <TEveManager.h>
31
32using namespace Belle2;
33
34REG_MODULE(Display);
35
37{
38 setDescription("Interactive visualisation of Monte Carlo, intermediate and reconstructed objects, plus geometry. See https://software.belle2.org/|release|/sphinx/display/doc/index.html for detailed documentation.");
39
40 addParam("options", m_options,
41 "Drawing options for RecoTracks, a combination of DHMP. See EVEVisualization::setOptions or the display.py example for an explanation.",
42 std::string("MH"));
43 addParam("showMCInfo", m_showMCInfo, "Show Monte Carlo information (MCParticles, SimHits)", true);
44 addParam("assignHitsToPrimaries", m_assignToPrimaries,
45 "If true, hits created by secondary particles (after scattering, decay-in-flight, ...) will be assigned to the original primary particle.",
46 false);
47 addParam("showAllPrimaries", m_showAllPrimaries,
48 "If true, all primary MCParticles will be shown, regardless of whether hits are produced.", true);
49 addParam("hideSecondaries", m_hideSecondaries, "If true, secondary MCParticles (and hits created by them) will not be shown.",
50 false);
51 addParam("showCharged", m_showCharged,
52 "If true, all charged MCParticles will be shown, including secondaries (implies disabled assignHitsToPrimaries). May be slow.",
53 true);
54 addParam("showNeutrals", m_showNeutrals,
55 "If true, all neutral MCParticles will be shown, including secondaries (implies disabled assignHitsToPrimaries). May be slow.",
56 true);
57 addParam("showTrackLevelObjects", m_showTrackLevelObjects,
58 "If true, fitted Tracks, GFRave Vertices and ECLCluster objects will be shown in the display.", true);
59 addParam("showRecoTracks", m_showRecoTracks,
60 "If true, track candidates (RecoTracks) and reconstructed hits will be shown in the display.", false);
61 addParam("showCDCHits", m_showCDCHits,
62 "If true, CDCHit objects will be shown as drift cylinders (shortened, z position set to zero).", false);
63 addParam("showTriggerObjects", m_showTriggerObjects,
64 "If true, CDCHit objects will be assigned to trigger segments and trigger tracks will be shown.", false);
65 addParam("showKLM2dHits", m_showKLM2dHits,
66 "If true, KLMHit2d objects will be shown in the display.", true);
67 addParam("showARICHHits", m_showARICHHits,
68 "If true, ARICHHit objects will be shown.", false);
69 addParam("automatic", m_automatic,
70 "Non-interactively save visualisations for each event. Note that this still requires an X server, but you can use the 'Xvfb' dummy server by running basf2 using 'xvfb-run -s \"-screen 0 640x480x24\" basf2 ...' to run headless.",
71 false);
72 addParam("fullGeometry", m_fullGeometry,
73 "Show full geometry instead of simplified shapes. Further details can be enabled by changing the VisLevel option for Eve -> Scenes -> Geometry Scene -> Top_1.",
74 false);
75 addParam("hideObjects", m_hideObjects,
76 "Objects which are to be hidden (can be manually re-enabled in tree view). Names correspond to the object names in the 'Event'. (Note that this won't work for objects somewhere deep in the tree, only for those immediately below 'Event'.)", {});
77 addParam("customGeometryExtractPath", m_customGeometryExtractPath, "Path to custom file with geometry extract.", std::string(""));
78 addParam("hideVolumes", m_hideVolumes,
79 "List of volumes to be hidden (can be re-enabled in Eve panel / Geometry scene. The volume and all its daughters will be hidden.", {});
80 addParam("deleteVolumes", m_deleteVolumes,
81 "List of volumes to be deleted. The volume and all its daughters will be deleted completely. Uses Regular Expressions (RE)! If the expression starts with '#', only daughters are removed (# is removed for RE)", {});
82 addParam("playOnStartup", m_playOnStartup,
83 "When launching the event display, immediately start advancing through events. Useful for control room uses etc.", false);
84
85
86 //create gApplication so we can use graphics support. Needs to be done before ROOT has a chance to do it for us.
87 if ((!gApplication) || (gApplication->TestBit(TApplication::kDefaultApplication))) {
88 new TApplication("ROOT_application", 0, 0);
89 }
90}
91
92
94{
95 //optional inputs
96 StoreArray<MCParticle> MCParticles; MCParticles.isOptional();
97 StoreArray<MCParticleTrajectory> MCParticleTrajectorys; MCParticleTrajectorys.isOptional();
98 StoreArray<CDCSimHit> CDCSimHits; CDCSimHits.isOptional();
99 StoreArray<PXDSimHit> PXDSimHits; PXDSimHits.isOptional();
100 StoreArray<SVDSimHit> SVDSimHits; SVDSimHits.isOptional();
101 StoreArray<KLMSimHit> KLMSimHits; KLMSimHits.isOptional();
102 StoreArray<ECLCluster> ECLClusters; ECLClusters.isOptional();
103 StoreArray<KLMCluster> KLMClusters; KLMClusters.isOptional();
104 StoreArray<KLMHit2d> KLMHit2ds; KLMHit2ds.isOptional();
105 StoreArray<Track> Tracks; Tracks.isOptional();
106 StoreArray<TrackFitResult> TrackFitResults; TrackFitResults.isOptional();
107 StoreArray<RecoTrack> RecoTracks; RecoTracks.isOptional();
108 StoreArray<genfit::GFRaveVertex> GFRaveVertexs; GFRaveVertexs.isOptional();
109 StoreObjPtr<DisplayData> DisplayDatas; DisplayDatas.isOptional();
110 StoreArray<PXDCluster> PXDClusters; PXDClusters.isOptional();
111 StoreArray<SVDCluster> SVDClusters; SVDClusters.isOptional();
112 StoreArray<CDCHit> CDCHits; CDCHits.isOptional();
113 StoreArray<CDCTriggerSegmentHit> CDCTriggerSegmentHits; CDCTriggerSegmentHits.isOptional();
114 StoreArray<ARICHHit> ARICHHits; ARICHHits.isOptional();
115 StoreArray<TOPDigit> TOPDigits; TOPDigits.isOptional();
116 StoreArray<ROIid> ROIids; ROIids.isOptional();
120
122 if (hasCondition())
123 m_display->allowFlaggingEvents(getCondition()->getPath()->getPathString());
124 m_display->addParameter("Show MC info", getParam<bool>("showMCInfo"), 0);
125 {
126 //MC-specific parameters
127 m_display->addParameter("Assign hits to primary particles", getParam<bool>("assignHitsToPrimaries"), 1);
128 m_display->addParameter("Show all primaries", getParam<bool>("showAllPrimaries"), 1);
129 m_display->addParameter("Show all charged particles", getParam<bool>("showCharged"), 1);
130 m_display->addParameter("Show all neutral particles", getParam<bool>("showNeutrals"), 1);
131 m_display->addParameter("Hide secondaries", getParam<bool>("hideSecondaries"), 1);
132 }
133 m_display->addParameter("Show candidates and rec. hits", getParam<bool>("showRecoTracks"), 0);
134 m_display->addParameter("Show tracks, vertices, gammas", getParam<bool>("showTrackLevelObjects"), 0);
135
136 if (!m_fullGeometry and Gearbox::getInstance().exists("Detector/Name")) {
137 std::string detectorName = Gearbox::getInstance().getString("Detector/Name");
138 if (detectorName != "Belle2Detector") {
139 B2INFO("Non-standard detector '" << detectorName << "' used, switching to full geometry.");
140 m_fullGeometry = true;
141 }
142 }
143 if (m_fullGeometry) {
144 //pass some parameters to DisplayUI to be able to change them at run time
145 m_display->addParameter("Show full geometry", getParam<bool>("fullGeometry"), 0);
146 }
147
149
152
155 m_visualizer->setOptions(m_options);
156 m_display->hideObjects(m_hideObjects);
157}
158
159
160
162{
163 setReturnValue(false);
164 if (!gEve) {
165 //window closed?
166 B2WARNING("Display window closed, continuing with next module. (hit Ctrl+C to exit)");
167 return;
168 }
169
171
172 //secondaries cannot be shown if they are merged into primaries
173 m_visualizer->setAssignToPrimaries(m_assignToPrimaries && !m_showNeutrals && !m_showCharged);
175 B2WARNING("assignHitsToPrimaries and showCharged/showNeutrals can not be used together!");
176 }
177
178 m_visualizer->setHideSecondaries(m_hideSecondaries);
179
180 if (m_showMCInfo) {
181 //gather MC particles
182 StoreArray<MCParticle> mcparticles;
184 for (const MCParticle& part : mcparticles) {
185 if ((m_showAllPrimaries and part.hasStatus(MCParticle::c_PrimaryParticle))
186 or (m_showCharged and TMath::Nint(part.getCharge()) != 0)
187 or (m_showNeutrals and TMath::Nint(part.getCharge()) == 0)) {
188 m_visualizer->addMCParticle(&part);
189 }
190 }
191 }
192
193 //gather simhits
194 m_visualizer->addSimHits(StoreArray<CDCSimHit>());
195 m_visualizer->addSimHits(StoreArray<PXDSimHit>());
196 m_visualizer->addSimHits(StoreArray<SVDSimHit>());
197 m_visualizer->addSimHits(StoreArray<KLMSimHit>());
198 }
199
200
201 if (m_showRecoTracks) {
202 //add all possible track candidate arrays
203 const auto recoTrackArrays = StoreArray<RecoTrack>::getArrayList();
204 for (const std::string& colName : recoTrackArrays) {
205 StoreArray<RecoTrack> recoTracks(colName);
206 for (const RecoTrack& recoTrack : recoTracks) {
207 if (colName != "RecoTracksMpl") {
208 m_visualizer->addTrackCandidate(colName, recoTrack);
209 } else {
210 m_visualizer->addTrackCandidateImproved(colName, recoTrack);
211 }
212 }
213 }
214
218
219 //add remaining recohits
220 m_visualizer->addUnassignedRecoHits(pxdStoreArray);
221 m_visualizer->addUnassignedRecoHits(svdStoreArray);
222 m_visualizer->addUnassignedRecoHits(cdcStoreArray);
223
225 for (int i = 0 ; i < ROIs.getEntries(); i++)
226 m_visualizer->addROI(ROIs[i]);
227 //well, non-standard names are used for testbeams?
228 StoreArray<ROIid> testbeamROIs("ROIs");
229 for (int i = 0 ; i < testbeamROIs.getEntries(); i++)
230 m_visualizer->addROI(testbeamROIs[i]);
231 }
232
234 StoreArray<CDCHit> cdchits;
235 for (const auto& hit : cdchits)
236 m_visualizer->addCDCHit(&hit, m_showTriggerObjects);
237 }
238
240 // Add Track Segment hits
241 const auto arrayList = StoreArray<CDCTriggerSegmentHit>::getArrayList();
242 for (const auto& i : arrayList) {
244 for (const auto& hit : tshits)
245 m_visualizer->addCDCTriggerSegmentHit(i, &hit);
246 }
247
248 // Add 2DNeuro and 2DHough tracks
249 const auto trgTrackArrays = StoreArray<CDCTriggerTrack>::getArrayList();
250 for (const std::string& colName : trgTrackArrays) {
251 StoreArray<CDCTriggerTrack> trgTracks(colName);
252 for (const CDCTriggerTrack& trgTrack : trgTracks) {
253 // Show all 2DHough tracks (tracks are by construction only in the x-y plane)
254 bool is2DHoughTrack = (trgTrack.getZ0() == 0 && trgTrack.getCotTheta() == 0);
255 // Show only 2DNeuro tracks (Neuro Tracks with 2DHough input) if they are:
256 // valid with regards to the stereo bit, i.e., have at least 3 out of 4 stereo TS hits
257 // not an old track from a previous clock cycle (relevant for raw data readout)
258 std::vector<bool> oldTracks = trgTrack.getFoundOldTrack();
259 bool isValid2DNeuroTrack = (trgTrack.getValidStereoBit() && !oldTracks[0]);
260 if (is2DHoughTrack || isValid2DNeuroTrack) {
261 m_visualizer->addCDCTriggerTrack(colName, trgTrack);
262 }
263 }
264 }
265
266 // Add 3DNeuro and 3DHough tracks
267 const auto trg3DHTrackArrays = StoreArray<CDCTrigger3DHTrack>::getArrayList();
268 for (std::string colName : trg3DHTrackArrays) {
269 StoreArray<CDCTrigger3DHTrack> trg3DHTracks(colName);
270 for (const CDCTrigger3DHTrack& trg3DHTrack : trg3DHTracks) {
271 m_visualizer->addCDCTriggerTrack(colName, trg3DHTrack);
272 }
273 }
274 }
275
276 if (m_showKLM2dHits) {
277 StoreArray<KLMHit2d> klmHits;
278 for (const auto& hit : klmHits) {
279 if (hit.getSubdetector() == KLMElementNumbers::c_BKLM)
280 m_visualizer->addBKLMHit2d(&hit);
281 else
282 m_visualizer->addEKLMHit2d(&hit);
283 }
284 }
285
286 if (m_showARICHHits) {
287 StoreArray<ARICHHit> arichhits;
288 for (const auto& hit : arichhits)
289 m_visualizer->addARICHHit(&hit);
290 }
291
293 //gather track-level objects
294 StoreArray<Track> tracks;
295 for (const Track& track : tracks)
296 m_visualizer->addTrack(&track);
297
299 const int nVertices = vertices.getEntries();
300 for (int i = 0; i < nVertices; i++) {
301 m_visualizer->addVertex(vertices[i]);
302 }
303
304 StoreArray<ECLCluster> clusters;
305 for (const ECLCluster& cluster : clusters) {
306 if (cluster.hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)) {
307 if (m_showMCInfo) {
308 //make sure we add particles producing these
309 const MCParticle* mcpart = cluster.getRelated<MCParticle>();
310 if (mcpart)
311 m_visualizer->addMCParticle(mcpart);
312 }
313
314 m_visualizer->addECLCluster(&cluster);
315 }
316 }
317
318 StoreArray<KLMCluster> klmclusters;
319 for (const KLMCluster& cluster : klmclusters) {
320 if (m_showMCInfo) {
321 //make sure we add particles producing these
322 const MCParticle* mcpart = cluster.getRelated<MCParticle>();
323 if (mcpart)
324 m_visualizer->addMCParticle(mcpart);
325 }
326
327 m_visualizer->addKLMCluster(&cluster);
328 }
329
330 m_visualizer->addTOPDigits(StoreArray<TOPDigit>());
331 }
332
333 //all hits/tracks are added, finish visual representations
334 m_visualizer->makeTracks();
335
336 StoreObjPtr<DisplayData> displayData;
337 if (displayData) {
338 m_visualizer->showUserData(*displayData);
339 m_display->showUserData(*displayData);
340 }
341
342
343 bool reshow = m_display->startDisplay();
344 setReturnValue(m_display->getReturnValue());
345 if (!m_display->cumulativeIsOn()) {
346 m_visualizer->clearEvent(); //clean up internal state of visualiser
347 }
348 m_display->clearEvent(); //clean up event scene, incl. projections
349
350 //reprocess current event (maybe some options changed)
351 if (reshow)
352 event();
353}
354
355
357{
358 if (gEve) {
359 gEve->Terminate();
360 }
361
362 delete m_visualizer;
363 delete m_display;
364}
Track created by the CDC trigger.
bool m_showCDCHits
If true, CDCHit objects will be shown as drift cylinders (shortened, z position set to zero).
bool m_showTriggerObjects
If true, CDCHit objects will be assigned to trigger segments and trigger tracks will be shown.
bool m_showTrackLevelObjects
If true, fitted RecoTracks, GFRave Vertices and ECLGamma objects will be shown in the display.
DisplayModule()
Constructor. Sets all the module parameters.
bool m_showRecoTracks
Whether to show RecoTracks.
bool m_showKLM2dHits
If true, KLMHit2d objects will be shown in the display.
void initialize() override
Sets up geometry if needed.
bool m_automatic
Non-interactively save visualizations for each event.
void event() override
Show various reconstructed or simulated objects in the event viewer until the next event is requested...
std::vector< std::string > m_deleteVolumes
List of volumes to be deleted.
void terminate() override
Terminate gEve to avoid problems with root's cleanup.
bool m_showAllPrimaries
If true, all primary MCParticles will be shown, regardless of whether hits are produced.
bool m_showNeutrals
If true, all neutral primary and secondary MCParticles will be shown, regardless of whether hits are ...
bool m_showCharged
If true, all charged primary and secondary MCParticles will be shown, regardless of whether hits are ...
EVEVisualization * m_visualizer
Pointer to visualizer.
bool m_showMCInfo
Show Monte Carlo information (MCParticles, SimHits).
bool m_fullGeometry
Show full geometry instead of simplified shapes.
bool m_showARICHHits
If true, ARICHHit objects will be shown as squares, corresponding to channel pixels.
std::string m_options
List of drawing options, see EVEVisualization::setOptions()
DisplayUI * m_display
pointer to actual display
bool m_hideSecondaries
If true, secondary MCParticles (and hits created by them) will not be shown.
bool m_playOnStartup
Start the module advancing through events.
std::vector< std::string > m_hideVolumes
List of volumes to be hidden (can be re-enabled in Eve panel / Geometry scene.
bool m_assignToPrimaries
If true, hits created by secondary particles (e.g.
std::string m_customGeometryExtractPath
Path to custom file with geometry extract.
std::vector< std::string > m_hideObjects
objects which are to be hidden (can be manually re-enabled in tree view).
Control TEve browser user interface.
Definition DisplayUI.h:41
ECL cluster data.
Definition ECLCluster.h:27
@ c_nPhotons
CR is split into n photons (N1)
Definition ECLCluster.h:41
Produces visualisation for MCParticles, simhits, genfit::Tracks, geometry and other things.
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition Gearbox.h:123
KLM cluster data.
Definition KLMCluster.h:29
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition MCParticle.h:47
const ModuleCondition * getCondition() const
Return a pointer to the first condition (or nullptr, if none was set)
Definition Module.h:313
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
void setReturnValue(int value)
Sets the return value for this module as integer.
Definition Module.cc:220
bool hasCondition() const
Returns true if at least one condition was set for the module.
Definition Module.h:310
std::string getPathString() const override
return the module name.
Definition Module.cc:192
This is the Reconstruction Event-Data Model Track.
Definition RecoTrack.h:79
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
static std::vector< std::string > getArrayList(DataStore::EDurability durability=DataStore::c_Event)
Return list of array names with matching type.
Definition StoreArray.h:275
int getEntries() const
Get the number of objects in the array.
Definition StoreArray.h:216
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
Class that bundles various TrackFitResults.
Definition Track.h:25
static Gearbox & getInstance()
Return reference to the Gearbox instance.
Definition Gearbox.cc:81
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
ModuleParam< T > & getParam(const std::string &name) const
Returns a reference to a parameter.
Definition Module.h:572
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
void addGeometry(EType visMode)
Add TGeo geometry to Eve (only needs to be done once.)
void setDeleteVolumes(const std::vector< std::string > &volumes)
List of volumes to be removed.
void setVisualisationMode(EType visMode)
switch to given visualisation mode.
void setCustomExtractPath(const std::string &extractPath)
Set custom path to the geometry extract (to change originally hard-coded value)
void setHideVolumes(const std::vector< std::string > &volumes)
List of volumes to be hidden (can be re-enabled in Eve panel / Geometry scene.
@ c_Full
Full geometry converted from Geant4 (use this for non-standard Belle II setups!).
Definition EveGeometry.h:26
@ c_Simplified
a simplified Belle II geometry.
Definition EveGeometry.h:27
Abstract base class for different kinds of events.