From 3215a61b9a63a42fced55479c3d5eb3ca57ed160 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 14:54:07 -0400 Subject: [PATCH 01/28] large refactor of variable names --- docs/_quarto.yml | 4 +- docs/usage/dev.qmd | 52 +++ poetry.lock | 2 +- pyproject.toml | 1 + src/new_fave/measurements/calcs.py | 34 ++ .../measurements/vowel_measurement.py | 365 ++++++++++++------ src/new_fave/optimize/optimize.py | 8 +- .../test_vowel_measurments.py | 12 +- tests/test_optimize/test_optimize.py | 8 +- 9 files changed, 358 insertions(+), 128 deletions(-) create mode 100644 docs/usage/dev.qmd create mode 100644 src/new_fave/measurements/calcs.py diff --git a/docs/_quarto.yml b/docs/_quarto.yml index d014135..c346953 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -109,7 +109,9 @@ quartodoc: - to_tracks_df - to_param_df - to_point_df - + - title: Calculations + contents: + - measurements.calcs.mahalanobis - title: Optimization desc: Functions for optimizing formant measurements contents: diff --git a/docs/usage/dev.qmd b/docs/usage/dev.qmd new file mode 100644 index 0000000..6a49347 --- /dev/null +++ b/docs/usage/dev.qmd @@ -0,0 +1,52 @@ +--- +title: Dev Notes +--- + +## Property naming descriptors + +### From Descriptors + +- `cand`: candidate tracks. + - Returns + - list of [](`fasttrackpy.OneTrack`)s + - a [](`numpy.array`) of concatenated results from [](`fasttrackpy.OneTrack`)s +- `winner`: The winner track + - Returns + - A single [](`fasttrackpy.OneTrack`) + - a [](`numpy.array`) of concatenated results from winner [](`fasttrackpy.OneTrack`)s + +### Value Descriptors + +- `param`: The DCT parameters +- `maxformant`: The maximum formant +- `error`: The smoothing error term + +### Summary Descriptors + +- `mean`: A mean +- `cov`: A covariance matrix +- `icov`: An inverse covariance matrix + + +### Derived Values Descriptors + +- `mahal`: Mahalanobis distance +- `logprob`: The log probability + +### Scope Descriptors + +- `vm`: Vowel Measurement +- `vclass`: Vowel Class +- `speaker`: Speaker +- `corpus`: Corpus + +### Scope Subdivision Descriptors + +- `global`: Global +- `byvclass`: By VowelClass + +## Property Naming Structure + +- `source`_`value`_`derived`_`scope`_`subdivision` +- `source`_`value`_`summary` +- `source`_`value` diff --git a/poetry.lock b/poetry.lock index 6e2eb03..d013d87 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4068,4 +4068,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "8dfc857869aa848a81242cb1a192b2138571a4a17078a3cc8c0d69967d0afe68" +content-hash = "d0cfc954a5375db89ef1a32865cc7eb18f1527792aeb85ab974965b6a786418a" diff --git a/pyproject.toml b/pyproject.toml index 04461a0..7980e52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ python-magic = {version = "^0.4.27", markers = "sys_platform != 'win32'"} python-magic-bin = {version = "^0.4.14", markers = "sys_platform == 'win32'"} scipy = "^1.13.1" cloudpickle = "^3.0.0" +nptyping = "^2.5.0" [tool.poetry.group.docs.dependencies] diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py new file mode 100644 index 0000000..fad7de6 --- /dev/null +++ b/src/new_fave/measurements/calcs.py @@ -0,0 +1,34 @@ +import numpy as np +import nptyping as npt +from nptyping import NDArray, Shape, Float +from typing import Any + +def mahalanobis( + params:NDArray[Shape['Dim, Cand'], Float], + param_means:NDArray[Shape['Dim, 1'], Float], + inv_cov:NDArray[Shape['Dim, Dim'], Float] + )->NDArray[Shape["Cand"], Float]: + """ + Calculates the Mahalanobis distance. + + Args: + params (NDArray[Shape['Dim, Cand'], Float]): + The parameters for which the Mahalanobis distance is to be calculated. + param_means (NDArray[Shape['Dim, 1'], Float]): + The mean of the distribution. + inv_cov (NDArray[Shape['Dim, Dim'], Float]): + The inverse of the covariance matrix of the distribution. + + Returns: + (NDArray[Shape["Cand"], Float]): + The Mahalanobis distance of each parameter from the distribution. + """ + + x_mu = params - param_means + left = np.dot(x_mu.T, inv_cov) + mahal = np.dot(left, x_mu) + return mahal.diagonal() + +def mahal_log_prob(mahals, df): + + pass \ No newline at end of file diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index a0d81ff..aeee930 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -2,8 +2,11 @@ from aligned_textgrid import AlignedTextGrid, SequenceInterval from fave_measurement_point.heuristic import Heuristic from fave_measurement_point.formants import FormantArray + from new_fave.utils.textgrid import get_textgrid from new_fave.speaker.speaker import Speaker +from new_fave.measurements.calcs import mahalanobis + from collections import defaultdict import numpy as np from typing import Literal @@ -15,6 +18,9 @@ from collections.abc import Sequence, Iterable from dataclasses import dataclass, field +from nptyping import NDArray, Shape, Float + +from functools import lru_cache NCPU = cpu_count() @@ -153,7 +159,7 @@ def __repr__(self): return out @property - def label(self): + def label(self) -> str: if (not self._label) or (self._label != self.interval.label): for cand in self.candidates: cand.label = self.interval.label @@ -168,7 +174,7 @@ def label(self, x:str): @property - def formant_array(self): + def formant_array(self) -> FormantArray: return FormantArray( self.winner.smoothed_formants, self.winner.time_domain, @@ -185,7 +191,7 @@ def vowel_class(self, vclass): self._vclass = vclass @property - def winner(self): + def winner(self)->OneTrack: return self._winner @winner.setter @@ -197,20 +203,22 @@ def winner(self, idx): self._optimized += 1 @property - def optimized(self): + def optimized(self)->int: return self._optimized @property - def winner_index(self): + def winner_index(self)->int: return self.candidates.index(self.winner) @property - def expanded_formants(self): + def expanded_formants( + self + )->NDArray[Shape['N, Formant, Cand'], Float]: if self._expanded_formants is not None: return self._expanded_formants - + N = self.winner.formants.shape[1] self._expanded_formants = np.apply_along_axis( - lambda x: idct(x.T, n = 20, orthogonalize=True, norm = "forward"), + lambda x: idct(x.T, n = N, orthogonalize=True, norm = "forward"), 0, self.cand_params ) @@ -218,7 +226,9 @@ def expanded_formants(self): @property - def cand_params(self): + def cand_param( + self + ) -> NDArray[Shape["Param, Formant, Cand"], Float]: params = np.array( [ x.parameters @@ -229,14 +239,18 @@ def cand_params(self): return params @property - def cand_max_formants(self): + def cand_maxformant( + self + ) -> NDArray[Shape["1, Cand"], Float]: return np.array([[ c.maximum_formant for c in self.candidates ]]) @property - def cand_errors(self): + def cand_error( + self + ) -> NDArray[Shape["Cand"], Float]: with warnings.catch_warnings(): warnings.simplefilter("ignore") return np.array([ @@ -245,22 +259,26 @@ def cand_errors(self): ]) @property - def cand_mahals(self): + def cand_param_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: N = len(self.candidates) - square_params = self.cand_params.reshape(-1, N) - inv_covmat = self.vowel_class.vowel_system.params_icov - param_means = self.vowel_class.vowel_system.params_means - x_mu = square_params - param_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + square_params = self.cand_param.reshape(-1, N) + mahal = mahalanobis( + square_params, + self.vowel_class.vowel_system.winner_param_mean, + self.vowel_class.vowel_system.winner_param_icov + ) + return mahal @property - def cand_mahal_log_prob(self): - winner_shape = self.cand_params.shape + def cand_param_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + winner_shape = self.cand_param.shape df = winner_shape[0] * winner_shape[1] log_prob = stats.chi2.logsf( - self.cand_mahals, + self.cand_param_mahal_speaker_global, df = df ) if np.isfinite(log_prob).mean() < 0.5: @@ -268,42 +286,58 @@ def cand_mahal_log_prob(self): return log_prob @property - def cand_vclass_mahals(self): + def cand_param_mahal_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: N = len(self.candidates) - square_params = self.cand_params.reshape(-1, N) - inv_covmat = self.vowel_class.params_icov - param_means = self.vowel_class.params_means + square_params = self.cand_param.reshape(-1, N) + inv_covmat = self.vowel_class.winner_param_icov + param_means = self.vowel_class.winner_param_mean x_mu = square_params - param_means left = np.dot(x_mu.T, inv_covmat) mahal = np.dot(left, x_mu) return mahal.diagonal() @property - def cand_vclass_mahal_log_prob(self): - df = self.cand_params.size + def cand_param_logprob_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + df = self.cand_param.shape[0] * self.cand_param.shape[1] log_prob = stats.chi2.logsf( - self.cand_vclass_mahals, + self.cand_param_mahal_speaker_byvclass, df = df ) if np.isfinite(log_prob).mean() < 0.5: log_prob = np.zeros(shape = log_prob.shape) if len(self.vowel_class) < 10: log_prob = np.zeros(shape = log_prob.shape) - return log_prob + return log_prob + + # @property + # def cand_corpus_mahals(self): + # N = len(self.candidates) + # square_params = self.cand_params.reshape(-1, N) + + @property - def max_formant_mahal(self): - inv_covmat = self.vowel_class.vowel_system.max_formant_icov - maximum_formant_means = self.vowel_class.vowel_system.maximum_formant_means - x_mu = self.cand_max_formants - maximum_formant_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + def cand_maxformant_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + inv_covmat = self.vowel_class.vowel_system.winner_maxformant_icov + maximum_formant_means = self.vowel_class.vowel_system.winner_maxformant_mean + # x_mu = self.cand_maxformant - maximum_formant_means + # left = np.dot(x_mu.T, inv_covmat) + # mahal = np.dot(left, x_mu) + mahal = mahalanobis(self.cand_maxformant, maximum_formant_means, inv_covmat) + return mahal @property - def max_formant_log_prob(self): + def cand_maxformant_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: log_prob = stats.chi2.logsf( - self.max_formant_mahal, + self.cand_maxformant_mahal_speaker_global, df = 1 ) @@ -313,16 +347,20 @@ def max_formant_log_prob(self): return log_prob @property - def error_log_prob(self): + def cand_error_logprob_vm( + self + ) -> NDArray[Shape["Cand"], Float]: with warnings.catch_warnings(): warnings.simplefilter("ignore") - err_norm = self.cand_errors - np.nanmin(self.cand_errors) + err_norm = self.cand_error - np.nanmin(self.cand_error) err_surv = 1 - (err_norm/np.nanmax(err_norm)) err_log_prob = np.log(err_surv) return err_log_prob @property - def point_measure(self): + def point_measure( + self + ) -> pl.DataFrame: winner_slice = self.heuristic.apply_heuristic( self.label, formants=self.formant_array @@ -345,7 +383,9 @@ def point_measure(self): return pl.DataFrame(point_dict) @property - def vm_context(self): + def vm_context( + self + ) -> pl.DataFrame: optimized = self.optimized id = self.winner.id word = self.winner.interval.within.label @@ -492,10 +532,10 @@ class VowelClass(Sequence): def __post_init__(self): super().__init__() self._winners = [x.winner for x in self.tracks] - self._winner_params = None - self._params_means = None - self._params_cov = None - self._params_icov = None + self._winner_param = None + self._winner_param_mean = None + self._winner_param_cov = None + self._winner_param_icov = None for t in self.tracks: t.vowel_class = self @@ -515,10 +555,10 @@ def __repr__(self): return out def _reset_winners(self): - self._winner_params = None - self._params_means = None - self._params_cov = None - self._params_icov = None + self._winner_param = None + self._winner_param_mean = None + self._winner_param_cov = None + self._winner_param_icov = None @property def vowel_system(self): @@ -534,9 +574,9 @@ def winners(self): return self._winners @property - def winner_params(self): - if not self._winner_params is None: - return self._winner_params + def winner_param(self): + if not self._winner_param is None: + return self._winner_param params = np.array( [ @@ -544,48 +584,49 @@ def winner_params(self): for x in self.winners ] ).T - + self._winner_param = params return params @property - def params_means(self): - if self._params_means is not None: - return self._params_means + def winner_param_mean(self): + if self._winner_param_mean is not None: + return self._winner_param_mean N = len(self.winners) - winner_mean = self.winner_params.reshape(-1, N).mean(axis = 1) + winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) winner_mean = winner_mean[:, np.newaxis] - self._params_means = winner_mean + self._winner_param_mean = winner_mean return winner_mean @property - def params_covs(self): - if self._params_cov is not None: - return self._params_cov + def winner_param_cov(self): + if self._winner_param_cov is not None: + return self._winner_param_cov N = len(self.winners) - square_param = self.winner_params.reshape(-1, N) + square_param = self.winner_param.reshape(-1, N) with warnings.catch_warnings(): warnings.simplefilter("ignore") param_cov = np.cov(square_param) + self._winner_param_cov = param_cov return param_cov @property - def params_icov(self): - if self._params_icov is not None: - return self._params_icov + def winner_param_icov(self): + if self._winner_param_icov is not None: + return self._winner_param_icov with warnings.catch_warnings(): warnings.simplefilter("ignore") try: - params_icov = np.linalg.inv(self.params_covs) - self._params_icov = params_icov + params_icov = np.linalg.inv(self.winner_param_cov) + self._winner_param_icov = params_icov return params_icov except: params_icov = np.array([ - [np.nan] * self.params_covs.size + [np.nan] * self.winner_param_cov.size ]).reshape( - self.params_covs.shape[0], - self.params_covs.shape[1] + self.winner_param_cov.shape[0], + self.winner_param_cov.shape[1] ) - self._params_icov = params_icov + self._winner_param_icov = params_icov return params_icov def to_param_df( @@ -692,22 +733,23 @@ def __init__(self, track_list:list[VowelMeasurement] = EMPTY_LIST): self._make_tracks_dict() self._dictify() self._vowel_system() - self._params_means = None - self._params_icov = None - self._maximum_formant_means = None - self._max_formant_icov = None + self._winner_param_mean = None + self._winner_param_icov = None + self._winner_maxformant_mean = None + self._winner_maxformant_icov = None self._textgrid = None self._file_name = None + self._corpus = None def __setitem__(self, __key, __value) -> None: super().__setitem__(__key, __value) def _reset_winners(self): - self._params_means = None - self._params_icov = None - self._maximum_formant_means = None - self._max_formant_icov = None + self._winner_param_mean = None + self._winner_param_icov = None + self._winner_maxformant_mean = None + self._winner_maxformant_icov = None def _make_tracks_dict(self): for v in self.track_list: @@ -724,6 +766,14 @@ def _vowel_system(self): for v in self.tracks_dict: self[v].vowel_system = self + @property + def corpus(self): + return self._corpus + + @corpus.setter + def corpus(self, corp): + self._corpus = corp + @property def winners(self): return [ @@ -757,7 +807,7 @@ def file_name(self): return self._file_name @property - def winner_params(self): + def winner_param(self): params = np.array( [ x.parameters @@ -790,7 +840,7 @@ def winner_expanded_formants(self): return formants @property - def winners_maximum_formant(self): + def winner_maxformant(self): max_formants = np.array([[ x.maximum_formant for x in self.winners @@ -800,69 +850,69 @@ def winners_maximum_formant(self): @property - def params_means(self): - if self._params_means is not None: - return self._params_means + def winner_param_mean(self): + if self._winner_param_mean is not None: + return self._winner_param_mean N = len(self.winners) - winner_mean = self.winner_params.reshape(-1, N).mean(axis = 1) + winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) winner_mean = winner_mean[:, np.newaxis] - self._params_means = winner_mean + self._winner_param_mean = winner_mean return winner_mean @property - def params_covs(self): + def winner_param_cov(self): N = len(self.winners) - square_param = self.winner_params.reshape(-1, N) + square_param = self.winner_param.reshape(-1, N) with warnings.catch_warnings(): warnings.simplefilter("ignore") param_cov = np.cov(square_param) return param_cov @property - def params_icov(self): - if self._params_icov is not None: - return self._params_icov + def winner_param_icov(self): + if self._winner_param_icov is not None: + return self._winner_param_icov with warnings.catch_warnings(): warnings.simplefilter("ignore") try: - params_icov = np.linalg.inv(self.params_covs) - self._params_icov = params_icov + params_icov = np.linalg.inv(self.winner_param_cov) + self._winner_param_icov = params_icov return params_icov except: params_icov = np.array([ - [np.nan] * self.params_covs.size + [np.nan] * self.winner_param_cov.size ]).reshape( - self.params_covs.shape[0], - self.params_covs.shape[1] + self.winner_param_cov.shape[0], + self.winner_param_cov.shape[1] ) - self._params_icov = params_icov + self._winner_param_icov = params_icov return params_icov @property - def maximum_formant_means(self): - if self._maximum_formant_means is not None: - return self._maximum_formant_means - self._maximum_formant_means = self.winners_maximum_formant.mean() - return self.winners_maximum_formant.mean() + def winner_maxformant_mean(self): + if self._winner_maxformant_mean is not None: + return self._winner_maxformant_mean + self._winner_maxformant_mean = self.winner_maxformant.mean() + return self._winner_maxformant_mean @property - def maximum_formant_cov(self): + def winner_maxformant_cov(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") - cov = np.cov(self.winners_maximum_formant).reshape(1,1) + cov = np.cov(self.winner_maxformant).reshape(1,1) return cov @property - def max_formant_icov(self): - if self._max_formant_icov is not None: - return self._max_formant_icov + def winner_maxformant_icov(self): + if self._winner_maxformant_icov is not None: + return self._winner_maxformant_icov try: - icov = np.linalg.inv(self.maximum_formant_cov) - self._max_formant_icov = icov + icov = np.linalg.inv(self.winner_maxformant_cov) + self._winner_maxformant_icov = icov return icov except: - self._max_formant_icov = np.array([[np.nan]]) + self._winner_maxformant_icov = np.array([[np.nan]]) return np.array([[np.nan]]) def to_tracks_df(self): @@ -925,15 +975,19 @@ class SpeakerCollection(defaultdict): track_list (list[VowelMeasurement]): A list of `VowelMeasurement`s. """ + __hash__ = object.__hash__ + def __init__(self, track_list:list[VowelMeasurement] = []): self.track_list = track_list self.speakers_dict = defaultdict(blank_list) self._make_tracks_dict() self._dictify() self._speaker = None + self._associate_corpus() def __setitem__(self, __key, __value) -> None: super().__setitem__(__key, __value) + self._associate_corpus() def _make_tracks_dict(self): for v in self.track_list: @@ -945,6 +999,93 @@ def _dictify(self): self[fs] = VowelClassCollection( self.speakers_dict[fs] ) + + def _associate_corpus(self): + for speaker in self.values(): + speaker.corpus = self + + @property + @lru_cache + def vowel_dict(self): + out = defaultdict(blank_list) + for speaker in self.values(): + for vowel in speaker: + out[vowel] += speaker[vowel] + return out + + @property + @lru_cache + def vowel_winners(self): + out = defaultdict(blank_list) + for vowel in self.vowel_dict: + out[vowel] += [x.winner for x in self.vowel_dict[vowel]] + + return out + + @property + @lru_cache + def vowel_winner_params(self): + out = defaultdict(blank_list) + for vowel in self.vowel_winners: + params = np.array( + [ + x.parameters + for x in self.vowel_winners[vowel] + ] + ).T + + out[vowel] = params + return out + + @property + @lru_cache + def vowel_params_means(self): + out = defaultdict(lambda: np.array([])) + + for vowel in self.vowel_winner_params: + N = len(self.vowel_winner_params[vowel]) + winner_mean = self.vowel_winner_params[vowel].reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + out[vowel] = winner_mean + return out + + + @property + def vowel_params_covs(self)->defaultdict: + out = defaultdict(lambda: np.array([])) + + for vowel in self.vowel_winner_params: + N = len(self.vowel_winner_params[vowel]) + square_param = self.vowel_winner_params[vowel].reshape(-1, N) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + param_cov = np.cov(square_param) + out[vowel] = param_cov + + return out + + @property + @lru_cache + def vowel_params_icov(self)->defaultdict[str, np.array]: + out = defaultdict(lambda: np.array([])) + + for vowel in self.vowel_params_covs: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + params_icov = np.linalg.inv(self.vowel_params_covs[vowel]) + out[vowel] = params_icov + except: + params_icov = np.array([ + [np.nan] * self.vowel_params_covs[vowel].size + ]).reshape( + self.vowel_params_covs[vowel][0], + self.vowel_params_covs[vowel][1] + ) + out[vowel] = params_icov + + return out + @property def speaker(self): diff --git a/src/new_fave/optimize/optimize.py b/src/new_fave/optimize/optimize.py index 3b1afce..f3ff037 100644 --- a/src/new_fave/optimize/optimize.py +++ b/src/new_fave/optimize/optimize.py @@ -100,15 +100,15 @@ def optimize_one_measure( prob_dict = dict() if "cand_mahal" in optim_params: - prob_dict["cand_mahal"] = vowel_measurement.cand_mahal_log_prob + prob_dict["cand_mahal"] = vowel_measurement.cand_param_logprob_speaker_global if "vclass_mahal" in optim_params: - prob_dict["vclass_mahal"] = vowel_measurement.cand_vclass_mahal_log_prob + prob_dict["vclass_mahal"] = vowel_measurement.cand_param_logprob_speaker_byvclass if "max_formant" in optim_params: - prob_dict["max_formant"] = vowel_measurement.max_formant_log_prob + prob_dict["max_formant"] = vowel_measurement.cand_maxformant_logprob_speaker_global - joint_prob = vowel_measurement.error_log_prob + joint_prob = vowel_measurement.cand_error_logprob_vm for dim in optim_params: joint_prob += prob_dict[dim] diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index a855699..d683865 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -86,12 +86,12 @@ def test_winner_reset(): speaker = speakers[first_speaker] speaker_vms = speaker.vowel_measurements - initial_mean = speaker.maximum_formant_means + initial_mean = speaker.winner_maxformant_mean initial_index = speaker_vms[0].winner_index speaker_vms[0].winner = initial_index+1 - new_mean = speaker.maximum_formant_means + new_mean = speaker.winner_maxformant_mean assert ~np.isclose(initial_mean, new_mean) @@ -143,7 +143,7 @@ def test_winner_param(): ] for vc in all_vcs: - params = vc.winner_params + params = vc.winner_param expected_shape = (5, NFORMANT, len(vc)) for s1, s2 in zip(params.shape, expected_shape): assert s1 == s2 @@ -155,9 +155,9 @@ def test_probs(): is equal to the number of steps """ for vm in vms: - cand_mahal_log_prob = vm.cand_mahal_log_prob - max_formant_log_prob = vm.max_formant_log_prob - error_log_prob = vm.error_log_prob + cand_mahal_log_prob = vm.cand_param_logprob_speaker_global + max_formant_log_prob = vm.cand_maxformant_logprob_speaker_global + error_log_prob = vm.cand_error_logprob_vm assert cand_mahal_log_prob.size == NSTEP assert max_formant_log_prob.size == NSTEP diff --git a/tests/test_optimize/test_optimize.py b/tests/test_optimize/test_optimize.py index ebec20a..4bda3dc 100644 --- a/tests/test_optimize/test_optimize.py +++ b/tests/test_optimize/test_optimize.py @@ -8,10 +8,10 @@ def __init__(self, len, winner_idx): log_prob = -np.ones(len)*2 log_prob[winner_idx] = -0.5 - self.cand_mahal_log_prob = log_prob - self.cand_vclass_mahal_log_prob = log_prob - self.max_formant_log_prob = log_prob - self.error_log_prob = log_prob + self.cand_param_logprob_speaker_global = log_prob + self.cand_param_logprob_speaker_byvclass = log_prob + self.cand_maxformant_logprob_speaker_global = log_prob + self.cand_error_logprob_vm = log_prob self.winner = None class MockVowelClassCollection: From 32a1bf3221d51ca3962ce45370546ee81768bca6 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 16:32:07 -0400 Subject: [PATCH 02/28] More explicit typing --- .../measurements/vowel_measurement.py | 102 ++++++++++++------ 1 file changed, 69 insertions(+), 33 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index aeee930..05726ab 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -216,11 +216,11 @@ def expanded_formants( )->NDArray[Shape['N, Formant, Cand'], Float]: if self._expanded_formants is not None: return self._expanded_formants - N = self.winner.formants.shape[1] + self._expanded_formants = np.apply_along_axis( - lambda x: idct(x.T, n = N, orthogonalize=True, norm = "forward"), + lambda x: idct(x.T, n = 20, orthogonalize=True, norm = "forward"), 0, - self.cand_params + self.cand_param ) return self._expanded_formants @@ -523,7 +523,7 @@ class VowelClass(Sequence): winners (list[fasttrackpy.OneTrack]): A list of winner OneTracks from the vowel class - winner_params (np.array): + winner_param (np.array): An `np.array` of winner DCT parameters from the vowel class. """ @@ -574,7 +574,9 @@ def winners(self): return self._winners @property - def winner_param(self): + def winner_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: if not self._winner_param is None: return self._winner_param @@ -588,7 +590,9 @@ def winner_param(self): return params @property - def winner_param_mean(self): + def winner_param_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: if self._winner_param_mean is not None: return self._winner_param_mean N = len(self.winners) @@ -598,7 +602,9 @@ def winner_param_mean(self): return winner_mean @property - def winner_param_cov(self): + def winner_param_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: if self._winner_param_cov is not None: return self._winner_param_cov N = len(self.winners) @@ -610,7 +616,9 @@ def winner_param_cov(self): return param_cov @property - def winner_param_icov(self): + def winner_param_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: if self._winner_param_icov is not None: return self._winner_param_icov with warnings.catch_warnings(): @@ -775,7 +783,9 @@ def corpus(self, corp): self._corpus = corp @property - def winners(self): + def winners( + self + ) -> list[OneTrack]: return [ x for vc in self.values() @@ -783,7 +793,9 @@ def winners(self): ] @property - def vowel_measurements(self): + def vowel_measurements( + self + ) -> list[VowelMeasurement]: return [ x for vc in self.values() @@ -791,7 +803,9 @@ def vowel_measurements(self): ] @property - def textgrid(self): + def textgrid( + self + ) -> AlignedTextGrid: if self._textgrid: return self._textgrid @@ -799,7 +813,9 @@ def textgrid(self): return self._textgrid @property - def file_name(self): + def file_name( + self + ) -> str: if self._file_name: return self._file_name @@ -807,7 +823,9 @@ def file_name(self): return self._file_name @property - def winner_param(self): + def winner_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: params = np.array( [ x.parameters @@ -817,19 +835,23 @@ def winner_param(self): return params - @property - def winner_formants(self): - formants = np.hstack( - [ - x.formants - for x in self.winners - ] - ) - - return formants + # @property + # def winner_formants( + # self + # ): + # formants = np.hstack( + # [ + # x.formants + # for x in self.winners + # ] + # ) + + # return formants @property - def winner_expanded_formants(self): + def winner_expanded_formants( + self + ) -> NDArray[Shape["20, FormantN"], Float]: formants = np.hstack( [ x.expanded_formants[:, :, x.winner_index] @@ -840,7 +862,9 @@ def winner_expanded_formants(self): return formants @property - def winner_maxformant(self): + def winner_maxformant( + self + ) -> NDArray[Shape["1, N"], Float]: max_formants = np.array([[ x.maximum_formant for x in self.winners @@ -850,7 +874,9 @@ def winner_maxformant(self): @property - def winner_param_mean(self): + def winner_param_mean( + self + ) -> NDArray[Shape["FormantParam"], Float]: if self._winner_param_mean is not None: return self._winner_param_mean N = len(self.winners) @@ -860,7 +886,9 @@ def winner_param_mean(self): return winner_mean @property - def winner_param_cov(self): + def winner_param_cov( + self + ) -> NDArray[Shape["FormantParam, FormantParam"], Float]: N = len(self.winners) square_param = self.winner_param.reshape(-1, N) with warnings.catch_warnings(): @@ -869,7 +897,9 @@ def winner_param_cov(self): return param_cov @property - def winner_param_icov(self): + def winner_param_icov( + self + ) -> NDArray[Shape["FormantParam, FormantParam"], Float] : if self._winner_param_icov is not None: return self._winner_param_icov with warnings.catch_warnings(): @@ -889,21 +919,27 @@ def winner_param_icov(self): return params_icov @property - def winner_maxformant_mean(self): + def winner_maxformant_mean( + self + ) -> float: if self._winner_maxformant_mean is not None: return self._winner_maxformant_mean self._winner_maxformant_mean = self.winner_maxformant.mean() return self._winner_maxformant_mean @property - def winner_maxformant_cov(self): + def winner_maxformant_cov( + self + ) -> NDArray[Shape["1, 1"], Float]: with warnings.catch_warnings(): warnings.simplefilter("ignore") cov = np.cov(self.winner_maxformant).reshape(1,1) return cov @property - def winner_maxformant_icov(self): + def winner_maxformant_icov( + self + ) -> NDArray[Shape["1, 1"], Float]: if self._winner_maxformant_icov is not None: return self._winner_maxformant_icov @@ -915,7 +951,7 @@ def winner_maxformant_icov(self): self._winner_maxformant_icov = np.array([[np.nan]]) return np.array([[np.nan]]) - def to_tracks_df(self): + def to_tracks_df(self)->pl.DataFrame: """Return a DataFrame of the formant tracks Returns: @@ -944,7 +980,7 @@ def to_param_df( return df - def to_point_df(self): + def to_point_df(self) -> pl.DataFrame: """Return a DataFrame of point measurements Returns: From be181365eb4a6907d2e2918739ab71063b4750aa Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 17:44:33 -0400 Subject: [PATCH 03/28] offloading common calculations from the classes --- src/new_fave/measurements/calcs.py | 75 +++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py index fad7de6..482ed8f 100644 --- a/src/new_fave/measurements/calcs.py +++ b/src/new_fave/measurements/calcs.py @@ -29,6 +29,79 @@ def mahalanobis( mahal = np.dot(left, x_mu) return mahal.diagonal() -def mahal_log_prob(mahals, df): +def mahal_log_prob( + mahals: NDArray[Shape["Cand"], Float], + params: NDArray[Shape["*, *, ..."], Float] + ) -> NDArray[Shape["Cand"], Float]: + """ + + Args: + mahals (NDArray[Shape["Cand"], Float]): + The Mahalanobis distances. + params (NDArray[Shape["*, *, ..."], Float]): + The parameters across which the mahalanobis + distance was calculated + + Returns: + (NDArray[Shape["Cand"], Float]): + The log probability + """ + df = np.prod(params.shape[0:-1]) + log_prob = stats.chi2.logsf( + mahals, + df = df + ) + if np.isfinite(log_prob).mean() < 0.5: + log_prob = np.zeros(shape = log_prob.shape) + return log_prob + + +def param_to_cov( + params:NDArray[Shape["*, *, ..."], Float] +) -> NDArray[Shape["X, X"], Float]: + """ + Calculates the covariance matrix of the given parameters. + + Args: + params (NDArray[Shape["*, *, ..."], Float]): + The parameters for which the covariance matrix is to be calculated. + Returns: + (NDArray[Shape["X, X"], Float]): + The covariance matrix of the parameters. + """ + N = params.shape[-1] + square_params = params.reshape(-1, N) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + param_cov = np.cov(square_params) + + return param_cov + +def cov_to_icov( + cov_mat: NDArray[Shape["X, X"], Float] +) -> NDArray[Shape["X, X"], Float]: + """ + Calculates the inverse covariance matrix of the given covariance matrix. + + Args: + cov_mat (NDArray[Shape["X, X"], Float]): + The covariance matrix for which the inverse is to be calculated. + + Returns: + (NDArray[Shape["X, X"], Float]): + The inverse covariance matrix of the given covariance matrix. + """ + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + params_icov = np.linalg.inv(cov_mat) + except: + params_icov = np.array([ + [np.nan] * cov_mat.size + ]).reshape( + cov_mat.shape[0], + cov_mat.shape[1] + ) + pass \ No newline at end of file From 6c61172d88dca509bbbec0bc96b676af30356cbe Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 17:44:53 -0400 Subject: [PATCH 04/28] full calcs --- src/new_fave/measurements/calcs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py index 482ed8f..042c765 100644 --- a/src/new_fave/measurements/calcs.py +++ b/src/new_fave/measurements/calcs.py @@ -2,6 +2,8 @@ import nptyping as npt from nptyping import NDArray, Shape, Float from typing import Any +import scipy.stats as stats +import warnings def mahalanobis( params:NDArray[Shape['Dim, Cand'], Float], @@ -104,4 +106,4 @@ def cov_to_icov( cov_mat.shape[1] ) - pass \ No newline at end of file + return params_icov \ No newline at end of file From f1cb2fa2970764058b9aa824722cc972f39a0375 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 17:45:33 -0400 Subject: [PATCH 05/28] import offloaded calcs --- src/new_fave/measurements/vowel_measurement.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 05726ab..49edd95 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -5,7 +5,10 @@ from new_fave.utils.textgrid import get_textgrid from new_fave.speaker.speaker import Speaker -from new_fave.measurements.calcs import mahalanobis +from new_fave.measurements.calcs import mahalanobis, \ + mahal_log_prob,\ + param_to_cov,\ + cov_to_icov from collections import defaultdict import numpy as np From 50dee73f3df72734b389dbb29ed1d440f8d0da2d Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 17:48:13 -0400 Subject: [PATCH 06/28] offload calcs --- .../measurements/vowel_measurement.py | 92 +++++-------------- 1 file changed, 22 insertions(+), 70 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 49edd95..ee46f02 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -278,14 +278,10 @@ def cand_param_mahal_speaker_global( def cand_param_logprob_speaker_global( self ) -> NDArray[Shape["Cand"], Float]: - winner_shape = self.cand_param.shape - df = winner_shape[0] * winner_shape[1] - log_prob = stats.chi2.logsf( + log_prob = mahal_log_prob( self.cand_param_mahal_speaker_global, - df = df + self.cand_param ) - if np.isfinite(log_prob).mean() < 0.5: - log_prob = np.zeros(shape = log_prob.shape) return log_prob @property @@ -296,22 +292,17 @@ def cand_param_mahal_speaker_byvclass( square_params = self.cand_param.reshape(-1, N) inv_covmat = self.vowel_class.winner_param_icov param_means = self.vowel_class.winner_param_mean - x_mu = square_params - param_means - left = np.dot(x_mu.T, inv_covmat) - mahal = np.dot(left, x_mu) - return mahal.diagonal() + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal @property def cand_param_logprob_speaker_byvclass( self ) -> NDArray[Shape["Cand"], Float]: - df = self.cand_param.shape[0] * self.cand_param.shape[1] - log_prob = stats.chi2.logsf( + log_prob = mahal_log_prob( self.cand_param_mahal_speaker_byvclass, - df = df + self.cand_param ) - if np.isfinite(log_prob).mean() < 0.5: - log_prob = np.zeros(shape = log_prob.shape) if len(self.vowel_class) < 10: log_prob = np.zeros(shape = log_prob.shape) return log_prob @@ -339,14 +330,11 @@ def cand_maxformant_mahal_speaker_global( def cand_maxformant_logprob_speaker_global( self ) -> NDArray[Shape["Cand"], Float]: - log_prob = stats.chi2.logsf( + log_prob = mahal_log_prob( self.cand_maxformant_mahal_speaker_global, - df = 1 + self.cand_maxformant ) - if np.isfinite(log_prob).mean() < 0.5: - log_prob = np.zeros(shape = log_prob.shape) - return log_prob @property @@ -610,11 +598,7 @@ def winner_param_cov( ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: if self._winner_param_cov is not None: return self._winner_param_cov - N = len(self.winners) - square_param = self.winner_param.reshape(-1, N) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - param_cov = np.cov(square_param) + param_cov = param_to_cov(self.winner_param) self._winner_param_cov = param_cov return param_cov @@ -624,21 +608,10 @@ def winner_param_icov( ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: if self._winner_param_icov is not None: return self._winner_param_icov - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - try: - params_icov = np.linalg.inv(self.winner_param_cov) - self._winner_param_icov = params_icov - return params_icov - except: - params_icov = np.array([ - [np.nan] * self.winner_param_cov.size - ]).reshape( - self.winner_param_cov.shape[0], - self.winner_param_cov.shape[1] - ) - self._winner_param_icov = params_icov - return params_icov + + params_icov = cov_to_icov(self.winner_param_cov) + self._winner_param_icov = params_icov + return params_icov def to_param_df( self, @@ -892,11 +865,7 @@ def winner_param_mean( def winner_param_cov( self ) -> NDArray[Shape["FormantParam, FormantParam"], Float]: - N = len(self.winners) - square_param = self.winner_param.reshape(-1, N) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - param_cov = np.cov(square_param) + param_cov = param_to_cov(self.winner_param) return param_cov @property @@ -905,21 +874,9 @@ def winner_param_icov( ) -> NDArray[Shape["FormantParam, FormantParam"], Float] : if self._winner_param_icov is not None: return self._winner_param_icov - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - try: - params_icov = np.linalg.inv(self.winner_param_cov) - self._winner_param_icov = params_icov - return params_icov - except: - params_icov = np.array([ - [np.nan] * self.winner_param_cov.size - ]).reshape( - self.winner_param_cov.shape[0], - self.winner_param_cov.shape[1] - ) - self._winner_param_icov = params_icov - return params_icov + params_icov = cov_to_icov(self.winner_param_cov) + self._winner_param_icov = params_icov + return params_icov @property def winner_maxformant_mean( @@ -934,9 +891,8 @@ def winner_maxformant_mean( def winner_maxformant_cov( self ) -> NDArray[Shape["1, 1"], Float]: - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - cov = np.cov(self.winner_maxformant).reshape(1,1) + cov = param_to_cov(self.winner_maxformant) + cov = cov.reshape(1,1) return cov @property @@ -946,13 +902,9 @@ def winner_maxformant_icov( if self._winner_maxformant_icov is not None: return self._winner_maxformant_icov - try: - icov = np.linalg.inv(self.winner_maxformant_cov) - self._winner_maxformant_icov = icov - return icov - except: - self._winner_maxformant_icov = np.array([[np.nan]]) - return np.array([[np.nan]]) + icov = cov_to_icov(self.winner_maxformant_cov) + self._winner_maxformant_icov = icov + return icov def to_tracks_df(self)->pl.DataFrame: """Return a DataFrame of the formant tracks From 4695d9d74f35bbe36422934f622d927e22902217 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 5 Jun 2024 17:48:45 -0400 Subject: [PATCH 07/28] implement corpus-level metrics --- .../measurements/vowel_measurement.py | 88 ++++++++++++------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index ee46f02..0d3679f 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -308,11 +308,36 @@ def cand_param_logprob_speaker_byvclass( return log_prob - # @property - # def cand_corpus_mahals(self): - # N = len(self.candidates) - # square_params = self.cand_params.reshape(-1, N) + @property + def cand_param_mahal_corpus_byvowel( + self + ) -> NDArray[Shape["Cand"], Float]: + + N = len(self.candidates) + square_params = self.cand_param.reshape(-1, N) + inv_covmat = self\ + .vowel_class\ + .vowel_system\ + .corpus\ + .winner_param_icov[self.label] + param_means = self\ + .vowel_class\ + .vowel_system\ + .corpus\ + .winner_param_mean[self.label] + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal + + @property + def cand_param_logprob_corpus_byvowel( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_param_mahal_corpus_byvowel, + self.cand_param + ) + return log_prob @property def cand_maxformant_mahal_speaker_global( @@ -997,7 +1022,9 @@ def _associate_corpus(self): @property @lru_cache - def vowel_dict(self): + def vowel_dict( + self + ) -> defaultdict[str, list[VowelMeasurement]]: out = defaultdict(blank_list) for speaker in self.values(): for vowel in speaker: @@ -1006,7 +1033,9 @@ def vowel_dict(self): @property @lru_cache - def vowel_winners(self): + def vowel_winners( + self + ) -> defaultdict[str, list[OneTrack]]: out = defaultdict(blank_list) for vowel in self.vowel_dict: out[vowel] += [x.winner for x in self.vowel_dict[vowel]] @@ -1015,7 +1044,9 @@ def vowel_winners(self): @property @lru_cache - def vowel_winner_params(self): + def winner_param( + self + ) -> defaultdict[str, NDArray[Shape["Param, Formant, N"], Float]]: out = defaultdict(blank_list) for vowel in self.vowel_winners: params = np.array( @@ -1030,50 +1061,41 @@ def vowel_winner_params(self): @property @lru_cache - def vowel_params_means(self): + def winner_param_mean( + self + ) -> defaultdict[str, NDArray[Shape["FormantParam, 1"], Float]]: out = defaultdict(lambda: np.array([])) - for vowel in self.vowel_winner_params: - N = len(self.vowel_winner_params[vowel]) - winner_mean = self.vowel_winner_params[vowel].reshape(-1, N).mean(axis = 1) + for vowel in self.winner_param: + N = len(self.vowel_dict[vowel]) + winner_mean = self.winner_param[vowel].reshape(-1, N).mean(axis = 1) winner_mean = winner_mean[:, np.newaxis] out[vowel] = winner_mean return out @property - def vowel_params_covs(self)->defaultdict: + def winner_param_cov( + self + )->defaultdict[str, NDArray[Shape["FormantParam, FormantParam"], Float]]: out = defaultdict(lambda: np.array([])) - for vowel in self.vowel_winner_params: - N = len(self.vowel_winner_params[vowel]) - square_param = self.vowel_winner_params[vowel].reshape(-1, N) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - param_cov = np.cov(square_param) + for vowel in self.winner_param: + param_cov = param_to_cov(self.winner_param[vowel]) out[vowel] = param_cov return out @property @lru_cache - def vowel_params_icov(self)->defaultdict[str, np.array]: + def winner_param_icov( + self + )->defaultdict[str, NDArray[Shape["FormantParam, FormantParam"], Float]]: out = defaultdict(lambda: np.array([])) - for vowel in self.vowel_params_covs: - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - try: - params_icov = np.linalg.inv(self.vowel_params_covs[vowel]) - out[vowel] = params_icov - except: - params_icov = np.array([ - [np.nan] * self.vowel_params_covs[vowel].size - ]).reshape( - self.vowel_params_covs[vowel][0], - self.vowel_params_covs[vowel][1] - ) - out[vowel] = params_icov + for vowel in self.winner_param_cov: + params_icov = cov_to_icov(self.winner_param_cov[vowel]) + out[vowel] = params_icov return out From 920d4add380ad81c893c0b5a3f535f198cc062dd Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Thu, 6 Jun 2024 13:14:31 -0400 Subject: [PATCH 08/28] replaced self written caching with functools.cached_property --- src/new_fave/measurements/calcs.py | 18 ++- .../measurements/vowel_measurement.py | 123 +++++------------- 2 files changed, 53 insertions(+), 88 deletions(-) diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py index 042c765..e8573b7 100644 --- a/src/new_fave/measurements/calcs.py +++ b/src/new_fave/measurements/calcs.py @@ -4,6 +4,7 @@ from typing import Any import scipy.stats as stats import warnings +import functools def mahalanobis( params:NDArray[Shape['Dim, Cand'], Float], @@ -106,4 +107,19 @@ def cov_to_icov( cov_mat.shape[1] ) - return params_icov \ No newline at end of file + return params_icov + +def clear_cached_properties(obj:object) -> None: + """Clear the cache of any property in an object + + Args: + obj (object): Any object. + """ + cls = obj.__class__ + to_clear = [ + k for k, v in vars(cls).items() + if isinstance(v, functools.cached_property) + ] + for var in to_clear: + if var in obj.__dict__: + del obj.__dict__[var] diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 0d3679f..db1dcee 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -8,7 +8,8 @@ from new_fave.measurements.calcs import mahalanobis, \ mahal_log_prob,\ param_to_cov,\ - cov_to_icov + cov_to_icov,\ + clear_cached_properties from collections import defaultdict import numpy as np @@ -23,7 +24,7 @@ from dataclasses import dataclass, field from nptyping import NDArray, Shape, Float -from functools import lru_cache +from functools import lru_cache, cached_property NCPU = cpu_count() @@ -398,7 +399,7 @@ def point_measure( return pl.DataFrame(point_dict) - @property + @cached_property def vm_context( self ) -> pl.DataFrame: @@ -571,10 +572,7 @@ def __repr__(self): return out def _reset_winners(self): - self._winner_param = None - self._winner_param_mean = None - self._winner_param_cov = None - self._winner_param_icov = None + clear_cached_properties(self) @property def vowel_system(self): @@ -584,58 +582,43 @@ def vowel_system(self): def vowel_system(self, vowel_system): self._vowel_system = vowel_system - @property + @cached_property def winners(self): - self._winners = [x.winner for x in self.tracks] - return self._winners + return [x.winner for x in self.tracks] - @property + @cached_property def winner_param( self ) -> NDArray[Shape["Param, Formant, N"], Float]: - if not self._winner_param is None: - return self._winner_param - params = np.array( [ x.parameters for x in self.winners ] ).T - self._winner_param = params return params - @property + @cached_property def winner_param_mean( self ) -> NDArray[Shape["ParamFormant, 1"], Float]: - if self._winner_param_mean is not None: - return self._winner_param_mean N = len(self.winners) winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) winner_mean = winner_mean[:, np.newaxis] - self._winner_param_mean = winner_mean return winner_mean - @property + @cached_property def winner_param_cov( self ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: - if self._winner_param_cov is not None: - return self._winner_param_cov param_cov = param_to_cov(self.winner_param) - self._winner_param_cov = param_cov return param_cov - @property + @cached_property def winner_param_icov( self ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: - if self._winner_param_icov is not None: - return self._winner_param_icov - params_icov = cov_to_icov(self.winner_param_cov) - self._winner_param_icov = params_icov return params_icov def to_param_df( @@ -742,11 +725,6 @@ def __init__(self, track_list:list[VowelMeasurement] = EMPTY_LIST): self._make_tracks_dict() self._dictify() self._vowel_system() - self._winner_param_mean = None - self._winner_param_icov = None - self._winner_maxformant_mean = None - self._winner_maxformant_icov = None - self._textgrid = None self._file_name = None self._corpus = None @@ -775,6 +753,9 @@ def _vowel_system(self): for v in self.tracks_dict: self[v].vowel_system = self + def _reset_winners(self): + clear_cached_properties(self) + @property def corpus(self): return self._corpus @@ -783,7 +764,7 @@ def corpus(self): def corpus(self, corp): self._corpus = corp - @property + @cached_property def winners( self ) -> list[OneTrack]: @@ -803,15 +784,11 @@ def vowel_measurements( for x in vc.tracks ] - @property + @cached_property def textgrid( self ) -> AlignedTextGrid: - if self._textgrid: - return self._textgrid - - self._textgrid = get_textgrid(self.vowel_measurements[0].interval) - return self._textgrid + return get_textgrid(self.vowel_measurements[0].interval) @property def file_name( @@ -823,7 +800,7 @@ def file_name( self._file_name = self.vowel_measurements[0].winner.file_name return self._file_name - @property + @cached_property def winner_param( self ) -> NDArray[Shape["Param, Formant, N"], Float]: @@ -836,20 +813,7 @@ def winner_param( return params - # @property - # def winner_formants( - # self - # ): - # formants = np.hstack( - # [ - # x.formants - # for x in self.winners - # ] - # ) - - # return formants - - @property + @cached_property def winner_expanded_formants( self ) -> NDArray[Shape["20, FormantN"], Float]: @@ -862,7 +826,7 @@ def winner_expanded_formants( return formants - @property + @cached_property def winner_maxformant( self ) -> NDArray[Shape["1, N"], Float]: @@ -874,45 +838,36 @@ def winner_maxformant( return max_formants - @property + @cached_property def winner_param_mean( self ) -> NDArray[Shape["FormantParam"], Float]: - if self._winner_param_mean is not None: - return self._winner_param_mean N = len(self.winners) winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) winner_mean = winner_mean[:, np.newaxis] - self._winner_param_mean = winner_mean return winner_mean - @property + @cached_property def winner_param_cov( self ) -> NDArray[Shape["FormantParam, FormantParam"], Float]: param_cov = param_to_cov(self.winner_param) return param_cov - @property + @cached_property def winner_param_icov( self ) -> NDArray[Shape["FormantParam, FormantParam"], Float] : - if self._winner_param_icov is not None: - return self._winner_param_icov params_icov = cov_to_icov(self.winner_param_cov) - self._winner_param_icov = params_icov return params_icov - @property + @cached_property def winner_maxformant_mean( self ) -> float: - if self._winner_maxformant_mean is not None: - return self._winner_maxformant_mean - self._winner_maxformant_mean = self.winner_maxformant.mean() - return self._winner_maxformant_mean + return self.winner_maxformant.mean() - @property + @cached_property def winner_maxformant_cov( self ) -> NDArray[Shape["1, 1"], Float]: @@ -920,15 +875,11 @@ def winner_maxformant_cov( cov = cov.reshape(1,1) return cov - @property + @cached_property def winner_maxformant_icov( self - ) -> NDArray[Shape["1, 1"], Float]: - if self._winner_maxformant_icov is not None: - return self._winner_maxformant_icov - + ) -> NDArray[Shape["1, 1"], Float]: icov = cov_to_icov(self.winner_maxformant_cov) - self._winner_maxformant_icov = icov return icov def to_tracks_df(self)->pl.DataFrame: @@ -1020,8 +971,10 @@ def _associate_corpus(self): for speaker in self.values(): speaker.corpus = self - @property - @lru_cache + def _reset_winners(self): + clear_cached_properties(self) + + @cached_property def vowel_dict( self ) -> defaultdict[str, list[VowelMeasurement]]: @@ -1031,8 +984,7 @@ def vowel_dict( out[vowel] += speaker[vowel] return out - @property - @lru_cache + @cached_property def vowel_winners( self ) -> defaultdict[str, list[OneTrack]]: @@ -1042,8 +994,7 @@ def vowel_winners( return out - @property - @lru_cache + @cached_property def winner_param( self ) -> defaultdict[str, NDArray[Shape["Param, Formant, N"], Float]]: @@ -1059,8 +1010,7 @@ def winner_param( out[vowel] = params return out - @property - @lru_cache + @cached_property def winner_param_mean( self ) -> defaultdict[str, NDArray[Shape["FormantParam, 1"], Float]]: @@ -1086,8 +1036,7 @@ def winner_param_cov( return out - @property - @lru_cache + @cached_property def winner_param_icov( self )->defaultdict[str, NDArray[Shape["FormantParam, FormantParam"], Float]]: From 8c9042a37fd225529f2fba48b3669014e28df3d6 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Thu, 6 Jun 2024 17:01:12 -0400 Subject: [PATCH 09/28] calc tests --- tests/test_measurements/test_calcs.py | 59 +++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/test_measurements/test_calcs.py diff --git a/tests/test_measurements/test_calcs.py b/tests/test_measurements/test_calcs.py new file mode 100644 index 0000000..638345c --- /dev/null +++ b/tests/test_measurements/test_calcs.py @@ -0,0 +1,59 @@ +from new_fave.measurements.calcs import mahalanobis, \ + mahal_log_prob,\ + param_to_cov,\ + cov_to_icov, \ + clear_cached_properties + +import numpy as np +from functools import cached_property + +NParam = 15 +NToken = 100 + +PARAM = np.random.random(NParam * NToken).reshape(NParam, NToken) + + +def test_param_to_cov(): + cov_mat = param_to_cov(PARAM) + assert cov_mat.shape == (NParam, NParam) + +def test_cov_to_icov(): + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + assert icov_mat.shape == (NParam, NParam) + +def test_mahalanobis(): + mean = PARAM.mean(axis=1) + mean = mean[:, np.newaxis] + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + distances = mahalanobis(PARAM, mean, icov_mat) + assert distances.shape == (NToken,) + +def test_mahalanobis_logprob(): + mean = PARAM.mean(axis=1) + mean = mean[:, np.newaxis] + cov_mat = param_to_cov(PARAM) + icov_mat = cov_to_icov(cov_mat) + distances = mahalanobis(PARAM, mean, icov_mat) + log_prob = mahal_log_prob(distances, PARAM) + assert log_prob.shape == (NToken,) + assert np.all(log_prob < 0) + +def test_clear_cache(): + class MyClass: + @cached_property + def name(self): + return "Cache Test" + + foo = MyClass() + + assert not "name" in foo.__dict__ + + emitted = foo.name + + assert "name" in foo.__dict__ + + clear_cached_properties(foo) + + assert not "name" in foo.__dict__ From 708cd0cba2a10d7c1b42448888677bf7d8042711 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Thu, 6 Jun 2024 17:12:58 -0400 Subject: [PATCH 10/28] improved logprob testing --- .../test_measurements/test_vowel_measurments.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index d683865..e46ba47 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -154,15 +154,16 @@ def test_probs(): Test that the length of log probs is equal to the number of steps """ - for vm in vms: - cand_mahal_log_prob = vm.cand_param_logprob_speaker_global - max_formant_log_prob = vm.cand_maxformant_logprob_speaker_global - error_log_prob = vm.cand_error_logprob_vm - - assert cand_mahal_log_prob.size == NSTEP - assert max_formant_log_prob.size == NSTEP - assert error_log_prob.size == NSTEP + target_properties = [ + x + for x in VowelMeasurement.__dict__.keys() + if "logprob" in x + ] + for vm in vms: + for target in target_properties: + log_prob = getattr(vm, target) + assert log_prob.size == NSTEP, f"{target}" ## output tests def test_vm_context(): From 97cf52b0250e15a5b913554a18f2513e32d2e30a Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Thu, 6 Jun 2024 17:13:22 -0400 Subject: [PATCH 11/28] clear cache on corpus level --- src/new_fave/measurements/vowel_measurement.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index db1dcee..247ce41 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -201,6 +201,7 @@ def winner(self)->OneTrack: @winner.setter def winner(self, idx): self._winner = self.candidates[idx] + self.vowel_class.vowel_system.corpus._reset_winners() self.vowel_class.vowel_system._reset_winners() self.vowel_class._reset_winners() self._expanded_formants = None @@ -346,9 +347,6 @@ def cand_maxformant_mahal_speaker_global( ) -> NDArray[Shape["Cand"], Float]: inv_covmat = self.vowel_class.vowel_system.winner_maxformant_icov maximum_formant_means = self.vowel_class.vowel_system.winner_maxformant_mean - # x_mu = self.cand_maxformant - maximum_formant_means - # left = np.dot(x_mu.T, inv_covmat) - # mahal = np.dot(left, x_mu) mahal = mahalanobis(self.cand_maxformant, maximum_formant_means, inv_covmat) return mahal From da3829f6e74738397d722880caed59170640b965 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Thu, 6 Jun 2024 17:15:47 -0400 Subject: [PATCH 12/28] caught an un-updated cache clearing --- src/new_fave/measurements/vowel_measurement.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 247ce41..add651c 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -731,10 +731,7 @@ def __setitem__(self, __key, __value) -> None: super().__setitem__(__key, __value) def _reset_winners(self): - self._winner_param_mean = None - self._winner_param_icov = None - self._winner_maxformant_mean = None - self._winner_maxformant_icov = None + clear_cached_properties(self) def _make_tracks_dict(self): for v in self.track_list: From 7740313dc0ba55f78b83eb63fc5de9b35f4895f1 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 16:38:42 -0400 Subject: [PATCH 13/28] update to prob test --- tests/test_measurements/test_vowel_measurments.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index e46ba47..f4c7ca5 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -153,6 +153,7 @@ def test_probs(): """ Test that the length of log probs is equal to the number of steps + And all log probs are finite and <= 0 """ target_properties = [ x @@ -164,6 +165,8 @@ def test_probs(): for target in target_properties: log_prob = getattr(vm, target) assert log_prob.size == NSTEP, f"{target}" + assert np.all(np.isfinite(log_prob)) + assert np.all(log_prob <= 0) ## output tests def test_vm_context(): From 8bab1d87163261f9df76b28aea3e2a1602b06a20 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 16:40:37 -0400 Subject: [PATCH 14/28] clearing cache on corpus should be done carefully --- src/new_fave/measurements/vowel_measurement.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index add651c..bf33db4 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -201,7 +201,6 @@ def winner(self)->OneTrack: @winner.setter def winner(self, idx): self._winner = self.candidates[idx] - self.vowel_class.vowel_system.corpus._reset_winners() self.vowel_class.vowel_system._reset_winners() self.vowel_class._reset_winners() self._expanded_formants = None From 0fbd5993cf78397dfc4951da5218ebe7d957cb8d Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 16:57:44 -0400 Subject: [PATCH 15/28] -inf is a possible logprob, so just making sure no nans --- tests/test_measurements/test_vowel_measurments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index f4c7ca5..e7c8735 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -165,7 +165,7 @@ def test_probs(): for target in target_properties: log_prob = getattr(vm, target) assert log_prob.size == NSTEP, f"{target}" - assert np.all(np.isfinite(log_prob)) + assert np.all(~np.isnan(log_prob)) assert np.all(log_prob <= 0) ## output tests From 677cd273290cd6e50ba9e5b1cb3e7fcdbdbe39f5 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 18:06:19 -0400 Subject: [PATCH 16/28] docs work --- docs/_quarto.yml | 63 +++++++++++------- docs/{dev_plan => dev}/assets/ay.wav | Bin .../corpus/josef-fruehwald_speaker.TextGrid | 0 .../assets/corpus/josef-fruehwald_speaker.wav | Bin docs/{dev_plan => dev}/index.qmd | 0 docs/{dev_plan => dev}/new-fave-approach.qmd | 0 .../{usage/dev.qmd => dev/variable_names.qmd} | 2 +- docs/usage/index.qmd | 3 + 8 files changed, 44 insertions(+), 24 deletions(-) rename docs/{dev_plan => dev}/assets/ay.wav (100%) rename docs/{dev_plan => dev}/assets/corpus/josef-fruehwald_speaker.TextGrid (100%) rename docs/{dev_plan => dev}/assets/corpus/josef-fruehwald_speaker.wav (100%) rename docs/{dev_plan => dev}/index.qmd (100%) rename docs/{dev_plan => dev}/new-fave-approach.qmd (100%) rename docs/{usage/dev.qmd => dev/variable_names.qmd} (96%) create mode 100644 docs/usage/index.qmd diff --git a/docs/_quarto.yml b/docs/_quarto.yml index c346953..54a27fd 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -25,8 +25,13 @@ website: style: floating align: left contents: - - index.qmd + - section: Home + contents: + - index.qmd - auto: usage + - section: Dev Notes + contents: + - auto: dev # - usage/getting_started.qmd # - usage/all_arguments.qmd # - usage/pythonic_use.ipynb @@ -82,33 +87,45 @@ quartodoc: - fave_corpus - fave_subcorpora - title: Vowel Measurements - desc: Vowel Measurements + #kind: page options: dynamic: true - contents: - - name: VowelMeasurement - members: - - to_tracks_df - - to_param_df - - to_point_df + contents: + - name: measurements.vowel_measurement + children: linked + - VowelMeasurement + - VowelClass + - VowelClassCollection + - SpeakerCollection + + # - title: Vowel Measurements + # desc: Vowel Measurements + # options: + # dynamic: true + # contents: + # - name: VowelMeasurement + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - - name: VowelClass - members: - - to_tracks_df - - to_param_df - - to_point_df + # - name: VowelClass + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - - name: VowelClassCollection - members: - - to_tracks_df - - to_param_df - - to_point_df + # - name: VowelClassCollection + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - - name: SpeakerCollection - members: - - to_tracks_df - - to_param_df - - to_point_df + # - name: SpeakerCollection + # members: + # - to_tracks_df + # - to_param_df + # - to_point_df - title: Calculations contents: - measurements.calcs.mahalanobis diff --git a/docs/dev_plan/assets/ay.wav b/docs/dev/assets/ay.wav similarity index 100% rename from docs/dev_plan/assets/ay.wav rename to docs/dev/assets/ay.wav diff --git a/docs/dev_plan/assets/corpus/josef-fruehwald_speaker.TextGrid b/docs/dev/assets/corpus/josef-fruehwald_speaker.TextGrid similarity index 100% rename from docs/dev_plan/assets/corpus/josef-fruehwald_speaker.TextGrid rename to docs/dev/assets/corpus/josef-fruehwald_speaker.TextGrid diff --git a/docs/dev_plan/assets/corpus/josef-fruehwald_speaker.wav b/docs/dev/assets/corpus/josef-fruehwald_speaker.wav similarity index 100% rename from docs/dev_plan/assets/corpus/josef-fruehwald_speaker.wav rename to docs/dev/assets/corpus/josef-fruehwald_speaker.wav diff --git a/docs/dev_plan/index.qmd b/docs/dev/index.qmd similarity index 100% rename from docs/dev_plan/index.qmd rename to docs/dev/index.qmd diff --git a/docs/dev_plan/new-fave-approach.qmd b/docs/dev/new-fave-approach.qmd similarity index 100% rename from docs/dev_plan/new-fave-approach.qmd rename to docs/dev/new-fave-approach.qmd diff --git a/docs/usage/dev.qmd b/docs/dev/variable_names.qmd similarity index 96% rename from docs/usage/dev.qmd rename to docs/dev/variable_names.qmd index 6a49347..93b1ff8 100644 --- a/docs/usage/dev.qmd +++ b/docs/dev/variable_names.qmd @@ -1,5 +1,5 @@ --- -title: Dev Notes +title: Variable Naming Conventions --- ## Property naming descriptors diff --git a/docs/usage/index.qmd b/docs/usage/index.qmd new file mode 100644 index 0000000..198f514 --- /dev/null +++ b/docs/usage/index.qmd @@ -0,0 +1,3 @@ +--- +title: Usage +--- \ No newline at end of file From ea1f6a5dfd8c10783eefcb4977efb2c404c41695 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 18:23:20 -0400 Subject: [PATCH 17/28] docs work --- .../measurements/vowel_measurement.py | 92 +++++++++++++------ 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index bf33db4..44e5bbe 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -1,3 +1,41 @@ +""" +This module contains classes to represent vowel measurements and their +aggregations at different levels. + +```{mermaid} +classDiagram +direction LR + +class VowelMeasurement~list~{ + .vowel_class +} +class VowelClass~list~{ + .vowel_system +} +class VowelClassCollection~dict~{ + .corpus +} +class SpeakerCollection~dict~ + +SpeakerCollection --o VowelClassCollection +VowelClassCollection --o VowelClass +VowelClass --o VowelMeasurement +``` + +When a class has a numpy array for an attribute, its +type is annotated using [nptyping](https://pypi.org/project/nptyping/) +to provide the expected dimensions. For example: + +``` +cand_param (NDArray[Shape["Param, Formant, Cand"], Float]) +``` + +This indicates that `cand_param` is a three dimensional array. +The first dimension is `"Param"` (the number of DCT parameters) +long, the second is `"Formant"` (the number of formants) long, +and the third is `"Cand"` (the number of candidates) long. +""" + from fasttrackpy import CandidateTracks, OneTrack from aligned_textgrid import AlignedTextGrid, SequenceInterval from fave_measurement_point.heuristic import Heuristic @@ -91,37 +129,37 @@ class VowelMeasurement(Sequence): The number of optimization iterations the vowel measurement has been through. - winner: fasttrackpy.OneTrack The winning formant track winner_index (int): The index of the winning formant track - - error_log_prob (np.array): - A conversion of the log-mean-squared-error to a - log-probabilities, based on an empirical cumulative - density function. - cand_errors (np.array): - A numpy array of the log-mean-squared-errors - for each candidate track. - cand_mahals (np.array): - The mahalanobis distance across DCT parameters - for each candidate from the vowel system - distribution. - cand_mahal_log_prob (np.array): - A conversion of `cand_mahals` to log-probabilies. - cand_max_formants (np.array): - A numpy array of the maximum formants for - this VowelMeasurement - cand_params (np.array): - A numpy array of the candidate track - DCT parameters. - max_formant_log_prob (np.array): - A conversion of `max_formant_mahal` to log-probabilities. - max_formant_mahal (np.array): - The mahalanobis distance of each - maximum formant to the speaker's entire - distribution. + + cand_param (NDArray[Shape["Param, Formant, Cand"], Float]): + A array of the candidate DCT parameters. + cand_maxformant (NDArray[Shape["1, Cand"], Float]): + An array of the candidate maximum formants. + cand_error (NDArray[Shape["Cand"], Float]): + An array of the candidate smoothing error. + + cand_error_logprob_vm (NDArray[Shape["Cand"], Float]): + Conversion of the smooth error to log probabilities. The candidate with + the lowest error = log(1), and the candidate with the largest + error = log(0). + cand_param_(mahal/logprob)_speaker_byvclass (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to the VowelClass for this speaker. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class` + cand_param_(mahal/logprob)_speaker_global (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to *all* vowel measurements for this speaker. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class.vowel_system` + cand_param_(mahal/logprob)_corpus_byvclass (NDArray[Shape["Cand"], Float]): + The mahalanobis distance (`mahal`) or associated log probability (`logprob`) + for each candidate relative to this vowel class across all speakers. + These are calculated by drawing the relevant mean and covariance matrix from + `vm.vowel_class.vowel_system.corpus` point_measure (pl.DataFrame): A polars dataframe of the point measurement for this vowel. From 1ababf208b36b8ac4ca819c9db3afc9cd9f2b5f8 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Fri, 7 Jun 2024 19:05:00 -0400 Subject: [PATCH 18/28] working on docstrings --- .../measurements/vowel_measurement.py | 273 ++++++++---------- 1 file changed, 121 insertions(+), 152 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 44e5bbe..69333af 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -35,7 +35,7 @@ class SpeakerCollection~dict~ long, the second is `"Formant"` (the number of formants) long, and the third is `"Cand"` (the number of candidates) long. """ - +import fasttrackpy from fasttrackpy import CandidateTracks, OneTrack from aligned_textgrid import AlignedTextGrid, SequenceInterval from fave_measurement_point.heuristic import Heuristic @@ -75,7 +75,77 @@ def blank_list(): return [] EMPTY_LIST = blank_list() + +class StatPropertyMixins: + + @cached_property + def winner_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: + params = np.array( + [ + x.parameters + for x in self.winners + ] + ).T + return params + + @cached_property + def winner_maxformant( + self + ) -> NDArray[Shape["1, N"], Float]: + max_formants = np.array([[ + x.maximum_formant + for x in self.winners + ]]) + + return max_formants + + @cached_property + def winner_param_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: + N = len(self.winners) + winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + return winner_mean + + @cached_property + def winner_param_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + param_cov = param_to_cov(self.winner_param) + return param_cov + + @cached_property + def winner_param_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + params_icov = cov_to_icov(self.winner_param_cov) + return params_icov + + @cached_property + def winner_maxformant_mean( + self + ) -> float: + return self.winner_maxformant.mean() + + @cached_property + def winner_maxformant_cov( + self + ) -> NDArray[Shape["1, 1"], Float]: + cov = param_to_cov(self.winner_maxformant) + cov = cov.reshape(1,1) + return cov + @cached_property + def winner_maxformant_icov( + self + ) -> NDArray[Shape["1, 1"], Float]: + icov = cov_to_icov(self.winner_maxformant_cov) + return icov + + @dataclass class VowelMeasurement(Sequence): """ A class used to represent a vowel measurement. @@ -543,7 +613,7 @@ def to_point_df(self) -> pl.DataFrame: return(df) @dataclass -class VowelClass(Sequence): +class VowelClass(Sequence, StatPropertyMixins): """A class used to represent a vowel class. ## Intended Usage @@ -557,7 +627,6 @@ class VowelClass(Sequence): vowel_measurements = [VowelMeasurement(t) for t in fasttrack_tracks] vowel_class = VowelClass("ay", vowel_measurements) ``` - Args: label (str): @@ -566,18 +635,22 @@ class VowelClass(Sequence): A list of VowelMeasurements Attributes: - label (str): + label (str): label of the vowel class - tracks (list): - A list of `VowelMeasurement`s + tracks (list): + A list of VowelMeasurements vowel_system (VowelClassCollection): - A the containing vowel system - winners (list[fasttrackpy.OneTrack]): - A list of winner OneTracks from - the vowel class - winner_param (np.array): - An `np.array` of winner DCT parameters - from the vowel class. + The containing vowel system + winners (list[OneTrack]): + A list of winner [](`~fasttrackpy.OneTrack`)s from the vowel class + winner_param (NDArray[Shape["Param, Formant, N"], Float]): + An np.array of winner DCT parameters from the vowel class + winner_param_mean (NDArray[Shape["ParamFormant, 1"], Float]): + Mean of winner DCT parameters + winner_param_cov (NDArray[Shape["ParamFormant, ParamFormant"], Float]): + Covariance of winner DCT parameters + winner_param_icov (NDArray[Shape["ParamFormant, ParamFormant"], Float]): + Inverse covariance of winner DCT parameters """ label: str = field(default="") tracks: list[VowelMeasurement] = field(default_factory= lambda : []) @@ -621,41 +694,6 @@ def vowel_system(self, vowel_system): def winners(self): return [x.winner for x in self.tracks] - @cached_property - def winner_param( - self - ) -> NDArray[Shape["Param, Formant, N"], Float]: - params = np.array( - [ - x.parameters - for x in self.winners - ] - ).T - return params - - @cached_property - def winner_param_mean( - self - ) -> NDArray[Shape["ParamFormant, 1"], Float]: - N = len(self.winners) - winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) - winner_mean = winner_mean[:, np.newaxis] - return winner_mean - - @cached_property - def winner_param_cov( - self - ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: - param_cov = param_to_cov(self.winner_param) - return param_cov - - @cached_property - def winner_param_icov( - self - ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: - params_icov = cov_to_icov(self.winner_param_cov) - return params_icov - def to_param_df( self, output:Literal["param", "log_param"] = "log_param" @@ -700,7 +738,7 @@ def to_point_df(self) -> pl.DataFrame: return df -class VowelClassCollection(defaultdict): +class VowelClassCollection(defaultdict, StatPropertyMixins): """ A class for an entire vowel system. @@ -718,39 +756,39 @@ class VowelClassCollection(defaultdict): A list of `VowelMeasurement`s. Attributes: - maximum_formant_cov (np.array): - The covariance matrix for the winners maximum formant - across the entire vowel system - maximum_formant_means (np.array): - The mean maximum formant for the winners - across the entire vowel system - max_formant_icov (np.array): - The inverse covariance matrix for the winners maximum formant - across the entire vowel system - params_covs (np.array): - The covariance matrix for the winners' DCT - parameters. - params_icov (np.array): - The inverse covariance matrix for the winners' - DCT parameters. - params_means (np.array): - An `np.array` for the winners' DCT parameters - in the entire vowel system. - vowel_measurements (list[VowelMeasurement]): - A list of all vowel measurements in the - vowel system - winner_formants (np.array): - An `np.array` for the formants - for the winners in the entire vowel system. - winner_params (np.array): - An `np.array` of DCT parameters for - the winners in entire vowel system. - winners (list[fasttrackpy.OneTrack]): - The winning `fasttrackpy.OneTrack` for - the entire vowel system - winners_maximum_formant (np.array): - An `np.array` of the maximum formants - for the winners in the entire vowel system + winners (list[OneTrack]): + All winner tracks from the entire vowel system. + vowel_measurements (list[VowelMeasurement]): + All `VowelMeasurement` objects within this vowel system + textgrid (AlignedTextGrid): + The `AlignedTextGrid` associated with this vowel system. + winner_expanded_formants (NDArray[Shape["20, FormantN"], Float]): + A cached property that returns the expanded formants for the winners. + + + winner_param (NDArray[Shape["Param, Formant, N"], Float]): + An array of all parameters from all winners across the + vowel system. + winner_maxformant (NDArray[Shape["1, N"], Float]): + An array of the maximum formants of all winners across + the vowel system + + winner_param_mean (NDArray[Shape["1, FormantParam"], Float]): + The mean of all DCT parameters across all formants for the winners + in this vowel system. + winner_param_cov (NDArray[Shape["FormantParam, FormantParam"], Float]): + The covariance of all parameters across all formants for the winners + in this vowel system + winner_param_icov (NDArray[Shape["FormantParam, FormantParam"], Float]): + The inverse of `winner_param_cov`. + + winner_maxformant_mean (float): + The mean maximum formant across all winners in this vowel system. + winner_maxformant_cov (NDArray[Shape["1, 1"], Float]): + The covariance of the maximum formant across all winners + in this vowel system. + winner_maxformant_icov (NDArray[Shape["1, 1"], Float]): + The inverse of `winner_maxformant_cov` """ def __init__(self, track_list:list[VowelMeasurement] = EMPTY_LIST): super().__init__(blank) @@ -831,19 +869,6 @@ def file_name( self._file_name = self.vowel_measurements[0].winner.file_name return self._file_name - - @cached_property - def winner_param( - self - ) -> NDArray[Shape["Param, Formant, N"], Float]: - params = np.array( - [ - x.parameters - for x in self.winners - ] - ).T - - return params @cached_property def winner_expanded_formants( @@ -857,62 +882,6 @@ def winner_expanded_formants( ) return formants - - @cached_property - def winner_maxformant( - self - ) -> NDArray[Shape["1, N"], Float]: - max_formants = np.array([[ - x.maximum_formant - for x in self.winners - ]]) - - return max_formants - - - @cached_property - def winner_param_mean( - self - ) -> NDArray[Shape["FormantParam"], Float]: - N = len(self.winners) - winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) - winner_mean = winner_mean[:, np.newaxis] - return winner_mean - - @cached_property - def winner_param_cov( - self - ) -> NDArray[Shape["FormantParam, FormantParam"], Float]: - param_cov = param_to_cov(self.winner_param) - return param_cov - - @cached_property - def winner_param_icov( - self - ) -> NDArray[Shape["FormantParam, FormantParam"], Float] : - params_icov = cov_to_icov(self.winner_param_cov) - return params_icov - - @cached_property - def winner_maxformant_mean( - self - ) -> float: - return self.winner_maxformant.mean() - - @cached_property - def winner_maxformant_cov( - self - ) -> NDArray[Shape["1, 1"], Float]: - cov = param_to_cov(self.winner_maxformant) - cov = cov.reshape(1,1) - return cov - - @cached_property - def winner_maxformant_icov( - self - ) -> NDArray[Shape["1, 1"], Float]: - icov = cov_to_icov(self.winner_maxformant_cov) - return icov def to_tracks_df(self)->pl.DataFrame: """Return a DataFrame of the formant tracks @@ -956,7 +925,7 @@ def to_point_df(self) -> pl.DataFrame: return df -class SpeakerCollection(defaultdict): +class SpeakerCollection(defaultdict, StatPropertyMixins): """ A class to represent the vowel system of all speakers in a TextGrid. From 4a7b878d06356e33ad5d233d88cc5839576c8a2c Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 10:16:59 -0400 Subject: [PATCH 19/28] conflict resolution --- poetry.lock | 8 +- pyproject.toml | 2 +- .../measurements/vowel_measurement.py | 94 ++++++++++++++++++- src/new_fave/optimize/optimize.py | 22 +++-- .../test_vowel_measurments.py | 7 +- 5 files changed, 116 insertions(+), 17 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6e2eb03..5e7cea9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -821,14 +821,14 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "fasttrackpy" -version = "0.4.7" +version = "0.4.8" description = "A python implementation of FastTrack" category = "main" optional = false python-versions = "<3.13,>=3.10" files = [ - {file = "fasttrackpy-0.4.7-py3-none-any.whl", hash = "sha256:ed5043e18455851abc76ad2a451e2774321b12dacfb60fc1cdda6d828a33771c"}, - {file = "fasttrackpy-0.4.7.tar.gz", hash = "sha256:ff6aa89a05cfbfaf806cac59873c263fce371f4b6d119a3fbb3936413c1c5838"}, + {file = "fasttrackpy-0.4.8-py3-none-any.whl", hash = "sha256:95de91df09237c7defdac5b209d875c5c3e4b3aa703ecffe2b1e8604932e09ad"}, + {file = "fasttrackpy-0.4.8.tar.gz", hash = "sha256:2b54cdc338a80b905cae2c299ed4f3bda48587621d6a4dbecccf6068eb558652"}, ] [package.dependencies] @@ -4068,4 +4068,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "8dfc857869aa848a81242cb1a192b2138571a4a17078a3cc8c0d69967d0afe68" +content-hash = "8b58df8e65cb17ef83f3c76a9513f237bdc5b73c7815eb6672743d1b9cc488c9" diff --git a/pyproject.toml b/pyproject.toml index 04461a0..9494db0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ repository = "https://github.com/Forced-Alignment-and-Vowel-Extraction/new-fave" [tool.poetry.dependencies] python = ">=3.11,<3.12" aligned-textgrid = "^0.6.7" -fasttrackpy = "^0.4.7" +fasttrackpy = "^0.4.8" numpy = "^1.26.4" tqdm = "^4.66.2" fave-recode = "^0.3.0" diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index a0d81ff..0615664 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -27,7 +27,87 @@ def blank_list(): return [] EMPTY_LIST = blank_list() + +class StatPropertyMixins: + + @cached_property + def winner_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: + params = np.array( + [ + x.parameters + for x in self.winners + ] + ).T + return params + + @cached_property + def winner_bandwidth_param( + self + ) -> NDArray[Shape["Param, Formant, N"], Float]: + params = np.array([ + x.bandwidth_parameters + for x in self.winners + ]) + return params + + @cached_property + def winner_maxformant( + self + ) -> NDArray[Shape["1, N"], Float]: + max_formants = np.array([[ + x.maximum_formant + for x in self.winners + ]]) + + return max_formants + + @cached_property + def winner_param_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: + N = len(self.winners) + winner_mean = self.winner_param.reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + return winner_mean + + @cached_property + def winner_param_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + param_cov = param_to_cov(self.winner_param) + return param_cov + + @cached_property + def winner_param_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + params_icov = cov_to_icov(self.winner_param_cov) + return params_icov + @cached_property + def winner_maxformant_mean( + self + ) -> float: + return self.winner_maxformant.mean() + + @cached_property + def winner_maxformant_cov( + self + ) -> NDArray[Shape["1, 1"], Float]: + cov = param_to_cov(self.winner_maxformant) + cov = cov.reshape(1,1) + return cov + + @cached_property + def winner_maxformant_icov( + self + ) -> NDArray[Shape["1, 1"], Float]: + icov = cov_to_icov(self.winner_maxformant_cov) + return icov + + @dataclass class VowelMeasurement(Sequence): """ A class used to represent a vowel measurement. @@ -227,9 +307,21 @@ def cand_params(self): ).T return params + + @property + def cand_bandwidth_param( + self + ) -> NDArray[Shape["Param, Formant, Cand"], Float]: + params = np.array([ + x.bandwidth_parameters + for x in self.candidates + ]) + @property - def cand_max_formants(self): + def cand_maxformant( + self + ) -> NDArray[Shape["1, Cand"], Float]: return np.array([[ c.maximum_formant for c in self.candidates diff --git a/src/new_fave/optimize/optimize.py b/src/new_fave/optimize/optimize.py index 3b1afce..6fd2e4f 100644 --- a/src/new_fave/optimize/optimize.py +++ b/src/new_fave/optimize/optimize.py @@ -8,7 +8,8 @@ def run_optimize( vowel_system: VowelClassCollection, - optim_params = ["cand_mahal", "vclass_mahal", "max_formant"], + optim_params: list[Literal["cand_mahal", "vclass_mahal","corpus_mahal", "max_formant"]] = + ["cand_mahal", "vclass_mahal", "max_formant"], max_iter = 10 ): """ @@ -20,7 +21,7 @@ def run_optimize( The vowel space to be optimized optim_params (list, optional): The parameters to use for optimization. - Defaults to ["cand_mahal", "max_formant"]. + Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. max_iter (int, optional): The maximum number of iterations to run. Defaults to 10. @@ -51,7 +52,7 @@ def run_optimize( def optimize_vowel_measures( vowel_measurements: list[VowelMeasurement], optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "max_formant"] + Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"] ] = ["cand_mahal", "vclass_mahal", "max_formant"] ): """ @@ -60,8 +61,8 @@ def optimize_vowel_measures( Args: vowel_measurements (list[VowelMeasurement]): The list of vowel measurements to optimize - optim_params (list[Literal["cand_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "max_formant"]. + optim_params (list[Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"]], optional): + The optimization parameters to use. Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. """ new_winners = [ @@ -80,7 +81,7 @@ def optimize_vowel_measures( def optimize_one_measure( vowel_measurement: VowelMeasurement, optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "max_formant"] + Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"] ] = ["cand_mahal", "vclass_mahal", "max_formant"] )->int: """ @@ -91,8 +92,8 @@ def optimize_one_measure( Args: vowel_measurement (VowelMeasurement): The VowelMeasurement to optimize - optim_params (list[Literal["cand_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "max_formant"]. + optim_params (list[Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"]], optional): + The optimization parameters to use. Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. Returns: (int): The index of the winning candidate. @@ -103,7 +104,10 @@ def optimize_one_measure( prob_dict["cand_mahal"] = vowel_measurement.cand_mahal_log_prob if "vclass_mahal" in optim_params: - prob_dict["vclass_mahal"] = vowel_measurement.cand_vclass_mahal_log_prob + prob_dict["vclass_mahal"] = vowel_measurement.cand_param_logprob_speaker_byvclass + + if "corpus_mahal" in optim_params: + prob_dict["corpus_mahal"] = vowel_measurement.cand_param_logprob_corpus_byvowel if "max_formant" in optim_params: prob_dict["max_formant"] = vowel_measurement.max_formant_log_prob diff --git a/tests/test_measurements/test_vowel_measurments.py b/tests/test_measurements/test_vowel_measurments.py index a855699..c60f67b 100644 --- a/tests/test_measurements/test_vowel_measurments.py +++ b/tests/test_measurements/test_vowel_measurments.py @@ -2,6 +2,7 @@ from fasttrackpy import CandidateTracks, OneTrack, process_corpus from pathlib import Path from functools import reduce +from copy import copy import polars as pl import numpy as np @@ -86,10 +87,12 @@ def test_winner_reset(): speaker = speakers[first_speaker] speaker_vms = speaker.vowel_measurements - initial_mean = speaker.maximum_formant_means + initial_mean = copy(speaker.winner_maxformant_mean) + assert "winner_maxformant_mean" in speaker.__dict__ initial_index = speaker_vms[0].winner_index - speaker_vms[0].winner = initial_index+1 + speaker_vms[0].winner = initial_index+2 + assert not "winner_maxformant_mean" in speaker.__dict__ new_mean = speaker.maximum_formant_means From 79ea8102cfbf3f0be09247a4702599fce33bc04a Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 11:50:49 -0400 Subject: [PATCH 20/28] crawl up mro to clear cached properties --- src/new_fave/measurements/calcs.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/new_fave/measurements/calcs.py b/src/new_fave/measurements/calcs.py index e8573b7..af2d596 100644 --- a/src/new_fave/measurements/calcs.py +++ b/src/new_fave/measurements/calcs.py @@ -115,9 +115,13 @@ def clear_cached_properties(obj:object) -> None: Args: obj (object): Any object. """ - cls = obj.__class__ - to_clear = [ - k for k, v in vars(cls).items() + clses = obj.__class__.mro() + to_clear = [] + + to_clear += [ + k + for cls in clses + for k, v in vars(cls).items() if isinstance(v, functools.cached_property) ] for var in to_clear: From 7b914cff69a0fd42dca5b13850e7c009e524cf2f Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:45:09 -0400 Subject: [PATCH 21/28] incorporate bandwidth params --- .../measurements/vowel_measurement.py | 88 +++++++++++++++-- src/new_fave/optimize/optimize.py | 98 ++++++++++++++----- 2 files changed, 154 insertions(+), 32 deletions(-) diff --git a/src/new_fave/measurements/vowel_measurement.py b/src/new_fave/measurements/vowel_measurement.py index 3d1e8eb..c4a7add 100644 --- a/src/new_fave/measurements/vowel_measurement.py +++ b/src/new_fave/measurements/vowel_measurement.py @@ -91,13 +91,13 @@ def winner_param( return params @cached_property - def winner_bandwidth_param( + def winner_bparam( self ) -> NDArray[Shape["Param, Formant, N"], Float]: params = np.array([ x.bandwidth_parameters for x in self.winners - ]) + ]).T return params @cached_property @@ -120,6 +120,16 @@ def winner_param_mean( winner_mean = winner_mean[:, np.newaxis] return winner_mean + @cached_property + def winner_bparam_mean( + self + ) -> NDArray[Shape["ParamFormant, 1"], Float]: + N = len(self.winners) + winner_mean = self.winner_bparam.reshape(-1, N).mean(axis = 1) + winner_mean = winner_mean[:, np.newaxis] + return winner_mean + pass + @cached_property def winner_param_cov( self @@ -134,6 +144,21 @@ def winner_param_icov( params_icov = cov_to_icov(self.winner_param_cov) return params_icov + @cached_property + def winner_bparam_cov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + param_cov = param_to_cov(self.winner_bparam) + return param_cov + + @cached_property + def winner_bparam_icov( + self + ) -> NDArray[Shape["ParamFormant, ParamFormant"], Float]: + params_icov = cov_to_icov(self.winner_bparam_cov) + return params_icov + + @cached_property def winner_maxformant_mean( self @@ -309,7 +334,7 @@ def vowel_class(self): return self._vclass @vowel_class.setter - def vowel_class(self, vclass): + def vowel_class(self, vclass: 'VowelClass'): self._vclass = vclass @property @@ -361,14 +386,15 @@ def cand_param( return params @property - def cand_bandwidth_param( + def cand_bparam( self ) -> NDArray[Shape["Param, Formant, Cand"], Float]: params = np.array([ x.bandwidth_parameters for x in self.candidates ]) - + + return params @property def cand_maxformant( @@ -466,7 +492,55 @@ def cand_param_logprob_corpus_byvowel( self.cand_param_mahal_corpus_byvowel, self.cand_param ) - return log_prob + return log_prob + + @property + def cand_bparam_mahal_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + N = len(self.candidates) + square_params = self.cand_bparam.reshape(-1, N) + inv_covmat = self.vowel_class.winner_bparam_icov + param_means = self.vowel_class.winner_bparam_mean + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal + + @property + def cand_bparam_logprob_speaker_byvclass( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_bparam_mahal_speaker_byvclass, + self.cand_bparam + ) + if len(self.vowel_class) < 10: + log_prob = np.zeros(shape = log_prob.shape) + return log_prob + + @property + def cand_bparam_mahal_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + N = len(self.candidates) + square_params = self.cand_bparam.reshape(-1, N) + inv_covmat = self.vowel_class.vowel_system.winner_bparam_icov + param_means = self.vowel_class.vowel_system.winner_bparam_mean + mahal = mahalanobis(square_params, param_means, inv_covmat) + return mahal + + @property + def cand_bparam_logprob_speaker_global( + self + ) -> NDArray[Shape["Cand"], Float]: + log_prob = mahal_log_prob( + self.cand_bparam_mahal_speaker_global, + self.cand_bparam + ) + if len(self.vowel_class) < 10: + log_prob = np.zeros(shape = log_prob.shape) + return log_prob + + @property def cand_maxformant_mahal_speaker_global( @@ -707,7 +781,7 @@ def vowel_system(self): return self._vowel_system @vowel_system.setter - def vowel_system(self, vowel_system): + def vowel_system(self, vowel_system: 'VowelClassCollection'): self._vowel_system = vowel_system @cached_property diff --git a/src/new_fave/optimize/optimize.py b/src/new_fave/optimize/optimize.py index fc66299..7f71c7a 100644 --- a/src/new_fave/optimize/optimize.py +++ b/src/new_fave/optimize/optimize.py @@ -8,10 +8,26 @@ def run_optimize( vowel_system: VowelClassCollection, - optim_params: list[Literal["cand_mahal", "vclass_mahal","corpus_mahal", "max_formant"]] = - ["cand_mahal", "vclass_mahal", "max_formant"], + optim_params: list[ + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ], max_iter = 10 ): + + """ Repeatedly run optimization until either `max_iter` is reached, or the difference between two iterations becomes small. @@ -19,9 +35,8 @@ def run_optimize( Args: vowel_system (VowelClassCollection): The vowel space to be optimized - optim_params (list, optional): - The parameters to use for optimization. - Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. max_iter (int, optional): The maximum number of iterations to run. Defaults to 10. @@ -52,8 +67,21 @@ def run_optimize( def optimize_vowel_measures( vowel_measurements: list[VowelMeasurement], optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"] - ] = ["cand_mahal", "vclass_mahal", "max_formant"] + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ] ): """ Optimize a list of VowelMeasurements. @@ -61,8 +89,8 @@ def optimize_vowel_measures( Args: vowel_measurements (list[VowelMeasurement]): The list of vowel measurements to optimize - optim_params (list[Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. """ new_winners = [ @@ -81,36 +109,56 @@ def optimize_vowel_measures( def optimize_one_measure( vowel_measurement: VowelMeasurement, optim_params: list[ - Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"] - ] = ["cand_mahal", "vclass_mahal", "max_formant"] + Literal[ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global", + "param_corpus_byvowel" + ] + ] = [ + "param_speaker_global", + "param_speaker_byvclass", + "bparam_speaker_global", + "bparam_speaker_byvclass", + "maxformant_speaker_global" + ] )->int: """ + Optimize a single vowel measurement + This function optimizes a given vowel measurement based on the - specified optimization parameters. The optimization parameters - can include 'cand_mahal' and 'max_formant'. + specified optimization parameters. Args: vowel_measurement (VowelMeasurement): The VowelMeasurement to optimize - optim_params (list[Literal["cand_mahal", "vclass_mahal", "corpus_mahal", "max_formant"]], optional): - The optimization parameters to use. Defaults to ["cand_mahal", "vclass_mahal", "max_formant"]. + optim_params (list[Literal["param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global", "param_corpus_byvowel"]], optional): + The optimization parameters to use. Defaults to [ "param_speaker_global", "param_speaker_byvclass", "bparam_speaker_global", "bparam_speaker_byvclass", "maxformant_speaker_global" ]. Returns: - (int): The index of the winning candidate. + int: _description_ """ prob_dict = dict() - if "cand_mahal" in optim_params: - prob_dict["cand_mahal"] = vowel_measurement.cand_param_logprob_speaker_global + if "param_speaker_global" in optim_params: + prob_dict["param_speaker_global"] = vowel_measurement.cand_param_logprob_speaker_global - if "vclass_mahal" in optim_params: - prob_dict["vclass_mahal"] = vowel_measurement.cand_param_logprob_speaker_byvclass - - if "corpus_mahal" in optim_params: - prob_dict["corpus_mahal"] = vowel_measurement.cand_param_logprob_corpus_byvowel + if "param_speaker_byvclass" in optim_params: + prob_dict["param_speaker_byvclass"] = vowel_measurement.cand_param_logprob_speaker_byvclass + + if "bparam_speaker_global" in optim_params: + prob_dict["bparam_speaker_global"] = vowel_measurement.cand_bparam_logprob_speaker_global + + if "bparam_speaker_byvclass" in optim_params: + prob_dict["bparam_speaker_byvclass"] = vowel_measurement.cand_bparam_logprob_speaker_byvclass + + if "param_corpus_byvclass" in optim_params: + prob_dict["param_corpus_byvclass"] = vowel_measurement.cand_param_logprob_corpus_byvowel - if "max_formant" in optim_params: - prob_dict["max_formant"] = vowel_measurement.cand_maxformant_logprob_speaker_global + if "maxformant_speaker_global" in optim_params: + prob_dict["maxformant_speaker_global"] = vowel_measurement.cand_maxformant_logprob_speaker_global joint_prob = vowel_measurement.cand_error_logprob_vm for dim in optim_params: From 103aa4a6301ededc0fe41bf2e7a4bf0cf9331d9d Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:45:20 -0400 Subject: [PATCH 22/28] implement version --- src/new_fave/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/new_fave/__init__.py b/src/new_fave/__init__.py index 6826c77..8a4696e 100644 --- a/src/new_fave/__init__.py +++ b/src/new_fave/__init__.py @@ -8,6 +8,10 @@ from new_fave.patterns.fave_subcorpora import fave_subcorpora from new_fave.patterns.writers import write_data, pickle_speakers, unpickle_speakers +from importlib.metadata import version + +___version__ = version("new-fave") + __all__ = [ "VowelMeasurement", "VowelClass", @@ -18,5 +22,6 @@ "fave_subcorpora", "write_data", "pickle_speakers", - "unpickle_speakers" + "unpickle_speakers", + "__version__" ] \ No newline at end of file From d6b744ebb270080ad28672314770b83ba882ee0d Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:45:30 -0400 Subject: [PATCH 23/28] update dev notes --- docs/dev/variable_names.qmd | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/dev/variable_names.qmd b/docs/dev/variable_names.qmd index 93b1ff8..803f894 100644 --- a/docs/dev/variable_names.qmd +++ b/docs/dev/variable_names.qmd @@ -20,6 +20,7 @@ title: Variable Naming Conventions - `param`: The DCT parameters - `maxformant`: The maximum formant - `error`: The smoothing error term +- `bparam`: The formant bandwidths parameters ### Summary Descriptors From 77a04d7bfd4d2297874cdda2ce7461739ef3bbe0 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:47:18 -0400 Subject: [PATCH 24/28] updating lock file --- poetry.lock | 463 ++++++++++++++++++++++++++-------------------------- 1 file changed, 235 insertions(+), 228 deletions(-) diff --git a/poetry.lock b/poetry.lock index da17281..62745a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -270,14 +270,14 @@ css = ["tinycss2 (>=1.1.0,<1.3)"] [[package]] name = "bokeh" -version = "3.4.1" +version = "3.4.2" description = "Interactive plots and applications in the browser from Python" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "bokeh-3.4.1-py3-none-any.whl", hash = "sha256:1e3c502a0a8205338fc74dadbfa321f8a0965441b39501e36796a47b4017b642"}, - {file = "bokeh-3.4.1.tar.gz", hash = "sha256:d824961e4265367b0750ce58b07e564ad0b83ca64b335521cd3421e9b9f10d89"}, + {file = "bokeh-3.4.2-py3-none-any.whl", hash = "sha256:931a43ee59dbf1720383ab904f8205e126b85561aac55592415b800c96f1b0eb"}, + {file = "bokeh-3.4.2.tar.gz", hash = "sha256:a16d5cc0abb93d2d270d70fc35851f3e1b9208814a985a4678e0ba5ef2d9cd42"}, ] [package.dependencies] @@ -638,64 +638,64 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" -version = "7.5.3" +version = "7.5.4" description = "Code coverage measurement for Python" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, - {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, - {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, - {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, - {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, - {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, - {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, - {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, - {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, - {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, - {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, - {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, - {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, - {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, - {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, - {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, - {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, - {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, - {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, - {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, - {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, - {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, - {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, - {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, - {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, - {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, - {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, - {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, + {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, + {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, + {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, + {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, + {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, + {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, + {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, + {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, + {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, + {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, + {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, + {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, + {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, + {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, + {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, + {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, + {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, + {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, + {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, + {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, + {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, + {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, + {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, + {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, + {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, + {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, + {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, ] [package.extras] @@ -719,34 +719,34 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "debugpy" -version = "1.8.1" +version = "1.8.2" description = "An implementation of the Debug Adapter Protocol for Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, - {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, - {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, - {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, - {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, - {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, - {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, - {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, - {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, - {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, - {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, - {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, - {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, - {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, - {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, - {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, - {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, - {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, - {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, - {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, - {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, - {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, + {file = "debugpy-1.8.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:7ee2e1afbf44b138c005e4380097d92532e1001580853a7cb40ed84e0ef1c3d2"}, + {file = "debugpy-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8c3f7c53130a070f0fc845a0f2cee8ed88d220d6b04595897b66605df1edd6"}, + {file = "debugpy-1.8.2-cp310-cp310-win32.whl", hash = "sha256:f179af1e1bd4c88b0b9f0fa153569b24f6b6f3de33f94703336363ae62f4bf47"}, + {file = "debugpy-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:0600faef1d0b8d0e85c816b8bb0cb90ed94fc611f308d5fde28cb8b3d2ff0fe3"}, + {file = "debugpy-1.8.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8a13417ccd5978a642e91fb79b871baded925d4fadd4dfafec1928196292aa0a"}, + {file = "debugpy-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acdf39855f65c48ac9667b2801234fc64d46778021efac2de7e50907ab90c634"}, + {file = "debugpy-1.8.2-cp311-cp311-win32.whl", hash = "sha256:2cbd4d9a2fc5e7f583ff9bf11f3b7d78dfda8401e8bb6856ad1ed190be4281ad"}, + {file = "debugpy-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:d3408fddd76414034c02880e891ea434e9a9cf3a69842098ef92f6e809d09afa"}, + {file = "debugpy-1.8.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:5d3ccd39e4021f2eb86b8d748a96c766058b39443c1f18b2dc52c10ac2757835"}, + {file = "debugpy-1.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62658aefe289598680193ff655ff3940e2a601765259b123dc7f89c0239b8cd3"}, + {file = "debugpy-1.8.2-cp312-cp312-win32.whl", hash = "sha256:bd11fe35d6fd3431f1546d94121322c0ac572e1bfb1f6be0e9b8655fb4ea941e"}, + {file = "debugpy-1.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:15bc2f4b0f5e99bf86c162c91a74c0631dbd9cef3c6a1d1329c946586255e859"}, + {file = "debugpy-1.8.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5a019d4574afedc6ead1daa22736c530712465c0c4cd44f820d803d937531b2d"}, + {file = "debugpy-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f062d6877d2e45b112c0bbade9a17aac507445fd638922b1a5434df34aed02"}, + {file = "debugpy-1.8.2-cp38-cp38-win32.whl", hash = "sha256:c78ba1680f1015c0ca7115671fe347b28b446081dada3fedf54138f44e4ba031"}, + {file = "debugpy-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:cf327316ae0c0e7dd81eb92d24ba8b5e88bb4d1b585b5c0d32929274a66a5210"}, + {file = "debugpy-1.8.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1523bc551e28e15147815d1397afc150ac99dbd3a8e64641d53425dba57b0ff9"}, + {file = "debugpy-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e24ccb0cd6f8bfaec68d577cb49e9c680621c336f347479b3fce060ba7c09ec1"}, + {file = "debugpy-1.8.2-cp39-cp39-win32.whl", hash = "sha256:7f8d57a98c5a486c5c7824bc0b9f2f11189d08d73635c326abef268f83950326"}, + {file = "debugpy-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:16c8dcab02617b75697a0a925a62943e26a0330da076e2a10437edd9f0bf3755"}, + {file = "debugpy-1.8.2-py2.py3-none-any.whl", hash = "sha256:16e16df3a98a35c63c3ab1e4d19be4cbc7fdda92d9ddc059294f18910928e0ca"}, + {file = "debugpy-1.8.2.zip", hash = "sha256:95378ed08ed2089221896b9b3a8d021e642c24edc8fef20e5d4342ca8be65c00"}, ] [[package]] @@ -806,14 +806,14 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth [[package]] name = "fastjsonschema" -version = "2.19.1" +version = "2.20.0" description = "Fastest Python implementation of JSON schema" category = "dev" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, - {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, + {file = "fastjsonschema-2.20.0-py3-none-any.whl", hash = "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a"}, + {file = "fastjsonschema-2.20.0.tar.gz", hash = "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23"}, ] [package.extras] @@ -964,14 +964,14 @@ files = [ [[package]] name = "griffe" -version = "0.45.2" +version = "0.47.0" description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "griffe-0.45.2-py3-none-any.whl", hash = "sha256:297ec8530d0c68e5b98ff86fb588ebc3aa3559bb5dc21f3caea8d9542a350133"}, - {file = "griffe-0.45.2.tar.gz", hash = "sha256:83ce7dcaafd8cb7f43cbf1a455155015a1eb624b1ffd93249e5e1c4a22b2fdb2"}, + {file = "griffe-0.47.0-py3-none-any.whl", hash = "sha256:07a2fd6a8c3d21d0bbb0decf701d62042ccc8a576645c7f8799fe1f10de2b2de"}, + {file = "griffe-0.47.0.tar.gz", hash = "sha256:95119a440a3c932b13293538bdbc405bee4c36428547553dc6b327e7e7d35e5a"}, ] [package.dependencies] @@ -991,41 +991,29 @@ files = [ [[package]] name = "holoviews" -version = "1.18.3" -description = "Stop plotting your data - annotate your data and let it visualize itself." +version = "1.19.0" +description = "A high-level plotting API for the PyData ecosystem built on HoloViews." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "holoviews-1.18.3-py2.py3-none-any.whl", hash = "sha256:b94b96560b64a84c07e89115aaf9b226e6009684800ec84d3c88cbad122c0c46"}, - {file = "holoviews-1.18.3.tar.gz", hash = "sha256:578e30e89d72754f97a83ebe08198fec8e87cc7e49b25b9f31ec393f939ca500"}, + {file = "holoviews-1.19.0-py3-none-any.whl", hash = "sha256:a74b26dc3285b4f8b801e23f0e23b4ac93ab4ec162ea76c69ae585fff627a21b"}, + {file = "holoviews-1.19.0.tar.gz", hash = "sha256:cab1522f75a9b46377f9364b675befd79812e220059714470a58e21475d531ba"}, ] [package.dependencies] +bokeh = ">=3.1" colorcet = "*" -numpy = ">=1.0" +numpy = ">=1.21" packaging = "*" -pandas = ">=0.20.0" +pandas = ">=1.3" panel = ">=1.0" -param = ">=1.12.0,<3.0" -pyviz-comms = ">=0.7.4" +param = ">=2.0,<3.0" +pyviz-comms = ">=2.1" [package.extras] -all = ["bokeh (>=3.1)", "cftime", "codecov", "contourpy", "cudf", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "graphviz", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "myst-nb (<1)", "nbconvert", "nbsite (>=0.8.4,<0.9.0)", "nbval", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "playwright", "plotly (>=4.0)", "pooch", "pre-commit", "pyarrow", "pytest", "pytest-cov", "pytest-github-actions-annotate-failures", "pytest-playwright", "pytest-rerunfailures", "pytest-xdist", "ruff", "scikit-image", "scipy", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -build = ["param (>=1.7.0)", "pyct (>=0.4.4)", "setuptools (>=30.3.0)"] -doc = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "graphviz", "ipython (>=5.4.0)", "matplotlib (>=3)", "myst-nb (<1)", "nbsite (>=0.8.4,<0.9.0)", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "selenium", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -examples = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ipython (>=5.4.0)", "matplotlib (>=3)", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -examples-tests = ["bokeh (>=3.1)", "cftime", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbval", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pyarrow", "scikit-image", "scipy", "shapely", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] -lint = ["pre-commit", "ruff"] -notebook = ["ipython (>=5.4.0)", "notebook"] -recommended = ["bokeh (>=3.1)", "ipython (>=5.4.0)", "matplotlib (>=3)", "notebook"] -tests = ["bokeh (>=3.1)", "cftime", "contourpy", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "networkx", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "xarray (>=0.10.4)"] -tests-ci = ["codecov", "pytest-github-actions-annotate-failures"] -tests-core = ["bokeh (>=3.1)", "contourpy", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist"] -tests-gpu = ["bokeh (>=3.1)", "cftime", "contourpy", "cudf", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "networkx", "pillow", "plotly (>=4.0)", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "xarray (>=0.10.4)"] -tests-nb = ["nbval"] -ui = ["playwright", "pytest-playwright"] -unit-tests = ["bokeh (>=3.1)", "cftime", "contourpy", "dash (>=1.16)", "dask", "datashader (>=0.11.1)", "ffmpeg", "ibis-framework", "ipython (>=5.4.0)", "matplotlib (>=3)", "nbconvert", "netcdf4", "networkx", "notebook", "notebook (>=7.0)", "pillow", "plotly (>=4.0)", "pooch", "pre-commit", "pyarrow", "pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "ruff", "scikit-image", "scipy", "scipy (>=1.10)", "selenium", "shapely", "spatialpandas", "streamz (>=0.5.0)", "xarray (>=0.10.4)"] +recommended = ["matplotlib (>=3)", "plotly (>=4.0)"] +tests = ["pytest", "pytest-rerunfailures"] [[package]] name = "httpcore" @@ -1120,23 +1108,23 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.1.0" +version = "8.0.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, - {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, + {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, + {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" @@ -1339,14 +1327,14 @@ files = [ [[package]] name = "jsonpointer" -version = "2.4" +version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] [[package]] @@ -1584,14 +1572,14 @@ test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (> [[package]] name = "jupyterlab" -version = "4.2.1" +version = "4.2.3" description = "JupyterLab computational environment" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.2.1-py3-none-any.whl", hash = "sha256:6ac6e3827b3c890e6e549800e8a4f4aaea6a69321e2240007902aa7a0c56a8e4"}, - {file = "jupyterlab-4.2.1.tar.gz", hash = "sha256:a10fb71085a6900820c62d43324005046402ffc8f0fde696103e37238a839507"}, + {file = "jupyterlab-4.2.3-py3-none-any.whl", hash = "sha256:0b59d11808e84bb84105c73364edfa867dd475492429ab34ea388a52f2e2e596"}, + {file = "jupyterlab-4.2.3.tar.gz", hash = "sha256:df6e46969ea51d66815167f23d92f105423b7f1f06fa604d4f44aeb018c82c7b"}, ] [package.dependencies] @@ -1605,6 +1593,7 @@ jupyter-server = ">=2.4.0,<3" jupyterlab-server = ">=2.27.1,<3" notebook-shim = ">=0.2" packaging = "*" +setuptools = ">=40.1.0" tornado = ">=6.2.0" traitlets = "*" @@ -2120,14 +2109,14 @@ files = [ [[package]] name = "notebook" -version = "7.2.0" +version = "7.2.1" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "notebook-7.2.0-py3-none-any.whl", hash = "sha256:b4752d7407d6c8872fc505df0f00d3cae46e8efb033b822adacbaa3f1f3ce8f5"}, - {file = "notebook-7.2.0.tar.gz", hash = "sha256:34a2ba4b08ad5d19ec930db7484fb79746a1784be9e1a5f8218f9af8656a141f"}, + {file = "notebook-7.2.1-py3-none-any.whl", hash = "sha256:f45489a3995746f2195a137e0773e2130960b51c9ac3ce257dbc2705aab3a6ca"}, + {file = "notebook-7.2.1.tar.gz", hash = "sha256:4287b6da59740b32173d01d641f763d292f49c30e7a51b89c46ba8473126341e"}, ] [package.dependencies] @@ -2242,14 +2231,14 @@ files = [ [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -2374,25 +2363,25 @@ ui = ["jupyter-server", "playwright", "pytest-playwright", "tomli"] [[package]] name = "param" -version = "2.1.0" +version = "2.1.1" description = "Make your Python code clearer and more reliable by declaring Parameters." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "param-2.1.0-py3-none-any.whl", hash = "sha256:f31d3745d227347d29b5868c4e4e3077df07463889b91d3bb28e634fde211e1c"}, - {file = "param-2.1.0.tar.gz", hash = "sha256:a7b30b08b547e2b78b02aeba6ed34e3c6a638f8e4824a76a96ffa2d7cf57e71f"}, + {file = "param-2.1.1-py3-none-any.whl", hash = "sha256:81066d040526fbaa44b6419f3e92348fa8856ea44c8d3915e9245937ddabe2d6"}, + {file = "param-2.1.1.tar.gz", hash = "sha256:3b1da14abafa75bfd908572378a58696826b3719a723bc31b40ffff2e9a5c852"}, ] [package.extras] -all = ["param[doc]", "param[lint]", "param[tests-full]"] -doc = ["nbsite (==0.8.4)", "param[examples]", "sphinx-remove-toctrees"] +all = ["aiohttp", "cloudpickle", "coverage[toml]", "flake8", "gmpy", "ipython", "jsonschema", "nbsite (==0.8.4)", "nbval", "nest-asyncio", "numpy", "odfpy", "openpyxl", "pandas", "panel", "pre-commit", "pyarrow", "pytest", "pytest-asyncio", "pytest-xdist", "sphinx-remove-toctrees", "tables", "xlrd"] +doc = ["aiohttp", "nbsite (==0.8.4)", "pandas", "panel", "sphinx-remove-toctrees"] examples = ["aiohttp", "pandas", "panel"] lint = ["flake8", "pre-commit"] tests = ["coverage[toml]", "pytest", "pytest-asyncio"] tests-deser = ["odfpy", "openpyxl", "pyarrow", "tables", "xlrd"] -tests-examples = ["nbval", "param[examples]", "pytest (<8.1)", "pytest-asyncio", "pytest-xdist"] -tests-full = ["cloudpickle", "gmpy", "ipython", "jsonschema", "nest-asyncio", "numpy", "pandas", "param[tests-deser]", "param[tests-examples]", "param[tests]"] +tests-examples = ["aiohttp", "nbval", "pandas", "panel", "pytest", "pytest-asyncio", "pytest-xdist"] +tests-full = ["aiohttp", "cloudpickle", "coverage[toml]", "gmpy", "ipython", "jsonschema", "nbval", "nest-asyncio", "numpy", "odfpy", "openpyxl", "pandas", "panel", "pyarrow", "pytest", "pytest-asyncio", "pytest-xdist", "tables", "xlrd"] [[package]] name = "parso" @@ -2547,14 +2536,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "plum-dispatch" -version = "2.4.1" +version = "2.4.2" description = "Multiple dispatch in Python" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "plum_dispatch-2.4.1-py3-none-any.whl", hash = "sha256:015b35c3081706718282da7ab248eec34b0f87cfc4aaa7fbc98ad9c34ee84a94"}, - {file = "plum_dispatch-2.4.1.tar.gz", hash = "sha256:23914fefc8ca79148c6acf04651f4916510a62e13f105bb7dc7c64de8587fe93"}, + {file = "plum_dispatch-2.4.2-py3-none-any.whl", hash = "sha256:72f35f6b44443a979c73b67b8a7245623d6f14f64b68ff912ba0adbb4cd50288"}, + {file = "plum_dispatch-2.4.2.tar.gz", hash = "sha256:248f73b2ca79ff5c1d307fb7c28e78a306c8f8c10776b71b3f0788aeeeae99ac"}, ] [package.dependencies] @@ -2719,14 +2708,14 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.46" +version = "3.0.47" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false python-versions = ">=3.7.0" files = [ - {file = "prompt_toolkit-3.0.46-py3-none-any.whl", hash = "sha256:45abe60a8300f3c618b23c16c4bb98c6fc80af8ce8b17c7ae92db48db3ee63c1"}, - {file = "prompt_toolkit-3.0.46.tar.gz", hash = "sha256:869c50d682152336e23c4db7f74667639b5047494202ffe7670817053fd57795"}, + {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"}, + {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"}, ] [package.dependencies] @@ -2734,28 +2723,29 @@ wcwidth = "*" [[package]] name = "psutil" -version = "5.9.8" +version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, ] [package.extras] @@ -2851,14 +2841,14 @@ files = [ [[package]] name = "pydantic" -version = "2.7.3" +version = "2.7.4" description = "Data validation using Python type hints" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.3-py3-none-any.whl", hash = "sha256:ea91b002777bf643bb20dd717c028ec43216b24a6001a280f83877fd2655d0b4"}, - {file = "pydantic-2.7.3.tar.gz", hash = "sha256:c46c76a40bb1296728d7a8b99aa73dd70a48c3510111ff290034f860c99c419e"}, + {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, + {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, ] [package.dependencies] @@ -3362,14 +3352,14 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] [[package]] name = "quartodoc" -version = "0.7.3" +version = "0.7.5" description = "Generate API documentation with Quarto." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "quartodoc-0.7.3-py3-none-any.whl", hash = "sha256:697a0d919d5bd4ff169b67bbd1a201b2f0699ea3de6ea4bb0cd97a884edefead"}, - {file = "quartodoc-0.7.3.tar.gz", hash = "sha256:6d8c7266ede844cebc9980c29956701f4b65e882daaa860a0f1391c539913f20"}, + {file = "quartodoc-0.7.5-py3-none-any.whl", hash = "sha256:293c45c4b1b10936d562921ff32f7a5d3e24bde250c638f0033c0c38ecbc9a92"}, + {file = "quartodoc-0.7.5.tar.gz", hash = "sha256:328d40374fa4397cab67a820cdac3dca47a90eb0a33328ccf50c8f41507ef125"}, ] [package.dependencies] @@ -3380,6 +3370,7 @@ importlib-resources = ">=5.10.2" plum-dispatch = {version = ">2.0.0", markers = "python_version >= \"3.10\""} pydantic = "*" pyyaml = "*" +requests = "*" sphobjinv = ">=2.3.1" tabulate = ">=0.9.0" typing-extensions = ">=4.4.0" @@ -3583,46 +3574,46 @@ files = [ [[package]] name = "scipy" -version = "1.13.1" +version = "1.14.0" description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, -] - -[package.dependencies] -numpy = ">=1.22.4,<2.3" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, + {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, + {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, + {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, + {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, + {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, + {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, + {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, +] + +[package.dependencies] +numpy = ">=1.23.5,<2.3" + +[package.extras] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "send2trash" @@ -3641,6 +3632,22 @@ nativelib = ["pyobjc-framework-Cocoa", "pywin32"] objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] +[[package]] +name = "setuptools" +version = "70.1.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "six" version = "1.16.0" @@ -3772,23 +3779,23 @@ test = ["pytest", "ruff"] [[package]] name = "tornado" -version = "6.4" +version = "6.4.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "dev" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"}, + {file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"}, + {file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"}, + {file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"}, + {file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"}, + {file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"}, + {file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"}, ] [[package]] @@ -3842,14 +3849,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.1" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, - {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -3896,14 +3903,14 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -3971,19 +3978,19 @@ files = [ [[package]] name = "webcolors" -version = "1.13" +version = "24.6.0" description = "A library for working with the color formats defined by HTML and CSS." category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, - {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, + {file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"}, + {file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"}, ] [package.extras] docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["pytest", "pytest-cov"] +tests = ["coverage[toml]"] [[package]] name = "webencodings" @@ -4039,14 +4046,14 @@ files = [ [[package]] name = "xyzservices" -version = "2024.4.0" +version = "2024.6.0" description = "Source of XYZ tiles providers" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "xyzservices-2024.4.0-py3-none-any.whl", hash = "sha256:b83e48c5b776c9969fffcfff57b03d02b1b1cd6607a9d9c4e7f568b01ef47f4c"}, - {file = "xyzservices-2024.4.0.tar.gz", hash = "sha256:6a04f11487a6fb77d92a98984cd107fbd9157fd5e65f929add9c3d6e604ee88c"}, + {file = "xyzservices-2024.6.0-py3-none-any.whl", hash = "sha256:fecb2508f0f2b71c819aecf5df2c03cef001c56a4b49302e640f3b34710d25e4"}, + {file = "xyzservices-2024.6.0.tar.gz", hash = "sha256:58c1bdab4257d2551b9ef91cd48571f77b7c4d2bc45bf5e3c05ac97b3a4d7282"}, ] [[package]] @@ -4068,4 +4075,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "d0cfc954a5375db89ef1a32865cc7eb18f1527792aeb85ab974965b6a786418a" +content-hash = "8b58df8e65cb17ef83f3c76a9513f237bdc5b73c7815eb6672743d1b9cc488c9" From 578ff9b6d0969971dc0390a05263447cf958165a Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:51:43 -0400 Subject: [PATCH 25/28] typo on __version__ --- src/new_fave/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/new_fave/__init__.py b/src/new_fave/__init__.py index 8a4696e..87dba80 100644 --- a/src/new_fave/__init__.py +++ b/src/new_fave/__init__.py @@ -10,7 +10,7 @@ from importlib.metadata import version -___version__ = version("new-fave") +__version__ = version("new-fave") __all__ = [ "VowelMeasurement", From 214c28c8dfcbc5fbfaee4b7e2b39d40c912b3d13 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:51:54 -0400 Subject: [PATCH 26/28] update MockVowelMeasurement --- tests/test_optimize/test_optimize.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_optimize/test_optimize.py b/tests/test_optimize/test_optimize.py index 4bda3dc..a9a6b09 100644 --- a/tests/test_optimize/test_optimize.py +++ b/tests/test_optimize/test_optimize.py @@ -10,7 +10,9 @@ def __init__(self, len, winner_idx): self.cand_param_logprob_speaker_global = log_prob self.cand_param_logprob_speaker_byvclass = log_prob - self.cand_maxformant_logprob_speaker_global = log_prob + self.cand_maxformant_logprob_speaker_global = log_prob + self.cand_bparam_logprob_speaker_global = log_prob + self.cand_bparam_logprob_speaker_byvclass = log_prob self.cand_error_logprob_vm = log_prob self.winner = None From b7740bfe4c5e64c41eb6609e8cd1c68b8c583952 Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:57:32 -0400 Subject: [PATCH 27/28] trying to get version to work --- src/new_fave/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/new_fave/__init__.py b/src/new_fave/__init__.py index 87dba80..331a73e 100644 --- a/src/new_fave/__init__.py +++ b/src/new_fave/__init__.py @@ -10,7 +10,7 @@ from importlib.metadata import version -__version__ = version("new-fave") +__version__ = version("new_fave") __all__ = [ "VowelMeasurement", From 1987739007074ac605aedad9680a9cf3e7284a7d Mon Sep 17 00:00:00 2001 From: JoFrhwld Date: Wed, 26 Jun 2024 13:59:28 -0400 Subject: [PATCH 28/28] rolling back fave version setting --- src/new_fave/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/new_fave/__init__.py b/src/new_fave/__init__.py index 331a73e..39243a4 100644 --- a/src/new_fave/__init__.py +++ b/src/new_fave/__init__.py @@ -10,8 +10,6 @@ from importlib.metadata import version -__version__ = version("new_fave") - __all__ = [ "VowelMeasurement", "VowelClass", @@ -22,6 +20,5 @@ "fave_subcorpora", "write_data", "pickle_speakers", - "unpickle_speakers", - "__version__" + "unpickle_speakers" ] \ No newline at end of file