From 5499a2b7f8df7e6fe86f5b2b961a9e5b4d7415b8 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Fri, 13 Apr 2018 13:05:33 +0200
Subject: [PATCH] Add detector state depending on the load state

---
 DDCore/CMakeLists.txt                  |   6 +-
 DDCore/include/DD4hep/Detector.h       |  12 ++
 DDCore/include/DD4hep/DetectorData.h   |   3 +
 DDCore/src/DetectorData.cpp            |   2 +-
 DDCore/src/DetectorImp.cpp             |  15 +--
 DDCore/src/DetectorImp.h               | 150 +++++++++++++------------
 DDCore/src/plugins/StandardPlugins.cpp |   2 -
 DDCore/src/python/PythonPlugin.cpp     | 113 +++++++++++++++++++
 8 files changed, 218 insertions(+), 85 deletions(-)
 create mode 100644 DDCore/src/python/PythonPlugin.cpp

diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index 08ea41d59..44e641cb5 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -73,11 +73,15 @@ dd4hep_add_package_library ( DDCore
 # Generate DDCore plugins---------------------------------------------------------
 dd4hep_add_plugin ( DDCorePlugins SOURCES src/plugins/*.cpp )
 
-#---------------------------  Specialized  GDML  plugins  --------------------------
+#---------------------------  Specialized  GDML  plugin ----------------------------
 # This plugins depends on the ROOT GDML readers. Hence, extra library
 dd4hep_add_plugin(DDGDMLPlugins
   OPTIONAL    [ROOT REQUIRED COMPONENTS Gdml SOURCES src/gdml/*.cpp]
 )
+#---------------------------  Specialized PYTHON plugin ----------------------------
+dd4hep_add_plugin(DDPythonPlugins
+  OPTIONAL    [ROOT REQUIRED COMPONENTS PyROOT SOURCES src/python/*.cpp]
+)
 #
 #
 #---Package installation procedure(s) ----------------------------------------------
diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index 9d5c1fadb..e0f4d5fa4 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -73,6 +73,16 @@ namespace dd4hep {
     typedef std::map<std::string, std::string>          PropertyValues;
     typedef std::map<std::string, PropertyValues>       Properties;
 
+    /// The detector description states
+    enum State   {
+      /// The detector description object is freshly created. No geometry nothing.
+      VIRGIN  = 1<<0,
+      /// The geometry is being created and loaded. (parsing ongoing)
+      LOADING = 1<<1,
+      /// The geometry is loaded.
+      READY   = 1<<2
+    };
+    
     /// Destructor
     virtual ~Detector() = default;
 
@@ -83,6 +93,8 @@ namespace dd4hep {
     /// Finalize the geometry
     virtual void endDocument() = 0;
 
+    /// Access the state of the geometry
+    virtual State state()  const = 0;
     /// Access the geometry manager of this instance
     virtual TGeoManager& manager() const = 0;
     /// Access to properties map
diff --git a/DDCore/include/DD4hep/DetectorData.h b/DDCore/include/DD4hep/DetectorData.h
index e8a6bfada..e67becbe0 100644
--- a/DDCore/include/DD4hep/DetectorData.h
+++ b/DDCore/include/DD4hep/DetectorData.h
@@ -130,6 +130,9 @@ namespace dd4hep {
     /// Volume manager reference
     VolumeManager            m_volManager;
 
+    /// Detector description state
+    Detector::State          m_state = Detector::VIRGIN;
+    
     /// Flag to inhibit the access to global constants. Value set by constants section 'Detector_InhibitConstants'
     bool                     m_inhibitConstants;
 
diff --git a/DDCore/src/DetectorData.cpp b/DDCore/src/DetectorData.cpp
index 83ba19d76..e71534cd8 100644
--- a/DDCore/src/DetectorData.cpp
+++ b/DDCore/src/DetectorData.cpp
@@ -152,7 +152,7 @@ namespace {
 /// Default constructor
 DetectorData::DetectorData()
   : m_manager(0), m_world(), m_trackers(), m_worldVol(),
-    m_trackingVol(), m_field("global"),
+    m_trackingVol(), m_field(),
     m_buildType(BUILD_DEFAULT), m_extensions(typeid(DetectorData)), m_volManager(),
     m_inhibitConstants(false)
 {
diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp
index 7e5eb2f98..c828ab6a3 100644
--- a/DDCore/src/DetectorImp.cpp
+++ b/DDCore/src/DetectorImp.cpp
@@ -38,9 +38,6 @@
 
 #include "XML/DocumentHandler.h"
 
-#if DD4HEP_USE_PYROOT
-#include "TPython.h"
-#endif
 #ifndef __TIXML__
 #include "xercesc/dom/DOMException.hpp"
 namespace dd4hep {
@@ -504,6 +501,7 @@ void DetectorImp::endDocument() {
     patcher.patchShapes();
     mapDetectorTypes();
   }
+  m_state = READY;
 }
 
 /// Initialize the geometry and set the bounding box of the world volume
@@ -543,23 +541,20 @@ void DetectorImp::init() {
     m_trackers.setPlacement(m_worldVol.placeVolume(tracking));
     m_world.add(m_trackers);
 #endif
+
     m_detectors.append(m_world);
     m_manager->SetTopVolume(m_worldVol.ptr());
     m_world.setPlacement(mgr->GetTopNode());
+
+    m_field = OverlayedField("global");
+    m_state = LOADING;
   }
 }
 
 /// Read any geometry description or alignment file
 void DetectorImp::fromXML(const string& xmlfile, DetectorBuildType build_type) {
   TypePreserve build_type_preserve(m_buildType = build_type);
-#if DD4HEP_USE_PYROOT
-  string cmd;
-  TPython::Exec("import description");
-  cmd = "description.fromXML('" + xmlfile + "')";
-  TPython::Exec(cmd.c_str());
-#else
   processXML(xmlfile,0);
-#endif
 }
 
 /// Read any geometry description or alignment file with external XML entity resolution
diff --git a/DDCore/src/DetectorImp.h b/DDCore/src/DetectorImp.h
index f280ef409..9796ca621 100644
--- a/DDCore/src/DetectorImp.h
+++ b/DDCore/src/DetectorImp.h
@@ -39,7 +39,7 @@ namespace dd4hep {
     typedef std::map<std::string, std::vector<DetElement> > DetectorTypeMap;
 
     /// Inventory of detector types
-    DetectorTypeMap m_detectorTypes;
+    DetectorTypeMap   m_detectorTypes;
 
     /// VolumeManager m_volManager;
     DetectorBuildType m_buildType;
@@ -64,184 +64,192 @@ namespace dd4hep {
     /// Standard destructor
     virtual ~DetectorImp();
 
+    /// Access the state of the geometry
+    virtual State state()  const  override   {
+      return m_state;
+    }
+
     /// Access flag to steer the detail of building of the geometry/detector description
-    virtual DetectorBuildType buildType() const {
+    virtual DetectorBuildType buildType() const   override {
       return m_buildType;
     }
 
     /// Read compact geometry description or alignment file
-    virtual void fromCompact(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT) {
+    virtual void fromCompact(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT)   override {
       fromXML(fname, type);
     }
 
     /// Read any XML file
-    virtual void fromXML(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT);
+    virtual void fromXML(const std::string& fname, DetectorBuildType type = BUILD_DEFAULT)  override;
 
     /// Read any geometry description or alignment file with external XML entity resolution
     virtual void fromXML(const std::string& fname,
                          xml::UriReader* entity_resolver,
-                         DetectorBuildType type = BUILD_DEFAULT);
+                         DetectorBuildType type = BUILD_DEFAULT)  override;
 
-    virtual void dump() const;
+    virtual void dump() const  override;
 
     /// Manipulate geometry using facroy converter
-    virtual long apply(const char* factory, int argc, char** argv);
+    virtual long apply(const char* factory, int argc, char** argv)  override;
+
+    /// Open the geometry at startup.
+    virtual void init()  override;
 
-    virtual void init();
-    virtual void endDocument();
+    /// Close the geometry
+    virtual void endDocument()  override;
 
     /// Add an extension object to the Detector instance
-    virtual void* addUserExtension(unsigned long long int key, ExtensionEntry* entry);
+    virtual void* addUserExtension(unsigned long long int key, ExtensionEntry* entry)  override;
 
     /// Remove an existing extension object from the Detector instance. If not destroyed, the instance is returned
-    virtual void* removeUserExtension(unsigned long long int key, bool destroy=true);
+    virtual void* removeUserExtension(unsigned long long int key, bool destroy=true)  override;
 
     /// Access an existing extension object from the Detector instance
-    virtual void* userExtension(unsigned long long int key, bool alert=true) const;
+    virtual void* userExtension(unsigned long long int key, bool alert=true) const  override;
 
     virtual Handle<NamedObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not = true) const;
 
     /// Register new mother volume using the detector name.
-    virtual void   declareMotherVolume(const std::string& detector_name, const Volume& vol);
+    virtual void   declareMotherVolume(const std::string& detector_name, const Volume& vol)  override;
 
     /// Access mother volume by detector element
-    virtual Volume pickMotherVolume(const DetElement& sd) const;
+    virtual Volume pickMotherVolume(const DetElement& sd) const  override;
 
     /// Access the geometry manager of this instance
-    virtual TGeoManager& manager() const {
+    virtual TGeoManager& manager() const   override  {
       return *m_manager;
     }
     /// Access to properties
-    Properties& properties() const {
+    Properties& properties() const  override {
       return *(Properties*)&m_properties;
     }
     /// Return handle to material describing air
-    virtual Material air() const {
+    virtual Material air() const  override {
       return m_materialAir;
     }
     /// Return handle to material describing vacuum
-    virtual Material vacuum() const {
+    virtual Material vacuum() const  override {
       return m_materialVacuum;
     }
     /// Return handle to "invisible" visualization attributes
-    virtual VisAttr invisible() const {
+    virtual VisAttr invisible() const  override {
       return m_invisibleVis;
     }
     /// Return reference to the top-most (world) detector element
-    virtual DetElement world() const {
+    virtual DetElement world() const  override {
       return m_world;
     }
     /// Return reference to detector element with all tracker devices.
-    virtual DetElement trackers() const {
+    virtual DetElement trackers() const  override {
       return m_trackers;
     }
     /// Return handle to the world volume containing everything
-    virtual Volume worldVolume() const {
+    virtual Volume worldVolume() const  override {
       return m_worldVol;
     }
     /// Return handle to the world volume containing the volume with the tracking devices
-    virtual Volume trackingVolume() const {
+    virtual Volume trackingVolume() const  override {
       return m_trackingVol;
     }
     /// Return handle to the VolumeManager
-    virtual VolumeManager volumeManager() const {
+    virtual VolumeManager volumeManager() const  override {
       return m_volManager;
     }
     /// Return handle to the combined electromagentic field description.
-    virtual OverlayedField field() const {
+    virtual OverlayedField field() const  override {
       return m_field;
     }
     /// Accessor to the header entry
-    virtual Header header() const {
+    virtual Header header() const  override {
       return m_header;
     }
     /// Accessor to the header entry
-    virtual void setHeader(Header h) {
+    virtual void setHeader(Header h)  override {
       m_header = h;
     }
 
     /// Typed access to constants: access string values
-    virtual std::string constantAsString(const std::string& name) const;
+    virtual std::string constantAsString(const std::string& name) const  override;
 
     /// Typed access to constants: long values
-    virtual long constantAsLong(const std::string& name) const;
+    virtual long constantAsLong(const std::string& name) const  override;
 
     /// Typed access to constants: double values
-    virtual double constantAsDouble(const std::string& name) const;
+    virtual double constantAsDouble(const std::string& name) const  override;
 
     /// Retrieve a constant by it's name from the detector description
-    virtual Constant constant(const std::string& name) const;
+    virtual Constant constant(const std::string& name) const  override;
 
     /// Retrieve a limitset by it's name from the detector description
-    virtual LimitSet limitSet(const std::string& name) const {
+    virtual LimitSet limitSet(const std::string& name) const  override {
       return getRefChild(m_limits, name);
     }
     /// Retrieve a visualization attribute by it's name from the detector description
-    virtual VisAttr visAttributes(const std::string& name) const {
+    virtual VisAttr visAttributes(const std::string& name) const  override {
       return getRefChild(m_display, name, false);
     }
     /// Retrieve a matrial by it's name from the detector description
-    virtual Material material(const std::string& name) const;
+    virtual Material material(const std::string& name) const  override;
 
     /// Retrieve a region object by it's name from the detector description
-    virtual Region region(const std::string& name) const {
+    virtual Region region(const std::string& name) const  override {
       return getRefChild(m_regions, name);
     }
     /// Retrieve a id descriptor by it's name from the detector description
-    virtual IDDescriptor idSpecification(const std::string& name) const {
+    virtual IDDescriptor idSpecification(const std::string& name) const  override {
       return getRefChild(m_idDict, name);
     }
     /// Retrieve a readout object by it's name from the detector description
-    virtual Readout readout(const std::string& name) const {
+    virtual Readout readout(const std::string& name) const  override {
       return getRefChild(m_readouts, name);
     }
     /// Retrieve a subdetector element by it's name from the detector description
-    virtual DetElement detector(const std::string& name) const {
+    virtual DetElement detector(const std::string& name) const  override {
       return getRefChild(m_detectors, name);
     }
     /// Retrieve a sensitive detector by it's name from the detector description
-    virtual SensitiveDetector sensitiveDetector(const std::string& name) const {
+    virtual SensitiveDetector sensitiveDetector(const std::string& name) const  override {
       return getRefChild(m_sensitive, name, false);
     }
     /// Retrieve a subdetector element by it's name from the detector description
-    virtual CartesianField field(const std::string& name) const {
+    virtual CartesianField field(const std::string& name) const  override {
       return getRefChild(m_fields, name, false);
     }
 
     /// Accessor to the map of constants
-    virtual const HandleMap& constants() const {
+    virtual const HandleMap& constants() const  override {
       return m_define;
     }
     /// Accessor to the map of visualisation attributes
-    virtual const HandleMap& visAttributes() const {
+    virtual const HandleMap& visAttributes() const  override {
       return m_display;
     }
     /// Accessor to the map of limit settings
-    virtual const HandleMap& limitsets() const {
+    virtual const HandleMap& limitsets() const  override {
       return m_limits;
     }
     /// Accessor to the map of region settings
-    virtual const HandleMap& regions() const {
+    virtual const HandleMap& regions() const  override {
       return m_regions;
     }
     /// Accessor to the map of readout structures
-    virtual const HandleMap& readouts() const {
+    virtual const HandleMap& readouts() const  override {
       return m_readouts;
     }
     /// Accessor to the map of sub-detectors
-    virtual const HandleMap& detectors() const {
+    virtual const HandleMap& detectors() const  override {
       return m_detectors;
     }
     /// Retrieve a sensitive detector by it's name from the detector description
-    virtual const HandleMap& sensitiveDetectors() const {
+    virtual const HandleMap& sensitiveDetectors() const  override {
       return m_sensitive;
     }
     /// Accessor to the map of field entries, which together form the global field
-    virtual const HandleMap& fields() const {
+    virtual const HandleMap& fields() const  override {
       return m_fields;
     }
     /// Accessor to the map of ID specifications
-    virtual const HandleMap& idSpecifications() const {
+    virtual const HandleMap& idSpecifications() const  override {
       return m_idDict;
     }
 
@@ -254,100 +262,100 @@ namespace dd4hep {
        - If throw_exc is set to true, an exception is thrown if the type
        is not present. Otherwise an empty detector container is returned.
     */
-    virtual const std::vector<DetElement>& detectors(const std::string& type, bool throw_exc);
+    virtual const std::vector<DetElement>& detectors(const std::string& type, bool throw_exc)  override;
 
     /// Access a set of subdetectors according to several sensitive types.
     virtual std::vector<DetElement> detectors(const std::string& type1,
                                               const std::string& type2,
                                               const std::string& type3="",
                                               const std::string& type4="",
-                                              const std::string& type5="" );
+                                              const std::string& type5="" )  override;
 
     /// Access the availible detector types
-    virtual std::vector<std::string> detectorTypes() const;
+    virtual std::vector<std::string> detectorTypes() const  override;
 
     /** return a vector with all detectors that have all the type properties in
      *  includeFlag set but none of the properties given in excludeFlag
      */
     virtual std::vector<DetElement> detectors(unsigned int includeFlag, 
-                                              unsigned int excludeFlag=0 ) const ;
+                                              unsigned int excludeFlag=0 ) const   override;
 
 
 #define __R  return *this
     /// Add a new constant to the detector description
