ATLAS Offline Software
integration_grid_tester.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 
3 from AthenaCommon import Logging
4 from ...decorators import timed
5 import glob
6 import math
7 import re
8 
9 
10 logger = Logging.logging.getLogger("PowhegControl")
11 
12 
13 regex_match_floats = r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?"
14 # [+-]? * # first, match an optional sign (and space)
15 # (?: # then match integers or f.p. mantissas:
16 # \d+ # start out with a ...
17 # (?:
18 # \.\d* # mantissa of the form a.b or a.
19 # )? # ? takes care of integers of the form a
20 # |\.\d+ # mantissa of the form .b
21 # )
22 # (?:[eE][+-]?\d+)? # finally, optionally match an exponent
23 
24 
25 @timed("integration grid testing")
27  """! Calculate and output integration grid quality.
28 
29  Read in integration quality metrics from output files.
30  Allow any check to fail, since this output is not a critical part of generation.
31 
32  @author James Robinson <james.robinson@cern.ch>
33  """
34  inclusive_xs, inclusive_xs_error, negative_weights, positive_weights, n_events, n_upper_bound_failures_xs, n_upper_bound_failures_radiation = 0, 0, 0, 0, 0, 0, 0
35  # Open stat files
36  for file_name in sum([glob.glob(_f) for _f in ["pwgstat.dat", "pwgstat-0001.dat", "pwg-stat.dat", "pwg-st3-0001-stat.dat", "pwg-0001-st3-stat.dat"]], []):
37  # Inclusive cross-section uncertainty [relative error on (total pos + |total neg|)]
38  with open(file_name, "r") as data_file:
39  try:
40  matched_lines = [line.replace("+-", "") for line in data_file if re.match(r"(.*)(btilde(.*)weights)(.*)[0-9](.*)\+\-(.*)[0-9](.*)", line)]
41  matched_lines = [re.sub(" +", " ", _l) for _l in matched_lines] # strip multiple whitespace
42  if len(matched_lines) > 0:
43  positive_weight_xs = sum([list(map(float, re.findall(regex_match_floats, line))) for line in matched_lines if "pos." in line],[])
44  negative_weight_xs = sum([list(map(float, re.findall(regex_match_floats, line))) for line in matched_lines if "|neg.|" in line], [])
45  inclusive_xs += positive_weight_xs[0] + negative_weight_xs[0]
46  inclusive_xs_error += math.sqrt(positive_weight_xs[1]**2 + negative_weight_xs[1]**2)
47  except Exception: # catch all exceptions
48  pass
49  # Negative weight test
50  with open(file_name, "r") as data_file:
51  try:
52  matched_lines = [line.replace("+-", "") for line in data_file if re.match(r"(.*)(btilde(.*)weights|Remnant cross section)(.*)[0-9](.*)\+\-(.*)[0-9](.*)", line)]
53  matched_lines = [re.sub(" +", " ", _l) for _l in matched_lines] # strip multiple whitespace
54  if len(matched_lines) > 0:
55  negative_weights += list(map(float, re.findall(regex_match_floats, [line for line in matched_lines if "btilde |neg.|" in line][0])))[0]
56  positive_weights += list(map(float, re.findall(regex_match_floats, [line for line in matched_lines if "btilde pos." in line][0])))[0]
57  positive_weights += list(map(float, re.findall(regex_match_floats, [line for line in matched_lines if "Remnant cross section" in line][0])))[0]
58  except Exception: # catch all exceptions
59  pass
60  # Open counter files
61  file_names = sum([glob.glob(_f) for _f in ["pwgcounters-st4-*.dat", "pwgcounters0*.dat"]], [])
62  if not file_names: file_names = glob.glob("pwgcounters.dat")
63  for file_name in file_names:
64  # Upper bound violations [in inclusive cross-section and generation of radiation]
65  with open(file_name, "r") as data_file:
66  try:
67  matched_lines = [line.replace("+-", "") for line in data_file if re.match(r"(.*)(btilde event|remnant event|upper bound failure)(.*)[0-9](.*)", line)]
68  matched_lines = [re.sub(" +", " ", _l) for _l in matched_lines] # strip multiple whitespace
69  if len(matched_lines) > 0:
70  n_events += sum(list(map(float, [re.findall(regex_match_floats, line)[0] for line in matched_lines if "event" in line])))
71  n_upper_bound_failures_xs += sum(list(map(float, [re.findall(regex_match_floats, line)[0] for line in matched_lines if "upper bound failure in inclusive" in line])))
72  n_upper_bound_failures_radiation += sum(list(map(float, [re.findall(regex_match_floats, line)[0] for line in matched_lines if "upper bound failure in generation" in line])))
73  except Exception: # catch all exceptions
74  pass
75 
76  # Calculate test statistics
77  inclusive_xs_test = safe_percentage(inclusive_xs_error, inclusive_xs)
78  negative_weight_test = safe_percentage(negative_weights, (negative_weights + positive_weights))
79  upper_bound_test = safe_percentage((n_upper_bound_failures_xs + n_upper_bound_failures_radiation), n_events)
80  upper_bound_test_xs = safe_percentage(n_upper_bound_failures_xs, n_events)
81  upper_bound_test_radiation = safe_percentage(n_upper_bound_failures_radiation, n_events)
82 
83  # Write output
84  try:
85  getattr(logger, ["warning", "info"][0.0 <= inclusive_xs_test < 1.0])("Integration test :: {:>30} : {:.2f}%".format("cross-section uncertainty", inclusive_xs_test))
86  getattr(logger, ["warning", "info"][0.0 <= negative_weight_test < 1.0])("Integration test :: {:>30} : {:.2f}%".format("negative weight fraction", negative_weight_test))
87  getattr(logger, ["warning", "info"][0.0 <= upper_bound_test < 1.0])("Integration test :: {:>30} : {:.2f}%".format("upper bound violations", upper_bound_test))
88  logger.info(" -> {:>30} : {:.2f}%".format("in inclusive cross-section", upper_bound_test_xs))
89  logger.info(" -> {:>30} : {:.2f}%".format("in generation of radiation", upper_bound_test_radiation))
90  if any((inclusive_xs_test < 0.0, inclusive_xs_test >= 1.0, negative_weight_test < 0.0, negative_weight_test >= 1.0, upper_bound_test < 0.0, upper_bound_test >= 1.0)):
91  logger.warning("Not all integration tests passed. Please ensure that physics validation is done before using this sample!")
92  except Exception: # catch all exceptions
93  pass
94 
95 def safe_percentage(numerator, denominator):
96  try:
97  return 100 * numerator / denominator
98  except Exception: # catch all exceptions
99  return float("nan")
python.algorithms.postprocessors.integration_grid_tester.integration_grid_tester
def integration_grid_tester()
Calculate and output integration grid quality.
Definition: integration_grid_tester.py:26
python.algorithms.postprocessors.integration_grid_tester.safe_percentage
def safe_percentage(numerator, denominator)
Definition: integration_grid_tester.py:95
python.decorators.timed.timed
def timed(name)
Decorator to output function execution time.
Definition: timed.py:12
vtune_athena.format
format
Definition: vtune_athena.py:14
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
Trk::open
@ open
Definition: BinningType.h:40
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65