From 52bae09e50084baaecb81943ff768a70914709d7 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Thu, 25 Sep 2014 09:11:14 +0000
Subject: [PATCH] Intermediate chick-in for Frank

---
 DDG4/examples/CLICSidSimu.py           | 13 +++-
 DDG4/examples/run.C                    |  4 +-
 DDG4/examples/sequences.xml            | 69 ++++++++++---------
 DDG4/examples/xmlAClick.C              | 37 +++++++++--
 DDG4/include/DDG4/Geant4Config.h       |  1 +
 DDG4/include/DDG4/Geant4Kernel.h       |  2 -
 DDG4/plugins/Geant4XMLSetup.cpp        |  9 +++
 DDG4/python/DD4hep.py                  | 91 ++++++++++++++------------
 DDG4/python/DDG4.py                    | 31 +++++++++
 DDG4/src/Geant4ParticleHandler.cpp     |  3 +-
 DDG4/src/Geant4UserParticleHandler.cpp |  1 +
 11 files changed, 177 insertions(+), 84 deletions(-)

diff --git a/DDG4/examples/CLICSidSimu.py b/DDG4/examples/CLICSidSimu.py
index d37fd24dc..562deed19 100644
--- a/DDG4/examples/CLICSidSimu.py
+++ b/DDG4/examples/CLICSidSimu.py
@@ -15,10 +15,12 @@ from SystemOfUnits import *
 """
 def run():
   kernel = DDG4.Kernel()
+  lcdd = kernel.lcdd()
   install_dir = os.environ['DD4hepINSTALL']
   example_dir = install_dir+'/examples/DDG4/examples';
   kernel.loadGeometry("file:"+install_dir+"/examples/CLICSiD/compact/compact.xml")
   kernel.loadXML("file:"+example_dir+"/DDG4_field.xml")
+  DDG4.importConstants(lcdd)
 
   simple = DDG4.Simple(kernel)
   simple.printDetectors()
@@ -111,6 +113,7 @@ def run():
   gen.OutputLevel = 4 # generator_output_level
   gen.MomentumScale = 0.1
   gen.Mask = 1
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
   # Install vertex smearing for this interaction
   gen = DDG4.GeneratorAction(kernel,"Geant4InteractionVertexSmear/Smear1");  
@@ -118,6 +121,7 @@ def run():
   gen.Mask = 1
   gen.Offset = (-20*mm, -10*mm, -10*mm, 0*ns)
   gen.Sigma = (12*mm, 8*mm, 8*mm, 0*ns)
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
 
   # Second particle file reader
@@ -127,6 +131,7 @@ def run():
   gen.OutputLevel = 4 # generator_output_level
   gen.Mask = 2
   gen.MomentumScale = 0.1
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
   # Install vertex smearing for this interaction
   gen = DDG4.GeneratorAction(kernel,"Geant4InteractionVertexSmear/Smear2");
@@ -134,6 +139,7 @@ def run():
   gen.Mask = 2
   gen.Offset = (20*mm, 10*mm, 10*mm, 0*ns)
   gen.Sigma = (2*mm, 1*mm, 1*mm, 0*ns)
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
 
   #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -141,11 +147,13 @@ def run():
   # Merge all existing interaction records
   gen = DDG4.GeneratorAction(kernel,"Geant4InteractionMerger/InteractionMerger")
   gen.OutputLevel = 4 #generator_output_level
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
 
   # Finally generate Geant4 primaries
   gen = DDG4.GeneratorAction(kernel,"Geant4PrimaryHandler/PrimaryHandler")
   gen.OutputLevel = 4 #generator_output_level
+  gen.enableUI()
   kernel.generatorAction().adopt(gen)
 
   # And handle the simulation particles.
@@ -157,8 +165,9 @@ def run():
   part.OutputLevel = 5 # generator_output_level
   part.enableUI()
   user = DDG4.Action(kernel,"Geant4TCUserParticleHandler/UserParticleHandler")
-  user.TrackingVolume_Zmax = 165.70*cm  # EcalEndcap_zmin
-  user.TrackingVolume_Rmax = 126.50*cm  # EcalBarrel_rmin
+  user.TrackingVolume_Zmax = DDG4.EcalEndcap_zmin
+  user.TrackingVolume_Rmax = DDG4.EcalBarrel_rmin
+  user.enableUI()
   part.adopt(user)
 
   """
