From 215664b64f60141fc2f837d04ba4fb400366b800 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Mon, 7 Jul 2014 18:28:00 +0000 Subject: [PATCH] Add MultiView pane --- DDEve/CMakeLists.txt | 8 +- DDEve/include/DDEve/Calo3DProjection.h | 4 - DDEve/include/DDEve/DDG4EventHandler.h | 6 +- DDEve/include/DDEve/Dictionary.h | 6 +- DDEve/include/DDEve/Display.h | 44 ++--- DDEve/include/DDEve/DisplayConfiguration.h | 7 +- DDEve/include/DDEve/EventControl.h | 2 +- DDEve/include/DDEve/EventHandler.h | 25 +-- DDEve/include/DDEve/GenericEventHandler.h | 73 +++++++ DDEve/include/DDEve/MultiView.h | 43 +++++ DDEve/include/DDEve/Projection.h | 7 + DDEve/include/DDEve/View.h | 55 +++--- DDEve/include/DDEve/ViewConfiguration.h | 62 ------ DDEve/include/DDEve/ViewMenu.h | 13 +- DDEve/lcio/LCIOEventHandler.cpp | 153 +++++++++++++++ DDEve/lcio/LCIOEventHandler.h | 73 +++++++ DDEve/src/Calo2DProjection.cpp | 3 +- DDEve/src/Calo3DProjection.cpp | 28 +-- DDEve/src/DD4hepMenu.cpp | 2 +- DDEve/src/DDG4EventHandler.cpp | 130 +++++-------- DDEve/src/Display.cpp | 124 +++--------- DDEve/src/DisplayConfiguration.cpp | 2 +- DDEve/src/DisplayConfigurationParser.cpp | 13 +- DDEve/src/EventControl.cpp | 12 +- DDEve/src/EventHandler.cpp | 23 --- DDEve/src/GenericEventHandler.cpp | 161 ++++++++++++++++ DDEve/src/MultiView.cpp | 92 +++++++++ DDEve/src/Projection.cpp | 33 ++-- DDEve/src/View.cpp | 214 +++++++++++++-------- DDEve/src/ViewConfiguration.cpp | 56 ------ DDEve/src/ViewMenu.cpp | 54 ++---- 31 files changed, 955 insertions(+), 573 deletions(-) create mode 100644 DDEve/include/DDEve/GenericEventHandler.h create mode 100644 DDEve/include/DDEve/MultiView.h delete mode 100644 DDEve/include/DDEve/ViewConfiguration.h create mode 100644 DDEve/lcio/LCIOEventHandler.cpp create mode 100644 DDEve/lcio/LCIOEventHandler.h create mode 100644 DDEve/src/GenericEventHandler.cpp create mode 100644 DDEve/src/MultiView.cpp delete mode 100644 DDEve/src/ViewConfiguration.cpp diff --git a/DDEve/CMakeLists.txt b/DDEve/CMakeLists.txt index a9c13a32a..7419daf1f 100644 --- a/DDEve/CMakeLists.txt +++ b/DDEve/CMakeLists.txt @@ -20,11 +20,17 @@ include_directories(${CMAKE_SOURCE_DIR}/DDCore/include #---DD4hepEve library -------------------------------------------------------------- file(GLOB headers include/DDEve/*.h) file(GLOB sources src/*.cpp) +if(DD4HEP_USE_LCIO) + find_package(LCIO REQUIRED) + include_directories( ${LCIO_INCLUDE_DIRS} ) + list(APPEND sources lcio/LCIOEventHandler.cpp) +endif() + root_generate_dictionary( G__DDEve ${headers} LINKDEF ${CMAKE_SOURCE_DIR}/DDCore/include/ROOT/LinkDef.h) list(APPEND sources G__DDEve.cxx) add_library(DD4hepEve SHARED ${sources}) -target_link_libraries(DD4hepEve DD4hepCore ${ROOT_EVE_LIBRARIES} -lFTGL) +target_link_libraries(DD4hepEve DD4hepCore ${ROOT_EVE_LIBRARIES} -lFTGL ${LCIO_LIBRARIES} ) SET( CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-long-long") SET_TARGET_PROPERTIES( DD4hepEve PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) diff --git a/DDEve/include/DDEve/Calo3DProjection.h b/DDEve/include/DDEve/Calo3DProjection.h index 22f9018e3..9b1002513 100644 --- a/DDEve/include/DDEve/Calo3DProjection.h +++ b/DDEve/include/DDEve/Calo3DProjection.h @@ -36,10 +36,6 @@ namespace DD4hep { virtual ~Calo3DProjection(); /// Build the projection view and map it to the given slot virtual View& Build(TEveWindow* slot); - /// Configure a single geometry view - virtual void ConfigureGeometry(const DisplayConfiguration::ViewConfig& config); - /// Configure a single event scene view - virtual void ConfigureEvent(const DisplayConfiguration::ViewConfig& config); /// Root implementation macro ClassDef(Calo3DProjection,0); diff --git a/DDEve/include/DDEve/DDG4EventHandler.h b/DDEve/include/DDEve/DDG4EventHandler.h index 6d50541dc..2160adffb 100644 --- a/DDEve/include/DDEve/DDG4EventHandler.h +++ b/DDEve/include/DDEve/DDG4EventHandler.h @@ -44,12 +44,16 @@ namespace DD4hep { Long64_t m_entry; /// HitAccessor_t m_simhitConverter; + /// Data collection map + TypedEventCollections m_data; public: /// Standard constructor DDG4EventHandler(); /// Default destructor virtual ~DDG4EventHandler(); + /// Access the map of simulation data collections + virtual const TypedEventCollections& data() const { return m_data; } /// Access the number of events on the current input data source (-1 if no data source connected) virtual long numEvents() const; /// Access the data source name @@ -57,7 +61,7 @@ namespace DD4hep { /// Call functor on hit collection virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor); /// Open new data file - virtual bool Open(const std::string& file_name); + virtual bool Open(const std::string& type, const std::string& file_name); /// User overloadable function: Load the next event virtual bool NextEvent(); /// User overloadable function: Load the previous event diff --git a/DDEve/include/DDEve/Dictionary.h b/DDEve/include/DDEve/Dictionary.h index 27efbf94a..ecf8404a2 100644 --- a/DDEve/include/DDEve/Dictionary.h +++ b/DDEve/include/DDEve/Dictionary.h @@ -19,6 +19,7 @@ #include "DDEve/EmbeddedView.h" #include "DDEve/EventHandler.h" #include "DDEve/View3D.h" +#include "DDEve/MultiView.h" #include "DDEve/RhoPhiProjection.h" #include "DDEve/RhoZProjection.h" #include "DDEve/CaloLego.h" @@ -29,7 +30,6 @@ #include "DDEve/Annotation.h" #include "DDEve/DD4hepMenu.h" #include "DDEve/ElementList.h" -#include "DDEve/ViewConfiguration.h" #include "DDEve/EveShapeContextMenu.h" #include "DDEve/EvePgonSetProjectedContextMenu.h" //#include "DDEve/.h" @@ -37,6 +37,7 @@ #include "DDEve/DisplayConfiguration.h" +#include "DDEve/GenericEventHandler.h" #include "DDEve/DDG4EventHandler.h" namespace DD4hep { @@ -58,6 +59,7 @@ namespace DD4hep { #pragma link C++ class DD4hep::BasicView; #pragma link C++ class DD4hep::SplitView; #pragma link C++ class DD4hep::Annotation; +#pragma link C++ class DD4hep::MultiView; #pragma link C++ class DD4hep::ProjectionView; #pragma link C++ class DD4hep::ElementList; #pragma link C++ class DD4hep::PopupMenu; @@ -65,6 +67,7 @@ namespace DD4hep { #pragma link C++ class DD4hep::EventHandler; #pragma link C++ class DD4hep::EventConsumer; #pragma link C++ class DD4hep::DDG4EventHandler; +#pragma link C++ class DD4hep::GenericEventHandler; #pragma link C++ class DD4hep::EventControl; #pragma link C++ class DD4hep::EmbeddedView; @@ -77,7 +80,6 @@ namespace DD4hep { #pragma link C++ class DD4hep::View; #pragma link C++ class DD4hep::ViewMenu; -#pragma link C++ class DD4hep::ViewConfiguration; #pragma link C++ class DD4hep::View3D; #pragma link C++ class DD4hep::Projection; #pragma link C++ class DD4hep::RhoZProjection; diff --git a/DDEve/include/DDEve/Display.h b/DDEve/include/DDEve/Display.h index aed3a71b0..609779b44 100644 --- a/DDEve/include/DDEve/Display.h +++ b/DDEve/include/DDEve/Display.h @@ -44,7 +44,7 @@ namespace DD4hep { class DD4hepMenu; class ViewConfiguration; class CalodataConfiguration; - class EventHandler; + class GenericEventHandler; class DisplayConfiguration; /** @class Display Display.h DDEve/Display.h @@ -54,13 +54,14 @@ namespace DD4hep { */ class Display : public EventConsumer { public: - typedef DisplayConfiguration::Config CalodataConfiguration; + typedef DisplayConfiguration::ViewConfig ViewConfig; + typedef DisplayConfiguration::Config CalodataConfig; typedef std::set<View*> Views; typedef std::set<DisplayConfiguration*> Configurations; typedef std::set<PopupMenu*> Menus; - typedef std::map<std::string, TEveElementList*> Topics; - typedef std::map<std::string, ViewConfiguration*> ViewConfigurations; - typedef std::map<std::string, CalodataConfiguration> CalodataConfigurations; + typedef std::map<std::string, TEveElementList*> Topics; + typedef std::map<std::string, ViewConfig> ViewConfigurations; + typedef std::map<std::string, CalodataConfig> CalodataConfigurations; struct CalodataContext { int slice; @@ -80,7 +81,7 @@ namespace DD4hep { /// Reference to geometry hub Geometry::LCDD* m_lcdd; /// Reference to the event reader object - EventHandler* m_evtHandler; + GenericEventHandler* m_evtHandler; TEveElementList* m_geoGlobal; TEveElementList* m_eveGlobal; ViewMenu* m_viewMenu; @@ -106,13 +107,13 @@ namespace DD4hep { /// Access to geometry hub Geometry::LCDD& lcdd() const; /// Access to the EVE manager - TEveManager& manager() const { return *m_eve; } + TEveManager& manager() const { return *m_eve; } /// Access View configurations - const ViewConfigurations& viewConfigurations() const { return m_viewConfigs; } + const ViewConfigurations& viewConfigurations() const { return m_viewConfigs; } /// Set Vis level in geo manager (either from XML or BEFORE XML file was loaded) - void setVisLevel(int new_level) { m_visLevel = new_level; } + void setVisLevel(int new_level) { m_visLevel = new_level; } /// Set Eve Geometry load level in manager (either from XML or BEFORE XML file was loaded) - void setLoadLevel(int new_level) { m_loadLevel = new_level; } + void setLoadLevel(int new_level) { m_loadLevel = new_level; } /// Access to X-client TGClient& client() const; @@ -126,7 +127,7 @@ namespace DD4hep { TFile* Open(const char* rootFile) const; /// Access to the event reader - EventHandler& eventHandler() const; + GenericEventHandler& eventHandler() const; /// Open standard message box void MessageBox(PrintLevel level, const std::string& text, const std::string& title="") const; @@ -135,7 +136,7 @@ namespace DD4hep { std::string OpenXmlFileDialog(const std::string& default_dir) const; /// Popup ROOT file chooser. returns chosen file name; empty on cancel - std::string OpenRootFileDialog(const std::string& default_dir) const; + std::string OpenEventFileDialog(const std::string& default_dir) const; /// Load 'levels' Children into the geometry scene void LoadGeoChildren(TEveElement* start, int levels, bool redraw); @@ -145,22 +146,13 @@ namespace DD4hep { /// Import configuration parameters void ImportConfiguration(const DisplayConfiguration& config); - /// Register a data filter by name - void RegisterViewConfiguration(ViewConfiguration* filter); /// Access a data filter by name. Data filters are used to customize views - ViewConfiguration* GetViewConfiguration(const std::string& name) const; + const ViewConfig* GetViewConfiguration(const std::string& name) const; /// Access a data filter by name. Data filters are used to customize views - const CalodataConfiguration* GetCalodataConfiguration(const std::string& name) const; + const CalodataConfig* GetCalodataConfiguration(const std::string& name) const; /// Access to calo data histograms by name as defined in the configuration CalodataContext& GetCaloHistogram(const std::string& name); - /// Configure a view using the view's name and a proper ViewConfiguration if present - virtual void ConfigureGeometry(View* view); - - /// Prepare the view for adding event data - virtual void PrepareEvent(View* view) const; - /// Configure the adding of event data - virtual void ConfigureEvent(View* view) const; /// Register to the main event scene on new events virtual void RegisterEvents(View* view); /// Unregister from the main event scene @@ -170,7 +162,7 @@ namespace DD4hep { TEveElementList& GetGeo(); /// Access/Create an geometry topic by name virtual TEveElementList& GetGeoTopic(const std::string& name); - /// Access/Create an geometry topic by name + /// Access/Create an geometry topic by name. Throws exception if the topic does not exist virtual TEveElementList& GetGeoTopic(const std::string& name) const; /// Call to import geometry elements @@ -178,11 +170,9 @@ namespace DD4hep { /// Call to import geometry elements by topic void ImportGeo(const std::string& topic, TEveElement* el); - /// Access/Create an event topic by name - virtual TEveElementList& GetEve(); /// Access/Create an event topic by name virtual TEveElementList& GetEveTopic(const std::string& name); - /// Access/Create an event topic by name + /// Access/Create an event topic by name. Throws exception if the topic does not exist virtual TEveElementList& GetEveTopic(const std::string& name) const; /// Call to import top level event elements diff --git a/DDEve/include/DDEve/DisplayConfiguration.h b/DDEve/include/DDEve/DisplayConfiguration.h index 8e63e4c00..2d3a7ab88 100644 --- a/DDEve/include/DDEve/DisplayConfiguration.h +++ b/DDEve/include/DDEve/DisplayConfiguration.h @@ -36,10 +36,10 @@ namespace DD4hep { protected: Display* m_display; public: - enum { CALODATA=1<<1, DETELEMENT=1<<2, VIEW=1<<3 }; + enum { CALODATA=1<<1, DETELEMENT=1<<2, VIEW=1<<3, PANEL=1<<4 }; struct Defaults { char load_geo; - char load_eve; + char show_evt; short color; float alpha; }; @@ -54,6 +54,8 @@ namespace DD4hep { short n_phi; int spare; }; + struct Panel : public Defaults { + }; class Config { public: union Values { @@ -61,6 +63,7 @@ namespace DD4hep { Defaults defaults; Calo3D calo3d; Calodata calodata; + Panel pane; } data; std::string name; std::string hits; diff --git a/DDEve/include/DDEve/EventControl.h b/DDEve/include/DDEve/EventControl.h index b296e2313..d7eb07770 100644 --- a/DDEve/include/DDEve/EventControl.h +++ b/DDEve/include/DDEve/EventControl.h @@ -11,7 +11,7 @@ // Framework include files #include "DDEve/FrameControl.h" -#include "DDEve/EventHandler.h" +#include "DDEve/GenericEventHandler.h" class TGPictureButton; class TGLabel; diff --git a/DDEve/include/DDEve/EventHandler.h b/DDEve/include/DDEve/EventHandler.h index 5ca60736b..04ce04ed2 100644 --- a/DDEve/include/DDEve/EventHandler.h +++ b/DDEve/include/DDEve/EventHandler.h @@ -49,14 +49,8 @@ namespace DD4hep { typedef std::pair<const char*,size_t> Collection; /// Types collection: collections are grouped by type (class name) typedef std::map<std::string,std::vector<Collection> > TypedEventCollections; - /// Subscriber set - typedef std::set<EventConsumer*> Subscriptions; protected: - /// Data collection map - TypedEventCollections m_data; - /// Data subscriptions (unordered) - Subscriptions m_subscriptions; /// Flag to indicate that a file is opened bool m_hasFile; /// Flag to indicate that an event is loaded @@ -66,22 +60,20 @@ namespace DD4hep { EventHandler(); /// Default destructor virtual ~EventHandler(); - /// Access the map of simulation data collections - virtual const TypedEventCollections& data() const { return m_data; } /// Check if an event is present in memory virtual bool hasEvent() const { return m_hasEvent; } /// Check if a data file is connected to the handler virtual bool hasFile() const { return m_hasFile; } + /// Access the map of simulation data collections + virtual const TypedEventCollections& data() const = 0; /// Access the number of events on the current input data source (-1 if no data source connected) virtual long numEvents() const = 0; /// Access the data source name virtual std::string datasourceName() const = 0; /// Loop over collection and extract data virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor) = 0; - /// Clear all event related data caches - virtual void ClearCache(); /// Open a new event data file - virtual bool Open(const std::string& file_name) = 0; + virtual bool Open(const std::string& type, const std::string& file_name) = 0; /// Load the next event virtual bool NextEvent() = 0; /// User overloadable function: Load the previous event @@ -89,16 +81,7 @@ namespace DD4hep { /// Goto a specified event in the file virtual bool GotoEvent(long event_number) = 0; - /// Subscribe to notification of new data present - virtual void Subscribe(EventConsumer* display); - /// Unsubscribe from notification of new data present - virtual void Unsubscribe(EventConsumer* display); - -#ifndef __CINT__ - /// Notfy all subscribers - virtual void NotifySubscribers(void (EventConsumer::*pmf)(EventHandler*)); -#endif - ClassDef(EventHandler,0); + ClassDef(EventHandler,0); }; /** @class EventConsumer EventHandler.h DDEve/EventHandler.h diff --git a/DDEve/include/DDEve/GenericEventHandler.h b/DDEve/include/DDEve/GenericEventHandler.h new file mode 100644 index 000000000..1e54de8eb --- /dev/null +++ b/DDEve/include/DDEve/GenericEventHandler.h @@ -0,0 +1,73 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_DDEVE_GENERICEVENTHANDLER_H +#define DD4HEP_DDEVE_GENERICEVENTHANDLER_H + +// Framework include files +#include "DDEve/EventHandler.h" + +// Forward declarations + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /// Event handler base class. Interface to all DDEve I/O actions + /** + * @author M.Frank + * @version 1.0 + */ + class GenericEventHandler : public EventHandler { + protected: + /// Subscriber set + typedef std::set<EventConsumer*> Subscriptions; + std::map<std::string,EventHandler*> m_handlers; + EventHandler* m_current; + /// Data subscriptions (unordered) + Subscriptions m_subscriptions; + + EventHandler* current() const; + public: + /// Standard constructor + GenericEventHandler(); + /// Default destructor + virtual ~GenericEventHandler(); + /// Access the map of simulation data collections + virtual const TypedEventCollections& data() const { return current()->data(); } + /// Access the number of events on the current input data source (-1 if no data source connected) + virtual long numEvents() const; + /// Access the data source name + virtual std::string datasourceName() const; + /// Loop over collection and extract data + virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor); + /// Open a new event data file + virtual bool Open(const std::string& type, const std::string& file_name); + /// Load the next event + virtual bool NextEvent(); + /// User overloadable function: Load the previous event + virtual bool PreviousEvent(); + /// Goto a specified event in the file + virtual bool GotoEvent(long event_number); + /// Subscribe to notification of new data present + virtual void Subscribe(EventConsumer* display); + /// Unsubscribe from notification of new data present + virtual void Unsubscribe(EventConsumer* display); + +#ifndef __CINT__ + /// Notfy all subscribers + virtual void NotifySubscribers(void (EventConsumer::*pmf)(EventHandler*)); +#endif + + ClassDef(GenericEventHandler,0); + }; +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DDEVE_GENERICEVENTHANDLER_H */ + diff --git a/DDEve/include/DDEve/MultiView.h b/DDEve/include/DDEve/MultiView.h new file mode 100644 index 000000000..a856fbdda --- /dev/null +++ b/DDEve/include/DDEve/MultiView.h @@ -0,0 +1,43 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// Original Author: Matevz Tadel 2009 (MultiView.C) +// +//==================================================================== +#ifndef DD4HEP_DDEVE_MULTIVIEW_H +#define DD4HEP_DDEVE_MULTIVIEW_H + +// Framework include files +#include "DDEve/View.h" +#include "DDEve/DisplayConfiguration.h" + +class TEveWindowPack; + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /** @class MultiView MultiView.h DDEve/MultiView.h + * + * @author M.Frank + * @version 1.0 + */ + class MultiView : public View { + public: + /// Initializing constructor + MultiView(Display* eve, const std::string& name); + /// Default destructor + virtual ~MultiView(); + /// Build the 3d view and map it to the given slot + virtual View& Build(TEveWindow* slot); + /// Root implementation macro + ClassDef(MultiView,0); + }; +} /* End namespace DD4hep */ + + +#endif /* DD4HEP_DDEVE_MULTIVIEW_H */ diff --git a/DDEve/include/DDEve/Projection.h b/DDEve/include/DDEve/Projection.h index b772f2a69..5da7c2ddd 100644 --- a/DDEve/include/DDEve/Projection.h +++ b/DDEve/include/DDEve/Projection.h @@ -36,6 +36,13 @@ namespace DD4hep { /// Call an element to a event element list virtual TEveElement* ImportElement(TEveElement* el, TEveElementList* list); + /// Call an element to a geometry element list + virtual TEveElement* ImportGeoElement(TEveElement* element, TEveElementList* list); + /// Call an element to a geometry element list + virtual TEveElement* ImportGeoTopic(TEveElement* element, TEveElementList* list); + /// Call an element to a event element list + virtual TEveElement* ImportEventElement(TEveElement* element, TEveElementList* list); + public: /// Initializing constructor diff --git a/DDEve/include/DDEve/View.h b/DDEve/include/DDEve/View.h index 02c6ca193..a05bb3c97 100644 --- a/DDEve/include/DDEve/View.h +++ b/DDEve/include/DDEve/View.h @@ -56,14 +56,22 @@ namespace DD4hep { TEveScene *m_eveScene; /// Reference to the global item (if added TEveElementList *m_global; + const DisplayConfiguration::ViewConfig* m_config; + /// The name of the view std::string m_name; Topics m_geoTopics; Topics m_eveTopics; + bool m_showGlobal; + public: + /// Call an element to a geometry element list + virtual TEveElement* ImportGeoElement(TEveElement* element, TEveElementList* list); + /// Call an element to a geometry element list + virtual TEveElement* ImportGeoTopic(TEveElement* element, TEveElementList* list); /// Call an element to a event element list - virtual TEveElement* ImportElement(TEveElement* element, TEveElementList* list); + virtual TEveElement* ImportEventElement(TEveElement* element, TEveElementList* list); public: /// Initializing constructor @@ -71,12 +79,18 @@ namespace DD4hep { /// Default destructor virtual ~View(); /// Access to the view name/title - const std::string& name() const { return m_name; } - const char* c_name() const { return m_name.c_str(); } + const std::string& name() const { return m_name; } + const char* c_name() const { return m_name.c_str(); } /// Access to the Eve viewer - TEveViewer* viewer() const { return m_view; } + TEveViewer* viewer() const { return m_view; } + /// Show global directory + bool showGlobal() const { return m_showGlobal; } + /// Set show globals + void setShowGlobal(bool value) { m_showGlobal = value; } /// Build the view view and map it to the given slot virtual View& Build(TEveWindow* slot); + /// Initialize the view port + virtual void Initialize(); /// Map the view view to the slot virtual View& Map(TEveWindow* slot); @@ -91,8 +105,14 @@ namespace DD4hep { TEveScene* geoScene() const { return m_geoScene; } /// Create the geometry scene virtual View& CreateGeoScene(); + + /// Configure a view with geo info. Used configuration if present. + virtual void ConfigureGeometry(); + /// Configure a single geometry view by default from the global geometry scene with all subdetectors + virtual void ConfigureGeometryFromGlobal(); /// Configure a single geometry view virtual void ConfigureGeometry(const DisplayConfiguration::ViewConfig& config); + /// Create a new instance of the geometry of a sub-detector virtual std::pair<bool,TEveElement*> CreateGeometry(DetElement de, const DisplayConfiguration::Config& cfg); @@ -109,8 +129,9 @@ namespace DD4hep { virtual void ImportGeo(TEveElement* element); /// Call to import geometry topics. If title is empty, do not add to global item list virtual void ImportGeoTopics(const std::string& title); - /// Call to destroy all geometry elements - virtual void DestroyGeo(); + /// Access/Create an geometry topic by name + virtual TEveElementList& GetGeoTopic(const std::string& name); + /** Manipulation of the event scene */ @@ -118,31 +139,17 @@ namespace DD4hep { TEveScene* eveScene() const { return m_eveScene; } /// Create the event scene virtual View& CreateEventScene(); + /// Configure a view with event info. Used configuration if present. + virtual void ConfigureEvent(); + /// Configure an event view by default from the global event scene + virtual void ConfigureEventFromGlobal(); /// Configure a single event scene view virtual void ConfigureEvent(const DisplayConfiguration::ViewConfig& config); /// Call to import event elements into the main event scene virtual void ImportEvent(TEveElement* element); - /// Import event data from event handler for a given subdetector - virtual void ImportEvent(EventHandler& hdlr, - DetElement det, - SensitiveDetector sd, - const DisplayConfiguration::ViewConfig& config); /// Import event typics after creation virtual void ImportEventTopics(); - /// Call to destroy all event elements - virtual void DestroyEvent(); - /// Prepare the view before loading new event data - virtual void PrepareEvent(); - /// Access/Create an geometry topic by name - virtual TEveElementList& GetGeoTopic(const std::string& name); -#if 0 - /// Access/Create an event topic by name - virtual TEveElementList& GetEveTopic(const std::string& name); - /// Call to import event elements into topics - virtual void ImportEvent(const std::string& topic, TEveElement* element); - void Finalize(); -#endif /// Root implementation macro ClassDef(View,0); }; diff --git a/DDEve/include/DDEve/ViewConfiguration.h b/DDEve/include/DDEve/ViewConfiguration.h deleted file mode 100644 index c461e649e..000000000 --- a/DDEve/include/DDEve/ViewConfiguration.h +++ /dev/null @@ -1,62 +0,0 @@ -// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ -//==================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------- -// -// Author : M.Frank -// -//==================================================================== -#ifndef DD4HEP_DDEVE_VIEWCONFIGURATION_H -#define DD4HEP_DDEVE_VIEWCONFIGURATION_H - -// Framework include files -#include "DDEve/DisplayConfiguration.h" - -// Forward declarations - -/* - * DD4hep namespace declaration - */ -namespace DD4hep { - - // Forward declarations - class View; - class Display; - - /** @class ViewConfiguration ViewConfiguration.h DDEve/ViewConfiguration.h - * - * @author M.Frank - * @version 1.0 - */ - class ViewConfiguration { - protected: - /// The view configuration data - DisplayConfiguration::ViewConfig config; - /// Reference to hosting display - Display* m_display; - public: - /// Standard constructor - ViewConfiguration(); - /// Initializing constructor - ViewConfiguration(Display* display, const DisplayConfiguration::ViewConfig& cfg); - /// Default destructor - virtual ~ViewConfiguration(); - /// Access to the name - const std::string& name() const { return config.name; } - /// Access to the type - const std::string& type() const { return config.type; } - /// Prepare the view for adding event data - void PrepareEvent(View* view) const; - /// Configure the event data display of a single view - void ConfigureEvent(View* view) const; - /// Configure the geometry of a single view - void ConfigureGeometry(View* view) const; - /// ROOT implementation macro - ClassDef(ViewConfiguration,0); - }; - -} /* End namespace DD4hep */ - - -#endif /* DD4HEP_DDEVE_VIEWCONFIGURATION_H */ - diff --git a/DDEve/include/DDEve/ViewMenu.h b/DDEve/include/DDEve/ViewMenu.h index fea415eb1..2ad1d7bff 100644 --- a/DDEve/include/DDEve/ViewMenu.h +++ b/DDEve/include/DDEve/ViewMenu.h @@ -49,17 +49,18 @@ namespace DD4hep { /// Import Geometry data and build the view void BuildView(View *view) const; - /// Menu callback: Create a generic view from an XML configuration - void CreateGenericView(TGMenuEntry* e, void* ud); - /// Menu callback: Create a new 3D view + /// Menu callback: Create a generic view using the user data void CreateView(TGMenuEntry* e, void* ud); - /// Create a new 3D view + /// Create a generic view of a given type with title + View* CreateView(const std::string& type,const std::string& title); + /// Specialization: Create a new 3D view View* CreateView3D(const std::string& title); - /// Create a new R-Z view + /// Specialization: Create a new R-Z view View* CreateRhoZProjection(const std::string& title); - /// Create a new R-Phi view + /// Specialization: Create a new R-Phi view View* CreateRhoPhiProjection(const std::string& title); + /// ROOT implementation macro ClassDef(ViewMenu,0); }; diff --git a/DDEve/lcio/LCIOEventHandler.cpp b/DDEve/lcio/LCIOEventHandler.cpp new file mode 100644 index 000000000..5205b7cba --- /dev/null +++ b/DDEve/lcio/LCIOEventHandler.cpp @@ -0,0 +1,153 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "LCIOEventHandler.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Objects.h" +#include "DD4hep/Factories.h" + +#include "IO/LCReader.h" +#include "EVENT/LCCollection.h" +#include "EVENT/SimCalorimeterHit.h" +#include "EVENT/SimTrackerHit.h" +#include "EVENT/MCParticle.h" + +#include "TSystem.h" +#include "TGMsgBox.h" + +// C/C++ include files +#include <stdexcept> +#include <climits> + +using namespace std; +using namespace lcio; +using namespace DD4hep; +using namespace EVENT; +using namespace IMPL; + +const void* _fill(const SimTrackerHit* s, DDEveHit* target) { + const double* p = s->getPosition(); + target->x = p[0]; + target->y = p[1]; + target->z = p[2]; + target->deposit = s->getEDep(); + return s; +} +const void* _fill(const SimCalorimeterHit* s, DDEveHit* target) { + const float* p = s->getPosition(); + target->x = p[0]; + target->y = p[1]; + target->z = p[2]; + target->deposit = s->getEnergy(); + return s; +} + +static const void* _convertHitFunc(const LCObject* source, DDEveHit* target) { + const SimTrackerHit* t = dynamic_cast<const SimTrackerHit*>(source); + if (t && _fill(t,target)) return t; + const SimCalorimeterHit* c = dynamic_cast<const SimCalorimeterHit*>(source); + if (c && _fill(c,target)) return c; + return 0; +} + +static void* _create(const char*) { + EventHandler* h = new LCIOEventHandler(); + return h; +} +using namespace DD4hep::Geometry; +DECLARE_CONSTRUCTOR(DDEve_LCIOEventHandler,_create) + +/// Standard constructor +LCIOEventHandler::LCIOEventHandler() : EventHandler(), m_lcReader(0), m_event(0) { + m_lcReader = LCFactory::getInstance()->createLCReader() ; +} + +/// Default destructor +LCIOEventHandler::~LCIOEventHandler() { + delete m_lcReader; +} + +/// Access the number of events on the current input data source (-1 if no data source connected) +long LCIOEventHandler::numEvents() const { + if ( hasFile() ) { + return m_lcReader->getNumberOfEvents(); + } + return -1; +} + +/// Call functor on hit collection +size_t LCIOEventHandler::collectionLoop(const std::string& collection, DDEveHitActor& actor) { + typedef std::vector<void*> _P; + Branches::const_iterator i = m_branches.find(collection); + if ( i != m_branches.end() ) { + LCCollection* c = (*i).second; + if ( c ) { + DDEveHit hit; + int n = c->getNumberOfElements(); + actor.setSize(n); + for(int i=0; i<n; ++i) { + LCObject* ptr = c->getElementAt(i); + if ( _convertHitFunc(ptr,&hit) ) { + actor(hit); + } + } + return n; + } + } + return 0; +} + +/// Open new data file +bool LCIOEventHandler::Open(const std::string&, const std::string& name) { + string err; + if ( m_hasFile ) m_lcReader->close(); + m_hasFile = false; + m_hasEvent = false; + m_event = 0; + m_branches.clear(); + m_lcReader->open(name); + m_hasFile = true; + return true; +} + +/// Load the next event +bool LCIOEventHandler::NextEvent() { + m_data.clear(); + m_hasEvent = false; + m_branches.clear(); + m_data.clear(); + if ( hasFile() ) { + m_event = m_lcReader->readNextEvent(); + if ( m_event ) { + const std::vector<std::string>* collnames = m_event->getCollectionNames(); + for( std::vector< std::string >::const_iterator i = collnames->begin(); i != collnames->end(); i++){ + LCCollection* c = m_event->getCollection(*i); + m_data[c->getTypeName()].push_back(make_pair((*i).c_str(),c->getNumberOfElements())); + m_branches[*i] = c; + } + m_hasEvent = true; + return 1; + } + throw runtime_error("+++ EventHandler::readEvent: Failed to read event"); + } + throw runtime_error("+++ EventHandler::readEvent: No file open!"); +} + +/// Load the previous event +bool LCIOEventHandler::PreviousEvent() { + throw runtime_error("+++ This version of the LCIO reader can only access files sequentially!\n" + "+++ Access to the previous event is not supported."); +} + +/// Goto a specified event in the file +bool LCIOEventHandler::GotoEvent(long /* event_number */) { + throw runtime_error("+++ This version of the LCIO reader can only access files sequentially!\n" + "+++ Random access is not supported."); +} diff --git a/DDEve/lcio/LCIOEventHandler.h b/DDEve/lcio/LCIOEventHandler.h new file mode 100644 index 000000000..be85697ee --- /dev/null +++ b/DDEve/lcio/LCIOEventHandler.h @@ -0,0 +1,73 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_DDEVE_LCIOEVENTHANDLER_H +#define DD4HEP_DDEVE_LCIOEVENTHANDLER_H + +// Framework include files +#include "DDEve/EventHandler.h" + +#include "lcio.h" + +// C/C++ include files +#include <map> +#include <string> + +// Forward declarations + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /** @class LCIOEventHandler LCIOEventHandler.h DDEve/LCIOEventHandler.h + * + * @author M.Frank + * @version 1.0 + */ + class LCIOEventHandler : public EventHandler { + public: + typedef std::map<std::string,lcio::LCCollection*> Branches; + typedef const void* (*HitAccessor_t)(const lcio::LCObject*, DDEveHit*); + protected: + /// Reference to data file reader + lcio::LCReader* m_lcReader; + lcio::LCEvent* m_event; + std::string m_fileName; + /// Branch map + Branches m_branches; + /// Data collection map + TypedEventCollections m_data; + public: + /// Standard constructor + LCIOEventHandler(); + /// Default destructor + virtual ~LCIOEventHandler(); + + /// Access the map of simulation data collections + virtual const TypedEventCollections& data() const { return m_data; } + /// Access the data source name + std::string datasourceName() const { return hasFile() ? m_fileName : std::string("UNKNOWN"); } + /// Access the number of events on the current input data source (-1 if no data source connected) + virtual long numEvents() const; + /// Call functor on hit collection + virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor); + /// Open new data file + virtual bool Open(const std::string& type, const std::string& file_name); + /// User overloadable function: Load the next event + virtual bool NextEvent(); + /// User overloadable function: Load the previous event + virtual bool PreviousEvent(); + /// Goto a specified event in the file + virtual bool GotoEvent(long event_number); + }; + +} /* End namespace DD4hep */ + +#endif /* DD4HEP_DDEVE_LCIOEVENTHANDLER_H */ + diff --git a/DDEve/src/Calo2DProjection.cpp b/DDEve/src/Calo2DProjection.cpp index 00414fefe..8212a9c11 100644 --- a/DDEve/src/Calo2DProjection.cpp +++ b/DDEve/src/Calo2DProjection.cpp @@ -17,6 +17,7 @@ #include "TEveCalo.h" #include "TEveScene.h" #include "TGLViewer.h" +#include "TEveArrow.h" using namespace std; using namespace DD4hep; @@ -43,7 +44,7 @@ View& Calo2DProjection::Build(TEveWindow* slot) { AddToGlobalItems(name()); return Map(slot); } -#include "TEveArrow.h" + /// Configure a single geometry view void Calo2DProjection::ConfigureGeometry(const DisplayConfiguration::ViewConfig& config) { DisplayConfiguration::Configurations::const_iterator fit; diff --git a/DDEve/src/Calo3DProjection.cpp b/DDEve/src/Calo3DProjection.cpp index c13118274..d00a9c38e 100644 --- a/DDEve/src/Calo3DProjection.cpp +++ b/DDEve/src/Calo3DProjection.cpp @@ -9,15 +9,9 @@ //==================================================================== // Framework include files #include "DDEve/Calo3DProjection.h" -#include "DDEve/Annotation.h" #include "DDEve/Factories.h" #include "DD4hep/InstanceCount.h" -// Root include files -#include "TEveCalo.h" -#include "TEveScene.h" - -using namespace std; using namespace DD4hep; ClassImp(Calo3DProjection) @@ -37,27 +31,7 @@ Calo3DProjection::~Calo3DProjection() { /// Build the projection view and map it to the given slot View& Calo3DProjection::Build(TEveWindow* slot) { - CreateGeoScene(); + CreateScenes(); AddToGlobalItems(name()); return Map(slot); } - -/// Configure a single geometry view -void Calo3DProjection::ConfigureGeometry(const DisplayConfiguration::ViewConfig& config) { - DisplayConfiguration::Configurations::const_iterator j = config.subdetectors.begin(); - float legend_y = Annotation::DefaultTextSize()+Annotation::DefaultMargin(); - for( ; j != config.subdetectors.end(); ++j) { - const char* n = (*j).name.c_str(); - const Display::CalodataContext& ctx = m_eve->GetCaloHistogram(n); - if ( ctx.config.use.empty() ) ImportGeo(ctx.calo3D); - printout(INFO,"Calo3DProjection","+++ %s: add detector %s %s", - name().c_str(), n, ctx.config.use.c_str()); - Color_t col = ctx.calo3D->GetDataSliceColor(ctx.slice); - Annotation* a = new Annotation(viewer(),n,Annotation::DefaultMargin(),legend_y,col); - legend_y += a->GetTextSize(); - } -} - -/// Configure a single event scene view -void Calo3DProjection::ConfigureEvent(const DisplayConfiguration::ViewConfig& /* config */) { -} diff --git a/DDEve/src/DD4hepMenu.cpp b/DDEve/src/DD4hepMenu.cpp index 9b4edcb05..951e96ef1 100644 --- a/DDEve/src/DD4hepMenu.cpp +++ b/DDEve/src/DD4hepMenu.cpp @@ -89,7 +89,7 @@ void DD4hepMenu::OnLoadXML(TGMenuEntry* /* entry */, void* /* ptr */) { /// Callback when loading the configuration void DD4hepMenu::OnLoadRootGeometry(TGMenuEntry* /* entry */, void* /* ptr */) { - std::string fname = m_display->OpenRootFileDialog("."); + std::string fname = m_display->OpenEventFileDialog("."); if ( !fname.empty() ) { m_display->LoadGeometryRoot(fname.c_str()); } diff --git a/DDEve/src/DDG4EventHandler.cpp b/DDEve/src/DDG4EventHandler.cpp index c19d423f6..916002899 100644 --- a/DDEve/src/DDG4EventHandler.cpp +++ b/DDEve/src/DDG4EventHandler.cpp @@ -13,17 +13,12 @@ #include "DD4hep/Objects.h" #include "DD4hep/Factories.h" -#include "TH2.h" #include "TFile.h" #include "TTree.h" #include "TBranch.h" -#include "TSystem.h" -#include "TBranch.h" -#include "TGMsgBox.h" // C/C++ include files #include <stdexcept> -#include <climits> using namespace std; using namespace DD4hep; @@ -37,6 +32,13 @@ namespace { }; } +static void* _create(const char*) { + EventHandler* h = new DDG4EventHandler(); + return h; +} +using namespace DD4hep::Geometry; +DECLARE_CONSTRUCTOR(DDEve_DDG4EventHandler,_create) + /// Standard constructor DDG4EventHandler::DDG4EventHandler() : EventHandler(), m_file(0,0), m_entry(-1) { void* ptr = ROOT::Reflex::PluginService::Create<void*>("DDEve_DDG4HitAccess",(const char*)""); @@ -109,93 +111,65 @@ size_t DDG4EventHandler::collectionLoop(const std::string& collection, DDEveHitA /// Load the specified event Int_t DDG4EventHandler::ReadEvent(Long64_t event_number) { - ClearCache(); m_data.clear(); m_hasEvent = false; - try { - if ( hasFile() ) { - if ( event_number >= m_file.second->GetEntries() ) { - event_number = m_file.second->GetEntries()-1; - printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Cannot read across End-of-file! Reading last event:%d.",event_number); - } - else if ( event_number < 0 ) { - event_number = 0; - printout(ERROR,"DDG4EventHandler","+++ nextEvent: Cannot read across Start-of-file! Reading first event:%d.",event_number); - } + if ( hasFile() ) { + if ( event_number >= m_file.second->GetEntries() ) { + event_number = m_file.second->GetEntries()-1; + printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Cannot read across End-of-file! Reading last event:%d.",event_number); + } + else if ( event_number < 0 ) { + event_number = 0; + printout(ERROR,"DDG4EventHandler","+++ nextEvent: Cannot read across Start-of-file! Reading first event:%d.",event_number); + } - Int_t nbytes = m_file.second->GetEntry(event_number); - if ( nbytes >= 0 ) { - printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Read %d bytes of event data for entry:%d",nbytes,event_number); - for(Branches::const_iterator i=m_branches.begin(); i != m_branches.end(); ++i) { - TBranch* b = (*i).second.first; - std::vector<void*>* data = *(std::vector<void*>**)b->GetAddress(); - m_data[b->GetClassName()].push_back(make_pair(b->GetName(),data->size())); - } - m_hasEvent = true; - NotifySubscribers(&EventConsumer::OnNewEvent); - return nbytes; + Int_t nbytes = m_file.second->GetEntry(event_number); + if ( nbytes >= 0 ) { + printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Read %d bytes of event data for entry:%d",nbytes,event_number); + for(Branches::const_iterator i=m_branches.begin(); i != m_branches.end(); ++i) { + TBranch* b = (*i).second.first; + std::vector<void*>* data = *(std::vector<void*>**)b->GetAddress(); + m_data[b->GetClassName()].push_back(make_pair(b->GetName(),data->size())); } - printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Cannot read event data for entry:%d",event_number); - throw runtime_error("+++ EventHandler::readEvent: Failed to read event"); + m_hasEvent = true; + return nbytes; } - throw runtime_error("+++ EventHandler::readEvent: No file open!"); + printout(ERROR,"DDG4EventHandler","+++ ReadEvent: Cannot read event data for entry:%d",event_number); + throw runtime_error("+++ EventHandler::readEvent: Failed to read event"); } - catch(const std::exception& e) { - string path = TString::Format("%s/icons/stop_t.xpm", gSystem->Getenv("ROOTSYS")).Data(); - string err = "\nAn exception occurred \n" - "while reading a new event:\n" + string(e.what()) + "\n\n"; - const TGPicture* pic = gClient->GetPicture(path.c_str()); - new TGMsgBox(gClient->GetRoot(),0,"Failed to read event", err.c_str(),pic); - } - return -1; + throw runtime_error("+++ EventHandler::readEvent: No file open!"); } /// Open new data file -bool DDG4EventHandler::Open(const std::string& name) { +bool DDG4EventHandler::Open(const std::string&, const std::string& name) { string err; if ( m_file.first ) m_file.first->Close(); m_hasFile = false; m_hasEvent = false; - try { - char buff[PATH_MAX]; - string dir = ::getcwd(buff,sizeof(buff)); - TFile* f = TFile::Open(name.c_str()); - if ( f && !f->IsZombie() ) { - m_file.first = f; - TTree* t = (TTree*)f->Get("EVENT"); - if ( t ) { - TObjArray* br = t->GetListOfBranches(); - m_file.second = t; - m_entry = -1; - m_branches.clear(); - for(Int_t i=0; i<br->GetSize(); ++i) { - TBranch* b = (TBranch*)br->At(i); - if ( !b ) continue; - m_branches[b->GetName()] = make_pair(b,(void*)0); - printout(INFO,"DDG4EventHandler::open","+++ Branch %s has %ld entries.",b->GetName(),b->GetEntries()); - } - for(Int_t i=0; i<br->GetSize(); ++i) { - TBranch* b = (TBranch*)br->At(i); - if ( !b ) continue; - b->SetAddress(&m_branches[b->GetName()].second); - } - m_hasFile = true; - NotifySubscribers(&EventConsumer::OnFileOpen); - return true; + TFile* f = TFile::Open(name.c_str()); + if ( f && !f->IsZombie() ) { + m_file.first = f; + TTree* t = (TTree*)f->Get("EVENT"); + if ( t ) { + TObjArray* br = t->GetListOfBranches(); + m_file.second = t; + m_entry = -1; + m_branches.clear(); + for(Int_t i=0; i<br->GetSize(); ++i) { + TBranch* b = (TBranch*)br->At(i); + if ( !b ) continue; + m_branches[b->GetName()] = make_pair(b,(void*)0); + printout(INFO,"DDG4EventHandler::open","+++ Branch %s has %ld entries.",b->GetName(),b->GetEntries()); } - err = "+++ Failed to access tree EVENT in ROOT file:"+name+" in "+dir; - } - else { - err = "+++ Failed to open ROOT file:"+name+" in "+dir; + for(Int_t i=0; i<br->GetSize(); ++i) { + TBranch* b = (TBranch*)br->At(i); + if ( !b ) continue; + b->SetAddress(&m_branches[b->GetName()].second); + } + m_hasFile = true; + return true; } + throw runtime_error("+++ Failed to access tree EVENT in ROOT file:"+name); } - catch(const std::exception& e) { - err = "\nAn exception occurred \n" - "while opening event data:\n" + string(e.what()) + "\n\n"; - } - string path = TString::Format("%s/icons/stop_t.xpm", gSystem->Getenv("ROOTSYS")).Data(); - const TGPicture* pic = gClient->GetPicture(path.c_str()); - new TGMsgBox(gClient->GetRoot(),0,"Failed to open event data", err.c_str(),pic); - return false; + throw runtime_error("+++ Failed to open ROOT file:"+name); } - diff --git a/DDEve/src/Display.cpp b/DDEve/src/Display.cpp index 66f1e9c01..bdfd5ba6d 100644 --- a/DDEve/src/Display.cpp +++ b/DDEve/src/Display.cpp @@ -13,10 +13,9 @@ #include "DDEve/ElementList.h" #include "DDEve/ViewMenu.h" #include "DDEve/DD4hepMenu.h" -#include "DDEve/ViewConfiguration.h" #include "DDEve/EveShapeContextMenu.h" #include "DDEve/EvePgonSetProjectedContextMenu.h" -#include "DDEve/DDG4EventHandler.h" +#include "DDEve/GenericEventHandler.h" #include "DDEve/Utilities.h" #include "DDEve/DDEveEventData.h" @@ -54,7 +53,7 @@ ClassImp(Display) namespace DD4hep { void EveDisplay(const char* xmlConfig = 0) { - Display* display = new Display(TEveManager::Create(true,"V")); + Display* display = new Display(TEveManager::Create(true,"VI")); if ( xmlConfig != 0 ) { char text[PATH_MAX]; ::snprintf(text,sizeof(text),"%s%s",strncmp(xmlConfig,"file:",5)==0 ? "file:" : "",xmlConfig); @@ -77,7 +76,7 @@ namespace DD4hep { int count; PointsetCreator(TEvePointSet* ps) : points(ps), count(0) {} virtual void operator()(const DDEveHit& hit) - { points->SetPoint(count++, hit.x/10e0, hit.y/10e0, hit.z/10e0); } + { points->SetPoint(count++, hit.x/10e0, hit.y/10e0, hit.z/10e0); } }; struct EtaPhiHistogramActor : public DDEveHitActor { TH2F* histogram; @@ -90,7 +89,7 @@ namespace DD4hep { } Display::CalodataContext::CalodataContext() -: slice(0), calo3D(0), caloViz(0), eveHist(0), config() + : slice(0), calo3D(0), caloViz(0), eveHist(0), config() { } @@ -121,7 +120,7 @@ Display::Display(TEveManager* eve) EvePgonSetProjectedContextMenu::install(this); ElementListContextMenu::install(this); m_lcdd = &Geometry::LCDD::getInstance(); - m_evtHandler = new DDG4EventHandler(); + m_evtHandler = new GenericEventHandler(); m_evtHandler->Subscribe(this); m_lcdd->addExtension<Display>(this); br->ShowCloseTab(kFALSE); @@ -135,7 +134,7 @@ Display::Display(TEveManager* eve) Display::~Display() { TRootBrowser* br = m_eve->GetBrowser(); m_lcdd->removeExtension<Display>(false); - destroyObjects(m_viewConfigs)(); + m_viewConfigs.clear(); deletePtr(m_evtHandler); deletePtr(m_eveGlobal); deletePtr(m_geoGlobal); @@ -188,7 +187,7 @@ TGClient& Display::client() const { } /// Access to the event reader -EventHandler& Display::eventHandler() const { +GenericEventHandler& Display::eventHandler() const { if ( m_evtHandler ) { return *m_evtHandler; } @@ -206,27 +205,15 @@ void Display::AddMenu(TGMenuBar* bar, PopupMenu* menu, int hints) { void Display::ImportConfiguration(const DisplayConfiguration& config) { DisplayConfiguration::ViewConfigurations::const_iterator i; for(i=config.views.begin(); i!=config.views.end(); ++i) - RegisterViewConfiguration(new ViewConfiguration(this,*i)); + m_viewConfigs[(*i).name] = *i; DisplayConfiguration::Configurations::const_iterator j; for(j=config.calodata.begin(); j!=config.calodata.end(); ++j) m_calodataConfigs[(*j).name] = *j; } -/// Register a data filter by name -void Display::RegisterViewConfiguration(ViewConfiguration* cfg) { - ViewConfigurations::iterator i = m_viewConfigs.find(cfg->name()); - printout(INFO,"Display","+++ Register view configuration for %s Config=%p.",cfg->name().c_str(),cfg); - if ( i != m_viewConfigs.end() ) { - delete (*i).second; - (*i).second = cfg; - return; - } - m_viewConfigs[cfg->name()] = cfg; -} - /// Access to calo data histograms by name as defined in the configuration -Display::CalodataContext& Display::GetCaloHistogram(const std::string& nam) { +Display::CalodataContext& Display::GetCaloHistogram(const string& nam) { Calodata::iterator i = m_calodata.find(nam); if ( i == m_calodata.end() ) { CalodataConfigurations::const_iterator j = m_calodataConfigs.find(nam); @@ -252,10 +239,10 @@ Display::CalodataContext& Display::GetCaloHistogram(const std::string& nam) { ctx.calo3D = new TEveCalo3D(ctx.eveHist); ctx.calo3D->SetName(n); - ctx.calo3D->SetBarrelRadius(cd.rmin*MM_2_CM); - ctx.calo3D->SetEndCapPos(cd.dz*MM_2_CM); + ctx.calo3D->SetBarrelRadius(cd.rmin); + ctx.calo3D->SetEndCapPos(cd.dz); ctx.calo3D->SetAutoRange(kTRUE); - ctx.calo3D->SetMaxTowerH(10); + ctx.calo3D->SetMaxTowerH(cd.towerH); ImportGeo(ctx.calo3D); EtaPhiHistogramActor actor(h); eventHandler().collectionLoop(hits,actor); @@ -277,61 +264,17 @@ Display::CalodataContext& Display::GetCaloHistogram(const std::string& nam) { } /// Access a data filter by name. Data filters are used to customize views -ViewConfiguration* Display::GetViewConfiguration(const string& nam) const { +const Display::ViewConfig* Display::GetViewConfiguration(const string& nam) const { ViewConfigurations::const_iterator i = m_viewConfigs.find(nam); - return (i == m_viewConfigs.end()) ? 0 : (*i).second; + return (i == m_viewConfigs.end()) ? 0 : &((*i).second); } /// Access a data filter by name. Data filters are used to customize calodatas -const Display::CalodataConfiguration* Display::GetCalodataConfiguration(const string& nam) const { +const Display::CalodataConfig* Display::GetCalodataConfiguration(const string& nam) const { CalodataConfigurations::const_iterator i = m_calodataConfigs.find(nam); return (i == m_calodataConfigs.end()) ? 0 : &((*i).second); } -/// Configure a view using the view's name and a proper ViewConfiguration if present -void Display::ConfigureGeometry(View* view) { - ViewConfiguration* cfg = GetViewConfiguration(view->name()); - printout(INFO,"Display","+++ Configure view %s Config=%p.",view->name().c_str(),cfg); - if ( 0 != cfg ) { - cfg->ConfigureGeometry(view); - } - else { - TEveElementList* l = &GetGeoTopic("Sensitive"); - TEveElementList* t = &view->GetGeoTopic("Sensitive"); - for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) - view->ImportGeo(*t,*i); - - l = &GetGeoTopic("Structure"); - t = &view->GetGeoTopic("Structure"); - for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) - view->ImportGeo(*t,*i); - } - view->ImportGeoTopics(view->name()); -} - -/// Configure the adding of event data -void Display::ConfigureEvent(View* view) const { - ViewConfiguration* cfg = GetViewConfiguration(view->name()); - printout(INFO,"Display","+++ Import event data into view %s.",view->name().c_str()); - if ( cfg ) { - cfg->ConfigureEvent(view); - } - else { - // view->ImportEvent(manager().GetEventScene()); - TEveElementList* l = manager().GetEventScene(); - for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) - view->ImportEvent(*i); - } - view->ImportEventTopics(); -} - -/// Prepare the view for adding event data -void Display::PrepareEvent(View* view) const { - ViewConfiguration* cfg = GetViewConfiguration(view->name()); - printout(INFO,"Display","+++ Prepare view %s for event data.",view->name().c_str()); - ( cfg ) ? cfg->PrepareEvent(view) : view->PrepareEvent(); -} - /// Register to the main event scene on new events void Display::RegisterEvents(View* view) { m_eveViews.insert(view); @@ -346,7 +289,7 @@ void Display::UnregisterEvents(View* view) { } /// Open standard message box -void Display::MessageBox(PrintLevel level, const std::string& text, const std::string& title) const { +void Display::MessageBox(PrintLevel level, const string& text, const string& title) const { string path = TString::Format("%s/icons/", gSystem->Getenv("ROOTSYS")).Data(); const TGPicture* pic = 0; if ( level == VERBOSE ) @@ -366,7 +309,7 @@ void Display::MessageBox(PrintLevel level, const std::string& text, const std::s } /// Popup XML file chooser. returns chosen file name; empty on cancel -std::string Display::OpenXmlFileDialog(const std::string& default_dir) const { +string Display::OpenXmlFileDialog(const string& default_dir) const { static const char *evtFiletypes[] = { "xml files", "*.xml", "XML files", "*.XML", @@ -387,10 +330,11 @@ std::string Display::OpenXmlFileDialog(const std::string& default_dir) const { } /// Popup ROOT file chooser. returns chosen file name; empty on cancel -std::string Display::OpenRootFileDialog(const std::string& default_dir) const { +string Display::OpenEventFileDialog(const string& default_dir) const { static const char *evtFiletypes[] = { "ROOT files", "*.root", - //"LCIO files", "*.lcio", + "SLCIO files", "*.slcio", + "LCIO files", "*.lcio", "All files", "*", 0, 0 }; @@ -430,11 +374,11 @@ TFile* Display::Open(const char* name) const { /// Consumer event data void Display::OnNewEvent(EventHandler* handler ) { typedef EventHandler::TypedEventCollections Types; - typedef std::vector<EventHandler::Collection> Collections; + typedef vector<EventHandler::Collection> Collections; const Types& types = handler->data(); printout(ERROR,"EventHandler","+++ Display new event....."); - GetEve().DestroyElements(); + manager().GetEventScene()->DestroyElements(); for(Types::const_iterator i=types.begin(); i!=types.end(); ++i) { const Collections& colls = (*i).second; for(Collections::const_iterator j=colls.begin(); j!=colls.end(); ++j) { @@ -450,8 +394,6 @@ void Display::OnNewEvent(EventHandler* handler ) { } for(Calodata::iterator i = m_calodata.begin(); i != m_calodata.end(); ++i) (*i).second.eveHist->GetHist(0)->Reset(); - for(Views::iterator i = m_eveViews.begin(); i != m_eveViews.end(); ++i) - PrepareEvent(*i); for(Calodata::iterator i = m_calodata.begin(); i != m_calodata.end(); ++i) { CalodataContext& ctx = (*i).second; TH2F* h = ctx.eveHist->GetHist(0); @@ -462,7 +404,7 @@ void Display::OnNewEvent(EventHandler* handler ) { ctx.calo3D->GetName(), n, ctx.config.hits.c_str()); } for(Views::iterator i = m_eveViews.begin(); i != m_eveViews.end(); ++i) - ConfigureEvent(*i); + (*i)->ConfigureEvent(); manager().Redraw3D(); } @@ -488,7 +430,7 @@ TEveElementList& Display::GetGeoTopic(const string& name) { return *((*i).second); } -/// Access/Create a topic by name +/// Access/Create a topic by name. Throws exception if the topic does not exist TEveElementList& Display::GetGeoTopic(const string& name) const { Topics::const_iterator i=m_geoTopics.find(name); if ( i == m_geoTopics.end() ) { @@ -497,29 +439,19 @@ TEveElementList& Display::GetGeoTopic(const string& name) const { return *((*i).second); } -/// Access/Create an event topic by name -TEveElementList& Display::GetEve() { - if ( 0 == m_eveGlobal ) { - m_eveGlobal = manager().GetEventScene(); - //m_eveGlobal = new ElementList("Eve-Global","Eve-Global", true, true); - //manager().GetEventScene()->AddElement(m_eveGlobal); - } - return *m_eveGlobal; -} - /// Access/Create a topic by name TEveElementList& Display::GetEveTopic(const string& name) { Topics::iterator i=m_eveTopics.find(name); if ( i == m_eveTopics.end() ) { TEveElementList* topic = new ElementList(name.c_str(), name.c_str(), true, true); m_eveTopics[name] = topic; - GetEve().AddElement(topic); + manager().GetEventScene()->AddElement(topic); return *topic; } return *((*i).second); } -/// Access/Create a topic by name +/// Access/Create a topic by name. Throws exception if the topic does not exist TEveElementList& Display::GetEveTopic(const string& name) const { Topics::const_iterator i=m_eveTopics.find(name); if ( i == m_eveTopics.end() ) { @@ -545,7 +477,7 @@ void Display::ImportEvent(const string& topic, TEveElement* el) { /// Call to import top level event elements void Display::ImportEvent(TEveElement* el) { - GetEve().AddElement(el); + manager().GetEventScene()->AddElement(el); } /// Load 'levels' Children into the geometry scene @@ -567,7 +499,7 @@ void Display::LoadGeoChildren(TEveElement* start, int levels, bool redraw) { DetElement de = (*i).second; SensitiveDetector sd = m_lcdd->sensitiveDetector(de.name()); TEveElementList& parent = sd.isValid() ? sens : struc; - std::pair<bool,TEveElement*> e = Utilities::LoadDetElement(de,levels,&parent); + pair<bool,TEveElement*> e = Utilities::LoadDetElement(de,levels,&parent); if ( e.second && e.first ) { parent.AddElement(e.second); } diff --git a/DDEve/src/DisplayConfiguration.cpp b/DDEve/src/DisplayConfiguration.cpp index 2604048c5..8222b6682 100644 --- a/DDEve/src/DisplayConfiguration.cpp +++ b/DDEve/src/DisplayConfiguration.cpp @@ -57,7 +57,7 @@ DisplayConfiguration::ViewConfig& DisplayConfiguration::ViewConfig::operator=(co DisplayConfiguration::Config::Config() { ::memset(&data,0,sizeof(data)); data.defaults.load_geo = -1; - data.defaults.load_eve = -2; + data.defaults.show_evt = 1; data.defaults.alpha = 0.5; } diff --git a/DDEve/src/DisplayConfigurationParser.cpp b/DDEve/src/DisplayConfigurationParser.cpp index 655dca7e3..d3cfff218 100644 --- a/DDEve/src/DisplayConfigurationParser.cpp +++ b/DDEve/src/DisplayConfigurationParser.cpp @@ -30,6 +30,7 @@ namespace DD4hep { namespace { /// Some utility class to specialize the convetrers: class ddeve; class view; + class panel; class calodata; class calodata_configs; class detelement; @@ -44,6 +45,7 @@ namespace DD4hep { namespace { template <> void Converter<ddeve>::operator()(xml_h seq) const; template <> void Converter<display>::operator()(xml_h seq) const; template <> void Converter<view>::operator()(xml_h seq) const; + template <> void Converter<panel>::operator()(xml_h seq) const; template <> void Converter<include>::operator()(xml_h seq) const; template <> void Converter<calodata>::operator()(xml_h e) const; template <> void Converter<calodata_configs>::operator()(xml_h e) const; @@ -54,7 +56,7 @@ namespace DD4hep { namespace { namespace { DECL_TAG(clone); DECL_TAG(load_geo); - DECL_TAG(load_eve); + DECL_TAG(show_evt); DECL_TAG(use); DECL_TAG(emax); DECL_TAG(hits); @@ -73,7 +75,7 @@ namespace { static void extract(DisplayConfiguration::Config& c, xml_h e, int typ) { c.name = e.attr<string>(_U(name)); c.type = typ; - //c.data.defaults.load_eve = e.hasAttr(u_load_eve) ? e.attr<int>(u_load_eve) : 2; + c.data.defaults.show_evt = e.hasAttr(u_show_evt) ? e.attr<int>(u_show_evt) : 1; c.data.defaults.load_geo = e.hasAttr(u_load_geo) ? e.attr<int>(u_load_geo) : -1; c.data.defaults.color = e.hasAttr(_U(color)) ? e.attr<int>(_U(color)) : 0xBBBBBB; c.data.defaults.alpha = e.hasAttr(_U(alpha)) ? e.attr<float>(_U(alpha)) : -1.0; @@ -100,6 +102,12 @@ template <> void Converter<detelement>::operator()(xml_h e) const { extract(c,e,DisplayConfiguration::DETELEMENT); configs->push_back(c); } +template <> void Converter<panel>::operator()(xml_h e) const { + Configurations* configs = (Configurations*)param; + DisplayConfiguration::Config c; + extract(c,e,DisplayConfiguration::PANEL); + configs->push_back(c); +} template <> void Converter<calodata_configs>::operator()(xml_h e) const { Configurations* configs = (Configurations*)param; DisplayConfiguration::Config c; @@ -128,6 +136,7 @@ template <> void Converter<view>::operator()(xml_h e) const { c.name = e.attr<string>(_U(name)); printout(INFO,"DisplayConfiguration","+++ View: %s sensitive:%d structure:%d.", c.name.c_str(), c.show_sensitive, c.show_structure); + xml_coll_t(e,_Unicode(panel)).for_each(Converter<panel>(lcdd,&c.subdetectors)); xml_coll_t(e,_Unicode(detelement)).for_each(Converter<detelement>(lcdd,&c.subdetectors)); xml_coll_t(e,_Unicode(calodata)).for_each(Converter<calodata_configs>(lcdd,&c.subdetectors)); config->views.push_back(c); diff --git a/DDEve/src/EventControl.cpp b/DDEve/src/EventControl.cpp index 8f42b3bb0..5931b712e 100644 --- a/DDEve/src/EventControl.cpp +++ b/DDEve/src/EventControl.cpp @@ -74,9 +74,9 @@ bool EventControl::Open() { // pi- shots: //m_display->eventHandler().Open("/home/frankm/SW/DD4hep_head_dbg.root_v5.34.10/build/CLICSiD_2014-06-18_12-48.root"); - std::string fname = m_display->OpenRootFileDialog("."); + std::string fname = m_display->OpenEventFileDialog("."); if ( !fname.empty() ) { - return m_display->eventHandler().Open(fname); + return m_display->eventHandler().Open("",fname); } return false; } @@ -111,8 +111,12 @@ void EventControl::OnNewEvent(EventHandler* handler) { for(Types::const_iterator i=types.begin(); i!=types.end() && cnt+1<m_lines.size(); ++i) { const Collections& colls = (*i).second; Line line = m_lines[cnt++]; - string cl = (*i).first.substr((*i).first.find("Simple")); - cl = cl.substr(0,cl.find('*')); + string cl = (*i).first; + size_t idx = cl.find("Simple"); + if ( idx != string::npos ) { + cl = cl.substr(idx); + cl = cl.substr(0,cl.find('*')); + } line.second.first->SetTextColor(kRed); line.second.second->SetTextColor(kRed); line.second.first->SetText(("Coll.Type: "+cl).c_str()); diff --git a/DDEve/src/EventHandler.cpp b/DDEve/src/EventHandler.cpp index cc2da6495..44aa3d08b 100644 --- a/DDEve/src/EventHandler.cpp +++ b/DDEve/src/EventHandler.cpp @@ -21,29 +21,6 @@ EventHandler::EventHandler() : m_hasFile(false), m_hasEvent(false) { /// Default destructor EventHandler::~EventHandler() { - m_subscriptions.clear(); - ClearCache(); -} - -/// Clear all event related data caches -void EventHandler::ClearCache() { -} - -/// Notfy all subscribers -void EventHandler::NotifySubscribers(void (EventConsumer::*pmf)(EventHandler*)) { - for(Subscriptions::iterator i=m_subscriptions.begin(); i!=m_subscriptions.end();++i) - ((*i)->*pmf)(this); -} - -/// Subscribe to notification of new data present -void EventHandler::Subscribe(EventConsumer* consumer) { - m_subscriptions.insert(consumer); -} - -/// Unsubscribe from notification of new data present -void EventHandler::Unsubscribe(EventConsumer* consumer) { - Subscriptions::iterator i=m_subscriptions.find(consumer); - if ( i != m_subscriptions.end() ) m_subscriptions.erase(i); } /// Standard constructor diff --git a/DDEve/src/GenericEventHandler.cpp b/DDEve/src/GenericEventHandler.cpp new file mode 100644 index 000000000..06144788d --- /dev/null +++ b/DDEve/src/GenericEventHandler.cpp @@ -0,0 +1,161 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DDEve/GenericEventHandler.h" +#include "DD4hep/Primitives.h" +#include "DD4hep/Factories.h" +#include <stdexcept> + +/// ROOT include files +#include "TGMsgBox.h" +#include "TSystem.h" +#include <climits> + +using namespace std; +using namespace DD4hep; + +ClassImp(GenericEventHandler) + +/// Standard constructor +GenericEventHandler::GenericEventHandler() : m_current(0) { +} + +/// Default destructor +GenericEventHandler::~GenericEventHandler() { + m_subscriptions.clear(); + deletePtr(m_current); +} + +EventHandler* GenericEventHandler::current() const { + if ( m_current ) { + return m_current; + } + throw runtime_error("Invalid event handler"); +} + +/// Notfy all subscribers +void GenericEventHandler::NotifySubscribers(void (EventConsumer::*pmf)(EventHandler*)) { + for(Subscriptions::iterator i=m_subscriptions.begin(); i!=m_subscriptions.end();++i) + ((*i)->*pmf)(this); +} + +/// Subscribe to notification of new data present +void GenericEventHandler::Subscribe(EventConsumer* consumer) { + m_subscriptions.insert(consumer); +} + +/// Unsubscribe from notification of new data present +void GenericEventHandler::Unsubscribe(EventConsumer* consumer) { + Subscriptions::iterator i=m_subscriptions.find(consumer); + if ( i != m_subscriptions.end() ) m_subscriptions.erase(i); +} + +/// Access the number of events on the current input data source (-1 if no data source connected) +long GenericEventHandler::numEvents() const { + return current()->numEvents(); +} + +/// Access the data source name +std::string GenericEventHandler::datasourceName() const { + return current()->datasourceName(); +} + +/// Loop over collection and extract data +size_t GenericEventHandler::collectionLoop(const std::string& collection, DDEveHitActor& actor) { + if ( m_current && m_current->hasEvent() ) { + return m_current->collectionLoop(collection,actor); + } + return 0; +} + +/// Open a new event data file +bool GenericEventHandler::Open(const string& file_type, const string& file_name) { + typedef ROOT::Reflex::PluginService _P; + size_t idx = file_name.find("lcio"); + string err; + m_hasFile = false; + m_hasEvent = false; + try { + deletePtr(m_current); + if ( idx != string::npos ) { + m_current = (EventHandler*)_P::Create<void*>("DDEve_LCIOEventHandler",(const char*)0); + } + else if ( (idx=file_name.find("root")) != string::npos ) { + m_current = (EventHandler*)_P::Create<void*>("DDEve_DDG4EventHandler",(const char*)0); + } + if ( m_current ) { + if ( m_current->Open(file_type, file_name) ) { + m_hasFile = true; + NotifySubscribers(&EventConsumer::OnFileOpen); + return true; + } + err = "+++ Failed to open the data file:"+file_name; + deletePtr(m_current); + } + else { + err = "+++ Failed to create fikle reader for file '"+file_name+"' of type '"+file_type+"'"; + } + } + catch(const std::exception& e) { + err = "\nAn exception occurred \n" + "while opening event data:\n" + string(e.what()) + "\n\n"; + } + string path = TString::Format("%s/icons/stop_t.xpm", gSystem->Getenv("ROOTSYS")).Data(); + const TGPicture* pic = gClient->GetPicture(path.c_str()); + new TGMsgBox(gClient->GetRoot(),0,"Failed to open event data",err.c_str(),pic, + kMBDismiss,0,kVerticalFrame,kTextLeft|kTextCenterY); + return false; +} + +/// Load the next event +bool GenericEventHandler::NextEvent() { + m_hasEvent = false; + try { + if ( m_hasFile ) { + if ( current()->NextEvent() > 0 ) { + m_hasEvent = true; + NotifySubscribers(&EventConsumer::OnNewEvent); + return 1; + } + } + throw runtime_error("+++ EventHandler::readEvent: No file open!"); + } + catch(const std::exception& e) { + string path = TString::Format("%s/icons/stop_t.xpm", gSystem->Getenv("ROOTSYS")).Data(); + string err = "\nAn exception occurred \n" + "while reading a new event:\n" + string(e.what()) + "\n\n"; + const TGPicture* pic = gClient->GetPicture(path.c_str()); + new TGMsgBox(gClient->GetRoot(),0,"Failed to read event", err.c_str(),pic, + kMBDismiss,0,kVerticalFrame,kTextLeft|kTextCenterY); + } + return -1; +} + +/// User overloadable function: Load the previous event +bool GenericEventHandler::PreviousEvent() { + m_hasEvent = false; + if ( m_hasFile && current()->PreviousEvent() > 0 ) { + m_hasEvent = true; + NotifySubscribers(&EventConsumer::OnNewEvent); + return 1; + } + return -1; +} + +/// Goto a specified event in the file +bool GenericEventHandler::GotoEvent(long event_number) { + m_hasEvent = false; + if ( m_hasFile && current()->GotoEvent(event_number) > 0 ) { + m_hasEvent = true; + NotifySubscribers(&EventConsumer::OnNewEvent); + return 1; + } + return -1; +} diff --git a/DDEve/src/MultiView.cpp b/DDEve/src/MultiView.cpp new file mode 100644 index 000000000..59706b3d3 --- /dev/null +++ b/DDEve/src/MultiView.cpp @@ -0,0 +1,92 @@ +// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// Original Author: Matevz Tadel 2009 (MultiView.C) +// +//==================================================================== +// Framework include files +#include "DDEve/MultiView.h" +#include "DDEve/Factories.h" +#include "DDEve/ViewConfiguration.h" +#include "DD4hep/Plugins.h" + +#include <iostream> + +using namespace std; +using namespace DD4hep; + +ClassImp(MultiView) +DECLARE_VIEW_FACTORY(MultiView) + +/// Import Geometry data +static void _build(Display* display, View* v, TEveWindowSlot* slot) { + v->Build(slot); + display->RegisterEvents(v); + v->ConfigureGeometry(); + v->ConfigureEvent(); + v->Initialize(); +} + +/// Initializing constructor +MultiView::MultiView(Display* eve, const string& name) : View(eve, name) +{ +} + +/// Default destructor +MultiView::~MultiView() { +} + +/// Build the projection view and map it to the given slot +View& MultiView::Build(TEveWindow* slot) { + typedef DisplayConfiguration::Configurations _C; + typedef Display::ViewConfigurations _V; + TEveWindowSlot* new_slot; + View* v; + + // Viewers + TEveWindowPack *pack = ((TEveWindowSlot*)slot)->MakePack(); + pack->SetElementName(m_name.c_str()); + pack->SetHorizontal(); + pack->SetShowTitleBar(kFALSE); + + CreateScenes().Map(new_slot = pack->NewSlot()); + pack = pack->NewSlot()->MakePack(); + pack->SetShowTitleBar(kFALSE); + + _C panels; + const _V& view_cfg = m_eve->viewConfigurations(); + _V::const_iterator icfg = view_cfg.find(m_name); + if ( icfg != view_cfg.end() ) { + const _C& c = (*icfg).second.subdetectors; + for(_C::const_iterator i = c.begin(); i!=c.end();++i) { + if ( (*i).type == DisplayConfiguration::PANEL ) panels.push_back(*i); + } + } + /// First panel + if ( panels.size()>0) { + const DisplayConfiguration::Config& cfg = panels[0]; + string typ = "DD4hep__"+cfg.use; + v = PluginService::Create<View*>(typ.c_str(),m_eve,cfg.name.c_str()); + } + else { + v = PluginService::Create<View*>("DD4hep__RhoZProjection",m_eve,(m_name+" - RhoZ View").c_str()); + } + (new_slot = pack->NewSlot())->MakeCurrent(); + _build(m_eve,v,new_slot); + + /// Second panel + if ( panels.size()>1) { + const DisplayConfiguration::Config& cfg = panels[1]; + string typ = "DD4hep__"+cfg.use; + v = PluginService::Create<View*>(typ.c_str(),m_eve,cfg.name.c_str()); + } + else { + v = PluginService::Create<View*>("DD4hep__RhoPhiProjection",m_eve,(m_name+" - RPhi View").c_str()); + } + (new_slot = pack->NewSlot())->MakeCurrent(); + _build(m_eve,v,new_slot); + return *this; +} diff --git a/DDEve/src/Projection.cpp b/DDEve/src/Projection.cpp index 8e855ea22..d4ec4293b 100644 --- a/DDEve/src/Projection.cpp +++ b/DDEve/src/Projection.cpp @@ -37,8 +37,13 @@ void Projection::SetDepth(Float_t d) { m_projMgr->SetCurrentDepth(d); } +/// Call an element to a geometry element list +TEveElement* Projection::ImportGeoTopic(TEveElement*, TEveElementList*) { + return 0; +} + /// Call an element to a event element list -TEveElement* Projection::ImportElement(TEveElement* el, TEveElementList* list) { +TEveElement* Projection::ImportElement(TEveElement* el, TEveElementList* list) { TEveElementList* unprojected = &GetGeoTopic("Unprojected"); for(Topics::iterator i=m_geoTopics.begin(); i!=m_geoTopics.end(); ++i) { if ( el == unprojected ) { @@ -46,27 +51,31 @@ TEveElement* Projection::ImportElement(TEveElement* el, TEveElementList* list) return 0; } } - TEveElement* e = m_projMgr->ImportElements(el, m_geoScene); + TEveElement* e = m_projMgr->ImportElements(el, list); printout(INFO,"Projection","ImportElement %s [%s] into list: %s Projectable:%s [%p]", Utilities::GetName(el),el->IsA()->GetName(),list->GetName(), dynamic_cast<TEveProjectable*>(list) ? "true" : "false", e); unprojected->AddElement(el); - TEveElement::List_ci ci = std::find(m_projMgr->BeginChildren(),m_projMgr->EndChildren(),list); - if ( list != m_geoScene && ci == m_projMgr->EndChildren() ) { - m_projMgr->AddElement(list); - m_geoScene->AddElement(list); - } - if ( e ) { - if ( list != m_geoScene ) { - list->AddElement(e); + if ( list != m_geoScene && list != m_eveScene ) { + TEveElement::List_ci ci = std::find(m_geoScene->BeginChildren(),m_geoScene->EndChildren(),list); + if ( ci == m_geoScene->EndChildren() ) { + m_geoScene->AddElement(list); } - m_projMgr->RemoveElement(e); - m_geoScene->RemoveElement(e); } return e; } +/// Call an element to a geometry element list +TEveElement* Projection::ImportGeoElement(TEveElement* element, TEveElementList* list) { + return element ? ImportElement(element, list) : 0; +} + +/// Call an element to a event element list +TEveElement* Projection::ImportEventElement(TEveElement* element, TEveElementList* list) { + return element ? ImportElement(element, list) : 0; +} + /// Add axis to the projection view Projection& Projection::AddAxis() { TEveProjectionAxes* a = new TEveProjectionAxes(m_projMgr); diff --git a/DDEve/src/View.cpp b/DDEve/src/View.cpp index 8e1f52052..5a9b9a62b 100644 --- a/DDEve/src/View.cpp +++ b/DDEve/src/View.cpp @@ -11,14 +11,14 @@ #include "DDEve/View.h" #include "DDEve/Display.h" #include "DDEve/ElementList.h" -#include "DDEve/EventHandler.h" #include "DDEve/Utilities.h" +#include "DDEve/Annotation.h" #include "DD4hep/InstanceCount.h" // Eve include files #include <TEveManager.h> -#include <TEveBrowser.h> #include <TEveWindow.h> +#include <TEveCalo.h> #include <TGLViewer.h> using namespace std; @@ -31,11 +31,11 @@ static inline typename T::const_iterator find(const T& c,const string& s) { return c.end(); } - /// Initializing constructor View::View(Display* eve, const string& name) - : m_eve(eve), m_view(0), m_geoScene(0), m_eveScene(0), m_global(0), m_name(name) + : m_eve(eve), m_view(0), m_geoScene(0), m_eveScene(0), m_global(0), m_name(name), m_showGlobal(false) { + m_config = m_eve->GetViewConfiguration(m_name); InstanceCount::increment(this); } @@ -55,20 +55,57 @@ View& View::Build(TEveWindow* /* slot */) { return *this; } +/// Initialize the view port +void View::Initialize() { + TEveScene *evt = this->eveScene(); + TEveScene *geo = this->geoScene(); + if ( evt ) evt->Repaint(kTRUE); + if ( geo ) geo->Repaint(kTRUE); + /// Update color set + TGLViewer* glv = viewer()->GetGLViewer(); + glv->PostSceneBuildSetup(kTRUE); + glv->SetSmartRefresh(kFALSE); + if ( m_eve->manager().GetViewers()->UseLightColorSet() ) + glv->UseLightColorSet(); + else + glv->UseDarkColorSet(); + glv->RequestDraw(TGLRnrCtx::kLODHigh); + glv->SetSmartRefresh(kTRUE); +} + /// Add the view to the global list of eve objects TEveElementList* View::AddToGlobalItems(const string& nam) { if ( 0 == m_global ) { m_global = new ElementList(nam.c_str(), nam.c_str(), true, true); if ( m_geoScene ) m_global->AddElement(geoScene()); if ( m_eveScene ) m_global->AddElement(eveScene()); - m_eve->manager().AddToListTree(m_global,kFALSE); + if ( m_showGlobal ) m_eve->manager().AddToListTree(m_global,kFALSE); } return m_global; } /// Call an element to a event element list -TEveElement* View::ImportElement(TEveElement* el, TEveElementList* list) { - list->AddElement(el); +TEveElement* View::ImportGeoElement(TEveElement* el, TEveElementList* list) { + TEveScene* s = dynamic_cast<TEveScene*>(el); + if ( s ) { + printf("ERROR: Adding a Scene [%s] to a list. This is BAD and causes crashes!\n",s->GetName()); + } + if ( el ) list->AddElement(el); + return el; +} + +/// Call an element to a geometry element list +TEveElement* View::ImportGeoTopic(TEveElement* element, TEveElementList* list) { + return ImportGeoElement(element, list); +} + +/// Call an element to a event element list +TEveElement* View::ImportEventElement(TEveElement* el, TEveElementList* list) { + TEveScene* s = dynamic_cast<TEveScene*>(el); + if ( s ) { + printf("ERROR: Adding a Scene [%s] to a list. This is BAD and causes crashes!\n",s->GetName()); + } + if ( el ) list->AddElement(el); return el; } @@ -89,28 +126,65 @@ View::CreateGeometry(DetElement de, const DisplayConfiguration::Config& cfg) { return Utilities::LoadDetElement(de,cfg.data.defaults.load_geo,&topic); } +/// Configure a view using the view's name and a proper ViewConfiguration if present +void View::ConfigureGeometry() { + printout(INFO,"View","+++ Configure Geometry for view %s Config=%p.",c_name(),m_config); + (m_config) ? ConfigureGeometry(*m_config) : ConfigureGeometryFromGlobal(); + ImportGeoTopics(name()); +} + +/// Configure a single geometry view by default from the global geometry scene +void View::ConfigureGeometryFromGlobal() { + TEveElementList* l = &m_eve->GetGeoTopic("Sensitive"); + TEveElementList* t = &GetGeoTopic("Sensitive"); + for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) + ImportGeo(*t,*i); + + l = &m_eve->GetGeoTopic("Structure"); + t = &GetGeoTopic("Structure"); + for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) + ImportGeo(*t,*i); +} + /// Configure a single geometry view void View::ConfigureGeometry(const DisplayConfiguration::ViewConfig& config) { string dets; + DisplayConfiguration::Configurations::const_iterator ic; + float legend_y = Annotation::DefaultTextSize()+Annotation::DefaultMargin(); const DetElement::Children& c = m_eve->lcdd().world().children(); - for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) { - DetElement de = (*i).second; - SensitiveDetector sd = m_eve->lcdd().sensitiveDetector(de.name()); - if ( (sd.isValid() && config.show_sensitive) || (!sd.isValid() && config.show_structure) ) { - DisplayConfiguration::Configurations::const_iterator i = find(config.subdetectors,de.name()); - if ( i != config.subdetectors.end() ) { + for( ic=config.subdetectors.begin(); ic != config.subdetectors.end(); ++ic) { + const DisplayConfiguration::Config& cfg = *ic; + string nam = cfg.name; + if ( nam == "global" ) { + m_view->AddScene(m_eve->manager().GetGlobalScene()); + m_view->AddScene(m_eve->manager().GetEventScene()); + dets += nam; + } + else if ( cfg.type == DisplayConfiguration::CALODATA ) { + // Note: The histogram grid must be handled like a geometry item. + const Display::CalodataContext& ctx = m_eve->GetCaloHistogram(nam); + if ( ctx.config.use.empty() ) ImportGeo(ctx.calo3D); + printout(INFO,"View","+++ %s: add detector %s %s",name().c_str(),nam.c_str(),ctx.config.use.c_str()); + Color_t col = ctx.calo3D->GetDataSliceColor(ctx.slice); + Annotation* a = new Annotation(viewer(),nam.c_str(),Annotation::DefaultMargin(),legend_y,col); + legend_y += a->GetTextSize(); + dets += nam + "(Calo3D) "; + } + else if ( cfg.type == DisplayConfiguration::DETELEMENT ) { + DetElement::Children::const_iterator i = c.find(nam); + if ( i != c.end() ) { + DetElement de = (*i).second; + SensitiveDetector sd = m_eve->lcdd().sensitiveDetector(nam); TEveElementList& topic = GetGeoTopic(sd.isValid() ? "Sensitive" : "Structure"); - const DisplayConfiguration::Config& cfg = *i; pair<bool,TEveElement*> e(false,0); if ( cfg.data.defaults.load_geo > 0 ) // Create a new instance e = CreateGeometry(de,cfg); // with the given number of levels else if ( cfg.data.defaults.load_geo < 0 ) // Use the global geometry instance e = GetGlobalGeometry(de,cfg); // with the given number of levels if ( e.first && e.second ) { - dets += de.name(); - dets += " "; ImportGeo(topic,e.second); } + dets += nam + "(Geo) "; } } } @@ -123,87 +197,81 @@ void View::ImportGeoTopics(const string& title) { printout(INFO,"View","+++ %s: Import geometry topics.",c_name()); for(Topics::iterator i=m_geoTopics.begin(); i!=m_geoTopics.end(); ++i) { printout(INFO,"ViewConfiguration","+++ Add topic %s",(*i).second->GetName()); - ImportElement((*i).second,m_geoScene); + ImportGeoTopic((*i).second,m_geoScene); } if ( !title.empty() ) AddToGlobalItems(title); } /// Call to import geometry elements by topic void View::ImportGeo(const string& topic, TEveElement* element) { - ImportElement(element,&GetGeoTopic(topic)); + ImportGeoElement(element,&GetGeoTopic(topic)); } /// Call to import geometry elements into topics void View::ImportGeo(TEveElementList& topic, TEveElement* element) { - ImportElement(element,&topic); + ImportGeoElement(element,&topic); } /// Call to import geometry elements void View::ImportGeo(TEveElement* el) { - ImportElement(el, m_geoScene); + ImportGeoElement(el, m_geoScene); } -/// Call to destroy all event elements -void View::DestroyGeo() { - m_geoScene->DestroyElements(); +/// Configure the adding of event data +void View::ConfigureEvent() { + printout(INFO,"View","+++ Import event data into view %s Config=%p.",c_name(),m_config); + (m_config) ? ConfigureEvent(*m_config) : ConfigureEventFromGlobal(); + ImportEventTopics(); } +/// Configure an event view by default from the global event scene +void View::ConfigureEventFromGlobal() { + TEveElementList* l = m_eve->manager().GetEventScene(); + for(TEveElementList::List_i i=l->BeginChildren(); i!=l->EndChildren(); ++i) + ImportEvent(*i); +} /// Configure a single view void View::ConfigureEvent(const DisplayConfiguration::ViewConfig& config) { - LCDD& lcdd = m_eve->lcdd(); - DetElement world = lcdd.world(); - EventHandler& handler = m_eve->eventHandler(); + DetElement world = m_eve->lcdd().world(); const DetElement::Children& c = world.children(); - - printout(INFO,"View","+++ Configure event for view %s.",c_name()); - for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) { - DetElement de = (*i).second; - SensitiveDetector sd = lcdd.sensitiveDetector(de.name()); - if ( sd.isValid() ) { - DisplayConfiguration::Configurations::const_iterator i=find(config.subdetectors,de.name()); - if ( i != config.subdetectors.end() ) { - ImportEvent(handler, de, sd, config); + DisplayConfiguration::Configurations::const_iterator ic; + for( ic=config.subdetectors.begin(); ic != config.subdetectors.end(); ++ic) { + const DisplayConfiguration::Config& cfg = *ic; + string nam = cfg.name; + if ( nam == "global" ) { + continue; + } + else if ( cfg.type == DisplayConfiguration::CALODATA ) { + continue; + } + else if ( cfg.type == DisplayConfiguration::DETELEMENT ) { + // Not using the global scene! + DetElement::Children::const_iterator i = c.find(nam); + if ( i != c.end() && cfg.data.defaults.show_evt>0 ) { + SensitiveDetector sd = m_eve->lcdd().sensitiveDetector(nam); + if ( sd.isValid() ) { + // This should be configurable! + const char* coll = sd.readout().name(); + TEveElement* child = m_eve->manager().GetEventScene()->FindChild(coll); + printout(INFO,"View","+++ Add detector event %s collection:%s data:%p scene:%p", + nam.c_str(),coll,child,m_eveScene); + if ( child ) { + ImportEvent(child); + } + } } } } } -/// Import event data from event handler for a given subdetector -void View::ImportEvent(EventHandler& /* hdlr */, - DetElement de, - SensitiveDetector sd, - const DisplayConfiguration::ViewConfig& /* config */) -{ - /// - /// By default we reuse the "global" event. We do not want to recreate the data - /// unless really necessary.... - /// - const char* coll = sd.readout().name(); - TEveElement* child = m_eve->GetEve().FindChild(coll); - printout(INFO,"View","+++ Add detector event %s collection:%s data:%p", - de.name(), coll, child); - if ( child ) { - ImportEvent(child); - } -} - /// Import event typics after creation void View::ImportEventTopics() { } /// Call to import event elements into the main event scene void View::ImportEvent(TEveElement* el) { - ImportElement(el, m_eveScene); -} - -/// Call to destroy all event elements -void View::DestroyEvent() { - m_eveScene->DestroyElements(); -} - -/// Prepare the view before loading new event data -void View::PrepareEvent() { + if ( m_eveScene ) ImportEventElement(el, m_eveScene); } /// Access/Create a topic by name @@ -217,24 +285,6 @@ TEveElementList& View::GetGeoTopic(const string& name) { return *((*i).second); } -#if 0 -/// Access/Create a topic by name -TEveElementList& View::GetEveTopic(const string& name) { - Topics::iterator i=m_eveTopics.find(name); - if ( i == m_eveTopics.end() ) { - TEveElementList* topic = new TEveElementList(name.c_str(), name.c_str(), true, true); - m_eveTopics[name] = topic; - return *topic; - } - return *((*i).second); -} - -/// Call to import event elements by topic -void View::ImportEvent(const string& topic, TEveElement* el) { - GetEveTopic(topic).AddElement(el); -} -#endif - /// Create the geometry and the event scene View& View::CreateScenes() { // Scenes diff --git a/DDEve/src/ViewConfiguration.cpp b/DDEve/src/ViewConfiguration.cpp deleted file mode 100644 index 8a0c73015..000000000 --- a/DDEve/src/ViewConfiguration.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $ -//==================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------- -// -// Author : M.Frank -// -//==================================================================== - -// Framework include files -#include "DDEve/ViewConfiguration.h" -#include "DDEve/View.h" -#include "DD4hep/Printout.h" - -// C/C++ include files -#include <stdexcept> - -using namespace DD4hep; - -ClassImp(ViewConfiguration) - -static inline View* checkedView(View* view) { - if ( !view ) { - throw std::runtime_error("Invalid View!"); - } - return view; -} - -/// Standard constructor -ViewConfiguration::ViewConfiguration() : config(), m_display(0) { -} - -/// Initializing constructor -ViewConfiguration::ViewConfiguration(Display* disp, const DisplayConfiguration::ViewConfig& cfg) - : config(cfg), m_display(disp) -{ -} - -/// Default destructor -ViewConfiguration::~ViewConfiguration() { -} - -/// Configure a single view -void ViewConfiguration::ConfigureGeometry(View* view) const { - checkedView(view)->ConfigureGeometry(config); -} - -/// Configure a single view -void ViewConfiguration::ConfigureEvent(View* view) const { - checkedView(view)->ConfigureEvent(config); -} - -/// Prepare the view for adding event data -void ViewConfiguration::PrepareEvent(View* view) const { - checkedView(view)->PrepareEvent(); -} diff --git a/DDEve/src/ViewMenu.cpp b/DDEve/src/ViewMenu.cpp index bea005f51..760d4b96a 100644 --- a/DDEve/src/ViewMenu.cpp +++ b/DDEve/src/ViewMenu.cpp @@ -57,46 +57,38 @@ void ViewMenu::Build(TGMenuBar* bar, int hints) { menu->AddEntry("Rho-&Phi Projection",this, &ViewMenu::CreateView, p=new pair<string,string>("DD4hep__RhoPhiProjection","Rho-Phi")); const Display::ViewConfigurations& vc = m_display->viewConfigurations(); for(Display::ViewConfigurations::const_iterator i=vc.begin(); i!=vc.end(); ++i) { - ViewConfiguration* v = (*i).second; - menu->AddEntry(v->name().c_str(), this, &ViewMenu::CreateGenericView, v); + const Display::ViewConfig& v = (*i).second; + menu->AddEntry(v.name.c_str(), this, &ViewMenu::CreateView,p=new pair<string,string>("DD4hep__"+v.type,v.name)); } bar->AddPopup(m_title.c_str(),*menu, new TGLayoutHints(hints, 0, 4, 0, 0)); } -/// Create a new 3D view -void ViewMenu::CreateGenericView(TGMenuEntry*, void* ud) { - ViewConfiguration* c = (ViewConfiguration*)ud; - string typ = "DD4hep__"+c->type(); - View* v = PluginService::Create<View*>(typ.c_str(),m_display,c->name().c_str()); - if ( v ) BuildView(v); -} - /// Create a new generic view void ViewMenu::CreateView(TGMenuEntry*, void* ud) { pair<string,string>* args = (pair<string,string>*)ud; - View* v = PluginService::Create<View*>(args->first.c_str(),m_display,args->second.c_str()); + CreateView(args->first,args->second); +} + +View* ViewMenu::CreateView(const std::string& type, const std::string& title) { + pair<string,string> args("DD4hep__"+type,title); + View* v = PluginService::Create<View*>(type.c_str(),m_display,title.c_str()); BuildView(v); + return v; } /// Create a new 3D view View* ViewMenu::CreateView3D(const std::string& title) { - View* v = PluginService::Create<View*>("DD4hep__View3D",m_display,title.c_str()); - BuildView(v); - return v; + return CreateView("DD4hep__View3D",title.c_str()); } /// Create a new R-Z view View* ViewMenu::CreateRhoZProjection(const std::string& title ) { - View* v = PluginService::Create<View*>("DD4hep__RhoZProjection",m_display,title.c_str()); - BuildView(v); - return v; + return CreateView("DD4hep__RhoZProjection",title.c_str()); } /// Create a new R-Phi view View* ViewMenu::CreateRhoPhiProjection(const std::string& title ) { - View* v = PluginService::Create<View*>("DD4hep__RhoPhiProjection",m_display,title.c_str()); - BuildView(v); - return v; + return CreateView("DD4hep__RhoPhiProjection",title.c_str()); } /// Import Geometry data @@ -105,26 +97,10 @@ void ViewMenu::BuildView(View* v) const { TEveBrowser *browser = m.GetBrowser(); TGTab *right = browser->GetTabRight(); TEveWindowSlot *slot = TEveWindow::CreateWindowInTab(right); - TEveScene *evt=0, *geo=0; v->Build(slot); m_display->RegisterEvents(v); - m_display->ConfigureGeometry(v); - m_display->PrepareEvent(v); - m_display->ConfigureEvent(v); - evt = v->eveScene(); - geo = v->geoScene(); - if ( evt ) evt->Repaint(kTRUE); - if ( geo ) geo->Repaint(kTRUE); - /// Update color set - TGLViewer* glv = v->viewer()->GetGLViewer(); - glv->PostSceneBuildSetup(kTRUE); - glv->SetSmartRefresh(kFALSE); - if ( m.GetViewers()->UseLightColorSet() ) - glv->UseLightColorSet(); - else - glv->UseDarkColorSet(); - glv->RequestDraw(TGLRnrCtx::kLODHigh); - glv->SetSmartRefresh(kTRUE); + v->ConfigureGeometry(); + v->ConfigureEvent(); + v->Initialize(); right->SetTab(right->GetNumberOfTabs()-1); } - -- GitLab