From 606d7b8a0f0486067b5a08b43e2200a87e60a624 Mon Sep 17 00:00:00 2001
From: James Robinson <james.robinson@cern.ch>
Date: Tue, 12 Jun 2018 13:07:23 +0000
Subject: [PATCH] PHOTOS updates for PowhegControl

Former-commit-id: 39ce2775877ed3acb58ad79706bd1e5e91a0e2e9
---
 .../python/algorithms/postprocessors/madspin.py       |  8 +++++---
 .../algorithms/postprocessors/nnlo_reweighter.py      |  8 +++++---
 .../python/algorithms/postprocessors/photos.py        |  3 +++
 .../PowhegControl/python/parameters/registry.py       |  2 +-
 Generators/PowhegControl/python/powheg_control.py     |  4 ++--
 .../python/processes/external/external_photos.py      |  6 ++++--
 .../PowhegControl/python/processes/powheg/W_EW.py     | 10 ++++++++--
 .../PowhegControl/python/processes/powheg/Z_EW.py     | 11 +++++++++--
 8 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/Generators/PowhegControl/python/algorithms/postprocessors/madspin.py b/Generators/PowhegControl/python/algorithms/postprocessors/madspin.py
index 756eed44d8f..222dfd09375 100644
--- a/Generators/PowhegControl/python/algorithms/postprocessors/madspin.py
+++ b/Generators/PowhegControl/python/algorithms/postprocessors/madspin.py
@@ -1,12 +1,12 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon import Logging
-from ...decorators import timed
-from ...utility import LHE, ProcessManager, SingleProcessThread
 import glob
 import os
 import shutil
 import subprocess
+from AthenaCommon import Logging
+from ...decorators import timed
+from ...utility import LHE, ProcessManager, SingleProcessThread
 
 ## Get handle to Athena logging
 logger = Logging.logging.getLogger("PowhegControl")
@@ -250,6 +250,8 @@ def __run_executable(executable):
 
     @author James Robinson <james.robinson@cern.ch>
     """
+    if not os.path.isfile(executable):
+        raise OSError("MadSpin executable {} not found!".format(executable))
     logger.info("MadSpin executable: {}".format(executable))
     with open("madspin_runcard.txt", "rb") as runcard_input:
         processes = [SingleProcessThread([executable], stdin=runcard_input, ignore_output=["INFO:", "MadSpin>"])]
diff --git a/Generators/PowhegControl/python/algorithms/postprocessors/nnlo_reweighter.py b/Generators/PowhegControl/python/algorithms/postprocessors/nnlo_reweighter.py
index 0a45841e43e..35074ab55df 100644
--- a/Generators/PowhegControl/python/algorithms/postprocessors/nnlo_reweighter.py
+++ b/Generators/PowhegControl/python/algorithms/postprocessors/nnlo_reweighter.py
@@ -1,12 +1,12 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
-from AthenaCommon import Logging
-from ...decorators import timed
-from ...utility import LHE, ProcessManager, SingleProcessThread
 import glob
 import os
 import re
 import shutil
+from AthenaCommon import Logging
+from ...decorators import timed
+from ...utility import LHE, ProcessManager, SingleProcessThread
 from xml.etree import ElementTree
 
 
@@ -97,6 +97,8 @@ def run_NNLOPS_executable(NNLO_executable, NNLO_reweighting_inputs, NNLO_weight_
         f_input_card.write("</initrwgt>\n")
 
     # Run the executable until finished
+    if not os.path.isfile(NNLO_executable):
+        raise OSError("NNLO reweighting executable {} not found!".format(NNLO_executable))
     manager = ProcessManager([SingleProcessThread(NNLO_executable)])
     while manager.monitor():
         pass
diff --git a/Generators/PowhegControl/python/algorithms/postprocessors/photos.py b/Generators/PowhegControl/python/algorithms/postprocessors/photos.py
index 7285bbdddac..9f9e0028855 100644
--- a/Generators/PowhegControl/python/algorithms/postprocessors/photos.py
+++ b/Generators/PowhegControl/python/algorithms/postprocessors/photos.py
@@ -1,5 +1,6 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
+import os
 from AthenaCommon import Logging
 from ...decorators import timed
 from ...utility import ProcessManager, SingleProcessThread
@@ -17,6 +18,8 @@ def PHOTOS(process):
     @author James Robinson <james.robinson@cern.ch>
     """
     logger.info("Running PHOTOS afterburner")