diff --git a/DDG4/examples/run.C b/DDG4/examples/run.C
index b62089327..ecfef7b36 100644
--- a/DDG4/examples/run.C
+++ b/DDG4/examples/run.C
@@ -2,11 +2,11 @@
 void run()  {
   gInterpreter->ProcessLine(".X initAClick.C");
   //gInterpreter->ProcessLine(".L exampleAClick.C+");
-  //gInterpreter->ProcessLine(".L xmlAClick.C+");
+  gInterpreter->ProcessLine(".L xmlAClick.C+");
   //gInterpreter->ProcessLine(".L TEve.C+");
   //gSystem->Load("libDD4hepCore");
   //gSystem->Load("libDD4hepG4");
-  gInterpreter->ProcessLine(".L FCC_Hcal.C+");
+  //gInterpreter->ProcessLine(".L FCC_Hcal.C+");
   //gInterpreter->ProcessLine(".X DDG4Dump.C+");
   //gInterpreter->ProcessLine(".X a.C++");
 }
diff --git a/DDG4/examples/sequences.xml b/DDG4/examples/sequences.xml
index 06b2fc69d..4d344897d 100644
--- a/DDG4/examples/sequences.xml
+++ b/DDG4/examples/sequences.xml
@@ -4,22 +4,22 @@
 
 
   <!-- Kernel parameters  
-  --   UI="UI" is default, 
-  --
-  --   Note:
-  --   NumEvents is ignored in interactive sessions, but  used
-  --   in batch mode without ui nor vis.
-  --
-  --   To run batch: set UI=""
+       UI="UI" is default, 
+    
+       Note:
+       NumEvents is ignored in interactive sessions, but  used
+       in batch mode without ui nor vis.
+    
+       To run batch: set UI=""
   -->
   <kernel UI="UI" NumEvents="5"/>  
 
   <!-- List of globally known actions. These actions will be registered with the Geant4Kernel 
-  --   object and may be retrieved by there using the action name.
-  --
-  --   Note: registered actions MUST be unique.
-  --   However, not all actions need to registered....
-  --   Only register those, you later need to retrieve by name.
+       object and may be retrieved by there using the action name.
+    
+       Note: registered actions MUST be unique.
+       However, not all actions need to registered....
+       Only register those, you later need to retrieve by name.
   -->
   <actions>
     <action name="Geant4TestRunAction/RunInit">
@@ -34,6 +34,11 @@
 		  Property_double="5e15"
 		  Property_string="Hello_2"/>
     </action>
+    <action name="Geant4TCUserParticleHandler/UserParticleHandler">
+      <properties Control="true"
+		  TrackingVolume_Zmax="165*cm"
+		  TrackingVolume_Rmax="125*cm"/>
+    </action>
 
     <!-- UI handler initializing vis and ui. NAME IS FIXED/COMMON KNOWLEDGE -->
     <action name="Geant4UIManager/UI">
@@ -42,16 +47,14 @@
 		  SetupUI="run.mac"
 		  SessionType="csh"/>
      </action>
-    <!-- void and empty for the time being.... NAME IS FIXED/COMMON KNOWLEDGE -->
-    <action name="Geant4DummyTruthHandler/MonteCarloTruthHandler"/>
   </actions>
 
   <!-- List of known phases.
