diff --git a/indica/bayesblackbox.py b/indica/bayesblackbox.py new file mode 100644 index 00000000..afe886da --- /dev/null +++ b/indica/bayesblackbox.py @@ -0,0 +1,147 @@ +from copy import deepcopy +import warnings + +from flatdict import FlatDict +import numpy as np +from scipy.stats import uniform + +np.seterr(all="ignore") +warnings.simplefilter("ignore", category=FutureWarning) + + +def gaussian(x, mean, sigma): + return 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-1 / 2 * ((x - mean) / sigma) ** 2) + + +def get_uniform(lower, upper): + # Less confusing parameterisation of scipy.stats uniform + return uniform(loc=lower, scale=upper - lower) + + +def ln_prior(priors: dict, parameters: dict): + ln_prior = 0 + for prior_name, prior_func in priors.items(): + param_names_in_prior = [x for x in parameters.keys() if x in prior_name] + if param_names_in_prior.__len__() == 0: + # if prior assigned but no parameter then skip + continue + param_values = [parameters[x] for x in param_names_in_prior] + if hasattr(prior_func, "pdf"): + # for scipy.stats objects use pdf / for lambda functions just call + ln_prior += np.log(prior_func.pdf(*param_values)) + else: + # if lambda prior with 2+ args is defined when only 1 of + # its parameters is given ignore it + if prior_func.__code__.co_argcount != param_values.__len__(): + continue + else: + # Sorting to make sure args are given in the same order + # as the prior_name string + name_index = [ + prior_name.find(param_name_in_prior) + for param_name_in_prior in param_names_in_prior + ] + sorted_name_index, sorted_param_values = ( + list(x) for x in zip(*sorted(zip(name_index, param_values))) + ) + ln_prior += np.log(prior_func(*sorted_param_values)) + return ln_prior + + +class BayesBlackBox: + """ + Bayesian black box model that creates _ln_posterior function + from plasma and diagnostic model objects + + Parameters + ---------- + data + processed diagnostic data of format [diagnostic].[quantity] + plasma_context + plasma context has methods for using plasma object + model_handler + model_handler object to be called by ln_posterior + quant_to_optimise + quantity from data which will be optimised with bckc from diagnostic_models + priors + prior functions to apply to parameters e.g. scipy.stats.rv_continuous objects + + """ + + def __init__( + self, + data: dict, + quant_to_optimise: list, + priors: dict, + plasma_context=None, + model_context=None, + percent_error: float = 0.10, + ): + self.data = data + self.quant_to_optimise = quant_to_optimise + self.priors = priors + + self.plasma_context = plasma_context + self.model_context = model_context + + self.percent_error = percent_error + + missing_data = list(set(quant_to_optimise).difference(data.keys())) + if missing_data: # gives list of keys in quant_to_optimise but not data + raise ValueError(f"{missing_data} not found in data given") + + def ln_likelihood(self): + ln_likelihood = 0 + for key in self.quant_to_optimise: + time_coord = self.plasma_context.plasma.time_to_calculate + model_data = self.bckc[key] + exp_data = self.data[key].sel(t=time_coord) + exp_error = exp_data * self.percent_error + + if hasattr(self.data[key], "error"): + if (self.data[key].error != 0).any(): + # TODO: Some models have an error of 0 given + exp_error = self.data[key].error.sel(t=time_coord) + + _ln_likelihood = np.log(gaussian(model_data, exp_data, exp_error)) + # treat channel as key dim which isn't averaged like other dims + if "channel" in _ln_likelihood.dims: + _ln_likelihood = _ln_likelihood.sum(dim="channel", skipna=True) + ln_likelihood += _ln_likelihood.mean(skipna=True).values + return ln_likelihood + + def ln_posterior(self, parameters: dict, **kwargs): + """ + Posterior probability given to optimisers + + Parameters + ---------- + parameters + inputs to optimise + kwargs + kwargs for models + + Returns + ------- + ln_posterior + log of posterior probability + blob + model outputs from bckc and kinetic profiles + """ + + _ln_prior = ln_prior(self.priors, parameters) + if _ln_prior == -np.inf: # Don't call models if outside priors + return -np.inf, {} + + self.plasma_context.update_profiles(parameters) + plasma_attributes = self.plasma_context.return_plasma_attrs() + + self.bckc = FlatDict( + self.model_context._build_bckc(parameters, **kwargs), "." + ) # model calls + + _ln_likelihood = self.ln_likelihood() # compare results to data + ln_posterior = _ln_likelihood + _ln_prior + + blob = deepcopy({**self.bckc, **plasma_attributes}) + return ln_posterior, blob diff --git a/indica/bayesmodels.py b/indica/bayesmodels.py deleted file mode 100644 index a05e8c77..00000000 --- a/indica/bayesmodels.py +++ /dev/null @@ -1,262 +0,0 @@ -from copy import deepcopy -import warnings - -import numpy as np -from scipy.stats import uniform - -np.seterr(all="ignore") -warnings.simplefilter("ignore", category=FutureWarning) - - -PROFILES = [ - "electron_temperature", - "electron_density", - "ion_temperature", - "ion_density", - "impurity_density", - "fast_density", - "neutral_density", - "zeff", -] - - -def gaussian(x, mean, sigma): - return 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-1 / 2 * ((x - mean) / sigma) ** 2) - - -def get_uniform(lower, upper): - # Less confusing parameterisation of scipy.stats uniform - return uniform(loc=lower, scale=upper - lower) - - -class BayesModels: - """ - Object that is used with Plasma object to create ln_posterior - - Parameters - ---------- - plasma - Plasma object needed for the diagnostic model calls - data - processed diagnostic data of format [diagnostic].[quantity] - quant_to_optimise - quantity from data which will be optimised with bckc from diagnostic_models - priors - prior functions to apply to parameters e.g. scipy.stats.rv_continuous objects - diagnostic_models - model objects to be called by ln_posterior - """ - - def __init__( - self, - plasma=None, - data: dict = {}, - quant_to_optimise: list = [], - priors: dict = {}, - diagnostic_models: list = [], - percent_error: float = 0.10, - ): - self.plasma = plasma - self.data = data - self.quant_to_optimise = quant_to_optimise - self.diagnostic_models = diagnostic_models - self.priors = priors - self.percent_error = percent_error - - for diag_model in self.diagnostic_models: - diag_model.plasma = self.plasma - - missing_data = list(set(quant_to_optimise).difference(data.keys())) - if missing_data: # gives list of keys in quant_to_optimise but not data - raise ValueError(f"{missing_data} not found in data given") - - def _build_bckc(self, params, **kwargs): - """ - Parameters - ---------- - params - dictionary which is updated by optimiser - kwargs - passed to model i.e. settings - - Returns - ------- - bckc of results - """ - self.bckc: dict = {} - for model in self.diagnostic_models: - # removes "model.name." from params and kwargs then passes them to model - # e.g. xrcs.background -> background - _nuisance_params = { - param_name.replace(model.name + ".", ""): param_value - for param_name, param_value in params.items() - if model.name in param_name - } - _model_settings = { - kwarg_name.replace(model.name + ".", ""): kwarg_value - for kwarg_name, kwarg_value in kwargs.items() - if model.name in kwarg_name - } - - _model_kwargs = { - **_nuisance_params, - **_model_settings, - } # combine dictionaries - _bckc = model(**_model_kwargs) - _model_bckc = { - f"{model.name}.{value_name}": value - for value_name, value in _bckc.items() - } # prepend model name to bckc - self.bckc = dict(self.bckc, **_model_bckc) - return - - def _ln_likelihood(self): - ln_likelihood = 0 - for key in self.quant_to_optimise: - # Float128 since rounding of small numbers causes problems - # when initial results are bad fits - model_data = self.bckc[key].astype("float128") - exp_data = ( - self.data[key].sel(t=self.plasma.time_to_calculate).astype("float128") - ) - exp_error = ( - exp_data * self.percent_error - ) # Assume percentage error if none given. - if hasattr(self.data[key], "error"): - if ( - self.data[key].error != 0 - ).any(): # TODO: Some models have an error of 0 given - exp_error = self.data[key].error.sel( - t=self.plasma.time_to_calculate - ) - - _ln_likelihood = np.log(gaussian(model_data, exp_data, exp_error)) - # treat channel as key dim which isn't averaged like other dims - if "channel" in _ln_likelihood.dims: - _ln_likelihood = _ln_likelihood.sum(dim="channel", skipna=True) - ln_likelihood += _ln_likelihood.mean(skipna=True).values - return ln_likelihood - - def _ln_prior(self, parameters: dict): - ln_prior = 0 - for prior_name, prior_func in self.priors.items(): - param_names_in_prior = [x for x in parameters.keys() if x in prior_name] - if param_names_in_prior.__len__() == 0: - # if prior assigned but no parameter then skip - continue - param_values = [parameters[x] for x in param_names_in_prior] - if hasattr(prior_func, "pdf"): - # for scipy.stats objects use pdf / for lambda functions just call - ln_prior += np.log(prior_func.pdf(*param_values)) - else: - # if lambda prior with 2+ args is defined when only 1 of - # its parameters is given ignore it - if prior_func.__code__.co_argcount != param_values.__len__(): - continue - else: - # Sorting to make sure args are given in the same order - # as the prior_name string - name_index = [ - prior_name.find(param_name_in_prior) - for param_name_in_prior in param_names_in_prior - ] - sorted_name_index, sorted_param_values = ( - list(x) for x in zip(*sorted(zip(name_index, param_values))) - ) - ln_prior += np.log(prior_func(*sorted_param_values)) - return ln_prior - - def sample_from_priors(self, param_names, size=10): - # Use priors to generate samples - for name in param_names: - if name in self.priors.keys(): - if hasattr(self.priors[name], "rvs"): - continue - else: - raise TypeError(f"prior object {name} missing rvs method") - else: - raise ValueError(f"Missing prior for {name}") - - # Throw out samples that don't meet conditional priors and redraw - samples = np.empty((param_names.__len__(), 0)) - while samples.size < param_names.__len__() * size: - # Some mangling of dictionaries so _ln_prior works - # Increase size * n if too slow / looping too much - new_sample = { - name: self.priors[name].rvs(size=size * 2) for name in param_names - } - ln_prior = self._ln_prior(new_sample) - # Convert from dictionary of arrays -> array, - # then filtering out where ln_prior is -infinity - accepted_samples = np.array(list(new_sample.values()))[ - :, ln_prior != -np.inf - ] - samples = np.append(samples, accepted_samples, axis=1) - samples = samples[:, 0:size] - return samples.transpose() - - def sample_from_high_density_region( - self, param_names: list, sampler, nwalkers: int, nsamples=100 - ): - start_points = self.sample_from_priors(param_names, size=nsamples) - - ln_prob, _ = sampler.compute_log_prob(start_points) - num_best_points = int(nsamples * 0.05) - index_best_start = np.argsort(ln_prob)[-num_best_points:] - best_start_points = start_points[index_best_start, :] - best_points_std = np.std(best_start_points, axis=0) - - # Passing samples through ln_prior and redrawing if they fail - samples = np.empty((param_names.__len__(), 0)) - while samples.size < param_names.__len__() * nwalkers: - sample = np.random.normal( - np.mean(best_start_points, axis=0), - best_points_std * 2, - size=(nwalkers * 5, len(param_names)), - ) - start = {name: sample[:, idx] for idx, name in enumerate(param_names)} - ln_prior = self._ln_prior(start) - # Convert from dictionary of arrays -> array, - # then filtering out where ln_prior is -infinity - accepted_samples = np.array(list(start.values()))[:, ln_prior != -np.inf] - samples = np.append(samples, accepted_samples, axis=1) - start_points = samples[:, 0:nwalkers].transpose() - return start_points - - def ln_posterior(self, parameters: dict, **kwargs): - """ - Posterior probability given to optimisers - - Parameters - ---------- - parameters - inputs to optimise - kwargs - kwargs for models - - Returns - ------- - ln_posterior - log of posterior probability - blob - model outputs from bckc and kinetic profiles - """ - - ln_prior = self._ln_prior(parameters) - if ln_prior == -np.inf: # Don't call models if outside priors - return -np.inf, {} - - self.plasma.update_profiles(parameters) - self._build_bckc(parameters, **kwargs) # model calls - ln_likelihood = self._ln_likelihood() # compare results to data - ln_posterior = ln_likelihood + ln_prior - - plasma_profiles = {} - for profile_key in PROFILES: - if hasattr(self.plasma, profile_key): - plasma_profiles[profile_key] = getattr(self.plasma, profile_key).sel( - t=self.plasma.time_to_calculate - ) - else: - raise ValueError(f"plasma does not have attribute {profile_key}") - - blob = deepcopy({**self.bckc, **plasma_profiles}) - return ln_posterior, blob diff --git a/indica/models/helike_spectroscopy.py b/indica/models/helike_spectroscopy.py index b35ba022..631bc3db 100644 --- a/indica/models/helike_spectroscopy.py +++ b/indica/models/helike_spectroscopy.py @@ -38,13 +38,14 @@ def __init__( name: str, instrument_method="get_helike_spectroscopy", etendue: float = 1.0, - calibration: float = 8.0e-20, + calibration: float = 1.0e-18, element: str = "ar", window_len: int = 1030, window_lim=None, window: np.array = None, window_masks=None, line_labels=None, + background=None, ): """ Read all atomic data and initialise objects @@ -73,6 +74,7 @@ def __init__( self.window_masks = window_masks self.line_ranges = LINE_RANGES self.line_labels = line_labels + self.background = background if window is None: window = np.linspace(window_lim[0], window_lim[1], window_len) @@ -206,8 +208,6 @@ def _make_spectra(self, calc_rho: bool = False): ), ) spectra = xr.concat([_spectra, empty], "wavelength") - spectra = spectra.sortby("wavelength") - self.spectra = spectra measured_spectra = self.los_transform.integrate_on_los( @@ -215,9 +215,11 @@ def _make_spectra(self, calc_rho: bool = False): t=self.spectra.t, calc_rho=calc_rho, ) - self.measured_spectra = measured_spectra.assign_coords( - {"wavelength": self.window.wavelength} + measured_spectra = measured_spectra.assign_coords( + {"wavelength": self.spectra.wavelength} ) + measured_spectra = xr.where(measured_spectra == 0, np.nan, measured_spectra) + self.measured_spectra = measured_spectra.sortby("wavelength") self.spectra_los = self.los_transform.along_los def _moment_analysis(self): @@ -390,6 +392,7 @@ def __call__( calc_rho: bool = False, moment_analysis: bool = False, background: int = None, + pixel_offset: int = None, **kwargs, ): """ @@ -420,22 +423,22 @@ def __call__( if hasattr(self, "plasma"): if t is None: t = self.plasma.time_to_calculate - Te = self.plasma.electron_temperature.interp( + Te = self.plasma.electron_temperature.sel( t=t, ) - Ne = self.plasma.electron_density.interp( + Ne = self.plasma.electron_density.sel( t=t, ) - Nh = self.plasma.neutral_density.interp( + Nh = self.plasma.neutral_density.sel( t=t, ) Fz = {} _Fz = self.plasma.fz for elem in _Fz.keys(): - Fz[elem] = _Fz[elem].interp(t=t) + Fz[elem] = _Fz[elem].sel(t=t) - Ti = self.plasma.ion_temperature.interp(t=t) - Nimp = self.plasma.impurity_density.interp(t=t) + Ti = self.plasma.ion_temperature.sel(t=t) + Nimp = self.plasma.impurity_density.sel(t=t) else: if ( Ne is None @@ -447,6 +450,10 @@ def __call__( ): raise ValueError("Give inputs or assign plasma class!") + if background is None: + if self.background is not None: + background = self.background.sel(t=t) + self.t = t self.Te = Te self.Ne = Ne @@ -466,6 +473,11 @@ def __call__( if background is not None: self.measured_spectra = self.measured_spectra + background + if pixel_offset is not None: + self.measured_spectra = self.measured_spectra.shift( + wavelength=round(pixel_offset), fill_value=np.nan + ) + self._build_bckc_dictionary() return self.bckc diff --git a/indica/models/plasma.py b/indica/models/plasma.py index a3c12cf9..1f14993d 100644 --- a/indica/models/plasma.py +++ b/indica/models/plasma.py @@ -278,6 +278,8 @@ def initialize_variables(self): self.Ti_prof = Profiles(datatype=("temperature", "ion"), xspl=self.rho) self.Ne_prof = Profiles(datatype=("density", "electron"), xspl=self.rho) self.Nimp_prof = Profiles(datatype=("density", "impurity"), xspl=self.rho) + self.Niz1_prof = Profiles(datatype=("density", "impurity"), xspl=self.rho) + self.Niz2_prof = Profiles(datatype=("density", "impurity"), xspl=self.rho) self.Nh_prof = Profiles(datatype=("density", "thermal_neutral"), xspl=self.rho) self.Vrot_prof = Profiles(datatype=("rotation", "toroidal"), xspl=self.rho) @@ -418,6 +420,27 @@ def initialize_variables(self): ], ) + self.Pth = CachedCalculation( + self.calc_pth, + [ + self.electron_density, + self.ion_density, + self.electron_temperature, + self.ion_temperature, + ], + ) + + self.Ptot = CachedCalculation( + self.calc_ptot, + [ + self.electron_density, + self.ion_density, + self.electron_temperature, + self.ion_temperature, + self.pressure_fast, + ], + ) + self.Lz_tot = CachedCalculation( self.calc_lz_tot, [ @@ -496,16 +519,20 @@ def update_profiles( """ Update plasma profiles with profile parameters i.e. {"Ne_prof.y0":1e19} -> Ne_prof.y0 + TODO: refactor profiles into profiler structure + and take care of initialisation of impurity profiles """ - profile_prefixs: list = [ + profile_prefixes: list = [ "Te_prof", "Ti_prof", "Ne_prof", - "Nimp_prof", + "Niz1_prof", + "Niz2_prof", + "Nh_prof", "Vrot_prof", ] for param, value in parameters.items(): - _prefix = [pref for pref in profile_prefixs if pref in param] + _prefix = [pref for pref in profile_prefixes if pref in param] if _prefix: prefix: str = _prefix[0] key = param.replace(prefix + ".", "") @@ -515,14 +542,41 @@ def update_profiles( else: raise ValueError(f"parameter: {key} not found in {prefix}") - for key in [ - "electron_density", - "electron_temperature", - "ion_temperature", - "toroidal_rotation", - "impurity_density", - ]: - self.assign_profiles(key, t=self.time_to_calculate) + # Only update profiles which are given in parameters + parameter_prefixes = [key.split(".")[0] for key in parameters.keys()] + profile_names = set(parameter_prefixes) & set(profile_prefixes) + + if "Te_prof" in profile_names: + self.electron_temperature.loc[ + dict(t=self.time_to_calculate) + ] = self.Te_prof() + if "Ti_prof" in profile_names: + self.ion_temperature.loc[dict(t=self.time_to_calculate)] = self.Ti_prof() + if "Ne_prof" in profile_names: + self.electron_density.loc[dict(t=self.time_to_calculate)] = self.Ne_prof() + if "Nh_prof" in profile_names: + self.neutral_density.loc[dict(t=self.time_to_calculate)] = self.Nh_prof() + if "Vrot_prof" in profile_names: + self.electron_temperature.loc[ + dict(t=self.time_to_calculate) + ] = self.Ne_prof() + if "Niz1_prof" in profile_names: + self.impurity_density.loc[ + dict(t=self.time_to_calculate, element=self.impurities[0]) + ] = self.Niz1_prof() + else: + self.impurity_density.loc[ + dict(t=self.time_to_calculate, element=self.impurities[0]) + ] = (self.Ne_prof() * self.impurity_concentration[0]) + + if "Niz2_prof" in profile_names: + self.impurity_density.loc[ + dict(t=self.time_to_calculate, element=self.impurities[1]) + ] = self.Niz2_prof() + else: + self.impurity_density.loc[ + dict(t=self.time_to_calculate, element=self.impurities[1]) + ] = (self.Ne_prof() * self.impurity_concentration[1]) @property def time_to_calculate(self): @@ -544,13 +598,10 @@ def pressure_el(self): @property def pressure_th(self): - ion_density = self.ion_density - self._pressure_th.values = self.pressure_el - for elem in self.elements: - self._pressure_th.values += ph.calc_pressure( - ion_density.sel(element=elem).values, - self.ion_temperature.sel(element=elem).values, - ) + self._pressure_th = ( + ph.calc_pressure(self.ion_density, self.ion_temperature).sum("element") + + self.pressure_el + ) return self._pressure_th @property @@ -568,6 +619,9 @@ def pressure_fast(self): @property def pth(self): + return self.Pth() + + def calc_pth(self): pressure_th = self.pressure_th for t in np.array(self.time_to_calculate, ndmin=1): self._pth.loc[dict(t=t)] = np.trapz( @@ -577,6 +631,9 @@ def pth(self): @property def ptot(self): + return self.Ptot() + + def calc_ptot(self): pressure_tot = self.pressure_tot for t in np.array(self.time_to_calculate, ndmin=1): self._ptot.loc[dict(t=t)] = np.trapz( @@ -598,7 +655,8 @@ def wp(self): @property def fz(self): - return self.calc_fz() # self.Fz() + return self.Fz() + # return self.calc_fz() # self.Fz() def calc_fz(self): for elem in self.elements: @@ -621,37 +679,32 @@ def calc_fz(self): @property def zeff(self): - return self.calc_zeff() # Zeff() + return self.Zeff() + # return self.calc_zeff() def calc_zeff(self): - electron_density = self.electron_density - ion_density = self.ion_density - meanz = self.meanz - for elem in self.elements: - self._zeff.loc[dict(element=elem)] = ( - (ion_density.sel(element=elem) * meanz.sel(element=elem) ** 2) - / electron_density - ).values + self._zeff = self.ion_density * self.meanz**2 / self.electron_density return self._zeff @property def ion_density(self): - return self.calc_ion_density() # self.Ion_density() + return self.Ion_density() + # return self.calc_ion_density() def calc_ion_density(self): meanz = self.meanz - main_ion_density = self.electron_density - self.fast_density * meanz.sel( - element=self.main_ion - ) for elem in self.impurities: self._ion_density.loc[dict(element=elem)] = self.impurity_density.sel( element=elem ).values - main_ion_density -= self.impurity_density.sel(element=elem) * meanz.sel( - element=elem - ) - self._ion_density.loc[dict(element=self.main_ion)] = main_ion_density.values + main_ion_density = ( + self.electron_density + - self.fast_density * meanz.sel(element=self.main_ion) + - (self.impurity_density * meanz).sum("element") + ) + + self._ion_density.loc[dict(element=self.main_ion)] = main_ion_density return self._ion_density @property @@ -752,6 +805,7 @@ def calc_sxr_radiation(self): @property def meanz(self): fz = self.fz + for elem in self.elements: self._meanz.loc[dict(element=elem)] = ( (fz[elem] * fz[elem].ion_charges).sum("ion_charges").values @@ -1233,7 +1287,6 @@ def __init__(self, operator: Callable, dependencies: list, verbose: bool = False @lru_cache() def __call__(self): - print("Recalculating") if self.verbose: print("Recalculating") return self.operator() diff --git a/indica/models/thomson_scattering.py b/indica/models/thomson_scattering.py index 5396fe3e..9b40f885 100644 --- a/indica/models/thomson_scattering.py +++ b/indica/models/thomson_scattering.py @@ -41,6 +41,9 @@ def _build_bckc_dictionary(self): self.bckc[quantity] = self.Te_at_channels long_name = "Te" units = "eV" + elif quant == "chi2": + # Placeholder + continue else: print(f"{quant} not available in model for {self.instrument_method}") continue @@ -82,7 +85,7 @@ def __call__( """ if self.plasma is not None: if t is None: - t = self.plasma.t + t = self.plasma.time_to_calculate Ne = self.plasma.electron_density.interp(t=t) Te = self.plasma.electron_temperature.interp(t=t) else: @@ -112,6 +115,20 @@ def __call__( return self.bckc +def ts_transform_example(nchannels): + x_positions = np.linspace(0.2, 0.8, nchannels) + y_positions = np.linspace(0.0, 0.0, nchannels) + z_positions = np.linspace(0.0, 0.0, nchannels) + transform = TransectCoordinates( + x_positions, + y_positions, + z_positions, + "ts", + machine_dimensions=((0.15, 0.95), (-0.7, 0.7)), + ) + return transform + + def example_run( pulse: int = None, diagnostic_name: str = "ts", @@ -124,19 +141,7 @@ def example_run( if plasma is None: plasma = example_plasma(pulse=pulse) - # Create new interferometers diagnostics - nchannels = 11 - x_positions = np.linspace(0.2, 0.8, nchannels) - y_positions = np.linspace(0.0, 0.0, nchannels) - z_positions = np.linspace(0.0, 0.0, nchannels) - - transect_transform = TransectCoordinates( - x_positions, - y_positions, - z_positions, - diagnostic_name, - machine_dimensions=plasma.machine_dimensions, - ) + transect_transform = ts_transform_example(11) transect_transform.set_equilibrium(plasma.equilibrium) model = ThomsonScattering( diagnostic_name, diff --git a/indica/operators/gpr_fit.py b/indica/operators/gpr_fit.py index 1cde899b..71d60e4e 100644 --- a/indica/operators/gpr_fit.py +++ b/indica/operators/gpr_fit.py @@ -1,3 +1,5 @@ +from pathlib import Path + import matplotlib.pyplot as plt import numpy as np from sklearn.gaussian_process import GaussianProcessRegressor @@ -7,7 +9,6 @@ from indica.readers.read_st40 import ReadST40 from indica.utilities import FIG_PATH -from indica.utilities import save_figure from indica.utilities import set_axis_sci from indica.utilities import set_plot_colors from indica.utilities import set_plot_rcparams @@ -15,66 +16,12 @@ CMAP, COLORS = set_plot_colors() -def choose_kernel(kernel: str): - """ - Wrapper to return GPR Kernel function selected by name - - Parameters - ---------- - kernel - Name of kernel - - Returns - ------- - Kernel function for GPR call - - """ - kernels = { - "RBF_noise": RadialBasisFunction_NoNoise(), - "RBF": RadialBasisFunction_WithNoise(), - } - - if kernel in kernels.keys(): - return kernels[kernel] - else: - raise ValueError - - -def RadialBasisFunction_NoNoise(length_scale=0.1, dlength_scale=0.001, **kwargs): - kernel = 1.0 * kernels.RBF( - length_scale=length_scale, - length_scale_bounds=( - length_scale - dlength_scale, - length_scale + dlength_scale, - ), - ) - return kernel - - -def RadialBasisFunction_WithNoise( - length_scale=0.1, dlength_scale=0.001, noise_level=1000, dnoise_level=3000, **kwargs -): - kernel = 1.0 * kernels.RBF( - length_scale=length_scale, - length_scale_bounds=( - length_scale - dlength_scale, - length_scale + dlength_scale, - ), - ) + kernels.WhiteKernel( - noise_level=noise_level, - noise_level_bounds=(noise_level - dnoise_level, noise_level + dnoise_level), - ) - return kernel - - def gpr_fit( x: np.array, y: np.array, y_err: np.array, x_fit: np.array, - kernel_name: str = "RBF_noise", - y_bounds: tuple = (1, 1), - err_bounds: tuple = (0, 0), + kernel: kernels.Kernel, ): """ Run GPR fit given input data and desired x-grid @@ -90,11 +37,7 @@ def gpr_fit( x_fit x-axis for fitting kernel - Kernel name - y_bounds - Boundery value at the edge of the x-grid - err_bounds - Boundery error at the edge of the x-grid + Kernel used Returns ------- @@ -102,17 +45,10 @@ def gpr_fit( """ - kernel = choose_kernel(kernel_name) - isort = np.argsort(x) - _x = np.sort(np.append(x, [x_fit[0], x_fit[-1]])) + _x = np.sort(x) _y = np.interp(_x, x[isort], y[isort]) - - _y[0] = y_bounds[0] - _y[-1] = y_bounds[1] _y_err = np.interp(_x, x[isort], y_err[isort]) - _y_err[0] = err_bounds[0] - _y_err[-1] = err_bounds[1] idx = np.isfinite(_y) @@ -120,206 +56,235 @@ def gpr_fit( _y_err = _y_err[idx] _y = _y[idx].reshape(-1, 1) - gpr = GaussianProcessRegressor(kernel=kernel, alpha=_y_err**2) # alpha is sigma^2 - gpr.fit(_x, _y) + gpr = GaussianProcessRegressor( + kernel=kernel, + alpha=_y_err**2, + ) # alpha is sigma^2 + gpr.fit( + _x, + _y, + ) _x_fit = x_fit.reshape(-1, 1) y_fit, y_fit_err = gpr.predict(_x_fit, return_std=True) - return y_fit, y_fit_err - - -def run_gpr_fit( - data: DataArray, - xdim: str = "R", - kernel_name: str = "RBF_noise", - x_bounds: tuple = (0, 1), - y_bounds: tuple = (1, 1), - err_bounds: tuple = (0, 0), -): - """ - Run GPR fit for experimental Indica-native DataArray structures - - Parameters - ---------- - data - Data to be fitted dims = (x, t) - xdim - Dimension on which fit is to be performed - kernel_name - Name of kernel to be used for fitting - - Returns - ------- - - """ - - x_fit = np.linspace(x_bounds[0], x_bounds[1], 1000) - - y_fit = [] - y_fit_err = [] - for t in data.t: - x = data.R.values - y = data.sel(t=t).values - y_err = data.error.sel(t=t).values - _y_fit, _y_fit_err = gpr_fit( - x, - y, - y_err, - x_fit, - kernel_name=kernel_name, - y_bounds=y_bounds, - err_bounds=err_bounds, - ) - - y_fit.append(DataArray(_y_fit, coords=[(xdim, x_fit)])) - y_fit_err.append(DataArray(_y_fit_err, coords=[(xdim, x_fit)])) - - fit = xr.concat(y_fit, "t").assign_coords(t=data.t) - fit_err = xr.concat(y_fit_err, "t").assign_coords(t=data.t) - - return fit, fit_err + return y_fit, y_fit_err, gpr def plot_gpr_fit( data: DataArray, - fit: DataArray, - fit_err: DataArray, - tplot: float, - x_data: DataArray = None, - x_fit: DataArray = None, + y_fit: DataArray, + y_fit_err: DataArray, fig_style: str = "profiles", ylabel: str = "", xlabel: str = "", label: str = "", title: str = "", fig_name: str = "", - figure: bool = True, save_fig: bool = False, color=None, ): set_plot_rcparams(fig_style) - if figure: - plt.figure() - - if x_data is None: - xdim = [dim for dim in data.dims if dim != "t"][0] - x_data = getattr(data, xdim) - - if x_fit is None: - xdim = [dim for dim in fit.dims if dim != "t"][0] - x_fit = getattr(fit, xdim) - - if "t" in x_data.dims: - _x_data = x_data.sel(t=tplot) - else: - _x_data = x_data - - if "t" in x_fit.dims: - _x_fit = x_fit.sel(t=tplot) - else: - _x_fit = x_fit - - y_data = data.sel(t=tplot) - y_err = data.error.sel(t=tplot) + plt.figure() - y_fit = fit.sel(t=tplot) - y_fit_err = fit_err.sel(t=tplot) + x_data = getattr(data, data.dims[0]) + x_fit = getattr(y_fit, data.dims[0]) + y_err = data.error plt.fill_between( - _x_fit, + x_fit, y_fit - y_fit_err, y_fit + y_fit_err, alpha=0.5, color=color, ) - plt.plot(_x_fit, y_fit, color=color) - plt.errorbar(_x_data, y_data, y_err, linestyle="", color=color) - plt.plot(_x_data, y_data, marker="o", linestyle="", color=color, label=label) + plt.plot(x_fit, y_fit, color=color) + plt.errorbar(x_data, data, y_err, linestyle="", color=color) + plt.plot(x_data, data, marker="o", linestyle="", color=color, label=label) plt.xlabel(xlabel) plt.ylabel(ylabel) - plt.title(f"{title} t = {tplot:.3f} s") + plt.title(title) set_axis_sci() if len(label) > 0: plt.legend() if save_fig: - save_figure(FIG_PATH, f"{fig_name}_GPR_fit_{tplot:.3f}_s", save_fig=save_fig) + plt.savefig( + FIG_PATH + f"{fig_name}_GPR_t:{data.t.values:.3f}.png", bbox_inches="tight" + ) + + +def post_process_ts(binned_data, equilibrium, quant, pulse, split=""): + rmag = binned_data["efit"]["rmag"] + data = binned_data["ts"][quant] + data["pulse"] = pulse + data["quantity"] = quant + + data.transform.set_equilibrium(equilibrium) + data.transform.convert_to_rho_theta(t=data.t) + data["rho"] = data.transform.rho + + # Normalising + if quant == "ne": + data.values = data.values * 1e-19 + data["error"] = data.error * 1e-19 + data["unit"] = "n19" + elif quant == "te": + data.values = data.values * 1e-3 + data["error"] = data.error * 1e-3 + data["unit"] = "keV" + else: + raise ValueError(f"Unknown data quantity: {quant}") + + rmag = rmag[0] + if split == "HFS": + data = data.where(data.R < rmag) + elif split == "LFS": + data = data.where(data.R > rmag) + else: + data = data + return data -def example_run( - pulse: int = 10619, - tstart=0.02, - tend=0.1, - kernel_name: str = "RBF_noise", - plot=True, + +def gpr_fit_ts( + data: xr.DataArray, + kernel: kernels.Kernel, + xdim: str = "rho", + virtual_obs=True, + virtual_symmetry=True, + x_bounds=None, + virtual_points=None, + plot=False, save_fig=False, - xdim: str = "R", - x_bounds: tuple = (0, 1), - y_bounds: tuple = (1, 1), - err_bounds: tuple = (0, 0), ): + if x_bounds is None: + if xdim == "rho": + x_bounds = (0, 1.3) + elif xdim == "R": + x_bounds = (0.1, 0.9) + + if virtual_points is None: + if xdim == "rho": + virtual_points = [ + (1.5, lambda y: 0), + ] + elif xdim == "R": + virtual_points = [(0, lambda y: 0), (0.9, lambda y: 0)] - st40 = ReadST40(pulse, tstart, tend) - st40(instruments=["ts", "efit"]) + x_fit = np.linspace(x_bounds[0], x_bounds[1], 1000) + y_fit = [] + y_fit_err = [] + gpr = [] - data = st40.raw_data["ts"]["te"] - if xdim not in data.dims and hasattr(data, xdim): - data = data.swap_dims({"channel": xdim}) - if xdim == "R": - x_bounds = data.transform._machine_dims[0] - if hasattr(data, "equilibrium"): - data.transform.convert_to_rho_theta(t=data.t) - - fit, fit_err = run_gpr_fit( - data, - kernel_name=kernel_name, - x_bounds=x_bounds, - y_bounds=y_bounds, - err_bounds=err_bounds, - xdim=xdim, - ) + for t in data.t: + if "t" in data.__getattr__(xdim).dims: + x = data.__getattr__(xdim).sel(t=t).values + else: + x = data.__getattr__(xdim).values + y = data.sel(t=t).values + y_err = data.error.sel(t=t).values + + if virtual_obs: + num_vo = len(virtual_points) + x = np.insert( + x, + [i for i in range(num_vo)], + [virtual_point[0] for virtual_point in virtual_points], + ) + y = np.insert( + y, + [i for i in range(num_vo)], + [virtual_point[1](y) for virtual_point in virtual_points], + ) + y_err = np.insert( + y_err, [i for i in range(num_vo)], [0.01 for i in range(num_vo)] + ) + + if virtual_symmetry: + x = np.concatenate((x, -x)) + y = np.concatenate((y, y)) + y_err = np.concatenate((y_err, y_err)) + + _y_fit, _y_fit_err, _gpr = gpr_fit( + x, + y, + y_err, + x_fit, + kernel, + ) + y_fit.append(DataArray(_y_fit, coords=[(xdim, x_fit)])) + y_fit_err.append(DataArray(_y_fit_err, coords=[(xdim, x_fit)])) + gpr.append(_gpr) + + fit = xr.concat(y_fit, "t").assign_coords(t=data.t) + fit_err = xr.concat(y_fit_err, "t").assign_coords(t=data.t) if plot or save_fig: - plt.ioff() - fig_name = f"{pulse}_TS_Te" - for tplot in data.t.values: + Path(FIG_PATH).mkdir(parents=True, exist_ok=True) + for idx, tplot in enumerate(data.t.values): plot_gpr_fit( - data, - fit, - fit_err, - tplot, - ylabel="Te [eV]", - xlabel="R [m]", - title=str(st40.pulse), - fig_name=f"{fig_name}_vs_R", + data.sel(t=tplot).swap_dims({"channel": xdim}), + fit.sel(t=tplot), + fit_err.sel(t=tplot), + ylabel=f"{data.quantity.values} ({data.unit.values})", + xlabel=f"{xdim}", + title=f"{data.pulse.values}\nOptimimum: {gpr[idx].kernel_}", + fig_name=f"{data.pulse.values}_TS.{data.quantity.values}", save_fig=save_fig, ) - if hasattr(data, "equilibrium"): - x_data = data.transform.rho.assign_coords( - R=("channel", data.R) - ).swap_dims({"channel": "R"}) - x_fit = x_data.interp(R=fit.R) - plot_gpr_fit( - data, - fit, - fit_err, - tplot, - x_data=x_data, - x_fit=x_fit, - ylabel="Te [eV]", - xlabel="rho-poloidal", - title=str(st40.pulse), - fig_name=f"{fig_name}_vs_rho", - save_fig=save_fig, - ) if not save_fig: plt.show() - return data, fit, fit_err + plt.close("all") + return fit, fit_err if __name__ == "__main__": - example_run() + pulse = 11089 + tstart = 0.03 + tend = 0.12 + dt = 0.01 + st40 = ReadST40(pulse, tstart, tend, dt) + st40(instruments=["ts", "efit"]) + + ne_data = post_process_ts( + st40.binned_data, + st40.equilibrium, + "ne", + pulse, + split="LFS", + ) + ne_kernel = 1.0 * kernels.RationalQuadratic( + alpha_bounds=(0.1, 1.0), length_scale_bounds=(0.4, 0.7) + ) + kernels.WhiteKernel(noise_level_bounds=(0.01, 10)) + + te_data = post_process_ts( + st40.binned_data, + st40.equilibrium, + "te", + pulse, + split="LFS", + ) + te_kernel = 1.0 * kernels.RationalQuadratic( + alpha_bounds=(0.1, 1.0), length_scale_bounds=(0.4, 0.7) + ) + kernels.WhiteKernel(noise_level_bounds=(0.01, 10)) + + gpr_fit_ts( + data=ne_data, + xdim="rho", + virtual_obs=True, + virtual_symmetry=True, + kernel=ne_kernel, + save_fig=True, + ) + gpr_fit_ts( + data=te_data, + xdim="rho", + virtual_obs=True, + virtual_symmetry=True, + kernel=te_kernel, + save_fig=True, + ) diff --git a/indica/profiles_gauss.py b/indica/profiles_gauss.py index e266a4ed..88cf6f11 100644 --- a/indica/profiles_gauss.py +++ b/indica/profiles_gauss.py @@ -55,6 +55,16 @@ def __init__( if parameters is None: parameters = get_defaults(datatype) + elif { + "y0", + "y1", + "yend", + "wcenter", + "wped", + "peaking", + } >= set(parameters): + _parameters = get_defaults(datatype) + parameters = dict(_parameters, **parameters) for k, p in parameters.items(): setattr(self, k, p) @@ -210,7 +220,7 @@ def get_defaults(datatype: tuple) -> dict: }, "impurity_density": { # (m**-3) "y0": 5.0e16, - "y1": 1.0e16, + "y1": 1.0e15, "yend": 1.0e15, "peaking": 2, "wcenter": 0.4, diff --git a/indica/readers/read_st40.py b/indica/readers/read_st40.py index dc7fa705..afb0fee1 100644 --- a/indica/readers/read_st40.py +++ b/indica/readers/read_st40.py @@ -96,17 +96,14 @@ def __init__( if _tstart < 0: _tstart = 0.0 self.reader = ST40Reader(pulse, _tstart, _tend, tree=tree) - self.reader_equil = ST40Reader(pulse, _tstart, _tend, tree=tree) self.equilibrium: Equilibrium self.raw_data: dict = {} - self.raw_data_trange: dict = {} self.binned_data: dict = {} self.transforms: dict = {} def reset_data(self): self.raw_data = {} - self.raw_data_trange = {} self.binned_data = {} def get_equilibrium( @@ -117,35 +114,29 @@ def get_equilibrium( z_shift: float = 0.0, ): - equilibrium_data = self.reader_equil.get("", instrument, revision) + equilibrium_data = self.reader.get("", instrument, revision) equilibrium = Equilibrium(equilibrium_data, R_shift=R_shift, z_shift=z_shift) self.equilibrium = equilibrium - def get_raw_data(self, uid: str, instrument: str, revision: RevisionLike = 0): + def get_raw_data( + self, + uid: str, + instrument: str, + revision: RevisionLike = 0, + set_equilibrium: bool = False, + ): data = self.reader.get(uid, instrument, revision) - if hasattr(self, "equilibrium"): - for quant in data.keys(): - if "transform" not in data[quant].attrs: - continue + for quant in data.keys(): + if "transform" not in data[quant].attrs: + continue + + transform = data[quant].transform + if hasattr(transform, "set_equilibrium") and set_equilibrium: + transform.set_equilibrium(self.equilibrium) + self.transforms[instrument] = transform - transform = data[quant].transform - if hasattr(transform, "set_equilibrium"): - transform.set_equilibrium(self.equilibrium) - self.transforms[instrument] = transform self.raw_data[instrument] = data - self.raw_data_trange[instrument] = {} - for quant in data.keys(): - if "t" in data[quant].dims: - self.raw_data_trange[instrument][quant] = data[quant].sel( - t=slice(self.tstart, self.tend) - ) - if "error" in data[quant].attrs: - self.raw_data_trange[instrument][quant].attrs["error"] = data[ - quant - ].error.sel(t=slice(self.tstart, self.tend)) - else: - self.raw_data_trange[instrument][quant] = data[quant] return data def bin_data_in_time( @@ -320,6 +311,7 @@ def __call__( self, instruments: list = [], revisions: dict = None, + filters: dict = None, map_raw: bool = False, tstart: float = None, tend: float = None, @@ -329,9 +321,9 @@ def __call__( map_diagnostics: bool = False, raw_only: bool = False, debug: bool = False, + set_equilibrium: bool = False, ): self.debug = debug - if len(instruments) == 0: instruments = INSTRUMENTS if revisions is None: @@ -341,7 +333,9 @@ def __call__( revisions[instr] = 0 if "efit" not in revisions: revisions["efit"] = 0 - + if not filters: + # TODO: fix default behaviour if missing key + filters = FILTER_LIMITS if tstart is None: tstart = self.tstart if tend is None: @@ -354,7 +348,12 @@ def __call__( for instrument in instruments: print(f"Reading {instrument}") try: - self.get_raw_data("", instrument, revisions[instrument]) + self.get_raw_data( + "", + instrument, + revisions[instrument], + set_equilibrium=set_equilibrium, + ) except Exception as e: print(f"Error reading {instrument}: {e}") if debug: diff --git a/indica/workflows/_zeff_profile.py b/indica/workflows/_zeff_profile.py index adf29bda..07474376 100644 --- a/indica/workflows/_zeff_profile.py +++ b/indica/workflows/_zeff_profile.py @@ -1,26 +1,22 @@ from copy import deepcopy -import emcee import matplotlib.pylab as plt import numpy as np -import pandas as pd from scipy.interpolate import CubicSpline +from sklearn.gaussian_process import kernels import xarray as xr from xarray import DataArray -from indica.bayesmodels import BayesModels -from indica.bayesmodels import get_uniform +from indica.bayesblackbox import get_uniform from indica.equilibrium import Equilibrium from indica.models.diode_filters import example_run as example_diode from indica.models.plasma import example_run as example_plasma from indica.models.plasma import Plasma from indica.operators import tomo_1D -from indica.operators.gpr_fit import run_gpr_fit +from indica.operators.gpr_fit import gpr_fit_ts import indica.physics as ph from indica.readers.read_st40 import ReadST40 from indica.utilities import set_plot_colors -from indica.workflows.bayes_workflow import plot_bayes_result -from indica.workflows.bayes_workflow import sample_with_autocorr PATHNAME = "./plots/" @@ -122,7 +118,7 @@ def prepare_data_ts( data = deepcopy(st40.binned_data["ts"][quantity]) * const data.attrs["error"] = deepcopy(st40.binned_data["ts"][quantity].error) * const - y_bounds = (1, 1) + # y_bounds = (1, 1) if xdim == "R": x_bounds = plasma.machine_dimensions[0] else: @@ -131,13 +127,11 @@ def prepare_data_ts( if xdim not in data.dims and hasattr(data, xdim): data = data.swap_dims({"channel": xdim}) - fit, fit_err = run_gpr_fit( - data, - x_bounds=x_bounds, - y_bounds=y_bounds, - err_bounds=err_bounds, - xdim=xdim, - ) + kernel = 1.0 * kernels.RationalQuadratic( + alpha_bounds=(0.1, 1.0), length_scale_bounds=(0.4, 0.7) + ) + kernels.WhiteKernel(noise_level_bounds=(0.01, 10)) + + fit, fit_err = gpr_fit_ts(data, x_bounds=x_bounds, xdim=xdim, kernel=kernel) fit /= const fit_err /= const @@ -335,88 +329,88 @@ def prepare_inputs( return plasma, models, flat_data, input_profiles -def run_bayes( - pulse: int, - time: float, - phantom_profile_params, - iterations, - result_path, - tstart=0.03, - tend=0.1, - dt=0.01, - burn_in=0, - nwalkers=10, - phantom_data: bool = True, - ts_side: str = "LFS", -): - plasma, models, flat_data, input_profiles = prepare_inputs( - pulse, - tstart=tstart, - tend=tend, - dt=dt, - time=time, - phantom_profile_params=phantom_profile_params, - phantom_data=phantom_data, - ts_side=ts_side, - ) - - print("Instatiating Bayes model") - diagnostic_models = [models["pi"]] - quant_to_optimise = [ - "pi.brightness", - ] - bm = BayesModels( - plasma=plasma, - data=flat_data, - diagnostic_models=diagnostic_models, - quant_to_optimise=quant_to_optimise, - priors=PRIORS, - ) - ndim = PARAM_NAMES.__len__() - start_points = bm.sample_from_priors(PARAM_NAMES, size=nwalkers) - move = [(emcee.moves.StretchMove(), 1.0), (emcee.moves.DEMove(), 0.0)] - sampler = emcee.EnsembleSampler( - nwalkers, - ndim, - log_prob_fn=bm.ln_posterior, - parameter_names=PARAM_NAMES, - moves=move, - ) - - print("Sampling") - autocorr = sample_with_autocorr( - sampler, start_points, iterations=iterations, auto_sample=5 - ) - - blobs = sampler.get_blobs(discard=burn_in, flat=True) - blob_names = sampler.get_blobs().flatten()[0].keys() - blob_dict = { - blob_name: xr.concat( - [data[blob_name] for data in blobs], - dim=pd.Index(np.arange(0, blobs.__len__()), name="index"), - ) - for blob_name in blob_names - } - - samples = sampler.get_chain(flat=True) - prior_samples = bm.sample_from_priors(PARAM_NAMES, size=int(1e5)) - result = { - "blobs": blob_dict, - "diag_data": flat_data, - "samples": samples, - "prior_samples": prior_samples, - "param_names": PARAM_NAMES, - "phantom_profiles": input_profiles, - "plasma": plasma, - "autocorr": autocorr, - } - print(sampler.acceptance_fraction.sum()) - plot_bayes_result(**result, figheader=result_path) - - if not phantom_data: - plot_ts(plasma, flat_data, ts_side=ts_side) - - return result +# def run_bayes( +# pulse: int, +# time: float, +# phantom_profile_params, +# iterations, +# result_path, +# tstart=0.03, +# tend=0.1, +# dt=0.01, +# burn_in=0, +# nwalkers=10, +# phantom_data: bool = True, +# ts_side: str = "LFS", +# ): +# plasma, models, flat_data, input_profiles = prepare_inputs( +# pulse, +# tstart=tstart, +# tend=tend, +# dt=dt, +# time=time, +# phantom_profile_params=phantom_profile_params, +# phantom_data=phantom_data, +# ts_side=ts_side, +# ) +# +# print("Instatiating Bayes model") +# diagnostic_models = [models["pi"]] +# quant_to_optimise = [ +# "pi.brightness", +# ] +# bm = BayesBlackBox( +# plasma=plasma, +# data=flat_data, +# diagnostic_models=diagnostic_models, +# quant_to_optimise=quant_to_optimise, +# priors=PRIORS, +# ) +# ndim = PARAM_NAMES.__len__() +# start_points = bm.sample_from_priors(PARAM_NAMES, size=nwalkers) +# move = [(emcee.moves.StretchMove(), 1.0), (emcee.moves.DEMove(), 0.0)] +# sampler = emcee.EnsembleSampler( +# nwalkers, +# ndim, +# log_prob_fn=bm.ln_posterior, +# parameter_names=PARAM_NAMES, +# moves=move, +# ) +# +# print("Sampling") +# autocorr = sample_with_autocorr( +# sampler, start_points, iterations=iterations, auto_sample=5 +# ) +# +# blobs = sampler.get_blobs(discard=burn_in, flat=True) +# blob_names = sampler.get_blobs().flatten()[0].keys() +# blob_dict = { +# blob_name: xr.concat( +# [data[blob_name] for data in blobs], +# dim=pd.Index(np.arange(0, blobs.__len__()), name="index"), +# ) +# for blob_name in blob_names +# } +# +# samples = sampler.get_chain(flat=True) +# prior_samples = bm.sample_from_priors(PARAM_NAMES, size=int(1e5)) +# result = { +# "blobs": blob_dict, +# "diag_data": flat_data, +# "samples": samples, +# "prior_samples": prior_samples, +# "param_names": PARAM_NAMES, +# "phantom_profiles": input_profiles, +# "plasma": plasma, +# "autocorr": autocorr, +# } +# print(sampler.acceptance_fraction.sum()) +# plot_bayes_result(**result, figheader=result_path) +# +# if not phantom_data: +# plot_ts(plasma, flat_data, ts_side=ts_side) + +# return result def run_inversion( @@ -601,24 +595,24 @@ def inversion_example( return ff -def bayesian_example( - pulse: int = 11085, - time: float = 0.03, - iterations=200, - nwalkers=50, - phantom_data: bool = True, - ts_side: str = "LFS", -): - ff = run_bayes( - pulse, - time, - PHANTOM_PROFILE_PARAMS, - iterations, - PATHNAME, - burn_in=0, - nwalkers=nwalkers, - phantom_data=phantom_data, - ts_side=ts_side, - ) - - return ff +# def bayesian_example( +# pulse: int = 11085, +# time: float = 0.03, +# iterations=200, +# nwalkers=50, +# phantom_data: bool = True, +# ts_side: str = "LFS", +# ): +# ff = run_bayes( +# pulse, +# time, +# PHANTOM_PROFILE_PARAMS, +# iterations, +# PATHNAME, +# burn_in=0, +# nwalkers=nwalkers, +# phantom_data=phantom_data, +# ts_side=ts_side, +# ) + +# return ff diff --git a/indica/workflows/abstract_bayes_workflow.py b/indica/workflows/abstract_bayes_workflow.py index 4839a2b5..510028ac 100644 --- a/indica/workflows/abstract_bayes_workflow.py +++ b/indica/workflows/abstract_bayes_workflow.py @@ -1,14 +1,11 @@ from abc import ABC from abc import abstractmethod +import getpass from pathlib import Path import pickle +import git import numpy as np -import pandas as pd -import xarray as xr - -from indica.equilibrium import fake_equilibrium -from indica.readers.read_st40 import ReadST40 class AbstractBayesWorkflow(ABC): @@ -28,267 +25,337 @@ def __init__( self.param_names = param_names self.opt_quantity = opt_quantity self.priors = priors - self.read_data(self.diagnostics) - self.setup_models(self.diagnostics) - - def read_test_data( - self, diagnostic_transforms: dict, tstart=None, tend=None, dt=None - ): - # Used with phantom data for purposes of tests - print("Reading fake data") - self.equilibrium = fake_equilibrium( - tstart, - tend, - dt, - ) - self.transforms = diagnostic_transforms - self.data: dict = {} - - def read_data(self, diagnostics: list, tstart=None, tend=None, dt=None): - self.reader = ReadST40(self.pulse, tstart=tstart, tend=tend, dt=dt) - self.reader(diagnostics) - self.equilibrium = self.reader.equilibrium - self.transforms = self.reader.transforms - self.data = self.reader.binned_data - - @abstractmethod - def setup_plasma(self): - """ - Contains all methods and settings for setting up / initialising plasma object - """ - self.plasma = None - self.plasma.set_equilibrium(self.reader.equilibrium) - self.save_phantom_profiles() - - @abstractmethod - def setup_models(self, diagnostics: list): - """ - Initialising models normally requires data to be read so transforms can be set - - """ - self.models: dict = {} - - @abstractmethod - def _phantom_data(self): - opt_data = {} - return opt_data - - @abstractmethod - def _exp_data(self): - opt_data = {} - return opt_data - @abstractmethod - def setup_opt_data(self, phantom: bool = False): - """ - Get and prepare the data in necessary format for optimiser - """ - for model in self.models: - model.plasma = self.plasma - - if phantom: - self.opt_data = self._phantom_data() - else: - self.opt_data = self._exp_data() - - @abstractmethod - def setup_optimiser(self, model_kwargs): - """ - Initialise and provide settings for optimiser - """ - self.bayesopt = None - - def save_phantom_profiles(self, kinetic_profiles=None): - if kinetic_profiles is None: - kinetic_profiles = [ - "electron_density", - "impurity_density", - "electron_temperature", - "ion_temperature", - "ion_density", - "fast_density", - "neutral_density", - ] - if self.phantoms: - phantom_profiles = { - profile_key: getattr(self.plasma, profile_key) - .sel(t=self.plasma.time_to_calculate) - .copy() - for profile_key in kinetic_profiles - } - else: - phantom_profiles = { - profile_key: getattr(self.plasma, profile_key).sel( - t=self.plasma.time_to_calculate - ) - * 0 - for profile_key in kinetic_profiles - } - - self.phantom_profiles = phantom_profiles - - def _build_result_dict(self): + def _build_inputs_dict(self): """ Returns ------- - dictionary of results in MDS+ structure + dictionary of inputs in MDS+ structure """ result = {} - quant_list = [item.split(".") for item in self.opt_quantity] + quant_list = [item.split(".") for item in self.blackbox_settings.opt_quantity] - result["TIME"] = self.plasma.t - result["TIME_OPT"] = self.plasma.time_to_calculate + result["TIME"] = self.plasma_context.plasma.t + git_id = git.Repo(search_parent_directories=True).head.object.hexsha result["METADATA"] = { - "GITCOMMIT": "PLACEHOLDER", - "USER": "PLACEHOLDER", + "GITCOMMIT": f"{git_id}", + "USER": f"{getpass.getuser()}", "EQUIL": "PLACEHOLDER", } result["INPUT"] = { - "BURN_FRAC": self.burn_frac, - "ITER": self.iterations, - "NWALKERS": self.nwalkers, - "MODEL_KWARGS": self.model_kwargs, - "OPT_QUANTITY": self.opt_quantity, - "PARAM_NAMES": self.param_names, - "PULSE": self.pulse, + "BURN_FRAC": self.optimiser_context.optimiser_settings.burn_frac, + "ITER": self.optimiser_context.optimiser_settings.iterations, + "NWALKERS": self.optimiser_context.optimiser_settings.nwalkers, + "MODEL_KWARGS": self.model_context.model_settings.init_kwargs, + "OPT_QUANTITY": self.blackbox_settings.opt_quantity, + "PARAM_NAMES": self.blackbox_settings.param_names, + "PULSE": self.data_context.pulse, + "IMPURITIES": self.plasma_context.plasma_settings.impurities, + "MAIN_ION": self.plasma_context.plasma_settings.main_ion, + "TSTART": self.tstart, + "TEND": self.tend, "DT": self.dt, - "IMPURITIES": self.plasma.impurities, - "MAIN_ION": self.plasma.main_ion, } result["INPUT"]["WORKFLOW"] = { diag_name.upper(): { - "PULSE": self.pulse, # Change this if different pulses used + "PULSE": self.data_context.pulse, "USAGE": "".join( [quantity[1] for quantity in quant_list if quantity[0] == diag_name] ), "RUN": "PLACEHOLDER", } - for diag_name in self.diagnostics + for diag_name in self.blackbox_settings.diagnostics } - result["MODEL_DATA"] = { + result["DIAG_DATA"] = { diag_name.upper(): { - quantity[1].upper(): self.blobs[f"{quantity[0]}.{quantity[1]}"] + quantity[1].upper(): self.data_context.opt_data[ + f"{quantity[0]}.{quantity[1]}" + ] for quantity in quant_list if quantity[0] == diag_name } - for diag_name in self.diagnostics + for diag_name in self.blackbox_settings.diagnostics } - result["MODEL_DATA"]["SAMPLES"] = self.samples - result["DIAG_DATA"] = { + return result + + def _build_result_dict( + self, + ): + result = {} + quant_list = [item.split(".") for item in self.blackbox_settings.opt_quantity] + + result["MODEL_DATA"] = { diag_name.upper(): { - quantity[1].upper(): self.opt_data[f"{quantity[0]}.{quantity[1]}"] + quantity[1].upper(): self.blobs[f"{quantity[0]}.{quantity[1]}"] for quantity in quant_list if quantity[0] == diag_name } - for diag_name in self.diagnostics + for diag_name in self.blackbox_settings.diagnostics } + result["MODEL_DATA"]["SAMPLE_IDX"] = np.arange( + self.optimiser_context.optimiser_settings.iterations + * (1 - self.optimiser_context.optimiser_settings.burn_frac) + ) result["PHANTOMS"] = { - "FLAG": self.phantoms, - "NE": self.phantom_profiles["electron_density"], - "TE": self.phantom_profiles["electron_temperature"], - "TI": self.phantom_profiles["ion_temperature"].sel( - element=self.plasma.main_ion + "FLAG": self.data_context.phantoms, + "NE": self.plasma_context.phantom_profiles["electron_density"], + "TE": self.plasma_context.phantom_profiles["electron_temperature"], + "TI": self.plasma_context.phantom_profiles["ion_temperature"].sel( + element=self.plasma_context.plasma_settings.main_ion ), - "NI": self.phantom_profiles["ion_density"].sel( - element=self.plasma.main_ion + "NI": self.plasma_context.phantom_profiles["ion_density"].sel( + element=self.plasma_context.plasma_settings.main_ion ), - "NNEUTR": self.phantom_profiles["neutral_density"], - "NFAST": self.phantom_profiles["fast_density"], + "NNEUTR": self.plasma_context.phantom_profiles["neutral_density"], + "NFAST": self.plasma_context.phantom_profiles["fast_density"], } result["PHANTOMS"].update( { - f"NIZ{num_imp + 1}": self.phantom_profiles["impurity_density"].sel( - element=imp + f"NIZ{num_imp + 1}": self.plasma_context.phantom_profiles[ + "impurity_density" + ].sel(element=imp) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities ) - for num_imp, imp in enumerate(self.plasma.impurities) } ) result["PHANTOMS"].update( { - f"TIZ{num_imp + 1}": self.phantom_profiles["ion_temperature"].sel( - element=imp + f"TIZ{num_imp + 1}": self.plasma_context.phantom_profiles[ + "ion_temperature" + ].sel(element=imp) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities ) - for num_imp, imp in enumerate(self.plasma.impurities) } ) result["PROFILES"] = { - "RHO_POLOIDAL": self.plasma.rho, - "RHO_TOR": self.plasma.equilibrium.rhotor.interp(t=self.plasma.t), - "NE": self.blobs["electron_density"].median(dim="index"), - "NI": self.blobs["ion_density"] - .sel(element=self.plasma.main_ion) - .median(dim="index"), - "TE": self.blobs["electron_temperature"].median(dim="index"), - "TI": self.blobs["ion_temperature"] - .sel(element=self.plasma.main_ion) - .median(dim="index"), - "NFAST": self.blobs["fast_density"].median(dim="index"), - "NNEUTR": self.blobs["neutral_density"].median(dim="index"), - "NE_ERR": self.blobs["electron_density"].std(dim="index"), - "NI_ERR": self.blobs["ion_density"] - .sel(element=self.plasma.main_ion) - .std(dim="index"), - "TE_ERR": self.blobs["electron_temperature"].std(dim="index"), - "TI_ERR": self.blobs["ion_temperature"] - .sel(element=self.plasma.main_ion) - .std(dim="index"), - "NFAST_ERR": self.blobs["fast_density"].std(dim="index"), - "NNEUTR_ERR": self.blobs["neutral_density"].std(dim="index"), + "PSI_NORM": { + "RHOP": self.plasma_context.plasma.rho, + "RHOT": self.plasma_context.plasma.equilibrium.rhotor.interp( + t=self.plasma_context.plasma.t + ), + "NE": self.blobs["electron_density"].median(dim="index"), + "NI": self.blobs["ion_density"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "TE": self.blobs["electron_temperature"].median(dim="index"), + "TI": self.blobs["ion_temperature"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "NFAST": self.blobs["fast_density"].median(dim="index"), + "NNEUTR": self.blobs["neutral_density"].median(dim="index"), + "NE_ERR": self.blobs["electron_density"].std(dim="index"), + "NI_ERR": self.blobs["ion_density"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + "TE_ERR": self.blobs["electron_temperature"].std(dim="index"), + "TI_ERR": self.blobs["ion_temperature"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + "NFAST_ERR": self.blobs["fast_density"].std(dim="index"), + "NNEUTR_ERR": self.blobs["neutral_density"].std(dim="index"), + "ZEFF": self.blobs["zeff"].sum("element").median(dim="index"), + "ZEFF_ERR": self.blobs["zeff"].sum("element").std(dim="index"), + "ZI": self.blobs["zeff"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "ZI_ERR": self.blobs["zeff"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + }, + "R_MIDPLANE": { + "RPOS": self.midplane_blobs["electron_temperature"].R, + "ZPOS": self.midplane_blobs["electron_temperature"].z, + "NE": self.midplane_blobs["electron_density"].median(dim="index"), + "NI": self.midplane_blobs["ion_density"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "TE": self.midplane_blobs["electron_temperature"].median(dim="index"), + "TI": self.midplane_blobs["ion_temperature"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "NFAST": self.midplane_blobs["fast_density"].median(dim="index"), + "NNEUTR": self.midplane_blobs["neutral_density"].median(dim="index"), + "NE_ERR": self.midplane_blobs["electron_density"].std(dim="index"), + "NI_ERR": self.midplane_blobs["ion_density"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + "TE_ERR": self.midplane_blobs["electron_temperature"].std(dim="index"), + "TI_ERR": self.midplane_blobs["ion_temperature"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + "NFAST_ERR": self.midplane_blobs["fast_density"].std(dim="index"), + "NNEUTR_ERR": self.midplane_blobs["neutral_density"].std(dim="index"), + "ZEFF": self.midplane_blobs["zeff"].sum("element").median(dim="index"), + "ZEFF_ERR": self.midplane_blobs["zeff"].sum("element").std(dim="index"), + "ZI": self.midplane_blobs["zeff"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .median(dim="index"), + "ZI_ERR": self.midplane_blobs["zeff"] + .sel(element=self.plasma_context.plasma_settings.main_ion) + .std(dim="index"), + }, } - result["PROFILES"] = { - **result["PROFILES"], + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], **{ f"NIZ{num_imp + 1}": self.blobs["impurity_density"] .sel(element=imp) .median(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } - result["PROFILES"] = { - **result["PROFILES"], + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], **{ f"NIZ{num_imp + 1}_ERR": self.blobs["impurity_density"] .sel(element=imp) .std(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } - result["PROFILES"] = { - **result["PROFILES"], + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], **{ f"TIZ{num_imp + 1}": self.blobs["ion_temperature"] .sel(element=imp) .median(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } - result["PROFILES"] = { - **result["PROFILES"], + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], **{ f"TIZ{num_imp + 1}_ERR": self.blobs["ion_temperature"] .sel(element=imp) .std(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], + **{ + f"ZIM{num_imp + 1}": self.blobs["zeff"] + .sel(element=imp) + .median(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["PSI_NORM"] = { + **result["PROFILES"]["PSI_NORM"], + **{ + f"ZIM{num_imp + 1}_ERR": self.blobs["zeff"] + .sel(element=imp) + .std(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"NIZ{num_imp + 1}": self.midplane_blobs["impurity_density"] + .sel(element=imp) + .median(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"NIZ{num_imp + 1}_ERR": self.midplane_blobs["impurity_density"] + .sel(element=imp) + .std(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"TIZ{num_imp + 1}": self.midplane_blobs["ion_temperature"] + .sel(element=imp) + .median(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"TIZ{num_imp + 1}_ERR": self.midplane_blobs["ion_temperature"] + .sel(element=imp) + .std(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"ZIM{num_imp + 1}": self.midplane_blobs["zeff"] + .sel(element=imp) + .median(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) + }, + } + result["PROFILES"]["R_MIDPLANE"] = { + **result["PROFILES"]["R_MIDPLANE"], + **{ + f"ZIM{num_imp + 1}_ERR": self.midplane_blobs["zeff"] + .sel(element=imp) + .std(dim="index") + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["PROFILE_STAT"] = { - "SAMPLES": self.samples, - "RHO_POLOIDAL": self.plasma.rho, + "SAMPLE_IDX": np.arange( + self.optimiser_context.optimiser_settings.iterations + * (1 - self.optimiser_context.optimiser_settings.burn_frac) + ), + "RHO_POLOIDAL": self.plasma_context.plasma.rho, "NE": self.blobs["electron_density"], - "NI": self.blobs["ion_density"].sel(element=self.plasma.main_ion), + "NI": self.blobs["ion_density"].sel( + element=self.plasma_context.plasma_settings.main_ion + ), "TE": self.blobs["electron_temperature"], - "TI": self.blobs["ion_temperature"].sel(element=self.plasma.main_ion), + "TI": self.blobs["ion_temperature"].sel( + element=self.plasma_context.plasma_settings.main_ion + ), "NFAST": self.blobs["fast_density"], "NNEUTR": self.blobs["neutral_density"], } @@ -296,27 +363,32 @@ def _build_result_dict(self): **result["PROFILE_STAT"], **{ f"NIZ{num_imp + 1}": self.blobs["impurity_density"].sel(element=imp) - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["PROFILE_STAT"] = { **result["PROFILE_STAT"], **{ f"TIZ{num_imp + 1}": self.blobs["ion_temperature"].sel(element=imp) - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["OPTIMISATION"] = { - "ACCEPT_FRAC": self.accept_frac, - "PRIOR_SAMPLE": self.prior_sample, - "POST_SAMPLE": self.post_sample, - "AUTOCORR": self.autocorr, + "ACCEPT_FRAC": self.opt_samples["accept_frac"], + "PRIOR_SAMPLE": self.opt_samples["prior_sample"], + "POST_SAMPLE": self.opt_samples["post_sample"], + "AUTO_CORR": self.opt_samples["auto_corr"], + # "GELMAN_RUBIN": gelman_rubin(self.sampler.get_chain(flat=False)) } result["GLOBAL"] = { "TI0": self.blobs["ion_temperature"] - .sel(element=self.plasma.main_ion) + .sel(element=self.plasma_context.plasma_settings.main_ion) .sel(rho_poloidal=0, method="nearest") .median(dim="index"), "TE0": self.blobs["electron_temperature"] @@ -326,23 +398,17 @@ def _build_result_dict(self): .sel(rho_poloidal=0, method="nearest") .median(dim="index"), "NI0": self.blobs["ion_density"] - .sel(element=self.plasma.main_ion) + .sel(element=self.plasma_context.plasma_settings.main_ion) .sel(rho_poloidal=0, method="nearest") .median(dim="index"), - "TI0_ERR": self.blobs["ion_temperature"] - .sel(element=self.plasma.main_ion) - .sel(rho_poloidal=0, method="nearest") - .std(dim="index"), - "TE0_ERR": self.blobs["electron_temperature"] - .sel(rho_poloidal=0, method="nearest") - .std(dim="index"), - "NE0_ERR": self.blobs["electron_density"] - .sel(rho_poloidal=0, method="nearest") - .std(dim="index"), - "NI0_ERR": self.blobs["ion_density"] - .sel(element=self.plasma.main_ion) - .sel(rho_poloidal=0, method="nearest") - .std(dim="index"), + "WP": self.blobs["wp"].median(dim="index"), + "WP_ERR": self.blobs["wp"].std(dim="index"), + "WTH": self.blobs["wth"].median(dim="index"), + "WTH_ERR": self.blobs["wth"].std(dim="index"), + "PTOT": self.blobs["ptot"].median(dim="index"), + "PTOT_ERR": self.blobs["ptot"].std(dim="index"), + "PTH": self.blobs["pth"].median(dim="index"), + "PTH_ERR": self.blobs["pth"].std(dim="index"), } result["GLOBAL"] = { **result["GLOBAL"], @@ -351,7 +417,9 @@ def _build_result_dict(self): .sel(element=imp) .sel(rho_poloidal=0, method="nearest") .median(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["GLOBAL"] = { @@ -361,7 +429,9 @@ def _build_result_dict(self): .sel(element=imp) .sel(rho_poloidal=0, method="nearest") .std(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["GLOBAL"] = { @@ -371,7 +441,9 @@ def _build_result_dict(self): .sel(element=imp) .sel(rho_poloidal=0, method="nearest") .median(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } result["GLOBAL"] = { @@ -381,99 +453,22 @@ def _build_result_dict(self): .sel(element=imp) .sel(rho_poloidal=0, method="nearest") .std(dim="index") - for num_imp, imp in enumerate(self.plasma.impurities) + for num_imp, imp in enumerate( + self.plasma_context.plasma_settings.impurities + ) }, } + return result - self.result = result - return self.result - - def run_sampler(self, iterations, burn_frac): - """ - TODO: unsure if keeping in abstract class is best practice - - Runs the sampler and saves certain attributes from the sampler - - Returns - - result in MDSPlus node formatting - - """ - self.burn_frac = burn_frac - self.iterations = iterations - - self.autocorr = sample_with_autocorr( - self.sampler, - self.start_points, - iterations, - self.param_names.__len__(), - auto_sample=10, - ) - blobs = self.sampler.get_blobs(discard=int(iterations * burn_frac), flat=True) - blob_names = self.sampler.get_blobs().flatten()[0].keys() - self.samples = np.arange(0, blobs.__len__()) - - self.blobs = { - blob_name: xr.concat( - [data[blob_name] for data in blobs], - dim=pd.Index(self.samples, name="index"), - ) - for blob_name in blob_names - } - self.accept_frac = self.sampler.acceptance_fraction.sum() - self.prior_sample = self.bayesmodel.sample_from_priors( - self.param_names, size=int(1e4) - ) - self.post_sample = self.sampler.get_chain(flat=True) - self.result = self._build_result_dict() - - def save_pickle(self, filepath): - if filepath: - Path(filepath).mkdir(parents=True, exist_ok=True) - with open(filepath + "results.pkl", "wb") as handle: - pickle.dump(self.result, handle) - - def dict_of_dataarray_to_numpy(self, dict_of_dataarray): - """ - Mutates input dictionary to change xr.DataArray objects to np.array - - """ - for key, value in dict_of_dataarray.items(): - if isinstance(value, dict): - self.dict_of_dataarray_to_numpy(value) - elif isinstance(value, xr.DataArray): - dict_of_dataarray[key] = dict_of_dataarray[key].values - return dict_of_dataarray + def save_pickle(self, result, filepath): + Path(filepath).mkdir(parents=True, exist_ok=True) + with open(filepath + "results.pkl", "wb") as handle: + pickle.dump(result, handle) @abstractmethod def __call__(self, filepath="./results/test/", **kwargs): - self.run_sampler() - self.save_pickle(filepath=filepath) - self.result = self.dict_of_dataarray_to_numpy(self.result) + result = self.run_sampler() + self.save_pickle(result, filepath=filepath) + self.result = result return self.result - - -def sample_with_autocorr(sampler, start_points, iterations, n_params, auto_sample=5): - autocorr = np.ones(shape=(iterations, n_params)) * np.nan - old_tau = np.inf - for sample in sampler.sample( - start_points, - iterations=iterations, - progress=True, - ): - if sampler.iteration % auto_sample: - continue - new_tau = sampler.get_autocorr_time(tol=0) - autocorr[ - sampler.iteration - 1, - ] = new_tau - converged = np.all(new_tau * 50 < sampler.iteration) - converged &= np.all(np.abs(old_tau - new_tau) / new_tau < 0.01) - if converged: - break - old_tau = new_tau - autocorr = autocorr[ - : sampler.iteration, - ] - return autocorr diff --git a/indica/workflows/bayes_plots.py b/indica/workflows/bayes_plots.py index 93955202..01a29dc1 100644 --- a/indica/workflows/bayes_plots.py +++ b/indica/workflows/bayes_plots.py @@ -1,20 +1,22 @@ import os +from pathlib import Path import pickle import corner import flatdict import matplotlib.pyplot as plt import numpy as np +import xarray as xr from indica.utilities import set_axis_sci from indica.utilities import set_plot_rcparams def plot_profile( - profile, - blobkey: str, + profile: xr.DataArray, + phantom_profile: xr.DataArray, + label: str, figheader="./results/test/", - phantom_profile=None, logscale=False, sharefig=False, filename="", @@ -28,38 +30,34 @@ def plot_profile( profile.rho_poloidal, profile.quantile(0.16, dim="index"), profile.quantile(0.84, dim="index"), - label=f"{blobkey}, 68% Confidence", + label=f"{label}, 68% Confidence", zorder=3, color=color, alpha=0.9, ) - if blobkey != "NFAST": + if label != "NFAST": plt.fill_between( profile.rho_poloidal, profile.quantile(0.025, dim="index"), profile.quantile(0.975, dim="index"), - label=f"{blobkey}, 95% Confidence", + label=f"{label}, 95% Confidence", zorder=2, color="grey", alpha=0.4, ) plt.fill_between( profile.rho_poloidal, - profile.quantile(0.00, dim="index"), - profile.quantile(1.00, dim="index"), - label=f"{blobkey}, Max-Min", + profile.quantile(0.005, dim="index"), + profile.quantile(0.995, dim="index"), + label=f"{label}, Max-Min", zorder=1, color="lightgrey", alpha=0.2, ) - if phantom_profile["FLAG"]: - if "element" in phantom_profile[blobkey].dims: - phantom = phantom_profile[blobkey].sel(element="ar") - else: - phantom = phantom_profile[blobkey] - phantom.plot( - label=f"{blobkey}, phantom profile", + if phantom_profile.any(): + phantom_profile.plot( + label=f"{label}, phantom profile", linestyle=linestyle, color="black", zorder=4, @@ -78,82 +76,83 @@ def plot_profile( if filename: plt.savefig(figheader + f"{filename}{filetype}") else: - plt.savefig(figheader + f"{blobkey}{filetype}") + plt.savefig(figheader + f"{label}{filetype}") plt.close("all") def _plot_1d( - blobs: dict, - blobkey: str, - diag_data: dict, + data: xr.DataArray, + diag_data: xr.DataArray, filename: str, figheader="./results/test/", + label="", ylabel="a.u.", xlabel="[]", xlim=None, figsize=(6.4, 4.8), + hide_legend=False, **kwargs, ): - if blobkey not in blobs.keys(): - raise ValueError(f"{blobkey} not in blobs") - plt.figure(figsize=figsize) - blob_data = blobs[blobkey] - dims = tuple(name for name in blob_data.dims if name != "index") + dims = tuple(name for name in data.dims if name != "index") plt.fill_between( - blob_data.__getattr__(dims[0]), - blob_data.quantile(0.16, dim="index"), - blob_data.quantile(0.84, dim="index"), - label=f"{blobkey}, 68% Confidence", + data.__getattr__(dims[0]), + data.quantile(0.16, dim="index"), + data.quantile(0.84, dim="index"), + label=f"{label}, 68% Confidence", zorder=3, color="blue", ) plt.fill_between( - blob_data.__getattr__(dims[0]), - blob_data.quantile(0.025, dim="index"), - blob_data.quantile(0.975, dim="index"), - label=f"{blobkey}, 95% Confidence", + data.__getattr__(dims[0]), + data.quantile(0.025, dim="index"), + data.quantile(0.975, dim="index"), + label=f"{label}, 95% Confidence", zorder=2, color="grey", ) plt.fill_between( - blob_data.__getattr__(dims[0]), - blob_data.quantile(0.00, dim="index"), - blob_data.quantile(1.00, dim="index"), - label=f"{blobkey}, Max-Min", + data.__getattr__(dims[0]), + data.quantile(0.005, dim="index"), + data.quantile(0.995, dim="index"), + label=f"{label}, Max-Min", zorder=1, color="lightgrey", ) if "channel" in dims: plt.plot( - diag_data[blobkey].__getattr__(dims[0]), - diag_data[blobkey].sel(t=blob_data.t).values, + diag_data.__getattr__(dims[0]), + diag_data, "k^", - label=f"{blobkey} data", + label=f"{label} data", zorder=4, ) else: plt.plot( - diag_data[blobkey].__getattr__(dims[0]), - diag_data[blobkey].sel(t=blob_data.t).values, + diag_data.__getattr__(dims[0]), + diag_data, "k-", - label=f"{blobkey} data", + label=f"{label} data", zorder=4, ) + + plt.gca().set_ylim(bottom=0) set_axis_sci() plt.ylabel(ylabel) plt.xlabel(xlabel) plt.xlim(xlim) - plt.legend() + if not hide_legend: + plt.legend() plt.savefig(figheader + filename) plt.close() def violinplot( - data: dict, - key: str, - diag_data: dict, + data, + diag_data, + diag_data_err, filename: str, + xlabel="", ylabel="[a.u.]", figheader="./results/test/", **kwargs, @@ -163,26 +162,28 @@ def violinplot( 1, 1, ) - _data = data[key].values - _data = _data[ - ((_data > np.quantile(_data, 0.16)) & (_data < np.quantile(_data, 0.84))) - ] + _data = data[((data > np.quantile(data, 0.16)) & (data < np.quantile(data, 0.84)))] + violin = axs.violinplot( _data, showextrema=False, # quantiles=[0.025, 0.975, 0.16, 0.84], # showmedians=True, ) - y = diag_data[key].sel(t=data[key].t).values - # TODO abstract the yerr axs.errorbar( - 1, y=y, yerr=y * 0.10, fmt="D", ecolor="black", capsize=10, color="black" + 1, + y=diag_data, + yerr=diag_data_err, + fmt="D", + ecolor="black", + capsize=10, + color="black", ) violin["bodies"][0].set_edgecolor("black") - axs.set_xlabel(key) + axs.set_xlabel(xlabel) top = axs.get_ylim()[1] - bot = axs.get_ylim()[0] - axs.set_ylim(top=top * 1.1, bottom=bot * 0.9) + # bot = axs.get_ylim()[0] + axs.set_ylim(top=top * 1.1, bottom=0) axs.set_ylabel(f"{ylabel}") set_axis_sci() @@ -236,14 +237,19 @@ def plot_autocorr(autocorr, param_names, figheader, filetype=".png"): plt.close() +# flake8: noqa: C901 def plot_bayes_result( results, - figheader="./results/test/", + filepath="./results/test/", filetype=".png", **kwargs, ): - # delete all but pickle in directory - for root, dirs, files in os.walk(figheader): + # delete all but pickle in directory and remove empty directories + for root, dirs, files in os.walk(filepath): + for dir in dirs: + if not os.listdir(root + dir): + print(f"Deleting {os.path.join(root, dir)}") + os.rmdir(os.path.join(root, dir)) for f in files: if f.endswith(".pkl"): continue @@ -251,196 +257,263 @@ def plot_bayes_result( print(f"Deleting {os.path.join(root, f)}") os.remove(os.path.join(root, f)) + # Create time directories + time = results["TIME"] + for t in time.values: + Path(filepath + f"/t:{t:.2f}").mkdir(parents=True, exist_ok=True) + diag_data = flatdict.FlatDict(results["DIAG_DATA"], ".") model_data = flatdict.FlatDict(results["MODEL_DATA"], ".") profiles = flatdict.FlatDict(results["PROFILE_STAT"], ".") post_sample = results["OPTIMISATION"]["POST_SAMPLE"] prior_sample = results["OPTIMISATION"]["PRIOR_SAMPLE"] - autocorr = results["OPTIMISATION"]["AUTOCORR"] + auto_corr = results["OPTIMISATION"]["AUTO_CORR"] param_names = results["INPUT"]["PARAM_NAMES"] phantom_profiles = flatdict.FlatDict(results["PHANTOMS"], ".") - plot_autocorr(autocorr, param_names, figheader, filetype=filetype) - - if "CXFF_PI.TI" in model_data.keys(): - model_data["CXFF_PI.TI0"] = model_data["CXFF_PI.TI"].sel( - channel=diag_data["CXFF_PI.TI"].channel + diag_data_err = {} + for key, value in diag_data.items(): + if hasattr(value, "error"): + error = value.error + if np.any(error == 0): + error = value * 0.10 + elif isinstance(value, flatdict.FlatDict): + continue + else: + error = value * 0.10 + diag_data_err[key] = error + + # select time index for plotting + for t_idx, t in enumerate(time): + figheader = filepath + f"t:{t.values:.2f}/" + + plot_autocorr( + auto_corr[ + t_idx, + ], + param_names, + figheader, + filetype=filetype, ) - diag_data["CXFF_PI.TI0"] = diag_data["CXFF_PI.TI"].sel( - channel=diag_data["CXFF_PI.TI"].channel + # set_plot_rcparams("multi") + + # check if model key exists + + key = "EFIT.WP" + if key in model_data.keys(): + violinplot( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + diag_data_err[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + xlabel=key, + figheader=figheader, + ylabel="Energy [J]", + ) + key = "SMMH1.NE" + if key in model_data.keys(): + violinplot( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + diag_data_err[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + figheader=figheader, + xlabel=key, + ylabel=r"Line Integrated Density [$m^{-2}$]", + ) + key = "XRCS.TE_KW" + if key in model_data.keys(): + violinplot( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + diag_data_err[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + figheader=figheader, + xlabel=key, + ylabel="Temperature [eV]", + ) + key = "XRCS.TI_W" + if key in model_data.keys(): + violinplot( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + diag_data_err[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + figheader=figheader, + xlabel=key, + ylabel="Temperature [eV]", + ) + + key = "XRCS.SPECTRA" + if key in model_data.keys(): + _plot_1d( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + label=key, + figheader=figheader, + ylabel="Intensity [a.u.]", + xlabel="Wavelength [nm]", + xlim=(0.394, 0.401), + figsize=(6, 4), + ) + key = "CXFF_PI.TI" + if key in model_data.keys(): + _plot_1d( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + label=key, + figheader=figheader, + ylabel="Temperature [eV]", + xlabel="Channel", + hide_legend=True, + ) + key = "CXFF_TWS_C.TI" + if key in model_data.keys(): + _plot_1d( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + label=key, + figheader=figheader, + ylabel="Temperature [eV]", + xlabel="Channel", + hide_legend=True, + ) + + key = "TS.TE" + if key in model_data.keys(): + _plot_1d( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + label=key, + figheader=figheader, + ylabel="Temperature [eV]", + xlabel="Channel", + ) + key = "TS.NE" + if key in model_data.keys(): + _plot_1d( + model_data[key].sel(t=t), + diag_data[key].sel(t=t), + f"{key.replace('.', '_')}" + filetype, + label=key, + figheader=figheader, + ylabel="Density [m^-3]", + xlabel="Channel", + ) + + key = "TE" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), + key, + figheader=figheader, + filetype=filetype, + sharefig=True, + color="blue", + linestyle="dashdot", ) - - key = "CXFF_PI.TI0" - if key in model_data.keys(): - violinplot( - model_data, + key = "TI" + plot_profile( + profiles[key].sel( + t=t, + ), + phantom_profiles[key].sel( + t=t, + ), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel="Temperature [eV]", + filename="temperature", + filetype=filetype, + color="red", + linestyle="dotted", ) - key = "EFIT.WP" - if key in model_data.keys(): - violinplot( - model_data, + key = "NE" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel="Energy [J]", + filetype=filetype, + color="blue", + sharefig=True, ) - key = "SMMH1.NE" - if key in model_data.keys(): - violinplot( - model_data, + key = "NI" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel=r"Line Integrated Density [$m^{-2}$]", + filetype=filetype, + sharefig=True, + color="red", ) - key = "XRCS.TE_KW" - if key in model_data.keys(): - violinplot( - model_data, + key = "NFAST" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel="Temperature [eV]", + filename="densities", + filetype=filetype, + color="green", ) - key = "XRCS.TI_W" - if key in model_data.keys(): - violinplot( - model_data, + + key = "NIZ1" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel="Temperature [eV]", + filename=f"{profiles[key].element.values} density", + filetype=filetype, + color="red", ) - set_plot_rcparams("multi") - key = "XRCS.SPECTRA" - if key in model_data.keys(): - _plot_1d( - model_data, + key = "NIZ2" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, figheader=figheader, - ylabel="Intensity [a.u.]", - xlabel="Wavelength [nm]", - xlim=(0.394, 0.401), - figsize=(6, 4), + filename=f"{profiles[key].element.values} density", + filetype=filetype, + color="red", ) - key = "CXFF_PI.TI" - if key in model_data.keys(): - _plot_1d( - model_data, + + key = "NNEUTR" + plot_profile( + profiles[key].sel(t=t), + phantom_profiles[key].sel(t=t), key, - diag_data, - f"{key.replace('.', '_')}" + filetype, + filename="neutral density", figheader=figheader, - ylabel="Temperature [eV]", - xlabel="Channel", + filetype=filetype, + logscale=True, ) - key = "TE" - plot_profile( - profiles[key], - key, - figheader=figheader, - filetype=filetype, - phantom_profile=phantom_profiles, - sharefig=True, - color="blue", - linestyle="dashdot", - ) - key = "TI" - plot_profile( - profiles[key], - key, - figheader=figheader, - filename="temperature", - filetype=filetype, - phantom_profile=phantom_profiles, - color="red", - linestyle="dotted", - ) - - key = "NE" - plot_profile( - profiles[key], - key, - figheader=figheader, - filetype=filetype, - phantom_profile=phantom_profiles, - color="blue", - sharefig=True, - ) - key = "NI" - plot_profile( - profiles[key], - key, - figheader=figheader, - filetype=filetype, - phantom_profile=phantom_profiles, - sharefig=True, - color="red", - ) - key = "NFAST" - plot_profile( - profiles[key], - key, - figheader=figheader, - filename="densities", - filetype=filetype, - phantom_profile=phantom_profiles, - color="green", - ) - - key = "NIZ1" - plot_profile( - profiles[key], - key, - figheader=figheader, - filename="ar density", - filetype=filetype, - phantom_profile=phantom_profiles, - color="red", - ) - - key = "NIZ2" - plot_profile( - profiles[key], - key, - figheader=figheader, - filename="c density", - filetype=filetype, - phantom_profile=phantom_profiles, - color="red", - ) - - key = "NNEUTR" - plot_profile( - profiles[key], - key, - filename="neutral density", - figheader=figheader, - filetype=filetype, - phantom_profile=phantom_profiles, - logscale=True, - ) - - corner.corner(post_sample, labels=param_names) - plt.savefig(figheader + "posterior" + filetype) - - corner.corner(prior_sample, labels=param_names) - plt.savefig(figheader + "prior" + filetype) - plt.close("all") + post_sample_filtered = post_sample[t_idx,][ + ~np.isnan( + post_sample[ + t_idx, + ] + ).any(axis=1) + ] + corner.corner(post_sample_filtered, labels=param_names) + plt.savefig(figheader + "posterior" + filetype) + + corner.corner( + prior_sample[ + t_idx, + ], + labels=param_names, + ) + plt.savefig(figheader + "prior" + filetype) + plt.close("all") if __name__ == "__main__": diff --git a/indica/workflows/bayes_workflow.py b/indica/workflows/bayes_workflow.py new file mode 100644 index 00000000..044f80a3 --- /dev/null +++ b/indica/workflows/bayes_workflow.py @@ -0,0 +1,1269 @@ +from abc import ABC +from abc import abstractmethod +from copy import deepcopy +from dataclasses import dataclass +from dataclasses import field +from typing import Any +from typing import Callable +from typing import Dict +from typing import Optional +from typing import Tuple +from typing import Union + +import emcee +import flatdict +import numpy as np +import pandas as pd +from scipy.stats import describe +from scipy.stats import loguniform +from sklearn.gaussian_process import kernels +import xarray as xr + +from indica.bayesblackbox import BayesBlackBox +from indica.bayesblackbox import get_uniform +from indica.bayesblackbox import ln_prior +from indica.equilibrium import Equilibrium +from indica.equilibrium import fake_equilibrium +from indica.models.charge_exchange import ChargeExchange +from indica.models.charge_exchange import pi_transform_example +from indica.models.equilibrium_reconstruction import EquilibriumReconstruction +from indica.models.helike_spectroscopy import helike_transform_example +from indica.models.helike_spectroscopy import HelikeSpectrometer +from indica.models.interferometry import Interferometry +from indica.models.interferometry import smmh1_transform_example +from indica.models.plasma import Plasma +from indica.models.thomson_scattering import ThomsonScattering +from indica.models.thomson_scattering import ts_transform_example +from indica.operators.gpr_fit import gpr_fit_ts +from indica.operators.gpr_fit import post_process_ts +from indica.readers.read_st40 import ReadST40 +from indica.workflows.abstract_bayes_workflow import AbstractBayesWorkflow +from indica.workflows.bayes_plots import plot_bayes_result +from indica.writers.bda_tree import create_nodes +from indica.writers.bda_tree import does_tree_exist +from indica.writers.bda_tree import write_nodes + +# global configurations +DEFAULT_PROFILE_PARAMS = { + "Ne_prof.y0": 5e19, + "Ne_prof.y1": 2e18, + "Ne_prof.yend": 1e18, + "Ne_prof.wped": 3, + "Ne_prof.wcenter": 0.3, + "Ne_prof.peaking": 1.2, + # "Niz1_prof.y0": 1e17, + # "Niz1_prof.y1": 1e15, + # "Niz1_prof.yend": 1e15, + # "Niz1_prof.wcenter": 0.3, + # "Niz1_prof.wped": 3, + # "Niz1_prof.peaking": 2, + "Te_prof.y0": 3000, + "Te_prof.y1": 50, + "Te_prof.yend": 10, + "Te_prof.wcenter": 0.2, + "Te_prof.wped": 3, + "Te_prof.peaking": 1.5, + "Ti_prof.y0": 6000, + "Ti_prof.y1": 50, + "Ti_prof.yend": 10, + "Ti_prof.wcenter": 0.2, + "Ti_prof.wped": 3, + "Ti_prof.peaking": 1.5, +} + +DEFAULT_PRIORS = { + "Ne_prof.y0": get_uniform(2e19, 4e20), + "Ne_prof.y1": get_uniform(1e18, 2e19), + "Ne_prof.y0/Ne_prof.y1": lambda x1, x2: np.where((x1 > x2 * 2), 1, 0), + "Ne_prof.wped": loguniform(2, 20), + "Ne_prof.wcenter": get_uniform(0.2, 0.4), + "Ne_prof.peaking": get_uniform(1, 4), + "Niz1_prof.y0": loguniform(2e15, 1e18), + "Niz1_prof.y1": loguniform(1e14, 1e16), + "Ne_prof.y0/Niz1_prof.y0": lambda x1, x2: np.where( + (x1 > x2 * 100) & (x1 < x2 * 1e5), 1, 0 + ), + "Niz1_prof.y0/Niz1_prof.y1": lambda x1, x2: np.where((x1 > x2), 1, 0), + "Niz1_prof.wped": get_uniform(2, 6), + "Niz1_prof.wcenter": get_uniform(0.2, 0.4), + "Niz1_prof.peaking": get_uniform(1, 6), + "Niz1_prof.peaking/Ne_prof.peaking": lambda x1, x2: np.where( + (x1 > x2), 1, 0 + ), # impurity always more peaked + "Te_prof.y0": get_uniform(1000, 5000), + "Te_prof.wped": get_uniform(1, 6), + "Te_prof.wcenter": get_uniform(0.2, 0.4), + "Te_prof.peaking": get_uniform(1, 4), + # "Ti_prof.y0/Te_prof.y0": lambda x1, x2: np.where(x1 > x2, 1, 0), # hot ion mode + "Ti_prof.y0": get_uniform(1000, 10000), + "Ti_prof.wped": get_uniform(1, 6), + "Ti_prof.wcenter": get_uniform(0.2, 0.4), + "Ti_prof.peaking": get_uniform(1, 6), +} + +OPTIMISED_PARAMS = [ + "Ne_prof.y1", + "Ne_prof.y0", + "Ne_prof.peaking", + # "Ne_prof.wcenter", + "Ne_prof.wped", + # "Niz1_prof.y1", + "Niz1_prof.y0", + # "Niz1_prof.wcenter", + # "Niz1_prof.wped", + "Niz1_prof.peaking", + "Te_prof.y0", + "Te_prof.wped", + "Te_prof.wcenter", + "Te_prof.peaking", + "Ti_prof.y0", + "Ti_prof.wped", + "Ti_prof.wcenter", + "Ti_prof.peaking", +] +OPTIMISED_QUANTITY = [ + "xrcs.spectra", + "cxff_pi.ti", + "efit.wp", + # "smmh1.ne", + "ts.te", + "ts.ne", +] + +DEFAULT_DIAG_NAMES = [ + "xrcs", + "efit", + "smmh1", + "cxff_pi", + "ts", +] + +FAST_DIAG_NAMES = [ + # "xrcs", + "efit", + "smmh1", + "cxff_pi", + "ts", +] + +FAST_OPT_QUANTITY = [ + # "xrcs.spectra", + "cxff_pi.ti", + "efit.wp", + "smmh1.ne", + "ts.te", + "ts.ne", +] + +FAST_OPT_PARAMS = [ + # "Ne_prof.y1", + "Ne_prof.y0", + # "Ne_prof.peaking", + # "Ne_prof.wcenter", + # "Ne_prof.wped", + # "Niz1_prof.y1", + # "Niz1_prof.y0", + # "Niz1_prof.wcenter", + # "Niz1_prof.wped", + # "Niz1_prof.peaking", + "Te_prof.y0", + # "Te_prof.wped", + # "Te_prof.wcenter", + # "Te_prof.peaking", + "Ti_prof.y0", + # "Ti_prof.wped", + # "Ti_prof.wcenter", + # "Ti_prof.peaking", +] + + +def sample_with_moments( + sampler, + start_points, + iterations, + n_params, + auto_sample=10, + stopping_factor=0.01, + debug=False, +): + # TODO: Compare old_chain to new_chain + # if moments are different then keep going / convergence diagnostics here + + autocorr = np.ones(shape=(iterations, n_params)) * np.nan + old_mean = np.inf + success_flag = False # requires succeeding check twice in a row + for sample in sampler.sample( + start_points, + iterations=iterations, + progress=True, + skip_initial_state_check=False, + ): + if sampler.iteration % auto_sample: + continue + new_tau = sampler.get_autocorr_time(tol=0) + autocorr[sampler.iteration - 1] = new_tau + + dist_stats = describe(sampler.get_chain(flat=True)) + + new_mean = dist_stats.mean + + dmean = np.abs(new_mean - old_mean) + rel_dmean = dmean / old_mean + + if debug: + print("") + print(f"rel_dmean: {rel_dmean.max()}") + if rel_dmean.max() < stopping_factor: + if success_flag: + break + else: + success_flag = True + else: + success_flag = False + old_mean = new_mean + + autocorr = autocorr[ + : sampler.iteration, + ] + return autocorr + + +def sample_with_autocorr( + sampler, + start_points, + iterations, + n_params, + auto_sample=5, +): + autocorr = np.ones(shape=(iterations, n_params)) * np.nan + old_tau = np.inf + for sample in sampler.sample( + start_points, + iterations=iterations, + progress=True, + skip_initial_state_check=False, + ): + if sampler.iteration % auto_sample: + continue + new_tau = sampler.get_autocorr_time(tol=0) + autocorr[ + sampler.iteration - 1, + ] = new_tau + converged = np.all(new_tau * 50 < sampler.iteration) + converged &= np.all(np.abs(old_tau - new_tau) / new_tau < 0.01) + if converged: + break + old_tau = new_tau + autocorr = autocorr[ + : sampler.iteration, + ] + return autocorr + + +def gelman_rubin(chain): + ssq = np.var(chain, axis=1, ddof=1) + w = np.mean(ssq, axis=0) + theta_b = np.mean(chain, axis=1) + theta_bb = np.mean(theta_b, axis=0) + m = chain.shape[0] + n = chain.shape[1] + B = n / (m - 1) * np.sum((theta_bb - theta_b) ** 2, axis=0) + var_theta = (n - 1) / n * w + 1 / n * B + R = np.sqrt(var_theta / w) + return R + + +def dict_of_dataarray_to_numpy(dict_of_dataarray): + """ + Mutates input dictionary to change xr.DataArray objects to np.array + + """ + for key, value in dict_of_dataarray.items(): + if isinstance(value, dict): + dict_of_dataarray_to_numpy(value) + elif isinstance(value, xr.DataArray): + dict_of_dataarray[key] = dict_of_dataarray[key].values + return dict_of_dataarray + + +def sample_from_priors(param_names: list, priors: dict, size=10): + """ + TODO: may be able to remove param_names from here and at some point earlier + remove priors that aren't used + then loop over remaining priors while handling conditional priors somehow... + The order of samples may need to be checked / reordered at some point then + """ + + # Throw out samples that don't meet conditional priors and redraw + samples = np.empty((param_names.__len__(), 0)) + while samples.size < param_names.__len__() * size: + # Some mangling of dictionaries so _ln_prior works + # Increase size * n if too slow / looping too much + new_sample = {name: priors[name].rvs(size=size * 2) for name in param_names} + _ln_prior = ln_prior(priors, new_sample) + # Convert from dictionary of arrays -> array, + # then filtering out where ln_prior is -infinity + accepted_samples = np.array(list(new_sample.values()))[:, _ln_prior != -np.inf] + samples = np.append(samples, accepted_samples, axis=1) + samples = samples[:, 0:size] + return samples.transpose() + + +@dataclass +class PlasmaSettings: + main_ion: str = "h" + impurities: Tuple[str, ...] = ("ar", "c") + impurity_concentration: Tuple[float, ...] = (0.001, 0.04) + n_rad: int = 20 + + +@dataclass +class PlasmaContext: + plasma_settings: PlasmaSettings + profile_params: dict = field(default_factory=lambda: DEFAULT_PROFILE_PARAMS) + + """ + set profiles / profiler + """ + + def init_plasma( + self, + equilibrium: Equilibrium, + tstart=None, + tend=None, + dt=None, + ): + + self.plasma = Plasma( + tstart=tstart, + tend=tend, + dt=dt, + main_ion=self.plasma_settings.main_ion, + impurities=self.plasma_settings.impurities, + impurity_concentration=self.plasma_settings.impurity_concentration, + full_run=False, + n_rad=self.plasma_settings.n_rad, + ) + + self.plasma.set_equilibrium(equilibrium) + self.update_profiles(self.profile_params) + self.plasma.build_atomic_data(calc_power_loss=False) + + def update_profiles(self, params: dict): + if not hasattr(self, "plasma"): + raise ValueError("plasma not initialised") + + self.plasma.update_profiles(params) + + def time_iterator(self): + print("resetting time iterator") + return iter(self.plasma.t) + + def return_plasma_attrs(self): + PLASMA_ATTRIBUTES = [ + "electron_temperature", + "electron_density", + "ion_temperature", + "ion_density", + "impurity_density", + "fast_density", + "neutral_density", + "zeff", + "wp", + "wth", + "ptot", + "pth", + ] + plasma_attributes = {} + for plasma_key in PLASMA_ATTRIBUTES: + if hasattr(self.plasma, plasma_key): + plasma_attributes[plasma_key] = getattr(self.plasma, plasma_key).sel( + t=self.plasma.time_to_calculate + ) + else: + raise ValueError(f"plasma does not have attribute {plasma_key}") + return plasma_attributes + + def save_phantom_profiles(self, kinetic_profiles=None, phantoms=None): + if kinetic_profiles is None: + kinetic_profiles = [ + "electron_density", + "impurity_density", + "electron_temperature", + "ion_temperature", + "ion_density", + "fast_density", + "neutral_density", + ] + if phantoms: + phantom_profiles = { + profile_key: getattr(self.plasma, profile_key) + .sel(t=self.plasma.time_to_calculate) + .copy() + for profile_key in kinetic_profiles + } + else: + phantom_profiles = { + profile_key: getattr(self.plasma, profile_key).sel( + t=self.plasma.time_to_calculate + ) + * 0 + for profile_key in kinetic_profiles + } + self.phantom_profiles = phantom_profiles + + def fit_ts_profile(self, data_context, split="LFS", quant="ne"): + kernel = 1.0 * kernels.RationalQuadratic( + alpha_bounds=(0.5, 1.0), length_scale_bounds=(0.4, 0.7) + ) + kernels.WhiteKernel(noise_level_bounds=(0.01, 10)) + + processed_data = post_process_ts( + deepcopy(data_context.binned_data), + data_context.equilibrium, + quant, + data_context.pulse, + split=split, + ) + fit, _ = gpr_fit_ts( + data=processed_data, + xdim="rho", + virtual_obs=True, + virtual_symmetry=True, + kernel=kernel, + save_fig=True, + ) + fit = xr.where(fit < 0, 1e-10, fit) + return fit + + def set_ts_profiles(self, data_context, split="LFS"): + + ne_fit = self.fit_ts_profile(data_context, quant="ne", split=split) * 1e19 + te_fit = self.fit_ts_profile(data_context, quant="te", split=split) * 1e3 + + self.plasma.electron_density.loc[dict()] = ne_fit.interp(rho=self.plasma.rho) + self.plasma.electron_temperature.loc[dict()] = te_fit.interp( + rho=self.plasma.rho + ) + + def map_profiles_to_midplane(self, blobs): + kinetic_profiles = [ + "electron_density", + "impurity_density", + "electron_temperature", + "ion_temperature", + "ion_density", + "fast_density", + "neutral_density", + "zeff", + ] + nchan = len(self.plasma.R_midplane) + chan = np.arange(nchan) + R = xr.DataArray(self.plasma.R_midplane, coords=[("channel", chan)]) + z = xr.DataArray(self.plasma.z_midplane, coords=[("channel", chan)]) + + rho = self.plasma.equilibrium.rho.interp(t=self.plasma.t, R=R, z=z).drop_vars( + ["R", "z"] + ) + midplane_profiles = {} + for profile in kinetic_profiles: + midplane_profiles[profile] = ( + blobs[profile].interp(rho_poloidal=rho).drop_vars("rho_poloidal") + ) + midplane_profiles[profile]["R"] = R + midplane_profiles[profile]["z"] = z + midplane_profiles[profile] = midplane_profiles[profile].swap_dims( + {"channel": "R"} + ) + return midplane_profiles + + +@dataclass +class ModelSettings: + init_kwargs: dict = field( + default_factory=lambda: { + "cxff_pi": {"element": "ar"}, + "cxff_tws_c": {"element": "c"}, + "xrcs": { + "window_masks": [slice(0.394, 0.396)], + }, + } + ) + call_kwargs: dict = field(default_factory=lambda: {"xrcs": {"pixel_offset": -4.0}}) + + +@dataclass +class ModelContext: + model_settings: ModelSettings + diagnostics: list + plasma_context: PlasmaContext + equilibrium: Union[Equilibrium, None] + transforms: Union[dict, None] + + """ + Setup models so that they have transforms / plasma / equilibrium etc.. + everything needed to produce bckc from models + + TODO: remove repeating code / likely make general methods + """ + + def __post_init__(self): + # Create empty dictionaries for diagnostics where no init or call kwargs defined + for diag in self.diagnostics: + if diag not in self.model_settings.init_kwargs.keys(): + self.model_settings.init_kwargs[diag] = {} + if diag not in self.model_settings.call_kwargs.keys(): + self.model_settings.call_kwargs[diag] = {} + + def update_model_kwargs(self, data: dict): + if "xrcs" in data.keys(): + self.model_settings.init_kwargs["xrcs"]["window"] = data["xrcs"][ + "spectra" + ].wavelength.values + + # TODO: handling model calls dependent on exp data + background = data["xrcs"]["spectra"].where( + (data["xrcs"]["spectra"].wavelength < 0.392) + & (data["xrcs"]["spectra"].wavelength > 0.388), + drop=True, + ) + self.model_settings.init_kwargs["xrcs"]["background"] = background.mean( + dim="wavelength" + ) + + def init_models( + self, + ): + if not hasattr(self, "plasma_context"): + raise ValueError("needs plasma_context to setup_models") + if not hasattr(self.plasma_context, "plasma"): + raise ValueError("plasma_context needs plasma to setup_models") + + self.models: Dict[str, Any] = {} + for diag in self.diagnostics: + if diag == "smmh1": + self.transforms[diag].set_equilibrium(self.equilibrium, force=True) + self.models[diag] = Interferometry( + name=diag, **self.model_settings.init_kwargs[diag] + ) + self.models[diag].set_los_transform(self.transforms[diag]) + + elif diag == "efit": + self.models[diag] = EquilibriumReconstruction( + name=diag, **self.model_settings.init_kwargs[diag] + ) + + elif diag == "cxff_pi": + self.transforms[diag].set_equilibrium(self.equilibrium, force=True) + self.models[diag] = ChargeExchange( + name=diag, **self.model_settings.init_kwargs[diag] + ) + self.models[diag].set_transect_transform(self.transforms[diag]) + + elif diag == "cxff_tws_c": + self.transforms[diag].set_equilibrium(self.equilibrium, force=True) + self.models[diag] = ChargeExchange( + name=diag, **self.model_settings.init_kwargs[diag] + ) + self.models[diag].set_transect_transform(self.transforms[diag]) + + elif diag == "ts": + self.transforms[diag].set_equilibrium(self.equilibrium, force=True) + self.models[diag] = ThomsonScattering( + name=diag, **self.model_settings.init_kwargs[diag] + ) + self.models[diag].set_transect_transform(self.transforms[diag]) + + elif diag == "xrcs": + self.transforms[diag].set_equilibrium(self.equilibrium, force=True) + self.models[diag] = HelikeSpectrometer( + name="xrcs", **self.model_settings.init_kwargs[diag] + ) + self.models[diag].set_los_transform(self.transforms[diag]) + else: + raise ValueError(f"{diag} not implemented in ModelHandler.setup_models") + + for model_name, model in self.models.items(): + model.plasma = self.plasma_context.plasma + + return self.models + + def _build_bckc( + self, + params: dict = None, + ): + """ + Parameters + ---------- + params - dictionary which is updated by optimiser + + Returns + ------- + nested bckc of results + """ + + if params is None: + params = {} + self.bckc: dict = {} + for model_name, model in self.models.items(): + # removes "model.name." from params and kwargs then passes them to model + # e.g. xrcs.background -> background + _call_params = { + param_name.replace(model.name + ".", ""): param_value + for param_name, param_value in params.items() + if model.name in param_name + } + # call_kwargs defined in model_settings + _call_kwargs = { + kwarg_name: kwarg_value + for kwarg_name, kwarg_value in self.model_settings.call_kwargs[ + model_name + ].items() + } + _model_kwargs = { + **_call_kwargs, + **_call_params, + } # combine dictionaries + + _bckc = model(**_model_kwargs) + _model_bckc = { + model.name: {value_name: value for value_name, value in _bckc.items()} + } + # prepend model name to bckc + self.bckc = dict(self.bckc, **_model_bckc) + return self.bckc + + +@dataclass +class ReaderSettings: + revisions: dict = field(default_factory=lambda: {}) + filters: dict = field(default_factory=lambda: {}) + + +@dataclass # type: ignore[misc] +class DataContext(ABC): + reader_settings: ReaderSettings + pulse: Optional[int] + tstart: float + tend: float + dt: float + diagnostics: list + phantoms = False + + @abstractmethod + def read_data( + self, + ): + self.equilbrium = None + self.transforms = None + self.raw_data = None + self.binned_data = None + + @abstractmethod + def data_strategy(self): + return None + + def _check_if_data_present(self, data_strategy: Callable = lambda: None): + if not self.binned_data: + print("Data not given: using data strategy") + self.binned_data = data_strategy() + + def pre_process_data(self, model_callable: Callable): + self.model_callable = model_callable + # TODO: handle this dependency (phantom data) some other way? + self._check_if_data_present(self.data_strategy) + + @abstractmethod + def process_data(self, model_callable: Callable): + self.pre_process_data(model_callable) + self.opt_data = flatdict.FlatDict(self.binned_data) + + +@dataclass +class ExpData(DataContext): + phantoms = False + + """ + Considering: either rewriting this class to take over from ReadST40 or vice versa + + """ + + def read_data( + self, + ): + self.reader = ReadST40( + self.pulse, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + ) + self.reader( + self.diagnostics, + revisions=self.reader_settings.revisions, + filters=self.reader_settings.filters, + ) + missing_keys = set(self.diagnostics) - set(self.reader.binned_data.keys()) + if len(missing_keys) > 0: + raise ValueError(f"missing data: {missing_keys}") + self.equilibrium = self.reader.equilibrium + self.transforms = self.reader.transforms + # TODO raw data included + self.raw_data = self.reader.raw_data + self.binned_data = self.reader.binned_data + + def data_strategy(self): + raise ValueError("Data strategy: Fail") + + def process_data(self, model_callable: Callable): + self.pre_process_data(model_callable) + opt_data = flatdict.FlatDict(self.binned_data, ".") + if "xrcs.spectra" in opt_data.keys(): + background = opt_data["xrcs.spectra"].where( + (opt_data["xrcs.spectra"].wavelength < 0.392) + & (opt_data["xrcs.spectra"].wavelength > 0.388), + drop=True, + ) + opt_data["xrcs.spectra"]["error"] = np.sqrt( + opt_data["xrcs.spectra"] + background.std(dim="wavelength") ** 2 + ) + # TODO move the channel filtering to the read_data method in filtering = {} + if "ts.ne" in opt_data.keys(): + opt_data["ts.ne"]["error"] = opt_data["ts.ne"].max(dim="channel") * 0.05 + # opt_data["ts.ne"] = opt_data["ts.ne"].where( + # opt_data["ts.ne"].channel < 21) + + if "ts.te" in opt_data.keys(): + opt_data["ts.ne"]["error"] = opt_data["ts.ne"].max(dim="channel") * 0.05 + # opt_data["ts.te"] = opt_data["ts.te"].where( + # opt_data["ts.te"].channel < 21) + + if "cxff_tws_c.ti" in opt_data.keys(): + opt_data["cxff_tws_c.ti"] = opt_data["cxff_tws_c.ti"].where( + opt_data["cxff_tws_c.ti"].channel == 0 + ) + + self.opt_data = opt_data + + +@dataclass +class PhantomData(DataContext): + phantoms = True + + def read_data( + self, + ): + self.reader = ReadST40( + self.pulse, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + ) + self.reader( + self.diagnostics, + revisions=self.reader_settings.revisions, + filters=self.reader_settings.filters, + ) + missing_keys = set(self.diagnostics) - set(self.reader.binned_data.keys()) + if len(missing_keys) > 0: + raise ValueError(f"missing data: {missing_keys}") + self.equilibrium = self.reader.equilibrium + self.transforms = self.reader.transforms + self.raw_data = {} + self.binned_data = {} + + def data_strategy(self): + print("Data strategy: Phantom data") + return self.model_callable() + + def process_data(self, model_callable: Callable): + self.pre_process_data(model_callable) + self.opt_data = flatdict.FlatDict(self.binned_data, ".") + + +@dataclass +class MockData(PhantomData): + diagnostic_transforms: dict = field( + default_factory=lambda: { + "xrcs": helike_transform_example(1), + "smmh1": smmh1_transform_example(1), + "cxff_pi": pi_transform_example(5), + "cxff_tws_c": pi_transform_example(3), + "ts": ts_transform_example(11), + "efit": lambda: None, + # placeholder to stop missing_transforms error + } + ) + + def read_data(self): + print("Reading mock equilibrium / transforms") + self.equilibrium = fake_equilibrium( + self.tstart, + self.tend, + self.dt, + ) + missing_transforms = list( + set(self.diagnostics).difference(self.diagnostic_transforms.keys()) + ) + if missing_transforms: + raise ValueError(f"Missing transforms: {missing_transforms}") + + self.transforms = self.diagnostic_transforms + self.binned_data: dict = {} + self.raw_data: dict = {} + + +@dataclass +class OptimiserEmceeSettings: + param_names: list + priors: dict + iterations: int = 1000 + nwalkers: int = 50 + burn_frac: float = 0.20 + sample_method: str = "random" + starting_samples: int = 100 + stopping_criteria: str = "mode" + stopping_criteria_factor: float = 0.01 + stopping_criteria_sample: int = 20 + stopping_criteria_debug: bool = False + + +@dataclass # type: ignore[misc] +class OptimiserContext(ABC): + optimiser_settings: OptimiserEmceeSettings + + @abstractmethod + def init_optimiser(self, *args, **kwargs): + self.optimiser = None + + @abstractmethod + def sample_start_points(self, *args, **kwargs): + self.start_points = None + + @abstractmethod + def format_results(self): + self.results = {} + + @abstractmethod + def run(self): + results = None + return results + + +@dataclass +class EmceeOptimiser(OptimiserContext): + def init_optimiser(self, blackbox_func: Callable, *args, **kwargs): # type: ignore + ndim = len(self.optimiser_settings.param_names) + self.move = [ + (emcee.moves.StretchMove(), 0.0), + (emcee.moves.DEMove(), 1.0), + (emcee.moves.DESnookerMove(), 0.0), + ] + self.optimiser = emcee.EnsembleSampler( + self.optimiser_settings.nwalkers, + ndim, + log_prob_fn=blackbox_func, + parameter_names=self.optimiser_settings.param_names, + moves=self.move, + ) + + def sample_start_points( + self, + ): + + if self.optimiser_settings.sample_method == "high_density": + + self.start_points = self.sample_from_high_density_region( + param_names=self.optimiser_settings.param_names, + priors=self.optimiser_settings.priors, + optimiser=self.optimiser, + nwalkers=self.optimiser_settings.nwalkers, + nsamples=self.optimiser_settings.starting_samples, + ) + + elif self.optimiser_settings.sample_method == "random": + self.start_points = sample_from_priors( + param_names=self.optimiser_settings.param_names, + priors=self.optimiser_settings.priors, + size=self.optimiser_settings.nwalkers, + ) + else: + raise ValueError( + f"Sample method: {self.optimiser_settings.sample_method} " + f"not recognised, Defaulting to random sampling" + ) + + def sample_from_high_density_region( + self, param_names: list, priors: dict, optimiser, nwalkers: int, nsamples=100 + ): + + # TODO: remove repeated code + start_points = sample_from_priors(param_names, priors, size=nsamples) + + ln_prob, _ = optimiser.compute_log_prob(start_points) + num_best_points = 3 + index_best_start = np.argsort(ln_prob)[-num_best_points:] + best_start_points = start_points[index_best_start, :] + best_points_std = np.std(best_start_points, axis=0) + + # Passing samples through ln_prior and redrawing if they fail + samples = np.empty((param_names.__len__(), 0)) + while samples.size < param_names.__len__() * nwalkers: + sample = np.random.normal( + np.mean(best_start_points, axis=0), + best_points_std, + size=(nwalkers * 5, len(param_names)), + ) + start = {name: sample[:, idx] for idx, name in enumerate(param_names)} + _ln_prior = ln_prior( + priors, + start, + ) + # Convert from dictionary of arrays -> array, + # then filtering out where ln_prior is -infinity + accepted_samples = np.array(list(start.values()))[:, _ln_prior != -np.inf] + samples = np.append(samples, accepted_samples, axis=1) + start_points = samples[:, 0:nwalkers].transpose() + return start_points + + def run( + self, + ): + + if self.optimiser_settings.stopping_criteria == "mode": + self.autocorr = sample_with_moments( + self.optimiser, + self.start_points, + self.optimiser_settings.iterations, + self.optimiser_settings.param_names.__len__(), + auto_sample=self.optimiser_settings.stopping_criteria_sample, + stopping_factor=self.optimiser_settings.stopping_criteria_factor, + debug=self.optimiser_settings.stopping_criteria_debug, + ) + else: + raise ValueError( + f"Stopping criteria: " + f"{self.optimiser_settings.stopping_criteria} invalid" + ) + + optimiser_results = self.format_results() + return optimiser_results + + def format_results(self): + results = {} + _blobs = self.optimiser.get_blobs( + discard=int(self.optimiser.iteration * self.optimiser_settings.burn_frac), + flat=True, + ) + blobs = [blob for blob in _blobs if blob] # remove empty blobs + + blob_names = blobs[0].keys() + samples = np.arange(0, blobs.__len__()) + + results["blobs"] = { + blob_name: xr.concat( + [data[blob_name] for data in blobs], + dim=pd.Index(samples, name="index"), + ) + for blob_name in blob_names + } + results["accept_frac"] = self.optimiser.acceptance_fraction.sum() + results["prior_sample"] = sample_from_priors( + self.optimiser_settings.param_names, + self.optimiser_settings.priors, + size=int(1e4), + ) + + post_sample = self.optimiser.get_chain( + discard=int(self.optimiser.iteration * self.optimiser_settings.burn_frac), + flat=True, + ) + # pad index dim with maximum number of iterations + max_iter = self.optimiser_settings.iterations * self.optimiser_settings.nwalkers + npad = ( + ( + 0, + int( + max_iter * (1 - self.optimiser_settings.burn_frac) + - post_sample.shape[0] + ), + ), + (0, 0), + ) + results["post_sample"] = np.pad(post_sample, npad, constant_values=np.nan) + + results["auto_corr"] = self.autocorr + return results + + +@dataclass +class BayesBBSettings: + diagnostics: list = field(default_factory=lambda: DEFAULT_DIAG_NAMES) + param_names: list = field(default_factory=lambda: OPTIMISED_PARAMS) + opt_quantity: list = field(default_factory=lambda: OPTIMISED_QUANTITY) + priors: dict = field(default_factory=lambda: DEFAULT_PRIORS) + percent_error: float = 0.10 + + """ + TODO: default methods / getter + setters + print warning if using default values + """ + + def __post_init__(self): + missing_quantities = [ + quant + for quant in self.opt_quantity + if quant.split(".")[0] not in self.diagnostics + ] + if missing_quantities: + raise ValueError(f"{missing_quantities} missing the relevant diagnostic") + + # check all priors are defined + for name in self.param_names: + if name in self.priors.keys(): + if hasattr(self.priors[name], "rvs"): + continue + else: + raise TypeError(f"prior object {name} missing rvs method") + else: + raise ValueError(f"Missing prior for {name}") + + +class BayesWorkflow(AbstractBayesWorkflow): + def __init__( + self, + blackbox_settings: BayesBBSettings, + data_context: DataContext, + plasma_context: PlasmaContext, + model_context: ModelContext, + optimiser_context: EmceeOptimiser, + tstart: float = 0.02, + tend: float = 0.10, + dt: float = 0.01, + ): + self.blackbox_settings = blackbox_settings + self.data_context = data_context + self.plasma_context = plasma_context + self.model_context = model_context + self.optimiser_context = optimiser_context + + self.tstart = tstart + self.tend = tend + self.dt = dt + + self.blackbox = BayesBlackBox( + data=self.data_context.opt_data, + plasma_context=self.plasma_context, + model_context=self.model_context, + quant_to_optimise=self.blackbox_settings.opt_quantity, + priors=self.blackbox_settings.priors, + percent_error=self.blackbox_settings.percent_error, + ) + + self.optimiser_context.init_optimiser( + self.blackbox.ln_posterior, + ) + + def __call__( + self, + filepath="./results/test/", + run="RUN01", + mds_write=False, + pulse_to_write=None, + plot=False, + **kwargs, + ): + + self.result = self._build_inputs_dict() + results = [] + + for time in self.plasma_context.time_iterator(): + self.plasma_context.plasma.time_to_calculate = time + print(f"Time: {time.values:.2f}") + self.optimiser_context.sample_start_points() + self.optimiser_context.run() + results.append(self.optimiser_context.format_results()) + self.optimiser_context.optimiser.reset() + + # unpack results and add time axis + blobs = {} + for key in results[0]["blobs"].keys(): + _blob = [result["blobs"][key] for result in results] + blobs[key] = xr.concat(_blob, self.plasma_context.plasma.t) + self.blobs = blobs + self.midplane_blobs = self.plasma_context.map_profiles_to_midplane(blobs) + + opt_samples = {} + for key in results[0].keys(): + if key == "blobs": + continue + _opt_samples = [result[key] for result in results] + opt_samples[key] = np.array(_opt_samples) + self.opt_samples = opt_samples + + result = self._build_result_dict() + self.result = dict(self.result, **result) + + if mds_write or plot: + self.save_pickle( + self.result, + filepath=filepath, + ) + + if plot: # currently requires result with DataArrays + plot_bayes_result(self.result, filepath) + + self.result = dict_of_dataarray_to_numpy(self.result) + + if mds_write: + tree_exists = does_tree_exist(pulse_to_write) + if tree_exists: + mode = "EDIT" + else: + mode = "NEW" + + self.node_structure = create_nodes( + pulse_to_write=pulse_to_write, + run=run, + diagnostic_quantities=self.blackbox_settings.opt_quantity, + mode=mode, + ) + write_nodes(pulse_to_write, self.node_structure, self.result) + return + + +if __name__ == "__main__": + pulse = None + tstart = 0.05 + tend = 0.06 + dt = 0.01 + + diagnostics = [ + # "xrcs", + # "efit", + # "smmh1", + "cxff_pi", + "cxff_tws_c", + # "ts", + ] + # diagnostic_quantities + opt_quant = [ + # "xrcs.spectra", + # "efit.wp", + # "smmh1.ne", + "cxff_pi.ti", + "cxff_tws_c.ti", + # "ts.te", + # "ts.ne", + ] + opt_params = [ + # "Ne_prof.y0", + # "Ne_prof.peaking", + # "Te_prof.y0", + # "Te_prof.peaking", + # "Te_prof.wped", + # "Te_prof.wcenter", + "Ti_prof.y0", + # "Ti_prof.peaking", + "Ti_prof.wped", + "Ti_prof.wcenter", + # "Niz1_prof.y0", + # "Niz1_prof.peaking", + # "Niz1_prof.wcenter", + # "Niz1_prof.wped", + ] + + # BlackBoxSettings + bayes_settings = BayesBBSettings( + diagnostics=diagnostics, + param_names=opt_params, + opt_quantity=opt_quant, + priors=DEFAULT_PRIORS, + ) + + data_settings = ReaderSettings( + filters={}, revisions={} + ) # Add general methods for filtering data co-ords to ReadST40 + data_context = MockData( + pulse=pulse, + diagnostics=diagnostics, + tstart=tstart, + tend=tend, + dt=dt, + reader_settings=data_settings, + ) + # data_context = PhantomData(pulse=pulse, diagnostics=diagnostics, + # tstart=tstart, tend=tend, dt=dt, reader_settings=data_settings, ) + # data_context = ExpData(pulse=pulse, diagnostics=diagnostics, + # tstart=tstart, tend=tend, dt=dt, reader_settings=data_settings, ) + data_context.read_data() + + plasma_settings = PlasmaSettings( + main_ion="h", + impurities=("ar", "c"), + impurity_concentration=(0.001, 0.04), + n_rad=20, + ) + plasma_context = PlasmaContext( + plasma_settings=plasma_settings, profile_params=DEFAULT_PROFILE_PARAMS + ) + + model_settings = ModelSettings(call_kwargs={"xrcs": {"pixel_offset": 0.0}}) + + model_context = ModelContext( + diagnostics=diagnostics, + plasma_context=plasma_context, + equilibrium=data_context.equilibrium, + transforms=data_context.transforms, + model_settings=model_settings, + ) + + # Initialise context objects + plasma_context.init_plasma( + equilibrium=data_context.equilibrium, + tstart=tstart, + tend=tend, + dt=dt, + ) + + # plasma_context.set_ts_profiles(data_context, split="LFS") + + plasma_context.save_phantom_profiles(phantoms=data_context.phantoms) + + model_context.update_model_kwargs(data_context.binned_data) + model_context.init_models() + + data_context.process_data( + model_context._build_bckc, + ) + + optimiser_settings = OptimiserEmceeSettings( + param_names=bayes_settings.param_names, + nwalkers=20, + iterations=1000, + sample_method="high_density", + starting_samples=50, + burn_frac=0.20, + stopping_criteria="mode", + stopping_criteria_factor=0.005, + stopping_criteria_debug=True, + priors=bayes_settings.priors, + ) + optimiser_context = EmceeOptimiser(optimiser_settings=optimiser_settings) + + workflow = BayesWorkflow( + tstart=tstart, + tend=tend, + dt=dt, + blackbox_settings=bayes_settings, + data_context=data_context, + optimiser_context=optimiser_context, + plasma_context=plasma_context, + model_context=model_context, + ) + + workflow( + pulse_to_write=43000000, + run="RUN01", + mds_write=True, + plot=True, + filepath="./results/test/", + ) diff --git a/indica/workflows/bayes_workflow_example.py b/indica/workflows/bayes_workflow_example.py deleted file mode 100644 index cb81a09d..00000000 --- a/indica/workflows/bayes_workflow_example.py +++ /dev/null @@ -1,445 +0,0 @@ -from typing import Any -from typing import Dict - -import emcee -import flatdict -import numpy as np -from scipy.stats import loguniform - -from indica.bayesmodels import BayesModels -from indica.bayesmodels import get_uniform -from indica.models.charge_exchange import ChargeExchange -from indica.models.charge_exchange import pi_transform_example -from indica.models.equilibrium_reconstruction import EquilibriumReconstruction -from indica.models.helike_spectroscopy import helike_transform_example -from indica.models.helike_spectroscopy import HelikeSpectrometer -from indica.models.interferometry import Interferometry -from indica.models.interferometry import smmh1_transform_example -from indica.models.plasma import Plasma -from indica.workflows.abstract_bayes_workflow import AbstractBayesWorkflow -from indica.workflows.bayes_plots import plot_bayes_result -from indica.writers.bda_tree import create_nodes -from indica.writers.bda_tree import write_nodes - -# global configurations -DEFAULT_PROFILE_PARAMS = { - "Ne_prof.y0": 5e19, - "Ne_prof.wcenter": 0.4, - "Ne_prof.peaking": 2, - "Ne_prof.y1": 2e18, - "Ne_prof.yend": 1e18, - "Ne_prof.wped": 2, - "Nimp_prof.y0": 1e17, - "Nimp_prof.y1": 5e15, - "Nimp_prof.wcenter": 0.4, - "Nimp_prof.wped": 6, - "Nimp_prof.peaking": 2, - "Te_prof.y0": 3000, - "Te_prof.y1": 50, - "Te_prof.wcenter": 0.4, - "Te_prof.wped": 3, - "Te_prof.peaking": 2, - "Ti_prof.y0": 6000, - "Ti_prof.y1": 50, - "Ti_prof.wcenter": 0.4, - "Ti_prof.wped": 3, - "Ti_prof.peaking": 2, -} - -DEFAULT_PRIORS = { - "Ne_prof.y0": get_uniform(2e19, 4e20), - "Ne_prof.y1": get_uniform(1e18, 1e19), - "Ne_prof.y0/Ne_prof.y1": lambda x1, x2: np.where((x1 > x2 * 2), 1, 0), - "Ne_prof.wped": get_uniform(1, 6), - "Ne_prof.wcenter": get_uniform(0.1, 0.8), - "Ne_prof.peaking": get_uniform(1, 6), - "Nimp_prof.y0": loguniform(1e16, 1e18), - "Nimp_prof.y1": get_uniform(1e15, 1e16), - "Ne_prof.y0/Nimp_prof.y0": lambda x1, x2: np.where( - (x1 > x2 * 100) & (x1 < x2 * 1e5), 1, 0 - ), - "Nimp_prof.y0/Nimp_prof.y1": lambda x1, x2: np.where((x1 > x2), 1, 0), - "Nimp_prof.wped": get_uniform(1, 6), - "Nimp_prof.wcenter": get_uniform(0.1, 0.8), - "Nimp_prof.peaking": get_uniform(1, 10), - "Nimp_prof.peaking/Ne_prof.peaking": lambda x1, x2: np.where( - (x1 > x2), 1, 0 - ), # impurity always more peaked - "Te_prof.y0": get_uniform(1000, 5000), - "Te_prof.wped": get_uniform(1, 6), - "Te_prof.wcenter": get_uniform(0.1, 0.8), - "Te_prof.peaking": get_uniform(1, 10), - # "Ti_prof.y0/Te_prof.y0": lambda x1, x2: np.where(x1 > x2, 1, 0), # hot ion mode - "Ti_prof.y0": get_uniform(1000, 10000), - "Ti_prof.wped": get_uniform(1, 6), - "Ti_prof.wcenter": get_uniform(0.1, 0.8), - "Ti_prof.peaking": get_uniform(1, 10), -} - -OPTIMISED_PARAMS = [ - # "Ne_prof.y1", - "Ne_prof.y0", - # "Ne_prof.peaking", - # "Ne_prof.wcenter", - # "Ne_prof.wped", - # "Nimp_prof.y1", - "Nimp_prof.y0", - # "Nimp_prof.wcenter", - # "Nimp_prof.wped", - # "Nimp_prof.peaking", - "Te_prof.y0", - # "Te_prof.wped", - "Te_prof.wcenter", - "Te_prof.peaking", - "Ti_prof.y0", - # "Ti_prof.wped", - "Ti_prof.wcenter", - "Ti_prof.peaking", -] -OPTIMISED_QUANTITY = [ - "xrcs.spectra", - "cxff_pi.ti", - "efit.wp", - "smmh1.ne", -] - - -class BayesWorkflowExample(AbstractBayesWorkflow): - def __init__( - self, - diagnostics: list, - param_names: list, - opt_quantity: list, - priors: dict, - profile_params: dict, - pulse: int = None, - phantoms: bool = False, - tstart=0.02, - tend=0.10, - dt=0.005, - ): - self.pulse = pulse - self.diagnostics = diagnostics - self.param_names = param_names - self.opt_quantity = opt_quantity - self.priors = priors - self.profile_params = profile_params - self.phantoms = phantoms - self.tstart = tstart - self.tend = tend - self.dt = dt - - for attribute in [ - "param_names", - "opt_quantity", - "priors", - "diagnostics", - "profile_params", - ]: - if getattr(self, attribute) is None: - raise ValueError(f"{attribute} needs to be defined") - - if self.pulse is None and self.phantoms is False: - raise ValueError( - "Set phantoms to True when running phantom plasma i.e. pulse=None" - ) - - # TODO: Add some abstraction here - if pulse is None: - print("Running in test mode") - example_transforms = { - "xrcs": helike_transform_example(1), - "smmh1": smmh1_transform_example(1), - "cxff_pi": pi_transform_example(5), - } - self.read_test_data( - example_transforms, tstart=self.tstart, tend=self.tend, dt=self.dt - ) - else: - self.read_data( - self.diagnostics, tstart=self.tstart, tend=self.tend, dt=self.dt - ) - self.setup_models(self.diagnostics) - - def setup_plasma( - self, - tstart=None, - tend=None, - dt=None, - tsample=0.050, - main_ion="h", - impurities=("ar", "c"), - impurity_concentration=(0.001, 0.04), - n_rad=20, - **kwargs, - ): - if not all([tstart, tend, dt]): - tstart = self.tstart - tend = self.tend - dt = self.dt - - # TODO: move to plasma.py - self.plasma = Plasma( - tstart=tstart, - tend=tend, - dt=dt, - main_ion=main_ion, - impurities=impurities, - impurity_concentration=impurity_concentration, - full_run=False, - n_rad=n_rad, - ) - self.tsample = tsample - self.plasma.time_to_calculate = self.plasma.t[ - np.abs(tsample - self.plasma.t).argmin() - ] - self.plasma.set_equilibrium(self.equilibrium) - self.plasma.update_profiles(self.profile_params) - self.plasma.build_atomic_data(calc_power_loss=False) - self.save_phantom_profiles() - - def setup_models(self, diagnostics: list): - self.models: Dict[str, Any] = {} - model: Any = None - for diag in diagnostics: - if diag == "smmh1": - los_transform = self.transforms[diag] - # machine_dims = ((0.15, 0.95), (-0.7, 0.7)) - # origin = np.array([[-0.38063365, 0.91893092, 0.01]]) - # # end = np.array([[0, 0, 0.01]]) - # direction = np.array([[0.38173721, -0.92387953, -0.02689453]]) - # los_transform = LineOfSightTransform( - # origin[:, 0], - # origin[:, 1], - # origin[:, 2], - # direction[:, 0], - # direction[:, 1], - # direction[:, 2], - # name="", - # machine_dimensions=machine_dims, - # passes=2, - # ) - los_transform.set_equilibrium(self.equilibrium) - model = Interferometry(name=diag) - model.set_los_transform(los_transform) - - elif diag == "xrcs": - los_transform = self.transforms[diag] - los_transform.set_equilibrium(self.equilibrium) - window = None - if hasattr(self, "data"): - if diag in self.data.keys(): - window = self.data[diag]["spectra"].wavelength.values - - model = HelikeSpectrometer( - name="xrcs", - window_masks=[slice(0.394, 0.396)], - window=window, - ) - model.set_los_transform(los_transform) - - elif diag == "efit": - model = EquilibriumReconstruction(name="efit") - - elif diag == "cxff_pi": - transform = self.transforms[diag] - transform.set_equilibrium(self.equilibrium) - model = ChargeExchange(name=diag, element="ar") - model.set_transect_transform(transform) - else: - raise ValueError(f"{diag} not found in setup_models") - self.models[diag] = model - - def setup_opt_data(self, phantoms=False, **kwargs): - if not hasattr(self, "plasma"): - raise ValueError("Missing plasma object required for setup_opt_data") - for model in self.models.values(): # Maybe refactor here... - model.plasma = self.plasma - - if phantoms: - self.opt_data = self._phantom_data(**kwargs) - else: - self.opt_data = self._exp_data(**kwargs) - - def _phantom_data(self, noise=False, noise_factor=0.1, **kwargs): - opt_data = {} - if "smmh1" in self.diagnostics: - opt_data["smmh1.ne"] = ( - self.models["smmh1"]() - .pop("ne") - .expand_dims(dim={"t": [self.plasma.time_to_calculate]}) - ) - if "xrcs" in self.diagnostics: - opt_data["xrcs.spectra"] = ( - self.models["xrcs"]() - .pop("spectra") - .expand_dims(dim={"t": [self.plasma.time_to_calculate]}) - ) - opt_data["xrcs.spectra"]["error"] = np.sqrt(opt_data["xrcs.spectra"]) - if "cxff_pi" in self.diagnostics: - cxrs_data = ( - self.models["cxff_pi"]() - .pop("ti") - .expand_dims(dim={"t": [self.plasma.time_to_calculate]}) - ) - opt_data["cxff_pi.ti"] = cxrs_data.where(cxrs_data.channel == 2, drop=True) - if "efit" in self.diagnostics: - opt_data["efit.wp"] = ( - self.models["efit"]() - .pop("wp") - .expand_dims(dim={"t": [self.plasma.time_to_calculate]}) - ) - - if noise: - opt_data["smmh1.ne"] = opt_data["smmh1.ne"] + opt_data[ - "smmh1.ne" - ].max().values * np.random.normal(0, noise_factor, None) - opt_data["xrcs.spectra"] = opt_data["xrcs.spectra"] + np.random.normal( - 0, - np.sqrt( - opt_data["xrcs.spectra"].values[ - 0, - ] - ), - opt_data["xrcs.spectra"].shape[1], - ) - opt_data["cxff_pi.ti"] = opt_data["cxff_pi.ti"] + opt_data[ - "cxff_pi.ti" - ].max().values * np.random.normal( - 0, noise_factor, opt_data["cxff_pi.ti"].shape[1] - ) - opt_data["efit.wp"] = opt_data["efit.wp"] + opt_data[ - "efit.wp" - ].max().values * np.random.normal(0, noise_factor, None) - return opt_data - - def _exp_data(self, **kwargs): - opt_data = flatdict.FlatDict(self.data, ".") - if "xrcs" in self.diagnostics: - opt_data["xrcs.spectra"]["wavelength"] = ( - opt_data["xrcs.spectra"].wavelength * 0.1 - ) - background = opt_data["xrcs.spectra"].where( - (opt_data["xrcs.spectra"].wavelength < 0.392) - & (opt_data["xrcs.spectra"].wavelength > 0.388), - drop=True, - ) - self.model_kwargs["xrcs_background"] = background.mean( - dim="wavelength" - ).sel(t=self.plasma.time_to_calculate) - opt_data["xrcs.spectra"]["error"] = np.sqrt( - opt_data["xrcs.spectra"] + background.std(dim="wavelength") ** 2 - ) - - if "cxff_pi" in self.diagnostics: - opt_data["cxff_pi"]["ti"] = opt_data["cxff_pi"]["ti"].where( - opt_data["cxff_pi"]["ti"].channel == 2, drop=True - ) - return opt_data - - def setup_optimiser( - self, - model_kwargs, - nwalkers=50, - burn_frac=0.10, - sample_high_density=False, - ): - self.model_kwargs = model_kwargs - self.nwalkers = nwalkers - self.burn_frac = burn_frac - self.sample_high_density = sample_high_density - - self.bayesmodel = BayesModels( - plasma=self.plasma, - data=self.opt_data, - diagnostic_models=[*self.models.values()], - quant_to_optimise=self.opt_quantity, - priors=self.priors, - ) - - ndim = len(self.param_names) - self.move = [(emcee.moves.StretchMove(), 0.9), (emcee.moves.DEMove(), 0.1)] - self.sampler = emcee.EnsembleSampler( - nwalkers, - ndim, - log_prob_fn=self.bayesmodel.ln_posterior, - parameter_names=self.param_names, - moves=self.move, - kwargs=model_kwargs, - ) - self.start_points = self._sample_start_points( - sample_high_density=self.sample_high_density - ) - - def _sample_start_points(self, sample_high_density: bool = True): - if sample_high_density: - start_points = self.bayesmodel.sample_from_high_density_region( - self.param_names, self.sampler, self.nwalkers, nsamples=100 - ) - else: - start_points = self.bayesmodel.sample_from_priors( - self.param_names, size=self.nwalkers - ) - return start_points - - def __call__( - self, - filepath="./results/test/", - run=None, - mds_write=False, - pulse_to_write=None, - plot=False, - iterations=100, - burn_frac=0.10, - **kwargs, - ): - if mds_write: - # check_analysis_run(self.pulse, self.run) - self.node_structure = create_nodes( - pulse_to_write=pulse_to_write, - run=run, - diagnostic_quantities=self.opt_quantity, - mode="NEW", - ) - - self.run_sampler(iterations=iterations, burn_frac=burn_frac) - self.save_pickle(filepath=filepath) - - if plot: # currently requires result with DataArrays - plot_bayes_result(self.result, filepath) - - self.result = self.dict_of_dataarray_to_numpy(self.result) - if mds_write: - write_nodes(pulse_to_write, self.node_structure, self.result) - - return self.result - - -if __name__ == "__main__": - run = BayesWorkflowExample( - pulse=None, - diagnostics=["xrcs", "efit", "smmh1", "cxff_pi"], - param_names=OPTIMISED_PARAMS, - opt_quantity=OPTIMISED_QUANTITY, - priors=DEFAULT_PRIORS, - profile_params=DEFAULT_PROFILE_PARAMS, - phantoms=True, - tstart=0.02, - tend=0.10, - dt=0.005, - ) - - run.setup_plasma( - tsample=0.060, - ) - run.setup_opt_data(phantoms=run.phantoms) - run.setup_optimiser(nwalkers=50, sample_high_density=True, model_kwargs={}) - results = run( - filepath="./results/test/", - pulse_to_write=23000101, - run="RUN01", - mds_write=True, - plot=True, - burn_frac=0.10, - iterations=100, - ) diff --git a/indica/workflows/bda_run.py b/indica/workflows/bda_run.py new file mode 100644 index 00000000..5820d07a --- /dev/null +++ b/indica/workflows/bda_run.py @@ -0,0 +1,450 @@ +from typing import Any +from typing import List + +from indica.workflows.bayes_workflow import BayesBBSettings +from indica.workflows.bayes_workflow import BayesWorkflow +from indica.workflows.bayes_workflow import DEFAULT_PRIORS +from indica.workflows.bayes_workflow import DEFAULT_PROFILE_PARAMS +from indica.workflows.bayes_workflow import EmceeOptimiser +from indica.workflows.bayes_workflow import ExpData +from indica.workflows.bayes_workflow import ModelContext +from indica.workflows.bayes_workflow import ModelSettings +from indica.workflows.bayes_workflow import OptimiserEmceeSettings +from indica.workflows.bayes_workflow import PhantomData +from indica.workflows.bayes_workflow import PlasmaContext +from indica.workflows.bayes_workflow import PlasmaSettings +from indica.workflows.bayes_workflow import ReaderSettings + +PARAMS_DEFAULT = [ + "Ne_prof.y1", + "Ne_prof.y0", + "Ne_prof.peaking", + # "Ne_prof.wcenter", + "Ne_prof.wped", + # "Niz1_prof.y1", + "Niz1_prof.y0", + # "Niz1_prof.wcenter", + # "Niz1_prof.wped", + "Niz1_prof.peaking", + "Te_prof.y0", + "Te_prof.wped", + "Te_prof.wcenter", + "Te_prof.peaking", + "Ti_prof.y0", + # "Ti_prof.wped", + "Ti_prof.wcenter", + "Ti_prof.peaking", +] + +PARAMS_SET_TS = [ + # "Ne_prof.y1", + # "Ne_prof.y0", + # "Ne_prof.peaking", + # "Ne_prof.wcenter", + # "Ne_prof.wped", + # "Niz1_prof.y1", + "Niz1_prof.y0", + # "Niz1_prof.wcenter", + # "Niz1_prof.wped", + "Niz1_prof.peaking", + # "Te_prof.y0", + # "Te_prof.wped", + # "Te_prof.wcenter", + # "Te_prof.peaking", + "Ti_prof.y0", + # "Ti_prof.wped", + "Ti_prof.wcenter", + "Ti_prof.peaking", +] + +DIAG_DEFAULT = [ + "xrcs", + "ts", + "efit", + "cxff_pi", + "cxff_tws_c" + # "smmh1", +] + +DIAG_DEFAULT_CHERS = [ + "xrcs", + "ts", + # "efit", + # "cxff_pi", + "cxff_tws_c" + # "smmh1", +] + +DIAG_DEFAULT_PI = [ + "xrcs", + "ts", + # "efit", + "cxff_pi", + # "cxff_tws_c" + # "smmh1", +] + +OPT_DEFAULT = [ + "xrcs.spectra", + "ts.ne", + "ts.te", + # "efit.wp", + "cxff_pi.ti", + "cxff_tws_c.ti", + # "smmh1.ne" +] + + +def bda_run( + pulse, + diagnostics, + param_names, + opt_quantity, + phantom=False, + tstart=0.02, + tend=0.05, + dt=0.01, + revisions={}, + filters={}, + iterations=500, + nwalkers=50, + stopping_criteria_factor=0.002, + mds_write=False, + plot=False, + run="RUN01", + dirname=None, + set_ts=False, + ts_split="LFS", + **kwargs, +): + + if dirname is None: + dirname = f"{pulse}" + + # BlackBoxSettings + bayes_settings = BayesBBSettings( + diagnostics=diagnostics, + param_names=param_names, + opt_quantity=opt_quantity, + priors=DEFAULT_PRIORS, + ) + + data_settings = ReaderSettings(filters=filters, revisions=revisions) + if phantom: + data_context = PhantomData( + pulse=pulse, + diagnostics=diagnostics, + tstart=tstart, + tend=tend, + dt=dt, + reader_settings=data_settings, + ) + else: + data_context = ExpData( + pulse=pulse, + diagnostics=diagnostics, + tstart=tstart, + tend=tend, + dt=dt, + reader_settings=data_settings, + ) + data_context.read_data() + + plasma_settings = PlasmaSettings( + main_ion="h", + impurities=("ar", "c"), + impurity_concentration=(0.001, 0.04), + n_rad=20, + ) + plasma_context = PlasmaContext( + plasma_settings=plasma_settings, profile_params=DEFAULT_PROFILE_PARAMS + ) + + plasma_context.init_plasma( + data_context.equilibrium, tstart=tstart, tend=tend, dt=dt + ) + plasma_context.save_phantom_profiles(phantoms=data_context.phantoms) + + if set_ts: + plasma_context.set_ts_profiles(data_context, split=ts_split) + + model_settings = ModelSettings(call_kwargs={"xrcs": {"pixel_offset": 0.0}}) + + model_context = ModelContext( + diagnostics=diagnostics, + plasma_context=plasma_context, + equilibrium=data_context.equilibrium, + transforms=data_context.transforms, + model_settings=model_settings, + ) + model_context.update_model_kwargs(data_context.binned_data) + model_context.init_models() + + data_context.process_data( + model_context._build_bckc, + ) + + optimiser_settings = OptimiserEmceeSettings( + param_names=bayes_settings.param_names, + nwalkers=nwalkers, + iterations=iterations, + sample_method="high_density", + starting_samples=100, + burn_frac=0.20, + stopping_criteria="mode", + stopping_criteria_factor=stopping_criteria_factor, + stopping_criteria_debug=True, + priors=bayes_settings.priors, + ) + optimiser_context = EmceeOptimiser(optimiser_settings=optimiser_settings) + + workflow = BayesWorkflow( + tstart=tstart, + tend=tend, + dt=dt, + blackbox_settings=bayes_settings, + data_context=data_context, + optimiser_context=optimiser_context, + plasma_context=plasma_context, + model_context=model_context, + ) + + workflow( + pulse_to_write=43000000 + pulse, + run=run, + mds_write=mds_write, + plot=plot, + filepath=f"./results/{dirname}/", + ) + + +if __name__ == "__main__": + + pulse_info: List[Any] = [ + # [(11226, + # ["xrcs", "cxff_pi", "cxff_tws_c", "ts"], + # PARAMS_DEFAULT, + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # "cxff_tws_c.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=True, + # tstart=0.05, + # tend=0.10, + # dt=0.01, + # iterations=5000, + # nwalkers=50, + # stopping_criteria_factor=0.002, + # mds_write=True, + # plot=True, + # run="RUN01", + # dirname=f"{11226}", + # )], + # [(10009, + # ["xrcs", "cxff_pi"], + # PARAMS_DEFAULT, + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # ]), + # dict( + # phantom=True, + # tstart=0.07, + # tend=0.08, + # dt=0.01, + # iterations=100, + # nwalkers=50, + # mds_write=True, + # plot=True, + # run="RUN01", + # dirname=f"{11336}_phantom", + # )], + # [(11089, + # ["xrcs", "cxff_tws_c", "ts", "efit"], + # PARAMS_SET_TS, + # [ + # "xrcs.spectra", + # "cxff_tws_c.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=False, + # tstart=0.05, + # tend=0.10, + # dt=0.01, + # iterations=1000, + # nwalkers=20, + # stopping_criteria_factor=0.002, + # mds_write=True, + # plot=True, + # revisions={}, + # run="RUN01", + # # dirname="test", + # set_ts=True, + # )], + # RFX low ti/te pulse + # [(11312, + # ["xrcs", "cxff_pi", "ts", "efit"], + # [ + # "Niz1_prof.y0", + # "Niz1_prof.peaking", + # "Ti_prof.y0", + # "Ti_prof.wcenter", + # "Ti_prof.peaking", + # ], + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=False, + # tstart=0.05, + # tend=0.10, + # dt=0.01, + # iterations=1000, + # nwalkers=20, + # stopping_criteria_factor=0.002, + # mds_write=True, + # plot=True, + # revisions={}, + # run="RUN01", + # # dirname="test", + # set_ts=True, + # )], + # [(11314, + # ["xrcs", "cxff_pi", "ts", "efit"], + # [ + # "Niz1_prof.y0", + # "Niz1_prof.peaking", + # "Ti_prof.y0", + # "Ti_prof.wcenter", + # "Ti_prof.peaking", + # ], + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=False, + # tstart=0.05, + # tend=0.10, + # dt=0.01, + # iterations=2000, + # nwalkers=20, + # stopping_criteria_factor=0.001, + # mds_write=True, + # plot=True, + # revisions={}, + # run="RUN01", + # # dirname="test", + # set_ts=True, + # )], + # [(11317, + # ["xrcs", "cxff_pi", "ts", "efit"], + # [ + # "Niz1_prof.y0", + # "Niz1_prof.peaking", + # "Ti_prof.y0", + # "Ti_prof.wcenter", + # "Ti_prof.peaking", + # ], + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=False, + # tstart=0.05, + # tend=0.10, + # dt=0.01, + # iterations=2000, + # nwalkers=20, + # stopping_criteria_factor=0.001, + # mds_write=True, + # plot=True, + # revisions={}, + # run="RUN01", + # # dirname="test", + # set_ts=True, + # )], + # [(11419, + # ["xrcs", "cxff_pi", "ts", "efit"], + # [ + # "Niz1_prof.y0", + # "Niz1_prof.peaking", + # "Ti_prof.y0", + # "Ti_prof.wcenter", + # "Ti_prof.peaking", + # ], + # [ + # "xrcs.spectra", + # "cxff_pi.ti", + # "ts.ne", + # "ts.te", + # ]), + # dict( + # phantom=False, + # tstart=0.10, + # tend=0.16, + # dt=0.01, + # iterations=2000, + # nwalkers=20, + # stopping_criteria_factor=0.002, + # mds_write=True, + # plot=True, + # revisions={}, + # run="RUN01", + # # dirname="test", + # set_ts=True, + # )], + [ + ( + 11032, + ["xrcs", "cxff_pi", "ts", "efit"], + [ + "Niz1_prof.y0", + "Niz1_prof.peaking", + "Ti_prof.y0", + "Ti_prof.wcenter", + "Ti_prof.peaking", + ], + [ + "xrcs.spectra", + "cxff_pi.ti", + "ts.ne", + "ts.te", + ], + ), + dict( + phantom=False, + tstart=0.03, + tend=0.09, + dt=0.01, + iterations=2000, + nwalkers=20, + stopping_criteria_factor=0.001, + mds_write=True, + plot=True, + revisions={}, + run="RUN01", + # dirname="test", + set_ts=True, + ts_split="", + ), + ], + ] + + for info in pulse_info: + print(f"pulse: {info[0][0]}") + bda_run(*info[0], **info[1]) diff --git a/indica/workflows/zeff_workflows.py b/indica/workflows/zeff_workflows.py index 5c84e808..89ab6a17 100644 --- a/indica/workflows/zeff_workflows.py +++ b/indica/workflows/zeff_workflows.py @@ -30,13 +30,13 @@ def calculate_zeff( ): print("Reading data") st40 = ReadST40(pulse, tstart, tend, dt) - st40(["pi", "tws_c", "ts", "efit"], revisions=revisions) + st40(["pi", "tws_c", "ts", "efit"], revisions=revisions, set_equilibrium=True) print("Fitting TS data") - te_data = st40.raw_data_trange["ts"]["te"] - te_err = st40.raw_data_trange["ts"]["te"].error - ne_data = st40.raw_data_trange["ts"]["ne"] - ne_err = st40.raw_data_trange["ts"]["ne"].error + te_data = st40.raw_data["ts"]["te"] + te_err = st40.raw_data["ts"]["te"].error + ne_data = st40.raw_data["ts"]["ne"] + ne_err = st40.raw_data["ts"]["ne"].error time = te_data.t te_fit, ne_fit = fit_ts( te_data, te_err, ne_data, ne_err, fit_Rshift=fit_Rshift, verbose=verbose diff --git a/indica/writers/bda_tree.py b/indica/writers/bda_tree.py index 6dfa20ae..994a94eb 100644 --- a/indica/writers/bda_tree.py +++ b/indica/writers/bda_tree.py @@ -7,31 +7,29 @@ import standard_utility as util -def bda(): - nodes = { - "TIME": ("NUMERIC", "time vector, s"), - "TIME_OPT": ("NUMERIC", "time of optimisation, s"), - "INPUT": { - "BURN_FRAC": ("NUMERIC", "Burn in fraction for chains"), - "ITER": ("NUMERIC", "Iterations of optimiser"), - "PARAM_NAMES": ("TEXT", "Names of parameters optimised"), - "OPT_QUANTITY": ("TEXT", "Names of quantities optimised"), - "MODEL_KWARGS": ("TEXT", "Model key word arguments"), - # "OPT_KWARGS": ("TEXT", "Optimiser key word arguments"), - "PULSE": ("NUMERIC", "Pulse number"), - "TSTART": ("NUMERIC", "Start of time vector, s"), - "TEND": ("NUMERIC", "End of time vector, s"), - "DT": ("NUMERIC", "Distance between time points, s"), - "TSAMPLE": ("NUMERIC", "Sample time, s"), - "IMPURITIES": ("TEXT", "Names of impurity elements"), - "MAIN_ION": ("TEXT", "Name of main ion"), - }, - "METADATA": { - "GITCOMMIT": ("TEXT", "Commit ID used for run"), - "USER": ("TEXT", "Username of owner"), - "EQUIL": ("TEXT", "Equilibrium used"), - }, - "PROFILES": { +BDA_NODES = { + "TIME": ("NUMERIC", "time vector of optimisation, s"), + "INPUT": { + "BURN_FRAC": ("NUMERIC", "Burn in fraction for chains"), + "ITER": ("NUMERIC", "Maximum iterations of optimiser"), + "PARAM_NAMES": ("TEXT", "Names of parameters optimised"), + "OPT_QUANTITY": ("TEXT", "Names of quantities optimised"), + "MODEL_KWARGS": ("TEXT", "Model key word arguments"), + # "OPT_KWARGS": ("TEXT", "Optimiser key word arguments"), + "PULSE": ("NUMERIC", "Pulse number"), + "TSTART": ("NUMERIC", "Start of time vector, s"), + "TEND": ("NUMERIC", "End of time vector, s"), + "DT": ("NUMERIC", "Distance between time points, s"), + "IMPURITIES": ("TEXT", "Names of impurity elements"), + "MAIN_ION": ("TEXT", "Name of main ion"), + }, + "METADATA": { + "GITCOMMIT": ("TEXT", "Commit ID used for run"), + "USER": ("TEXT", "Username of owner"), + "EQUIL": ("TEXT", "Equilibrium used"), + }, + "PROFILES": { + "PSI_NORM": { "RHOP": ("NUMERIC", "Radial vector, Sqrt of normalised poloidal flux"), "RHOT": ("SIGNAL", "Radial vector, toroidal flux"), "NE": ("SIGNAL", "Electron density, m^-3"), @@ -65,77 +63,131 @@ def bda(): "NIZ3_ERR": ("SIGNAL", "Density of impurity Z3 error, m^-3"), "NNEUTR_ERR": ("SIGNAL", "Density of neutral main ion error, m^-3"), "NFAST_ERR": ("SIGNAL", "Density of fast ion error, m^-3"), + "ZI_ERR": ("SIGNAL", "Average charge of main ion error, "), + "ZIM1_ERR": ("SIGNAL", "Average charge of impurity IMP1 error, "), + "ZIM2_ERR": ("SIGNAL", "Average charge of impurity IMP2 error, "), + "ZIM3_ERR": ("SIGNAL", "Averagnodese charge of impurity IMP3 error, "), + "ZEFF_ERR": ("SIGNAL", "Effective charge error, "), }, - "PROFILE_STAT": { - "SAMPLES": ("NUMERIC", "Numerical index of the optimisation samples"), - "RHOP": ("NUMERIC", "Radial vector, Sqrt of normalised poloidal flux"), + "R_MIDPLANE": { + "RPOS": ("NUMERIC", "Major radius position of measurement, m"), + "ZPOS": ("NUMERIC", "Z position of measurement, m"), "NE": ("SIGNAL", "Electron density, m^-3"), "NI": ("SIGNAL", "Ion density, m^-3"), "TE": ("SIGNAL", "Electron temperature, eV"), "TI": ("SIGNAL", "Ion temperature of main ion, eV"), - "TIZ1": ("SIGNAL", "Ion temperature of impurity IMP1, eV"), - "TIZ2": ("SIGNAL", "Ion temperature of impurity IMP2, eV"), - "TIZ3": ("SIGNAL", "Ion temperature of impurity IMP3, eV"), - "NIZ1": ("SIGNAL", "Density of impurity IMP1, m^-3"), - "NIZ2": ("SIGNAL", "Density of impurity IMP2, m^-3"), - "NIZ3": ("SIGNAL", "Density of impurity IMP3, m^-3"), + "TIZ1": ("SIGNAL", "Ion temperature of impurity Z1, eV"), + "TIZ2": ("SIGNAL", "Ion temperature of impurity Z2, eV"), + "TIZ3": ("SIGNAL", "Ion temperature of impurity Z3, eV"), + "NIZ1": ("SIGNAL", "Density of impurity Z1, m^-3"), + "NIZ2": ("SIGNAL", "Density of impurity Z2, m^-3"), + "NIZ3": ("SIGNAL", "Density of impurity Z3, m^-3"), "NNEUTR": ("SIGNAL", "Density of neutral main ion, m^-3"), - "NFAST": ("SIGNAL", "Density of fast ions, m^-3"), + "NFAST": ("SIGNAL", "Density of fast ion, m^-3"), "ZI": ("SIGNAL", "Average charge of main ion, "), "ZIM1": ("SIGNAL", "Average charge of impurity IMP1, "), "ZIM2": ("SIGNAL", "Average charge of impurity IMP2, "), "ZIM3": ("SIGNAL", "Average charge of impurity IMP3, "), "ZEFF": ("SIGNAL", "Effective charge, "), "P": ("SIGNAL", "Pressure,Pa"), - "VOLUME": ("SIGNAL", "Volume inside magnetic surface, m^3"), - }, - "GLOBAL": { - "NE0": ("SIGNAL", "Central electron density, m^-3"), - "NI0": ("SIGNAL", "Central ion density, m^-3"), - "TE0": ("SIGNAL", "Central electron temperature, eV"), - "TI0": ("SIGNAL", "Central ion temperature of main ion, eV"), - "TI0Z1": ("SIGNAL", "Central ion temperature of impurity Z1, eV"), - "TI0Z2": ("SIGNAL", "Central ion temperature of impurity Z2, eV"), - "TI0Z3": ("SIGNAL", "Central ion temperature of impurity Z3, eV"), - "NI0Z1": ("SIGNAL", "Central density of impurity Z1, m^-3"), - "NI0Z2": ("SIGNAL", "Central density of impurity Z2, m^-3"), - "NI0Z3": ("SIGNAL", "Central density of impurity Z3, m^-3"), - "NE0_ERR": ("SIGNAL", "Central electron density error, m^-3"), - "NI0_ERR": ("SIGNAL", "Central ion density error, m^-3"), - "TE0_ERR": ("SIGNAL", "Central electron temperature error, eV"), - "TI0_ERR": ("SIGNAL", "Central ion temperature of main ion error, eV"), - "TI0Z1_ERR": ("SIGNAL", "Central ion temperature of impurity Z1, eV"), - "TI0Z2_ERR": ("SIGNAL", "Central ion temperature of impurity Z2, eV"), - "TI0Z3_ERR": ("SIGNAL", "Central ion temperature of impurity Z3, eV"), - "NI0Z1_ERR": ("SIGNAL", "Central density of impurity Z1, m^-3"), - "NI0Z2_ERR": ("SIGNAL", "Central density of impurity Z2, m^-3"), - "NI0Z3_ERR": ("SIGNAL", "Central density of impurity Z3, m^-3"), - }, - "PHANTOMS": { - "FLAG": ("TEXT", "True if phantoms used"), - "RHO_POLOIDAL": ( - "NUMERIC", - "Radial vector, Sqrt of normalised poloidal flux", - ), - "NE": ("SIGNAL", "Electron density, m^-3"), - "NI": ("SIGNAL", "Ion density, m^-3"), - "TE": ("SIGNAL", "Electron temperature, eV"), - "TI": ("SIGNAL", "Ion temperature of main ion, eV"), - "TIZ1": ("SIGNAL", "Ion temperature of impurity Z1 , eV"), - "TIZ2": ("SIGNAL", "Ion temperature of impurity Z2, eV"), - "TIZ3": ("SIGNAL", "Ion temperature of impurity Z3, eV"), - "NIZ1": ("SIGNAL", "Impurity density of Z1, m^-3"), - "NIZ2": ("SIGNAL", "Impurity density of Z2, m^-3"), - "NIZ3": ("SIGNAL", "Impurity density of Z3, m^-3"), - }, - "OPTIMISATION": { - "ACCEPT_FRAC": ("NUMERIC", "Fraction of samples accepted by optimiser"), - "AUTO_CORR": ("NUMERIC", "Auto-correlation (iteration nwalker)"), - "POST_SAMPLE": ("NUMERIC", "Posterior probability samples (sample)"), - "PRIOR_SAMPLE": ("NUMERIC", "Prior samples"), + "VOLUME": ("SIGNAL", "Volume inside magnetic surface,m^3"), + "NE_ERR": ("SIGNAL", "Electron density error, m^-3"), + "NI_ERR": ("SIGNAL", "Ion density error, m^-3"), + "TE_ERR": ("SIGNAL", "Electron temperature error, eV"), + "TI_ERR": ("SIGNAL", "Ion temperature of main ion error, eV"), + "TIZ1_ERR": ("SIGNAL", "Ion temperature of impurity Z1 error, eV"), + "TIZ2_ERR": ("SIGNAL", "Ion temperature of impurity Z2 error, eV"), + "TIZ3_ERR": ("SIGNAL", "Ion temperature of impurity Z3 error, eV"), + "NIZ1_ERR": ("SIGNAL", "Density of impurity Z1 error, m^-3"), + "NIZ2_ERR": ("SIGNAL", "Density of impurity Z2 error, m^-3"), + "NIZ3_ERR": ("SIGNAL", "Density of impurity Z3 error, m^-3"), + "NNEUTR_ERR": ("SIGNAL", "Density of neutral main ion error, m^-3"), + "NFAST_ERR": ("SIGNAL", "Density of fast ion error, m^-3"), + "ZI_ERR": ("SIGNAL", "Average charge of main ion error, "), + "ZIM1_ERR": ("SIGNAL", "Average charge of impurity IMP1 error, "), + "ZIM2_ERR": ("SIGNAL", "Average charge of impurity IMP2 error, "), + "ZIM3_ERR": ("SIGNAL", "Average charge of impurity IMP3 error, "), + "ZEFF_ERR": ("SIGNAL", "Effective charge error, "), }, - } - return nodes + }, + "PROFILE_STAT": { + "SAMPLE_IDX": ("NUMERIC", "Index of the optimisation samples"), + "RHOP": ("NUMERIC", "Radial vector, Sqrt of normalised poloidal flux"), + "NE": ("SIGNAL", "Electron density, m^-3"), + "NI": ("SIGNAL", "Ion density, m^-3"), + "TE": ("SIGNAL", "Electron temperature, eV"), + "TI": ("SIGNAL", "Ion temperature of main ion, eV"), + "TIZ1": ("SIGNAL", "Ion temperature of impurity IMP1, eV"), + "TIZ2": ("SIGNAL", "Ion temperature of impurity IMP2, eV"), + "TIZ3": ("SIGNAL", "Ion temperature of impurity IMP3, eV"), + "NIZ1": ("SIGNAL", "Density of impurity IMP1, m^-3"), + "NIZ2": ("SIGNAL", "Density of impurity IMP2, m^-3"), + "NIZ3": ("SIGNAL", "Density of impurity IMP3, m^-3"), + "NNEUTR": ("SIGNAL", "Density of neutral main ion, m^-3"), + "NFAST": ("SIGNAL", "Density of fast ions, m^-3"), + "ZI": ("SIGNAL", "Average charge of main ion, "), + "ZIM1": ("SIGNAL", "Average charge of impurity IMP1, "), + "ZIM2": ("SIGNAL", "Average charge of impurity IMP2, "), + "ZIM3": ("SIGNAL", "Average charge of impurity IMP3, "), + "ZEFF": ("SIGNAL", "Effective charge, "), + "P": ("SIGNAL", "Pressure,Pa"), + "VOLUME": ("SIGNAL", "Volume inside magnetic surface, m^3"), + }, + "GLOBAL": { + "NE0": ("SIGNAL", "Central electron density, m^-3"), + "NI0": ("SIGNAL", "Central ion density, m^-3"), + "TE0": ("SIGNAL", "Central electron temperature, eV"), + "TI0": ("SIGNAL", "Central ion temperature of main ion, eV"), + "TI0Z1": ("SIGNAL", "Central ion temperature of impurity Z1, eV"), + "TI0Z2": ("SIGNAL", "Central ion temperature of impurity Z2, eV"), + "TI0Z3": ("SIGNAL", "Central ion temperature of impurity Z3, eV"), + "NI0Z1": ("SIGNAL", "Central density of impurity Z1, m^-3"), + "NI0Z2": ("SIGNAL", "Central density of impurity Z2, m^-3"), + "NI0Z3": ("SIGNAL", "Central density of impurity Z3, m^-3"), + "NE0_ERR": ("SIGNAL", "Central electron density error, m^-3"), + "NI0_ERR": ("SIGNAL", "Central ion density error, m^-3"), + "TE0_ERR": ("SIGNAL", "Central electron temperature error, eV"), + "TI0_ERR": ("SIGNAL", "Central ion temperature of main ion error, eV"), + "TI0Z1_ERR": ("SIGNAL", "Central ion temperature of impurity Z1 error, eV"), + "TI0Z2_ERR": ("SIGNAL", "Central ion temperature of impurity Z2 error, eV"), + "TI0Z3_ERR": ("SIGNAL", "Central ion temperature of impurity Z3 error, eV"), + "NI0Z1_ERR": ("SIGNAL", "Central density of impurity Z1 error, m^-3"), + "NI0Z2_ERR": ("SIGNAL", "Central density of impurity Z2 error, m^-3"), + "NI0Z3_ERR": ("SIGNAL", "Central density of impurity Z3 error, m^-3"), + "WP": ("SIGNAL", "Stored energy, J"), + "WTH": ("SIGNAL", "Thermal component of stored energy, J"), + "PTOT": ("SIGNAL", "Total pressure, Pa"), + "PTH": ("SIGNAL", "Thermal pressure, Pa"), + "WP_ERR": ("SIGNAL", "Stored energy error, J"), + "WTH_ERR": ("SIGNAL", "Thermal component of stored energy error, J"), + "PTOT_ERR": ("SIGNAL", "Total pressure error, Pa"), + "PTH_ERR": ("SIGNAL", "Thermal pressure error, Pa"), + }, + "PHANTOMS": { + "FLAG": ("TEXT", "True if phantoms used"), + "RHO_POLOIDAL": ( + "NUMERIC", + "Radial vector, Sqrt of normalised poloidal flux", + ), + "NE": ("SIGNAL", "Electron density, m^-3"), + "NI": ("SIGNAL", "Ion density, m^-3"), + "TE": ("SIGNAL", "Electron temperature, eV"), + "TI": ("SIGNAL", "Ion temperature of main ion, eV"), + "TIZ1": ("SIGNAL", "Ion temperature of impurity Z1 , eV"), + "TIZ2": ("SIGNAL", "Ion temperature of impurity Z2, eV"), + "TIZ3": ("SIGNAL", "Ion temperature of impurity Z3, eV"), + "NIZ1": ("SIGNAL", "Impurity density of Z1, m^-3"), + "NIZ2": ("SIGNAL", "Impurity density of Z2, m^-3"), + "NIZ3": ("SIGNAL", "Impurity density of Z3, m^-3"), + }, + "OPTIMISATION": { + "ACCEPT_FRAC": ("NUMERIC", "Fraction of samples accepted by optimiser"), + "AUTO_CORR": ("NUMERIC", "Auto-correlation"), + "POST_SAMPLE": ("NUMERIC", "Posterior probability samples"), + "PRIOR_SAMPLE": ("NUMERIC", "Prior samples"), + "GELMAN_RUBIN": ("NUMERIC", "Gelmin-Rubin convergence diagnostic"), + }, +} DIAGNOSTIC_QUANTITY = [ @@ -146,13 +198,13 @@ def bda(): def create_nodes( - pulse_to_write=23000101, + pulse_to_write=43000000, run="RUN01", best=True, diagnostic_quantities=DIAGNOSTIC_QUANTITY, mode="EDIT", ): - bda_nodes = bda() + bda_nodes = BDA_NODES quant_list = [ item.upper().split(".") for item in diagnostic_quantities ] # replace OPTIMISED_QUANTITY @@ -183,7 +235,7 @@ def create_nodes( } for diag_name in diag_names } - model_nodes["SAMPLES"] = ("NUMERIC", "index of samples taken from optimisation") + model_nodes["SAMPLE_IDX"] = ("NUMERIC", "Index of the optimisation samples") bda_nodes["MODEL_DATA"] = model_nodes bda_nodes["DIAG_DATA"] = diag_nodes bda_nodes["INPUT"]["WORKFLOW"] = workflow_nodes @@ -226,7 +278,7 @@ def write_nodes(pulse, node_info, data): ) -def check_analysis_run( +def check_to_overwrite_run( pulseNo, which_run, ): @@ -250,6 +302,20 @@ def check_analysis_run( return overwrite_flag +def does_tree_exist( + pulse, +): + IP_address_smaug = "smaug" + conn = Connection(IP_address_smaug) + + try: + conn.openTree("BDA", pulse) + conn.closeAllTrees() + return True + except Exception: + return False + + def query_yes_no( question, ): @@ -266,4 +332,13 @@ def query_yes_no( if __name__ == "__main__": - create_nodes(pulse_to_write=23000101) + + pulse = 43000000 + run = "RUN01" + + tree_exists = does_tree_exist(pulse) + if tree_exists: + mode = "EDIT" + else: + mode = "NEW" + create_nodes(pulse_to_write=pulse, mode=mode, run=run) diff --git a/poetry.lock b/poetry.lock index 5d84cb92..fad81917 100644 --- a/poetry.lock +++ b/poetry.lock @@ -9,27 +9,20 @@ python-versions = "*" [package.extras] dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"] -[[package]] -name = "appnope" -version = "0.1.3" -description = "Disable App Nap on macOS >= 10.9" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "asttokens" -version = "2.2.1" +version = "2.4.1" description = "Annotate AST trees with source code positions" category = "main" optional = false python-versions = "*" [package.dependencies] -six = "*" +six = ">=1.12.0" [package.extras] -test = ["astroid", "pytest"] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] [[package]] name = "atomicwrites" @@ -41,7 +34,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "23.1.0" +version = "23.2.0" description = "Classes Without Boilerplate" category = "dev" optional = false @@ -52,27 +45,20 @@ cov = ["attrs", "coverage[toml] (>=5.3)"] dev = ["attrs", "pre-commit"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] tests = ["attrs", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] - -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -category = "main" -optional = false -python-versions = "*" +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist"] [[package]] name = "blinker" -version = "1.6.2" +version = "1.7.0" description = "Fast, simple object-to-object and broadcast signaling" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [[package]] name = "certifi" -version = "2023.5.7" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -80,26 +66,26 @@ python-versions = ">=3.6" [[package]] name = "cfgv" -version = "3.3.1" +version = "3.4.0" description = "Validate configuration and produce human readable error messages." category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8" [[package]] name = "cftime" -version = "1.6.2" +version = "1.6.3" description = "Time-handling functionality from netcdf4-python" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -numpy = ">1.13.3" +numpy = {version = ">1.13.3", markers = "python_version < \"3.12.0.rc1\""} [[package]] name = "charset-normalizer" -version = "3.1.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -107,7 +93,7 @@ python-versions = ">=3.7.0" [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" category = "main" optional = false @@ -126,21 +112,21 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7 [[package]] name = "contourpy" -version = "1.1.0" +version = "1.2.0" description = "Python library for calculating contours of 2D quadrilateral grids" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] -numpy = ">=1.16" +numpy = ">=1.20,<2.0" [package.extras] bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx-copybutton"] -mypy = ["contourpy", "docutils-stubs", "mypy (==1.2.0)", "types-pillow"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy", "docutils-stubs", "mypy (==1.6.1)", "types-pillow"] test = ["contourpy", "matplotlib", "pillow"] -test-no-images = ["pytest", "pytest-cov", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "corner" @@ -166,11 +152,15 @@ toml = ["toml"] [[package]] name = "cycler" -version = "0.11.0" +version = "0.12.1" description = "Composable style cycles" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "decorator" @@ -182,7 +172,7 @@ python-versions = ">=3.5" [[package]] name = "distlib" -version = "0.3.6" +version = "0.3.8" description = "Distribution utilities" category = "dev" optional = false @@ -203,43 +193,55 @@ numpy = "*" extras = ["h5py", "scipy"] tests = ["coverage", "pytest", "pytest-cov"] +[[package]] +name = "exceptiongroup" +version = "1.2.0" +description = "Backport of PEP 654 (exception groups)" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "execnet" -version = "1.9.0" +version = "2.0.2" description = "execnet: rapid multi-Python deployment" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.extras] -testing = ["pre-commit"] +testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "executing" -version = "1.2.0" +version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.5" [package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] [[package]] name = "filelock" -version = "3.12.2" +version = "3.13.1" description = "A platform independent file lock." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "flask" -version = "2.3.2" +version = "3.0.2" description = "A simple framework for building complex web applications." category = "main" optional = false @@ -251,7 +253,7 @@ click = ">=8.1.3" importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} itsdangerous = ">=2.1.2" Jinja2 = ">=3.1.2" -Werkzeug = ">=2.3.3" +Werkzeug = ">=3.0.0" [package.extras] async = ["asgiref (>=3.2)"] @@ -284,26 +286,51 @@ python-versions = "*" [[package]] name = "fonttools" -version = "4.40.0" +version = "4.48.1" description = "Tools to manipulate font files" category = "main" optional = false python-versions = ">=3.8" [package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "scipy"] -lxml = ["lxml (>=4.0,<5)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.0.0)"] +unicode = ["unicodedata2 (>=15.1.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +[[package]] +name = "gitdb" +version = "4.0.11" +description = "Git Object Database" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.41" +description = "GitPython is a Python library used to interact with Git repositories" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.extras] +test = ["black", "coverage", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] + [[package]] name = "hypothesis" version = "5.49.0" @@ -335,18 +362,18 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "importlib-resources (>=3.3.0)", "tz [[package]] name = "identify" -version = "2.5.24" +version = "2.5.33" description = "File identification library for Python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] license = ["ukkonen"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false @@ -354,34 +381,34 @@ python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "6.7.0" +version = "7.0.1" description = "Read metadata from Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" -version = "5.12.0" +version = "6.1.1" description = "Read resources from Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -393,39 +420,37 @@ python-versions = ">=3.7" [[package]] name = "ipython" -version = "8.13.0" +version = "8.18.1" description = "IPython: Productive Interactive Computing" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +prompt-toolkit = ">=3.0.41,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test_extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test_extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isodate" @@ -448,23 +473,23 @@ python-versions = ">=3.7" [[package]] name = "jedi" -version = "0.18.2" +version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -parso = ">=0.8.0,<0.9.0" +parso = ">=0.8.3,<0.9.0" [package.extras] docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["attrs", "colorama", "django", "docopt", "pytest (<7.0.0)"] [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." category = "main" optional = false @@ -478,7 +503,7 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "joblib" -version = "1.3.1" +version = "1.3.2" description = "Lightweight pipelining with Python functions" category = "main" optional = false @@ -486,7 +511,7 @@ python-versions = ">=3.7" [[package]] name = "kiwisolver" -version = "1.4.4" +version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" category = "main" optional = false @@ -494,21 +519,21 @@ python-versions = ">=3.7" [[package]] name = "lxml" -version = "4.9.2" +version = "5.1.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +python-versions = ">=3.6" [package.extras] cssselect = ["cssselect (>=0.7)"] html5 = ["html5lib"] htmlsoup = ["beautifulsoup4"] -source = ["Cython (>=0.29.7)"] +source = ["Cython (>=3.0.7)"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false @@ -516,24 +541,23 @@ python-versions = ">=3.7" [[package]] name = "matplotlib" -version = "3.7.1" +version = "3.8.2" description = "Python plotting package" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.0.1" -numpy = ">=1.20" +kiwisolver = ">=1.3.1" +numpy = ">=1.21,<2" packaging = ">=20.0" -pillow = ">=6.2.0" +pillow = ">=8" pyparsing = ">=2.3.1" python-dateutil = ">=2.7" -setuptools_scm = ">=7" [[package]] name = "matplotlib-inline" @@ -574,7 +598,7 @@ python-versions = ">=3.5" [[package]] name = "netcdf4" -version = "1.6.4" +version = "1.6.5" description = "Provides an object-oriented python interface to the netCDF version 4 library" category = "main" optional = false @@ -585,20 +609,23 @@ certifi = "*" cftime = "*" numpy = "*" +[package.extras] +tests = ["cython", "packaging", "pytest"] + [[package]] name = "networkx" -version = "3.1" +version = "3.2.1" description = "Python package for creating and manipulating graphs and networks" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.extras] -default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"] -developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"] -test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] +default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "nodeenv" @@ -618,7 +645,7 @@ python-versions = ">=3.7" [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" category = "main" optional = false @@ -654,7 +681,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pexpect" -version = "4.8.0" +version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." category = "main" optional = false @@ -663,45 +690,64 @@ python-versions = "*" [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -category = "main" -optional = false -python-versions = "*" - [[package]] name = "pillow" -version = "9.5.0" +version = "10.2.0" description = "Python Imaging Library (Fork)" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "pint" +version = "0.23" +description = "Physical quantities module" +category = "main" +optional = false +python-versions = ">=3.9" + +[package.dependencies] +typing-extensions = "*" + +[package.extras] +babel = ["babel (<=2.8)"] +bench = ["pytest", "pytest-codspeed"] +dask = ["dask"] +mip = ["mip (>=1.13)"] +numpy = ["numpy (>=1.19.5)"] +pandas = ["pint-pandas (>=0.3)"] +test = ["pytest", "pytest-benchmark", "pytest-cov", "pytest-mpl", "pytest-subtests"] +testbase = ["pytest", "pytest-benchmark", "pytest-cov", "pytest-subtests"] +uncertainties = ["uncertainties (>=3.1.6)"] +xarray = ["xarray"] [[package]] name = "platformdirs" -version = "3.8.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] dev = ["pre-commit", "tox"] @@ -724,7 +770,7 @@ virtualenv = ">=20.10.0" [[package]] name = "prompt-toolkit" -version = "3.0.38" +version = "3.0.43" description = "Library for building powerful interactive command lines in Python" category = "main" optional = false @@ -780,7 +826,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pygments" -version = "2.15.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false @@ -788,10 +834,11 @@ python-versions = ">=3.7" [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyparsing" -version = "3.1.0" +version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "main" optional = false @@ -880,7 +927,7 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.3" +version = "2024.1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -888,7 +935,7 @@ python-versions = "*" [[package]] name = "pyyaml" -version = "6.0" +version = "6.0.1" description = "YAML parser and emitter for Python" category = "dev" optional = false @@ -896,11 +943,11 @@ python-versions = ">=3.6" [[package]] name = "rdflib" -version = "6.3.2" +version = "7.0.0" description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." category = "main" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.8.1,<4.0.0" [package.dependencies] isodate = ">=0.6.0,<0.7.0" @@ -950,23 +997,23 @@ ldap = ["ldap3"] [[package]] name = "scikit-learn" -version = "1.3.0" +version = "1.4.0" description = "A set of python modules for machine learning and data mining" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] -joblib = ">=1.1.1" -numpy = ">=1.17.3" -scipy = ">=1.5.0" +joblib = ">=1.2.0" +numpy = ">=1.19.5" +scipy = ">=1.6.0" threadpoolctl = ">=2.0.0" [package.extras] -benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] -tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"] +benchmark = ["matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "pandas (>=1.1.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.3.4)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.15.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.3.4)", "pandas (>=1.1.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.17.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=23.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.1.5)", "polars (>=0.19.12)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pyarrow (>=12.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.17.2)"] [[package]] name = "scipy" @@ -984,23 +1031,6 @@ dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] -[[package]] -name = "setuptools-scm" -version = "7.1.0" -description = "the blessed package to manage your versions by scm tags" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -packaging = ">=20.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} -typing-extensions = "*" - -[package.extras] -test = ["pytest (>=6.2)", "virtualenv (>20)"] -toml = ["setuptools (>=42)"] - [[package]] name = "six" version = "1.16.0" @@ -1009,6 +1039,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "smmap" +version = "5.0.1" +description = "A pure Python implementation of a sliding window memory map manager" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "sortedcontainers" version = "2.4.0" @@ -1019,7 +1057,7 @@ python-versions = "*" [[package]] name = "stack-data" -version = "0.6.2" +version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" category = "main" optional = false @@ -1035,11 +1073,11 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "threadpoolctl" -version = "3.1.0" +version = "3.2.0" description = "threadpoolctl" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" [[package]] name = "toml" @@ -1053,13 +1091,13 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" [[package]] name = "tqdm" -version = "4.65.0" +version = "4.66.1" description = "Fast, Extensible Progress Meter" category = "main" optional = false @@ -1069,22 +1107,22 @@ python-versions = ">=3.7" colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["py-make (>=0.1.0)", "twine", "wheel"] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] [[package]] name = "traitlets" -version = "5.9.0" +version = "5.14.1" description = "Traitlets Python configuration system" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] [[package]] name = "types-setuptools" @@ -1096,46 +1134,46 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "4.7.0" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [[package]] name = "urllib3" -version = "2.0.3" +version = "2.2.0" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.23.1" +version = "20.25.0" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = ">=3.7" [package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.12,<4" -platformdirs = ">=3.5.1,<4" +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.3.1)", "pytest-env (>=0.8.1)", "pytest-freezer (>=0.4.6)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=67.8)", "time-machine (>=2.9)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" category = "main" optional = false @@ -1143,7 +1181,7 @@ python-versions = "*" [[package]] name = "werkzeug" -version = "2.3.6" +version = "3.0.1" description = "The comprehensive WSGI web application library." category = "main" optional = false @@ -1177,205 +1215,217 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] [[package]] name = "zipp" -version = "3.15.0" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-o", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-o", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [metadata] lock-version = "1.1" -python-versions = ">=3.8,<3.11" -content-hash = "27cf16cddd6c0208dbd532d34116d912270318f680df17d1026f89a9fabb4500" +python-versions = ">=3.9,<3.11" +content-hash = "900b71fe9062e8768a92fb7273aad6661d52ca65a50fd7fbeb22603388bf3e7c" [metadata.files] aniso8601 = [ {file = "aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, {file = "aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, ] -appnope = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] asttokens = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, ] atomicwrites = [ {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] attrs = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] blinker = [ - {file = "blinker-1.6.2-py3-none-any.whl", hash = "sha256:c3d739772abb7bc2860abf5f2ec284223d9ad5c76da018234f6f50d6f31ab1f0"}, - {file = "blinker-1.6.2.tar.gz", hash = "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213"}, + {file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"}, + {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, ] certifi = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] cfgv = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] cftime = [ - {file = "cftime-1.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4d2a1920f0aad663f25700b30621ff64af373499e52b544da1148dd8c09409a"}, - {file = "cftime-1.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ba7909a0cd4adcb16797d8d6ab2767e7ddb980b2bf9dbabfc71b3bdd94f072b"}, - {file = "cftime-1.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acb294fdb80e33545ae54b4421df35c4e578708a5ffce1c00408b2294e70ecef"}, - {file = "cftime-1.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:2abdac6ca5b8b6102f319122546739dfc42406b816c16f2a98a8f0cd406d3bf0"}, - {file = "cftime-1.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eb7f8cd0996640b83020133b5ef6b97fc9216c3129eaeeaca361abdff5d82166"}, - {file = "cftime-1.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8d49d69c64cee2c175478eed84c3a57fce083da4ceebce16440f72be561a8489"}, - {file = "cftime-1.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:455cec3627e6ca8694b0d9201da6581eb4381b58389f1fbcb51a14fa0e2b3d94"}, - {file = "cftime-1.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:29c18601abea0fd160fbe423e05c7a56fe1d38dd250a6b010de499a132d3fe18"}, - {file = "cftime-1.6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:afb5b38b51b8bc02f1656a9f15c52b0b20a3999adbe1ab9ac57f926e0065b48a"}, - {file = "cftime-1.6.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aedfb7a783d19d7a30cb41951310f3bfe98f9f21fffc723c8af08a11962b0b17"}, - {file = "cftime-1.6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3042048324b4d6a1066c978ec78101effdd84320e8862bfdbf8122d7ad7588ec"}, - {file = "cftime-1.6.2-cp37-none-win_amd64.whl", hash = "sha256:ee70fa069802652cf534de1dd3fc590b7d22d4127447bf96ac9849abcdadadf1"}, - {file = "cftime-1.6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:93f00f454329c1f2588ebca2650e8edf7607d6189dbdcc81b5f3be2080155cc4"}, - {file = "cftime-1.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e83db2fdda900eb154a9f79dfb665ac6190781c61d2e18151996de5ee7ffd8a2"}, - {file = "cftime-1.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56d0242fc4990584b265622622b25bb262a178097711d2d95e53ef52a9d23e7e"}, - {file = "cftime-1.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:055d5d60a756c6c1857cf84d77655bb707057bb6c4a4fbb104a550e76c40aad9"}, - {file = "cftime-1.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0955e1f3e1c09a9e0296b50f135ff9719cb2466f81c8ad4a10ef06fa394de984"}, - {file = "cftime-1.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:07fdef2f75a0f0952b0376fa4cd08ef8a1dad3b963976ac07517811d434936b7"}, - {file = "cftime-1.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:892d5dc38f8b998c83a2a01f131e63896d020586de473e1878f9e85acc70ad44"}, - {file = "cftime-1.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86fe550b94525c327578a90b2e13418ca5ba6c636d5efe3edec310e631757eea"}, - {file = "cftime-1.6.2.tar.gz", hash = "sha256:8614c00fb8a5046de304fdd86dbd224f99408185d7b245ac6628d0276596e6d2"}, + {file = "cftime-1.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b62d42546fa5c914dfea5b15a9aaed2087ea1211cc36d08c374502ef95892038"}, + {file = "cftime-1.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb6dd70b2ccabfe1a14b7fbb0bbdce0418e71697094373c0d573c880790fa291"}, + {file = "cftime-1.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9878bfd8c1c3f24184ecbd528f739ba46ebaceaf1c8a24d348d7befb117a285"}, + {file = "cftime-1.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:3cf6e216a4c06f9a628cdf8e9c9d5e8097fb3eb02dd087dd14ab3b18478a7271"}, + {file = "cftime-1.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d2c01456d9d7b46aa710a41d1c711a50d5ea259aff4a987d0e973d1093bc922"}, + {file = "cftime-1.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80eb1170ce1639016f55760847f4aadd04b0312496c5bac2797e930914bba48d"}, + {file = "cftime-1.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d87dadd0824262bdd7493babd2a44447da0a22175ded8ae9e060a3aebec7c5d7"}, + {file = "cftime-1.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:0a38eb9f5c733a23e1714bd3ef2762ed5acee34f127670f8fb4ad6464946f6b3"}, + {file = "cftime-1.6.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2d113a01ab924445e61d65c26bbd95bc08e4a22878d3b947064bba056c884c4a"}, + {file = "cftime-1.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f11685663a6af97418908060492a07663c16d42519c139ca03c2ffb1377fd25"}, + {file = "cftime-1.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a98abb1d46d118e52b0611ce668a0b714b407be26177ef0581ecf5e95f894725"}, + {file = "cftime-1.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:4d6fbd5f41b322cfa7b0ac3aaadeceb4450100a164b5bccbbb9e7c5048489a88"}, + {file = "cftime-1.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bedb577bc8b8f3f10f5336c0792e5dae88605781890f50f36b45bb46907968e8"}, + {file = "cftime-1.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:022dabf1610cdd04a693e730fa8f71d307059717f29dba921e7486e553412bb4"}, + {file = "cftime-1.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbf782ab4ac0605bdec2b941952c897595613203942b7f8c2fccd17efa5147df"}, + {file = "cftime-1.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:9eb177a02db7cd84aa6962278e4bd2d3106a545de82e6aacd9404f1e153661db"}, + {file = "cftime-1.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b86be8c2f254147be4ba88f12099466dde457a4a3a21de6c69d52a7224c13ae"}, + {file = "cftime-1.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:523b9a6bf03f5e36407979e248381d0fcab2d225b915bbde77d00c6dde192b90"}, + {file = "cftime-1.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a14d2c7d22fd2a6dfa6ad563283b6d6679f1df95e0ed8d14b8f284dad402887"}, + {file = "cftime-1.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:d9b00c2844c7a1701d8ede5336b6321dfee256ceab81a34a1aff0483d56891a6"}, + {file = "cftime-1.6.3.tar.gz", hash = "sha256:d0a6b29f72a13f08e008b9becff247cc75c84acb213332ede18879c5b6aa4dfd"}, ] charset-normalizer = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] click = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] colorama = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] contourpy = [ - {file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc"}, - {file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"}, - {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"}, - {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"}, - {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"}, - {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"}, - {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"}, - {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"}, - {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"}, - {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"}, - {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"}, - {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"}, - {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"}, - {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"}, - {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"}, - {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"}, - {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"}, - {file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104"}, - {file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f"}, - {file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21"}, + {file = "contourpy-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8"}, + {file = "contourpy-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9"}, + {file = "contourpy-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa"}, + {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9"}, + {file = "contourpy-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab"}, + {file = "contourpy-1.2.0-cp310-cp310-win32.whl", hash = "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488"}, + {file = "contourpy-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41"}, + {file = "contourpy-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727"}, + {file = "contourpy-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e"}, + {file = "contourpy-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686"}, + {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286"}, + {file = "contourpy-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95"}, + {file = "contourpy-1.2.0-cp311-cp311-win32.whl", hash = "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6"}, + {file = "contourpy-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de"}, + {file = "contourpy-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0"}, + {file = "contourpy-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399"}, + {file = "contourpy-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0"}, + {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0"}, + {file = "contourpy-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431"}, + {file = "contourpy-1.2.0-cp312-cp312-win32.whl", hash = "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f"}, + {file = "contourpy-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9"}, + {file = "contourpy-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5fd1810973a375ca0e097dee059c407913ba35723b111df75671a1976efa04bc"}, + {file = "contourpy-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:999c71939aad2780f003979b25ac5b8f2df651dac7b38fb8ce6c46ba5abe6ae9"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7caf9b241464c404613512d5594a6e2ff0cc9cb5615c9475cc1d9b514218ae8"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:266270c6f6608340f6c9836a0fb9b367be61dde0c9a9a18d5ece97774105ff3e"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbd50d0a0539ae2e96e537553aff6d02c10ed165ef40c65b0e27e744a0f10af8"}, + {file = "contourpy-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11f8d2554e52f459918f7b8e6aa20ec2a3bce35ce95c1f0ef4ba36fbda306df5"}, + {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ce96dd400486e80ac7d195b2d800b03e3e6a787e2a522bfb83755938465a819e"}, + {file = "contourpy-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d3364b999c62f539cd403f8123ae426da946e142312a514162adb2addd8d808"}, + {file = "contourpy-1.2.0-cp39-cp39-win32.whl", hash = "sha256:1c88dfb9e0c77612febebb6ac69d44a8d81e3dc60f993215425b62c1161353f4"}, + {file = "contourpy-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:78e6ad33cf2e2e80c5dfaaa0beec3d61face0fb650557100ee36db808bfa6843"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be16975d94c320432657ad2402f6760990cb640c161ae6da1363051805fa8108"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b95a225d4948b26a28c08307a60ac00fb8671b14f2047fc5476613252a129776"}, + {file = "contourpy-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d7e03c0f9a4f90dc18d4e77e9ef4ec7b7bbb437f7f675be8e530d65ae6ef956"}, + {file = "contourpy-1.2.0.tar.gz", hash = "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a"}, ] corner = [ {file = "corner-1.0.3.tar.gz", hash = "sha256:8330a1f44ecf98ba6a74b866351758e4ee5d7b9264988165f36757429b4dc4e9"}, @@ -1435,36 +1485,40 @@ coverage = [ {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, ] cycler = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, ] decorator = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] distlib = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, + {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, + {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] emcee = [ {file = "emcee-3.1.4-py2.py3-none-any.whl", hash = "sha256:13d216a96b4f60661839d5f6ec482eda9e86b499502cda2bf6d8cc839ccf3e59"}, {file = "emcee-3.1.4.tar.gz", hash = "sha256:8e0e19dc8bcef9c6d02f860bef8ddc6c876b8878a6ce666943e2c5cfd9317fed"}, ] +exceptiongroup = [ + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, +] execnet = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, + {file = "execnet-2.0.2-py3-none-any.whl", hash = "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41"}, + {file = "execnet-2.0.2.tar.gz", hash = "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"}, ] executing = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, ] filelock = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] flask = [ - {file = "Flask-2.3.2-py3-none-any.whl", hash = "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0"}, - {file = "Flask-2.3.2.tar.gz", hash = "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef"}, + {file = "flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e"}, + {file = "flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d"}, ] flask-restful = [ {file = "Flask-RESTful-0.3.10.tar.gz", hash = "sha256:fe4af2ef0027df8f9b4f797aba20c5566801b6ade995ac63b588abf1a59cec37"}, @@ -1474,68 +1528,84 @@ flatdict = [ {file = "flatdict-4.0.1.tar.gz", hash = "sha256:cd32f08fd31ed21eb09ebc76f06b6bd12046a24f77beb1fd0281917e47f26742"}, ] fonttools = [ - {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b802dcbf9bcff74672f292b2466f6589ab8736ce4dcf36f48eb994c2847c4b30"}, - {file = "fonttools-4.40.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f6e3fa3da923063c286320e728ba2270e49c73386e3a711aa680f4b0747d692"}, - {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fdf60f8a5c6bcce7d024a33f7e4bc7921f5b74e8ea13bccd204f2c8b86f3470"}, - {file = "fonttools-4.40.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91784e21a1a085fac07c6a407564f4a77feb471b5954c9ee55a4f9165151f6c1"}, - {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:05171f3c546f64d78569f10adc0de72561882352cac39ec7439af12304d8d8c0"}, - {file = "fonttools-4.40.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7449e5e306f3a930a8944c85d0cbc8429cba13503372a1a40f23124d6fb09b58"}, - {file = "fonttools-4.40.0-cp310-cp310-win32.whl", hash = "sha256:bae8c13abbc2511e9a855d2142c0ab01178dd66b1a665798f357da0d06253e0d"}, - {file = "fonttools-4.40.0-cp310-cp310-win_amd64.whl", hash = "sha256:425b74a608427499b0e45e433c34ddc350820b6f25b7c8761963a08145157a66"}, - {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:00ab569b2a3e591e00425023ade87e8fef90380c1dde61be7691cb524ca5f743"}, - {file = "fonttools-4.40.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:18ea64ac43e94c9e0c23d7a9475f1026be0e25b10dda8f236fc956188761df97"}, - {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:022c4a16b412293e7f1ce21b8bab7a6f9d12c4ffdf171fdc67122baddb973069"}, - {file = "fonttools-4.40.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:530c5d35109f3e0cea2535742d6a3bc99c0786cf0cbd7bb2dc9212387f0d908c"}, - {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5e00334c66f4e83535384cb5339526d01d02d77f142c23b2f97bd6a4f585497a"}, - {file = "fonttools-4.40.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb52c10fda31159c22c7ed85074e05f8b97da8773ea461706c273e31bcbea836"}, - {file = "fonttools-4.40.0-cp311-cp311-win32.whl", hash = "sha256:6a8d71b9a5c884c72741868e845c0e563c5d83dcaf10bb0ceeec3b4b2eb14c67"}, - {file = "fonttools-4.40.0-cp311-cp311-win_amd64.whl", hash = "sha256:15abb3d055c1b2dff9ce376b6c3db10777cb74b37b52b78f61657634fd348a0d"}, - {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14037c31138fbd21847ad5e5441dfdde003e0a8f3feb5812a1a21fd1c255ffbd"}, - {file = "fonttools-4.40.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:94c915f6716589f78bc00fbc14c5b8de65cfd11ee335d32504f1ef234524cb24"}, - {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37467cee0f32cada2ec08bc16c9c31f9b53ea54b2f5604bf25a1246b5f50593a"}, - {file = "fonttools-4.40.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56d4d85f5374b45b08d2f928517d1e313ea71b4847240398decd0ab3ebbca885"}, - {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8c4305b171b61040b1ee75d18f9baafe58bd3b798d1670078efe2c92436bfb63"}, - {file = "fonttools-4.40.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a954b90d1473c85a22ecf305761d9fd89da93bbd31dae86e7dea436ad2cb5dc9"}, - {file = "fonttools-4.40.0-cp38-cp38-win32.whl", hash = "sha256:1bc4c5b147be8dbc5df9cc8ac5e93ee914ad030fe2a201cc8f02f499db71011d"}, - {file = "fonttools-4.40.0-cp38-cp38-win_amd64.whl", hash = "sha256:8a917828dbfdb1cbe50cf40eeae6fbf9c41aef9e535649ed8f4982b2ef65c091"}, - {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:882983279bf39afe4e945109772c2ffad2be2c90983d6559af8b75c19845a80a"}, - {file = "fonttools-4.40.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c55f1b4109dbc3aeb496677b3e636d55ef46dc078c2a5e3f3db4e90f1c6d2907"}, - {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec468c022d09f1817c691cf884feb1030ef6f1e93e3ea6831b0d8144c06480d1"}, - {file = "fonttools-4.40.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d5adf4ba114f028fc3f5317a221fd8b0f4ef7a2e5524a2b1e0fd891b093791a"}, - {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa83b3f151bc63970f39b2b42a06097c5a22fd7ed9f7ba008e618de4503d3895"}, - {file = "fonttools-4.40.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97d95b8301b62bdece1af943b88bcb3680fd385f88346a4a899ee145913b414a"}, - {file = "fonttools-4.40.0-cp39-cp39-win32.whl", hash = "sha256:1a003608400dd1cca3e089e8c94973c6b51a4fb1ef00ff6d7641617b9242e637"}, - {file = "fonttools-4.40.0-cp39-cp39-win_amd64.whl", hash = "sha256:7961575221e3da0841c75da53833272c520000d76f7f71274dbf43370f8a1065"}, - {file = "fonttools-4.40.0-py3-none-any.whl", hash = "sha256:200729d12461e2038700d31f0d49ad5a7b55855dec7525074979a06b46f88505"}, - {file = "fonttools-4.40.0.tar.gz", hash = "sha256:337b6e83d7ee73c40ea62407f2ce03b07c3459e213b6f332b94a69923b9e1cb9"}, + {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:702ae93058c81f46461dc4b2c79f11d3c3d8fd7296eaf8f75b4ba5bbf813cd5f"}, + {file = "fonttools-4.48.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97f0a49fa6aa2d6205c6f72f4f98b74ef4b9bfdcb06fd78e6fe6c7af4989b63e"}, + {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3260db55f1843e57115256e91247ad9f68cb02a434b51262fe0019e95a98738"}, + {file = "fonttools-4.48.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e740a7602c2bb71e1091269b5dbe89549749a8817dc294b34628ffd8b2bf7124"}, + {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4108b1d247953dd7c90ec8f457a2dec5fceb373485973cc852b14200118a51ee"}, + {file = "fonttools-4.48.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56339ec557f0c342bddd7c175f5e41c45fc21282bee58a86bd9aa322bec715f2"}, + {file = "fonttools-4.48.1-cp310-cp310-win32.whl", hash = "sha256:bff5b38d0e76eb18e0b8abbf35d384e60b3371be92f7be36128ee3e67483b3ec"}, + {file = "fonttools-4.48.1-cp310-cp310-win_amd64.whl", hash = "sha256:f7449493886da6a17472004d3818cc050ba3f4a0aa03fb47972e4fa5578e6703"}, + {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18b35fd1a850ed7233a99bbd6774485271756f717dac8b594958224b54118b61"}, + {file = "fonttools-4.48.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cad5cfd044ea2e306fda44482b3dd32ee47830fa82dfa4679374b41baa294f5f"}, + {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f30e605c7565d0da6f0aec75a30ec372072d016957cd8fc4469721a36ea59b7"}, + {file = "fonttools-4.48.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee76fd81a8571c68841d6ef0da750d5ff08ff2c5f025576473016f16ac3bcf7"}, + {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5057ade278e67923000041e2b195c9ea53e87f227690d499b6a4edd3702f7f01"}, + {file = "fonttools-4.48.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b10633aafc5932995a391ec07eba5e79f52af0003a1735b2306b3dab8a056d48"}, + {file = "fonttools-4.48.1-cp311-cp311-win32.whl", hash = "sha256:0d533f89819f9b3ee2dbedf0fed3825c425850e32bdda24c558563c71be0064e"}, + {file = "fonttools-4.48.1-cp311-cp311-win_amd64.whl", hash = "sha256:d20588466367f05025bb1efdf4e5d498ca6d14bde07b6928b79199c588800f0a"}, + {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0a2417547462e468edf35b32e3dd06a6215ac26aa6316b41e03b8eeaf9f079ea"}, + {file = "fonttools-4.48.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cf5a0cd974f85a80b74785db2d5c3c1fd6cc09a2ba3c837359b2b5da629ee1b0"}, + {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0452fcbfbce752ba596737a7c5ec5cf76bc5f83847ce1781f4f90eab14ece252"}, + {file = "fonttools-4.48.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578c00f93868f64a4102ecc5aa600a03b49162c654676c3fadc33de2ddb88a81"}, + {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:63dc592a16cd08388d8c4c7502b59ac74190b23e16dfc863c69fe1ea74605b68"}, + {file = "fonttools-4.48.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9b58638d8a85e3a1b32ec0a91d9f8171a877b4b81c408d4cb3257d0dee63e092"}, + {file = "fonttools-4.48.1-cp312-cp312-win32.whl", hash = "sha256:d10979ef14a8beaaa32f613bb698743f7241d92f437a3b5e32356dfb9769c65d"}, + {file = "fonttools-4.48.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdfd7557d1bd294a200bd211aa665ca3b02998dcc18f8211a5532da5b8fad5c5"}, + {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3cdb9a92521b81bf717ebccf592bd0292e853244d84115bfb4db0c426de58348"}, + {file = "fonttools-4.48.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b4ec6d42a7555f5ae35f3b805482f0aad0f1baeeef54859492ea3b782959d4a"}, + {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:902e9c4e9928301912f34a6638741b8ae0b64824112b42aaf240e06b735774b1"}, + {file = "fonttools-4.48.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8c8b54bd1420c184a995f980f1a8076f87363e2bb24239ef8c171a369d85a31"}, + {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12ee86abca46193359ea69216b3a724e90c66ab05ab220d39e3fc068c1eb72ac"}, + {file = "fonttools-4.48.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6978bade7b6c0335095bdd0bd97f8f3d590d2877b370f17e03e0865241694eb5"}, + {file = "fonttools-4.48.1-cp38-cp38-win32.whl", hash = "sha256:bcd77f89fc1a6b18428e7a55dde8ef56dae95640293bfb8f4e929929eba5e2a2"}, + {file = "fonttools-4.48.1-cp38-cp38-win_amd64.whl", hash = "sha256:f40441437b039930428e04fb05ac3a132e77458fb57666c808d74a556779e784"}, + {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0d2b01428f7da26f229a5656defc824427b741e454b4e210ad2b25ed6ea2aed4"}, + {file = "fonttools-4.48.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:df48798f9a4fc4c315ab46e17873436c8746f5df6eddd02fad91299b2af7af95"}, + {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2eb4167bde04e172a93cf22c875d8b0cff76a2491f67f5eb069566215302d45d"}, + {file = "fonttools-4.48.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c900508c46274d32d308ae8e82335117f11aaee1f7d369ac16502c9a78930b0a"}, + {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:594206b31c95fcfa65f484385171fabb4ec69f7d2d7f56d27f17db26b7a31814"}, + {file = "fonttools-4.48.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:292922dc356d7f11f5063b4111a8b719efb8faea92a2a88ed296408d449d8c2e"}, + {file = "fonttools-4.48.1-cp39-cp39-win32.whl", hash = "sha256:4709c5bf123ba10eac210d2d5c9027d3f472591d9f1a04262122710fa3d23199"}, + {file = "fonttools-4.48.1-cp39-cp39-win_amd64.whl", hash = "sha256:63c73b9dd56a94a3cbd2f90544b5fca83666948a9e03370888994143b8d7c070"}, + {file = "fonttools-4.48.1-py3-none-any.whl", hash = "sha256:e3e33862fc5261d46d9aae3544acb36203b1a337d00bdb5d3753aae50dac860e"}, + {file = "fonttools-4.48.1.tar.gz", hash = "sha256:8b8a45254218679c7f1127812761e7854ed5c8e34349aebf581e8c9204e7495a"}, +] +gitdb = [ + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, +] +gitpython = [ + {file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"}, + {file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"}, ] hypothesis = [ {file = "hypothesis-5.49.0-py3-none-any.whl", hash = "sha256:e91111f2f01abf2566041c4c86366aa7f08bfd5b3d858cc77a545fcf67df335e"}, {file = "hypothesis-5.49.0.tar.gz", hash = "sha256:36a4d5587c34193125d654b61bf9284e24a227d1edd339c49143378658a10c7d"}, ] identify = [ - {file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"}, - {file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"}, + {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"}, + {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"}, ] idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] importlib-metadata = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, ] importlib-resources = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, + {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, + {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, ] iniconfig = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipython = [ - {file = "ipython-8.13.0-py3-none-any.whl", hash = "sha256:a0a8a30376cee8019c6e22bc0ab4320762f5f5e4d7abed0ea3ee4b95e3982ad5"}, - {file = "ipython-8.13.0.tar.gz", hash = "sha256:8d56026b882958db8eab089654f0c045d1237622313a1506da136fb0cce4270f"}, + {file = "ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397"}, + {file = "ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27"}, ] isodate = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, @@ -1546,260 +1616,294 @@ itsdangerous = [ {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, ] jedi = [ - {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, - {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"}, + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, ] jinja2 = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] joblib = [ - {file = "joblib-1.3.1-py3-none-any.whl", hash = "sha256:89cf0529520e01b3de7ac7b74a8102c90d16d54c64b5dd98cafcd14307fdf915"}, - {file = "joblib-1.3.1.tar.gz", hash = "sha256:1f937906df65329ba98013dc9692fe22a4c5e4a648112de500508b18a21b41e3"}, + {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, + {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, ] kiwisolver = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3"}, + {file = "kiwisolver-1.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa"}, + {file = "kiwisolver-1.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525"}, + {file = "kiwisolver-1.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win32.whl", hash = "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238"}, + {file = "kiwisolver-1.4.5-cp310-cp310-win_amd64.whl", hash = "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90"}, + {file = "kiwisolver-1.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da"}, + {file = "kiwisolver-1.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win32.whl", hash = "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac"}, + {file = "kiwisolver-1.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192"}, + {file = "kiwisolver-1.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228"}, + {file = "kiwisolver-1.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3"}, + {file = "kiwisolver-1.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win32.whl", hash = "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20"}, + {file = "kiwisolver-1.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win32.whl", hash = "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3"}, + {file = "kiwisolver-1.4.5-cp37-cp37m-win_amd64.whl", hash = "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93"}, + {file = "kiwisolver-1.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18"}, + {file = "kiwisolver-1.4.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc"}, + {file = "kiwisolver-1.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win32.whl", hash = "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e"}, + {file = "kiwisolver-1.4.5-cp38-cp38-win_amd64.whl", hash = "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958"}, + {file = "kiwisolver-1.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342"}, + {file = "kiwisolver-1.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win32.whl", hash = "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f"}, + {file = "kiwisolver-1.4.5-cp39-cp39-win_amd64.whl", hash = "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523"}, + {file = "kiwisolver-1.4.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd"}, + {file = "kiwisolver-1.4.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea"}, + {file = "kiwisolver-1.4.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee"}, + {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, ] lxml = [ - {file = "lxml-4.9.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2"}, - {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892"}, - {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a"}, - {file = "lxml-4.9.2-cp27-cp27m-win32.whl", hash = "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de"}, - {file = "lxml-4.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3"}, - {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50"}, - {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975"}, - {file = "lxml-4.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4"}, - {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7"}, - {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184"}, - {file = "lxml-4.9.2-cp310-cp310-win32.whl", hash = "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda"}, - {file = "lxml-4.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380"}, - {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92"}, - {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1"}, - {file = "lxml-4.9.2-cp311-cp311-win32.whl", hash = "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33"}, - {file = "lxml-4.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd"}, - {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0"}, - {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e"}, - {file = "lxml-4.9.2-cp35-cp35m-win32.whl", hash = "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df"}, - {file = "lxml-4.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5"}, - {file = "lxml-4.9.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e"}, - {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74"}, - {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38"}, - {file = "lxml-4.9.2-cp36-cp36m-win32.whl", hash = "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5"}, - {file = "lxml-4.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3"}, - {file = "lxml-4.9.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45"}, - {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e"}, - {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b"}, - {file = "lxml-4.9.2-cp37-cp37m-win32.whl", hash = "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe"}, - {file = "lxml-4.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9"}, - {file = "lxml-4.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c"}, - {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f"}, - {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457"}, - {file = "lxml-4.9.2-cp38-cp38-win32.whl", hash = "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b"}, - {file = "lxml-4.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7"}, - {file = "lxml-4.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5"}, - {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5"}, - {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2"}, - {file = "lxml-4.9.2-cp39-cp39-win32.whl", hash = "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1"}, - {file = "lxml-4.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f"}, - {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c"}, - {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409"}, - {file = "lxml-4.9.2.tar.gz", hash = "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2befa20a13f1a75c751f47e00929fb3433d67eb9923c2c0b364de449121f447c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22b7ee4c35f374e2c20337a95502057964d7e35b996b1c667b5c65c567d2252a"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf8443781533b8d37b295016a4b53c1494fa9a03573c09ca5104550c138d5c05"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, + {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, + {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af8920ce4a55ff41167ddbc20077f5698c2e710ad3353d32a07d3264f3a2021e"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cfced4a069003d8913408e10ca8ed092c49a7f6cefee9bb74b6b3e860683b45"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9e5ac3437746189a9b4121db2a7b86056ac8786b12e88838696899328fc44bb2"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, + {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, + {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16dd953fb719f0ffc5bc067428fc9e88f599e15723a85618c45847c96f11f431"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16018f7099245157564d7148165132c70adb272fb5a17c048ba70d9cc542a1a1"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82cd34f1081ae4ea2ede3d52f71b7be313756e99b4b5f829f89b12da552d3aa3"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19a1bc898ae9f06bccb7c3e1dfd73897ecbbd2c96afe9095a6026016e5ca97b8"}, + {file = "lxml-5.1.0-cp312-cp312-win32.whl", hash = "sha256:13521a321a25c641b9ea127ef478b580b5ec82aa2e9fc076c86169d161798b01"}, + {file = "lxml-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:1ad17c20e3666c035db502c78b86e58ff6b5991906e55bdbef94977700c72623"}, + {file = "lxml-5.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:24ef5a4631c0b6cceaf2dbca21687e29725b7c4e171f33a8f8ce23c12558ded1"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d2900b7f5318bc7ad8631d3d40190b95ef2aa8cc59473b73b294e4a55e9f30f"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:601f4a75797d7a770daed8b42b97cd1bb1ba18bd51a9382077a6a247a12aa38d"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4b68c961b5cc402cbd99cca5eb2547e46ce77260eb705f4d117fd9c3f932b95"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:afd825e30f8d1f521713a5669b63657bcfe5980a916c95855060048b88e1adb7"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:262bc5f512a66b527d026518507e78c2f9c2bd9eb5c8aeeb9f0eb43fcb69dc67"}, + {file = "lxml-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:e856c1c7255c739434489ec9c8aa9cdf5179785d10ff20add308b5d673bed5cd"}, + {file = "lxml-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c7257171bb8d4432fe9d6fdde4d55fdbe663a63636a17f7f9aaba9bcb3153ad7"}, + {file = "lxml-5.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9e240ae0ba96477682aa87899d94ddec1cc7926f9df29b1dd57b39e797d5ab5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96f02ba1bcd330807fc060ed91d1f7a20853da6dd449e5da4b09bfcc08fdcf5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3898ae2b58eeafedfe99e542a17859017d72d7f6a63de0f04f99c2cb125936"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61c5a7edbd7c695e54fca029ceb351fc45cd8860119a0f83e48be44e1c464862"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3aeca824b38ca78d9ee2ab82bd9883083d0492d9d17df065ba3b94e88e4d7ee6"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, + {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, + {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:98f3f020a2b736566c707c8e034945c02aa94e124c24f77ca097c446f81b01f1"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, + {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, + {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8b0c78e7aac24979ef09b7f50da871c2de2def043d468c4b41f512d831e912"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bcf86dfc8ff3e992fed847c077bd875d9e0ba2fa25d859c3a0f0f76f07f0c8d"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:49a9b4af45e8b925e1cd6f3b15bbba2c81e7dba6dce170c677c9cda547411e14"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:280f3edf15c2a967d923bcfb1f8f15337ad36f93525828b40a0f9d6c2ad24890"}, + {file = "lxml-5.1.0-cp39-cp39-win32.whl", hash = "sha256:ed7326563024b6e91fef6b6c7a1a2ff0a71b97793ac33dbbcf38f6005e51ff6e"}, + {file = "lxml-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8d7b4beebb178e9183138f552238f7e6613162a42164233e2bda00cb3afac58f"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9bd0ae7cc2b85320abd5e0abad5ccee5564ed5f0cc90245d2f9a8ef330a8deae"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c1d679df4361408b628f42b26a5d62bd3e9ba7f0c0e7969f925021554755aa"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2ad3a8ce9e8a767131061a22cd28fdffa3cd2dc193f399ff7b81777f3520e372"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:304128394c9c22b6569eba2a6d98392b56fbdfbad58f83ea702530be80d0f9df"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d74fcaf87132ffc0447b3c685a9f862ffb5b43e70ea6beec2fb8057d5d2a1fea"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8cf5877f7ed384dabfdcc37922c3191bf27e55b498fecece9fd5c2c7aaa34c33"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:877efb968c3d7eb2dad540b6cabf2f1d3c0fbf4b2d309a3c141f79c7e0061324"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f14a4fb1c1c402a22e6a341a24c1341b4a3def81b41cd354386dcb795f83897"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:25663d6e99659544ee8fe1b89b1a8c0aaa5e34b103fab124b17fa958c4a324a6"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8b9f19df998761babaa7f09e6bc169294eefafd6149aaa272081cbddc7ba4ca3"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e53d7e6a98b64fe54775d23a7c669763451340c3d44ad5e3a3b48a1efbdc96f"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c3cd1fc1dc7c376c54440aeaaa0dcc803d2126732ff5c6b68ccd619f2e64be4f"}, + {file = "lxml-5.1.0.tar.gz", hash = "sha256:3eea6ed6e6c918e468e693c41ef07f3c3acc310b70ddd9cc72d9ef84bc9564ca"}, ] markupsafe = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] matplotlib = [ - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, - {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, - {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, - {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, - {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, - {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, - {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, - {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, - {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, - {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, + {file = "matplotlib-3.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7"}, + {file = "matplotlib-3.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367"}, + {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18"}, + {file = "matplotlib-3.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31"}, + {file = "matplotlib-3.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a"}, + {file = "matplotlib-3.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a"}, + {file = "matplotlib-3.8.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63"}, + {file = "matplotlib-3.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8"}, + {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6"}, + {file = "matplotlib-3.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788"}, + {file = "matplotlib-3.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0"}, + {file = "matplotlib-3.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717"}, + {file = "matplotlib-3.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627"}, + {file = "matplotlib-3.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4"}, + {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d"}, + {file = "matplotlib-3.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331"}, + {file = "matplotlib-3.8.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213"}, + {file = "matplotlib-3.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630"}, + {file = "matplotlib-3.8.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:deaed9ad4da0b1aea77fe0aa0cebb9ef611c70b3177be936a95e5d01fa05094f"}, + {file = "matplotlib-3.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:172f4d0fbac3383d39164c6caafd3255ce6fa58f08fc392513a0b1d3b89c4f89"}, + {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7d36c2209d9136cd8e02fab1c0ddc185ce79bc914c45054a9f514e44c787917"}, + {file = "matplotlib-3.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5864bdd7da445e4e5e011b199bb67168cdad10b501750367c496420f2ad00843"}, + {file = "matplotlib-3.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ef8345b48e95cee45ff25192ed1f4857273117917a4dcd48e3905619bcd9c9b8"}, + {file = "matplotlib-3.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:7c48d9e221b637c017232e3760ed30b4e8d5dfd081daf327e829bf2a72c731b4"}, + {file = "matplotlib-3.8.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa11b3c6928a1e496c1a79917d51d4cd5d04f8a2e75f21df4949eeefdf697f4b"}, + {file = "matplotlib-3.8.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1095fecf99eeb7384dabad4bf44b965f929a5f6079654b681193edf7169ec20"}, + {file = "matplotlib-3.8.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:bddfb1db89bfaa855912261c805bd0e10218923cc262b9159a49c29a7a1c1afa"}, + {file = "matplotlib-3.8.2.tar.gz", hash = "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1"}, ] matplotlib-inline = [ {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, @@ -1835,37 +1939,37 @@ mypy-extensions = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] netcdf4 = [ - {file = "netCDF4-1.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59eba11eac34f9c7bd209121b26954c71ff69a2eb2838d2ac339b39ea60a95c0"}, - {file = "netCDF4-1.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:541286ce7318033b326da2e4325f08037b561887d5fd25d12c2b0cad74eb1edc"}, - {file = "netCDF4-1.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6620f7962daff02df2fbcbc8f7af53edf21512bc7f5697d846d424a094f96345"}, - {file = "netCDF4-1.6.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2dcf74f7b15ae6105c09df93af22ad61366a288fbb329fdbe3b9606c56c788f5"}, - {file = "netCDF4-1.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b368fc185cac7d8890a8cf1016488cd252a144008144d06a615925b09bf8d67e"}, - {file = "netCDF4-1.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:eb19c51fa090b562be4f87ff736b629ffafc03d7bf1fa10f623f957d49417b4f"}, - {file = "netCDF4-1.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08a7efab50d5a4da6227244e544a74f676b732ccdff2b8a4678174c15a3f8dff"}, - {file = "netCDF4-1.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9b7ad3f66d50970fa1bd5509c52bb8a99740c8a79fafa83bfd0bc7348b6ab5a"}, - {file = "netCDF4-1.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c5cad50d4e6e5a3b35c76862c58393ddf93baa44de98b6e040ac21896145881"}, - {file = "netCDF4-1.6.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c2395c53a37717b1047650e1c9de68a3d69542bb25df5c594e1e14e9480bb18"}, - {file = "netCDF4-1.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:c85f77599c61a88d512d6536e181ff1c01fd16f4740367e4f8e5cacb36500293"}, - {file = "netCDF4-1.6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e3efefdb9fc936503e89ff5b40b33f2c96527bae1e9672a2d369c5f7cb30bbd"}, - {file = "netCDF4-1.6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74a3e720a9764d13d669763c1f3c73f3f719ef181dccecad062440eea03f069e"}, - {file = "netCDF4-1.6.4-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c67bc7fafced3f9370fdef6ce7abe235a771bed7ebe534f4ba3c84d9689dae23"}, - {file = "netCDF4-1.6.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b599a3b5c0d0e3affa70d7954c2b0c4ab7d7bdb52b0e413c811da9725982de33"}, - {file = "netCDF4-1.6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b21d47c23edd02ff83160c8ccc1e4d4946a91d454b246e7f63d7a6d63901707c"}, - {file = "netCDF4-1.6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8eff69acdf250ebaf817cc9bbfb457d241f92f989c7f9cca33eb29985c0f9797"}, - {file = "netCDF4-1.6.4-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d6bcdf27fd611eaec891f4281caf5c56bbad6f5fc245ce3e6dd2dc4fc3fad56"}, - {file = "netCDF4-1.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99a3d476242d489da26f71e318ddd314723ca766f4db11270863a764b107bc3"}, - {file = "netCDF4-1.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:422077c7303cb17cbe8b9ace965cafda1f9d4c9b035809fc5c87091e7ff4d606"}, - {file = "netCDF4-1.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0050e49889c357ae0a73f96e2b9988f250396689b78142de88a39ac8b1e702aa"}, - {file = "netCDF4-1.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a2cd2e2a9da98f1838e1edfeb011b840a434e04d156052b936ffe49f5298126"}, - {file = "netCDF4-1.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:695cd0a40df49b4218350686c44e13b3a4671e53ee33faf7439a89940cbccc68"}, - {file = "netCDF4-1.6.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e582e6e41b27fc3a3296239afe065941bda60118d585df0ad41603f6f962888e"}, - {file = "netCDF4-1.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7b4ab3f0cd28a6685031e8b9be00c3047b4256da576c9de540440d013a31cea"}, - {file = "netCDF4-1.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:1a950b3d8fcffca05e371a4cb64dc76580375588d1fca43b788192f409108ebe"}, - {file = "netCDF4-1.6.4.tar.gz", hash = "sha256:66da6542cbc7a6045cd1d979397dfd5a3f6c880c76d52b8f98bb108c82ee8c6e"}, + {file = "netCDF4-1.6.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d23b97cbde2bf413fadc4697c5c255a0436511c02f811e127e0fb12f5b882a4c"}, + {file = "netCDF4-1.6.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e5edfed673005f47f8d2fbea9c72c382b085dd358ac3c20ca743a563ed7b90e"}, + {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10d2ac9ae1308ca837d86c6dc304ec455a85bdba0f2175e222844a54589168dc"}, + {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a63a2be2f80977ac23bb0aa736c565011fd4639097ce0922e01b0dc38015df2"}, + {file = "netCDF4-1.6.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aaceea2097d292bad398d9f9b4fe403efa7b1568fcfa6faba9b67b1630027f9"}, + {file = "netCDF4-1.6.5-cp310-cp310-win_amd64.whl", hash = "sha256:111357d9e12eb79e8d58bfd91bc6b230d35b17a0ebd8c546d17416e8ceebea49"}, + {file = "netCDF4-1.6.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c5fede0b34c0a02a1b9e84116bfb3fcd2f80124a651d4836e72b785d10e2f15"}, + {file = "netCDF4-1.6.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3de5512b9270aa6472e4f3aa2bf895a7364c1d4f8667ce3b82e8232197d4fec8"}, + {file = "netCDF4-1.6.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b20971a164431f6eca1d24df8aa153db15c2c1b9630e83ccc5cf004e8ac8151d"}, + {file = "netCDF4-1.6.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad1101d538077152b866782e44458356981526bf2ea9cc07930bf28b589c82a7"}, + {file = "netCDF4-1.6.5-cp311-cp311-win_amd64.whl", hash = "sha256:de4dc973fae9e2bbdf42e094125e423a4c25393172a61958314969b055a38889"}, + {file = "netCDF4-1.6.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:19e16c63cdd7c0dbffe284a4a65f226ba1026f476f35cbedd099b4792b395f69"}, + {file = "netCDF4-1.6.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b994afce2ca4073f6b757385a6c0ffec25ecaae2b8821535b303c7cdbf6de42b"}, + {file = "netCDF4-1.6.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0187646e3348e7a8cd654617dda65517df138042c94c2fcc6682ff7c8c6654dc"}, + {file = "netCDF4-1.6.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1ab5dabac27d25fcc82c52dc29a74a6585e865208cce35f4e285df83d3df0b2"}, + {file = "netCDF4-1.6.5-cp312-cp312-win_amd64.whl", hash = "sha256:081e9043ac6160989f60570928eabe803c88ce7df1d3f79f2345dc48f68ef752"}, + {file = "netCDF4-1.6.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b47b22dda5b25ba6291f97634d7ac67b0a843f8ae5c9d9d5813c15364f66d0a"}, + {file = "netCDF4-1.6.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4609dd62d14798c9524327287091875449d68588c128abb768fc0c76c4a28165"}, + {file = "netCDF4-1.6.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2455e9d35fde067e6a6bdc24aa9d44962235a071cec49904d1589e298c23dcd3"}, + {file = "netCDF4-1.6.5-cp38-cp38-win_amd64.whl", hash = "sha256:2c210794d96431d92b5992e46ad8a9f97237bf6d6956f8816978a03dc0fa18c3"}, + {file = "netCDF4-1.6.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:18255b8b283d32d3900092f29c67e53aa25bd8f0dfe7adde59fe782d865a381c"}, + {file = "netCDF4-1.6.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:53050562bac84738bbd121fbbee9593d074579f5d6fdaafcb981abeb5c964225"}, + {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:938c062382406bca9198b16adddd87c09b00521766b138cdfd11c95546eefeb8"}, + {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a8300451d7542d3c4ff1dcccf5fb1c7d44bdd1dc08ec77dab04416caf13cb1f"}, + {file = "netCDF4-1.6.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27db2701feef31201c9b20b04a9579196edc20dfc339ca423c7b81e462d6e14"}, + {file = "netCDF4-1.6.5-cp39-cp39-win_amd64.whl", hash = "sha256:574d7742ab321e5f9f33b5b1296c4ad4e5c469152c17d4fc453d5070e413e596"}, + {file = "netCDF4-1.6.5.tar.gz", hash = "sha256:824881d0aacfde5bd982d6adedd8574259c85553781e7b83e0ce82b890bfa0ef"}, ] networkx = [ - {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, - {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, + {file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"}, + {file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"}, ] nodeenv = [ {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, @@ -1902,8 +2006,8 @@ numpy = [ {file = "numpy-1.21.0.zip", hash = "sha256:e80fe25cba41c124d04c662f33f6364909b985f2eb5998aaa5ae4b9587242cce"}, ] packaging = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] pandas = [ {file = "pandas-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c81b8d91e9ae861eb4406b4e0f8d4dabbc105b9c479b3d1e921fba1d35b5b62a"}, @@ -1931,96 +2035,98 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pexpect = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] -pickleshare = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, ] pillow = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"}, + {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"}, + {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"}, + {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"}, + {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"}, + {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"}, + {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"}, + {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"}, + {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"}, + {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"}, + {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"}, + {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"}, + {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"}, + {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"}, + {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"}, + {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"}, + {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"}, +] +pint = [ + {file = "Pint-0.23-py3-none-any.whl", hash = "sha256:df79b6b5f1beb7ed0cd55d91a0766fc55f972f757a9364e844958c05e8eb66f9"}, + {file = "Pint-0.23.tar.gz", hash = "sha256:e1509b91606dbc52527c600a4ef74ffac12fff70688aff20e9072409346ec9b4"}, ] platformdirs = [ - {file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"}, - {file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] pluggy = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] pre-commit = [ {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, - {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, ] prov = [ {file = "prov-1.5.3-py2.py3-none-any.whl", hash = "sha256:b9c553cc0775bf193eb62de69e2a2b3bab545ab8e6bf597be243e8f0916e1d1b"}, @@ -2039,12 +2145,12 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pygments = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] pyparsing = [ - {file = "pyparsing-3.1.0-py3-none-any.whl", hash = "sha256:d554a96d1a7d3ddaf7183104485bc19fd80543ad6ac5bdb6426719d766fb06c1"}, - {file = "pyparsing-3.1.0.tar.gz", hash = "sha256:edb662d6fe322d6e990b1594b5feaeadf806803359e3d4d42f11e295e588f0ea"}, + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -2067,54 +2173,65 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] pytz = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] rdflib = [ - {file = "rdflib-6.3.2-py3-none-any.whl", hash = "sha256:36b4e74a32aa1e4fa7b8719876fb192f19ecd45ff932ea5ebbd2e417a0247e63"}, - {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, + {file = "rdflib-7.0.0-py3-none-any.whl", hash = "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd"}, + {file = "rdflib-7.0.0.tar.gz", hash = "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae"}, ] requests = [ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, @@ -2125,27 +2242,47 @@ sal = [ {file = "sal-1.2.5.tar.gz", hash = "sha256:369f059fb775dbc320e380d590e04ac5692726f09bb4df08de35bfcad78f5f83"}, ] scikit-learn = [ - {file = "scikit-learn-1.3.0.tar.gz", hash = "sha256:8be549886f5eda46436b6e555b0e4873b4f10aa21c07df45c4bc1735afbccd7a"}, - {file = "scikit_learn-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981287869e576d42c682cf7ca96af0c6ac544ed9316328fd0d9292795c742cf5"}, - {file = "scikit_learn-1.3.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:436aaaae2c916ad16631142488e4c82f4296af2404f480e031d866863425d2a2"}, - {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e28d8fa47a0b30ae1bd7a079519dd852764e31708a7804da6cb6f8b36e3630"}, - {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111"}, - {file = "scikit_learn-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:552fd1b6ee22900cf1780d7386a554bb96949e9a359999177cf30211e6b20df6"}, - {file = "scikit_learn-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79970a6d759eb00a62266a31e2637d07d2d28446fca8079cf9afa7c07b0427f8"}, - {file = "scikit_learn-1.3.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:850a00b559e636b23901aabbe79b73dc604b4e4248ba9e2d6e72f95063765603"}, - {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee04835fb016e8062ee9fe9074aef9b82e430504e420bff51e3e5fffe72750ca"}, - {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d953531f5d9f00c90c34fa3b7d7cfb43ecff4c605dac9e4255a20b114a27369"}, - {file = "scikit_learn-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:151ac2bf65ccf363664a689b8beafc9e6aae36263db114b4ca06fbbbf827444a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a885a9edc9c0a341cab27ec4f8a6c58b35f3d449c9d2503a6fd23e06bbd4f6a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9877af9c6d1b15486e18a94101b742e9d0d2f343d35a634e337411ddb57783f3"}, - {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c470f53cea065ff3d588050955c492793bb50c19a92923490d18fcb637f6383a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6e2d7389542eae01077a1ee0318c4fec20c66c957f45c7aac0c6eb0fe3c612"}, - {file = "scikit_learn-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:3a11936adbc379a6061ea32fa03338d4ca7248d86dd507c81e13af428a5bc1db"}, - {file = "scikit_learn-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:998d38fcec96584deee1e79cd127469b3ad6fefd1ea6c2dfc54e8db367eb396b"}, - {file = "scikit_learn-1.3.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ded35e810438a527e17623ac6deae3b360134345b7c598175ab7741720d7ffa7"}, - {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8102d5036e28d08ab47166b48c8d5e5810704daecf3a476a4282d562be9a28"}, - {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7617164951c422747e7c32be4afa15d75ad8044f42e7d70d3e2e0429a50e6718"}, - {file = "scikit_learn-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d54fb9e6038284548072df22fd34777e434153f7ffac72c8596f2d6987110dd"}, + {file = "scikit-learn-1.4.0.tar.gz", hash = "sha256:d4373c984eba20e393216edd51a3e3eede56cbe93d4247516d205643c3b93121"}, + {file = "scikit_learn-1.4.0-1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fce93a7473e2f4ee4cc280210968288d6a7d7ad8dc6fa7bb7892145e407085f9"}, + {file = "scikit_learn-1.4.0-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d77df3d1e15fc37a9329999979fa7868ba8655dbab21fe97fc7ddabac9e08cc7"}, + {file = "scikit_learn-1.4.0-1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2404659fedec40eeafa310cd14d613e564d13dbf8f3c752d31c095195ec05de6"}, + {file = "scikit_learn-1.4.0-1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e98632da8f6410e6fb6bf66937712c949b4010600ccd3f22a5388a83e610cc3c"}, + {file = "scikit_learn-1.4.0-1-cp310-cp310-win_amd64.whl", hash = "sha256:11b3b140f70fbc9f6a08884631ae8dd60a4bb2d7d6d1de92738ea42b740d8992"}, + {file = "scikit_learn-1.4.0-1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8341eabdc754d5ab91641a7763243845e96b6d68e03e472531e88a4f1b09f21"}, + {file = "scikit_learn-1.4.0-1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d1f6bce875ac2bb6b52514f67c185c564ccd299a05b65b7bab091a4c13dde12d"}, + {file = "scikit_learn-1.4.0-1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c408b46b2fd61952d519ea1af2f8f0a7a703e1433923ab1704c4131520b2083b"}, + {file = "scikit_learn-1.4.0-1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b465dd1dcd237b7b1dcd1a9048ccbf70a98c659474324fa708464c3a2533fad"}, + {file = "scikit_learn-1.4.0-1-cp311-cp311-win_amd64.whl", hash = "sha256:0db8e22c42f7980fe5eb22069b1f84c48966f3e0d23a01afde5999e3987a2501"}, + {file = "scikit_learn-1.4.0-1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7eef6ea2ed289af40e88c0be9f7704ca8b5de18508a06897c3fe21e0905efdf"}, + {file = "scikit_learn-1.4.0-1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:349669b01435bc4dbf25c6410b0892073befdaec52637d1a1d1ff53865dc8db3"}, + {file = "scikit_learn-1.4.0-1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d439c584e58434d0350701bd33f6c10b309e851fccaf41c121aed55f6851d8cf"}, + {file = "scikit_learn-1.4.0-1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0e2427d9ef46477625ab9b55c1882844fe6fc500f418c3f8e650200182457bc"}, + {file = "scikit_learn-1.4.0-1-cp312-cp312-win_amd64.whl", hash = "sha256:d3d75343940e7bf9b85c830c93d34039fa015eeb341c5c0b4cd7a90dadfe00d4"}, + {file = "scikit_learn-1.4.0-1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:76986d22e884ab062b1beecdd92379656e9d3789ecc1f9870923c178de55f9fe"}, + {file = "scikit_learn-1.4.0-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:e22446ad89f1cb7657f0d849dcdc345b48e2d10afa3daf2925fdb740f85b714c"}, + {file = "scikit_learn-1.4.0-1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74812c9eabb265be69d738a8ea8d4884917a59637fcbf88a5f0e9020498bc6b3"}, + {file = "scikit_learn-1.4.0-1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad2a63e0dd386b92da3270887a29b308af4d7c750d8c4995dfd9a4798691bcc"}, + {file = "scikit_learn-1.4.0-1-cp39-cp39-win_amd64.whl", hash = "sha256:53b9e29177897c37e2ff9d4ba6ca12fdb156e22523e463db05def303f5c72b5c"}, + {file = "scikit_learn-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb8f044a8f5962613ce1feb4351d66f8d784bd072d36393582f351859b065f7d"}, + {file = "scikit_learn-1.4.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:a6372c90bbf302387792108379f1ec77719c1618d88496d0df30cb8e370b4661"}, + {file = "scikit_learn-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:785ce3c352bf697adfda357c3922c94517a9376002971bc5ea50896144bc8916"}, + {file = "scikit_learn-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0aba2a20d89936d6e72d95d05e3bf1db55bca5c5920926ad7b92c34f5e7d3bbe"}, + {file = "scikit_learn-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:2bac5d56b992f8f06816f2cd321eb86071c6f6d44bb4b1cb3d626525820d754b"}, + {file = "scikit_learn-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27ae4b0f1b2c77107c096a7e05b33458354107b47775428d1f11b23e30a73e8a"}, + {file = "scikit_learn-1.4.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:5c5c62ffb52c3ffb755eb21fa74cc2cbf2c521bd53f5c04eaa10011dbecf5f80"}, + {file = "scikit_learn-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f0d2018ac6fa055dab65fe8a485967990d33c672d55bc254c56c35287b02fab"}, + {file = "scikit_learn-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a8918c415c4b4bf1d60c38d32958849a9191c2428ab35d30b78354085c7c7a"}, + {file = "scikit_learn-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:80a21de63275f8bcd7877b3e781679d2ff1eddfed515a599f95b2502a3283d42"}, + {file = "scikit_learn-1.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0f33bbafb310c26b81c4d41ecaebdbc1f63498a3f13461d50ed9a2e8f24d28e4"}, + {file = "scikit_learn-1.4.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:8b6ac1442ec714b4911e5aef8afd82c691b5c88b525ea58299d455acc4e8dcec"}, + {file = "scikit_learn-1.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05fc5915b716c6cc60a438c250108e9a9445b522975ed37e416d5ea4f9a63381"}, + {file = "scikit_learn-1.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:842b7d6989f3c574685e18da6f91223eb32301d0f93903dd399894250835a6f7"}, + {file = "scikit_learn-1.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:88bcb586fdff865372df1bc6be88bb7e6f9e0aa080dab9f54f5cac7eca8e2b6b"}, + {file = "scikit_learn-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f77674647dd31f56cb12ed13ed25b6ed43a056fffef051715022d2ebffd7a7d1"}, + {file = "scikit_learn-1.4.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:833999872e2920ce00f3a50839946bdac7539454e200eb6db54898a41f4bfd43"}, + {file = "scikit_learn-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:970ec697accaef10fb4f51763f3a7b1250f9f0553cf05514d0e94905322a0172"}, + {file = "scikit_learn-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923d778f378ebacca2c672ab1740e5a413e437fb45ab45ab02578f8b689e5d43"}, + {file = "scikit_learn-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d041bc95006b545b59e458399e3175ab11ca7a03dc9a74a573ac891f5df1489"}, ] scipy = [ {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, @@ -2170,25 +2307,25 @@ scipy = [ {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, ] -setuptools-scm = [ - {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, - {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +smmap = [ + {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, + {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, +] sortedcontainers = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] stack-data = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, ] threadpoolctl = [ - {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, - {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, + {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"}, + {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"}, ] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -2199,42 +2336,42 @@ tomli = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] tqdm = [ - {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, - {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, + {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, + {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, ] traitlets = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, + {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, + {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, ] types-setuptools = [ {file = "types-setuptools-57.4.18.tar.gz", hash = "sha256:8ee03d823fe7fda0bd35faeae33d35cb5c25b497263e6a58b34c4cfd05f40bcf"}, {file = "types_setuptools-57.4.18-py3-none-any.whl", hash = "sha256:9660b8774b12cd61b448e2fd87a667c02e7ec13ce9f15171f1d49a4654c4df6a"}, ] typing-extensions = [ - {file = "typing_extensions-4.7.0-py3-none-any.whl", hash = "sha256:5d8c9dac95c27d20df12fb1d97b9793ab8b2af8a3a525e68c80e21060c161771"}, - {file = "typing_extensions-4.7.0.tar.gz", hash = "sha256:935ccf31549830cda708b42289d44b6f74084d616a00be651601a4f968e77c82"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] urllib3 = [ - {file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"}, - {file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"}, + {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"}, + {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"}, ] virtualenv = [ - {file = "virtualenv-20.23.1-py3-none-any.whl", hash = "sha256:34da10f14fea9be20e0fd7f04aba9732f84e593dac291b757ce42e3368a39419"}, - {file = "virtualenv-20.23.1.tar.gz", hash = "sha256:8ff19a38c1021c742148edc4f81cb43d7f8c6816d2ede2ab72af5b84c749ade1"}, + {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"}, + {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"}, ] wcwidth = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, ] werkzeug = [ - {file = "Werkzeug-2.3.6-py3-none-any.whl", hash = "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890"}, - {file = "Werkzeug-2.3.6.tar.gz", hash = "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330"}, + {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, + {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, ] xarray = [ {file = "xarray-0.16.2-py3-none-any.whl", hash = "sha256:88d0f80145999443730f87c7575e426d377f0b62677d915f21059cc364b4a1e1"}, {file = "xarray-0.16.2.tar.gz", hash = "sha256:38e8439d6c91bcd5b7c0fca349daf8e0643ac68850c987262d53526e9d7d01e4"}, ] zipp = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] diff --git a/pyproject.toml b/pyproject.toml index c455fda5..218013e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ include = [".git", "indica/git_version"] [tool.poetry.dependencies] corner = "^1.0" pandas = "1.3.0" -python = ">=3.8,<3.11" +python = ">=3.9,<3.11" prov = "^1.5.3" netCDF4 = "^1.5.4" numpy = "1.21.0" @@ -55,6 +55,8 @@ emcee = "^3.1.4" flatdict = "^4.0.1" tqdm = "^4.65.0" scikit-learn = "^1.3.0" +Pint = "^0.23" +GitPython = "^3.1.41" [tool.poetry.dev-dependencies] click = "^8.0.0" diff --git a/tests/integration/models/test_diagnostic_models.py b/tests/integration/models/test_diagnostic_models.py index e1215725..35419053 100644 --- a/tests/integration/models/test_diagnostic_models.py +++ b/tests/integration/models/test_diagnostic_models.py @@ -110,8 +110,8 @@ def test_helike_timepoint_fail(self): def test_helike_timepoint_pass(self): self._test_timepoint_pass("helike_spectroscopy") - def test_helike_interpolation(self): - self._test_time_interpolation("helike_spectroscopy") + # def test_helike_interpolation(self): + # self._test_time_interpolation("helike_spectroscopy") def test_equil_recon_timepoint_fail(self): self._test_timepoint_fail("equilibrium_reconstruction") diff --git a/tests/integration/workflows/test_bayes_workflow.py b/tests/integration/workflows/test_bayes_workflow.py new file mode 100644 index 00000000..c8a5596d --- /dev/null +++ b/tests/integration/workflows/test_bayes_workflow.py @@ -0,0 +1,120 @@ +from indica.workflows.bayes_workflow import BayesBBSettings +from indica.workflows.bayes_workflow import BayesWorkflow +from indica.workflows.bayes_workflow import DEFAULT_PRIORS +from indica.workflows.bayes_workflow import DEFAULT_PROFILE_PARAMS +from indica.workflows.bayes_workflow import EmceeOptimiser +from indica.workflows.bayes_workflow import MockData +from indica.workflows.bayes_workflow import ModelContext +from indica.workflows.bayes_workflow import ModelSettings +from indica.workflows.bayes_workflow import OptimiserEmceeSettings +from indica.workflows.bayes_workflow import PlasmaContext +from indica.workflows.bayes_workflow import PlasmaSettings +from indica.workflows.bayes_workflow import ReaderSettings + + +class TestBayesWorkflow: + def setup_class(self): + self.diagnostics = ["cxff_tws_c", "cxff_pi"] + self.opt_params = [ + "Ti_prof.y0", + # "Ti_prof.peaking", + # "Ti_prof.wped", + # "Ti_prof.wcenter", + ] + self.opt_quant = ["cxff_tws_c.ti", "cxff_pi.ti"] + + self.pulse = None + self.tstart = 0.01 + self.tend = 0.02 + self.dt = 0.01 + + self.plasma_settings = PlasmaSettings( + main_ion="h", + impurities=("ar", "c"), + impurity_concentration=(0.001, 0.04), + n_rad=10, + ) + + self.bayes_settings = BayesBBSettings( + diagnostics=self.diagnostics, + param_names=self.opt_params, + opt_quantity=self.opt_quant, + priors=DEFAULT_PRIORS, + ) + + self.data_settings = ReaderSettings(filters={}, revisions={}) + + self.model_settings = ModelSettings(call_kwargs={"xrcs": {"pixel_offset": 0.0}}) + + self.optimiser_settings = OptimiserEmceeSettings( + param_names=self.bayes_settings.param_names, + nwalkers=5, + iterations=2, + sample_method="random", + starting_samples=2, + burn_frac=0, + stopping_criteria="mode", + stopping_criteria_factor=0.005, + stopping_criteria_debug=True, + priors=self.bayes_settings.priors, + ) + + def test_workflow_runs(self): + + data_context = MockData( + pulse=self.pulse, + diagnostics=self.diagnostics, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + reader_settings=self.data_settings, + ) + data_context.read_data() + + plasma_context = PlasmaContext( + plasma_settings=self.plasma_settings, profile_params=DEFAULT_PROFILE_PARAMS + ) + plasma_context.init_plasma( + data_context.equilibrium, self.tstart, self.tend, self.dt + ) + plasma_context.save_phantom_profiles(phantoms=data_context.phantoms) + + model_context = ModelContext( + diagnostics=self.diagnostics, + plasma_context=plasma_context, + equilibrium=data_context.equilibrium, + transforms=data_context.transforms, + model_settings=self.model_settings, + ) + model_context.update_model_kwargs(data_context.binned_data) + model_context.init_models() + data_context.process_data( + model_context._build_bckc, + ) + + optimiser_context = EmceeOptimiser(optimiser_settings=self.optimiser_settings) + + workflow = BayesWorkflow( + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + blackbox_settings=self.bayes_settings, + data_context=data_context, + optimiser_context=optimiser_context, + plasma_context=plasma_context, + model_context=model_context, + ) + workflow( + pulse_to_write=43000001, + run="TEST", + mds_write=False, + plot=False, + filepath="./results/test/", + ) + + +if __name__ == "__main__": + + test = TestBayesWorkflow() + test.setup_class() + test.test_workflow_runs() diff --git a/tests/unit/workflows/test_bayes_workflow.py b/tests/unit/workflows/test_bayes_workflow.py new file mode 100644 index 00000000..6bd2bab5 --- /dev/null +++ b/tests/unit/workflows/test_bayes_workflow.py @@ -0,0 +1,163 @@ +from unittest.mock import MagicMock + +from indica.workflows.bayes_workflow import BayesBBSettings +from indica.workflows.bayes_workflow import BayesWorkflow +from indica.workflows.bayes_workflow import DEFAULT_PRIORS +from indica.workflows.bayes_workflow import DEFAULT_PROFILE_PARAMS +from indica.workflows.bayes_workflow import EmceeOptimiser +from indica.workflows.bayes_workflow import MockData +from indica.workflows.bayes_workflow import ModelContext +from indica.workflows.bayes_workflow import ModelSettings +from indica.workflows.bayes_workflow import OptimiserEmceeSettings +from indica.workflows.bayes_workflow import PlasmaContext +from indica.workflows.bayes_workflow import PlasmaSettings +from indica.workflows.bayes_workflow import ReaderSettings + + +class TestBayesWorkflow: + def setup_class(self): + self.diagnostics = ["cxff_tws_c", "cxff_pi"] + self.opt_params = [ + "Ti_prof.y0", + "Ti_prof.peaking", + "Ti_prof.wped", + "Ti_prof.wcenter", + ] + self.opt_quant = ["cxff_tws_c.ti", "cxff_pi.ti"] + + self.pulse = None + self.tstart = 0.01 + self.tend = 0.10 + self.dt = 0.01 + self.phantoms = True + + self.plasma_settings = PlasmaSettings( + main_ion="h", + impurities=("ar", "c"), + impurity_concentration=(0.001, 0.04), + n_rad=10, + ) + + self.bayes_settings = BayesBBSettings( + diagnostics=self.diagnostics, + param_names=self.opt_params, + opt_quantity=self.opt_quant, + priors=DEFAULT_PRIORS, + ) + + self.data_settings = ReaderSettings(filters={}, revisions={}) + + self.model_settings = ModelSettings(call_kwargs={"xrcs": {"pixel_offset": 0.0}}) + + self.optimiser_settings = OptimiserEmceeSettings( + param_names=self.bayes_settings.param_names, + nwalkers=10, + iterations=10, + sample_method="random", + starting_samples=10, + burn_frac=0.05, + stopping_criteria="mode", + stopping_criteria_factor=0.005, + stopping_criteria_debug=True, + priors=self.bayes_settings.priors, + ) + + self.data_context = MagicMock( + pulse=self.pulse, + diagnostics=self.diagnostics, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + reader_settings=self.data_settings, + ) + self.data_context.opt_data.keys = MagicMock(return_value=self.opt_quant) + + self.plasma_context = MagicMock( + plasma_settings=self.plasma_settings, profile_params=DEFAULT_PROFILE_PARAMS + ) + + self.model_context = MagicMock( + diagnostics=self.diagnostics, + plasma_context=self.plasma_context, + equilibrium=self.data_context.equilibrium, + transforms=self.data_context.transforms, + model_settings=self.model_settings, + ) + + self.optimiser_context = MagicMock(optimiser_settings=self.optimiser_settings) + + self.workflow = MagicMock( + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + blackbox_settings=self.bayes_settings, + data_context=self.data_context, + optimiser_context=self.optimiser_context, + plasma_context=self.plasma_context, + model_context=self.model_context, + ) + + def test_data_context_initialises(self): + data_context = MockData( + pulse=self.pulse, + diagnostics=self.diagnostics, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + reader_settings=self.data_settings, + ) + data_context.read_data() + data_context.process_data( + self.model_context._build_bckc, + ) + assert True + + def test_plasma_context_initialises(self): + plasma_context = PlasmaContext( + plasma_settings=self.plasma_settings, profile_params=DEFAULT_PROFILE_PARAMS + ) + plasma_context.init_plasma( + equilibrium=self.data_context.equilibrium, + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + ) + plasma_context.save_phantom_profiles(phantoms=self.data_context.phantoms) + assert True + + def test_model_context_initialises(self): + model_context = ModelContext( + diagnostics=self.diagnostics, + plasma_context=self.plasma_context, + equilibrium=self.data_context.equilibrium, + transforms=self.data_context.transforms, + model_settings=self.model_settings, + ) + model_context.update_model_kwargs(self.data_context.binned_data) + model_context.init_models() + assert True + + def test_optimiser_context_initialises(self): + optimiser_context = EmceeOptimiser(optimiser_settings=self.optimiser_settings) + optimiser_context.init_optimiser(MagicMock()) + assert True + + def test_workflow_initialises(self): + workflow = BayesWorkflow( + tstart=self.tstart, + tend=self.tend, + dt=self.dt, + blackbox_settings=self.bayes_settings, + data_context=self.data_context, + optimiser_context=self.optimiser_context, + plasma_context=self.plasma_context, + model_context=self.model_context, + ) + workflow.dummy = "" + assert True + + +if __name__ == "__main__": + test = TestBayesWorkflow() + test.setup_class() + test.test_workflow_initialises() diff --git a/tests/unit/workflows/test_bayes_workflow_example.py b/tests/unit/workflows/test_bayes_workflow_example.py deleted file mode 100644 index 383f19c8..00000000 --- a/tests/unit/workflows/test_bayes_workflow_example.py +++ /dev/null @@ -1,160 +0,0 @@ -import copy - -import pytest - -from indica.workflows.bayes_workflow_example import BayesWorkflowExample -from indica.workflows.bayes_workflow_example import DEFAULT_PRIORS -from indica.workflows.bayes_workflow_example import DEFAULT_PROFILE_PARAMS -from indica.workflows.bayes_workflow_example import OPTIMISED_PARAMS -from indica.workflows.bayes_workflow_example import OPTIMISED_QUANTITY - -""" -TODO: -Mock reader for testing experimental data reading -""" - - -class TestBayesWorkflowExample: - def setup_class(self): - self.init_settings = dict( - pulse=None, - phantoms=True, - diagnostics=["xrcs", "efit", "smmh1", "cxff_pi"], - opt_quantity=OPTIMISED_QUANTITY, - param_names=OPTIMISED_PARAMS, - profile_params=DEFAULT_PROFILE_PARAMS, - priors=DEFAULT_PRIORS, - tstart=0.02, - tend=0.10, - dt=0.005, - ) - self.plasma_settings = dict( - tsample=0.060, - ) - - self.optimiser_settings = dict( - model_kwargs={ - "xrcs_moment_analysis": False, - }, - nwalkers=20, - sample_high_density=False, - ) - - self.call_settings = dict( - filepath=None, - pulse_to_write=23000101, - run="RUN01", - mds_write=False, - plot=False, - iterations=1, - burn_frac=0.10, - ) - self.sampler_settings = dict( - iterations=1, - burn_frac=0.10, - ) - - self.workflow_untouched = BayesWorkflowExample(**self.init_settings) - self.workflow = None - - def setup_method(self): - self.workflow = copy.deepcopy(self.workflow_untouched) - - def teardown_method(self): - self.workflow = None - - def test_workflow_initializes(self): - attributes_to_check = ["data", "models", "equilibrium"] - for attribute in attributes_to_check: - if not hasattr(self.workflow, attribute): - raise ValueError(f"missing {attribute} in workflow object") - assert True - - def test_init_phantoms_false_with_example_plasma(self): - with pytest.raises(ValueError): - BayesWorkflowExample(**dict(self.init_settings, **{"phantoms": False})) - - def test_init_not_including_all_required_inputs(self): - with pytest.raises(ValueError): - BayesWorkflowExample(**dict(self.init_settings, **{"param_names": None})) - - # def test_reader_has_read_all_diagnostic_data(self): - # assert all(diag_name in self.workflow.reader.keys() - # for diag_name in self.workflow.diagnostics) - - def test_plasma_has_equilibrium(self): - self.workflow.setup_plasma(**self.plasma_settings) - assert hasattr(self.workflow.plasma, "equilibrium") - - def test_phantom_profiles_are_not_mutatable(self): - self.workflow.setup_plasma(**self.plasma_settings) - phantoms = copy.deepcopy(self.workflow.phantom_profiles) - self.workflow.plasma.electron_temperature += 1 - assert phantoms is not self.workflow.phantom_profiles - - def test_setup_models_with_wrong_diagnostic_names(self): - with pytest.raises(ValueError): - self.workflow.setup_models(["foo", "bar", "xrcs"]) - - def test_opt_data_without_plasma(self): - with pytest.raises(ValueError): - self.workflow.setup_opt_data(phantoms=True) - - def test_phantom_data_exists(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data(phantoms=True) - assert self.workflow.opt_data - - # def test_experimental_data_exists(self): - # self.workflow._exp_data() - # assert self.workflow.opt_data - - def test_phantom_data_has_time_dim(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data(phantoms=True) - for key, value in self.workflow.opt_data.items(): - assert "t" in value.dims - - # def test_experimental_data_has_time_dim(self): - # self.workflow._exp_data() - # for key, value in self.workflow.opt_data.items(): - # assert "t" in value.dims - - def test_phantom_data_runs_with_noise_added(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data(phantoms=True, noise=True) - assert self.workflow.opt_data - - def test_sampling_from_priors(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data( - phantoms=True, - ) - self.workflow.setup_optimiser( - **dict(self.optimiser_settings, **{"sample_high_density": False}) - ) - assert True - - def test_sampling_from_high_density(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data( - phantoms=True, - ) - self.workflow.setup_optimiser( - **dict(self.optimiser_settings, **{"sample_high_density": True}) - ) - assert True - - def test_worklow_has_results_after_run(self): - self.workflow.setup_plasma(**self.plasma_settings) - self.workflow.setup_opt_data(phantoms=True) - self.workflow.setup_optimiser(**self.optimiser_settings) - self.workflow.run_sampler(**self.sampler_settings) - if not hasattr(self.workflow, "result"): - raise ValueError("missing result in workflow object") - assert True - - -if __name__ == "__main__": - test = TestBayesWorkflowExample() - test.setup_class()