Evaluator fixes
This commit is contained in:
@@ -21,6 +21,16 @@ class ErrorRecord(NamedTuple):
|
|||||||
rules_stack: tuple[Rule]
|
rules_stack: tuple[Rule]
|
||||||
traceback: str
|
traceback: str
|
||||||
|
|
||||||
|
def pretty_format(self) -> str:
|
||||||
|
return "\n".join(
|
||||||
|
[
|
||||||
|
*(rule.func_name for rule in self.rules_stack[:-1]),
|
||||||
|
self.traceback,
|
||||||
|
self.rules_stack[-1].pretty_format(),
|
||||||
|
str(self.error),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EvaluatorError(Exception):
|
class EvaluatorError(Exception):
|
||||||
target: str | None = None
|
target: str | None = None
|
||||||
@@ -65,14 +75,11 @@ class EvaluatorErrorTree:
|
|||||||
self.all_errors.append(ErrorRecord(error, tuple(lookup_stack), tuple(rules_stack), tr))
|
self.all_errors.append(ErrorRecord(error, tuple(lookup_stack), tuple(rules_stack), tr))
|
||||||
|
|
||||||
def compile_error(self) -> EvaluatorError:
|
def compile_error(self) -> EvaluatorError:
|
||||||
failed_rules = set(rec for rec in self.all_errors if rec.rules_stack)
|
line = "\n" + "-" * 80 + "\n"
|
||||||
failed_rules = [
|
failed_rules = line.join(rec.pretty_format() for rec in self.all_errors)
|
||||||
rec.rules_stack[-1].pretty_format() + "\n" + str(rec.error) for rec in failed_rules
|
|
||||||
]
|
|
||||||
failed_rules = ("\n" + "-" * 80 + "\n").join(failed_rules)
|
|
||||||
|
|
||||||
raise EvaluatorError(
|
raise EvaluatorError(
|
||||||
f"Couldn't compute {self.target}. {len(self)} rules failed.\n{failed_rules}"
|
f"Couldn't compute {self.target}. {len(self)} rules failed.{line}{failed_rules}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -486,12 +493,7 @@ default_rules: list[Rule] = [
|
|||||||
fiber.n_eff_marcatili_adjusted,
|
fiber.n_eff_marcatili_adjusted,
|
||||||
conditions=dict(model="marcatili_adjusted"),
|
conditions=dict(model="marcatili_adjusted"),
|
||||||
),
|
),
|
||||||
Rule(
|
Rule("n_eff", fiber.n_eff_pcf, conditions=dict(model="pcf")),
|
||||||
"n_eff",
|
|
||||||
fiber.n_eff_pcf,
|
|
||||||
["wl_for_disp", "pcf_pitch", "pcf_pitch_ratio"],
|
|
||||||
conditions=dict(model="pcf"),
|
|
||||||
),
|
|
||||||
Rule("n0", lambda w0_ind, n_eff: n_eff[w0_ind]),
|
Rule("n0", lambda w0_ind, n_eff: n_eff[w0_ind]),
|
||||||
Rule("capillary_spacing", fiber.capillary_spacing_hasan),
|
Rule("capillary_spacing", fiber.capillary_spacing_hasan),
|
||||||
Rule("capillary_resonance_strengths", fiber.capillary_resonance_strengths),
|
Rule("capillary_resonance_strengths", fiber.capillary_resonance_strengths),
|
||||||
@@ -504,16 +506,17 @@ default_rules: list[Rule] = [
|
|||||||
lambda beta2_arr, wl_for_disp: wl_for_disp[math.argclosest(beta2_arr, 0)],
|
lambda beta2_arr, wl_for_disp: wl_for_disp[math.argclosest(beta2_arr, 0)],
|
||||||
),
|
),
|
||||||
# Fiber nonlinearity
|
# Fiber nonlinearity
|
||||||
Rule("effective_area", fiber.effective_area_from_V),
|
Rule("effective_area", fiber.effective_area_pcf),
|
||||||
|
Rule("effective_area", fiber.effective_area_from_V, priorities=-1),
|
||||||
Rule("effective_area", fiber.effective_area_from_diam),
|
Rule("effective_area", fiber.effective_area_from_diam),
|
||||||
Rule("effective_area", fiber.effective_area_hasan, conditions=dict(model="hasan")),
|
Rule("effective_area", fiber.effective_area_hasan, conditions=dict(model="hasan")),
|
||||||
Rule("effective_area", fiber.effective_area_from_gamma, priorities=-1),
|
Rule("effective_area", fiber.effective_area_from_gamma, priorities=-1),
|
||||||
Rule("effective_area", fiber.effective_area_marcatili, priorities=-2),
|
Rule("effective_area", fiber.effective_area_marcatili, priorities=-2),
|
||||||
Rule("effective_area", fiber.effective_area_from_pitch),
|
Rule("effective_area_arr", fiber.effective_area_from_V, ["core_radius", "V_eff_arr"]),
|
||||||
Rule("effective_area_arr", fiber.effective_area_from_V, ["core_radius", "V_eff"]),
|
|
||||||
Rule("effective_area_arr", fiber.load_custom_effective_area),
|
Rule("effective_area_arr", fiber.load_custom_effective_area),
|
||||||
Rule("V_eff", fiber.V_parameter_koshiba, conditions=dict(model="pcf")),
|
Rule("V_eff_arr", fiber.V_parameter_koshiba, conditions=dict(model="pcf")),
|
||||||
Rule("V_eff", fiber.V_eff_step_index),
|
Rule("V_eff_arr", fiber.V_eff_step_index),
|
||||||
|
Rule("V_eff", lambda V_eff_arr: V_eff_arr[0]),
|
||||||
Rule("n2", materials.gas_n2),
|
Rule("n2", materials.gas_n2),
|
||||||
Rule("n2", lambda: 2.2e-20, priorities=-1),
|
Rule("n2", lambda: 2.2e-20, priorities=-1),
|
||||||
Rule("gamma", lambda gamma_arr: gamma_arr[0], priorities=-1),
|
Rule("gamma", lambda gamma_arr: gamma_arr[0], priorities=-1),
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ import numpy as np
|
|||||||
|
|
||||||
def data_file(path: str) -> Path:
|
def data_file(path: str) -> Path:
|
||||||
"""returns a `Path` object pointing to the desired data file included in `scgenerator`"""
|
"""returns a `Path` object pointing to the desired data file included in `scgenerator`"""
|
||||||
file = importlib.resources.files("scgenerator") / "data" / path
|
return importlib.resources.path("scgenerator", "data") / path
|
||||||
return importlib.resources.as_file(file)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomEncoder(json.JSONEncoder):
|
class CustomEncoder(json.JSONEncoder):
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ def wspace(t, t_num=0):
|
|||||||
return w
|
return w
|
||||||
|
|
||||||
|
|
||||||
def tspace(time_window=None, t_num=None, dt=None):
|
def tspace(time_window: float | None = None, t_num: float | None = None, dt: float | None = None):
|
||||||
"""
|
"""
|
||||||
returns a time array centered on 0
|
returns a time array centered on 0
|
||||||
|
|
||||||
@@ -199,8 +199,7 @@ def tspace(time_window=None, t_num=None, dt=None):
|
|||||||
elif isinstance(time_window, (float, int)) and isinstance(dt, (float, int)):
|
elif isinstance(time_window, (float, int)) and isinstance(dt, (float, int)):
|
||||||
t_num = int(time_window / dt) + 1
|
t_num = int(time_window / dt) + 1
|
||||||
return np.linspace(-time_window / 2, time_window / 2, t_num)
|
return np.linspace(-time_window / 2, time_window / 2, t_num)
|
||||||
else:
|
raise TypeError("not enough parameter to determine time vector")
|
||||||
raise TypeError("not enough parameter to determine time vector")
|
|
||||||
|
|
||||||
|
|
||||||
def dt_from_min_wl(wl_min: float, wavelength: float) -> float:
|
def dt_from_min_wl(wl_min: float, wavelength: float) -> float:
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ class Parameters:
|
|||||||
raman_fraction: float = Parameter(non_negative(float, int))
|
raman_fraction: float = Parameter(non_negative(float, int))
|
||||||
spm: bool = Parameter(boolean, default=True)
|
spm: bool = Parameter(boolean, default=True)
|
||||||
repeat: int = Parameter(positive(int), default=1)
|
repeat: int = Parameter(positive(int), default=1)
|
||||||
t_num: int = Parameter(positive(int), default=8192)
|
t_num: int = Parameter(positive(int), default=4096)
|
||||||
z_num: int = Parameter(positive(int), default=128)
|
z_num: int = Parameter(positive(int), default=128)
|
||||||
time_window: float = Parameter(positive(float, int))
|
time_window: float = Parameter(positive(float, int))
|
||||||
dt: float = Parameter(in_range_excl(0, 10e-15))
|
dt: float = Parameter(in_range_excl(0, 10e-15))
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import warnings
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Iterable, TypeVar
|
from typing import Iterable, TypeVar
|
||||||
|
|
||||||
@@ -445,8 +446,8 @@ def V_parameter_koshiba(l: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float)
|
|||||||
"""
|
"""
|
||||||
ratio_l = l / pcf_pitch
|
ratio_l = l / pcf_pitch
|
||||||
n_co = 1.45
|
n_co = 1.45
|
||||||
a_eff = effective_area_from_pitch(pcf_pitch)
|
r_eff = pcf_pitch / np.sqrt(3)
|
||||||
pi2a = pipi * a_eff
|
pi2a = pipi * r_eff
|
||||||
A, B = saitoh_paramters(pcf_pitch_ratio)
|
A, B = saitoh_paramters(pcf_pitch_ratio)
|
||||||
|
|
||||||
V = A[0] + A[1] / (1 + A[2] * np.exp(A[3] * ratio_l))
|
V = A[0] + A[1] / (1 + A[2] * np.exp(A[3] * ratio_l))
|
||||||
@@ -457,8 +458,8 @@ def V_parameter_koshiba(l: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float)
|
|||||||
return V_eff
|
return V_eff
|
||||||
|
|
||||||
|
|
||||||
def effective_area_from_pitch(pcf_pitch: float):
|
def effective_area_pcf(pcf_pitch: float):
|
||||||
return pcf_pitch / np.sqrt(3)
|
return pi / 3 * pcf_pitch**2
|
||||||
|
|
||||||
|
|
||||||
def effective_area_from_V(core_radius: float, V_eff: T) -> T:
|
def effective_area_from_V(core_radius: float, V_eff: T) -> T:
|
||||||
@@ -599,10 +600,13 @@ def n_eff_pcf(wl_for_disp: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float)
|
|||||||
"""
|
"""
|
||||||
# Check validity
|
# Check validity
|
||||||
if pcf_pitch_ratio < 0.2 or pcf_pitch_ratio > 0.8:
|
if pcf_pitch_ratio < 0.2 or pcf_pitch_ratio > 0.8:
|
||||||
print("WARNING : Fitted formula valid only for pcf_pitch ratio between 0.2 and 0.8")
|
warnings.warn(
|
||||||
|
"fitted formula for PCF dispersion is valid only for pcf_pitch_ratio between"
|
||||||
|
f" 0.2 and 0.8, {pcf_pitch_ratio:0.6f} was specified"
|
||||||
|
)
|
||||||
|
|
||||||
effective_area = pcf_pitch / np.sqrt(3)
|
r_eff = pcf_pitch / np.sqrt(3)
|
||||||
pi2a = pipi * effective_area
|
pi2a = pipi * r_eff
|
||||||
|
|
||||||
ratio_l = wl_for_disp / pcf_pitch
|
ratio_l = wl_for_disp / pcf_pitch
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user