-  --   Note: Phases can only be attached to the program at very well defined moments,
-  --   which are explained in the documentation.
-  --   These are typically the "standard" moments: BeginRun, EndRun, BeginEvent, etc.
-  --   and the calls after processing the hits of each sensitive detector.
-  --
+       Note: Phases can only be attached to the program at very well defined moments,
+       which are explained in the documentation.
+       These are typically the "standard" moments: BeginRun, EndRun, BeginEvent, etc.
+       and the calls after processing the hits of each sensitive detector.
+    
   -->
   <phases>
     <phase type="RunAction/begin">
@@ -72,13 +75,13 @@
   </phases>
 
   <!-- List of globally known filters. Filters are called by Geant4 before the
-  --   hit processing in the sensitive detectors start. The global filters
-  --   may be shared between many sensitive detectors. Alternatively filters
-  --   may be directly attached to the sensitive detector in question.
-  --   Attributes are directly passed as properties to the filter action.
-  --
-  --   Note: registered global filters MUST be unique.
-  --   However, not all filters need to registered....
+       hit processing in the sensitive detectors start. The global filters
+       may be shared between many sensitive detectors. Alternatively filters
+       may be directly attached to the sensitive detector in question.
+       Attributes are directly passed as properties to the filter action.
+    
+       Note: registered global filters MUST be unique.
+       However, not all filters need to registered....
   -->
   <filters>
     <filter name="GeantinoRejectFilter/GeantinoRejector"/>
@@ -94,10 +97,10 @@
   </filters>
 
   <!-- List of known action sequences.
-  --   Note: Action sequences exist for each of the various geant4 callback,
-  --   which are explained in the documentation, such as EventAction, RunAction, etc
-  --   and the calls after processing the hits of each sensitive detector.
-  --
+       Note: Action sequences exist for each of the various geant4 callback,
+       which are explained in the documentation, such as EventAction, RunAction, etc
+       and the calls after processing the hits of each sensitive detector.
+    
   -->
   <sequences>
     <sequence name="Geant4EventActionSequence/EventAction">
@@ -124,6 +127,12 @@
 		    multiplicity="1"
 		    direction="(1,1,1)"/>
       </action>
+      <action name="Geant4ParticleHandler/ParticleHandler">
+        <properties Control="true"
+		    SaveProcesses="['Decay']"
+  	  	    MinimalKineticEnergy="100*MeV"/>
+	<adopt name="UserParticleHandler"/>
+      </action>
     </sequence>
 
     <sequence sd="SiVertexBarrel" type="Geant4SensDetActionSequence">
diff --git a/DDG4/examples/xmlAClick.C b/DDG4/examples/xmlAClick.C
index ee44cd48d..1096deeeb 100644
--- a/DDG4/examples/xmlAClick.C
+++ b/DDG4/examples/xmlAClick.C
@@ -1,19 +1,44 @@
 #include "DDG4/Geant4Config.h"
+#if 0
+#include "DDG4/Geant4Handle.h"
+#include "DDG4/Geant4Particle.h"
+#include "DDG4/Geant4Kernel.h"
+#include "DDG4/Geant4PhysicsList.h"
+#include "DDG4/Geant4GeneratorAction.h"
+#include "DDG4/Geant4RunAction.h"
+#include "DDG4/Geant4EventAction.h"
+#include "DDG4/Geant4TrackingAction.h"
+#include "DDG4/Geant4SteppingAction.h"
+#include "DDG4/Geant4StackingAction.h"
+#include "DDG4/Geant4ActionPhase.h"
+#include "DDG4/Geant4SensDetAction.h"
+#include "DDG4/Geant4ParticleHandler.h"
+#include "DDG4/Geant4UserParticleHandler.h"
+#include "DDG4/ComponentUtils.h"
+#include "DD4hep/LCDD.h"
+#endif
+
 #include <iostream>
