better sech pulse, improved evaluator
This commit is contained in:
@@ -576,6 +576,9 @@ class Rule:
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Rule(targets={self.targets!r}, func={self.func!r}, args={self.args!r})"
|
return f"Rule(targets={self.targets!r}, func={self.func!r}, args={self.args!r})"
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"[{', '.join(self.args)}] -- {self.func.__module__}.{self.func.__name__} --> [{', '.join(self.targets)}]"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def deduce(
|
def deduce(
|
||||||
cls,
|
cls,
|
||||||
@@ -649,7 +652,8 @@ class Evaluator:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.rules: dict[str, list[Rule]] = defaultdict(list)
|
self.rules: dict[str, list[Rule]] = defaultdict(list)
|
||||||
self.params = {}
|
self.params = {}
|
||||||
self.__curent_lookup = set()
|
self.__curent_lookup: list[str] = []
|
||||||
|
self.__failed_rules: dict[str, list[Rule]] = defaultdict(list)
|
||||||
self.eval_stats: dict[str, EvalStat] = defaultdict(EvalStat)
|
self.eval_stats: dict[str, EvalStat] = defaultdict(EvalStat)
|
||||||
self.logger = get_logger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
|
|
||||||
@@ -703,10 +707,11 @@ class Evaluator:
|
|||||||
raise EvaluatorError(
|
raise EvaluatorError(
|
||||||
"cyclic dependency detected : "
|
"cyclic dependency detected : "
|
||||||
f"{target!r} seems to depend on itself, "
|
f"{target!r} seems to depend on itself, "
|
||||||
f"please provide a value for at least one variable in {self.__curent_lookup}"
|
f"please provide a value for at least one variable in {self.__curent_lookup!r}. "
|
||||||
|
+ self.attempted_rules_str(target)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.__curent_lookup.add(target)
|
self.__curent_lookup.append(target)
|
||||||
|
|
||||||
if len(self.rules[target]) == 0:
|
if len(self.rules[target]) == 0:
|
||||||
error = EvaluatorError(f"no rule for {target}")
|
error = EvaluatorError(f"no rule for {target}")
|
||||||
@@ -753,23 +758,27 @@ class Evaluator:
|
|||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
prefix + f"error using {rule.func.__name__} : {str(error).strip()}"
|
prefix + f"error using {rule.func.__name__} : {str(error).strip()}"
|
||||||
)
|
)
|
||||||
|
self.__failed_rules[target].append(rule)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
default = self.get_default(target)
|
default = self.get_default(target)
|
||||||
if default is None:
|
if default is None:
|
||||||
error = error or NoDefaultError(
|
error = error or NoDefaultError(
|
||||||
prefix
|
prefix
|
||||||
+ f"No default provided for {target}. Current lookup cycle : {self.__curent_lookup!r}"
|
+ f"No default provided for {target}. Current lookup cycle : {self.__curent_lookup!r}. "
|
||||||
|
+ self.attempted_rules_str(target)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
value = default
|
value = default
|
||||||
self.logger.info(prefix + f"using default value of {value} for {target}")
|
self.logger.info(prefix + f"using default value of {value} for {target}")
|
||||||
self.set_value(target, value, 0)
|
self.set_value(target, value, 0)
|
||||||
|
|
||||||
|
assert target == self.__curent_lookup.pop()
|
||||||
|
self.__failed_rules[target] = []
|
||||||
|
|
||||||
if value is None and error is not None:
|
if value is None and error is not None:
|
||||||
raise error
|
raise error
|
||||||
|
|
||||||
self.__curent_lookup.remove(target)
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __getitem__(self, key: str) -> Any:
|
def __getitem__(self, key: str) -> Any:
|
||||||
@@ -782,23 +791,11 @@ class Evaluator:
|
|||||||
def validate_condition(self, rule: Rule) -> bool:
|
def validate_condition(self, rule: Rule) -> bool:
|
||||||
return all(self.compute(k) == v for k, v in rule.conditions.items())
|
return all(self.compute(k) == v for k, v in rule.conditions.items())
|
||||||
|
|
||||||
def __call__(self, target: str, args: list[str] = None):
|
def attempted_rules_str(self, target: str) -> str:
|
||||||
"""creates a wrapper that adds decorated functions to the set of rules
|
rules = ", ".join(str(r) for r in self.__failed_rules[target])
|
||||||
|
if len(rules) == 0:
|
||||||
Parameters
|
return ""
|
||||||
----------
|
return "attempted rules : " + rules
|
||||||
target : str
|
|
||||||
name of the target
|
|
||||||
args : list[str], optional
|
|
||||||
list of name of arguments. Automatically deduced from function signature if
|
|
||||||
not provided, by default None
|
|
||||||
"""
|
|
||||||
|
|
||||||
def wrapper(func):
|
|
||||||
self.append(Rule(target, func, args))
|
|
||||||
return func
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class Configuration:
|
class Configuration:
|
||||||
@@ -1095,9 +1092,9 @@ default_rules: list[Rule] = [
|
|||||||
),
|
),
|
||||||
Rule("peak_power", pulse.E0_to_P0, ["energy", "t0", "shape"]),
|
Rule("peak_power", pulse.E0_to_P0, ["energy", "t0", "shape"]),
|
||||||
Rule("peak_power", pulse.soliton_num_to_peak_power),
|
Rule("peak_power", pulse.soliton_num_to_peak_power),
|
||||||
|
Rule("mean_power", pulse.energy_to_mean_power),
|
||||||
Rule("energy", pulse.P0_to_E0, ["peak_power", "t0", "shape"]),
|
Rule("energy", pulse.P0_to_E0, ["peak_power", "t0", "shape"]),
|
||||||
Rule("energy", pulse.mean_power_to_energy, priorities=2),
|
Rule("energy", pulse.mean_power_to_energy, priorities=2),
|
||||||
Rule("mean_power", pulse.energy_to_mean_power),
|
|
||||||
Rule("t0", pulse.width_to_t0),
|
Rule("t0", pulse.width_to_t0),
|
||||||
Rule("t0", pulse.soliton_num_to_t0),
|
Rule("t0", pulse.soliton_num_to_t0),
|
||||||
Rule("width", pulse.t0_to_width),
|
Rule("width", pulse.t0_to_width),
|
||||||
|
|||||||
@@ -371,7 +371,11 @@ def P0_to_E0(P0, t0, shape):
|
|||||||
|
|
||||||
|
|
||||||
def sech_pulse(t, t0, P0, offset=0):
|
def sech_pulse(t, t0, P0, offset=0):
|
||||||
return np.sqrt(P0) / np.cosh((t - offset) / t0)
|
arg = (t - offset) / t0
|
||||||
|
ind = (arg < 700) & (arg > -700)
|
||||||
|
out = np.zeros_like(t)
|
||||||
|
out[ind] = np.sqrt(P0) / np.cosh(arg[ind])
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def gaussian_pulse(t, t0, P0, offset=0):
|
def gaussian_pulse(t, t0, P0, offset=0):
|
||||||
|
|||||||
Reference in New Issue
Block a user