From ec6f1805b32c4201c7363997fa910cabee8700a7 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Mon, 21 Mar 2022 14:06:16 +0100
Subject: [PATCH] Handle material properties (and const properties) beyond the
 G4 material table

---
 DDCore/src/plugins/StandardPlugins.cpp        |  3 +-
 DDG4/src/Geant4Converter.cpp                  | 99 ++++++++++---------
 .../ClientTests/src/MaterialTester_geo.cpp    | 40 ++++++++
 .../compact/ReadMaterialProperties.xml        | 37 +++++++
 .../scripts/ReadMaterialProperties.py         | 75 ++++++++++++++
 5 files changed, 204 insertions(+), 50 deletions(-)
 create mode 100644 examples/OpticalSurfaces/scripts/ReadMaterialProperties.py

diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index 34211d8bf..ffd0d15cd 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -139,7 +139,8 @@ static long display(Detector& description, int argc, char** argv) {
         "     -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"       
+        "     -visopt   <number> Visualization option [TGeoManager::SetVisOption] Default: 1\n"       
+        "     -load              Only load the geometry. Do not invoke the display          \n"
         "     -help              Print this help output  \n"       
         "     Arguments given: " << arguments(argc,argv) << endl << flush;
       ::exit(EINVAL);
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index a0e44ad0d..2158a9d2a 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -339,6 +339,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       state = kStateUndefined;
       break;
     }
+    printout(lvl,"Geant4Material","+++ Setting up material %s", name.c_str());
     if ( material->IsMixture() )  {
       double A_total = 0.0;
       double W_total = 0.0;
@@ -354,8 +355,8 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
         TGeoElement* e = mix->GetElement(i);
         G4Element* g4e = (G4Element*) handleElement(e->GetName(), Atom(e));
         if (!g4e) {
-          printout(ERROR, "Material", 
-                   "Missing component %s for material %s. A=%f W=%f", 
+          printout(ERROR, name, 
+                   "Missing element component %s for material %s. A=%f W=%f", 
                    e->GetName(), mix->GetName(), A_total, W_total);
         }
         //mat->AddElement(g4e, (mix->GetAmixt())[i] / A_total);
@@ -379,15 +380,15 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       TGDMLMatrix* matrix = info.manager->GetGDMLMatrix(named->GetTitle());
       const char*  cptr   = ::strstr(matrix->GetName(), GEANT4_TAG_IGNORE);
       if ( 0 != cptr )   {
-	printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-		 matrix->GetName(), matrix->GetTitle());
-	continue;
+        printout(INFO,name,"++ Ignore property %s [%s]. Not Suitable for Geant4.",
+                 matrix->GetName(), matrix->GetTitle());
+        continue;
       }
       cptr = ::strstr(matrix->GetTitle(), GEANT4_TAG_IGNORE);
       if ( 0 != cptr )   {
-	printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-		 matrix->GetName(), matrix->GetTitle());
-	continue;
+        printout(INFO,name,"++ Ignore property %s [%s]. Not Suitable for Geant4.",
+                 matrix->GetName(), matrix->GetTitle());
+        continue;
       }
       Geant4GeometryInfo::PropertyVector* v =
         (Geant4GeometryInfo::PropertyVector*)handleMaterialProperties(matrix);
@@ -412,7 +413,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       }
       if ( idx < 0 )   {
         printout(ERROR, "Geant4Converter",
-                 "++ UNKNOWN Geant4 CONST Property: %-20s %s [IGNORED]",
+                 "++ UNKNOWN Geant4 Property: %-20s %s [IGNORED]",
                  exc_str.c_str(), named->GetName());
         continue;
       }
@@ -423,13 +424,13 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
         bins[i] *= conv.first, vals[i] *= conv.second;
 
       G4MaterialPropertyVector* vec =
-	new G4MaterialPropertyVector(&bins[0], &vals[0], bins.size());
+        new G4MaterialPropertyVector(&bins[0], &vals[0], bins.size());
       tab->AddProperty(named->GetName(), vec);
-      printout(lvl, "Geant4Converter", "++      Property: %-20s [%ld x %ld] -> %s ",
+      printout(lvl, name, "++      Property: %-20s [%ld x %ld] -> %s ",
                named->GetName(), matrix->GetRows(), matrix->GetCols(), named->GetTitle());
       for(size_t i=0, count=v->bins.size(); i<count; ++i)
-        printout(lvl,named->GetName(),"  Geant4: %8.3g [MeV]  TGeo: %8.3g [GeV] Conversion: %8.3g",
-                 bins[i], v->bins[i], conv.first);
+        printout(lvl, name, "  Geant4: %s %8.3g [MeV]  TGeo: %8.3g [GeV] Conversion: %8.3g",
+                 named->GetName(), bins[i], v->bins[i], conv.first);
     }
     /// Attach the material properties if any
     TListIter cpropIt(&material->GetConstProperties());