+
+
+using namespace DD4hep;
+using namespace DD4hep::Simulation;
 using namespace DD4hep::Simulation::Setup;
 
 void setupG4_XML()  {
-  DD4hep::Geometry::LCDD& lcdd = DD4hep::Geometry::LCDD::getInstance();
-  Kernel& kernel = Kernel::instance(lcdd);
-  kernel.loadGeometry("file:../DD4hep.trunk/DDExamples/CLICSiD/compact/compact.xml");
-  kernel.loadXML("DDG4_field.xml");
-  kernel.loadXML("sequences.xml");
-  kernel.loadXML("physics.xml");
+  std::string prefix = "file:../DD4hep.trunk";
+  Geant4Kernel& kernel = Kernel::instance(Geometry::LCDD::getInstance());
+  kernel.loadGeometry((prefix+"/DDExamples/CLICSiD/compact/compact.xml").c_str());
+  kernel.loadXML((prefix+"/DDG4/examples/DDG4_field.xml").c_str());
+  kernel.loadXML((prefix+"/DDG4/examples/sequences.xml").c_str());
+  kernel.loadXML((prefix+"/DDG4/examples/physics.xml").c_str());
   kernel.configure();
   kernel.initialize();
   kernel.run();
   std::cout << "Successfully executed application .... " << std::endl;
   kernel.terminate();
+#if 0
+#endif
 }
 
 
diff --git a/DDG4/include/DDG4/Geant4Config.h b/DDG4/include/DDG4/Geant4Config.h
index 74e2cc1ed..194823065 100644
--- a/DDG4/include/DDG4/Geant4Config.h
+++ b/DDG4/include/DDG4/Geant4Config.h
@@ -79,6 +79,7 @@ namespace DD4hep {
   }    // End namespace Simulation
 }      // End namespace DD4hep
 
+#include "DDG4/Geant4Particle.h"
 #include "DDG4/Geant4Handle.h"
 #include "DDG4/Geant4Kernel.h"
 #include "DDG4/Geant4PhysicsList.h"
