wilson.classes module
Main classes used at the top level of the wilson package:
Wilson
: main interface to the wilson package, providing automatic running
and matching in SMEFT and WET
RGsolution
: Class representing a continuous solution to the
SMEFT and WET RGEs to be used for plotting.
"""Main classes used at the top level of the wilson package: `Wilson`: main interface to the wilson package, providing automatic running and matching in SMEFT and WET `RGsolution`: Class representing a continuous solution to the SMEFT and WET RGEs to be used for plotting. """ from wilson.run.smeft import SMEFT from wilson.run.wet import WETrunner from wilson import parameters import numpy as np from math import log, e from wilson import wcxf import voluptuous as vol class ConfigurableClass: """Class that provides the functionality to set and get configuration options. Methods: - `set_option`: Set configuration option - `get_option`: Show configuration option - `set_default_option`: Class method! Set deault configuration option affecting only future instances of the class. """ # default config options: # dictionary with option name as 'key' and default option value as 'value' _default_options = {} # option schema: # Voluptuous schema defining allowed option values/types _option_schema = vol.Schema({}) def __init__(self): self._options = self._default_options.copy() @classmethod def set_default_option(cls, key, value): """Class method. Set the default value of the option `key` (string) to `value` for all future instances of the class. Note that this does not affect existing instances or the instance called from.""" cls._default_options.update(cls._option_schema({key: value})) def set_option(self, key, value): """Set the option `key` (string) to `value`. Instance method, affects only current instance. This will clear the cache.""" self._options.update(self._option_schema({key: value})) self.clear_cache() def get_option(self, key): """Return the current value of the option `key` (string). Instance method, only refers to current instance.""" return self._options.get(key, self._default_options[key]) class Wilson(ConfigurableClass): """Main interface to the wilson package, providing automatic running and matching in SMEFT and WET. Caching is used for intermediate results. Methods: - `from_wc`: Return a `Wilson` instance initialized by a `wcxf.WC` instance - `load_wc`: Return a `Wilson` instance initialized by a WCxf file-like object - `match_run`: Run the Wilson coefficients to a different scale (and possibly different EFT) and return them as `wcxf.WC` instance - `set_option`: Set configuration option - `get_option`: Show configuration option - `set_default_option`: Class method! Set deault configuration option affecting only future instances of the class. """ # default config options: # dictionary with option name as 'key' and default option value as 'value' _default_options = {'smeft_accuracy': 'integrate', 'qed_order': 1, 'qcd_order': 1, 'smeft_matching_order': 0, 'smeft_matchingscale': 91.1876, 'mb_matchingscale': 4.2, 'mc_matchingscale': 1.3, 'parameters': {}, } # option schema: # Voluptuous schema defining allowed option values/types _option_schema = vol.Schema({ 'smeft_accuracy': vol.In(['integrate','leadinglog']), 'qed_order': vol.In([0,1]), 'qcd_order': vol.In([0,1]), 'smeft_matching_order': vol.In([0,1]), 'smeft_matchingscale': vol.Coerce(float), 'mb_matchingscale': vol.Coerce(float), 'mc_matchingscale': vol.Coerce(float), 'parameters': vol.Schema({vol.Extra: vol.Coerce(float)}), }) def __init__(self, wcdict, scale, eft, basis): """Initialize the `Wilson` class. Parameters: - `wcdict`: dictionary of Wilson coefficient values at the input scale. The keys must exist as Wilson coefficients in the WCxf basis file. The values must be real or complex numbers (not dictionaries with key 'Re'/'Im'!) - `scale`: input scale in GeV - `eft`: input EFT - `basis`: input basis """ super().__init__() self.wc = wcxf.WC(eft=eft, basis=basis, scale=scale, values=wcxf.WC.dict2values(wcdict)) self.wc.validate() self._cache = {} def __hash__(self): """Return a hash of the `Wilson` instance. The hash changes when Wilson coefficient values or options are modified. It assumes that `wcxf.WC` instances are not modified after instantiation.""" return hash((self.wc, frozenset(self._options))) @classmethod def from_wc(cls, wc): """Return a `Wilson` instance initialized by a `wcxf.WC` instance""" return cls(wcdict=wc.dict, scale=wc.scale, eft=wc.eft, basis=wc.basis) @classmethod def load_wc(cls, stream): """Return a `Wilson` instance initialized by a WCxf file-like object""" wc = wcxf.WC.load(stream) return cls.from_wc(wc) def _repr_html_(self): r_wcxf = self.wc._repr_html_() r_wcxf = '\n'.join(r_wcxf.splitlines()[2:]) # remove WCxf heading html = "<h3>Wilson coefficients</h3>\n\n" html += r_wcxf return html @property def parameters(self): """Parameters to be used for running and translation.""" # start with a copy of the default parameters p = parameters.p.copy() # overwrite by the user defined parameters, if any p.update(self.get_option('parameters')) return p @property def matching_parameters(self): """Parameters to be used for the SMEFT->WET matching.""" # start with a copy of the numerical parameters p = self.parameters.copy() # properly set 'loop_order' for `match.smeft.match_all` p['loop_order'] = self.get_option('smeft_matching_order') return p def _wetrun_opt(self): """Return a dictionary of options to pass to a `run.wet.WETrunner` instance.""" return {'qed_order': self.get_option('qed_order'), 'qcd_order': self.get_option('qcd_order')} def match_run(self, scale, eft, basis, sectors='all'): """Run the Wilson coefficients to a different scale (and possibly different EFT) and return them as `wcxf.WC` instance. Parameters: - `scale`: output scale in GeV - `eft`: output EFT - `basis`: output basis - `sectors`: in the case of WET (or WET-4 or WET-3), a tuple of sector names can be optionally provided. In this case, only the Wilson coefficients from this sector(s) will be returned and all others discareded. This can speed up the computation significantly if only a small number of sectors is of interest. The sector names are defined in the WCxf basis file. """ cached = self._get_from_cache(sector=sectors, scale=scale, eft=eft, basis=basis) if cached is not None: return cached if sectors == 'all': # the default value for sectors is "None" for translators translate_sectors = None else: translate_sectors = sectors scale_ew = self.get_option('smeft_matchingscale') mb = self.get_option('mb_matchingscale') mc = self.get_option('mc_matchingscale') if self.wc.basis == basis and self.wc.eft == eft and scale == self.wc.scale: return self.wc # nothing to do if self.wc.eft == eft and scale == self.wc.scale: wc_out = self.wc.translate(basis, sectors=translate_sectors, parameters=self.parameters) # only translation necessary self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out if self.wc.eft == 'SMEFT': smeft_accuracy = self.get_option('smeft_accuracy') if eft == 'SMEFT': smeft = SMEFT(self.wc.translate('Warsaw', sectors=translate_sectors, parameters=self.parameters)) # if input and output EFT ist SMEFT, just run. wc_out = smeft.run(scale, accuracy=smeft_accuracy).translate(basis) self._set_cache('all', scale, 'SMEFT', wc_out.basis, wc_out) return wc_out else: # if SMEFT -> WET-x: match to WET at the EW scale wc_ew = self._get_from_cache(sector='all', scale=scale_ew, eft='WET', basis='JMS') if wc_ew is None: if self.wc.scale == scale_ew: wc_ew = self.wc.match('WET', 'JMS', parameters=self.matching_parameters) # no need to run else: smeft = SMEFT(self.wc.translate('Warsaw', parameters=self.parameters)) wc_ew = smeft.run(scale_ew, accuracy=smeft_accuracy).match('WET', 'JMS', parameters=self.matching_parameters) self._set_cache('all', scale_ew, wc_ew.eft, wc_ew.basis, wc_ew) wet = WETrunner(wc_ew, **self._wetrun_opt()) elif self.wc.eft in ['WET', 'WET-4', 'WET-3']: wet = WETrunner(self.wc.translate('JMS', parameters=self.parameters, sectors=translate_sectors), **self._wetrun_opt()) else: raise ValueError(f"Input EFT {self.wc.eft} unknown or not supported") if eft == wet.eft: # just run wc_out = wet.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out elif eft == 'WET-4' and wet.eft == 'WET': # match at mb wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_out = wet4.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-4', basis, wc_out) return wc_out elif eft == 'WET-3' and wet.eft == 'WET-4': # match at mc wc_mc = wet.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) return wc_out self._set_cache(sectors, scale, 'WET-3', basis, wc_out) elif eft == 'WET-3' and wet.eft == 'WET': # match at mb and mc wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_mc = wet4.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-3', basis, wc_out) return wc_out else: raise ValueError(f"Running from {wet.eft} to {eft} not implemented") def clear_cache(self): self._cache = {} def _get_from_cache(self, sector, scale, eft, basis): """Try to load a set of Wilson coefficients from the cache, else return None.""" try: return self._cache[eft][scale][basis][sector] except KeyError: return None def _set_cache(self, sector, scale, eft, basis, wc_out): if eft not in self._cache: self._cache[eft] = {scale: {basis: {sector: wc_out}}} elif scale not in self._cache[eft]: self._cache[eft][scale] = {basis: {sector: wc_out}} elif basis not in self._cache[eft][scale]: self._cache[eft][scale][basis] = {sector: wc_out} else: self._cache[eft][scale][basis][sector] = wc_out class RGsolution: """Class representing a continuous (interpolated) solution to the SMEFT RGEs to be used for plotting.""" def __init__(self, fun, scale_min, scale_max): """Initialize. Parameters: - fun: function of the scale that is expected to return a dictionary with the RGE solution and to accept vectorized input. - scale_min, scale_max: lower and upper boundaries of the scale """ self.fun = fun self.scale_min = scale_min self.scale_max = scale_max def plotdata(self, key, part='re', scale='log', steps=50): """Return a tuple of arrays x, y that can be fed to plt.plot, where x is the scale in GeV and y is the parameter of interest. Parameters: - key: dicionary key of the parameter to be plotted (e.g. a WCxf coefficient name or a SM parameter like 'g') - part: plot the real part 're' (default) or the imaginary part 'im' - scale: 'log'; make the x steps logarithmically distributed; for 'linear', linearly distributed - steps: steps in x to take (default: 50) """ if scale == 'log': x = np.logspace(log(self.scale_min), log(self.scale_max), steps, base=e) elif scale == 'linear': x = np.linspace(self.scale_min, self.scale_max, steps) y = self.fun(x) y = np.array([d[key] for d in y]) if part == 're': return x, y.real elif part == 'im': return x, y.imag def plot(self, key, part='re', scale='log', steps=50, legend=True, plotargs={}): """Plot the RG evolution of parameter `key`. Parameters: - part, scale, steps: see `plotdata` - legend: boolean, show the legend (default: True) - plotargs: dictionary of arguments to be passed to plt.plot """ try: import matplotlib.pyplot as plt except ImportError: raise ImportError("Please install matplotlib if you want to use the plot method") pdat = self.plotdata(key, part=part, scale=scale, steps=steps) plt.plot(*pdat, label=key, **plotargs) if scale == 'log': plt.xscale('log') if legend: plt.legend()
Module variables
var e
Classes
class ConfigurableClass
Class that provides the functionality to set and get configuration options.
Methods:
set_option
: Set configuration optionget_option
: Show configuration optionset_default_option
: Class method! Set deault configuration option affecting only future instances of the class.
class ConfigurableClass: """Class that provides the functionality to set and get configuration options. Methods: - `set_option`: Set configuration option - `get_option`: Show configuration option - `set_default_option`: Class method! Set deault configuration option affecting only future instances of the class. """ # default config options: # dictionary with option name as 'key' and default option value as 'value' _default_options = {} # option schema: # Voluptuous schema defining allowed option values/types _option_schema = vol.Schema({}) def __init__(self): self._options = self._default_options.copy() @classmethod def set_default_option(cls, key, value): """Class method. Set the default value of the option `key` (string) to `value` for all future instances of the class. Note that this does not affect existing instances or the instance called from.""" cls._default_options.update(cls._option_schema({key: value})) def set_option(self, key, value): """Set the option `key` (string) to `value`. Instance method, affects only current instance. This will clear the cache.""" self._options.update(self._option_schema({key: value})) self.clear_cache() def get_option(self, key): """Return the current value of the option `key` (string). Instance method, only refers to current instance.""" return self._options.get(key, self._default_options[key])
Ancestors (in MRO)
- ConfigurableClass
- builtins.object
Static methods
def __init__(
self)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self): self._options = self._default_options.copy()
def get_option(
self, key)
Return the current value of the option key
(string).
Instance method, only refers to current instance.
def get_option(self, key): """Return the current value of the option `key` (string). Instance method, only refers to current instance.""" return self._options.get(key, self._default_options[key])
def set_option(
self, key, value)
Set the option key
(string) to value
.
Instance method, affects only current instance. This will clear the cache.
def set_option(self, key, value): """Set the option `key` (string) to `value`. Instance method, affects only current instance. This will clear the cache.""" self._options.update(self._option_schema({key: value})) self.clear_cache()
Methods
def set_default_option(
cls, key, value)
Class method. Set the default value of the option key
(string)
to value
for all future instances of the class.
Note that this does not affect existing instances or the instance called from.
@classmethod def set_default_option(cls, key, value): """Class method. Set the default value of the option `key` (string) to `value` for all future instances of the class. Note that this does not affect existing instances or the instance called from.""" cls._default_options.update(cls._option_schema({key: value}))
class RGsolution
Class representing a continuous (interpolated) solution to the SMEFT RGEs to be used for plotting.
class RGsolution: """Class representing a continuous (interpolated) solution to the SMEFT RGEs to be used for plotting.""" def __init__(self, fun, scale_min, scale_max): """Initialize. Parameters: - fun: function of the scale that is expected to return a dictionary with the RGE solution and to accept vectorized input. - scale_min, scale_max: lower and upper boundaries of the scale """ self.fun = fun self.scale_min = scale_min self.scale_max = scale_max def plotdata(self, key, part='re', scale='log', steps=50): """Return a tuple of arrays x, y that can be fed to plt.plot, where x is the scale in GeV and y is the parameter of interest. Parameters: - key: dicionary key of the parameter to be plotted (e.g. a WCxf coefficient name or a SM parameter like 'g') - part: plot the real part 're' (default) or the imaginary part 'im' - scale: 'log'; make the x steps logarithmically distributed; for 'linear', linearly distributed - steps: steps in x to take (default: 50) """ if scale == 'log': x = np.logspace(log(self.scale_min), log(self.scale_max), steps, base=e) elif scale == 'linear': x = np.linspace(self.scale_min, self.scale_max, steps) y = self.fun(x) y = np.array([d[key] for d in y]) if part == 're': return x, y.real elif part == 'im': return x, y.imag def plot(self, key, part='re', scale='log', steps=50, legend=True, plotargs={}): """Plot the RG evolution of parameter `key`. Parameters: - part, scale, steps: see `plotdata` - legend: boolean, show the legend (default: True) - plotargs: dictionary of arguments to be passed to plt.plot """ try: import matplotlib.pyplot as plt except ImportError: raise ImportError("Please install matplotlib if you want to use the plot method") pdat = self.plotdata(key, part=part, scale=scale, steps=steps) plt.plot(*pdat, label=key, **plotargs) if scale == 'log': plt.xscale('log') if legend: plt.legend()
Ancestors (in MRO)
- RGsolution
- builtins.object
Static methods
def __init__(
self, fun, scale_min, scale_max)
Initialize.
Parameters:
- fun: function of the scale that is expected to return a dictionary with the RGE solution and to accept vectorized input.
- scale_min, scale_max: lower and upper boundaries of the scale
def __init__(self, fun, scale_min, scale_max): """Initialize. Parameters: - fun: function of the scale that is expected to return a dictionary with the RGE solution and to accept vectorized input. - scale_min, scale_max: lower and upper boundaries of the scale """ self.fun = fun self.scale_min = scale_min self.scale_max = scale_max
def plot(
self, key, part='re', scale='log', steps=50, legend=True, plotargs={})
Plot the RG evolution of parameter key
.
Parameters:
- part, scale, steps: see
plotdata
- legend: boolean, show the legend (default: True)
- plotargs: dictionary of arguments to be passed to plt.plot
def plot(self, key, part='re', scale='log', steps=50, legend=True, plotargs={}): """Plot the RG evolution of parameter `key`. Parameters: - part, scale, steps: see `plotdata` - legend: boolean, show the legend (default: True) - plotargs: dictionary of arguments to be passed to plt.plot """ try: import matplotlib.pyplot as plt except ImportError: raise ImportError("Please install matplotlib if you want to use the plot method") pdat = self.plotdata(key, part=part, scale=scale, steps=steps) plt.plot(*pdat, label=key, **plotargs) if scale == 'log': plt.xscale('log') if legend: plt.legend()
def plotdata(
self, key, part='re', scale='log', steps=50)
Return a tuple of arrays x, y that can be fed to plt.plot, where x is the scale in GeV and y is the parameter of interest.
Parameters:
- key: dicionary key of the parameter to be plotted (e.g. a WCxf coefficient name or a SM parameter like 'g')
- part: plot the real part 're' (default) or the imaginary part 'im'
- scale: 'log'; make the x steps logarithmically distributed; for 'linear', linearly distributed
- steps: steps in x to take (default: 50)
def plotdata(self, key, part='re', scale='log', steps=50): """Return a tuple of arrays x, y that can be fed to plt.plot, where x is the scale in GeV and y is the parameter of interest. Parameters: - key: dicionary key of the parameter to be plotted (e.g. a WCxf coefficient name or a SM parameter like 'g') - part: plot the real part 're' (default) or the imaginary part 'im' - scale: 'log'; make the x steps logarithmically distributed; for 'linear', linearly distributed - steps: steps in x to take (default: 50) """ if scale == 'log': x = np.logspace(log(self.scale_min), log(self.scale_max), steps, base=e) elif scale == 'linear': x = np.linspace(self.scale_min, self.scale_max, steps) y = self.fun(x) y = np.array([d[key] for d in y]) if part == 're': return x, y.real elif part == 'im': return x, y.imag
Instance variables
var fun
var scale_max
var scale_min
class Wilson
Main interface to the wilson package, providing automatic running and matching in SMEFT and WET.
Caching is used for intermediate results.
Methods:
from_wc
: Return aWilson
instance initialized by awcxf.WC
instanceload_wc
: Return aWilson
instance initialized by a WCxf file-like objectmatch_run
: Run the Wilson coefficients to a different scale (and possibly different EFT) and return them aswcxf.WC
instanceset_option
: Set configuration optionget_option
: Show configuration optionset_default_option
: Class method! Set deault configuration option affecting only future instances of the class.
class Wilson(ConfigurableClass): """Main interface to the wilson package, providing automatic running and matching in SMEFT and WET. Caching is used for intermediate results. Methods: - `from_wc`: Return a `Wilson` instance initialized by a `wcxf.WC` instance - `load_wc`: Return a `Wilson` instance initialized by a WCxf file-like object - `match_run`: Run the Wilson coefficients to a different scale (and possibly different EFT) and return them as `wcxf.WC` instance - `set_option`: Set configuration option - `get_option`: Show configuration option - `set_default_option`: Class method! Set deault configuration option affecting only future instances of the class. """ # default config options: # dictionary with option name as 'key' and default option value as 'value' _default_options = {'smeft_accuracy': 'integrate', 'qed_order': 1, 'qcd_order': 1, 'smeft_matching_order': 0, 'smeft_matchingscale': 91.1876, 'mb_matchingscale': 4.2, 'mc_matchingscale': 1.3, 'parameters': {}, } # option schema: # Voluptuous schema defining allowed option values/types _option_schema = vol.Schema({ 'smeft_accuracy': vol.In(['integrate','leadinglog']), 'qed_order': vol.In([0,1]), 'qcd_order': vol.In([0,1]), 'smeft_matching_order': vol.In([0,1]), 'smeft_matchingscale': vol.Coerce(float), 'mb_matchingscale': vol.Coerce(float), 'mc_matchingscale': vol.Coerce(float), 'parameters': vol.Schema({vol.Extra: vol.Coerce(float)}), }) def __init__(self, wcdict, scale, eft, basis): """Initialize the `Wilson` class. Parameters: - `wcdict`: dictionary of Wilson coefficient values at the input scale. The keys must exist as Wilson coefficients in the WCxf basis file. The values must be real or complex numbers (not dictionaries with key 'Re'/'Im'!) - `scale`: input scale in GeV - `eft`: input EFT - `basis`: input basis """ super().__init__() self.wc = wcxf.WC(eft=eft, basis=basis, scale=scale, values=wcxf.WC.dict2values(wcdict)) self.wc.validate() self._cache = {} def __hash__(self): """Return a hash of the `Wilson` instance. The hash changes when Wilson coefficient values or options are modified. It assumes that `wcxf.WC` instances are not modified after instantiation.""" return hash((self.wc, frozenset(self._options))) @classmethod def from_wc(cls, wc): """Return a `Wilson` instance initialized by a `wcxf.WC` instance""" return cls(wcdict=wc.dict, scale=wc.scale, eft=wc.eft, basis=wc.basis) @classmethod def load_wc(cls, stream): """Return a `Wilson` instance initialized by a WCxf file-like object""" wc = wcxf.WC.load(stream) return cls.from_wc(wc) def _repr_html_(self): r_wcxf = self.wc._repr_html_() r_wcxf = '\n'.join(r_wcxf.splitlines()[2:]) # remove WCxf heading html = "<h3>Wilson coefficients</h3>\n\n" html += r_wcxf return html @property def parameters(self): """Parameters to be used for running and translation.""" # start with a copy of the default parameters p = parameters.p.copy() # overwrite by the user defined parameters, if any p.update(self.get_option('parameters')) return p @property def matching_parameters(self): """Parameters to be used for the SMEFT->WET matching.""" # start with a copy of the numerical parameters p = self.parameters.copy() # properly set 'loop_order' for `match.smeft.match_all` p['loop_order'] = self.get_option('smeft_matching_order') return p def _wetrun_opt(self): """Return a dictionary of options to pass to a `run.wet.WETrunner` instance.""" return {'qed_order': self.get_option('qed_order'), 'qcd_order': self.get_option('qcd_order')} def match_run(self, scale, eft, basis, sectors='all'): """Run the Wilson coefficients to a different scale (and possibly different EFT) and return them as `wcxf.WC` instance. Parameters: - `scale`: output scale in GeV - `eft`: output EFT - `basis`: output basis - `sectors`: in the case of WET (or WET-4 or WET-3), a tuple of sector names can be optionally provided. In this case, only the Wilson coefficients from this sector(s) will be returned and all others discareded. This can speed up the computation significantly if only a small number of sectors is of interest. The sector names are defined in the WCxf basis file. """ cached = self._get_from_cache(sector=sectors, scale=scale, eft=eft, basis=basis) if cached is not None: return cached if sectors == 'all': # the default value for sectors is "None" for translators translate_sectors = None else: translate_sectors = sectors scale_ew = self.get_option('smeft_matchingscale') mb = self.get_option('mb_matchingscale') mc = self.get_option('mc_matchingscale') if self.wc.basis == basis and self.wc.eft == eft and scale == self.wc.scale: return self.wc # nothing to do if self.wc.eft == eft and scale == self.wc.scale: wc_out = self.wc.translate(basis, sectors=translate_sectors, parameters=self.parameters) # only translation necessary self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out if self.wc.eft == 'SMEFT': smeft_accuracy = self.get_option('smeft_accuracy') if eft == 'SMEFT': smeft = SMEFT(self.wc.translate('Warsaw', sectors=translate_sectors, parameters=self.parameters)) # if input and output EFT ist SMEFT, just run. wc_out = smeft.run(scale, accuracy=smeft_accuracy).translate(basis) self._set_cache('all', scale, 'SMEFT', wc_out.basis, wc_out) return wc_out else: # if SMEFT -> WET-x: match to WET at the EW scale wc_ew = self._get_from_cache(sector='all', scale=scale_ew, eft='WET', basis='JMS') if wc_ew is None: if self.wc.scale == scale_ew: wc_ew = self.wc.match('WET', 'JMS', parameters=self.matching_parameters) # no need to run else: smeft = SMEFT(self.wc.translate('Warsaw', parameters=self.parameters)) wc_ew = smeft.run(scale_ew, accuracy=smeft_accuracy).match('WET', 'JMS', parameters=self.matching_parameters) self._set_cache('all', scale_ew, wc_ew.eft, wc_ew.basis, wc_ew) wet = WETrunner(wc_ew, **self._wetrun_opt()) elif self.wc.eft in ['WET', 'WET-4', 'WET-3']: wet = WETrunner(self.wc.translate('JMS', parameters=self.parameters, sectors=translate_sectors), **self._wetrun_opt()) else: raise ValueError(f"Input EFT {self.wc.eft} unknown or not supported") if eft == wet.eft: # just run wc_out = wet.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out elif eft == 'WET-4' and wet.eft == 'WET': # match at mb wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_out = wet4.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-4', basis, wc_out) return wc_out elif eft == 'WET-3' and wet.eft == 'WET-4': # match at mc wc_mc = wet.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) return wc_out self._set_cache(sectors, scale, 'WET-3', basis, wc_out) elif eft == 'WET-3' and wet.eft == 'WET': # match at mb and mc wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_mc = wet4.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-3', basis, wc_out) return wc_out else: raise ValueError(f"Running from {wet.eft} to {eft} not implemented") def clear_cache(self): self._cache = {} def _get_from_cache(self, sector, scale, eft, basis): """Try to load a set of Wilson coefficients from the cache, else return None.""" try: return self._cache[eft][scale][basis][sector] except KeyError: return None def _set_cache(self, sector, scale, eft, basis, wc_out): if eft not in self._cache: self._cache[eft] = {scale: {basis: {sector: wc_out}}} elif scale not in self._cache[eft]: self._cache[eft][scale] = {basis: {sector: wc_out}} elif basis not in self._cache[eft][scale]: self._cache[eft][scale][basis] = {sector: wc_out} else: self._cache[eft][scale][basis][sector] = wc_out
Ancestors (in MRO)
- Wilson
- ConfigurableClass
- builtins.object
Static methods
def __init__(
self, wcdict, scale, eft, basis)
Initialize the Wilson
class.
Parameters:
wcdict
: dictionary of Wilson coefficient values at the input scale. The keys must exist as Wilson coefficients in the WCxf basis file. The values must be real or complex numbers (not dictionaries with key 'Re'/'Im'!)scale
: input scale in GeVeft
: input EFTbasis
: input basis
def __init__(self, wcdict, scale, eft, basis): """Initialize the `Wilson` class. Parameters: - `wcdict`: dictionary of Wilson coefficient values at the input scale. The keys must exist as Wilson coefficients in the WCxf basis file. The values must be real or complex numbers (not dictionaries with key 'Re'/'Im'!) - `scale`: input scale in GeV - `eft`: input EFT - `basis`: input basis """ super().__init__() self.wc = wcxf.WC(eft=eft, basis=basis, scale=scale, values=wcxf.WC.dict2values(wcdict)) self.wc.validate() self._cache = {}
def clear_cache(
self)
def clear_cache(self): self._cache = {}
def get_option(
self, key)
Return the current value of the option key
(string).
Instance method, only refers to current instance.
def get_option(self, key): """Return the current value of the option `key` (string). Instance method, only refers to current instance.""" return self._options.get(key, self._default_options[key])
def match_run(
self, scale, eft, basis, sectors='all')
Run the Wilson coefficients to a different scale
(and possibly different EFT)
and return them as wcxf.WC
instance.
Parameters:
scale
: output scale in GeVeft
: output EFTbasis
: output basissectors
: in the case of WET (or WET-4 or WET-3), a tuple of sector names can be optionally provided. In this case, only the Wilson coefficients from this sector(s) will be returned and all others discareded. This can speed up the computation significantly if only a small number of sectors is of interest. The sector names are defined in the WCxf basis file.
def match_run(self, scale, eft, basis, sectors='all'): """Run the Wilson coefficients to a different scale (and possibly different EFT) and return them as `wcxf.WC` instance. Parameters: - `scale`: output scale in GeV - `eft`: output EFT - `basis`: output basis - `sectors`: in the case of WET (or WET-4 or WET-3), a tuple of sector names can be optionally provided. In this case, only the Wilson coefficients from this sector(s) will be returned and all others discareded. This can speed up the computation significantly if only a small number of sectors is of interest. The sector names are defined in the WCxf basis file. """ cached = self._get_from_cache(sector=sectors, scale=scale, eft=eft, basis=basis) if cached is not None: return cached if sectors == 'all': # the default value for sectors is "None" for translators translate_sectors = None else: translate_sectors = sectors scale_ew = self.get_option('smeft_matchingscale') mb = self.get_option('mb_matchingscale') mc = self.get_option('mc_matchingscale') if self.wc.basis == basis and self.wc.eft == eft and scale == self.wc.scale: return self.wc # nothing to do if self.wc.eft == eft and scale == self.wc.scale: wc_out = self.wc.translate(basis, sectors=translate_sectors, parameters=self.parameters) # only translation necessary self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out if self.wc.eft == 'SMEFT': smeft_accuracy = self.get_option('smeft_accuracy') if eft == 'SMEFT': smeft = SMEFT(self.wc.translate('Warsaw', sectors=translate_sectors, parameters=self.parameters)) # if input and output EFT ist SMEFT, just run. wc_out = smeft.run(scale, accuracy=smeft_accuracy).translate(basis) self._set_cache('all', scale, 'SMEFT', wc_out.basis, wc_out) return wc_out else: # if SMEFT -> WET-x: match to WET at the EW scale wc_ew = self._get_from_cache(sector='all', scale=scale_ew, eft='WET', basis='JMS') if wc_ew is None: if self.wc.scale == scale_ew: wc_ew = self.wc.match('WET', 'JMS', parameters=self.matching_parameters) # no need to run else: smeft = SMEFT(self.wc.translate('Warsaw', parameters=self.parameters)) wc_ew = smeft.run(scale_ew, accuracy=smeft_accuracy).match('WET', 'JMS', parameters=self.matching_parameters) self._set_cache('all', scale_ew, wc_ew.eft, wc_ew.basis, wc_ew) wet = WETrunner(wc_ew, **self._wetrun_opt()) elif self.wc.eft in ['WET', 'WET-4', 'WET-3']: wet = WETrunner(self.wc.translate('JMS', parameters=self.parameters, sectors=translate_sectors), **self._wetrun_opt()) else: raise ValueError(f"Input EFT {self.wc.eft} unknown or not supported") if eft == wet.eft: # just run wc_out = wet.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, eft, basis, wc_out) return wc_out elif eft == 'WET-4' and wet.eft == 'WET': # match at mb wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_out = wet4.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-4', basis, wc_out) return wc_out elif eft == 'WET-3' and wet.eft == 'WET-4': # match at mc wc_mc = wet.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) return wc_out self._set_cache(sectors, scale, 'WET-3', basis, wc_out) elif eft == 'WET-3' and wet.eft == 'WET': # match at mb and mc wc_mb = wet.run(mb, sectors=sectors).match('WET-4', 'JMS', parameters=self.matching_parameters) wet4 = WETrunner(wc_mb, **self._wetrun_opt()) wc_mc = wet4.run(mc, sectors=sectors).match('WET-3', 'JMS', parameters=self.matching_parameters) wet3 = WETrunner(wc_mc, **self._wetrun_opt()) wc_out = wet3.run(scale, sectors=sectors).translate(basis, sectors=translate_sectors, parameters=self.parameters) self._set_cache(sectors, scale, 'WET-3', basis, wc_out) return wc_out else: raise ValueError(f"Running from {wet.eft} to {eft} not implemented")
def set_option(
self, key, value)
Set the option key
(string) to value
.
Instance method, affects only current instance. This will clear the cache.
def set_option(self, key, value): """Set the option `key` (string) to `value`. Instance method, affects only current instance. This will clear the cache.""" self._options.update(self._option_schema({key: value})) self.clear_cache()
Instance variables
var matching_parameters
Parameters to be used for the SMEFT->WET matching.
var parameters
Parameters to be used for running and translation.
var wc
Methods
def from_wc(
cls, wc)
Return a Wilson
instance initialized by a wcxf.WC
instance
@classmethod def from_wc(cls, wc): """Return a `Wilson` instance initialized by a `wcxf.WC` instance""" return cls(wcdict=wc.dict, scale=wc.scale, eft=wc.eft, basis=wc.basis)
def load_wc(
cls, stream)
Return a Wilson
instance initialized by a WCxf file-like object
@classmethod def load_wc(cls, stream): """Return a `Wilson` instance initialized by a WCxf file-like object""" wc = wcxf.WC.load(stream) return cls.from_wc(wc)
def set_default_option(
cls, key, value)
Class method. Set the default value of the option key
(string)
to value
for all future instances of the class.
Note that this does not affect existing instances or the instance called from.
@classmethod def set_default_option(cls, key, value): """Class method. Set the default value of the option `key` (string) to `value` for all future instances of the class. Note that this does not affect existing instances or the instance called from.""" cls._default_options.update(cls._option_schema({key: value}))