working fullfied (kind of), better units
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
plots*
|
plots*
|
||||||
/make_*.py
|
/make_*.py
|
||||||
|
/debug*.py
|
||||||
Archive
|
Archive
|
||||||
*.mp4
|
*.mp4
|
||||||
*.png
|
*.png
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import itertools
|
import itertools
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from operator import itemgetter
|
|
||||||
from typing import Any, Callable, Optional, Union
|
from typing import Any, Callable, Optional, Union
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@@ -259,8 +258,8 @@ class Evaluator:
|
|||||||
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)
|
||||||
|
last_target = self.__curent_lookup.pop()
|
||||||
assert target == self.__curent_lookup.pop()
|
assert target == last_target
|
||||||
self.__failed_rules[target] = []
|
self.__failed_rules[target] = []
|
||||||
|
|
||||||
if value is None and error is not None:
|
if value is None and error is not None:
|
||||||
|
|||||||
@@ -354,3 +354,48 @@ def _polynom_extrapolation_in_place(y: np.ndarray, left_ind: int, right_ind: int
|
|||||||
y[:left_ind] = r_left * (y[left_ind] - y[left_ind + 1]) + y[left_ind]
|
y[:left_ind] = r_left * (y[left_ind] - y[left_ind + 1]) + y[left_ind]
|
||||||
y[right_ind:] = r_right * (y[right_ind] - y[right_ind - 1]) + y[right_ind]
|
y[right_ind:] = r_right * (y[right_ind] - y[right_ind - 1]) + y[right_ind]
|
||||||
return y
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
def envelope_ind(
|
||||||
|
signal: np.ndarray, dmin: int = 1, dmax: int = 1, split: bool = False
|
||||||
|
) -> tuple[np.ndarray, np.ndarray]:
|
||||||
|
"""
|
||||||
|
returns the indices of the top/bottom envelope of a signal
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
signal : np.ndarray, shape (n,)
|
||||||
|
signal array (must be sorted)
|
||||||
|
dmin, dmax : int, optional
|
||||||
|
size of chunks for lower/upper envelope
|
||||||
|
split: bool, optional
|
||||||
|
split the signal in half along its mean, might help to generate the envelope in some cases
|
||||||
|
this has the effect of forcing the envlopes to be on either side of the dc signal
|
||||||
|
by default False
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
np.ndarray, shape (m,), m < n
|
||||||
|
lower envelope indices
|
||||||
|
np.ndarray, shape (l,), l < n
|
||||||
|
upper envelope indices
|
||||||
|
"""
|
||||||
|
|
||||||
|
local_min = (np.diff(np.sign(np.diff(signal))) > 0).nonzero()[0] + 1
|
||||||
|
local_max = (np.diff(np.sign(np.diff(signal))) < 0).nonzero()[0] + 1
|
||||||
|
|
||||||
|
if split:
|
||||||
|
dc_value = np.mean(signal)
|
||||||
|
local_min = local_min[signal[local_min] < dc_value]
|
||||||
|
local_max = local_max[signal[local_max] > dc_value]
|
||||||
|
|
||||||
|
if dmin > 1:
|
||||||
|
local_min = local_min[
|
||||||
|
[i + np.argmin(signal[local_min[i : i + dmin]]) for i in range(0, len(local_min), dmin)]
|
||||||
|
]
|
||||||
|
if dmax > 1:
|
||||||
|
local_max = local_max[
|
||||||
|
[i + np.argmax(signal[local_max[i : i + dmax]]) for i in range(0, len(local_max), dmax)]
|
||||||
|
]
|
||||||
|
|
||||||
|
return local_min, local_max
|
||||||
|
|||||||
@@ -630,7 +630,7 @@ class FullFieldSPM(AbstractSPM):
|
|||||||
self.factor = self.fraction * chi3 * units.epsilon0
|
self.factor = self.fraction * chi3 * units.epsilon0
|
||||||
|
|
||||||
def __call__(self, state: CurrentState) -> np.ndarray:
|
def __call__(self, state: CurrentState) -> np.ndarray:
|
||||||
return self.fraction * state.field2 * state.field
|
return self.factor * state.field2 * state.field
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ from .evaluator import Evaluator
|
|||||||
from .logger import get_logger
|
from .logger import get_logger
|
||||||
from .operators import (
|
from .operators import (
|
||||||
AbstractConservedQuantity,
|
AbstractConservedQuantity,
|
||||||
EnvelopeLinearOperator,
|
|
||||||
LinearOperator,
|
LinearOperator,
|
||||||
NonLinearOperator,
|
NonLinearOperator,
|
||||||
)
|
)
|
||||||
@@ -423,12 +422,13 @@ class Parameters:
|
|||||||
def __repr_list__(self) -> Iterator[str]:
|
def __repr_list__(self) -> Iterator[str]:
|
||||||
yield from (f"{k}={v}" for k, v in self.dump_dict().items())
|
yield from (f"{k}={v}" for k, v in self.dump_dict().items())
|
||||||
|
|
||||||
def dump_dict(self, compute=True) -> dict[str, Any]:
|
def dump_dict(self, compute=True, add_metadata=True) -> dict[str, Any]:
|
||||||
if compute:
|
if compute:
|
||||||
self.compute_in_place()
|
self.compute_in_place()
|
||||||
param = Parameters.strip_params_dict(self._param_dico)
|
param = Parameters.strip_params_dict(self._param_dico)
|
||||||
param["datetime"] = datetime_module.datetime.now()
|
if add_metadata:
|
||||||
param["version"] = __version__
|
param["datetime"] = datetime_module.datetime.now()
|
||||||
|
param["version"] = __version__
|
||||||
return param
|
return param
|
||||||
|
|
||||||
def compute_in_place(self, *to_compute: str):
|
def compute_in_place(self, *to_compute: str):
|
||||||
@@ -440,7 +440,8 @@ class Parameters:
|
|||||||
def compute(self, key: str) -> Any:
|
def compute(self, key: str) -> Any:
|
||||||
return self._evaluator.compute(key)
|
return self._evaluator.compute(key)
|
||||||
|
|
||||||
def pformat(self) -> str:
|
def pretty_str(self) -> str:
|
||||||
|
"""return a pretty formatted string describing the parameters"""
|
||||||
return "\n".join(
|
return "\n".join(
|
||||||
f"{k} = {VariationDescriptor.format_value(k, v)}" for k, v in self.dump_dict().items()
|
f"{k} = {VariationDescriptor.format_value(k, v)}" for k, v in self.dump_dict().items()
|
||||||
)
|
)
|
||||||
@@ -597,7 +598,7 @@ class Configuration:
|
|||||||
self.variationer.append(config.variable)
|
self.variationer.append(config.variable)
|
||||||
self.fiber_paths.append(
|
self.fiber_paths.append(
|
||||||
utils.ensure_folder(
|
utils.ensure_folder(
|
||||||
self.final_path / fiber_folder(i, self.name, config.fixed["name"]),
|
self.final_path / fiber_folder(i, self.name, Path(config.fixed["name"]).name),
|
||||||
mkdir=False,
|
mkdir=False,
|
||||||
prevent_overwrite=not self.overwrite,
|
prevent_overwrite=not self.overwrite,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ def material_dispersion(
|
|||||||
disp = np.zeros(len(w))
|
disp = np.zeros(len(w))
|
||||||
ind = w > 0
|
ind = w > 0
|
||||||
disp[ind] = material_dispersion(
|
disp[ind] = material_dispersion(
|
||||||
units.To.m(w[ind]), material, pressure, temperature, ideal, False
|
units.m.inv(w[ind]), material, pressure, temperature, ideal, False
|
||||||
)
|
)
|
||||||
return disp
|
return disp
|
||||||
else:
|
else:
|
||||||
@@ -102,7 +102,7 @@ def find_optimal_depth(
|
|||||||
w = w_c + w0
|
w = w_c + w0
|
||||||
disp = np.zeros(len(w))
|
disp = np.zeros(len(w))
|
||||||
ind = w > (w0 / 10)
|
ind = w > (w0 / 10)
|
||||||
disp[ind] = material_dispersion(units.To.m(w[ind]), material)
|
disp[ind] = material_dispersion(units.m.inv(w[ind]), material)
|
||||||
|
|
||||||
propagate = lambda z: spectrum * np.exp(-0.5j * disp * w_c ** 2 * z)
|
propagate = lambda z: spectrum * np.exp(-0.5j * disp * w_c ** 2 * z)
|
||||||
integrate = lambda z: math.abs2(np.fft.ifft(propagate(z)))
|
integrate = lambda z: math.abs2(np.fft.ifft(propagate(z)))
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
# For example, nm(X) means "I give the number X in nm, figure out the ang. freq."
|
# For example, nm(X) means "I give the number X in nm, figure out the ang. freq."
|
||||||
# to be used especially when giving plotting ranges : (400, 1400, nm), (-4, 8, ps), ...
|
# to be used especially when giving plotting ranges : (400, 1400, nm), (-4, 8, ps), ...
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
from typing import Callable, TypeVar, Union
|
from typing import Callable, TypeVar, Union
|
||||||
|
from functools import wraps
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
@@ -25,17 +29,38 @@ provided you decorate it with @unit and provide at least a type and a label
|
|||||||
types are "WL", "FREQ", "AFREQ", "TIME", "PRESSURE", "TEMPERATURE", "OTHER"
|
types are "WL", "FREQ", "AFREQ", "TIME", "PRESSURE", "TEMPERATURE", "OTHER"
|
||||||
"""
|
"""
|
||||||
_T = TypeVar("_T")
|
_T = TypeVar("_T")
|
||||||
|
_UT = Callable[[_T], _T]
|
||||||
|
|
||||||
|
|
||||||
class From:
|
def chain(c1: _UT, c2: _UT) -> _UT:
|
||||||
pass
|
def chained_function(x: _T) -> _T:
|
||||||
|
return c1(c2(x))
|
||||||
|
|
||||||
|
return chained_function
|
||||||
|
|
||||||
|
|
||||||
|
class UnitMap(dict):
|
||||||
|
def __setitem__(self, new_name, new_func):
|
||||||
|
super().__setitem__(new_name, new_func)
|
||||||
|
already_here = [(name, func) for name, func in self.items() if isinstance(name, str)]
|
||||||
|
for name, func in already_here:
|
||||||
|
super().__setitem__((name, new_name), chain(self[name].inv, new_func))
|
||||||
|
super().__setitem__((new_name, name), chain(self[new_name].inv, func))
|
||||||
|
|
||||||
|
|
||||||
|
units_map: dict[str, dict[Union[str, tuple[str, str]], Unit]] = defaultdict(UnitMap)
|
||||||
|
|
||||||
|
|
||||||
class To:
|
class To:
|
||||||
pass
|
def __init__(self, name: str, tpe: str):
|
||||||
|
self.name = name
|
||||||
|
self.type = tpe
|
||||||
|
|
||||||
|
def __getattr__(self, key: str):
|
||||||
units_map = dict()
|
try:
|
||||||
|
return units_map[self.type][self.name, key]
|
||||||
|
except KeyError:
|
||||||
|
raise KeyError(f"no registered unit named {key!r} of type {self.type!r}") from None
|
||||||
|
|
||||||
|
|
||||||
def W_to_Vm(n0: float, A_eff: float) -> float:
|
def W_to_Vm(n0: float, A_eff: float) -> float:
|
||||||
@@ -54,22 +79,36 @@ def W_to_Vm(n0: float, A_eff: float) -> float:
|
|||||||
return 1.0 / np.sqrt(A_eff * 0.5 * epsilon0 * c * n0)
|
return 1.0 / np.sqrt(A_eff * 0.5 * epsilon0 * c * n0)
|
||||||
|
|
||||||
|
|
||||||
|
class Unit:
|
||||||
|
__func: _UT
|
||||||
|
to: To
|
||||||
|
inv: _UT
|
||||||
|
name: str
|
||||||
|
label: str
|
||||||
|
|
||||||
|
def __init__(self, func: _UT, inv: _UT, name: str, label: str, tpe: str):
|
||||||
|
self.__func = func
|
||||||
|
self.inv = inv
|
||||||
|
self.to = To(name, tpe)
|
||||||
|
self.name = name
|
||||||
|
self.label = label
|
||||||
|
self.type = tpe
|
||||||
|
self.__name__ = name
|
||||||
|
|
||||||
|
def __call__(self, x: _T) -> _T:
|
||||||
|
"""call the original unit function"""
|
||||||
|
return self.__func(x)
|
||||||
|
|
||||||
|
|
||||||
def unit(tpe: str, label: str, inv: Callable = None):
|
def unit(tpe: str, label: str, inv: Callable = None):
|
||||||
def unit_maker(func):
|
def unit_maker(func) -> Unit:
|
||||||
nonlocal inv
|
nonlocal inv
|
||||||
name = func.__name__
|
name = func.__name__
|
||||||
if inv is None:
|
if inv is None:
|
||||||
inv = func
|
inv = func
|
||||||
setattr(From, name, func.__call__)
|
unit_obj = wraps(func)(Unit(func, inv, name, label, tpe))
|
||||||
setattr(To, name, inv.__call__)
|
units_map[tpe][name] = unit_obj
|
||||||
func.type = tpe
|
return unit_obj
|
||||||
func.label = label
|
|
||||||
func.name = name
|
|
||||||
func.inv = inv
|
|
||||||
if name in units_map:
|
|
||||||
raise NameError(f"Two unit functions with the same name {name!r} were defined")
|
|
||||||
units_map[name] = func
|
|
||||||
return func
|
|
||||||
|
|
||||||
return unit_maker
|
return unit_maker
|
||||||
|
|
||||||
@@ -89,6 +128,11 @@ def um(l: _T) -> _T:
|
|||||||
return 2 * pi * c / (l * 1e-6)
|
return 2 * pi * c / (l * 1e-6)
|
||||||
|
|
||||||
|
|
||||||
|
@unit("FREQ", r"Frequency $f$ (Hz)", lambda w: w / (2 * pi))
|
||||||
|
def Hz(f: _T) -> _T:
|
||||||
|
return 2 * pi * f
|
||||||
|
|
||||||
|
|
||||||
@unit("FREQ", r"Frequency $f$ (THz)", lambda w: w / (1e12 * 2 * pi))
|
@unit("FREQ", r"Frequency $f$ (THz)", lambda w: w / (1e12 * 2 * pi))
|
||||||
def THz(f: _T) -> _T:
|
def THz(f: _T) -> _T:
|
||||||
return 1e12 * 2 * pi * f
|
return 1e12 * 2 * pi * f
|
||||||
@@ -306,7 +350,7 @@ class PlotRange(tuple):
|
|||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
yield self.left
|
yield self.left
|
||||||
yield self.right
|
yield self.right
|
||||||
yield self.unit.__name__
|
yield self.unit.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "PlotRange" + super().__repr__()
|
return "PlotRange" + super().__repr__()
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ def transform_2D_propagation(
|
|||||||
params: Parameters,
|
params: Parameters,
|
||||||
log: Union[int, float, bool, str] = "1D",
|
log: Union[int, float, bool, str] = "1D",
|
||||||
skip: int = 1,
|
skip: int = 1,
|
||||||
|
y_axis=None,
|
||||||
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
||||||
"""transforms raws values into plottable values
|
"""transforms raws values into plottable values
|
||||||
|
|
||||||
@@ -455,8 +456,8 @@ def transform_2D_propagation(
|
|||||||
is_complex, x_axis, plt_range = prep_plot_axis(values, plt_range, params)
|
is_complex, x_axis, plt_range = prep_plot_axis(values, plt_range, params)
|
||||||
if is_complex:
|
if is_complex:
|
||||||
values = abs2(values)
|
values = abs2(values)
|
||||||
|
if y_axis is None:
|
||||||
y_axis = params.z_targets
|
y_axis = params.z_targets
|
||||||
|
|
||||||
x_axis, values = uniform_axis(x_axis, values, plt_range)
|
x_axis, values = uniform_axis(x_axis, values, plt_range)
|
||||||
y_axis, values.T[:] = uniform_axis(y_axis, values.T, None)
|
y_axis, values.T[:] = uniform_axis(y_axis, values.T, None)
|
||||||
@@ -1102,7 +1103,7 @@ def partial_plot(root: os.PathLike):
|
|||||||
)
|
)
|
||||||
|
|
||||||
t, z, values = transform_2D_propagation(
|
t, z, values = transform_2D_propagation(
|
||||||
np.fft.ifft(raw_values),
|
params.ifft(raw_values),
|
||||||
PlotRange(-10, 10, "ps"),
|
PlotRange(-10, 10, "ps"),
|
||||||
params,
|
params,
|
||||||
log=False,
|
log=False,
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ def plot_init(
|
|||||||
lbl = plot_1_dispersion(lim_disp, tl, tr, style, lbl, params, loss_ax)
|
lbl = plot_1_dispersion(lim_disp, tl, tr, style, lbl, params, loss_ax)
|
||||||
lbl = plot_1_init_spec_field(lim_field, lim_spec, bl, br, style, lbl, params)
|
lbl = plot_1_init_spec_field(lim_field, lim_spec, bl, br, style, lbl, params)
|
||||||
all_labels.append(lbl)
|
all_labels.append(lbl)
|
||||||
print(params.pformat())
|
print(params.pretty_str())
|
||||||
finish_plot(fig, tr, all_labels, params)
|
finish_plot(fig, tr, all_labels, params)
|
||||||
|
|
||||||
|
|
||||||
@@ -142,8 +142,8 @@ def plot_1_init_spec_field(
|
|||||||
):
|
):
|
||||||
field = math.abs2(params.field_0)
|
field = math.abs2(params.field_0)
|
||||||
spec = math.abs2(params.spec_0)
|
spec = math.abs2(params.spec_0)
|
||||||
t = units.To.fs(params.t)
|
t = units.fs.inv(params.t)
|
||||||
wl = units.To.nm(params.w)
|
wl = units.nm.inv(params.w)
|
||||||
|
|
||||||
lbl += f" max at {wl[spec.argmax()]:.1f} nm"
|
lbl += f" max at {wl[spec.argmax()]:.1f} nm"
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ def plot_1_dispersion(
|
|||||||
right.set_ylabel(units.D_ps_nm_km.label)
|
right.set_ylabel(units.D_ps_nm_km.label)
|
||||||
|
|
||||||
# plot beta2
|
# plot beta2
|
||||||
left.plot(units.To.nm(params.w[m]), units.beta2_fs_cm.inv(beta_arr[m]), label=" ", **style)
|
left.plot(units.nm.inv(params.w[m]), units.beta2_fs_cm.inv(beta_arr[m]), label=" ", **style)
|
||||||
left.set_ylabel(units.beta2_fs_cm.label)
|
left.set_ylabel(units.beta2_fs_cm.label)
|
||||||
|
|
||||||
left.set_xlabel(units.nm.label)
|
left.set_xlabel(units.nm.label)
|
||||||
|
|||||||
@@ -311,8 +311,18 @@ def ensure_folder(path: Path, prevent_overwrite: bool = True, mkdir=True) -> Pat
|
|||||||
path = path.parent / (folder_name + f"_{i}")
|
path = path.parent / (folder_name + f"_{i}")
|
||||||
|
|
||||||
|
|
||||||
def branch_id(branch: tuple[Path, ...]) -> str:
|
def branch_id(branch: Path) -> tuple[int, int]:
|
||||||
return branch[-1].name.split()[1]
|
sim_match = branch.parent.name.split()[0]
|
||||||
|
if sim_match.isdigit():
|
||||||
|
s_int = int(sim_match)
|
||||||
|
else:
|
||||||
|
s_int = 0
|
||||||
|
branch_match = re.search(r"(?<=b_)[0-9]+", branch.name)
|
||||||
|
if branch_match is None:
|
||||||
|
b_int = 0
|
||||||
|
else:
|
||||||
|
b_int = int(branch_match[0])
|
||||||
|
return s_int, b_int
|
||||||
|
|
||||||
|
|
||||||
def find_last_spectrum_num(data_dir: Path):
|
def find_last_spectrum_num(data_dir: Path):
|
||||||
@@ -519,5 +529,5 @@ def simulations_list(path: os.PathLike) -> list[Path]:
|
|||||||
for pwd, _, files in os.walk(path):
|
for pwd, _, files in os.walk(path):
|
||||||
if PARAM_FN in files:
|
if PARAM_FN in files:
|
||||||
paths.append(Path(pwd))
|
paths.append(Path(pwd))
|
||||||
paths.sort(key=lambda el: el.parent.name)
|
paths.sort(key=branch_id)
|
||||||
return [p for p in paths if p.parent.name == paths[-1].parent.name]
|
return [p for p in paths if p.parent.name == paths[-1].parent.name]
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ class VariationDescriptor(BaseModel):
|
|||||||
p = Path(value)
|
p = Path(value)
|
||||||
if p.exists():
|
if p.exists():
|
||||||
return p.stem
|
return p.stem
|
||||||
|
elif callable(value):
|
||||||
|
return getattr(value, "__name__", repr(value))
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ width = 30e-15
|
|||||||
core_radius = 10e-6
|
core_radius = 10e-6
|
||||||
model = "marcatili"
|
model = "marcatili"
|
||||||
gas_name = "argon"
|
gas_name = "argon"
|
||||||
pressure = 1e5
|
pressure = 3.2e5
|
||||||
|
|
||||||
length = 0.1
|
length = 0.1
|
||||||
interpolation_range = [100e-9, 3000e-9]
|
interpolation_range = [120e-9, 3000e-9]
|
||||||
full_field = true
|
full_field = true
|
||||||
dt = 0.1e-15
|
dt = 0.05e-15
|
||||||
t_num = 32768
|
t_num = 32768
|
||||||
z_num = 128
|
z_num = 128
|
||||||
step_size = 2e-6
|
step_size = 10e-6
|
||||||
|
|||||||
@@ -1,36 +1,61 @@
|
|||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import rediscache
|
||||||
import scgenerator as sc
|
import scgenerator as sc
|
||||||
from customfunc.app import PlotApp
|
from customfunc.app import PlotApp
|
||||||
from scgenerator.physics.simulate import RK4IP
|
from scipy.interpolate import interp1d
|
||||||
from customfunc import pprint
|
from tqdm import tqdm
|
||||||
|
|
||||||
warnings.filterwarnings("error")
|
# warnings.filterwarnings("error")
|
||||||
|
|
||||||
|
|
||||||
|
@rediscache.rcache
|
||||||
|
def get_specs(params: dict):
|
||||||
|
p = sc.Parameters(**params)
|
||||||
|
sim = sc.RK4IP(p)
|
||||||
|
return [s[-1] for s in tqdm(sim.irun(), total=p.z_num)], p.dump_dict()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
params = sc.Parameters.load("testing/configs/Chang2011Fig2.toml")
|
params = sc.Parameters.load("testing/configs/Chang2011Fig2.toml")
|
||||||
x = params.l * 1e9
|
specs, params = get_specs(params.dump_dict(add_metadata=False))
|
||||||
o = np.argsort(x)
|
params = sc.Parameters(**params)
|
||||||
x = x[o]
|
rs = sc.PlotRange(100, 1500, "nm")
|
||||||
|
rt = sc.PlotRange(-500, 500, "fs")
|
||||||
|
x, o, ext = rs.sort_axis(params.w)
|
||||||
|
vmin = -50
|
||||||
|
with PlotApp(i=(int, 0, params.z_num - 1)) as app:
|
||||||
|
spec_ax = app[0]
|
||||||
|
spec_ax.set_xlabel(rs.unit.label)
|
||||||
|
field_ax = app[1]
|
||||||
|
field_ax.set_xlabel(rt.unit.label)
|
||||||
|
x: float = 4.5
|
||||||
|
y = sc.units.m.to.nm(x)
|
||||||
|
|
||||||
plt.plot(x, sc.abs2(params.spec_0[o]))
|
@app.update
|
||||||
state = sc.operators.CurrentState(
|
def draw(i):
|
||||||
params.length, 0, params.step_size, 1.0, params.ifft, params.spec_0
|
spec, *fields = compute(i)
|
||||||
)
|
spec_ax.set_line_data("spec", *spec, label=f"z = {params.z_targets[i]*1e2:.0f}cm")
|
||||||
# expD = np.exp(state.h / 2 * params.linear_operator(state))
|
for label, x, y in fields:
|
||||||
# plt.plot(x, expD.imag[o], x, expD.real[o])
|
field_ax.set_line_data(label, x, y)
|
||||||
plt.plot(x, sc.abs2(params.nonlinear_operator(state))[o])
|
|
||||||
plt.yscale("log")
|
|
||||||
plt.xlim(100, 2000)
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
# for *_, spec in RK4IP(params).irun():
|
print(params)
|
||||||
# plt.plot(w[2:-2], sc.abs2(spec[ind]))
|
|
||||||
# plt.show()
|
@app.cache
|
||||||
# plt.close()
|
def compute(i):
|
||||||
|
xt, field = sc.transform_1D_values(params.ifft(specs[i]), rt, params)
|
||||||
|
x, spec = sc.transform_1D_values(sc.abs2(specs[i]), rs, params, log=True)
|
||||||
|
# spec = np.where(spec > vmin, spec, vmin)
|
||||||
|
field2 = sc.abs2(field)
|
||||||
|
bot, top = sc.math.envelope_ind(field2)
|
||||||
|
return (x, spec), ("field^2", xt, field2), ("envelope", xt[top], field2[top])
|
||||||
|
|
||||||
|
# bot, top = sc.math.envelope_ind(field)
|
||||||
|
# bot = interp1d(xt[bot], field[bot], "cubic", bounds_error=False, fill_value=0)(xt)
|
||||||
|
# top = interp1d(xt[top], field[top], "cubic", bounds_error=False, fill_value=0)(xt)
|
||||||
|
|
||||||
|
# return ((x, spec), ("upper", xt, top), ("field", xt, field), ("lower", xt, bot))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user