diff --git a/DDG4/include/DDG4/Geant4Kernel.h b/DDG4/include/DDG4/Geant4Kernel.h
index 8fadb8b0d..69001fde0 100644
--- a/DDG4/include/DDG4/Geant4Kernel.h
+++ b/DDG4/include/DDG4/Geant4Kernel.h
@@ -115,8 +115,6 @@ namespace DD4hep {
       /// Helper to register an action sequence
       template <typename C> bool registerSequence(C*& seq, const std::string& name);
 
-#if defined(__CINT__) || defined(__MAKECINT__)
-#endif
     public:
       /// Standard constructor
       Geant4Kernel(LCDD& lcdd);
diff --git a/DDG4/plugins/Geant4XMLSetup.cpp b/DDG4/plugins/Geant4XMLSetup.cpp
index 79b363584..b85a2c3c8 100644
--- a/DDG4/plugins/Geant4XMLSetup.cpp
+++ b/DDG4/plugins/Geant4XMLSetup.cpp
@@ -83,6 +83,15 @@ namespace DD4hep  {
     _setProperties(handle,e);
     printout(INFO,"Geant4Setup","+++ Added action %s of type %s",tn.second.c_str(),tn.first.c_str());
     installMessenger(handle);
+
+    if ( action.hasChild(_Unicode(adopt)) )  {
+      xml_comp_t child = action.child(_Unicode(adopt));
+      Geant4Action* user = kernel.globalAction(child.nameStr());
+      Geant4ParticleHandler* ph = dynamic_cast<Geant4ParticleHandler*>(handle.get());
+      if ( ph )  {
+	ph->adopt(user);
+      }
+    }
     return handle;
   }
 
diff --git a/DDG4/python/DD4hep.py b/DDG4/python/DD4hep.py
index b586739e5..2545d7bb2 100644
--- a/DDG4/python/DD4hep.py
+++ b/DDG4/python/DD4hep.py
@@ -37,9 +37,11 @@ def loadDD4hep():
 
 # We are nearly there ....
 name_space = __import__(__name__)
-def import_class(ns,nam):  
+def import_namespace_item(ns,nam):  
   scope = getattr(name_space,ns)
-  setattr(name_space,nam,getattr(scope,nam))
+  attr = getattr(scope,nam)
+  setattr(name_space,nam,attr)
+  return attr
 
 def import_root(nam):
   #print 'import ROOT class ',nam,str(name_space)
@@ -73,58 +75,65 @@ OutputLevel = _Levels()
 Core       = DD4hep
 Geo        = DD4hep.Geometry
 Geometry   = DD4hep.Geometry
+
+import_root('XmlTools')
+import_namespace_item('XmlTools','Evaluator')
 #---------------------------------------------------------------------------
-import_class('Core','NamedObject')
-import_class('Core','run_interpreter')
+import_namespace_item('Core','NamedObject')
+import_namespace_item('Core','run_interpreter')
 
 def import_geometry():
-  import_class('Core','setPrintLevel')
-  import_class('Core','printLevel')
-  import_class('Geo','LCDD')
-  import_class('Geo','VolumeManager')
-  import_class('Geo','OverlayedField')
+  import_namespace_item('Core','setPrintLevel')
+  import_namespace_item('Core','printLevel')
+  import_namespace_item('Geo','LCDD')
+  import_namespace_item('Core','evaluator')
+  import_namespace_item('Core','g4Evaluator')
+  
+  import_namespace_item('Geo','VolumeManager')
+  import_namespace_item('Geo','OverlayedField')
+  import_namespace_item('Geo','Ref_t')
 
   #// Objects.h
-  import_class('Geo','Author')
-  import_class('Geo','Header')
-  import_class('Geo','Constant')
-  import_class('Geo','Atom')
-  import_class('Geo','Material')
-  import_class('Geo','VisAttr')
-  import_class('Geo','AlignmentEntry')
-  import_class('Geo','Limit')
-  import_class('Geo','LimitSet')
-  import_class('Geo','Region')
+  import_namespace_item('Geo','Author')
+  import_namespace_item('Geo','Header')
+  import_namespace_item('Geo','Constant')
+  import_namespace_item('Geo','Atom')
+  import_namespace_item('Geo','Material')
+  import_namespace_item('Geo','VisAttr')
+  import_namespace_item('Geo','AlignmentEntry')
+  import_namespace_item('Geo','Limit')
+  import_namespace_item('Geo','LimitSet')
+  import_namespace_item('Geo','Region')
 
   #// Readout.h
-  import_class('Geo','Readout')
-  import_class('Geo','Alignment')
-  import_class('Geo','Conditions')
+  import_namespace_item('Geo','Readout')
+  import_namespace_item('Geo','Alignment')
+  import_namespace_item('Geo','Conditions')
 
   #// DetElement.h
-  import_class('Geo','DetElement')
-  import_class('Geo','SensitiveDetector')
+  import_namespace_item('Geo','DetElement')
+  import_namespace_item('Geo','SensitiveDetector')
 
   #// Volume.h
-  import_class('Geo','Volume')
-  import_class('Geo','PlacedVolume')
+  import_namespace_item('Geo','Volume')
+  import_namespace_item('Geo','PlacedVolume')
 
   #// Shapes.h
-  import_class('Geo','Polycone')
-  import_class('Geo','ConeSegment')
-  import_class('Geo','Box')
-  import_class('Geo','Torus')
-  import_class('Geo','Cone')
-  import_class('Geo','Tube')
-  import_class('Geo','Trap')
-  import_class('Geo','Trapezoid')
-  import_class('Geo','Sphere')
-  import_class('Geo','Paraboloid')
-  import_class('Geo','PolyhedraRegular')
-  import_class('Geo','BooleanSolid')
-  import_class('Geo','SubtractionSolid')
-  import_class('Geo','UnionSolid')
-  import_class('Geo','IntersectionSolid')
+  import_namespace_item('Geo','Polycone')
+  import_namespace_item('Geo','ConeSegment')
+  import_namespace_item('Geo','Box')
+  import_namespace_item('Geo','Torus')
+  import_namespace_item('Geo','Cone')
+  import_namespace_item('Geo','Tube')
+  import_namespace_item('Geo','Trap')
+  import_namespace_item('Geo','Trapezoid')
+  import_namespace_item('Geo','Sphere')
+  import_namespace_item('Geo','Paraboloid')
+  import_namespace_item('Geo','PolyhedraRegular')
+  import_namespace_item('Geo','BooleanSolid')
+  import_namespace_item('Geo','SubtractionSolid')
+  import_namespace_item('Geo','UnionSolid')
+  import_namespace_item('Geo','IntersectionSolid')
 
 
 def import_tgeo():
diff --git a/DDG4/python/DDG4.py b/DDG4/python/DDG4.py
index b1e2a3a36..b32bd0182 100644
--- a/DDG4/python/DDG4.py
+++ b/DDG4/python/DDG4.py
@@ -31,7 +31,38 @@ Simulation = DD4hep.Simulation
 
 Kernel     = Sim.KernelHandle
 Interface  = Sim.Geant4ActionCreation
+LCDD       = Geo.LCDD
 
+#---------------------------------------------------------------------------
+def _constant(self,name):
+  return self.constantAsString(name)
+
+LCDD.globalVal = _constant
+#---------------------------------------------------------------------------
+
+"""
+import DDG4
+l=DDG4.LCDD.getInstance()
+l.addConstant(DDG4.Ref_t(DDG4.NamedObject('AA','10*cm')))
+DDG4.importConstants(l,'sub-name-space')
+"""
+def importConstants(lcdd,namespace=None):
+  scope = current
+  ns = current
+  if namespace is not None and not hasattr(current,namespace):
+    import imp
+    m = imp.new_module('DDG4.'+namespace)
+    setattr(current,namespace,m)
+    ns = m
+  values = {}
+  for c in lcdd.constants():
+    values[c.first] = c.second.GetTitle()
+  evaluator = DD4hep.evaluator()
+  for key,value in values:
+    setattr(ns,key,value)
+    #print 'Imported global value:',c.first,'=',c.second.GetTitle(),'into namespace',ns.__name__
+#---------------------------------------------------------------------------
+  
 def _registerGlobalAction(self,action):
   self.get().registerGlobalAction(Interface.toAction(action))
 def _registerGlobalFilter(self,filter):
diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 8e9309789..0c642a7c0 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -57,6 +57,7 @@ namespace {
 Geant4ParticleHandler::Geant4ParticleHandler(Geant4Context* context, const string& nam)
   : Geant4GeneratorAction(context,nam), Geant4MonteCarloTruth(), m_userHandler(0), m_primaryMap(0)
 {
+  InstanceCount::increment(this);
   //generatorAction().adopt(this);
   eventAction().callAtBegin(this,&Geant4ParticleHandler::beginEvent);
   eventAction().callAtEnd(this,&Geant4ParticleHandler::endEvent);
@@ -69,7 +70,7 @@ Geant4ParticleHandler::Geant4ParticleHandler(Geant4Context* context, const strin
   declareProperty("KeepAllParticles",    m_keepAll = false);
   declareProperty("SaveProcesses",       m_processNames);
   declareProperty("MinimalKineticEnergy",m_kinEnergyCut = 100e0*MeV);
-  InstanceCount::increment(this);
+  m_needsControl = true;
 }
 
 /// No default constructor
diff --git a/DDG4/src/Geant4UserParticleHandler.cpp b/DDG4/src/Geant4UserParticleHandler.cpp
index 0ed51d41c..221756edf 100644
--- a/DDG4/src/Geant4UserParticleHandler.cpp
+++ b/DDG4/src/Geant4UserParticleHandler.cpp
@@ -18,6 +18,7 @@ Geant4UserParticleHandler::Geant4UserParticleHandler(Geant4Context* context, con
   : Geant4Action(context,nam)
 {
   InstanceCount::increment(this);
+  m_needsControl = true;
 }
 
 /// Default destructor
-- 
GitLab