From 68fee3a62ceccbf6a33331794feff77f3083c74f Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Thu, 8 Jan 2015 12:53:17 +0000
Subject: [PATCH] Improve exception handling in LCDDImp and DDG4 output writing

---
 DDCore/src/LCDDImp.cpp                 | 34 +++++++++++++-------------
 DDG4/examples/CLICSidSimuMarkus.py     |  8 +++---
 DDG4/include/DDG4/Geant4OutputAction.h |  4 ++-
 DDG4/src/Geant4Kernel.cpp              | 10 +++++++-
 DDG4/src/Geant4OutputAction.cpp        | 29 +++++++++++++++++++---
 UtilityApps/src/materialScan.cpp       |  7 +++---
 6 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index 9e34b39bd..210e0c1a5 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -57,24 +57,24 @@ namespace {
     }
   };
   static LCDD* s_lcdd = 0;
-}
 
-void lcdd_unexpected(){
-  try{
-    throw ;
-  }catch( std::exception& e){
-    std::cout << "\n"
-              << "**************************************************** \n"
-              << "*  A runtime error has occured :                     \n"
-              << "*    " << e.what()   << std::endl
-              << "*  the program will have to be terminated - sorry.   \n"
-              << "**************************************************** \n"
-              << std::endl ;
-
-    std::set_unexpected( std::unexpected ) ;
-    std::set_terminate( std::terminate ) ;
-    // this provokes ROOT seg fault and stack trace (comment out to avoid it)
-    exit(1) ;
+  void lcdd_unexpected()    {
+    try  {
+      throw;
+    }  catch( std::exception& e){
+      std::cout << "\n"
+		<< "**************************************************** \n"
+		<< "*  A runtime error has occured :                     \n"
+		<< "*    " << e.what()   << std::endl
+		<< "*  the program will have to be terminated - sorry.   \n"
+		<< "**************************************************** \n"
+		<< std::endl ;
+
+      std::set_unexpected( std::unexpected ) ;
+      std::set_terminate( std::terminate ) ;
+      // this provokes ROOT seg fault and stack trace (comment out to avoid it)
+      ::_exit(1) ;
+    }
   }
 }
 
diff --git a/DDG4/examples/CLICSidSimuMarkus.py b/DDG4/examples/CLICSidSimuMarkus.py
index d6a6056ed..15c822c49 100644
--- a/DDG4/examples/CLICSidSimuMarkus.py
+++ b/DDG4/examples/CLICSidSimuMarkus.py
@@ -41,7 +41,7 @@ def run():
   generator_output_level = Output.WARNING
 
   # Configure I/O
-  ##evt_lcio = simple.setupLCIOOutput('LcioOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
+  evt_lcio = simple.setupLCIOOutput('LcioOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
   ##evt_lcio.OutputLevel = generator_output_level
   evt_root = simple.setupROOTOutput('RootOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
 
@@ -53,7 +53,7 @@ def run():
   # First particle file reader
   gen = DDG4.GeneratorAction(kernel,"LCIOInputAction/LCIO1");
   #gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/e2e2nn_gen_1343_1.stdhep"
-  gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/qq_gen_128_999.stdhep"
+  #gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/qq_gen_128_999.stdhep"
   #gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/smuonLR_PointK_3TeV_BS_noBkg_run0001.stdhep"
   #gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/bbbb_3TeV.stdhep"
   #gen.Input = "LCIOFileReader|/home/frankm/SW/data/mcparticles_pi-_5GeV.slcio"
@@ -62,7 +62,7 @@ def run():
   #gen.Input = "LCIOStdHepReader|/home/frankm/SW/data/FCC-eh.stdhep"
   #gen.Input = "Geant4EventReaderHepMC|/home/frankm/SW/data/data.hepmc.txt"
   #gen.Input = "Geant4EventReaderHepMC|/home/frankm/SW/data/sherpa-2.1.1_zjets.hepmc2g"
-  #gen.Input = "LCIOFileReader|/afs/cern.ch/user/n/nikiforo/public/Markus/muons.slcio"
+  gen.Input = "LCIOFileReader|/afs/cern.ch/user/n/nikiforo/public/Markus/muons.slcio"
   #gen.Input = "LCIOFileReader|/afs/cern.ch/user/n/nikiforo/public/Markus/geantinos.slcio"
   gen.MomentumScale = 1.0
   gen.Mask = 1
@@ -74,7 +74,6 @@ def run():
   gen.direction = (1,0,0)
   gen.OutputLevel = generator_output_level
   """
-  """
   # And handle the simulation particles.
   part = DDG4.GeneratorAction(kernel,"Geant4ParticleHandler/ParticleHandler")
   kernel.generatorAction().adopt(part)
@@ -90,6 +89,7 @@ def run():
   part.adopt(user)
   """
   """
+  """
   rdr = DDG4.GeneratorAction(kernel,"LcioGeneratorAction/Reader")
   rdr.zSpread = 0.0
   rdr.lorentzAngle = 0.0
diff --git a/DDG4/include/DDG4/Geant4OutputAction.h b/DDG4/include/DDG4/Geant4OutputAction.h
index 15b10d6c4..e7efac725 100644
--- a/DDG4/include/DDG4/Geant4OutputAction.h
+++ b/DDG4/include/DDG4/Geant4OutputAction.h
@@ -48,8 +48,10 @@ namespace DD4hep {
         }
       };
 
-      /// Property: output destination
+      /// Property: "Output" output destination
       std::string m_output;
+      /// Property: "HandleErrorsAsFatal" Handle errors as fatal and rethrow eventual exceptions
+      bool        m_errorFatal;
       /// Reference to MC truth object
       Geant4ParticleMap* m_truth;
     public:
diff --git a/DDG4/src/Geant4Kernel.cpp b/DDG4/src/Geant4Kernel.cpp
index 6736095f8..4d652ca34 100644
--- a/DDG4/src/Geant4Kernel.cpp
+++ b/DDG4/src/Geant4Kernel.cpp
@@ -190,7 +190,15 @@ void Geant4Kernel::initialize() {
 }
 
 void Geant4Kernel::run() {
-  Geant4Exec::run(*this);
+  try  {
+    Geant4Exec::run(*this);
+  }
+  catch(const exception& e)   {
+    printout(FATAL,"Geant4Kernel","+++ Exception while simulating:%s",e.what());
+  }
+  catch(...)   {
+    printout(FATAL,"Geant4Kernel","+++ UNKNOWN exception while simulating.");
+  }
 }
 
 void Geant4Kernel::runEvents(int num_events) {
diff --git a/DDG4/src/Geant4OutputAction.cpp b/DDG4/src/Geant4OutputAction.cpp
index e6c48c9fb..4c54f82be 100644
--- a/DDG4/src/Geant4OutputAction.cpp
+++ b/DDG4/src/Geant4OutputAction.cpp
@@ -28,6 +28,7 @@ Geant4OutputAction::Geant4OutputAction(Geant4Context* ctxt, const string& nam)
 {
   InstanceCount::increment(this);
   declareProperty("Output", m_output);
+  declareProperty("HandleErrorsAsFatal", m_errorFatal=true);
   context()->runAction().callAtBegin(this, &Geant4OutputAction::beginRun);
   context()->runAction().callAtEnd(this, &Geant4OutputAction::endRun);
 }
@@ -54,14 +55,34 @@ void Geant4OutputAction::end(const G4Event* evt) {
 	printout(WARNING,name(),"+++ [Event:%d] No valid MC truth info present. "
 		 "Is a Particle handler installed ?",evt->GetEventID());
       }
-      saveEvent(ctxt);
-      for (int i = 0; i < nCol; ++i) {
-	G4VHitsCollection* hc = hce->GetHC(i);
-	saveCollection(ctxt, hc);
+      try  {
+	saveEvent(ctxt);
+	for (int i = 0; i < nCol; ++i) {
+	  G4VHitsCollection* hc = hce->GetHC(i);
+	  saveCollection(ctxt, hc);
+	}
+      }
+      catch(const exception& e)   {
+	printout(ERROR,name(),"+++ [Event:%d] Exception while saving event:%s",
+		 evt->GetEventID(),e.what());
+	if ( m_errorFatal ) throw;
+      }
+      catch(...)   {
+	printout(ERROR,name(),"+++ [Event:%d] UNKNWON Exception while saving event",
+		 evt->GetEventID());
+	if ( m_errorFatal ) throw;
       }
       commit(ctxt);
     }
+    catch(const exception& e)   {
+      printout(ERROR,name(),"+++ [Event:%d] Exception while saving event:%s",
+	       evt->GetEventID(),e.what());
+      if ( m_errorFatal ) throw;
+    }
     catch(...)   {
+      printout(ERROR,name(),"+++ [Event:%d] UNKNWON Exception while saving event",
+	       evt->GetEventID());
+      if ( m_errorFatal ) throw;
     }
     m_truth = 0;
     return;
diff --git a/UtilityApps/src/materialScan.cpp b/UtilityApps/src/materialScan.cpp
index f62feecbf..0a3d06393 100644
--- a/UtilityApps/src/materialScan.cpp
+++ b/UtilityApps/src/materialScan.cpp
@@ -66,10 +66,10 @@ int main(int argc, char** argv)   {
 
   for( unsigned i=0,n=materials.size();i<n;++i){
     TGeoMaterial* mat =  materials[i].first->GetMaterial();
-    double length = materials[i].second ;
-    double nx0 = length / mat->GetRadLen() ;
+    double length = materials[i].second;
+    double nx0 = length / mat->GetRadLen();
     sum_x0 += nx0;
-    double nLambda = length / mat->GetIntLen() ;
+    double nLambda = length / mat->GetIntLen();
     sum_lambda += nLambda;
     path_length += length;
     end = path_length * direction;
@@ -77,6 +77,7 @@ int main(int argc, char** argv)   {
     ::printf(fmt, i+1, mat->GetName(), mat->GetZ(), mat->GetA(),
 	     mat->GetDensity(), mat->GetRadLen(), mat->GetIntLen(), 
 	     length, path_length, sum_x0, sum_lambda, end[0], end[1], end[2]);
+    //mat->Print();
   }
   printf("%s",line);
   const MaterialData& avg = matMgr.createAveragedMaterial(materials);
-- 
GitLab