-    virtual Detector& add(Constant x) {
+    virtual Detector& add(Constant x)  override {
       return addConstant(x);
     }
     /// Add a new limit set to the detector description
-    virtual Detector& add(LimitSet x) {
+    virtual Detector& add(LimitSet x)  override {
       return addLimitSet(x);
     }
     /// Add a new detector region to the detector description
-    virtual Detector& add(Region x) {
+    virtual Detector& add(Region x)  override {
       return addRegion(x);
     }
     /// Add a new visualisation attribute to the detector description
-    virtual Detector& add(VisAttr x) {
+    virtual Detector& add(VisAttr x)  override {
       return addVisAttribute(x);
     }
     /// Add a new id descriptor to the detector description
-    virtual Detector& add(IDDescriptor x) {
+    virtual Detector& add(IDDescriptor x)  override {
       return addIDSpecification(x);
     }
     /// Add a new detector readout to the detector description
-    virtual Detector& add(Readout x) {
+    virtual Detector& add(Readout x)  override {
       return addReadout(x);
     }
     /// Add a new sensitive detector to the detector description
-    virtual Detector& add(SensitiveDetector x) {
+    virtual Detector& add(SensitiveDetector x)  override {
       return addSensitiveDetector(x);
     }
     /// Add a new subdetector to the detector description
-    virtual Detector& add(DetElement x) {
+    virtual Detector& add(DetElement x)  override {
       return addDetector(x);
     }
     /// Add a field component to the detector description
-    virtual Detector& add(CartesianField x) {
+    virtual Detector& add(CartesianField x)  override {
       return addField(x);
     }
 
     /// Add a new constant by named reference to the detector description
-    virtual Detector& addConstant(const Handle<NamedObject>& x);
+    virtual Detector& addConstant(const Handle<NamedObject>& x)  override;
 
     /// Add a new limit set by named reference to the detector description
-    virtual Detector& addLimitSet(const Handle<NamedObject>& x) {
+    virtual Detector& addLimitSet(const Handle<NamedObject>& x)  override {
       m_limits.append(x);
       __R;
     }
     /// Add a new detector region by named reference to the detector description
-    virtual Detector& addRegion(const Handle<NamedObject>& x) {
+    virtual Detector& addRegion(const Handle<NamedObject>& x)  override {
       m_regions.append(x);
       __R;
     }
     /// Add a new id descriptor by named reference to the detector description
-    virtual Detector& addIDSpecification(const Handle<NamedObject>& x) {
+    virtual Detector& addIDSpecification(const Handle<NamedObject>& x)  override {
       m_idDict.append(x);
       __R;
     }
     /// Add a new detector readout by named reference to the detector description
-    virtual Detector& addReadout(const Handle<NamedObject>& x) {
+    virtual Detector& addReadout(const Handle<NamedObject>& x)  override {
       m_readouts.append(x);
       __R;
     }
     /// Add a new visualisation attribute by named reference to the detector description
-    virtual Detector& addVisAttribute(const Handle<NamedObject>& x) {
+    virtual Detector& addVisAttribute(const Handle<NamedObject>& x)  override {
       m_display.append(x);
       __R;
     }
     /// Add a new sensitive detector by named reference to the detector description
-    virtual Detector& addSensitiveDetector(const Handle<NamedObject>& x) {
+    virtual Detector& addSensitiveDetector(const Handle<NamedObject>& x)  override {
       m_sensitive.append(x);
       __R;
     }
     /// Add a new subdetector by named reference to the detector description
-    virtual Detector& addDetector(const Handle<NamedObject>& x);
+    virtual Detector& addDetector(const Handle<NamedObject>& x)  override;
     /// Add a field component by named reference to the detector description
-    virtual Detector& addField(const Handle<NamedObject>& x);
+    virtual Detector& addField(const Handle<NamedObject>& x)  override;
 #undef __R
 
   };
diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index d21f44906..0f45963a8 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -232,8 +232,6 @@ 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);",
diff --git a/DDCore/src/python/PythonPlugin.cpp b/DDCore/src/python/PythonPlugin.cpp
new file mode 100644
index 000000000..67ecee0f9
--- /dev/null
+++ b/DDCore/src/python/PythonPlugin.cpp
@@ -0,0 +1,113 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DD4hep/Factories.h"
+#include "DD4hep/Printout.h"
+
+// ROOT includes
+#include "TPython.h"
+
+using namespace std;
+using namespace dd4hep;
+
+/// Do not clutter the global namespace ....
+namespace  {
+  
+  void usage(int argc, char** argv)    {
+    cout <<
+      "Usage: -plugin <name> -arg [-arg]                                                  \n"
+      "     name:   factory name     DD4hep_Python                                        \n"
+      "     -import  <string>        import a python module, making its classes available.\n"
+      "     -macro   <string>        load a python script as if it were a macro.          \n"
+      "     -exec    <string>        execute a python statement (e.g. \"import ROOT\".    \n"
+      "     -eval    <string>        evaluate a python expression (e.g. \"1+1\")          \n"
+      "     -prompt                  enter an interactive python session (exit with ^D)   \n"
+      "     -dd4hep                  Equivalent to -exec \"import dd4hep\"                \n"
+      "     -help                    Show this online help message.                       \n"
+      "                                                                                   \n"
+      "     Note: entries can be given multiple times and are executed in exactly the     \n"
+      "           order specified at the command line!                                    \n"
+      "                                                                                   \n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::exit(EINVAL);
+  }
+
+  /// ROOT GDML writer plugin
+  /**
+   *  Factory: DD4hep_ROOTGDMLExtract
+   *
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \date    01/04/2014
+   */
+  long call_python(Detector& /* description */, int argc, char** argv) {
+    if ( argc > 0 )   {
+      vector<pair<string, string> > commands;
+      for(int i = 0; i < argc && argv[i]; ++i)  {
+        if ( 0 == ::strncmp("-import",argv[i],2) )
+          commands.push_back(make_pair("import",argv[++i]));
+        else if ( 0 == ::strncmp("-dd4hep", argv[i],2) )
+          commands.push_back(make_pair("exec","import dd4hep"));
+        else if ( 0 == ::strncmp("-macro", argv[i],2) )
+          commands.push_back(make_pair("macro",argv[++i]));
+        else if ( 0 == ::strncmp("-exec", argv[i],2) )
+          commands.push_back(make_pair("exec",argv[++i]));
+        else if ( 0 == ::strncmp("-eval", argv[i],2) )
+          commands.push_back(make_pair("calc",argv[++i]));
+        else if ( 0 == ::strncmp("-prompt", argv[i],2) )
+          commands.push_back(make_pair("prompt",""));
+        else
+          usage(argc, argv);
+      }
+      if ( commands.empty() )   {
+        usage(argc, argv);
+      }
+      for(const auto& c : commands)   {
+        Bool_t result = kFALSE;
+        switch(c.first[0])  {
+        case 'i':
+          result = TPython::Import(c.second.c_str());
+          break;
+        case 'm':
+          TPython::LoadMacro(c.second.c_str());
+          result = kTRUE;
+          break;
+        case 'e':
+          result = TPython::Exec(c.second.c_str());
+          break;
+        case 'c':
+          TPython::Eval(c.second.c_str());
+          result = kTRUE;
+          break;
+        case 'p':
+          TPython::Prompt();
+          result = kTRUE;
+          break;
+        default:
+          usage(argc, argv);
+          ::exit(EINVAL);
+          break;
+        }
+        if ( result != kTRUE )    {
+          except("DD4hep_Python","+++ Failed to invoke the statement: %s",c.second.c_str());
+        }
+      }
+      return 1;
+    }
+    except("DD4hep_Python","+++ No commands file name given.");
+    return 0;
+  }
+}
+
+DECLARE_APPLY(DD4hep_Python,call_python)
-- 
GitLab