import warnings
from hepi.input import Order
from .. import Input, Result, get_output_dir
import re
from uncertainties import ufloat_fromstr
from string import Template
import pkgutil
import os
import shutil
[docs]class ResumminoResult(Result):
"""
Resummino Result Data.
Attributes:
VNLO (double): virtual NLO result.
RNLO (double): real NLO result.
P_PLUS_K (double): collineare remainders P+K NLO result.
RNLOG (double): real NLO gluon result.
RNLOQ (double): real NLO quark result.
VNLO_PLUS_P_PLUS_K (double): VNLO+P+K result.
RNLO_PLUS_VNLO_PLUS_P_PLUS_K (double): RNLO+VNLO+P+K result.
"""
def __init__(self, lo, nlo, nlo_plus_nll, annlo_plus_nnll, vnlo, p_plus_k,
rnlog, rnloq):
"""
Sets given and computes dependent ``Attributes``.
Args:
lo (:obj:`double`): corresponds to :attr:`LO`.
nlo (:obj:`double`): corresponds to :attr:`NLO`.
nlo_plus_nll (:obj:`double`): corresponds to :attr:`NLO_PLUS_NLL`.
vnlo (:obj:`double`): corresponds to :attr:`VNLO`.
p_plus_k (:obj:`double`): corresponds to :attr:`P_PLUS_K`.
rnlog (:obj:`double`): corresponds to :attr:`RNLOG`.
rnloq (:obj:`double`): corresponds to :attr:`RNLOQ`.
"""
Result.__init__(self, lo, nlo, nlo_plus_nll, annlo_plus_nnll)
self.VNLO = vnlo
self.P_PLUS_K = p_plus_k
self.RNLOG = rnlog
self.RNLOQ = rnloq
if not (vnlo is None or p_plus_k is None):
self.VNLO_PLUS_P_PLUS_K = self.VNLO + self.P_PLUS_K
else:
self.VNLO_PLUS_P_PLUS_K = None
if not (rnlog is None or rnloq is None):
self.RNLO = rnlog + rnloq
else:
self.RNLO = None
if not (self.RNLO is None or self.VNLO_PLUS_P_PLUS_K is None):
self.RNLO_PLUS_VNLO_PLUS_P_PLUS_K = self.RNLO + self.VNLO_PLUS_P_PLUS_K
else:
self.RNLO_PLUS_VNLO_PLUS_P_PLUS_K = None
[docs]def is_valid(file: str, p: Input, d,**kwargs) -> bool:
"""
Verifies that an file is a complete output.
Args:
file (str): File path to be parsed.
p (:class:`hepi.Input`): Onput parameters.
d (:obj:`dict`): Param dictionary.
Returns:
bool : True if `file` could be parsed.
"""
order = p.order
data = pkgutil.get_data(__name__, "plot_template.in").decode('utf-8')
src = Template(data)
result = src.substitute(d)
sname = d['slha']
with open(file, mode='r') as f:
with open(get_output_dir() + sname, 'r') as sf:
if not kwargs['ignore_error'] and not f.read().startswith(result + "\n\n" + sf.read()):
warnings.warn(
"Possible hash collision in " + file + " -> moved to " +
file + ".old", RuntimeWarning)
shutil.move(file, file + ".old")
return False
res = parse_single(file)
if res.LO is not None and order is Order.LO:
return True
if res.LO is not None and res.NLO is not None and order is Order.NLO:
return True
if res.LO is not None and res.NLO is not None and res.NLO_PLUS_NLL is not None and order is Order.NLO_PLUS_NLL:
return True
if res.LO is not None and res.NLO is not None and res.aNNLO_PLUS_NNLL is not None and order is Order.aNNLO_PLUS_NNLL:
return True
print("RESTART", res.LO, res.NLO, res.NLO_PLUS_NLL, file)
return False
[docs]def parse_single(file: str) -> ResumminoResult:
"""
Extracts LO, NLO and NLO+NLL from Resummino output file.
Args:
file (str): File path to be parsed.
Returns:
:class:`ResumminoResult` : If a value is not found in the file None is used.
"""
# TODO aNNLO+ NNLL support?
# TODO generalize units like RS
lo_pattern = re.compile(r'^LO = \((.*)\) pb')
nlo_pattern = re.compile(r'^NLO = \((.*)\) pb')
nll_pattern = re.compile(r'^NLO\+NLL = \((.*)\) pb')
nnll_pattern = re.compile(r'^aNNLO\+NNLL = \((.*)\) pb')
vnlo_pattern = re.compile(r'^vNLO = \((.*)\) pb')
ppk_pattern = re.compile(r'^P\+K = \((.*)\) pb')
rnlog_pattern = re.compile(r'^rNLOg = \((.*)\) pb')
rnloq_pattern = re.compile(r'^rNLOq = \((.*)\) pb')
lo_result = None
nlo_result = None
nll_result = None
nnll_result = None
vnlo_result = None
ppk_result = None
rnlog_result = None
rnloq_result = None
with open(file) as output:
for line in output:
tmp = lo_pattern.search(line)
if tmp is not None:
lo_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = nlo_pattern.search(line)
if tmp is not None:
nlo_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = nll_pattern.search(line)
if tmp is not None:
nll_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = nnll_pattern.search(line)
if tmp is not None:
nnll_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = vnlo_pattern.search(line)
if tmp is not None:
vnlo_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = ppk_pattern.search(line)
if tmp is not None:
ppk_result = ufloat_fromstr(tmp.group(1).replace("+-", "+/-"))
tmp = rnlog_pattern.search(line)
if tmp is not None:
rnlog_result = ufloat_fromstr(
tmp.group(1).replace("+-", "+/-"))
tmp = rnloq_pattern.search(line)
if tmp is not None:
rnloq_result = ufloat_fromstr(
tmp.group(1).replace("+-", "+/-"))
return ResumminoResult(lo_result, nlo_result, nll_result, nnll_result,
vnlo_result, ppk_result, rnlog_result, rnloq_result)