@@ -440,19 +441,19 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
 
       const char*  cptr = ::strstr(named->GetName(), GEANT4_TAG_IGNORE);
       if ( 0 != cptr )   {
-	printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-		 named->GetName(), named->GetTitle());
-	continue;
+        printout(INFO, name, "++ Ignore CONST property %s [%s].",
+                 named->GetName(), named->GetTitle());
+        continue;
       }
       cptr = ::strstr(named->GetTitle(), GEANT4_TAG_IGNORE);
       if ( 0 != cptr )   {
-	printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-		 named->GetName(), named->GetTitle());
-	continue;
+        printout(INFO, name,"++ Ignore CONST property %s [%s].",
+                 named->GetName(), named->GetTitle());
+        continue;
       }
       double v = info.manager->GetProperty(named->GetTitle(),&err);
       if ( err != kFALSE )   {
-        except("Geant4Converter",
+        except(name,
                "++ FAILED to create G4 material %s "
                "[Cannot convert const property: %s]",
                material->GetName(), named->GetName());
@@ -473,14 +474,14 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
         idx = -1;
       }
       if ( idx < 0 )   {
-        printout(ERROR, "Geant4Converter",
+        printout(ERROR, name,
                  "++ UNKNOWN Geant4 CONST Property: %-20s %s [IGNORED]",
                  exc_str.c_str(), named->GetName());
         continue;
       }
       // We need to convert the property from TGeo units to Geant4 units
       double conv = g4ConstPropertyConversion(idx);
-      printout(lvl, "Geant4Converter", "++      CONST Property: %-20s %g ", named->GetName(), v);
+      printout(lvl, name, "++      CONST Property: %-20s %g ", named->GetName(), v);
       tab->AddConstProperty(named->GetName(), v * conv);
     }
 #endif
@@ -491,7 +492,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
       str << "              log(MEE): " << ionization->GetLogMeanExcEnergy();
     else
       str << "              log(MEE): UNKNOWN";
-    printout(lvl, "Geant4Converter", "++ Created G4 material %s", str.str().c_str());
+    printout(lvl, name, "++ Created G4 material %s", str.str().c_str());
     info.g4Materials[medium] = mat;
   }
   return mat;
@@ -562,9 +563,9 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
       G4Scale3D        scal(vals[0], vals[1], vals[2]);
       G4VSolid* g4solid = (G4VSolid*)handleSolid(sol->GetName(), sol);
       if ( scal.xx()>0e0 && scal.yy()>0e0 && scal.zz()>0e0 )
-	solid = new G4ScaledSolid(sh->GetName(), g4solid, scal);
+        solid = new G4ScaledSolid(sh->GetName(), g4solid, scal);
       else
-	solid = new G4ReflectedSolid(g4solid->GetName()+"_refl", g4solid, scal);
+        solid = new G4ReflectedSolid(g4solid->GetName()+"_refl", g4solid, scal);
 #else
       except("Geant4Converter","++ TGeoScaledShape are only supported by Geant4 for versions >= 10.3");
 #endif