+    if not os.path.isfile(process.executable):
+        raise OSError("PHOTOS executable {} not found!".format(process.executable))
     processes = [SingleProcessThread(process.executable)]
     manager = ProcessManager(processes)
     while manager.monitor():
diff --git a/Generators/PowhegControl/python/parameters/registry.py b/Generators/PowhegControl/python/parameters/registry.py
index 56558fb976b..bf282c50c00 100644
--- a/Generators/PowhegControl/python/parameters/registry.py
+++ b/Generators/PowhegControl/python/parameters/registry.py
@@ -324,7 +324,7 @@ class Registry(object):
         self.add_default("pdfreweight", 1, frozen=True, description="store PDF information. Deprecated for processes with XML-reweighting. [1:enabled]")
         self.add_default("Phasespace", 1, name="phasespace", description="phasespace to use. [1:standard; 2:use separate unweighted events from event.total.lhe as input]")
         self.add_default("photoninduced", -1, description="[-1:use Powheg default]")
-        self.add_default("PHOTOS_enabled", 1, description="use PHOTOS for photon radiation. [1:enabled]")
+        self.add_default("PHOTOS_enabled", True, description="use PHOTOS for photon radiation. [False:disabled; True:enabled]")
         self.add_default("phsp_Wm", atlas_common.mass.W, name="mass_W", description="W boson mass in GeV")
         self.add_default("phsp_Ww", atlas_common.width.W, name="width_W", description="W boson width in GeV")
         self.add_default("phsp_Zm", atlas_common.mass.Z, name="mass_Z", description="Z boson mass in GeV")
diff --git a/Generators/PowhegControl/python/powheg_control.py b/Generators/PowhegControl/python/powheg_control.py
index 6b2cae9bfef..0f001cf79df 100644
--- a/Generators/PowhegControl/python/powheg_control.py
+++ b/Generators/PowhegControl/python/powheg_control.py
@@ -147,14 +147,14 @@ class PowhegControl(object):
         logger.info("|     Option name     |    ATLAS default    |                     Description                     |")
         logger.info("===================================================================================================")
         for parameter in [p for p in parameters_sorted if p.is_visible]:
-            logger.info("| {:<19} | {:>19} | {}".format(parameter.name, parameter.default_value, parameter.description))
+            logger.info("| {:<19} | {:>19} | {}".format(parameter.name, str(parameter.default_value), parameter.description))
         logger.info("==================================================================================================")
 
         # Print list of parameters that have been changed by the user
         parameters_changed = [p for p in parameters_sorted if p.value != p.default_value]
         logger.info("In these jobOptions {} parameter(s) have been changed from their default value:".format(len(parameters_changed)))
         for idx, parameter in enumerate(parameters_changed):
-            logger.info("  {:<3} {:<19} {:>15} => {}".format("{})".format(idx + 1), "{}:".format(parameter.name), parameter.default_value, parameter.value))
+            logger.info("  {:<3} {:<19} {:>15} => {}".format("{})".format(idx + 1), "{}:".format(parameter.name), str(parameter.default_value), parameter.value))
 
         # Validate any parameters which need validation/processing
         self.process.validate_parameters()
