Big upgrade
This commit is contained in:
60
README.md
60
README.md
@@ -16,8 +16,28 @@ spectra, params = load_sim_data("varyTechNoise100kW_sim_data")
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
You can load parameters by simpling passing the path to a toml file to the appropriate simulation function. Each possible key of this dictionary is described below. Every value must be given in standard SI units (m, s, W, J, ...)
|
You can load parameters by simply passing the path to a toml file to the appropriate simulation function. Each possible key of this dictionary is described below. Every value must be given in standard SI units (m, s, W, J, ...)
|
||||||
The configuration file can have a ```name``` parameter at the root and must otherwise contain the following sections with the specified parameters
|
The configuration file can have a ```name``` parameter at the root and must otherwise contain the following sections with the specified parameters. Every section ("fiber", "gas", "pulse", "simulation") can have a "variable" subsection where parameters are specified in a list INSTEAD of being specified as a single value in the main section. This has the effect of running one simulation per value in the list. If many parameters are variable, all possible combinations are ran.
|
||||||
|
Examples :
|
||||||
|
|
||||||
|
```
|
||||||
|
[fiber]
|
||||||
|
n2 = 2.2e-20
|
||||||
|
```
|
||||||
|
a single simulation is ran with this value
|
||||||
|
```
|
||||||
|
[fiber.variable]
|
||||||
|
n2 = [2.1e-20, 2.4e-20, 2.6e-20]
|
||||||
|
```
|
||||||
|
3 simulations are ran, one for each value
|
||||||
|
```
|
||||||
|
[fiber]
|
||||||
|
n2 = 2.2e-20
|
||||||
|
[fiber.variable]
|
||||||
|
n2 = [2.1e-20, 2.4e-20, 2.6e-20]
|
||||||
|
```
|
||||||
|
NOT ALLOWED
|
||||||
|
|
||||||
|
|
||||||
note : internally, another structure with a flattened dictionary is used
|
note : internally, another structure with a flattened dictionary is used
|
||||||
|
|
||||||
@@ -29,6 +49,11 @@ If you already know the Taylor coefficients corresponding to the expansion of th
|
|||||||
beta: list-like
|
beta: list-like
|
||||||
list of Taylor coefficients for the beta_2 function
|
list of Taylor coefficients for the beta_2 function
|
||||||
|
|
||||||
|
If you already have a dispersion curve, you can convert it to a npz file with the wavelength (key : 'wavelength') in m and the D parameter (key : 'dispersion') in s/m/m. You the refer to this file as
|
||||||
|
|
||||||
|
dispersion_file : str
|
||||||
|
path to the npz dispersion file
|
||||||
|
|
||||||
|
|
||||||
else, you can choose a mathematical fiber model
|
else, you can choose a mathematical fiber model
|
||||||
|
|
||||||
@@ -81,7 +106,7 @@ capillary_thickness : float
|
|||||||
capillary_spacing : float, optional if d is specified
|
capillary_spacing : float, optional if d is specified
|
||||||
spacing between the capillary
|
spacing between the capillary
|
||||||
|
|
||||||
capillray_resonance_strengths : list, optional
|
capillary_resonance_strengths : list, optional
|
||||||
list of resonance strengths. Default is []
|
list of resonance strengths. Default is []
|
||||||
|
|
||||||
capillary_nested : int, optional
|
capillary_nested : int, optional
|
||||||
@@ -93,14 +118,20 @@ capillary_nested : int, optional
|
|||||||
gamma: float, optional unless beta is directly provided
|
gamma: float, optional unless beta is directly provided
|
||||||
nonlinear parameter in m^2 / W. Will overwrite any computed gamma parameter.
|
nonlinear parameter in m^2 / W. Will overwrite any computed gamma parameter.
|
||||||
|
|
||||||
|
effective_mode_diameter : float, optional
|
||||||
|
effective mode field diameter in m
|
||||||
|
|
||||||
|
n2 : float, optional
|
||||||
|
non linear refractive index
|
||||||
|
|
||||||
|
A_eff : float, optional
|
||||||
|
effective mode field area
|
||||||
|
|
||||||
length: float, optional
|
length: float, optional
|
||||||
length of the fiber in m. default : 1
|
length of the fiber in m. default : 1
|
||||||
|
|
||||||
fiber_id : int
|
|
||||||
in case multiple fibers are chained together, indicates the index of this particular fiber, default : 0
|
|
||||||
|
|
||||||
input_transmission : float
|
input_transmission : float
|
||||||
number between 0 and 1 indicating how much light enters the fiber, default : 1
|
number between 0 and 1 indicating how much light enters the fiber, useful when chaining many fibers together, default : 1
|
||||||
|
|
||||||
|
|
||||||
## Gas parameters
|
## Gas parameters
|
||||||
@@ -124,11 +155,17 @@ plasma_density: float
|
|||||||
wavelength: float
|
wavelength: float
|
||||||
pump wavelength in m
|
pump wavelength in m
|
||||||
|
|
||||||
To specify the initial pulse shape, either use one of 2 in (power, energy) together with one of 2 in (width, t0), or use soliton_num together with one of 4 in (power, energy, width, t0)
|
To specify the initial pulse properties, either use one of 3 in (peak_power, energy, mean_power) together with one of 2 in (width, t0), or use soliton_num together with one of 5 in (peak_power, mean_power, energy, width, t0)
|
||||||
|
|
||||||
power: float
|
peak_power : float
|
||||||
peak power in W
|
peak power in W
|
||||||
|
|
||||||
|
mean_power : float
|
||||||
|
mean power of the pulse train in W. if specified, repetition_rate must also be specified
|
||||||
|
|
||||||
|
repetition_rate : float
|
||||||
|
repetition rate of the pulse train in Hz
|
||||||
|
|
||||||
energy: float
|
energy: float
|
||||||
total pulse energy in J
|
total pulse energy in J
|
||||||
|
|
||||||
@@ -138,11 +175,14 @@ width: float
|
|||||||
t0: float
|
t0: float
|
||||||
pulse width parameter
|
pulse width parameter
|
||||||
|
|
||||||
solition_num: float
|
soliton_num: float
|
||||||
soliton number
|
soliton number
|
||||||
|
|
||||||
### optional
|
### optional
|
||||||
|
|
||||||
|
field_file : str
|
||||||
|
if you have an initial field to use, convert it to a npz file with time (key : 'time') in s and electric field (key : 'field') in sqrt(W) (can be complex). You the use it with this config key. You can then scale it by settings any 1 of mean_power, energy and peak_power (priority is in this order)
|
||||||
|
|
||||||
quantum_noise: bool
|
quantum_noise: bool
|
||||||
whether or not one-photon-per-mode quantum noise is activated. default : False
|
whether or not one-photon-per-mode quantum noise is activated. default : False
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ from .initialize import compute_init_parameters
|
|||||||
from .io import Paths, load_toml
|
from .io import Paths, load_toml
|
||||||
from .math import abs2, argclosest, span
|
from .math import abs2, argclosest, span
|
||||||
from .physics import fiber, materials, pulse, simulate, units
|
from .physics import fiber, materials, pulse, simulate, units
|
||||||
from .physics.simulate import RK4IP, new_simulations, resume_simulations
|
from .physics.simulate import RK4IP, new_simulation, resume_simulations
|
||||||
from .plotting import plot_avg, plot_results_1D, plot_results_2D, plot_spectrogram
|
from .plotting import plot_avg, plot_results_1D, plot_results_2D, plot_spectrogram
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import sys
|
|||||||
import ray
|
import ray
|
||||||
|
|
||||||
from scgenerator import initialize
|
from scgenerator import initialize
|
||||||
from ..physics.simulate import new_simulations, resume_simulations, SequencialSimulations
|
from ..physics.simulate import run_simulation_sequence, resume_simulations, SequencialSimulations
|
||||||
from .. import io
|
from .. import io
|
||||||
|
|
||||||
|
|
||||||
@@ -37,11 +37,14 @@ def create_parser():
|
|||||||
|
|
||||||
run_parser.add_argument("configs", help="path(s) to the toml configuration file(s)", nargs="+")
|
run_parser.add_argument("configs", help="path(s) to the toml configuration file(s)", nargs="+")
|
||||||
run_parser.add_argument(
|
run_parser.add_argument(
|
||||||
"appendto",
|
"--append-to",
|
||||||
|
"-a",
|
||||||
help="optional directory where a compatible simulation has already been ran",
|
help="optional directory where a compatible simulation has already been ran",
|
||||||
nargs="?",
|
|
||||||
default=None,
|
default=None,
|
||||||
)
|
)
|
||||||
|
run_parser.add_argument(
|
||||||
|
"--output-name", "--o", help="path to the final output folder", default=None
|
||||||
|
)
|
||||||
run_parser.set_defaults(func=run_sim)
|
run_parser.set_defaults(func=run_sim)
|
||||||
|
|
||||||
resume_parser = subparsers.add_parser("resume", help="resume a simulation")
|
resume_parser = subparsers.add_parser("resume", help="resume a simulation")
|
||||||
@@ -53,11 +56,10 @@ def create_parser():
|
|||||||
|
|
||||||
merge_parser = subparsers.add_parser("merge", help="merge simulation results")
|
merge_parser = subparsers.add_parser("merge", help="merge simulation results")
|
||||||
merge_parser.add_argument(
|
merge_parser.add_argument(
|
||||||
"paths",
|
"path", help="path to the final simulation folder containing 'initial_config.toml'"
|
||||||
nargs="+",
|
)
|
||||||
help="path(s) to simulation folder(s) containing 'initial_config.toml'. If more "
|
merge_parser.add_argument(
|
||||||
"than one path is given, simulations are appended to each other as if they're "
|
"--output-name", "--o", help="path to the final output folder", default=None
|
||||||
"physically the continuation of the previous one.",
|
|
||||||
)
|
)
|
||||||
merge_parser.set_defaults(func=merge)
|
merge_parser.set_defaults(func=merge)
|
||||||
|
|
||||||
@@ -73,29 +75,11 @@ def main():
|
|||||||
def run_sim(args):
|
def run_sim(args):
|
||||||
|
|
||||||
method = prep_ray(args)
|
method = prep_ray(args)
|
||||||
configs = args.configs.copy()
|
run_simulation_sequence(*args.configs, method=method, final_name=args.output_name)
|
||||||
first_config = configs.pop(0)
|
|
||||||
|
|
||||||
if args.appendto is None:
|
|
||||||
sim = new_simulations(first_config, method=method)
|
|
||||||
else:
|
|
||||||
sim = new_simulations(
|
|
||||||
first_config, prev_data_folder=args.appendto, method=method, initial=False
|
|
||||||
)
|
|
||||||
sim.run()
|
|
||||||
data_folders = [sim.data_folder]
|
|
||||||
for config in configs:
|
|
||||||
print("launching", config)
|
|
||||||
sim = new_simulations(
|
|
||||||
config, prev_data_folder=data_folders[-1], method=method, initial=False
|
|
||||||
)
|
|
||||||
sim.run()
|
|
||||||
data_folders.append(sim.data_folder)
|
|
||||||
io.merge(data_folders)
|
|
||||||
|
|
||||||
|
|
||||||
def merge(args):
|
def merge(args):
|
||||||
io.merge(args.paths)
|
io.append_and_merge(args.path, args.output_name)
|
||||||
|
|
||||||
|
|
||||||
def prep_ray(args):
|
def prep_ray(args):
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def pbar_format(worker_id: int):
|
||||||
|
if worker_id == 0:
|
||||||
|
return dict(
|
||||||
|
position=0,
|
||||||
|
bar_format="{l_bar}{bar}" "|[{elapsed}<{remaining}, " "{rate_fmt}{postfix}]",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return dict(
|
||||||
|
total=1,
|
||||||
|
desc=f"Worker {worker_id}",
|
||||||
|
position=worker_id,
|
||||||
|
bar_format="{l_bar}{bar}" "|[{elapsed}<{remaining}, " "{rate_fmt}{postfix}]",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#####
|
||||||
|
|
||||||
|
|
||||||
def in_range_excl(func, r):
|
def in_range_excl(func, r):
|
||||||
def _in_range(n):
|
def _in_range(n):
|
||||||
if not func(n):
|
if not func(n):
|
||||||
return False
|
return False
|
||||||
return n > r[0] and n < r[1]
|
return n > r[0] and n < r[1]
|
||||||
|
|
||||||
_in_range.__doc__ = func.__doc__ + f" between {r[0]} and {r[1]}"
|
_in_range.__doc__ = func.__doc__ + f" between {r[0]} and {r[1]} (exclusive) "
|
||||||
return _in_range
|
return _in_range
|
||||||
|
|
||||||
|
|
||||||
@@ -17,7 +35,7 @@ def in_range_incl(func, r):
|
|||||||
return False
|
return False
|
||||||
return n >= r[0] and n <= r[1]
|
return n >= r[0] and n <= r[1]
|
||||||
|
|
||||||
_in_range.__doc__ = func.__doc__ + f" between {r[0]} and {r[1]}"
|
_in_range.__doc__ = func.__doc__ + f" between {r[0]} and {r[1]} (inclusive)"
|
||||||
return _in_range
|
return _in_range
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +140,7 @@ valid_param_types = dict(
|
|||||||
beta=beta,
|
beta=beta,
|
||||||
dispersion_file=lambda s: isinstance(s, str),
|
dispersion_file=lambda s: isinstance(s, str),
|
||||||
model=string(["pcf", "marcatili", "marcatili_adjusted", "hasan", "custom"]),
|
model=string(["pcf", "marcatili", "marcatili_adjusted", "hasan", "custom"]),
|
||||||
length=num,
|
length=in_range_excl(num, (0, 1e9)),
|
||||||
capillary_num=integer,
|
capillary_num=integer,
|
||||||
capillary_outer_d=in_range_excl(num, (0, 1e-3)),
|
capillary_outer_d=in_range_excl(num, (0, 1e-3)),
|
||||||
capillary_thickness=in_range_excl(num, (0, 1e-3)),
|
capillary_thickness=in_range_excl(num, (0, 1e-3)),
|
||||||
@@ -139,7 +157,9 @@ valid_param_types = dict(
|
|||||||
pulse=dict(
|
pulse=dict(
|
||||||
field_0=field_0,
|
field_0=field_0,
|
||||||
field_file=lambda s: isinstance(s, str),
|
field_file=lambda s: isinstance(s, str),
|
||||||
power=num,
|
repetition_rate=num,
|
||||||
|
peak_power=num,
|
||||||
|
mean_power=num,
|
||||||
energy=num,
|
energy=num,
|
||||||
soliton_num=num,
|
soliton_num=num,
|
||||||
quantum_noise=boolean,
|
quantum_noise=boolean,
|
||||||
@@ -201,7 +221,9 @@ valid_variable = dict(
|
|||||||
],
|
],
|
||||||
gas=["pressure", "temperature", "gas_name", "plasma_density"],
|
gas=["pressure", "temperature", "gas_name", "plasma_density"],
|
||||||
pulse=[
|
pulse=[
|
||||||
"power",
|
"peak_power",
|
||||||
|
"mean_power",
|
||||||
|
"energy",
|
||||||
"quantum_noise",
|
"quantum_noise",
|
||||||
"shape",
|
"shape",
|
||||||
"wavelength",
|
"wavelength",
|
||||||
|
|||||||
@@ -50,5 +50,5 @@ done
|
|||||||
##############################################################################################
|
##############################################################################################
|
||||||
|
|
||||||
#### call your code below
|
#### call your code below
|
||||||
scgenerator run {config}
|
scgenerator run {configs_list}
|
||||||
exit
|
exit
|
||||||
@@ -18,10 +18,10 @@ default_parameters = dict(
|
|||||||
quantum_noise=False,
|
quantum_noise=False,
|
||||||
intensity_noise=0,
|
intensity_noise=0,
|
||||||
shape="gaussian",
|
shape="gaussian",
|
||||||
frep=80e6,
|
frep=40e6,
|
||||||
behaviors=["spm", "ss"],
|
behaviors=["spm", "ss"],
|
||||||
raman_type="agrawal",
|
raman_type="agrawal",
|
||||||
parallel=False,
|
parallel=True,
|
||||||
repeat=1,
|
repeat=1,
|
||||||
tolerated_error=1e-11,
|
tolerated_error=1e-11,
|
||||||
lower_wavelength_interp_limit=300e-9,
|
lower_wavelength_interp_limit=300e-9,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from typing import Any, Dict, Iterator, List, Set, Tuple
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
from numpy.core.numeric import full
|
|
||||||
from scipy.interpolate.interpolate import interp1d
|
from scipy.interpolate.interpolate import interp1d
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -15,7 +14,7 @@ from .errors import *
|
|||||||
from .logger import get_logger
|
from .logger import get_logger
|
||||||
from .math import length, power_fact
|
from .math import length, power_fact
|
||||||
from .physics import fiber, pulse, units
|
from .physics import fiber, pulse, units
|
||||||
from .utils import count_variations, required_simulations
|
from .utils import count_variations, override_config, required_simulations
|
||||||
|
|
||||||
|
|
||||||
class ParamSequence(Mapping):
|
class ParamSequence(Mapping):
|
||||||
@@ -66,7 +65,7 @@ class ContinuationParamSequence(ParamSequence):
|
|||||||
for variable_list, _ in required_simulations(init_config)
|
for variable_list, _ in required_simulations(init_config)
|
||||||
]
|
]
|
||||||
|
|
||||||
new_config = utils.override_config(init_config, new_config)
|
new_config = utils.override_config(new_config, init_config)
|
||||||
super().__init__(new_config)
|
super().__init__(new_config)
|
||||||
|
|
||||||
def __iter__(self) -> Iterator[Tuple[List[Tuple[str, Any]], Dict[str, Any]]]:
|
def __iter__(self) -> Iterator[Tuple[List[Tuple[str, Any]], Dict[str, Any]]]:
|
||||||
@@ -75,7 +74,6 @@ class ContinuationParamSequence(ParamSequence):
|
|||||||
for variable_list, full_config in required_simulations(self.config):
|
for variable_list, full_config in required_simulations(self.config):
|
||||||
prev_sim_folder = self.find_prev_data_folder(variable_list)
|
prev_sim_folder = self.find_prev_data_folder(variable_list)
|
||||||
full_config["prev_data_dir"] = str(prev_sim_folder.resolve())
|
full_config["prev_data_dir"] = str(prev_sim_folder.resolve())
|
||||||
|
|
||||||
yield variable_list, compute_subsequent_paramters(prev_sim_folder, full_config)
|
yield variable_list, compute_subsequent_paramters(prev_sim_folder, full_config)
|
||||||
|
|
||||||
def find_prev_data_folder(self, new_variable_list: List[Tuple[str, Any]]) -> Path:
|
def find_prev_data_folder(self, new_variable_list: List[Tuple[str, Any]]) -> Path:
|
||||||
@@ -170,6 +168,28 @@ def validate(config: dict) -> dict:
|
|||||||
return _ensure_consistency(config)
|
return _ensure_consistency(config)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_config_sequence(*configs: os.PathLike) -> Dict[str, Any]:
|
||||||
|
"""validates a sequence of configs where all but the first one may have
|
||||||
|
parameters missing
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
configs : os.PathLike
|
||||||
|
sequence of paths to toml config files
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Dict[str, Any]
|
||||||
|
the final config as would be simulated, but of course missing input fields in the middle
|
||||||
|
"""
|
||||||
|
previous = None
|
||||||
|
for config in configs:
|
||||||
|
dico = io.load_toml(config)
|
||||||
|
previous = override_config(dico, previous)
|
||||||
|
validate(previous)
|
||||||
|
return previous
|
||||||
|
|
||||||
|
|
||||||
def wspace(t, t_num=0):
|
def wspace(t, t_num=0):
|
||||||
"""frequency array such that x(t) <-> np.fft(x)(w)
|
"""frequency array such that x(t) <-> np.fft(x)(w)
|
||||||
Parameters
|
Parameters
|
||||||
@@ -312,15 +332,13 @@ def _ensure_consistency_fiber(fiber: Dict[str, Any]):
|
|||||||
When at least one required parameter with no default is missing
|
When at least one required parameter with no default is missing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if _contains(fiber, "beta") and not (
|
if _contains(fiber, "beta"):
|
||||||
_contains(fiber, "n2") and _contains(fiber, "effective_mode_diameter")
|
if not (_contains(fiber, "A_eff") or _contains(fiber, "effective_mode_diameter")):
|
||||||
):
|
|
||||||
fiber = defaults.get(fiber, "gamma", specified_parameters=["beta"])
|
fiber = defaults.get(fiber, "gamma", specified_parameters=["beta"])
|
||||||
fiber.setdefault("model", "custom")
|
fiber.setdefault("model", "custom")
|
||||||
|
|
||||||
elif _contains(fiber, "dispersion_file") and not (
|
elif _contains(fiber, "dispersion_file"):
|
||||||
_contains(fiber, "n2") and _contains(fiber, "effective_mode_diameter")
|
if not (_contains(fiber, "A_eff") or _contains(fiber, "effective_mode_diameter")):
|
||||||
):
|
|
||||||
fiber = defaults.get(fiber, "gamma", specified_parameters=["dispersion_file"])
|
fiber = defaults.get(fiber, "gamma", specified_parameters=["dispersion_file"])
|
||||||
fiber.setdefault("model", "custom")
|
fiber.setdefault("model", "custom")
|
||||||
|
|
||||||
@@ -400,12 +418,17 @@ def _ensure_consistency_pulse(pulse):
|
|||||||
|
|
||||||
if _contains(pulse, "soliton_num"):
|
if _contains(pulse, "soliton_num"):
|
||||||
pulse = defaults.get_multiple(
|
pulse = defaults.get_multiple(
|
||||||
pulse, ["power", "energy", "width", "t0"], 1, specified_parameters=["soliton_num"]
|
pulse,
|
||||||
|
["peak_power", "mean_power", "energy", "width", "t0"],
|
||||||
|
1,
|
||||||
|
specified_parameters=["soliton_num"],
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pulse = defaults.get_multiple(pulse, ["t0", "width"], 1)
|
pulse = defaults.get_multiple(pulse, ["t0", "width"], 1)
|
||||||
pulse = defaults.get_multiple(pulse, ["power", "energy"], 1)
|
pulse = defaults.get_multiple(pulse, ["peak_power", "energy", "mean_power"], 1)
|
||||||
|
if _contains(pulse, "mean_power"):
|
||||||
|
pulse = defaults.get(pulse, "repetition_rate", specified_parameters=["mean_power"])
|
||||||
return pulse
|
return pulse
|
||||||
|
|
||||||
|
|
||||||
@@ -565,6 +588,9 @@ def compute_init_parameters(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
params["hr_w"] = fiber.delayed_raman_w(params["t"], params["dt"], params["raman_type"])
|
params["hr_w"] = fiber.delayed_raman_w(params["t"], params["dt"], params["raman_type"])
|
||||||
|
|
||||||
# PULSE
|
# PULSE
|
||||||
|
if "mean_power" in params:
|
||||||
|
params["energy"] = params["mean_power"] / params["repetition_rate"]
|
||||||
|
|
||||||
if "field_file" in params:
|
if "field_file" in params:
|
||||||
field_data = np.load(params["field_file"])
|
field_data = np.load(params["field_file"])
|
||||||
field_interp = interp1d(
|
field_interp = interp1d(
|
||||||
@@ -581,7 +607,7 @@ def compute_init_parameters(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
logger.info(f"computed initial N = {params['soliton_num']:.3g}")
|
logger.info(f"computed initial N = {params['soliton_num']:.3g}")
|
||||||
|
|
||||||
params["L_D"] = params["t0"] ** 2 / abs(params["beta"][0])
|
params["L_D"] = params["t0"] ** 2 / abs(params["beta"][0])
|
||||||
params["L_NL"] = 1 / (params["gamma"] * params["power"]) if params["gamma"] else np.inf
|
params["L_NL"] = 1 / (params["gamma"] * params["peak_power"]) if params["gamma"] else np.inf
|
||||||
params["L_sol"] = pi / 2 * params["L_D"]
|
params["L_sol"] = pi / 2 * params["L_D"]
|
||||||
|
|
||||||
# Technical noise
|
# Technical noise
|
||||||
@@ -589,7 +615,7 @@ def compute_init_parameters(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
params = _technical_noise(params)
|
params = _technical_noise(params)
|
||||||
|
|
||||||
params["field_0"] = pulse.initial_field(
|
params["field_0"] = pulse.initial_field(
|
||||||
params["t"], params["shape"], params["t0"], params["power"]
|
params["t"], params["shape"], params["t0"], params["peak_power"]
|
||||||
)
|
)
|
||||||
|
|
||||||
if params["quantum_noise"]:
|
if params["quantum_noise"]:
|
||||||
@@ -605,17 +631,22 @@ def compute_init_parameters(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
def compute_subsequent_paramters(sim_folder: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
def compute_subsequent_paramters(sim_folder: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
|
||||||
params = compute_init_parameters(config)
|
params = compute_init_parameters(config)
|
||||||
params["spec_0"] = io.load_last_spectrum(sim_folder)[1]
|
spec = io.load_last_spectrum(sim_folder)[1]
|
||||||
params["field_0"] = np.fft.ifft(params["spec_0"]) * params["input_transmission"]
|
params["field_0"] = np.fft.ifft(spec) * params["input_transmission"]
|
||||||
|
params["spec_0"] = np.fft.fft(params["field_0"])
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
def _comform_custom_field(params):
|
def _comform_custom_field(params):
|
||||||
params["field_0"] = params["field_0"] * pulse.modify_field_ratio(
|
params["field_0"] = params["field_0"] * pulse.modify_field_ratio(
|
||||||
params["field_o"], params.get("power"), params.get("intensity_noise")
|
params["t"],
|
||||||
|
params["field_0"],
|
||||||
|
params.get("peak_power"),
|
||||||
|
params.get("energy"),
|
||||||
|
params.get("intensity_noise"),
|
||||||
)
|
)
|
||||||
params["width"], params["power"], params["energy"] = pulse.measure_field(
|
params["width"], params["peak_power"], params["energy"] = pulse.measure_field(
|
||||||
params["t"], params["field_0"]
|
params["t"], params["field_0"]
|
||||||
)
|
)
|
||||||
return params
|
return params
|
||||||
@@ -625,14 +656,14 @@ def _update_pulse_parameters(params):
|
|||||||
(
|
(
|
||||||
params["width"],
|
params["width"],
|
||||||
params["t0"],
|
params["t0"],
|
||||||
params["power"],
|
params["peak_power"],
|
||||||
params["energy"],
|
params["energy"],
|
||||||
params["soliton_num"],
|
params["soliton_num"],
|
||||||
) = pulse.conform_pulse_params(
|
) = pulse.conform_pulse_params(
|
||||||
shape=params["shape"],
|
shape=params["shape"],
|
||||||
width=params.get("width", None),
|
width=params.get("width", None),
|
||||||
t0=params.get("t0", None),
|
t0=params.get("t0", None),
|
||||||
power=params.get("power", None),
|
peak_power=params.get("peak_power", None),
|
||||||
energy=params.get("energy", None),
|
energy=params.get("energy", None),
|
||||||
gamma=params["gamma"],
|
gamma=params["gamma"],
|
||||||
beta2=params["beta"][0],
|
beta2=params["beta"][0],
|
||||||
@@ -658,7 +689,7 @@ def _technical_noise(params):
|
|||||||
if params["intensity_noise"] > 0:
|
if params["intensity_noise"] > 0:
|
||||||
logger.info(f"intensity noise of {params['intensity_noise']}")
|
logger.info(f"intensity noise of {params['intensity_noise']}")
|
||||||
delta_int, delta_T0 = pulse.technical_noise(params["intensity_noise"])
|
delta_int, delta_T0 = pulse.technical_noise(params["intensity_noise"])
|
||||||
params["power"] *= delta_int
|
params["peak_power"] *= delta_int
|
||||||
params["t0"] *= delta_T0
|
params["t0"] *= delta_T0
|
||||||
params["width"] *= delta_T0
|
params["width"] *= delta_T0
|
||||||
params = _update_pulse_parameters(params)
|
params = _update_pulse_parameters(params)
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ from glob import glob
|
|||||||
from typing import Any, Dict, Iterable, List, Tuple, Union
|
from typing import Any, Dict, Iterable, List, Tuple, Union
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.lib import delete
|
|
||||||
import pkg_resources as pkg
|
import pkg_resources as pkg
|
||||||
import toml
|
import toml
|
||||||
from ray import util
|
|
||||||
from send2trash import TrashPermissionError, send2trash
|
from send2trash import TrashPermissionError, send2trash
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -139,6 +137,7 @@ def load_toml(path: os.PathLike):
|
|||||||
|
|
||||||
def save_toml(path, dico):
|
def save_toml(path, dico):
|
||||||
"""saves a dictionary into a toml file"""
|
"""saves a dictionary into a toml file"""
|
||||||
|
path = str(path)
|
||||||
if not path.lower().endswith(".toml"):
|
if not path.lower().endswith(".toml"):
|
||||||
path += ".toml"
|
path += ".toml"
|
||||||
with open(path, mode="w") as file:
|
with open(path, mode="w") as file:
|
||||||
@@ -366,42 +365,11 @@ def load_last_spectrum(path: str) -> Tuple[int, np.ndarray]:
|
|||||||
return num, np.load(os.path.join(path, f"spectrum_{num}.npy"))
|
return num, np.load(os.path.join(path, f"spectrum_{num}.npy"))
|
||||||
|
|
||||||
|
|
||||||
def merge(paths: Union[str, List[str]]):
|
def merge(paths: Union[str, List[str]], delete=False):
|
||||||
if isinstance(paths, str):
|
if isinstance(paths, (str, Path)):
|
||||||
paths = [paths]
|
paths = [paths]
|
||||||
for path in paths:
|
for path in paths:
|
||||||
merge_same_simulations(path, delete=False)
|
merge_same_simulations(path, delete=delete)
|
||||||
|
|
||||||
|
|
||||||
def append_simulations(paths: List[os.PathLike]):
|
|
||||||
paths: List[Path] = [Path(p).resolve() for p in paths]
|
|
||||||
master_sim_path = paths[-1]
|
|
||||||
merged_path = master_sim_path.parent / "merged_sims"
|
|
||||||
merged_path.mkdir(exist_ok=True)
|
|
||||||
for i, path in enumerate(paths):
|
|
||||||
shutil.copy(path / "initial_config.toml", merged_path / f"initial_config{i}.toml")
|
|
||||||
for sim in master_sim_path.glob("*"):
|
|
||||||
if not sim.is_dir() or not str(sim).endswith("merged"):
|
|
||||||
continue
|
|
||||||
sim_name = sim.name
|
|
||||||
merge_sim_path = merged_path / sim_name
|
|
||||||
merge_sim_path.mkdir(exist_ok=True)
|
|
||||||
shutil.copy(sim / "params.toml", merge_sim_path / f"params.toml")
|
|
||||||
z = []
|
|
||||||
z_num = 0
|
|
||||||
last_z = 0
|
|
||||||
for path in paths:
|
|
||||||
curr_z_num = load_toml(str(path / sim_name / "params.toml"))["z_num"]
|
|
||||||
for i in range(curr_z_num):
|
|
||||||
shutil.copy(
|
|
||||||
path / sim_name / f"spectra_{i}.npy",
|
|
||||||
merge_sim_path / f"spectra_{i + z_num}.npy",
|
|
||||||
)
|
|
||||||
z_arr = np.load(path / sim_name / "z.npy")
|
|
||||||
z.append(z_arr + last_z)
|
|
||||||
last_z += z_arr[-1]
|
|
||||||
z_num += curr_z_num
|
|
||||||
np.save(merge_sim_path / "z.npy", np.concatenate(z))
|
|
||||||
|
|
||||||
|
|
||||||
def append_and_merge(final_sim_path: os.PathLike, new_name=None):
|
def append_and_merge(final_sim_path: os.PathLike, new_name=None):
|
||||||
@@ -409,20 +377,56 @@ def append_and_merge(final_sim_path: os.PathLike, new_name=None):
|
|||||||
if new_name is None:
|
if new_name is None:
|
||||||
new_name = final_sim_path.name + " appended"
|
new_name = final_sim_path.name + " appended"
|
||||||
|
|
||||||
appended_path = final_sim_path.parent / new_name
|
destination_path = final_sim_path.parent / new_name
|
||||||
appended_path.mkdir(exist_ok=True)
|
destination_path.mkdir(exist_ok=True)
|
||||||
|
|
||||||
for sim_path in final_sim_path.glob("id*num*"):
|
for sim_path in tqdm(list(final_sim_path.glob("id*num*")), position=0, desc="Appending"):
|
||||||
path_tree = [sim_path]
|
path_tree = [sim_path]
|
||||||
sim_name = sim_path.name
|
sim_name = sim_path.name
|
||||||
appended_sim_path = appended_path / sim_name
|
appended_sim_path = destination_path / sim_name
|
||||||
appended_sim_path.mkdir(exist_ok=True)
|
appended_sim_path.mkdir(exist_ok=True)
|
||||||
|
|
||||||
while (prev_sim_path := load_toml(path_tree[-1] / "params.toml")).get(
|
while (
|
||||||
"prev_sim_dir"
|
prev_sim_path := load_toml(path_tree[-1] / "params.toml").get("prev_data_dir")
|
||||||
) is not None:
|
) is not None:
|
||||||
path_tree.append(Path(prev_sim_path).resolve())
|
path_tree.append(Path(prev_sim_path).resolve())
|
||||||
|
|
||||||
|
z: List[np.ndarray] = []
|
||||||
|
z_num = 0
|
||||||
|
last_z = 0
|
||||||
|
for path in tqdm(list(reversed(path_tree)), position=1, leave=False):
|
||||||
|
curr_z_num = load_toml(path / "params.toml")["z_num"]
|
||||||
|
for i in range(curr_z_num):
|
||||||
|
shutil.copy(
|
||||||
|
path / f"spectrum_{i}.npy",
|
||||||
|
appended_sim_path / f"spectrum_{i + z_num}.npy",
|
||||||
|
)
|
||||||
|
z_arr = np.load(path / "z.npy")
|
||||||
|
z.append(z_arr + last_z)
|
||||||
|
last_z += z_arr[-1]
|
||||||
|
z_num += curr_z_num
|
||||||
|
z_arr = np.concatenate(z)
|
||||||
|
update_appended_params(sim_path / "params.toml", appended_sim_path / "params.toml", z_arr)
|
||||||
|
np.save(appended_sim_path / "z.npy", z_arr)
|
||||||
|
|
||||||
|
update_appended_params(
|
||||||
|
final_sim_path / "initial_config.toml", destination_path / "initial_config.toml", z_arr
|
||||||
|
)
|
||||||
|
|
||||||
|
merge(destination_path, delete=True)
|
||||||
|
|
||||||
|
|
||||||
|
def update_appended_params(param_path, new_path, z):
|
||||||
|
z_num = len(z)
|
||||||
|
params = load_toml(param_path)
|
||||||
|
if "simulation" in params:
|
||||||
|
params["simulation"]["z_num"] = z_num
|
||||||
|
params["simulation"]["z_targets"] = z_num
|
||||||
|
else:
|
||||||
|
params["z_num"] = z_num
|
||||||
|
params["z_targets"] = z_num
|
||||||
|
save_toml(new_path, params)
|
||||||
|
|
||||||
|
|
||||||
def merge_same_simulations(path: str, delete=True):
|
def merge_same_simulations(path: str, delete=True):
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
@@ -443,7 +447,7 @@ def merge_same_simulations(path: str, delete=True):
|
|||||||
base_folders.add(base_folder)
|
base_folders.add(base_folder)
|
||||||
|
|
||||||
sim_num, param_num = utils.count_variations(config)
|
sim_num, param_num = utils.count_variations(config)
|
||||||
pbar = utils.PBars(tqdm(total=sim_num * z_num, desc="merging data", ncols=100))
|
pbar = utils.PBars(tqdm(total=sim_num * z_num, desc="Merging data", ncols=100))
|
||||||
|
|
||||||
spectra = []
|
spectra = []
|
||||||
for z_id in range(z_num):
|
for z_id in range(z_num):
|
||||||
@@ -462,7 +466,7 @@ def merge_same_simulations(path: str, delete=True):
|
|||||||
if repeat_id == max_repeat_id:
|
if repeat_id == max_repeat_id:
|
||||||
out_path = os.path.join(
|
out_path = os.path.join(
|
||||||
path,
|
path,
|
||||||
utils.format_variable_list(variable_and_ind[:-1]) + PARAM_SEPARATOR + "merged",
|
utils.format_variable_list(variable_and_ind[1:-1]) + PARAM_SEPARATOR + "merged",
|
||||||
)
|
)
|
||||||
out_path = ensure_folder(out_path, prevent_overwrite=False)
|
out_path = ensure_folder(out_path, prevent_overwrite=False)
|
||||||
spectra = np.array(spectra).reshape(repeat, len(spectra[0]))
|
spectra = np.array(spectra).reshape(repeat, len(spectra[0]))
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def _power_fact_array(x, n):
|
|||||||
|
|
||||||
|
|
||||||
@jit(nopython=True)
|
@jit(nopython=True)
|
||||||
def abs2(z):
|
def abs2(z: np.ndarray) -> np.ndarray:
|
||||||
return z.real ** 2 + z.imag ** 2
|
return z.real ** 2 + z.imag ** 2
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ P0T0_to_E0_fac = dict(
|
|||||||
"""relates the total energy (amplitue^2) to the t0 parameter of the amplitude and the peak intensity (peak_amplitude^2)"""
|
"""relates the total energy (amplitue^2) to the t0 parameter of the amplitude and the peak intensity (peak_amplitude^2)"""
|
||||||
|
|
||||||
|
|
||||||
def initial_field(t, shape, t0, power):
|
def initial_field(t, shape, t0, peak_power):
|
||||||
"""returns the initial field
|
"""returns the initial field
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -56,7 +56,7 @@ def initial_field(t, shape, t0, power):
|
|||||||
t0 : float
|
t0 : float
|
||||||
time parameters. Can be obtained by dividing the FWHM by
|
time parameters. Can be obtained by dividing the FWHM by
|
||||||
`scgenerator.physics.pulse.fwhm_to_T0_fac[shape]`
|
`scgenerator.physics.pulse.fwhm_to_T0_fac[shape]`
|
||||||
power : float
|
peak_power : float
|
||||||
peak power
|
peak power
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@@ -70,20 +70,26 @@ def initial_field(t, shape, t0, power):
|
|||||||
raised when shape is not recognized
|
raised when shape is not recognized
|
||||||
"""
|
"""
|
||||||
if shape == "gaussian":
|
if shape == "gaussian":
|
||||||
return gauss_pulse(t, t0, power)
|
return gauss_pulse(t, t0, peak_power)
|
||||||
elif shape == "sech":
|
elif shape == "sech":
|
||||||
return sech_pulse(t, t0, power)
|
return sech_pulse(t, t0, peak_power)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"shape '{shape}' not understood")
|
raise ValueError(f"shape '{shape}' not understood")
|
||||||
|
|
||||||
|
|
||||||
def modify_field_ratio(
|
def modify_field_ratio(
|
||||||
field: np.ndarray, target_power: float = None, intensity_noise: float = None
|
t: np.ndarray,
|
||||||
|
field: np.ndarray,
|
||||||
|
target_power: float = None,
|
||||||
|
target_energy: float = None,
|
||||||
|
intensity_noise: float = None,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""multiply a field by this number to get the desired effects
|
"""multiply a field by this number to get the desired effects
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
t : np.ndarray
|
||||||
|
time (only used when target_energy is not None)
|
||||||
field : np.ndarray
|
field : np.ndarray
|
||||||
initial field
|
initial field
|
||||||
target_power : float, optional
|
target_power : float, optional
|
||||||
@@ -97,8 +103,11 @@ def modify_field_ratio(
|
|||||||
ratio (multiply field by this number)
|
ratio (multiply field by this number)
|
||||||
"""
|
"""
|
||||||
ratio = 1
|
ratio = 1
|
||||||
if target_power is not None:
|
if target_energy is not None:
|
||||||
|
ratio *= np.sqrt(target_energy / np.trapz(abs2(field), t))
|
||||||
|
elif target_power is not None:
|
||||||
ratio *= np.sqrt(target_power / abs2(field).max())
|
ratio *= np.sqrt(target_power / abs2(field).max())
|
||||||
|
|
||||||
if intensity_noise is not None:
|
if intensity_noise is not None:
|
||||||
d_int, _ = technical_noise(intensity_noise)
|
d_int, _ = technical_noise(intensity_noise)
|
||||||
ratio *= np.sqrt(d_int)
|
ratio *= np.sqrt(d_int)
|
||||||
@@ -109,7 +118,7 @@ def conform_pulse_params(
|
|||||||
shape,
|
shape,
|
||||||
width=None,
|
width=None,
|
||||||
t0=None,
|
t0=None,
|
||||||
power=None,
|
peak_power=None,
|
||||||
energy=None,
|
energy=None,
|
||||||
soliton_num=None,
|
soliton_num=None,
|
||||||
gamma=None,
|
gamma=None,
|
||||||
@@ -125,7 +134,7 @@ def conform_pulse_params(
|
|||||||
fwhm of the intensity pulse, by default None
|
fwhm of the intensity pulse, by default None
|
||||||
t0 : float, optional
|
t0 : float, optional
|
||||||
time parameter of the amplitude pulse, by default None
|
time parameter of the amplitude pulse, by default None
|
||||||
power : float, optional
|
peak_power : float, optional
|
||||||
peak power, by default None
|
peak power, by default None
|
||||||
energy : float, optional
|
energy : float, optional
|
||||||
total energy of the pulse, by default None
|
total energy of the pulse, by default None
|
||||||
@@ -140,17 +149,17 @@ def conform_pulse_params(
|
|||||||
indicated by the order in which the parameters are enumerated below holds,
|
indicated by the order in which the parameters are enumerated below holds,
|
||||||
meaning the superflous parameters will be overwritten.
|
meaning the superflous parameters will be overwritten.
|
||||||
choose one of the possible combinations :
|
choose one of the possible combinations :
|
||||||
1 of (width, t0), 1 of (power, energy), gamma and beta2 together optional (not one without the other)
|
1 of (width, t0), 1 of (peak_power, energy), gamma and beta2 together optional (not one without the other)
|
||||||
soliton_num, gamma, 1 of (width, power, energy, t0)
|
soliton_num, gamma, 1 of (width, peak_power, energy, t0)
|
||||||
examples :
|
examples :
|
||||||
specify width, power and energy -> t0 and energy will be computed
|
specify width, peak_power and energy -> t0 and energy will be computed
|
||||||
specify soliton_num, gamma, power, t0 -> width, t0 and energy will be computed
|
specify soliton_num, gamma, peak_power, t0 -> width, t0 and energy will be computed
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
width, t0, power, energy
|
width, t0, peak_power, energy
|
||||||
when no gamma is specified
|
when no gamma is specified
|
||||||
width, t0, power, energy, soliton_num
|
width, t0, peak_power, energy, soliton_num
|
||||||
when gamma is specified
|
when gamma is specified
|
||||||
|
|
||||||
Raises
|
Raises
|
||||||
@@ -167,14 +176,14 @@ def conform_pulse_params(
|
|||||||
raise TypeError("gamma must be specified when soliton_num is")
|
raise TypeError("gamma must be specified when soliton_num is")
|
||||||
|
|
||||||
if width is not None:
|
if width is not None:
|
||||||
power = soliton_num ** 2 * abs(beta2) / (gamma * t0 ** 2)
|
peak_power = soliton_num ** 2 * abs(beta2) / (gamma * t0 ** 2)
|
||||||
elif power is not None:
|
elif peak_power is not None:
|
||||||
t0 = np.sqrt(soliton_num ** 2 * abs(beta2) / (power * gamma))
|
t0 = np.sqrt(soliton_num ** 2 * abs(beta2) / (peak_power * gamma))
|
||||||
elif energy is not None:
|
elif energy is not None:
|
||||||
t0 = P0T0_to_E0_fac[shape] * soliton_num ** 2 * abs(beta2) / (energy * gamma)
|
t0 = P0T0_to_E0_fac[shape] * soliton_num ** 2 * abs(beta2) / (energy * gamma)
|
||||||
elif t0 is not None:
|
elif t0 is not None:
|
||||||
width = t0 / fwhm_to_T0_fac[shape]
|
width = t0 / fwhm_to_T0_fac[shape]
|
||||||
power = soliton_num ** 2 * abs(beta2) / (gamma * t0 ** 2)
|
peak_power = soliton_num ** 2 * abs(beta2) / (gamma * t0 ** 2)
|
||||||
else:
|
else:
|
||||||
raise TypeError("not enough parameters to determine pulse")
|
raise TypeError("not enough parameters to determine pulse")
|
||||||
|
|
||||||
@@ -183,26 +192,26 @@ def conform_pulse_params(
|
|||||||
else:
|
else:
|
||||||
width = t0 / fwhm_to_T0_fac[shape]
|
width = t0 / fwhm_to_T0_fac[shape]
|
||||||
|
|
||||||
if power is not None:
|
if peak_power is not None:
|
||||||
energy = P0_to_E0(power, t0, shape)
|
energy = P0_to_E0(peak_power, t0, shape)
|
||||||
else:
|
else:
|
||||||
power = E0_to_P0(energy, t0, shape)
|
peak_power = E0_to_P0(energy, t0, shape)
|
||||||
|
|
||||||
if gamma is None:
|
if gamma is None:
|
||||||
return width, t0, power, energy
|
return width, t0, peak_power, energy
|
||||||
else:
|
else:
|
||||||
if soliton_num is None:
|
if soliton_num is None:
|
||||||
soliton_num = np.sqrt(power * gamma * t0 ** 2 / abs(beta2))
|
soliton_num = np.sqrt(peak_power * gamma * t0 ** 2 / abs(beta2))
|
||||||
return width, t0, power, energy, soliton_num
|
return width, t0, peak_power, energy, soliton_num
|
||||||
|
|
||||||
|
|
||||||
def E0_to_P0(E0, t0, shape="gaussian"):
|
def E0_to_P0(E0, t0, shape="gaussian"):
|
||||||
"""convert an initial total pulse energy to a pulse peak power"""
|
"""convert an initial total pulse energy to a pulse peak peak_power"""
|
||||||
return E0 / (t0 * P0T0_to_E0_fac[shape])
|
return E0 / (t0 * P0T0_to_E0_fac[shape])
|
||||||
|
|
||||||
|
|
||||||
def P0_to_E0(P0, t0, shape="gaussian"):
|
def P0_to_E0(P0, t0, shape="gaussian"):
|
||||||
"""converts initial peak power to pulse energy"""
|
"""converts initial peak peak_power to pulse energy"""
|
||||||
return P0 * t0 * P0T0_to_E0_fac[shape]
|
return P0 * t0 * P0T0_to_E0_fac[shape]
|
||||||
|
|
||||||
|
|
||||||
@@ -234,7 +243,7 @@ def technical_noise(rms_noise, relative_factor=0.4):
|
|||||||
rms_noise : float
|
rms_noise : float
|
||||||
RMS amplitude noise of the laser
|
RMS amplitude noise of the laser
|
||||||
relative factor : float
|
relative factor : float
|
||||||
magnitude of the anticorrelation between power and pulse width noise
|
magnitude of the anticorrelation between peak_power and pulse width noise
|
||||||
Returns
|
Returns
|
||||||
----------
|
----------
|
||||||
delta_int : float
|
delta_int : float
|
||||||
@@ -825,9 +834,10 @@ def measure_properties(spectra, t, compress=True, debug=""):
|
|||||||
|
|
||||||
|
|
||||||
def measure_field(t: np.ndarray, field: np.ndarray) -> Tuple[float, float, float]:
|
def measure_field(t: np.ndarray, field: np.ndarray) -> Tuple[float, float, float]:
|
||||||
|
"""returns fwhm, peak_power, energy"""
|
||||||
intensity = abs2(field)
|
intensity = abs2(field)
|
||||||
_, fwhm_lim, _, _ = find_lobe_limits(t, intensity)
|
_, fwhm_lim, _, _ = find_lobe_limits(t, intensity)
|
||||||
fwhm = length(fwhm_lim)
|
fwhm = length(fwhm_lim)
|
||||||
power = intensity.max()
|
peak_power = intensity.max()
|
||||||
energy = np.trapz(intensity, t)
|
energy = np.trapz(intensity, t)
|
||||||
return fwhm, power, energy
|
return fwhm, peak_power, energy
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import numpy as np
|
|||||||
from numba import jit
|
from numba import jit
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from .. import initialize, io, utils
|
from .. import initialize, io, utils, const
|
||||||
from ..errors import IncompleteDataFolderError
|
from ..errors import IncompleteDataFolderError
|
||||||
from ..logger import get_logger
|
from ..logger import get_logger
|
||||||
from . import pulse
|
from . import pulse
|
||||||
@@ -36,7 +36,7 @@ class RK4IP:
|
|||||||
w0 : float
|
w0 : float
|
||||||
central angular frequency of the pulse
|
central angular frequency of the pulse
|
||||||
w_power_fact : numpy.ndarray
|
w_power_fact : numpy.ndarray
|
||||||
precomputed factorial/power operations on w_c (scgenerator.math.power_fact)
|
precomputed factorial/peak_power operations on w_c (scgenerator.math.power_fact)
|
||||||
spec_0 : numpy.ndarray
|
spec_0 : numpy.ndarray
|
||||||
initial spectral envelope as function of w_c
|
initial spectral envelope as function of w_c
|
||||||
z_targets : list
|
z_targets : list
|
||||||
@@ -304,6 +304,31 @@ class RK4IP:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SequentialRK4IP(RK4IP):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
sim_params,
|
||||||
|
overall_pbar: tqdm,
|
||||||
|
save_data=False,
|
||||||
|
job_identifier="",
|
||||||
|
task_id=0,
|
||||||
|
n_percent=10,
|
||||||
|
):
|
||||||
|
self.overall_pbar = overall_pbar
|
||||||
|
self.pbar = tqdm(**const.pbar_format(1))
|
||||||
|
super().__init__(
|
||||||
|
sim_params,
|
||||||
|
save_data=save_data,
|
||||||
|
job_identifier=job_identifier,
|
||||||
|
task_id=task_id,
|
||||||
|
n_percent=n_percent,
|
||||||
|
)
|
||||||
|
|
||||||
|
def step_saved(self):
|
||||||
|
self.overall_pbar.update()
|
||||||
|
self.pbar.update(self.z / self.z_final - self.pbar.n)
|
||||||
|
|
||||||
|
|
||||||
class MutliProcRK4IP(RK4IP):
|
class MutliProcRK4IP(RK4IP):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -360,20 +385,25 @@ class Simulations:
|
|||||||
New Simulations child classes can be written and must implement the following
|
New Simulations child classes can be written and must implement the following
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_available_simulation_methods = []
|
simulation_methods: List[Tuple[Type["Simulations"], int]] = []
|
||||||
_available_simulation_methods_dict: Dict[str, Type["Simulations"]] = dict()
|
simulation_methods_dict: Dict[str, Type["Simulations"]] = dict()
|
||||||
|
|
||||||
def __init_subclass__(cls, available: bool, priority=0, **kwargs):
|
def __init_subclass__(cls, priority=0, **kwargs):
|
||||||
cls._available = available
|
cls._available = cls.is_available()
|
||||||
if available:
|
Simulations.simulation_methods.append((cls, priority))
|
||||||
Simulations._available_simulation_methods.append((cls, priority))
|
Simulations.simulation_methods_dict[cls.__name__] = cls
|
||||||
Simulations._available_simulation_methods_dict[cls.__name__] = cls
|
Simulations.simulation_methods.sort(key=lambda el: el[1], reverse=True)
|
||||||
Simulations._available_simulation_methods.sort(key=lambda el: el[1])
|
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_best_method(cls):
|
def get_best_method(cls):
|
||||||
return Simulations._available_simulation_methods[-1][0]
|
for method, _ in Simulations.simulation_methods:
|
||||||
|
if method.is_available():
|
||||||
|
return method
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_available(cls) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
def __init__(self, param_seq: initialize.ParamSequence, task_id=0):
|
def __init__(self, param_seq: initialize.ParamSequence, task_id=0):
|
||||||
"""
|
"""
|
||||||
@@ -454,11 +484,23 @@ class Simulations:
|
|||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class SequencialSimulations(Simulations, available=True, priority=0):
|
class SequencialSimulations(Simulations, priority=0):
|
||||||
|
@classmethod
|
||||||
|
def is_available(cls):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __init__(self, param_seq: initialize.ParamSequence, task_id):
|
||||||
|
super().__init__(param_seq, task_id=task_id)
|
||||||
|
self.overall_pbar = tqdm(
|
||||||
|
total=self.param_seq.num_steps, desc="Simulating", unit="step", **const.pbar_format(0)
|
||||||
|
)
|
||||||
|
|
||||||
def new_sim(self, variable_list: List[tuple], params: Dict[str, Any]):
|
def new_sim(self, variable_list: List[tuple], params: Dict[str, Any]):
|
||||||
v_list_str = utils.format_variable_list(variable_list)
|
v_list_str = utils.format_variable_list(variable_list)
|
||||||
self.logger.info(f"launching simulation with {v_list_str}")
|
self.logger.info(f"launching simulation with {v_list_str}")
|
||||||
RK4IP(params, save_data=True, job_identifier=v_list_str, task_id=self.id).run()
|
SequentialRK4IP(
|
||||||
|
params, self.overall_pbar, save_data=True, job_identifier=v_list_str, task_id=self.id
|
||||||
|
).run()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
pass
|
pass
|
||||||
@@ -467,7 +509,11 @@ class SequencialSimulations(Simulations, available=True, priority=0):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MultiProcSimulations(Simulations, available=True, priority=10):
|
class MultiProcSimulations(Simulations, priority=1):
|
||||||
|
@classmethod
|
||||||
|
def is_available(cls):
|
||||||
|
return True
|
||||||
|
|
||||||
def __init__(self, param_seq: initialize.ParamSequence, task_id):
|
def __init__(self, param_seq: initialize.ParamSequence, task_id):
|
||||||
super().__init__(param_seq, task_id=task_id)
|
super().__init__(param_seq, task_id=task_id)
|
||||||
self.sim_jobs_per_node = max(1, os.cpu_count() // 2)
|
self.sim_jobs_per_node = max(1, os.cpu_count() // 2)
|
||||||
@@ -481,7 +527,7 @@ class MultiProcSimulations(Simulations, available=True, priority=10):
|
|||||||
for i in range(self.sim_jobs_per_node)
|
for i in range(self.sim_jobs_per_node)
|
||||||
]
|
]
|
||||||
self.p_worker = multiprocessing.Process(
|
self.p_worker = multiprocessing.Process(
|
||||||
target=MultiProcSimulations.progress_worker,
|
target=utils.progress_worker,
|
||||||
args=(self.param_seq.num_steps, self.progress_queue),
|
args=(self.param_seq.num_steps, self.progress_queue),
|
||||||
)
|
)
|
||||||
self.p_worker.start()
|
self.p_worker.start()
|
||||||
@@ -530,33 +576,37 @@ class MultiProcSimulations(Simulations, available=True, priority=10):
|
|||||||
).run()
|
).run()
|
||||||
queue.task_done()
|
queue.task_done()
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def progress_worker(num_steps: int, progress_queue: multiprocessing.Queue):
|
# def progress_worker(num_steps: int, progress_queue: multiprocessing.Queue):
|
||||||
pbars: Dict[int, tqdm] = {}
|
# pbars: Dict[int, tqdm] = {}
|
||||||
with tqdm(total=num_steps, desc="Simulating", unit="step", position=0) as tq:
|
# with tqdm(total=num_steps, desc="Simulating", unit="step", position=0) as tq:
|
||||||
while True:
|
# while True:
|
||||||
raw = progress_queue.get()
|
# raw = progress_queue.get()
|
||||||
if raw == 0:
|
# if raw == 0:
|
||||||
for pbar in pbars.values():
|
# for pbar in pbars.values():
|
||||||
pbar.close()
|
# pbar.close()
|
||||||
return
|
# return
|
||||||
i, rel_pos = raw
|
# i, rel_pos = raw
|
||||||
if i not in pbars:
|
# if i not in pbars:
|
||||||
pbars[i] = tqdm(
|
# pbars[i] = tqdm(
|
||||||
total=1,
|
# total=1,
|
||||||
desc=f"Worker {i}",
|
# desc=f"Worker {i}",
|
||||||
position=i,
|
# position=i,
|
||||||
bar_format="{l_bar}{bar}"
|
# bar_format="{l_bar}{bar}"
|
||||||
"|[{elapsed}<{remaining}, "
|
# "|[{elapsed}<{remaining}, "
|
||||||
"{rate_fmt}{postfix}]",
|
# "{rate_fmt}{postfix}]",
|
||||||
)
|
# )
|
||||||
pbars[i].update(rel_pos - pbars[i].n)
|
# pbars[i].update(rel_pos - pbars[i].n)
|
||||||
tq.update()
|
# tq.update()
|
||||||
|
|
||||||
|
|
||||||
class RaySimulations(Simulations, available=using_ray, priority=2):
|
class RaySimulations(Simulations, priority=2):
|
||||||
"""runs simulation with the help of the ray module. ray must be initialized before creating an instance of RaySimulations"""
|
"""runs simulation with the help of the ray module. ray must be initialized before creating an instance of RaySimulations"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_available(cls):
|
||||||
|
return using_ray and ray.is_initialized()
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
param_seq: initialize.ParamSequence,
|
param_seq: initialize.ParamSequence,
|
||||||
@@ -660,8 +710,17 @@ class RaySimulations(Simulations, available=using_ray, priority=2):
|
|||||||
self.p_bars.print()
|
self.p_bars.print()
|
||||||
|
|
||||||
|
|
||||||
def new_simulations(
|
def run_simulation_sequence(*config_files: os.PathLike, method=None, final_name: str = None):
|
||||||
config_file: str,
|
prev = None
|
||||||
|
for config_file in config_files:
|
||||||
|
sim = new_simulation(config_file, prev, method)
|
||||||
|
sim.run()
|
||||||
|
prev = sim.data_folder
|
||||||
|
io.append_and_merge(prev, final_name)
|
||||||
|
|
||||||
|
|
||||||
|
def new_simulation(
|
||||||
|
config_file: os.PathLike,
|
||||||
prev_data_folder=None,
|
prev_data_folder=None,
|
||||||
method: Type[Simulations] = None,
|
method: Type[Simulations] = None,
|
||||||
) -> Simulations:
|
) -> Simulations:
|
||||||
@@ -697,7 +756,7 @@ def _new_simulations(
|
|||||||
) -> Simulations:
|
) -> Simulations:
|
||||||
if method is not None:
|
if method is not None:
|
||||||
if isinstance(method, str):
|
if isinstance(method, str):
|
||||||
method = Simulations._available_simulation_methods_dict[method]
|
method = Simulations.simulation_methods_dict[method]
|
||||||
return method(param_seq, task_id)
|
return method(param_seq, task_id)
|
||||||
elif param_seq.num_sim > 1 and param_seq["simulation", "parallel"] and using_ray:
|
elif param_seq.num_sim > 1 and param_seq["simulation", "parallel"] and using_ray:
|
||||||
return Simulations.get_best_method()(param_seq, task_id)
|
return Simulations.get_best_method()(param_seq, task_id)
|
||||||
@@ -711,4 +770,4 @@ if __name__ == "__main__":
|
|||||||
except NameError:
|
except NameError:
|
||||||
pass
|
pass
|
||||||
config_file, *opts = sys.argv[1:]
|
config_file, *opts = sys.argv[1:]
|
||||||
new_simulations(config_file, *opts)
|
new_simulation(config_file, *opts)
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
# 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 numba.core.types.misc import Phantom
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy import pi
|
from numpy import isin, pi
|
||||||
|
|
||||||
c = 299792458.0
|
c = 299792458.0
|
||||||
hbar = 1.05457148e-34
|
hbar = 1.05457148e-34
|
||||||
@@ -198,6 +199,30 @@ D_ps_nm_km.label = r"$D$ (ps/(nm km))"
|
|||||||
D_ps_nm_km.type = "OTHER"
|
D_ps_nm_km.type = "OTHER"
|
||||||
|
|
||||||
|
|
||||||
|
units_map = dict(
|
||||||
|
nm=nm,
|
||||||
|
um=um,
|
||||||
|
m=m,
|
||||||
|
THz=THz,
|
||||||
|
PHz=PHz,
|
||||||
|
rad_s=rad_s,
|
||||||
|
Prad_s=Prad_s,
|
||||||
|
rel_freq=rel_freq,
|
||||||
|
rel_time=rel_time,
|
||||||
|
s=s,
|
||||||
|
us=us,
|
||||||
|
ns=ns,
|
||||||
|
ps=ps,
|
||||||
|
fs=fs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_unit(unit):
|
||||||
|
if isinstance(unit, str):
|
||||||
|
return units_map[unit]
|
||||||
|
return unit
|
||||||
|
|
||||||
|
|
||||||
def beta2_coef(beta):
|
def beta2_coef(beta):
|
||||||
fac = 1e27
|
fac = 1e27
|
||||||
out = np.zeros_like(beta)
|
out = np.zeros_like(beta)
|
||||||
@@ -217,11 +242,16 @@ def standardize_dictionary(dico):
|
|||||||
same dictionary with units converted
|
same dictionary with units converted
|
||||||
Example
|
Example
|
||||||
----------
|
----------
|
||||||
standardize_dictionary({"power": [23, "kW"], "points": [1, 2, 3]})
|
standardize_dictionary({"peak_power": [23, "kW"], "points": [1, 2, 3]})
|
||||||
{"power": 23000, "points": [1, 2, 3]})
|
{"peak_power": 23000, "points": [1, 2, 3]})
|
||||||
"""
|
"""
|
||||||
for key, item in dico.items():
|
for key, item in dico.items():
|
||||||
if isinstance(item, list) and len(item) == 2 and isinstance(item[0], (int, float)) and isinstance(item[1], str):
|
if (
|
||||||
|
isinstance(item, list)
|
||||||
|
and len(item) == 2
|
||||||
|
and isinstance(item[0], (int, float))
|
||||||
|
and isinstance(item[1], str)
|
||||||
|
):
|
||||||
num, unit = item
|
num, unit = item
|
||||||
fac = 1
|
fac = 1
|
||||||
if len(unit) == 2:
|
if len(unit) == 2:
|
||||||
@@ -263,7 +293,7 @@ def sort_axis(axis, plt_range):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
r = np.array(plt_range[:2], dtype="float")
|
r = np.array(plt_range[:2], dtype="float")
|
||||||
func = plt_range[2]
|
func = get_unit(plt_range[2])
|
||||||
|
|
||||||
indices = np.arange(len(axis))[(axis <= np.max(func(r))) & (axis >= np.min(func(r)))]
|
indices = np.arange(len(axis))[(axis <= np.max(func(r))) & (axis >= np.min(func(r)))]
|
||||||
cropped = axis[indices]
|
cropped = axis[indices]
|
||||||
|
|||||||
@@ -528,12 +528,7 @@ def plot_results_2D(
|
|||||||
print(f"Shape was {values.shape}. plot_results_2D can only plot 2D arrays")
|
print(f"Shape was {values.shape}. plot_results_2D can only plot 2D arrays")
|
||||||
return
|
return
|
||||||
|
|
||||||
is_spectrum = values.dtype == "complex"
|
is_spectrum, x_axis, plt_range = _prep_plot(values, plt_range, params)
|
||||||
|
|
||||||
if plt_range[2].type in ["WL", "FREQ", "AFREQ"]:
|
|
||||||
x_axis = params["w"].copy()
|
|
||||||
else:
|
|
||||||
x_axis = params["t"].copy()
|
|
||||||
|
|
||||||
# crop and convert
|
# crop and convert
|
||||||
x_axis, ind, ext = units.sort_axis(x_axis[::skip], plt_range)
|
x_axis, ind, ext = units.sort_axis(x_axis[::skip], plt_range)
|
||||||
@@ -648,12 +643,7 @@ def plot_results_1D(
|
|||||||
print(f"Shape was {values.shape}. plot_results_1D can only plot 1D arrays")
|
print(f"Shape was {values.shape}. plot_results_1D can only plot 1D arrays")
|
||||||
return
|
return
|
||||||
|
|
||||||
is_spectrum = values.dtype == "complex"
|
is_spectrum, x_axis, plt_range = _prep_plot(values, plt_range, params)
|
||||||
|
|
||||||
if plt_range[2].type in ["WL", "FREQ", "AFREQ"]:
|
|
||||||
x_axis = params["w"].copy()
|
|
||||||
else:
|
|
||||||
x_axis = params["t"].copy()
|
|
||||||
|
|
||||||
# crop and convert
|
# crop and convert
|
||||||
x_axis, ind, ext = units.sort_axis(x_axis, plt_range)
|
x_axis, ind, ext = units.sort_axis(x_axis, plt_range)
|
||||||
@@ -716,6 +706,16 @@ def plot_results_1D(
|
|||||||
return fig, ax
|
return fig, ax
|
||||||
|
|
||||||
|
|
||||||
|
def _prep_plot(values, plt_range, params):
|
||||||
|
is_spectrum = values.dtype == "complex"
|
||||||
|
plt_range = (*plt_range[:2], units.get_unit(plt_range[2]))
|
||||||
|
if plt_range[2].type in ["WL", "FREQ", "AFREQ"]:
|
||||||
|
x_axis = params["w"].copy()
|
||||||
|
else:
|
||||||
|
x_axis = params["t"].copy()
|
||||||
|
return is_spectrum, x_axis, plt_range
|
||||||
|
|
||||||
|
|
||||||
def plot_avg(
|
def plot_avg(
|
||||||
values,
|
values,
|
||||||
plt_range,
|
plt_range,
|
||||||
@@ -795,12 +795,7 @@ def plot_avg(
|
|||||||
print(f"Shape was {values.shape}. plot_avg can only plot 2D arrays")
|
print(f"Shape was {values.shape}. plot_avg can only plot 2D arrays")
|
||||||
return
|
return
|
||||||
|
|
||||||
is_spectrum = values.dtype == "complex"
|
is_spectrum, x_axis, plt_range = _prep_plot(values, plt_range, params)
|
||||||
|
|
||||||
if plt_range[2].type in ["WL", "FREQ", "AFREQ"]:
|
|
||||||
x_axis = params["w"].copy()
|
|
||||||
else:
|
|
||||||
x_axis = params["t"].copy()
|
|
||||||
|
|
||||||
# crop and convert
|
# crop and convert
|
||||||
x_axis, ind, ext = units.sort_axis(x_axis, plt_range)
|
x_axis, ind, ext = units.sort_axis(x_axis, plt_range)
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from scgenerator.initialize import validate
|
from ..initialize import validate_config_sequence
|
||||||
from scgenerator.io import Paths, load_toml
|
from ..utils import count_variations
|
||||||
from scgenerator.utils import count_variations
|
|
||||||
|
|
||||||
|
|
||||||
def format_time(t):
|
def format_time(t):
|
||||||
@@ -20,7 +19,7 @@ def format_time(t):
|
|||||||
|
|
||||||
def create_parser():
|
def create_parser():
|
||||||
parser = argparse.ArgumentParser(description="submit a job to a slurm cluster")
|
parser = argparse.ArgumentParser(description="submit a job to a slurm cluster")
|
||||||
parser.add_argument("config", help="path to the toml configuration file")
|
parser.add_argument("configs", nargs="+", help="path to the toml configuration file")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-t", "--time", required=True, type=str, help="time required for the job in hh:mm:ss"
|
"-t", "--time", required=True, type=str, help="time required for the job in hh:mm:ss"
|
||||||
)
|
)
|
||||||
@@ -59,19 +58,23 @@ def main():
|
|||||||
"time format must be an integer number of minute or must match the pattern hh:mm:ss"
|
"time format must be an integer number of minute or must match the pattern hh:mm:ss"
|
||||||
)
|
)
|
||||||
|
|
||||||
config = load_toml(args.config)
|
config_paths = args.configs
|
||||||
config = validate(config)
|
final_config = validate_config_sequence(*config_paths)
|
||||||
|
|
||||||
sim_num, _ = count_variations(config)
|
sim_num, _ = count_variations(final_config)
|
||||||
|
|
||||||
file_name = "submit " + config["name"] + "-" + format(datetime.now(), "%Y%m%d%H%M") + ".sh"
|
file_name = (
|
||||||
job_name = f"supercontinuum {config['name']}"
|
"submit " + final_config["name"] + "-" + format(datetime.now(), "%Y%m%d%H%M") + ".sh"
|
||||||
submit_sh = template.format(job_name=job_name, **vars(args))
|
)
|
||||||
|
job_name = f"supercontinuum {final_config['name']}"
|
||||||
|
submit_sh = template.format(
|
||||||
|
job_name=job_name, configs_list=" ".join(args.configs), **vars(args)
|
||||||
|
)
|
||||||
with open(file_name, "w") as file:
|
with open(file_name, "w") as file:
|
||||||
file.write(submit_sh)
|
file.write(submit_sh)
|
||||||
subprocess.run(["sbatch", "--test-only", file_name])
|
subprocess.run(["sbatch", "--test-only", file_name])
|
||||||
submit = input(
|
submit = input(
|
||||||
f"Propagate {sim_num} pulses from config {args.config} with {args.cpus_per_node} cpus"
|
f"Propagate {sim_num} pulses from configs {args.configs} with {args.cpus_per_node} cpus"
|
||||||
+ f" per node on {args.nodes} nodes for {format_time(args.time)} ? (y/[n])\n"
|
+ f" per node on {args.nodes} nodes for {format_time(args.time)} ? (y/[n])\n"
|
||||||
)
|
)
|
||||||
if submit.lower() in ["y", "yes"]:
|
if submit.lower() in ["y", "yes"]:
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ class Spectrum(np.ndarray):
|
|||||||
|
|
||||||
|
|
||||||
class Pulse(Sequence):
|
class Pulse(Sequence):
|
||||||
def __init__(self, path: str):
|
def __init__(self, path: str, ensure_2d=True):
|
||||||
self.logger = get_logger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
self.path = path
|
self.path = path
|
||||||
|
self.__ensure_2d = ensure_2d
|
||||||
|
|
||||||
if not os.path.isdir(self.path):
|
if not os.path.isdir(self.path):
|
||||||
raise FileNotFoundError(f"Folder {self.path} does not exist")
|
raise FileNotFoundError(f"Folder {self.path} does not exist")
|
||||||
@@ -175,17 +176,18 @@ class Pulse(Sequence):
|
|||||||
# Load the spectra
|
# Load the spectra
|
||||||
spectra = []
|
spectra = []
|
||||||
for i in ind:
|
for i in ind:
|
||||||
spectra.append(io.load_single_spectrum(self.path, i))
|
spectra.append(self._load1(i))
|
||||||
spectra = np.array(spectra)
|
spectra = np.array(spectra)
|
||||||
|
|
||||||
self.logger.debug(f"all spectra from {self.path} successfully loaded")
|
self.logger.debug(f"all spectra from {self.path} successfully loaded")
|
||||||
|
|
||||||
return spectra.squeeze()
|
return spectra
|
||||||
|
|
||||||
def _load1(self, i: int):
|
def _load1(self, i: int):
|
||||||
return Spectrum(
|
spec = io.load_single_spectrum(self.path, i)
|
||||||
np.atleast_2d(io.load_single_spectrum(self.path, i)), self.wl, self.params["frep"]
|
if self.__ensure_2d:
|
||||||
)
|
spec = np.atleast_2d(spec)
|
||||||
|
return Spectrum(spec, self.wl, self.params["frep"])
|
||||||
|
|
||||||
|
|
||||||
class SpectraCollection(Mapping, Sequence):
|
class SpectraCollection(Mapping, Sequence):
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import collections
|
|||||||
import datetime as dt
|
import datetime as dt
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
import multiprocessing
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
from typing import Any, Callable, Dict, Iterator, List, Mapping, Tuple, Union
|
from typing import Any, Callable, Dict, Iterator, List, Mapping, Tuple, Union
|
||||||
@@ -20,7 +21,7 @@ from copy import deepcopy
|
|||||||
|
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from .const import PARAM_SEPARATOR, PREFIX_KEY_BASE, valid_variable
|
from .const import PARAM_SEPARATOR, PREFIX_KEY_BASE, valid_variable, pbar_format
|
||||||
from .logger import get_logger
|
from .logger import get_logger
|
||||||
from .math import *
|
from .math import *
|
||||||
|
|
||||||
@@ -162,6 +163,33 @@ class ProgressBarActor:
|
|||||||
return self.counters
|
return self.counters
|
||||||
|
|
||||||
|
|
||||||
|
def progress_worker(num_steps: int, progress_queue: multiprocessing.Queue):
|
||||||
|
"""keeps track of progress on a separate thread
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
num_steps : int
|
||||||
|
total number of steps, used for the main progress bar (position 0)
|
||||||
|
progress_queue : multiprocessing.Queue
|
||||||
|
values are either
|
||||||
|
Literal[0] : stop the worker and close the progress bars
|
||||||
|
Tuple[int, float] : worker id and relative progress between 0 and 1
|
||||||
|
"""
|
||||||
|
pbars: Dict[int, tqdm] = {}
|
||||||
|
with tqdm(total=num_steps, desc="Simulating", unit="step", position=0) as tq:
|
||||||
|
while True:
|
||||||
|
raw = progress_queue.get()
|
||||||
|
if raw == 0:
|
||||||
|
for pbar in pbars.values():
|
||||||
|
pbar.close()
|
||||||
|
return
|
||||||
|
i, rel_pos = raw
|
||||||
|
if i not in pbars:
|
||||||
|
pbars[i] = tqdm(**pbar_format(i))
|
||||||
|
pbars[i].update(rel_pos - pbars[i].n)
|
||||||
|
tq.update()
|
||||||
|
|
||||||
|
|
||||||
def count_variations(config: dict) -> Tuple[int, int]:
|
def count_variations(config: dict) -> Tuple[int, int]:
|
||||||
"""returns (sim_num, variable_params_num) where sim_num is the total number of simulations required and
|
"""returns (sim_num, variable_params_num) where sim_num is the total number of simulations required and
|
||||||
variable_params_num is the number of distinct parameters that will vary."""
|
variable_params_num is the number of distinct parameters that will vary."""
|
||||||
@@ -347,7 +375,10 @@ def deep_update(d: Mapping, u: Mapping):
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def override_config(old: Dict[str, Any], new: Dict[str, Any]) -> Dict[str, Any]:
|
def override_config(new: Dict[str, Any], old: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||||
|
"""makes sure all the parameters set in new are there, leaves untouched parameters in old"""
|
||||||
|
if old is None:
|
||||||
|
return new
|
||||||
out = deepcopy(old)
|
out = deepcopy(old)
|
||||||
for section_name, section in new.items():
|
for section_name, section in new.items():
|
||||||
if isinstance(section, Mapping):
|
if isinstance(section, Mapping):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pitch_ratio = 0.37
|
|||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
intensity_noise = 0.05e-2
|
intensity_noise = 0.05e-2
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ model = "marcatili"
|
|||||||
gas_name = ["air", "helium"]
|
gas_name = ["air", "helium"]
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
wavelength = 800e-9
|
wavelength = 800e-9
|
||||||
|
|
||||||
[pulse.variable]
|
[pulse.variable]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ model = "marcatili"
|
|||||||
gas_name = "air"
|
gas_name = "air"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
wavelength = 800e-9
|
wavelength = 800e-9
|
||||||
width = 250e-15
|
width = 250e-15
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ model = "marcatili"
|
|||||||
gas_name = "air"
|
gas_name = "air"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
wavelength = 800e-9
|
wavelength = 800e-9
|
||||||
|
|
||||||
[pulse.variable]
|
[pulse.variable]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ model = "marcatili"
|
|||||||
gas_name = "air"
|
gas_name = "air"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
wavelength = 800e-9
|
wavelength = 800e-9
|
||||||
width = 250e-15
|
width = 250e-15
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#t0, width, power or energy missing
|
#t0, width, peak_power or energy missing
|
||||||
|
|
||||||
name = "test config"
|
name = "test config"
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ length = 1
|
|||||||
model = "hasan"
|
model = "hasan"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ length = 1
|
|||||||
model = "hasan"
|
model = "hasan"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ gas_name = "helium"
|
|||||||
temperature = [300, 350, 400]
|
temperature = [300, 350, 400]
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ length = 1
|
|||||||
model = "marcatili"
|
model = "marcatili"
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
name = "full anomalous"
|
name = "full anomalous"
|
||||||
|
|
||||||
[fiber]
|
[fiber]
|
||||||
beta = [ -1.183e-26, 8.1038e-41, -9.5205e-56, 2.0737e-70, -5.3943e-85, 1.3486e-99, -2.5495e-114, 3.0524e-129, -1.714e-144,]
|
beta = [-1.183e-26, 8.1038e-41, -9.5205e-56, 2.0737e-70, -5.3943e-85, 1.3486e-99, -2.5495e-114, 3.0524e-129, -1.714e-144]
|
||||||
gamma = 0.11
|
gamma = 0.11
|
||||||
|
input_transmission = 1.0
|
||||||
length = 0.02
|
length = 0.02
|
||||||
model = "custom"
|
model = "custom"
|
||||||
input_transmission = 1.0
|
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 10000
|
|
||||||
t0 = 2.84e-14
|
|
||||||
shape = "gaussian"
|
|
||||||
quantum_noise = false
|
|
||||||
intensity_noise = 0
|
intensity_noise = 0
|
||||||
|
peak_power = 10000
|
||||||
|
quantum_noise = false
|
||||||
|
shape = "gaussian"
|
||||||
|
t0 = 2.84e-14
|
||||||
|
|
||||||
[simulation]
|
[simulation]
|
||||||
|
behaviors = ["spm", "ss"]
|
||||||
dt = 1e-15
|
dt = 1e-15
|
||||||
|
frep = 80000000.0
|
||||||
|
ideal_gas = false
|
||||||
|
lower_wavelength_interp_limit = 3e-7
|
||||||
parallel = true
|
parallel = true
|
||||||
raman_type = "measured"
|
raman_type = "measured"
|
||||||
repeat = 3
|
repeat = 3
|
||||||
t_num = 16384
|
t_num = 16384
|
||||||
tolerated_error = 1e-9
|
tolerated_error = 1e-9
|
||||||
z_num = 64
|
|
||||||
behaviors = [ "spm", "ss",]
|
|
||||||
frep = 80000000.0
|
|
||||||
lower_wavelength_interp_limit = 3e-7
|
|
||||||
upper_wavelength_interp_limit = 1.9e-6
|
upper_wavelength_interp_limit = 1.9e-6
|
||||||
ideal_gas = false
|
z_num = 64
|
||||||
|
|
||||||
[pulse.variable]
|
[pulse.variable]
|
||||||
wavelength = [ 8.35e-7, 8.3375e-7,]
|
wavelength = [8.35e-7, 8.3375e-7]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pitch_ratio = 0.37
|
|||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
intensity_noise = 0.1e-2
|
intensity_noise = 0.1e-2
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ gamma = 0.11
|
|||||||
length = 0.02
|
length = 0.02
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 10000
|
peak_power = 10000
|
||||||
t0 = 2.84e-14
|
t0 = 2.84e-14
|
||||||
|
|
||||||
[pulse.variable]
|
[pulse.variable]
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ model = "pcf"
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
|
peak_power = 100e3
|
||||||
pitch = 1.5e-6
|
pitch = 1.5e-6
|
||||||
power = 100e3
|
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pitch_ratio = 0.37
|
|||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
intensity_noise = 0.05e-2
|
intensity_noise = 0.05e-2
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ gamma = 0.018
|
|||||||
length = 1
|
length = 1
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pitch = 1.5e-6
|
|||||||
pitch_ratio = 0.37
|
pitch_ratio = 0.37
|
||||||
|
|
||||||
[pulse]
|
[pulse]
|
||||||
power = 100e3
|
peak_power = 100e3
|
||||||
quantum_noise = true
|
quantum_noise = true
|
||||||
shape = "gaussian"
|
shape = "gaussian"
|
||||||
wavelength = 1050e-9
|
wavelength = 1050e-9
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class TestInitializeMethods(unittest.TestCase):
|
|||||||
|
|
||||||
with self.assertRaisesRegex(
|
with self.assertRaisesRegex(
|
||||||
MissingParameterError,
|
MissingParameterError,
|
||||||
r"1 of '\['power', 'energy', 'width', 't0'\]' is required when 'soliton_num' is specified and no defaults have been set",
|
r"1 of '\['peak_power', 'energy', 'width', 't0'\]' is required when 'soliton_num' is specified and no defaults have been set",
|
||||||
):
|
):
|
||||||
init._ensure_consistency(conf("bad2"))
|
init._ensure_consistency(conf("bad2"))
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ class TestPulseMethods(unittest.TestCase):
|
|||||||
def test_conform_pulse_params(self):
|
def test_conform_pulse_params(self):
|
||||||
self.assertNotIn(None, conform_pulse_params("gaussian", t0=5, energy=6))
|
self.assertNotIn(None, conform_pulse_params("gaussian", t0=5, energy=6))
|
||||||
self.assertNotIn(None, conform_pulse_params("gaussian", width=5, energy=6))
|
self.assertNotIn(None, conform_pulse_params("gaussian", width=5, energy=6))
|
||||||
self.assertNotIn(None, conform_pulse_params("gaussian", t0=5, power=6))
|
self.assertNotIn(None, conform_pulse_params("gaussian", t0=5, peak_power=6))
|
||||||
self.assertNotIn(None, conform_pulse_params("gaussian", width=5, power=6))
|
self.assertNotIn(None, conform_pulse_params("gaussian", width=5, peak_power=6))
|
||||||
|
|
||||||
self.assertEqual(4, len(conform_pulse_params("gaussian", t0=5, energy=6)))
|
self.assertEqual(4, len(conform_pulse_params("gaussian", t0=5, energy=6)))
|
||||||
self.assertEqual(4, len(conform_pulse_params("gaussian", width=5, energy=6)))
|
self.assertEqual(4, len(conform_pulse_params("gaussian", width=5, energy=6)))
|
||||||
self.assertEqual(4, len(conform_pulse_params("gaussian", t0=5, power=6)))
|
self.assertEqual(4, len(conform_pulse_params("gaussian", t0=5, peak_power=6)))
|
||||||
self.assertEqual(4, len(conform_pulse_params("gaussian", width=5, power=6)))
|
self.assertEqual(4, len(conform_pulse_params("gaussian", width=5, peak_power=6)))
|
||||||
|
|
||||||
with self.assertRaisesRegex(
|
with self.assertRaisesRegex(
|
||||||
TypeError, "when soliton number is desired, both gamma and beta2 must be specified"
|
TypeError, "when soliton number is desired, both gamma and beta2 must be specified"
|
||||||
@@ -30,10 +30,10 @@ class TestPulseMethods(unittest.TestCase):
|
|||||||
5, len(conform_pulse_params("gaussian", width=5, energy=6, gamma=0.01, beta2=2e-6))
|
5, len(conform_pulse_params("gaussian", width=5, energy=6, gamma=0.01, beta2=2e-6))
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
5, len(conform_pulse_params("gaussian", t0=5, power=6, gamma=0.01, beta2=2e-6))
|
5, len(conform_pulse_params("gaussian", t0=5, peak_power=6, gamma=0.01, beta2=2e-6))
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
5, len(conform_pulse_params("gaussian", width=5, power=6, gamma=0.01, beta2=2e-6))
|
5, len(conform_pulse_params("gaussian", width=5, peak_power=6, gamma=0.01, beta2=2e-6))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class TestUtilsMethods(unittest.TestCase):
|
|||||||
old = conf("initial_config")
|
old = conf("initial_config")
|
||||||
new = conf("fiber2")
|
new = conf("fiber2")
|
||||||
|
|
||||||
over = utils.override_config(old, new)
|
over = utils.override_config(new, old)
|
||||||
self.assertIn("input_transmission", over["fiber"]["variable"])
|
self.assertIn("input_transmission", over["fiber"]["variable"])
|
||||||
self.assertNotIn("input_transmission", over["fiber"])
|
self.assertNotIn("input_transmission", over["fiber"])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user