@@ -753,16 +754,16 @@ void* Geant4Converter::handleAssembly(const string& name, const TGeoNode* node)
       MyTransform3D transform(tr->GetTranslation(),tr->IsRotation() ? tr->GetRotationMatrix() : s_identity_rot);
 
       if ( is_left_handed(tr) )   {
-	G4Scale3D     scale;
-	G4Rotate3D    rot;
-	G4Translate3D trans;
-	transform.getDecomposition(scale, rot, trans);
-	printout(debugReflections ? ALWAYS : lvl, "Geant4Converter",
-		 "++ Placing reflected ASSEMBLY. dau:%s to mother %s "
-		 "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
+        G4Scale3D     scale;
+        G4Rotate3D    rot;
+        G4Translate3D trans;
+        transform.getDecomposition(scale, rot, trans);
+        printout(debugReflections ? ALWAYS : lvl, "Geant4Converter",
+                 "++ Placing reflected ASSEMBLY. dau:%s to mother %s "
+                 "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
                  dau_vol->GetName(), mot_vol->GetName(),
                  transform.dx(), transform.dy(), transform.dz(),
-		 scale.xx(), scale.yy(), scale.zz());
+                 scale.xx(), scale.yy(), scale.zz());
       }
 
       if ( dau_vol->IsA() == TGeoVolumeAssembly::Class() )  {
@@ -817,12 +818,12 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
     TGeoMatrix* tr = node->GetMatrix();
     if ( !tr ) {
       except("Geant4Converter",
-	     "++ Attempt to handle placement without transformation:%p %s of type %s vol:%p",
-	     node, node->GetName(), node->IsA()->GetName(), vol);
+             "++ Attempt to handle placement without transformation:%p %s of type %s vol:%p",
+             node, node->GetName(), node->IsA()->GetName(), vol);
     }
     else if (0 == vol) {
       except("Geant4Converter", "++ Unknown G4 volume:%p %s of type %s ptr:%p",
-	     node, node->GetName(), node->IsA()->GetName(), vol);
+             node, node->GetName(), node->IsA()->GetName(), vol);
     }
     else {
       int           copy               = node->GetNumber();
@@ -857,9 +858,9 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
         printout(lvl, "Geant4Converter", "++ Assembly: makeImprint: dau:%-12s %s in mother %-12s "
                  "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
                  node->GetName(), node_is_reflected ? "(REFLECTED)" : "",
-		 mot_vol ? mot_vol->GetName() : "<unknown>",
+                 mot_vol ? mot_vol->GetName() : "<unknown>",
                  transform.dx(), transform.dy(), transform.dz(),
-		 scale.xx(), scale.yy(), scale.zz());
+                 scale.xx(), scale.yy(), scale.zz());
         Geant4AssemblyVolume* ass = (Geant4AssemblyVolume*)info.g4AssemblyVolumes[node];
         Geant4AssemblyVolume::Chain chain;
         chain.emplace_back(node);
@@ -880,12 +881,12 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node)
                                                copy,      // its copy number
                                                checkOverlaps);
       printout(debugReflections||debugPlacements ? ALWAYS : lvl, "Geant4Converter",
-	       "++ Place %svolume %-12s in mother %-12s "
-	       "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
-	       node_is_reflected ? "REFLECTED " : "", _v.name(),
-	       mot_vol ? mot_vol->GetName() : "<unknown>",
-	       transform.dx(), transform.dy(), transform.dz(),
-	       scale.xx(), scale.yy(), scale.zz());
+               "++ Place %svolume %-12s in mother %-12s "
+               "Tr:x=%8.1f y=%8.1f z=%8.1f   Scale:x=%4.2f y=%4.2f z=%4.2f",
+               node_is_reflected ? "REFLECTED " : "", _v.name(),
+               mot_vol ? mot_vol->GetName() : "<unknown>",
+               transform.dx(), transform.dy(), transform.dz(),
+               scale.xx(), scale.yy(), scale.zz());
       // First 2 cases can be combined.
       // Leave them separated for debugging G4ReflectionFactory for now...
       if ( node_is_reflected  && !pvPlaced.second )
@@ -1086,13 +1087,13 @@ void* Geant4Converter::handleMaterialProperties(TObject* mtx) const    {
 
   if ( 0 != cptr )   {  // Check if the property should not be passed to Geant4
     printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-	     matrix->GetName(), matrix->GetTitle());	     
+             matrix->GetName(), matrix->GetTitle());	     
     return nullptr;
   }
   cptr = ::strstr(matrix->GetTitle(), GEANT4_TAG_IGNORE);
   if ( 0 != cptr )   {  // Check if the property should not be passed to Geant4
     printout(INFO,"Geant4MaterialProperties","++ Ignore property %s [%s].",
-	     matrix->GetName(), matrix->GetTitle());
+             matrix->GetName(), matrix->GetTitle());
     return nullptr;
   }
   
@@ -1109,7 +1110,7 @@ void* Geant4Converter::handleMaterialProperties(TObject* mtx) const    {
       g4->values.emplace_back(matrix->Get(i,1));
     }
     printout(lvl, "Geant4Converter",
-	     "++ Successfully converted material property:%s : %s [%ld rows]",
+             "++ Successfully converted material property:%s : %s [%ld rows]",
              matrix->GetName(), matrix->GetTitle(), rows);
     info.g4OpticalProperties[matrix] = g4;
   }
