From 0420320c1a35fb627db4e78714f208163d2025a0 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Mon, 28 May 2018 16:46:59 +0200 Subject: [PATCH] Improve selective handling of subdetectors in DDDB --- DDCore/include/DD4hep/DD4hepUI.h | 27 +++++++- DDCore/include/DD4hep/Volumes.h | 4 +- DDCore/src/DD4hepRootPersistency.cpp | 58 ++++++++++------- DDCore/src/DD4hepUI.cpp | 64 ++++++++++++++++++- DDCore/src/plugins/StandardPlugins.cpp | 40 ++++++++++-- UtilityApps/src/plugin_runner.cpp | 2 +- .../DDDB/include/DDDB/DDDBConditionsLoader.h | 4 +- examples/DDDB/include/DDDB/DDDBConversion.h | 5 ++ examples/DDDB/include/DDDB/DDDBDimension.h | 1 + examples/DDDB/include/DDDB/DDDBHelper.h | 2 +- examples/DDDB/include/DDDB/DDDBReader.h | 2 +- 11 files changed, 167 insertions(+), 42 deletions(-) diff --git a/DDCore/include/DD4hep/DD4hepUI.h b/DDCore/include/DD4hep/DD4hepUI.h index 3517dcef9..7bd6e19c5 100644 --- a/DDCore/include/DD4hep/DD4hepUI.h +++ b/DDCore/include/DD4hep/DD4hepUI.h @@ -36,7 +36,9 @@ namespace dd4hep { Detector& m_detDesc; Handle<NamedObject> m_condMgr; Handle<NamedObject> m_alignMgr; - + /// Default visualiztion level + int visLevel = 4; + public: /// Default constructor DD4hepUI(Detector& instance); @@ -48,12 +50,20 @@ namespace dd4hep { Detector* detectorDescription() const; /// Set the printout level from the interactive prompt PrintLevel setPrintLevel(PrintLevel level) const; + /// Set the visualization level when invoking the display + int setVisLevel(int level); /// Install the dd4hep conditions manager object Handle<NamedObject> conditionsMgr() const; /// Load conditions from file long loadConditions(const std::string& fname) const; - + + /// Dump the entire detector description object to a root file + long saveROOT(const char* file_name) const; + + /// Import the entire detector description object from a root file + long importROOT(const char* file_name) const; + /// Install the dd4hep alignment manager object Handle<NamedObject> alignmentMgr() const; @@ -66,12 +76,23 @@ namespace dd4hep { virtual long apply(const char* factory, int argc, char** argv) const; /// Detector interface: Read any geometry description or alignment file virtual void fromXML(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT) const; + + /// Detector interface: Draw the scene on a OpenGL pane + virtual void draw() const; /// Detector interface: Re-draw the entire scene virtual void redraw() const; + + /// Detector interface: Draw detector sub-tree the scene on a OpenGL pane + virtual void drawSubtree(const char* path) const; + /// Detector interface: Re-draw the entire sub-tree scene + virtual void redrawSubtree(const char* path) const; + /// Dump the volume tree virtual long dumpVols(int argc=0, char** argv=0) const; - /// Dump the DetElement tree + /// Dump the DetElement tree with placement volumes virtual long dumpDet() const; + /// Dump the raw DetElement tree + virtual long dumpStructure() const; }; } diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 6f730b9fa..64cd3c064 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -126,7 +126,7 @@ namespace dd4hep { /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore virtual void Release() const override; /// Enable ROOT persistency - ClassDefOverride(PlacedVolumeExtension,1); + ClassDefOverride(PlacedVolumeExtension,200); }; /// Handle class holding a placed volume (also called physical volume) @@ -235,7 +235,7 @@ namespace dd4hep { /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore virtual void Release() const override; /// Enable ROOT persistency - ClassDefOverride(VolumeExtension,1); + ClassDefOverride(VolumeExtension,200); }; /// Handle class holding a placed volume (also called physical volume) diff --git a/DDCore/src/DD4hepRootPersistency.cpp b/DDCore/src/DD4hepRootPersistency.cpp index eddc3ba2e..2c8f6ed04 100644 --- a/DDCore/src/DD4hepRootPersistency.cpp +++ b/DDCore/src/DD4hepRootPersistency.cpp @@ -43,13 +43,20 @@ int DD4hepRootPersistency::save(Detector& description, const char* fname, const persist->m_segments[ro].second = ro.segmentation().segmentation(); } } - for( const auto& mgr : persist->m_data->m_volManager->managers ) { - for( const auto& v : mgr.second->volumes ) { - persist->nominals[v.second->element] = v.second->element.nominal(); + if ( persist->volumeManager().isValid() ) { + for( const auto& mgr : persist->m_data->m_volManager->managers ) { + for( const auto& v : mgr.second->volumes ) { + persist->nominals[v.second->element] = v.second->element.nominal(); + } } + printout(ALWAYS,"DD4hepRootPersistency","+++ Saving %ld nominals....",persist->nominals.size()); } - printout(ALWAYS,"DD4hepRootPersistency","+++ Saving %ld nominals....",persist->nominals.size()); - + else { + printout(ALWAYS, + "DD4hepRootPersistency","+++ No valid Volume manager. No nominals saved.", + persist->nominals.size()); + } + /// Now we write the object int nBytes = persist->Write(instance); f->Close(); @@ -95,28 +102,33 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const printout(ALWAYS,"DD4hepRootPersistency", "+++ Fixed %ld segmentation objects.",persist->m_segments.size()); persist->m_segments.clear(); - const auto& sdets = persist->volumeManager()->subdetectors; - size_t num[3] = {0,0,0}; - for( const auto& vm : sdets ) { - VolumeManager::Object* obj = vm.second.ptr(); - obj->system = obj->id.field("system"); - if ( 0 != obj->system ) { + if ( persist->volumeManager().isValid() ) { + const auto& sdets = persist->volumeManager()->subdetectors; + size_t num[3] = {0,0,0}; + for( const auto& vm : sdets ) { + VolumeManager::Object* obj = vm.second.ptr(); + obj->system = obj->id.field("system"); + if ( 0 != obj->system ) { + printout(ALWAYS,"DD4hepRootPersistency", + "+++ Fixed VolumeManager.system for %-24s %6ld volumes %4ld sdets %4ld mgrs.", + obj->detector.path().c_str(), obj->volumes.size(), + obj->subdetectors.size(), obj->managers.size()); + num[0] += obj->volumes.size(); + num[1] += obj->subdetectors.size(); + num[2] += obj->managers.size(); + continue; + } printout(ALWAYS,"DD4hepRootPersistency", - "+++ Fixed VolumeManager.system for %-24s %6ld volumes %4ld sdets %4ld mgrs.", - obj->detector.path().c_str(), obj->volumes.size(), - obj->subdetectors.size(), obj->managers.size()); - num[0] += obj->volumes.size(); - num[1] += obj->subdetectors.size(); - num[2] += obj->managers.size(); - continue; + "+++ FAILED to fix VolumeManager.system for '%s: %s'.", + obj->detector.path().c_str(), "[No IDDescriptor field 'system']"); } printout(ALWAYS,"DD4hepRootPersistency", - "+++ FAILED to fix VolumeManager.system for '%s: %s'.", - obj->detector.path().c_str(), "[No IDDescriptor field 'system']"); + "+++ Fixed VolumeManager TOTALS %-24s %6ld volumes %4ld sdets %4ld mgrs.","",num[0],num[1],num[2]); + printout(ALWAYS,"DD4hepRootPersistency","+++ loaded %ld nominals....",persist->nominals.size()); + } + else { + printout(ALWAYS,"DD4hepRootPersistency","+++ Volume manager NOT restored. [Was it ever up when saved?]"); } - printout(ALWAYS,"DD4hepRootPersistency", - "+++ Fixed VolumeManager TOTALS %-24s %6ld volumes %4ld sdets %4ld mgrs.","",num[0],num[1],num[2]); - printout(ALWAYS,"DD4hepRootPersistency","+++ loaded %ld nominals....",persist->nominals.size()); DetectorData* tar_data = dynamic_cast<DetectorData*>(&description); DetectorData* src_data = dynamic_cast<DetectorData*>(source); if( tar_data != nullptr && src_data != nullptr ){ diff --git a/DDCore/src/DD4hepUI.cpp b/DDCore/src/DD4hepUI.cpp index 3ab5eb7b7..e42e9a6da 100644 --- a/DDCore/src/DD4hepUI.cpp +++ b/DDCore/src/DD4hepUI.cpp @@ -20,6 +20,14 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::detail; +namespace { + string _visLevel(int lvl) { + char text[32]; + ::snprintf(text,sizeof(text),"%d",lvl); + return text; + } +} + /// Default constructor DD4hepUI::DD4hepUI(Detector& instance) : m_detDesc(instance) { } @@ -43,6 +51,13 @@ PrintLevel DD4hepUI::setPrintLevel(PrintLevel level) const { return dd4hep::setPrintLevel(level); } +/// Set the visualization level when invoking the display +int DD4hepUI::setVisLevel(int value) { + int old_value = visLevel; + visLevel = value; + return old_value; +} + /// Install the dd4hep conditions manager object Handle<NamedObject> DD4hepUI::conditionsMgr() const { if ( !m_condMgr.isValid() ) { @@ -83,7 +98,7 @@ Handle<NamedObject> DD4hepUI::alignmentMgr() const { /// Detector interface: Manipulate geometry using facroy converter long DD4hepUI::apply(const char* factory, int argc, char** argv) const { - return m_detDesc.apply(factory,argc,argv); + return m_detDesc.apply(factory, argc, argv); } /// Detector interface: Read any geometry description or alignment file @@ -91,9 +106,26 @@ void DD4hepUI::fromXML(const std::string& fname, DetectorBuildType type) const return m_detDesc.fromXML(fname, type); } +/// Detector interface: Draw the scene on a OpenGL pane +void DD4hepUI::draw() const { + drawSubtree("/world"); +} + /// Detector interface: Re-draw the entire scene void DD4hepUI::redraw() const { - m_detDesc.worldVolume()->Draw("oglsame"); + redrawSubtree("/world"); +} + +/// Detector interface: Draw detector sub-tree the scene on a OpenGL pane +void DD4hepUI::drawSubtree(const char* path) const { + const void* av[] = {"-detector", path, "-option", "ogl", "-level", _visLevel(visLevel).c_str(), 0}; + m_detDesc.apply("DD4hep_GeometryDisplay", 2, (char**)av); +} + +/// Detector interface: Re-draw the entire sub-tree scene +void DD4hepUI::redrawSubtree(const char* path) const { + const void* av[] = {"-detector", path, "-option", "oglsame", "-level", _visLevel(visLevel).c_str(), 0}; + m_detDesc.apply("DD4hep_GeometryDisplay", 4, (char**)av); } /// Dump the volume tree @@ -105,11 +137,36 @@ long DD4hepUI::dumpVols(int argc, char** argv) const { return m_detDesc.apply("DD4hep_VolumeDump",argc,argv); } -/// Dump the DetElement tree +/// Dump the DetElement tree with placements long DD4hepUI::dumpDet() const { return m_detDesc.apply("DD4hep_DetectorVolumeDump",0,0); } +/// Dump the DetElement tree with placements +long DD4hepUI::dumpStructure() const { + return m_detDesc.apply("DD4hep_DetectorDump",0,0); +} + +/// Dump the entire detector description object to a root file +long DD4hepUI::saveROOT(const char* file_name) const { + if ( file_name ) { + const void* av[] = {"-output",file_name,0}; + return m_detDesc.apply("DD4hep_Geometry2ROOT",2,(char**)av); + } + printout(WARNING,"DD4hepUI","++ saveROOT: No valid output file name supplied"); + return 0; +} + +/// Import the entire detector description object from a root file +long DD4hepUI::importROOT(const char* file_name) const { + if ( file_name ) { + const void* av[] = {"-input",file_name,0}; + return m_detDesc.apply("DD4hep_RootLoader",2,(char**)av); + } + printout(WARNING,"DD4hepUI","++ importROOT: No valid output file name supplied"); + return 0; +} + /// Create ROOT interpreter instance long DD4hepUI::createInterpreter(int argc, char** argv) { if ( 0 == gApplication ) { @@ -135,3 +192,4 @@ long DD4hepUI::runInterpreter() const { except("DD4hepUI","++ No ROOT interpreter instance present!"); return 0; } + diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index 0f45963a8..132341f03 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -117,6 +117,7 @@ DECLARE_CONSTRUCTOR(Detector_constructor,create_description_instance) static long display(Detector& description, int argc, char** argv) { TGeoManager& mgr = description.manager(); int vislevel = 4, visopt = 1; + string detector = "/world"; const char* opt = "ogl"; for(int i = 0; i < argc && argv[i]; ++i) { if ( 0 == ::strncmp("-option",argv[i],4) ) @@ -125,12 +126,15 @@ static long display(Detector& description, int argc, char** argv) { vislevel = ::atol(argv[++i]); else if ( 0 == ::strncmp("-visopt",argv[i],4) ) visopt = ::atol(argv[++i]); + else if ( 0 == ::strncmp("-detector",argv[i],4) ) + detector = argv[++i]; else { cout << - "Usage: -plugin <name> -arg [-arg] \n" - " -option <string> ROOT Draw option. Default: 'ogl' \n" - " -level <number> Visualization level [TGeoManager::SetVisLevel] Default: 4 \n" - " -visopt <number> Visualization option [TGeoManager::SetVisOption] Default: 1 \n" + "Usage: -plugin <name> -arg [-arg] \n" + " -detector <string> Top level DetElement path. Default: '/world' \n" + " -option <string> ROOT Draw option. Default: 'ogl' \n" + " -level <number> Visualization level [TGeoManager::SetVisLevel] Default: 4 \n" + " -visopt <number> Visualization option [TGeoManager::SetVisOption] Default: 1 \n" "\tArguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); } @@ -138,7 +142,17 @@ static long display(Detector& description, int argc, char** argv) { mgr.SetVisLevel(vislevel); mgr.SetVisOption(visopt); TGeoVolume* vol = mgr.GetTopVolume(); - if (vol) { + if ( detector != "/world" ) { + DetElement elt = detail::tools::findElement(description,detector); + if ( !elt.isValid() ) { + except("DD4hep_GeometryDisplay","+++ Invalid DetElement path: %s",detector.c_str()); + } + if ( !elt.placement().isValid() ) { + except("DD4hep_GeometryDisplay","+++ Invalid DetElement placement: %s",detector.c_str()); + } + vol = elt.placement().volume(); + } + if ( vol ) { vol->Draw(opt); return 1; } @@ -232,6 +246,8 @@ DECLARE_APPLY(DD4hep_Rint,run_interpreter) */ static long root_ui(Detector& description, int /* argc */, char** /* argv */) { char cmd[256]; + //DD4hepUI* ui = new DD4hepUI(description); + //::snprintf(cmd,sizeof(cmd),"dd4hep::detail::DD4hepUI* gDD4hepUI = (dd4hep::detail::DD4hepUI*)%p;",(void*)ui); ::snprintf(cmd,sizeof(cmd), "dd4hep::detail::DD4hepUI* gDD4hepUI = new " "dd4hep::detail::DD4hepUI(*(dd4hep::Detector*)%p);", @@ -643,7 +659,19 @@ DECLARE_APPLY(DD4hep_Geometry2ROOT,dump_geometry2root) */ static long load_geometryFromroot(Detector& description, int argc, char** argv) { if ( argc > 0 ) { - string input = argv[0]; + string input = argv[0]; // <-- for backwards compatibility + for(int i = 0; i < argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + } + if ( input.empty() ) { + cout << + "Usage: DD4hep_RootLoader -arg [-arg] \n" + " name: factory name DD4hepGeometry2ROOT \n" + " -input <string> Input file name. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } printout(INFO,"DD4hepRootLoader","+++ Read geometry from root file:%s",input.c_str()); if ( 1 == DD4hepRootPersistency::load(description,input.c_str(),"Geometry") ) { return 1; diff --git a/UtilityApps/src/plugin_runner.cpp b/UtilityApps/src/plugin_runner.cpp index 07efbe5f1..99adfd167 100644 --- a/UtilityApps/src/plugin_runner.cpp +++ b/UtilityApps/src/plugin_runner.cpp @@ -48,7 +48,7 @@ namespace { usage(); } } - if ( arguments.plugins.empty() ) { + if ( !arguments.ui && !arguments.interpreter && arguments.plugins.empty() ) { usage(); } unique_ptr<TRint> interpreter; diff --git a/examples/DDDB/include/DDDB/DDDBConditionsLoader.h b/examples/DDDB/include/DDDB/DDDBConditionsLoader.h index ab6ac287a..cca8c8900 100644 --- a/examples/DDDB/include/DDDB/DDDBConditionsLoader.h +++ b/examples/DDDB/include/DDDB/DDDBConditionsLoader.h @@ -38,7 +38,7 @@ namespace dd4hep { /** * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_CONDITIONS + * \ingroup DD4HEP_DDDB */ class DDDBConditionsLoader : public cond::ConditionsDataLoader { typedef std::pair<std::string, std::string> Key; @@ -46,7 +46,7 @@ namespace dd4hep { /** * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_CONDITIONS + * \ingroup DD4HEP_DDDB */ class KeyCollector : public cond::ConditionsListener { public: diff --git a/examples/DDDB/include/DDDB/DDDBConversion.h b/examples/DDDB/include/DDDB/DDDBConversion.h index f50b21e7a..913c218e0 100644 --- a/examples/DDDB/include/DDDB/DDDBConversion.h +++ b/examples/DDDB/include/DDDB/DDDBConversion.h @@ -610,8 +610,13 @@ namespace dd4hep { }; /// Declaration of a tag-class to handle conditions + /** \ingroup DD4HEP_DDDB + */ class dddb_conditions {}; + /// Helper to implement reference counting depending on types. + /** \ingroup DD4HEP_DDDB + */ template <typename T> class Increment { public: static int& counter() { static int cnt=0; return cnt; } diff --git a/examples/DDDB/include/DDDB/DDDBDimension.h b/examples/DDDB/include/DDDB/DDDBDimension.h index 7e1fc49f6..b0e0efec2 100644 --- a/examples/DDDB/include/DDDB/DDDBDimension.h +++ b/examples/DDDB/include/DDDB/DDDBDimension.h @@ -54,6 +54,7 @@ namespace dd4hep { * \author M.Frank * \version 1.0 * \ingroup DD4HEP_XML + * \ingroup DD4HEP_DDDB */ struct dddb_dim_t : public xml::Dimension { /// Default constructor diff --git a/examples/DDDB/include/DDDB/DDDBHelper.h b/examples/DDDB/include/DDDB/DDDBHelper.h index 803253227..7c81fc5e3 100644 --- a/examples/DDDB/include/DDDB/DDDBHelper.h +++ b/examples/DDDB/include/DDDB/DDDBHelper.h @@ -48,7 +48,7 @@ namespace dd4hep { * * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_XML + * \ingroup DD4HEP_DDDB */ class DDDBHelper : public PropertyConfigurable { public: diff --git a/examples/DDDB/include/DDDB/DDDBReader.h b/examples/DDDB/include/DDDB/DDDBReader.h index fc1a8b430..6997c0397 100644 --- a/examples/DDDB/include/DDDB/DDDBReader.h +++ b/examples/DDDB/include/DDDB/DDDBReader.h @@ -38,7 +38,7 @@ namespace dd4hep { * * \author M.Frank * \version 1.0 - * \ingroup DD4HEP_XML + * \ingroup DD4HEP_DDDB */ class DDDBReader : public dd4hep::xml::UriReader, public PropertyConfigurable -- GitLab