diff --git a/src/scgenerator/evaluator.py b/src/scgenerator/evaluator.py index 339647f..c0d948d 100644 --- a/src/scgenerator/evaluator.py +++ b/src/scgenerator/evaluator.py @@ -21,6 +21,16 @@ class ErrorRecord(NamedTuple): rules_stack: tuple[Rule] 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): target: str | None = None @@ -65,14 +75,11 @@ class EvaluatorErrorTree: self.all_errors.append(ErrorRecord(error, tuple(lookup_stack), tuple(rules_stack), tr)) def compile_error(self) -> EvaluatorError: - failed_rules = set(rec for rec in self.all_errors if rec.rules_stack) - failed_rules = [ - rec.rules_stack[-1].pretty_format() + "\n" + str(rec.error) for rec in failed_rules - ] - failed_rules = ("\n" + "-" * 80 + "\n").join(failed_rules) + line = "\n" + "-" * 80 + "\n" + failed_rules = line.join(rec.pretty_format() for rec in self.all_errors) 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, conditions=dict(model="marcatili_adjusted"), ), - Rule( - "n_eff", - fiber.n_eff_pcf, - ["wl_for_disp", "pcf_pitch", "pcf_pitch_ratio"], - conditions=dict(model="pcf"), - ), + Rule("n_eff", fiber.n_eff_pcf, conditions=dict(model="pcf")), Rule("n0", lambda w0_ind, n_eff: n_eff[w0_ind]), Rule("capillary_spacing", fiber.capillary_spacing_hasan), 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)], ), # 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_hasan, conditions=dict(model="hasan")), 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_from_pitch), - Rule("effective_area_arr", fiber.effective_area_from_V, ["core_radius", "V_eff"]), + Rule("effective_area_arr", fiber.effective_area_from_V, ["core_radius", "V_eff_arr"]), Rule("effective_area_arr", fiber.load_custom_effective_area), - Rule("V_eff", fiber.V_parameter_koshiba, conditions=dict(model="pcf")), - Rule("V_eff", fiber.V_eff_step_index), + Rule("V_eff_arr", fiber.V_parameter_koshiba, conditions=dict(model="pcf")), + 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", lambda: 2.2e-20, priorities=-1), Rule("gamma", lambda gamma_arr: gamma_arr[0], priorities=-1), diff --git a/src/scgenerator/io.py b/src/scgenerator/io.py index bdb2f86..5ea03d0 100644 --- a/src/scgenerator/io.py +++ b/src/scgenerator/io.py @@ -15,8 +15,7 @@ import numpy as np def data_file(path: str) -> Path: """returns a `Path` object pointing to the desired data file included in `scgenerator`""" - file = importlib.resources.files("scgenerator") / "data" / path - return importlib.resources.as_file(file) + return importlib.resources.path("scgenerator", "data") / path class CustomEncoder(json.JSONEncoder): diff --git a/src/scgenerator/math.py b/src/scgenerator/math.py index bda2c70..ebba1c6 100644 --- a/src/scgenerator/math.py +++ b/src/scgenerator/math.py @@ -165,7 +165,7 @@ def wspace(t, t_num=0): 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 @@ -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)): t_num = int(time_window / dt) + 1 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: diff --git a/src/scgenerator/parameter.py b/src/scgenerator/parameter.py index 9a9bf5f..321f50c 100644 --- a/src/scgenerator/parameter.py +++ b/src/scgenerator/parameter.py @@ -386,7 +386,7 @@ class Parameters: raman_fraction: float = Parameter(non_negative(float, int)) spm: bool = Parameter(boolean, default=True) 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) time_window: float = Parameter(positive(float, int)) dt: float = Parameter(in_range_excl(0, 10e-15)) diff --git a/src/scgenerator/physics/fiber.py b/src/scgenerator/physics/fiber.py index 1cda9a2..40d311e 100644 --- a/src/scgenerator/physics/fiber.py +++ b/src/scgenerator/physics/fiber.py @@ -1,3 +1,4 @@ +import warnings from io import BytesIO 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 n_co = 1.45 - a_eff = effective_area_from_pitch(pcf_pitch) - pi2a = pipi * a_eff + r_eff = pcf_pitch / np.sqrt(3) + pi2a = pipi * r_eff A, B = saitoh_paramters(pcf_pitch_ratio) 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 -def effective_area_from_pitch(pcf_pitch: float): - return pcf_pitch / np.sqrt(3) +def effective_area_pcf(pcf_pitch: float): + return pi / 3 * pcf_pitch**2 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 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) - pi2a = pipi * effective_area + r_eff = pcf_pitch / np.sqrt(3) + pi2a = pipi * r_eff ratio_l = wl_for_disp / pcf_pitch