@@ -1232,7 +1233,7 @@ void* Geant4Converter::handleOpticalSurface(TObject* surface) const    {
       TGDMLMatrix* matrix = info.manager->GetGDMLMatrix(named->GetTitle());
       const char*  cptr   = ::strstr(matrix->GetName(), GEANT4_TAG_IGNORE);
       if ( 0 != cptr )  // Check if the property should not be passed to Geant4
-	continue;
+        continue;
 
       if ( 0 == tab )  {
         tab = new G4MaterialPropertiesTable();
@@ -1426,7 +1427,7 @@ namespace  {
     for (typename C::const_iterator i = c.begin(); i != c.end(); ++i)  {
       const auto& cc = (*i).second;
       for (const auto& j : cc)   {
-	(o->*pmf)(j);
+        (o->*pmf)(j);
       }
     }
   }
diff --git a/examples/ClientTests/src/MaterialTester_geo.cpp b/examples/ClientTests/src/MaterialTester_geo.cpp
index 653ada20e..b84c70023 100644
--- a/examples/ClientTests/src/MaterialTester_geo.cpp
+++ b/examples/ClientTests/src/MaterialTester_geo.cpp
@@ -37,6 +37,15 @@ static Ref_t create_element(Detector& description, xml_h xml_det, SensitiveDetec
   Assembly     assembly(det_name+"_assembly");
   DetElement   det(det_name,x_det.typeStr(), x_det.id());
 
+  if ( x_det.hasChild(_U(box)) )    {
+    xml_det_t xbox = x_det.child(_U(box));
+    Volume box = Volume(det_name+"_box",
+                        Box(xbox.x(), xbox.y(), xbox.z()),
+                        description.material(xbox.attr<string>(_U(material))));
+    PlacedVolume place = assembly.placeVolume(box);
+    place.addPhysVolID("box",0);
+  }
+  
   for(xml_coll_t k(x_det,_Unicode(test)); k; ++k)  {	
     xml_comp_t c = k;
     Material mat = description.material(c.nameStr());
@@ -66,6 +75,37 @@ static Ref_t create_element(Detector& description, xml_h xml_det, SensitiveDetec
                  mix->GetAmixt()[i],wmix ? wmix[i] : -1e0);
       }
     }
+    if ( material->GetNproperties() > 0 )    {
+      printout(INFO,det_name,"+++          Properties: %d", material->GetNproperties());
+      for(Int_t i=0, n=material->GetNproperties(); i<n; ++i)  {
+        TGDMLMatrix* m = material->GetProperty(i);
+        printout(INFO,det_name,"+++                   \"%s\" [%s] rows:%d cols:%d",
+                 m->GetName(), m->GetTitle(), m->GetRows(), m->GetCols());
+        m->Print();
+      }
+      printout(INFO,det_name,"+++          Properties by NAME:");
+      for(Int_t i=0, n=material->GetNproperties(); i<n; ++i)  {
+        const auto* name = material->GetProperties().At(i)->GetName();
+        const auto* m = material->GetProperty(name);
+        printout(INFO,det_name,"+++                   \"%s\" [%s,%s] cols: %d rows: %d", name,
+                 m->GetName(), m->GetTitle(), m->GetCols(), m->GetRows());
+      }
+    }
+    if ( material->GetNconstProperties() > 0 )    {
+      printout(INFO,det_name,"+++          CONST Properties: %d", material->GetNconstProperties());
+      const TList& all = material->GetConstProperties();
+      for(Int_t i=0, n=material->GetNconstProperties(); i<n; ++i)  {
+        const TNamed* m = (const TNamed*)all.At(i);
+        double        v = material->GetConstProperty(i);
+        printout(INFO,det_name,"+++                   \"%s\" [%s] value: %f", m->GetName(), m->GetTitle(), v);
+      }
+      printout(INFO,det_name,"+++          CONST Properties by NAME:");
+      for(Int_t i=0, n=material->GetNconstProperties(); i<n; ++i)  {
+        const auto* name = material->GetConstProperties().At(i)->GetName();
+        double v = material->GetConstProperty(name);
+        printout(INFO,det_name,"+++                   \"%s\"  value: %f", name, v);
+      }
+    }
   }
 
   printout(INFO,det_name,"+++ Basic units:");
diff --git a/examples/OpticalSurfaces/compact/ReadMaterialProperties.xml b/examples/OpticalSurfaces/compact/ReadMaterialProperties.xml
index 481291d10..c8c493516 100644
--- a/examples/OpticalSurfaces/compact/ReadMaterialProperties.xml
+++ b/examples/OpticalSurfaces/compact/ReadMaterialProperties.xml
@@ -20,6 +20,10 @@
     <comment>Test reading of TGeo's Material Properties</comment>
   </info>
 
+  <debug>
+    <type name="materials" value="1"/>
+  </debug>
+
   <define>
     <constant name="world_side" value="1*m"/>
     <constant name="world_x" value="world_side/2"/>
@@ -200,11 +204,26 @@
               4.136*eV 
     "/>
     </ignore>
+
+    <matrix name= "Water__SpecialMine" option="Geant4-ignore" coldim="1" values="  
+              2.034*eV 
+              2.068*eV 
+              2.103*eV 
+              2.139*eV 
+              2.177*eV 
+              2.216*eV 
+    "/>
   </properties>
 
   <includes>
     <gdmlFile  ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
   </includes>
+
+  <properties>
+    <constant name="Birk__Water|Geant4-ignore" value="12.345678"/>
+    <constant name="Water__Mine|Geant4-ignore" value="87.654321"/>
+  </properties>
+
   <materials>
     <material name="Air">
       <D type="density" unit="g/cm3" value="0.0012"/>
@@ -227,6 +246,24 @@
       <property name="ABSLENGTH"     ref="ABSLENGTH__0x123aff00"/>
       <property name="FASTCOMPONENT" ref="FASTCOMPONENT__0x123aff00"/>
       <property name="SLOWCOMPONENT" ref="SLOWCOMPONENT__0x123aff00"/>
+      <!-- Properties ignored by Geant4 -->
+      <property name="Property_of_mine" ref="Water__SpecialMine"/>
+      <constant name="BirksConstant"    ref="Birk__Water|Geant4-ignore"/>
+      <!-- Constants  ignored by Geant4 -->
+      <constant name="Constant_of_mine" ref="Water__Mine|Geant4-ignore"/>
     </material>
   </materials>
+
+  <readouts>
+    <readout name="Hits">
+      <id>system:8,box:8</id>
+    </readout>
+  </readouts>
+    
+  <detectors>
+    <detector id="1" name="MaterialTester" type="MaterialTester" readout="Hits">
+      <box x="50*cm" y="50*cm" z="50*cm" material="Water"/>
+      <test name="Water"/>
+    </detector>
+  </detectors>
 </lccdd>
diff --git a/examples/OpticalSurfaces/scripts/ReadMaterialProperties.py b/examples/OpticalSurfaces/scripts/ReadMaterialProperties.py
new file mode 100644
index 000000000..5b4cd3df3
--- /dev/null
+++ b/examples/OpticalSurfaces/scripts/ReadMaterialProperties.py
@@ -0,0 +1,75 @@
+# ==========================================================================
+#  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.
+#
+# ==========================================================================
+#
+from __future__ import absolute_import, unicode_literals
+import os
+import sys
+import DDG4
+from DDG4 import OutputLevel as Output
+from g4units import keV
+#
+#
+"""
+
+   dd4hep simulation example setup using the python configuration
+
+   @author  M.Frank
+   @version 1.0
+
+"""
+
+
+def run():
+  kernel = DDG4.Kernel()
+  install_dir = os.environ['DD4hepExamplesINSTALL']
+  kernel.loadGeometry(str("file:" + install_dir + "/examples/OpticalSurfaces/compact/ReadMaterialProperties.xml"))
+
+  DDG4.importConstants(kernel.detectorDescription(), debug=False)
+  geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction')
+  geant4.printDetectors()
+  # Configure UI
+  if len(sys.argv) > 1:
+    geant4.setupCshUI(macro=sys.argv[1])
+  else:
+    geant4.setupCshUI()
+
+  # Configure field
+  geant4.setupTrackingField(prt=True)
+  # Configure Event actions
+  prt = DDG4.EventAction(kernel, 'Geant4ParticlePrint/ParticlePrint')
+  prt.OutputLevel = Output.DEBUG
+  prt.OutputType = 3  # Print both: table and tree
+  kernel.eventAction().adopt(prt)
+
+  generator_output_level = Output.INFO
+
+  # Configure G4 geometry setup
+  seq, act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo")
+  act.DebugMaterials = True
+  act.DebugVolumes   = True
+  act.DebugShapes    = True
+
+
+  # Setup particle gun
+  gun = geant4.setupGun("Gun", particle='gamma', energy=5 * keV, multiplicity=1)
+  gun.OutputLevel = generator_output_level
+
+  geant4.setupTracker('MaterialTester')
+
+  # Now build the physics list:
+  phys = geant4.setupPhysics('QGSP_BERT')
+  phys.dump()
+
+  geant4.execute()
+
+
+if __name__ == "__main__":
+  run()
-- 
GitLab