diff --git a/Generators/PowhegControl/python/processes/external/external_photos.py b/Generators/PowhegControl/python/processes/external/external_photos.py
index 20dcfb03cd9..e925257b934 100644
--- a/Generators/PowhegControl/python/processes/external/external_photos.py
+++ b/Generators/PowhegControl/python/processes/external/external_photos.py
@@ -30,7 +30,9 @@ class ExternalPHOTOS(ExternalBase):
         """
         # Check that PHOTOS is not disabled
         self.expose()
-        if self.PHOTOS_enabled != 1:
-            logger.warning("PHOTOS not enabled")
+        if self.PHOTOS_enabled:
+            logger.info("Running with PHOTOS enabled")
+        else:
+            logger.info("Running without PHOTOS")
             return False
         return True
diff --git a/Generators/PowhegControl/python/processes/powheg/W_EW.py b/Generators/PowhegControl/python/processes/powheg/W_EW.py
index c0e807db1ea..8b91c295462 100644
--- a/Generators/PowhegControl/python/processes/powheg/W_EW.py
+++ b/Generators/PowhegControl/python/processes/powheg/W_EW.py
@@ -1,9 +1,9 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
+import os
 from AthenaCommon import Logging
 from ..external import ExternalPHOTOS
 from ..powheg_V2 import PowhegV2
-import os
 
 ## Get handle to Athena logging
 logger = Logging.logging.getLogger("PowhegControl")
@@ -171,7 +171,13 @@ class W_EW(PowhegV2):
         self.add_keyword("Zwidth")
 
     def validate_decays(self):
-        """! Validate idvecbos and vdecaymode keywords."""
+        """! Validate idvecbos and vdecaymode keywords and check that 'no_ew' is compatible with 'PHOTOS_enabled'."""
+        # If PHOTOS is disabled but EW effects are on, any subsequent PHOTOS process will have to run in vetoed mode which is not supported
+        if not self.externals["PHOTOS"].parameters_by_keyword("PHOTOS_enabled")[0].value and self.parameters_by_keyword("no_ew")[0].value == 0:
+            logger.error("Attempting to run with native PHOTOS disabled but with EW corrections on.")
+            logger.error("This would require any later PHOTOS generation to run in vetoed mode.")
+            logger.error("Please change 'PHOTOS_enabled' and/or 'no_ew' in your jobOptions.")
+            raise ValueError("Incompatible options. Please change 'PHOTOS_enabled' and/or 'no_ew' in your jobOptions.")
         self.expose()  # convenience call to simplify syntax
         self.check_decay_mode(self.decay_mode, self.allowed_decay_modes)
         # Calculate appropriate decay mode numbers
diff --git a/Generators/PowhegControl/python/processes/powheg/Z_EW.py b/Generators/PowhegControl/python/processes/powheg/Z_EW.py
index 1a3ab806e5a..2e34535ce78 100644
--- a/Generators/PowhegControl/python/processes/powheg/Z_EW.py
+++ b/Generators/PowhegControl/python/processes/powheg/Z_EW.py
@@ -1,13 +1,14 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
+import os
 from AthenaCommon import Logging
 from ..external import ExternalPHOTOS
 from ..powheg_V2 import PowhegV2
-import os
 
 ## Get handle to Athena logging
 logger = Logging.logging.getLogger("PowhegControl")
 
+
 class Z_EW(PowhegV2):
     """! Default Powheg configuration for single Z-boson production with electroweak corrections.
 
@@ -170,7 +171,13 @@ class Z_EW(PowhegV2):
         self.add_keyword("Zwidth")
 
     def validate_decays(self):
-        """! Validate vdecaymode keyword."""
+        """! Validate vdecaymode keyword and check that 'no_ew' is compatible with 'PHOTOS_enabled'."""
+        # If PHOTOS is disabled but EW effects are on, any subsequent PHOTOS process will have to run in vetoed mode which is not supported
+        if not self.externals["PHOTOS"].parameters_by_keyword("PHOTOS_enabled")[0].value and self.parameters_by_keyword("no_ew")[0].value == 0:
+            logger.error("Attempting to run with native PHOTOS disabled but with EW corrections on.")
+            logger.error("This would require any later PHOTOS generation to run in vetoed mode.")
+            logger.error("Please change 'PHOTOS_enabled' and/or 'no_ew' in your jobOptions.")
+            raise ValueError("Incompatible options. Please change 'PHOTOS_enabled' and/or 'no_ew' in your jobOptions.")
         self.expose()  # convenience call to simplify syntax
         self.check_decay_mode(self.decay_mode, self.allowed_decay_modes)
         # Calculate appropriate decay mode numbers
-- 
GitLab