From 93c18d6078ffab92999b6f871581c686e52ca44b Mon Sep 17 00:00:00 2001
From: Andre Sailer <andre.philippe.sailer@cern.ch>
Date: Fri, 9 Oct 2015 17:07:24 +0000
Subject: [PATCH] ddsim: check input for some gun options, better error
 handling when something goes wrong

---
 DDSim/DD4hepSimulation.py       | 22 ++++++++++++-------
 DDSim/Helper/ConfigHelper.py    | 29 +++++++++++++++++++++++-
 DDSim/Helper/Gun.py             | 39 ++++++++++++++++++++++++++++++---
 DDSim/Helper/ParticleHandler.py |  2 +-
 4 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/DDSim/DD4hepSimulation.py b/DDSim/DD4hepSimulation.py
index 089f840a3..ee9eb3e6f 100644
--- a/DDSim/DD4hepSimulation.py
+++ b/DDSim/DD4hepSimulation.py
@@ -434,12 +434,16 @@ class DD4hepSimulation(object):
 
   def __setGunOptions(self, gun):
     """set the starting properties of the DDG4 particle gun"""
-    gun.energy       = self.gun.energy
-    gun.particle     = self.gun.particle
-    gun.multiplicity = self.gun.multiplicity
-    gun.position     = self.gun.position
-    gun.isotrop      = self.gun.isotrop
-    gun.direction    = self.gun.direction
+    try:
+      gun.energy       = self.gun.energy
+      gun.particle     = self.gun.particle
+      gun.multiplicity = self.gun.multiplicity
+      gun.position     = self.gun.position
+      gun.isotrop      = self.gun.isotrop
+      gun.direction    = self.gun.direction
+    except Exception as e: #pylint: disable=W0703
+      print "ERROR: parsing gun options:\n%s\nException: %s " % (self.gun, e )
+      exit(1)
 
   def __setupRandomGenerator(self, rndm):
     """set the properties for the random number generator"""
@@ -510,8 +514,10 @@ class DD4hepSimulation(object):
         for var in obj.getOptions():
           key = "%s.%s" %( name,var )
           if key in parsedDict:
-            obj.setOption( var, parsedDict[key] )
-
+            try:
+              obj.setOption( var, parsedDict[key] )
+            except RuntimeError as e:
+              self.errorMessages.append( "ERROR: %s " % e )
 
   def __checkOutputLevel(self, level):
     """return outputlevel as int so we don't have to import anything for faster startup"""
diff --git a/DDSim/Helper/ConfigHelper.py b/DDSim/Helper/ConfigHelper.py
index 942e9e738..644946012 100644
--- a/DDSim/Helper/ConfigHelper.py
+++ b/DDSim/Helper/ConfigHelper.py
@@ -43,9 +43,36 @@ class ConfigHelper( object ):
     setattr(self, name, val)
 
   @staticmethod
-  def listifyString( stringVal, sep=" "):
+  def makeList( stringVal, sep=" "):
     """returns a list from a string separated by sep"""
     if isinstance( stringVal, list ):
       return stringVal
     else:
       return stringVal.split(sep)
+
+  @staticmethod
+  def makeTuple( val ):
+    """ returns a tuple of the string, separators are space or comma """
+    myTuple = None
+    if isinstance( val, tuple ):
+      myTuple = val
+    if isinstance( val, list ):
+      myTuple = tuple(val)
+    if isinstance( val, basestring ):
+      sep = ',' if ',' in val else ' '
+      myTuple = tuple([ _.strip("(), ") for _ in val.split(sep) ])
+    if myTuple is None:
+      raise RuntimeError( "Cannot parse input value %s" % val )
+    return myTuple
+
+  @staticmethod
+  def makeBool( val ):
+    """check if val is a bool or a string of true/false, otherwise raise exception"""
+    if isinstance(val, bool):
+      return val
+    elif isinstance(val, basestring):
+      if val.lower() == 'true':
+        return True
+      elif val.lower() == 'false':
+        return False
+    raise RuntimeError( val )
diff --git a/DDSim/Helper/Gun.py b/DDSim/Helper/Gun.py
index 0babf1d3b..5db30c158 100644
--- a/DDSim/Helper/Gun.py
+++ b/DDSim/Helper/Gun.py
@@ -10,8 +10,41 @@ class Gun( ConfigHelper ):
     self.energy = 10*GeV
     self.particle = "mu-"
     self.multiplicity = 1
-    self.position = (0.0,0.0,0.0)
-    self.isotrop = False
-    self.direction = (0,0,1)
+    self._position = (0.0,0.0,0.0)
+    self._isotrop = False
+    self._direction = (0,0,1)
 
+  @property
+  def isotrop( self ):
+    """ isotropic distribution for the particle gun """
+    return self._isotrop
+  @isotrop.setter
+  def isotrop( self, val ):
+    """check that value is equivalent to bool"""
+    try:
+      self._isotrop = ConfigHelper.makeBool( val )
+    except RuntimeError:
+      raise RuntimeError( "malformed input '%s' for gun.isotrop " % val)
 
+  @property
+  def direction( self ):
+    """ direction of the particle gun, 3 vector """
+    return self._direction
+  @direction.setter
+  def direction( self, val ):
+    """ make sure the direction is parseable by boost, i.e. (1.0, 1.0, 1.0) """
+    self._direction = ConfigHelper.makeTuple( val )
+    if len(self._direction) != 3:
+      raise RuntimeError(" gun.direction: malformed input '%s', needs to be a string representing a three vector " % val )
+
+
+  @property
+  def position( self ):
+    """ position of the particle gun, 3 vector """
+    return self._position
+  @position.setter
+  def position( self, val ):
+    """check that the position is a three vector and can be parsed by ddg4"""
+    self._position = ConfigHelper.makeTuple( val )
+    if len(self._position) != 3:
+      raise RuntimeError(" gun.position: malformed input '%s', needs to be a string representing a three vector " % val )
diff --git a/DDSim/Helper/ParticleHandler.py b/DDSim/Helper/ParticleHandler.py
index 641ff5d21..a2f078286 100644
--- a/DDSim/Helper/ParticleHandler.py
+++ b/DDSim/Helper/ParticleHandler.py
@@ -19,7 +19,7 @@ class ParticleHandler( ConfigHelper ):
     return self._saveProcesses
   @saveProcesses.setter
   def saveProcesses(self, stringVal):
-    self._saveProcesses = ConfigHelper.listifyString( stringVal )
+    self._saveProcesses = ConfigHelper.makeList( stringVal )
 
   @property
   def minimalKineticEnergy(self):
-- 
GitLab