diff --git a/batchglm/external/edgeR/__init__.py b/batchglm/external/edgeR/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/batchglm/external/edgeR/adjProfileLik.py b/batchglm/external/edgeR/adjProfileLik.py new file mode 100644 index 00000000..d06f3d12 --- /dev/null +++ b/batchglm/external/edgeR/adjProfileLik.py @@ -0,0 +1,77 @@ +import dask.array +import numpy as np +import scipy + +from .estimator import NBEstimator + + +def adjusted_profile_likelihood( + estimator: NBEstimator, + adjust: bool = True, +): + """ + Featurewise Cox-Reid adjusted profile log-likelihoods for the dispersion. + dispersion can be a scalar or a featurewise vector. + Computationally, dispersion can also be a matrix, but the apl is still computed tagwise. + y is a matrix: rows are genes/tags/transcripts, columns are samples/libraries. + offset is a matrix of the same dimensions as y. + This is a numpy vectorized python version of edgeR's adjProfileLik function implemented in C++. + """ + low_value = 1e-10 + log_low_value = np.log(low_value) + + estimator.train(maxit=250, tolerance=1e-10) + model = estimator._model_container + poisson_idx = np.where(1 / model.scale < 0)[0] + if isinstance(poisson_idx, dask.array.core.Array): + poisson_idx = poisson_idx.compute() + + if len(poisson_idx) == model.num_features: + loglik = model.x * np.log(model.location) - model.location - scipy.special.lgamma(model.x + 1) + elif len(poisson_idx) == 0: + loglik = model.ll + else: + loglik = np.zeros_like(model.x) + + poisson_x = model.x[:, poisson_idx] + poisson_loc = model.location_j(poisson_idx) + + loglik[:, poisson_idx] = poisson_x * np.log(poisson_loc) - poisson_loc - scipy.special.lgamma(poisson_x + 1) + + non_poisson_idx = np.where(model.theta_scale > 0)[0] + loglik[:, non_poisson_idx] = model.ll_j(non_poisson_idx) + + sum_loglik = np.sum(loglik, axis=0) + + if adjust: + w = -model.fim_weight_location_location + + adj = np.zeros(model.num_features) + n_loc_params = model.design_loc.shape[1] + if n_loc_params == 1: + adj = np.sum(w, axis=0) + adj = np.log(np.abs(adj)) + if isinstance(adj, dask.array.core.Array): + adj = adj.compute() + else: + xh = model.xh_loc + xhw = np.einsum("ob,of->fob", xh, w) + fim = np.einsum("fob,oc->fbc", xhw, xh) + if isinstance(fim, dask.array.core.Array): + fim = fim.compute() + for i in range(fim.shape[0]): + + ldu, _, info = scipy.linalg.lapack.dsytrf(lower=0, a=fim[i]) + if info < 0: + adj[i] = 0 + print(f"LDL factorization failed for feature {i}") + else: + ldu_diag = np.diag(ldu) + adj[i] = np.sum( + np.where((ldu_diag < low_value) | np.isinf(ldu_diag), log_low_value, np.log(ldu_diag)) + ) + + adj /= 2 + sum_loglik -= adj + + return sum_loglik diff --git a/batchglm/external/edgeR/aveLogCPM.py b/batchglm/external/edgeR/aveLogCPM.py new file mode 100644 index 00000000..9020b81d --- /dev/null +++ b/batchglm/external/edgeR/aveLogCPM.py @@ -0,0 +1,80 @@ +from typing import Optional, Union + +import dask.array +import numpy as np + +from .external import InputDataGLM, ModelContainer, NBModel +from .glm_one_group import fit_single_group, get_single_group_start + + +def calculate_avg_log_cpm( + x: np.ndarray, + size_factors: Optional[np.ndarray] = None, + dispersion: Union[np.ndarray, float] = 0.05, + prior_count: int = 2, + weights: Optional[Union[np.ndarray, float]] = None, + maxit: int = 50, + tolerance: float = 1e-10, + chunk_size_cells=1e6, + chunk_size_genes=1e6, +): + """ + Computes average log2 counts per million per feature over all observations. + The method is a python derivative of edgeR's aveLogCPM method. + + :param x: the counts data. + :param model_class: the class object to use for creation of a model during the calculation + :param size_factors: Optional size_factors. This is equivalent to edgeR's offsets. + :param dispersion: Optional fixed dispersion parameter used during the calculation. + :param prior_count: The count to be added to x prior to calculation. + :param weights: Optional weights per feature (currently unsupported and ignored) + :param: maxit: The max number of iterations during newton-raphson approximation. + :param: tolerance: The minimal difference in change used as a stopping criteria during NR approximation. + :param: chunk_size_cells: chunks used over the feature axis when using dask + :param: chunk_size_genes: chunks used over the observation axis when using dask + """ + + if weights is None: + weights = 1.0 + if isinstance(dispersion, float): + dispersion = np.full((1, x.shape[1]), dispersion, dtype=float) + if size_factors is None: + size_factors = np.full((x.shape[0], 1), np.log(1.0)) + + adjusted_prior, adjusted_size_factors = add_priors(prior_count, size_factors) + x = x + adjusted_prior + avg_cpm_model = NBModel( + InputDataGLM( + data=x, + design_loc=np.ones((x.shape[0], 1)), + design_loc_names=["Intercept"], + size_factors=adjusted_size_factors, + design_scale=np.ones((x.shape[0], 1)), + design_scale_names=["Intercept"], + as_dask=isinstance(x, dask.array.core.Array), + chunk_size_cells=chunk_size_cells, + chunk_size_genes=chunk_size_genes, + ) + ) + avg_cpm_model_container = ModelContainer( + model=avg_cpm_model, + init_theta_location=get_single_group_start(avg_cpm_model.x, avg_cpm_model.size_factors), + init_theta_scale=np.log(1 / dispersion), + chunk_size_genes=chunk_size_genes, + dtype=x.dtype, + ) + + fit_single_group(avg_cpm_model_container, maxit=maxit, tolerance=tolerance) + output = (avg_cpm_model_container.theta_location + np.log(1e6)) / np.log(2) + + return output + + +def add_priors(prior_count: int, size_factors: np.ndarray): + + factors = np.exp(size_factors) + avg_factors = np.mean(factors) + adjusted_priors = prior_count * factors / avg_factors + adjusted_size_factors = np.log(factors + 2 * adjusted_priors) + + return adjusted_priors, adjusted_size_factors diff --git a/batchglm/external/edgeR/c_utils.cpp b/batchglm/external/edgeR/c_utils.cpp new file mode 100644 index 00000000..97c2eae0 --- /dev/null +++ b/batchglm/external/edgeR/c_utils.cpp @@ -0,0 +1,267 @@ +#include +#include +#include + + +const double one_tenthousandth=std::pow(10, -4.0); +const double mildly_low_value=std::pow(10, -8.0); +const double one_million=std::pow(10, 6); + +/* All functions are taken from the C++ backend of edgeR. + * The R wrappers were replaced with according numpy / python C-API. + */ + +double compute_unit_nb_deviance (double y, double mu, double phi) { + y+=mildly_low_value; + mu+=mildly_low_value; + + /* Calculating the deviance using either the Poisson (small phi*mu), the Gamma (large) or NB (everything else). + * Some additional work is put in to make the transitions between families smooth. + */ + if (phi < one_tenthousandth) { + const double resid = y - mu; + return 2 * ( y * std::log(y/mu) - resid - 0.5*resid*resid*phi*(1+phi*(2/3*resid-y)) ); + } else { + const double product=mu*phi; + if (product > one_million) { + return 2 * ( (y - mu)/mu - std::log(y/mu) ) * mu/(1+product); + } else { + const double invphi=1/phi; + return 2 * (y * std::log( y/mu ) + (y + invphi) * std::log( (mu + invphi)/(y + invphi) ) ); + } + } +}; + + +static PyObject *loess_by_col(PyObject *self, PyObject *args) { + + const double low_value = std::pow(10.0, -10.0); + PyArrayObject *x, *y; + int span; + PyArg_ParseTuple(args, "OOi", &x, &y, &span); + if (PyErr_Occurred()) { + return NULL; + } + if (!(PyArray_Check(x)) && !(PyArray_Check(y))) { + PyErr_SetString(PyExc_TypeError, "First two arguments must be numpy arrays."); + return NULL; + } + int total = PyArray_SIZE(x); + npy_intp *x_dims = PyArray_DIMS(x); + npy_intp *y_dims = PyArray_DIMS(y); + + int ncols = y_dims[1]; + + double *x_ptr; + double **y_ptrs; + PyArray_AsCArray((PyObject **)&x, &x_ptr, x_dims, 1, PyArray_DescrFromType(NPY_DOUBLE)); + if (PyErr_Occurred()){ + return NULL; + } + PyArray_AsCArray((PyObject **)&y, &y_ptrs, y_dims, 2, PyArray_DescrFromType(NPY_DOUBLE)); + if (PyErr_Occurred()){ + return NULL; + } + + if (span > total) { + PyErr_SetString(PyExc_RuntimeError, "Span must be smaller than the total number of points."); + return NULL; + } + double w_ptr[total]; + double f_ptrs[y_dims[0]][y_dims[1]]; + + try { + int frame_end=span-1; + std::cout << frame_end << '\n'; + for (int cur_p=0; cur_pframe_end) { frame_end=cur_p; } + const double& cur_point=x_ptr[cur_p]; + double back_dist=cur_point-x_ptr[frame_end-span+1], front_dist=x_ptr[frame_end]-cur_point, + max_dist=(back_dist > front_dist ? back_dist : front_dist); + + while (frame_end < total-1 && cur_p+span-1>frame_end) { + /* Every time we advance, we twiddle with the ends of the frame to see if we can't get + * a better fit. The frame will always advance in the forward direction. This is because the + * current frame is optimal with respect to the previous tag. If the previous maximal distance + * was at the back, shifting the frame backward will increase the back distance with respect to + * the current tag (and thus increase the maximal distance). + * + * If the previous maximal distance was at the front, shifting the frame backward may + * decrease the front distance with respect to the current tag. However, we note that + * because of optimality, having a previous maximal distance at the front must mean + * that a back-shifted frame will result in an even larger previous maximal distance at + * the back (otherwise the optimal frame would be located further back to start with). In + * short, shifting the frame backwards will flip the maximal distance to that of the back + * distance which is even larger than the non-shifted forward distance. + * + * Thus, the frame can only go forwards. Note that below, the frame is defined by + * the 'end' position which notes the end point of the current frame. The start + * point is inherently defined by revolving around the minimum point. + */ + back_dist=cur_point-x_ptr[frame_end-span+2]; + front_dist=x_ptr[frame_end+1]-cur_point; + const double& next_max=(back_dist > front_dist ? back_dist : front_dist); + /* This bit provides some protection against near-equal values, by forcing the frame + * forward provided that the difference between the lowest maximum distance and + * the maximum distance at any other frame is less than a low_value. This ensures + * that values following a stretch of identical x-coordinates are accessible + * to the algorithm (rather than being blocked off by inequalities introduced by + * double imprecision). + */ + const double diff=(next_max-max_dist)/max_dist; + if (diff > low_value) { + break; + } else if (diff < 0) { + max_dist=next_max; + } + ++frame_end; + } + /* Now that we've located our optimal window, we can calculate the weighted average + * across the points in the window (weighted according to distance from the current point). + * and we can calculate the leverages. Unfortunately, we have to loop over the points in the + * window because each weight must be recomputed according to its new distance and new maximal + * distance. + */ + double total_weight=0; + double& out_leverage=(w_ptr[cur_p]=-1); + for (int i=0; i B - A. The algorithm above will move the + * frame to [1,3] when calculating the maximum distance for B. This is the same as [0, 2] in terms + * of distance, but only using the frame components to calculate the mean will miss out on element 0. + * So, the computation should work from [0, 3]. There's no need to worry about the extra 'C' as it + * will have weight zero. + */ + for (int m=frame_end; m>=0; --m) { + const double rel_dist=(max_dist > low_value ? std::abs(x_ptr[m]-cur_point)/max_dist : 0); + const double weight=std::pow(1-std::pow(rel_dist, 3.0), 3.0); + if (weight < 0) { continue; } + total_weight+=weight; + + for (int i=0; i 0] + + if method is None: + size_factors = np.ones((x.shape[1], 1), dtype=float) + elif method.lower() == "tmm": + size_factors = _calc_factor_tmm(data=x, **kwargs) + elif method.lower() == "tmmwsp": + size_factors = _calc_factor_tmmwsp(data=x, **kwargs) + elif method.lower() == "rle": + size_factors = _calc_factor_rle(data=x) + elif method == "upperquartile": + size_factors = _calc_factor_quantile(data=x, **kwargs) + else: + raise ValueError(f"Method {method} not recognized.") + + # Factors should multiple to one + size_factors = size_factors / np.exp(np.mean(np.log(size_factors))) + return size_factors + + +def _calc_factor_rle(data: np.ndarray): + # Scale factors as in Anders et al (2010) + geometric_feature_means = np.exp(np.mean(np.log(data), axis=0)) + adjusted_data = data / geometric_feature_means + return np.median(adjusted_data[:, geometric_feature_means > 0], axis=1, keepdims=True) / np.sum( + data, axis=1, keepdims=True + ) + + +def _calc_factor_quantile(data, p=0.75): + # Generalized version of upper-quartile normalization + size_factors = np.quantile(data, q=p, axis=1, keepdims=True) + if np.min(size_factors) == 0: + print("Warning: One or more quantiles are zero.") + size_factors = size_factors / np.sum(data, axis=1, keepdims=True) + return size_factors + + +def _calc_factor_tmm( + data: np.ndarray, + ref_idx: Optional[int] = None, + logratio_trim: float = 0.3, + sum_trim: float = 0.05, + do_weighting: bool = True, + a_cutoff: float = -1e10, +): + # TMM between two libraries + + if ref_idx is None: + f75 = _calc_factor_quantile(data, p=0.75) + if np.median(f75) < 1e-20: + ref_idx = np.sum(np.sqrt(data), axis=1).argmax() + else: + ref_idx = np.abs(f75 - np.mean(f75)).argmin() + + sample_sums = np.sum(data, axis=1, keepdims=True) + sum_normalized_data = data / sample_sums + with np.errstate(divide="ignore", invalid="ignore"): + opfer = sum_normalized_data / sum_normalized_data[ref_idx] + log_ratios = np.log2(opfer) + absolute_values = (np.log2(sum_normalized_data) + np.log2(sum_normalized_data[ref_idx])) / 2 + estimated_asymptotic_variance = (sample_sums - data) / sample_sums / data + estimated_asymptotic_variance += (sample_sums[ref_idx] - data[ref_idx]) / sample_sums[ref_idx] / data[ref_idx] + + # remove infinite values, cutoff based on aCutOff + finite_idx = np.isfinite(log_ratios) & np.isfinite(absolute_values) & (absolute_values > a_cutoff) + + size_factors = np.ones_like(sample_sums, dtype=float) + for i in range(data.shape[0]): + log_ratios_i = log_ratios[i, finite_idx[i]] + absolute_values_i = absolute_values[i, finite_idx[i]] + estimated_asymptotic_variance_i = estimated_asymptotic_variance[i, finite_idx[i]] + + if np.max(np.abs(log_ratios_i) < 1e-6): + continue + + # taken from the original mean() function + n = len(log_ratios_i) + lo_l = np.floor(n * logratio_trim) + 1 + hi_l = n + 1 - lo_l + lo_s = np.floor(n * sum_trim) + 1 + hi_s = n + 1 - lo_s + + keep = (rankdata(log_ratios_i) >= lo_l) & (rankdata(log_ratios_i) <= hi_l) + keep &= (rankdata(absolute_values_i) >= lo_s) & (rankdata(absolute_values_i) <= hi_s) + + if do_weighting: + size_factor_i = np.nansum(log_ratios_i[keep] / estimated_asymptotic_variance_i[keep]) + size_factor_i = size_factor_i / np.nansum(1 / estimated_asymptotic_variance_i[keep]) + else: + size_factor_i = np.nanmean(log_ratios_i[keep]) + + # Results will be missing if the two libraries share no features with positive counts + # In this case, return unity + if np.isnan(size_factor_i): + size_factor_i = 0 + size_factors[i] = 2**size_factor_i + return size_factors + + +def _calc_factor_tmmwsp( + data: np.ndarray, + ref_idx: Optional[int] = None, + logratio_trim: float = 0.3, + sum_trim: float = 0.05, + do_weighting: bool = True, + a_cutoff: float = -1e10, +): + # TMM with pairing of singleton positive counts between the obs and ref libraries + if ref_idx is None: + ref_idx = np.sum(np.sqrt(data), axis=1).argmax() + eps = 1e-14 + sample_sums = np.sum(data, axis=1, keepdims=True) + + # Identify zero counts + n_pos = np.where(data > eps, 1, 0) + n_pos = 2 * n_pos + n_pos[ref_idx] + + size_factors = np.ones_like(sample_sums, dtype=float) + + for i in range(data.shape[0]): + # Remove double zeros and NAs + keep = np.where(n_pos[i] > 0) + data_i = data[i, keep] + ref_i = data[ref_idx, keep] + n_pos_i = n_pos[i, keep] + + # Pair up as many singleton positives as possible + # The unpaired singleton positives are discarded so that no zeros remain + zero_obs = n_pos_i == 1 + zero_ref = n_pos_i == 2 + k = zero_obs | zero_ref + n_eligible_singles = np.min((np.sum(zero_obs), np.sum(zero_ref))) + if n_eligible_singles > 0: + ref_i_k = np.sort(ref_i[k])[::-1][:n_eligible_singles] + data_i_k = np.sort(data_i[k])[::-1][:n_eligible_singles] + data_i = np.concatenate((data_i[~k], data_i_k)) + ref_i = np.concatenate((ref_i[~k], ref_i_k)) + else: + data_i = data_i[~k] + ref_i = ref_i[~k] + + # Any left? + n = len(data_i) + if n == 0: + continue + + # Compute M and A values + data_i_p = data_i / sample_sums[i] + ref_i_p = ref_i / sample_sums[ref_idx] + m = np.log2(data_i_p / ref_i_p) + a = 0.5 * np.log2(data_i_p * ref_i_p) + + # If M all zero, return 1 + if np.max(np.abs(m)) < 1e-6: + continue + + # M order, breaking ties by shrunk M + data_i_p_shrunk = (data_i + 0.5) / (sample_sums[i] + 0.5) + ref_i_p_shrunk = (ref_i + 0.5) / (sample_sums[ref_idx] + 0.5) + m_shrunk = np.log2(data_i_p_shrunk / ref_i_p_shrunk) + m_ordered = np.argsort( + np.array(list(zip(m, m_shrunk)), dtype={"names": ["m", "m_shrunk"], "formats": [m.dtype, m_shrunk.dtype]}), + kind="stable", + ) + + # a order + a_ordered = np.argsort(a, kind="stable") + + # Trim + lo_m = int(n * logratio_trim) + hi_m = n - lo_m + keep_m = np.zeros(n, dtype=bool) + keep_m[m_ordered[lo_m:hi_m]] = True + lo_a = int(n * sum_trim) + hi_a = n - lo_a + keep_a = np.zeros(n, dtype=bool) + keep_a[a_ordered[lo_a:hi_a]] = True + keep = keep_a & keep_m + m = m[keep] + + # Average the m values + if do_weighting: + data_i_p = data_i_p[keep] + ref_i_p = ref_i_p[keep] + v = (1 - data_i_p) / data_i_p / sample_sums[i] + (1 - ref_i_p) / ref_i_p / sample_sums[ref_idx] + w = (1 + 1e-6) / (v + 1e-6) + size_factor_i = np.sum(w * m) / np.sum(w) + else: + size_factor_i = np.mean(m) + size_factors[i] = 2**size_factor_i + return size_factors diff --git a/batchglm/external/edgeR/estimateDisp.py b/batchglm/external/edgeR/estimateDisp.py new file mode 100644 index 00000000..62418018 --- /dev/null +++ b/batchglm/external/edgeR/estimateDisp.py @@ -0,0 +1,247 @@ +from typing import List, Optional, Tuple, Union + +import dask.array +import numpy as np +from scipy.linalg import qr + +from .adjProfileLik import adjusted_profile_likelihood +from .aveLogCPM import calculate_avg_log_cpm +from .estimator import NBEstimator +from .external import InputDataGLM, NBModel +from .maximizeInterpolant import maximize_interpolant +from .prior_df import calculate_prior_df +from .residDF import combo_groups +from .wleb import wleb + + +def estimate_disp( + x: Union[NBModel, np.ndarray], + design: Optional[np.ndarray] = None, + design_loc_names: Optional[List[str]] = None, + size_factors: Optional[np.ndarray] = None, + group=None, # + prior_df=None, # TODO + trend_method="loess", + tagwise: bool = True, # TODO + span=None, # TODO + min_rowsum: int = 5, # TODO + grid_length: int = 21, # TODO + grid_range: Tuple[float, float] = (-10.0, 10.0), # TODO + robust: bool = False, # TODO + winsor_tail_p: Tuple[float, float] = (0.05, 0.1), # TODO + tol: float = 1e-6, # TODO + weights=None, # TODO + adjust: bool = True, + **input_data_kwargs, +): + + """ + Implements edgeR's estimateDisp function. + + :param y: np.ndarray of counts + :param design: design_loc + :param prior_df: prior degrees of freedom. It is used in calculating prior.n.????? + :param trend_method: method for estimating dispersion trend. Possible values are + "none" and "loess" (default). + :param mixed_df: logical, only used when trend.method="locfit". + If FALSE, locfit uses a polynomial of degree 0. + If TRUE, locfit uses a polynomial of degree 1 for lowly expressed genes. + Care is taken to smooth the curve. This argument is ignored since locfit isn't implemented. + :param tagwise: logical, should the tagwise dispersions be estimated? + :param span: width of the smoothing window, as a proportion of the data set. + :param min_rowsum: numeric scalar giving a value for the filtering out of low abundance tags. + Only tags with total sum of counts above this value are used. + Low abundance tags can adversely affect the dispersion estimation, + so this argument allows the user to select an appropriate filter threshold for the tag abundance. + :param grid_length: the number of points on which the interpolation is applied for each tag. + :param grid_range: the range of the grid points around the trend on a log2 scale. + :param robust: logical, should the estimation of prior.df be robustified against outliers? + :param winsor_tail_p: numeric vector of length 1 or 2, giving left and right tail proportions + of the deviances to Winsorize when estimating prior.df. + :param tol: the desired accuracy, passed to optimize + :param group: vector or factor giving the experimental group/condition for each library. + :param libsize: numeric vector giving the total count (sequence depth) for each library. + :param offset: offset matrix for the log-linear model, as for glmFit. + Defaults to the log-effective library sizes. + :param weights: optional numeric matrix giving observation weights + """ + + # define return values: + trended_dispersion: Optional[np.ndarray] = None + + if isinstance(x, np.ndarray): + if design is None: + raise AssertionError("Provide design when x is not a model already.") + if size_factors is None: + size_factors = np.log(x.sum(axis=1)) + input_data = InputDataGLM( + data=x, + design_loc=design, + design_loc_names=design_loc_names, + size_factors=size_factors, + design_scale=np.ones((x.shape[0], 1)), + design_scale_names=["Intercept"], + **input_data_kwargs, + ) + model = NBModel(input_data) + else: + model = x + x_all = model.x.copy() + selected_features = x_all.sum(axis=0) >= min_rowsum + model._x = x_all[:, selected_features] + + # Spline points + spline_pts = np.linspace(start=grid_range[0], stop=grid_range[1], num=grid_length) + spline_disp = 0.1 * 2**spline_pts + l0 = np.zeros((model.num_features, grid_length)) + + # Identify which observations have means of zero (weights aren't needed here). + print("Performing initial fit...", end="") + estimator = NBEstimator(model, dispersion=0.05) + estimator.train(maxit=250, tolerance=tol) + + zerofit = (model.x < 1e-4) & (np.nan_to_num(model.location) < 1e-4) + if isinstance(zerofit, dask.array.core.Array): + zerofit = zerofit.compute() # shape (obs, features) + groups = combo_groups(zerofit) + print("DONE.") + print("Calculating adjusted profile likelihoods in subgroups...", end="") + for subgroup in groups: + not_zero_obs_in_group = ~zerofit[:, subgroup[0]] + if not np.any(not_zero_obs_in_group): + continue + if np.all(not_zero_obs_in_group): + design_new = model.design_loc + new_dloc_names = model.design_loc_names + else: + design_new = model.design_loc[not_zero_obs_in_group] + if isinstance(design_new, dask.array.core.Array): + _, _, pivot = qr(design_new.compute(), mode="raw", pivoting=True) + coefs_new = np.array( + pivot[: np.linalg.matrix_rank(design_new.compute())] + ) # explicitly make this array to keep dimension info + else: + _, _, pivot = qr(design_new, mode="raw", pivoting=True) + coefs_new = np.array( + pivot[: np.linalg.matrix_rank(design_new)] + ) # explicitly make this array to keep dimension info + if len(coefs_new) == design_new.shape[0]: + continue + design_new = design_new[:, coefs_new] + new_dloc_names = [model.design_loc_names[i] for i in coefs_new] + + subgroup_x = model.x + if isinstance(subgroup_x, dask.array.core.Array): + subgroup_x = subgroup_x.compute() + sf = model.size_factors + if sf is not None: + sf = sf[not_zero_obs_in_group] + if isinstance(sf, dask.array.core.Array): + sf = sf.compute() + input_data = InputDataGLM( + data=subgroup_x[np.ix_(not_zero_obs_in_group, subgroup)], + design_loc=design_new, + design_loc_names=new_dloc_names, + size_factors=sf, + design_scale=model.design_scale[not_zero_obs_in_group], + design_scale_names=["Intercept"], + as_dask=isinstance(model.x, dask.array.core.Array), + chunk_size_cells=1000000, + chunk_size_genes=1000000, + ) + group_model = NBModel(input_data) + estimator = NBEstimator(group_model, dispersion=0.05) + for i in range(len(spline_disp)): + estimator.reset_theta_scale(np.log(1 / spline_disp[i])) + l0[subgroup, i] = adjusted_profile_likelihood(estimator, adjust=adjust) + print("DONE.") + + # Calculate common dispersion + overall = maximize_interpolant(spline_pts, l0.sum(axis=0, keepdims=True)) # (1, spline_pts) + common_dispersion = 0.1 * 2**overall + + print(f"Common dispersion is {common_dispersion}.") + + # Allow dispersion trend? + if trend_method is not None: + print("Calculating trended dispersion...", flush=True) + sf = model.size_factors + if sf is not None and isinstance(sf, dask.array.core.Array): + sf = sf.compute() + avg_log_cpm = calculate_avg_log_cpm(x_all, size_factors=sf, dispersion=common_dispersion[0], weights=weights) + span, _, m0, trend, _ = wleb( + theta=spline_pts, + loglik=l0, + covariate=avg_log_cpm[0, selected_features], + trend_method=trend_method, + span=span, + overall=False, + individual=False, + ) + disp_trend = 0.1 * 2**trend + trended_dispersion = np.full(x_all.shape[1], disp_trend[np.argmin(avg_log_cpm[0, selected_features])]) + trended_dispersion[selected_features] = disp_trend + print("DONE.") + else: + avg_log_cpm = None + m0 = np.broadcast_to(l0.mean(axis=0), shape=(model.x.shape[1], len(spline_pts))) + disp_trend = common_dispersion + + # Are tagwise dispersions required? + if not tagwise: + return common_dispersion, trended_dispersion + if isinstance(avg_log_cpm, dask.array.core.Array): + avg_log_cpm = avg_log_cpm.compute() + # Calculate prior.df + print("Calculating featurewise dispersion...") + if prior_df is None: + prior_df, _, _ = calculate_prior_df( + model=model, + robust=robust, + dispersion=disp_trend, + winsor_tail_p=winsor_tail_p, + avg_log_cpm=avg_log_cpm[0, selected_features], + tolerance=tol, + ) + n_loc_params = model.design_loc.shape[1] + prior_n = prior_df / (model.num_observations - n_loc_params) + + # Initiate featurewise dispersions + if trend_method is not None and trended_dispersion is not None: + featurewise_dispersion = trended_dispersion.copy() + else: + featurewise_dispersion = np.full(x_all.shape[1], common_dispersion) + + # Checking if the shrinkage is near-infinite. + too_large = prior_n > 1e6 + if not np.all(too_large): + temp_n = prior_n + if np.any(too_large): + temp_n[too_large] = 1e6 + + # Estimating tagwise dispersions + _, _, _, _, out_individual = wleb( + theta=spline_pts, + loglik=l0, + prior_n=temp_n, + covariate=avg_log_cpm[0, selected_features], + trend_method=trend_method, + span=span, + overall=False, + trend=False, + m0=m0, + ) + if not robust or len(too_large) == 1: + featurewise_dispersion[selected_features] = 0.1 * 2**out_individual + else: + featurewise_dispersion[selected_features][~too_large] = 0.1 * 2 ** out_individual[~too_large] + print("DONE.") + if robust: + temp_df = prior_df + temp_n = prior_n + prior_df = np.full(x_all.shape[1], np.inf) + prior_n = np.full(x_all.shape[1], np.inf) + prior_df[selected_features] = temp_df + prior_n[selected_features] = temp_n + + return common_dispersion, trended_dispersion, featurewise_dispersion, span, prior_df, prior_n diff --git a/batchglm/external/edgeR/estimator.py b/batchglm/external/edgeR/estimator.py new file mode 100644 index 00000000..0057aec8 --- /dev/null +++ b/batchglm/external/edgeR/estimator.py @@ -0,0 +1,406 @@ +import sys +from typing import Union + +import dask.array +import numpy as np +from scipy.linalg import cho_solve, cholesky + +from .c_utils import nb_deviance +from .external import EstimatorGlm, InputDataGLM, ModelContainer, NBModel, NumpyModelContainer, init_par +from .glm_one_group import fit_single_group, get_single_group_start +from .qr_decomposition import get_levenberg_start + +one_millionth = 1e-6 +low_value = 1e-10 +supremely_low_value = 1e-13 +ridiculously_low_value = 1e-100 + + +class Estimator: + + _train_loc: bool = False + _train_scale: bool = False + _model_container: NumpyModelContainer + + def __init__(self, model_container: NumpyModelContainer, dtype: str): + """ + Performs initialisation and creates a new estimator. + :param model_container: + The model_container to be fit using Levenberg-Marquardt as in edgeR. + :param dtype: + i.e float64 + """ + self._model_container = model_container + if self._model_container.design_scale.shape[1] != 1: + raise ValueError("cannot model more than one scale parameter with edgeR/numpy backend right now.") + self.dtype = dtype + + """ + check which algorithm to use. We can use a shortcut algorithm if the number of unique rows in the design + matrix is equal to the number of coefficients. + """ + if isinstance(self._model_container.design_loc, dask.array.core.Array): + unique_design = np.unique(self._model_container.design_loc.compute(), axis=0) + else: + unique_design = np.unique(self._model_container.design_loc, axis=0) + + if unique_design.shape[0] == unique_design.shape[1]: + self.fitting_algorithm = "one_way" + else: + self.fitting_algorithm = "levenberg" + self._model_container.theta_location = get_levenberg_start( + model=self._model_container.model, disp=self._model_container.scale, use_null=True + ) + + def train(self, maxit: int, tolerance: float = 1e-6): + + if self.fitting_algorithm == "one_way": + self.train_oneway(maxit=maxit, tolerance=tolerance) + elif self.fitting_algorithm == "levenberg": + self.train_levenberg(maxit=maxit, tolerance=tolerance) + else: + raise ValueError(f"Unrecognized algorithm: {self.train_levenberg}") + + def train_oneway(self, maxit: int, tolerance: float): + model = self._model_container + if isinstance(model.design_loc, dask.array.core.Array): + unique_design, group_idx = np.unique(model.design_loc.compute(), return_inverse=True, axis=0) + else: + unique_design, group_idx = np.unique(model.design_loc, return_inverse=True, axis=0) + + n_groups = unique_design.shape[1] + + theta_location = model.theta_location + if isinstance(theta_location, dask.array.core.Array): + theta_location = theta_location.compute() # .copy() + + for i in range(n_groups): + obs_group = np.where(group_idx == i)[0] + dloc = model.design_loc + if isinstance(model.design_loc, dask.array.core.Array): + dloc = dloc.compute() + sf = model.size_factors + if sf is not None: + sf = sf[obs_group] + if isinstance(model.size_factors, dask.array.core.Array): + sf = sf.compute() + dscale = model.design_scale + if isinstance(model.design_loc, dask.array.core.Array): + dscale = dscale.compute() + _group_model = model.model.__class__( + InputDataGLM( + data=model.x[obs_group], + design_loc=dloc[np.ix_(obs_group, np.array([i]))], + design_loc_names=model.design_loc_names[[i]], + size_factors=sf, + design_scale=dscale[np.ix_(obs_group, np.array([0]))], + design_scale_names=model.design_scale_names[[0]], + as_dask=isinstance(model.x, dask.array.core.Array), + chunk_size_cells=model.chunk_size_cells, + chunk_size_genes=model.chunk_size_genes, + ) + ) + group_model = ModelContainer( + model=_group_model, + init_theta_location=get_single_group_start(_group_model.x, _group_model.size_factors), + init_theta_scale=model.theta_scale, + chunk_size_genes=model.chunk_size_genes, + dtype=model.theta_location.dtype, + ) + fit_single_group(group_model, maxit=maxit, tolerance=tolerance) + if isinstance(group_model.theta_location, dask.array.core.Array): + theta_location[i] = group_model.theta_location.compute() + else: + theta_location[i] = group_model.theta_location + + theta_location = np.linalg.solve(unique_design, theta_location) + model.theta_location = theta_location + + def train_levenberg(self, maxit: int, tolerance: float = 1e-6): + model = self._model_container + max_x = np.max(model.x, axis=0).compute() + + n_parm = model.num_loc_params + n_features = model.num_features + + iteration = 1 + + """ + + // If we start off with all entries at zero, there's really no point continuing. + if (ymax 0 and iteration <= maxit: + print("iteration:", iteration) + """ + Here we set up the matrix XtWX i.e. the Fisher information matrix. X is the design matrix + and W is a diagonal matrix with the working weights for each observation (i.e. library). + The working weights are part of the first derivative of the log-likelihood for a given coefficient, + multiplied by any user-specified weights. When multiplied by two covariates in the design matrix, + you get the Fisher information (i.e. variance of the log-likelihood) for that pair. This takes + the role of the second derivative of the log-likelihood. The working weights are formed by taking + the reciprocal of the product of the variance (in terms of the mean) and the square of the + derivative of the link function. + + We also set up the actual derivative of the log likelihoods in 'dl'. This is done by multiplying + each covariate by the difference between the mu and observation and dividing by the variance and + derivative of the link function. This is then summed across all observations for each coefficient. + The aim is to solve (XtWX)(dbeta)=dl for 'dbeta'. As XtWX is the second derivative, and dl is the + first, you can see that we are effectively performing a multivariate Newton-Raphson procedure with + 'dbeta' as the step. + """ + loc = model.location_j(not_done_idx) + scale = model.scale_j(not_done_idx) + w = -model.fim_weight_location_location_j(not_done_idx) # shape (obs, features) + denom = 1 + loc / scale # shape (obs, features) + deriv = (model.x[:, not_done_idx] - loc) / denom * weights # shape (obs, features) + xh = model.xh_loc + + xhw = np.einsum("ob,of->fob", xh, w) + fim[not_done_idx] = np.einsum("fob,oc->fbc", xhw, xh) # .compute() + + fim_diags = np.einsum("...ii->...i", fim[not_done_idx]) # shape (features x constrained_coefs) + + dl[not_done_idx] = np.einsum("of,oc->fc", deriv, model.design_loc) + + max_infos[not_done_idx] = np.max(fim_diags, axis=1) # shape (features,) + + if iteration == 1: + lambdas = np.maximum(max_infos * one_millionth, supremely_low_value) + + """ + Levenberg/Marquardt damping reduces step size until the deviance increases or no + step can be found that increases the deviance. In short, increases in the deviance + are enforced to avoid problems with convergence. + """ + + inner_idx_update = not_done_idx + n_inner_idx = len(inner_idx_update) + + levenberg_steps.fill(0) + failed_in_levenberg_loop[not_done_idx] = False + f = 0 + overall_steps.fill(0) + while n_inner_idx > 0: + f += 1 + levenberg_steps[inner_idx_update] += 1 + cholesky_failed_idx = inner_idx_update.copy() # + cholesky_failed = np.ones(n_inner_idx, dtype=bool) + np.copyto(fim_copy, fim) + + m = 0 + while len(cholesky_failed_idx) > 0: + m += 1 + cholesky_failed = np.zeros(len(cholesky_failed_idx), dtype=bool) + """ + We need to set up copies as the decomposition routine overwrites the originals, and + we want the originals in case we don't like the latest step. For efficiency, we only + refer to the upper triangular for the XtWX copy (as it should be symmetrical). We also add + 'lambda' to the diagonals. This reduces the step size as the second derivative is increased. + """ + + lambda_diags = np.einsum( + "ab,bc->abc", + np.repeat(lambdas[cholesky_failed_idx], n_parm).reshape(len(cholesky_failed_idx), n_parm), + np.eye(n_parm), + ) + + fim_copy[cholesky_failed_idx] = fim[cholesky_failed_idx] + lambda_diags + + for i, idx in enumerate(cholesky_failed_idx): + try: + """ + Overwriting FIM with cholesky factorization using scipy.linalg.cholesky. + This is equivalent to LAPACK's dportf function (wrapper is + scipy.linalg.lapack.dpotrf) as used in the code from edgeR. + Returned is the upper triangular matrix. This is important for the steps downstream. + Overwriting the array is not possible here as individual slices are passed to the + scipy function - maybe it makes sense to use a C++ backend here and call LAPACK + directly as done in edgeR. + """ + fim_copy[idx] = cholesky(a=fim_copy[idx], lower=False, overwrite_a=False) + + except np.linalg.LinAlgError: + """ + If it fails, it MUST mean that the matrix is singular due to numerical imprecision + as all the diagonal entries of the XtWX matrix must be positive. This occurs because of + fitted values being exactly zero; thus, the coefficients attempt to converge to negative + infinity. This generally forces the step size to be larger (i.e. lambda lower) in order to + get to infinity faster (which is impossible). Low lambda leads to numerical instability + and effective singularity. To solve this, we actually increase lambda; this avoids code + breakage to give the other coefficients a chance to converge. + Failure of convergence for the zero-fitted values isn't a problem as the change in + deviance from small --> smaller coefficients isn't that great when the true value + is negative inifinity. + """ + lambdas[idx] *= 10 + if lambdas[idx] <= 0: + lambdas[idx] = ridiculously_low_value + + cholesky_failed[i] = True + + cholesky_failed_idx = cholesky_failed_idx[cholesky_failed] + + steps.fill(0) + for i in inner_idx_update: + """ + Calculating the step by solving fim_copy * step = dl using scipy.linalg.cho_solve. + This is equivalent to LAPACK's dpotrs function (wrapper is scipy.linalg.lapack.dpotrs) + as used in the code from edgeR. The int in the first argument tuple denotes lower + triangular (= 1) or upper triangular (= 0). + Again, we cannot overwrite due to a slice not passed by reference. + """ + step = cho_solve((fim_copy[i], 0), dl[i], overwrite_b=False) + overall_steps[:, i] = step + steps[:, i] = step + + # Updating loc params. + + model.theta_location += steps + + """ + Checking if the deviance has decreased or if it's too small to care about. Either case is good + and means that we'll be using the updated fitted values and coefficients. Otherwise, if we have + to repeat the inner loop, then we want to do so from the original values (as we'll be scaling + lambda up so we want to retake the step from where we were before). This is why we don't modify + the values in-place until we're sure we want to take the step. + """ + + dev_new = nb_deviance(model, inner_idx_update) # TODO ### make this a property of model + + low_deviances[inner_idx_update] = (dev_new / max_x[inner_idx_update]) < supremely_low_value + + good_updates = (dev_new <= deviances[inner_idx_update]) | low_deviances[inner_idx_update] + idx_bad_step = inner_idx_update[~good_updates] + + # Reverse update by feature if update leads to worse loss: + theta_location_new = model.theta_location.compute() + + theta_location_new[:, idx_bad_step] = theta_location_new[:, idx_bad_step] - steps[:, idx_bad_step] + model.theta_location = theta_location_new + good_idx = inner_idx_update[good_updates] + if len(good_idx) > 0: + deviances[good_idx] = dev_new[good_updates] + + # Increasing lambda, to increase damping. Again, we have to make sure it's not zero. + lambdas[idx_bad_step] = np.where( + lambdas[idx_bad_step] <= 0, ridiculously_low_value, lambdas[idx_bad_step] * 2 + ) + + # Excessive damping; steps get so small that it's pointless to continue. + failed_in_levenberg_loop[inner_idx_update] = ( + lambdas[inner_idx_update] / max_infos[inner_idx_update] + ) > (1 / supremely_low_value) + + inner_idx_update = inner_idx_update[ + ~(good_updates | failed_in_levenberg_loop[inner_idx_update]) + ] # the features for which both the update was reversed and the step size is not too small yet + + n_inner_idx = len(inner_idx_update) + + """ + Terminating if we failed, if divergence from the exact solution is acceptably low + (cross-product of dbeta with the log-likelihood derivative) or if the actual deviance + of the fit is acceptably low. + """ + divergence = np.einsum("fc,cf->f", dl[not_done_idx], overall_steps[:, not_done_idx]) + not_done_idx = not_done_idx[ + (divergence >= tolerance) & ~low_deviances[not_done_idx] & ~failed_in_levenberg_loop[not_done_idx] + ] + + n_idx = len(not_done_idx) + """ + If we quit the inner levenberg loop immediately and survived all the break conditions above, + that means that deviance is decreasing substantially. Thus, we need larger steps to get there faster. + To do so, we decrease the damping factor. Note that this only applies if we didn't decrease the + damping factor in the inner levenberg loop, as that would indicate that we need to slow down. + """ + + lambdas[levenberg_steps == 1] /= 10 + iteration += 1 + + def reset_theta_scale(self, new_scale: Union[np.ndarray, dask.array.core.Array, float]): + if isinstance(new_scale, float): + new_scale = np.full(self._model_container.theta_scale.shape, new_scale) + self._model_container.theta_scale = new_scale + + +class NBEstimator(Estimator): + def __init__( + self, + model: NBModel, + dispersion: Union[float, np.ndarray], + dtype: str = "float64", + ): + """ + Performs initialisation using QR decomposition as in edgeR and creates a new estimator. + + :param model: The NBModel object to fit. + :param dispersion: The fixed dispersion parameter to use during fitting the loc model. + :param dtype: Numerical precision. + """ + init_theta_location = np.zeros((model.xh_loc.shape[1], model.num_features), dtype=model.cast_dtype) + if isinstance(dispersion, float): + init_theta_scale = np.full((1, model.num_features), np.log(1 / dispersion)) + elif isinstance(dispersion, np.ndarray): + if dispersion.shape != (1, model.num_features): + raise ValueError( + f"Shape mismatch (dispersion): Given: {dispersion.shape} Expected: (1, {model.num_features}))" + ) + init_theta_scale = dispersion + self._train_loc = True + self._train_scale = False # This is fixed as edgeR doesn't fit the scale parameter + _model_container = ModelContainer( + model=model, + init_theta_location=init_theta_location, + init_theta_scale=init_theta_scale, + chunk_size_genes=model.chunk_size_genes, + dtype=dtype, + ) + super(NBEstimator, self).__init__(model_container=_model_container, dtype=dtype) diff --git a/batchglm/external/edgeR/external.py b/batchglm/external/edgeR/external.py new file mode 100644 index 00000000..900543c3 --- /dev/null +++ b/batchglm/external/edgeR/external.py @@ -0,0 +1,8 @@ +from batchglm.models.base_glm import ModelGLM +from batchglm.models.glm_nb.model import Model as NBModel +from batchglm.models.glm_nb.utils import init_par +from batchglm.train.numpy.base_glm import EstimatorGlm, NumpyModelContainer +from batchglm.train.numpy.glm_nb import ModelContainer +from batchglm.utils.input import InputDataGLM + +# from batchglm.train.numpy.glm_nb import Estimator as NBEstimator diff --git a/batchglm/external/edgeR/glmQLFit.py b/batchglm/external/edgeR/glmQLFit.py new file mode 100644 index 00000000..53a835b0 --- /dev/null +++ b/batchglm/external/edgeR/glmQLFit.py @@ -0,0 +1,77 @@ +from typing import List, Optional, Tuple, Union + +import numpy as np + +from .aveLogCPM import calculate_avg_log_cpm +from .estimator import NBEstimator +from .external import InputDataGLM, NBModel +from .prior_df import calculate_prior_df + + +def glm_ql_fit( + x: Union[NBModel, np.ndarray], + dispersion: Union[np.ndarray, float], + design: Optional[np.ndarray] = None, + design_loc_names: Optional[List[str]] = None, + offset: Optional[np.ndarray] = None, + lib_size: Optional[np.ndarray] = None, + size_factors: Optional[np.ndarray] = None, + tol: float = 1e-6, # TODO + weights: Optional[np.ndarray] = None, + abundance_trend: bool = True, + ave_log_cpm: Optional[np.ndarray] = None, + robust: bool = False, + winsor_tail_p: Tuple[float, float] = (0.05, 0.1), + **input_data_kwargs, +): + """ + Fit a GLM and compute quasi-likelihood dispersions for each gene. + """ + # Original method docstring: + # Fits a GLM and computes quasi-likelihood dispersions for each gene. + # Davis McCarthy, Gordon Smyth, Yunshun Chen, Aaron Lun. + # Originally part of glmQLFTest, as separate function 15 September 2014. Last modified 4 April 2020. + + if isinstance(x, np.ndarray): + if design is None: + raise AssertionError("Provide design when x is not a model already.") + if size_factors is None: + size_factors = np.log(x.sum(axis=1)) + input_data = InputDataGLM( + data=x, + design_loc=design, + design_loc_names=design_loc_names, + size_factors=size_factors, + design_scale=np.ones((x.shape[0], 1)), + design_scale_names=["Intercept"], + **input_data_kwargs, + ) + model = NBModel(input_data) + elif isinstance(x, NBModel): + model = x + else: + raise TypeError(f"Type for argument x not understood: {type(x)}. Valid types are NBModel, np.ndarray") + + # estimator = NBEstimator(model, dispersion=dispersion) + # estimator.train(maxit=250, tolerance=tol) + # glmfit = glmFit(y, design=design, dispersion=dispersion, offset=offset, lib.size=lib.size, weights=weights,...) + + # Setting up the abundances. + if abundance_trend: + if ave_log_cpm is None: + pass + # big TODO + # ave_log_cpm = calculate_avg_log_cpm(x=model.x, size_factors=TODO, dispersion=dispersion, weights=weights) + # ave_log_cpm = aveLogCPM(y, lib.size=lib.size, weights=weights, dispersion=dispersion) + # glmfit$AveLogCPM <- AveLogCPM + else: + ave_log_cpm = None + + return calculate_prior_df( + model=model, + avg_log_cpm=ave_log_cpm, + robust=robust, + winsor_tail_p=winsor_tail_p, + dispersion=dispersion, + tolerance=tol, + ) diff --git a/batchglm/external/edgeR/glm_one_group.py b/batchglm/external/edgeR/glm_one_group.py new file mode 100644 index 00000000..a5c155cd --- /dev/null +++ b/batchglm/external/edgeR/glm_one_group.py @@ -0,0 +1,84 @@ +import logging +from typing import Optional, Union + +import dask.array +import numpy as np + +from .external import NumpyModelContainer + +low_value = 1e-10 +logger = logging.getLogger(__name__) + + +def get_single_group_start( + x: Union[np.ndarray, dask.array.core.Array], + sf: Optional[Union[np.ndarray, dask.array.core.Array, float]] = None, + weights: Optional[Union[np.ndarray, float]] = None, +) -> np.ndarray: + if weights is None: + weights = 1.0 + if isinstance(weights, float): + weights = np.full(x.shape, weights) + + if weights.shape != x.shape: + raise ValueError("Shape of weights must be idential to shape of model.x") + + total_weights = weights.sum(axis=0) + + if sf is None: + sf = np.log(1.0) + elif isinstance(sf, dask.array.core.Array): + sf = sf.compute() + if not isinstance(sf, (np.ndarray, float)): + raise TypeError("sf must be of type np.ndarray, dask.array.core.Array or None") + if isinstance(x, dask.array.core.Array): + x = x.compute() + + theta_location = np.sum(np.where(x > low_value, x / np.exp(sf) * weights, 0), axis=0, keepdims=True) + with np.errstate(divide="ignore", invalid="ignore"): + theta_location = np.log(theta_location / total_weights) + return theta_location + + +def fit_single_group( + model: NumpyModelContainer, + maxit: int = 50, + tolerance: float = 1e-10, +): + """ + Setting up initial values for beta as the log of the mean of the ratio of counts to offsets. + * This is the exact solution for the gamma distribution (which is the limit of the NB as + * the dispersion goes to infinity. However, if cur_beta is not NA, then we assume it's good. + """ + low_mask = np.all(model.x <= low_value, axis=0) + if isinstance(low_mask, dask.array.core.Array): + low_mask = low_mask.compute() + unconverged_idx = np.where(~low_mask)[0] + + iteration = 0 + weights = 1.0 + + step = np.zeros((1, model.num_features), dtype=float) + + while iteration < maxit: + loc_j = model.location_j(unconverged_idx) + scale_j = 1 / model.scale_j(unconverged_idx) + denominator = 1 + loc_j * scale_j + + dl = np.sum((model.x[:, unconverged_idx] - loc_j) / denominator * weights, axis=0) + if isinstance(dl, dask.array.core.Array): + dl = dl.compute() + + info = np.sum(loc_j / denominator * weights, axis=0) + if isinstance(info, dask.array.core.Array): + info = info.compute() + cur_step = dl / info + step[0, unconverged_idx] = cur_step + model.theta_location = model.theta_location + step + unconverged_idx = unconverged_idx[np.abs(cur_step) >= tolerance] + if len(unconverged_idx) == 0: + break + step.fill(0) + iteration += 1 + else: + logger.warning("Maximum iterations exceeded.") diff --git a/batchglm/external/edgeR/limma/__init__.py b/batchglm/external/edgeR/limma/__init__.py new file mode 100644 index 00000000..98a3d3c4 --- /dev/null +++ b/batchglm/external/edgeR/limma/__init__.py @@ -0,0 +1 @@ +from .squeezeVar import squeeze_var diff --git a/batchglm/external/edgeR/limma/effects.py b/batchglm/external/edgeR/limma/effects.py new file mode 100644 index 00000000..d1a80944 --- /dev/null +++ b/batchglm/external/edgeR/limma/effects.py @@ -0,0 +1,20 @@ +from scipy.linalg.lapack import dormqr + + +def calc_effects(qr, tau, y, trans: bool = True): + """ + This function calculates the effects as returned by R's lm.fit(design, y)$effects. + The input parameters are expected to originate from calculating a qr decomposition using + (qr, tau), r = scipy.linalg.qr(design, mode='raw'). + This function is replicating R's qr.qty(qr.result, y) using the internal C-function qr_qy_real: + https://github.com/SurajGupta/r-source/blob/a28e609e72ed7c47f6ddfbb86c85279a0750f0b7/src/modules/lapack/Lapack.c#L1206 + The function uses scipy's lapack interface to call the fortran soubroutine dormqr. + """ + cq, work, info = dormqr(side="L", trans="T" if trans else "F", a=qr, tau=tau, c=y, lwork=-1) + if info != 0: + raise RuntimeError(f"dormqr in calc_effects returned error code {info}") + + cq, work, info = dormqr(side="L", trans="T" if trans else "F", a=qr, tau=tau, c=y, lwork=work[0]) + if info != 0: + raise RuntimeError(f"dormqr in calc_effects returned error code {info}") + return cq diff --git a/batchglm/external/edgeR/limma/fitFDist.py b/batchglm/external/edgeR/limma/fitFDist.py new file mode 100644 index 00000000..cf553994 --- /dev/null +++ b/batchglm/external/edgeR/limma/fitFDist.py @@ -0,0 +1,190 @@ +import logging +from typing import Optional, Tuple + +import numpy as np +import patsy +import scipy.special + +from .effects import calc_effects + +logger = logging.getLogger(__name__) + + +def fit_f_dist(x: np.ndarray, df1: np.ndarray, covariate: Optional[np.ndarray]): + """ + Moment estimation of the parameters of a scaled F-distribution. + The numerator degrees of freedom is given, the scale factor and denominator df is to be estimated. + This function is a python version of limma's fitFDist function. + """ + # Check x + n = len(x) + if n == 1: + return x, 0 + + ok = np.isfinite(df1) & (df1 > 1e-15) + + # Check covariate + + if covariate is None: + spline_df = 1 + else: + assert len(x) == len(df1) == len(covariate), "All inputs must have the same length" + if np.any(np.isnan(covariate)): + raise ValueError("NA covariate values are not allowed.") + isfin = np.isfinite(covariate) + if not np.all(isfin): + if np.any(isfin): + min_covariate = np.min(covariate) + max_covariate = np.max(covariate) + np.clip(covariate, min_covariate, max_covariate, out=covariate) + else: + covariate = np.sign(covariate) + + # Remove missing or infinite or negative values and zero degrees of freedom + ok &= np.isfinite(x) & (x > -1e-15) + n_ok = np.sum(ok) + if n_ok == 1: + return x[ok], 0 + not_all_ok = n_ok < n + if not_all_ok: + x = x[ok] + df1 = df1[ok] + if covariate is not None: + covariate_not_ok = covariate[~ok] + covariate = covariate[ok] + + # Set df for spline trend + if covariate is not None: + spline_df = 1 + int(n_ok >= 3) + int(n_ok >= 6) + int(n_ok >= 30) + spline_df = np.minimum(spline_df, len(np.unique(covariate))) + # If covariate takes only one unique value or insufficient + # observations, recall with NULL covariate + if spline_df < 2: + scale, df2 = fit_f_dist(x=x, df1=df1, covariate=None) + scale = np.full(n, scale) + return scale, df2 + + # Avoid exactly zero values + x = np.maximum(x, 0) + m = np.median(x) + if m == 0: + logger.warning("More than half of residual variances are exactly zero: eBayes unreliable") + m = 1 + elif np.any(x == 0): + logger.warning("Zero sample variances detected, have been offset away from zero") + x = np.maximum(x, 1e-5 * m) + + # Better to work on with log(F) + z = np.log(x) + e = z - scipy.special.digamma(df1 / 2) + np.log(df1 / 2) + + if covariate is None: + e_mean = np.mean(e) + e_var = np.sum(np.square(e - e_mean), keepdims=True) / (n_ok - 1) + else: + # formula = f"bs(x, df={spline_df}, degree=3, include_intercept=False)" + # formula = f"cr(x, df={spline_df})-1" + formula = f"cr(x, df={spline_df}) -1" + + design = patsy.dmatrix(formula, {"x": covariate}) + + loc_params, _, rank, _ = scipy.linalg.lstsq(design, e) + if not_all_ok: + design2 = patsy.build_design_matrices([design.design_info], data={"x": covariate_not_ok})[0] + + e_mean = np.zeros(n, dtype=float) + + e_mean[ok] = np.matmul(design, loc_params) + e_mean[~ok] = np.matmul(design2, loc_params) + else: + e_mean = np.matmul(design, loc_params) + + (qr, tau), r = scipy.linalg.qr(np.asarray(design), mode="raw") + effects = calc_effects(qr, tau, e) + e_var = np.mean(np.square(effects[rank:]), keepdims=True) + + # Estimate scale and df2 + e_var = e_var - np.mean(scipy.special.polygamma(x=df1 / 2, n=1)) # this is the trigamma function in R + + # return 0, e_var + e_var = np.array([0.5343055]) + if e_var > 0: + df2 = 2 * trigamma_inverse(e_var) + np.save(arr=e_mean, file="/home/mario/phd/collabs/batchglm/eman.csv") + s20 = np.exp(e_mean + scipy.special.digamma(df2 / 2) - np.log(df2 / 2)) + else: + df2 = np.array([np.inf]) + if covariate is None: + """ + Use simple pooled variance, which is MLE of the scale in this case. + Versions of limma before Jan 2017 returned the limiting + value of the evar>0 estimate, which is larger. + """ + s20 = np.mean(x) + else: + s20 = np.exp(e_mean) + return s20, df2 + + +def trigamma_inverse(x: np.ndarray): + """ + Solve trigamma(y) = x for y. Python version of limma's trigammaInverse function. + """ + # Non-numeric or zero length input + if len(x) == 0: + return 0 + + # Treat out-of-range values as special cases + omit = np.isnan(x) + if np.any(omit): + y = x + if np.any(~omit): + y[~omit] = trigamma_inverse(x[~omit]) + return y + + omit = x < 0 + if np.any(omit): + y = x + y[omit] = np.nan + logger.warning("NaNs produced") + if np.any(~omit): + y[~omit] = trigamma_inverse(x[~omit]) + return y + + omit = x > 1e7 + if np.any(omit): + y = x + y[omit] = 1 / np.sqrt(x[omit]) + if np.any(~omit): + y[~omit] = trigamma_inverse(x[~omit]) + return y + + omit = x < 1e-6 + if np.any(omit): + y = x + y[omit] = 1 / x[omit] + if np.any(~omit): + y[~omit] = trigamma_inverse(x[~omit]) + return y + """ + Newton's method + 1/trigamma(y) is convex, nearly linear and strictly > y-0.5, + so iteration to solve 1/x = 1/trigamma is monotonically convergent + """ + y = 0.5 + 1 / x + for _ in range(50): + tri = scipy.special.polygamma(x=y, n=1) # this is the trigamma function (psi^1(x)) + dif = tri * (1 - tri / x) / scipy.special.polygamma(x=y, n=2) # this is psi^2(x) + y = y + dif + if np.max(-dif / y) < 1e-8: + break + else: + logger.warning("Iteration limit exceeded for trigammaInverse function.") + + return y + + +def fit_f_dist_robustly( + var: np.ndarray, df1: np.ndarray, winsor_tail_p: Tuple[float, float], covariate: Optional[np.ndarray] = None +): + pass diff --git a/batchglm/external/edgeR/limma/squeezeVar.py b/batchglm/external/edgeR/limma/squeezeVar.py new file mode 100644 index 00000000..2443053f --- /dev/null +++ b/batchglm/external/edgeR/limma/squeezeVar.py @@ -0,0 +1,66 @@ +from typing import Optional, Tuple + +import numpy as np + +from .fitFDist import fit_f_dist, fit_f_dist_robustly + + +def squeeze_var( + var: np.ndarray, + df: np.ndarray, + robust: bool, + winsor_tail_p: Tuple[float, float], + covariate: Optional[np.ndarray] = None, +): + """ + This method is a python version of limma's squeezeVar function. + """ + n = len(var) + # Degenerate special cases + if n == 1: + return var, var, 0 + + # When df==0, guard against missing or infinite values in var + if len(df) > 1: + var[df == 0] = 0 + + # Estimate hyperparameters + if robust: + var_prior, df_prior = fit_f_dist_robustly(var=var, df1=df, covariate=covariate, winsor_tail_p=winsor_tail_p) + else: + var_prior, df_prior = fit_f_dist(var, df1=df, covariate=covariate) + + if np.any(np.isnan(df_prior)): + raise ValueError("Could not estimate prior df due to NaN") + + # Posterior variances + var_post = _squeeze_var(var=var, df=df, var_prior=var_prior, df_prior=df_prior) + + return df_prior, var_prior, var_post + + +def _squeeze_var(var: np.ndarray, df: np.ndarray, var_prior: np.ndarray, df_prior: np.ndarray): + """ + Squeeze posterior variances given hyperparameters. + This method is a python version of limma's _squeezeVar function. + """ + n = len(var) + isfin = np.isfinite(df_prior) + if np.all(isfin): + return (df * var + df_prior * var_prior) / (df + df_prior) + + # From here, at least some df.prior are infinite + # For infinite df_prior, return var_prior + if len(var_prior) == n: + var_post = var_prior + else: + var_post = np.full(n, var_prior) + + # Maybe some df.prior are finite + if np.any(isfin): + if len(df) > 1: + df = df[isfin] + df_prior = df_prior[isfin] + var_post[isfin] = (df * var[isfin] + df_prior * var_post[isfin]) / (df + df_prior) + + return var_post diff --git a/batchglm/external/edgeR/maximizeInterpolant.py b/batchglm/external/edgeR/maximizeInterpolant.py new file mode 100644 index 00000000..da6eb347 --- /dev/null +++ b/batchglm/external/edgeR/maximizeInterpolant.py @@ -0,0 +1,210 @@ +import numpy as np + + +def maximize_interpolant(x, y): + """ + This function takes an ordered set of spline points and a likelihood matrix where each row + corresponds to a tag and each column corresponds to a spline point. It then calculates the + position at which the maximum interpolated likelihood occurs for each by solving the derivative + of the spline function. + This function is a python derivative of edgeR's C++ implementation. + :param x: Spline points + :param y: likelihoods + """ + interpolator = Interpolator(n=len(x)) + output = np.zeros(y.shape[0], dtype=float) + for i in range(y.shape[0]): + output[i] = interpolator.find_max(x, y[i]) + return output + + +class Interpolator: + def __init__(self, n: int): + + self.npts = n + if self.npts < 2: + raise ValueError("Must have at lest two points for interpolation") + + self.b = np.zeros(n, dtype=float) + self.c = np.zeros(n, dtype=float) + self.d = np.zeros(n, dtype=float) + + def find_max(self, x, y): + maxed_at = np.argmax(y) + maxed = y[maxed_at] + """ + maxed = -1 + maxed_at = -1 + for i in range(self.npts): + # Getting a good initial guess for the MLE. + if maxed_at < 0 or y[i] > maxed: + maxed = y[i] + maxed_at = i + """ + x_max = x[maxed_at] + x, y, self.b, self.c, self.d = fmm_spline(self.npts, x, y, self.b, self.c, self.d) + + # First we have a look at the segment on the left and see if it contains the maximum. + + if maxed_at > 0: + ld = self.d[maxed_at - 1] + lc = self.c[maxed_at - 1] + lb = self.b[maxed_at - 1] + sol1_left, sol2_left, solvable_left = quad_solver(3 * ld, 2 * lc, lb) + if solvable_left: + """ + Using the solution with the maximum (not minimum). If the curve is mostly increasing, the + maximal point is located at the smaller solution (i.e. sol1 for a>0). If the curve is mostly + decreasing, the maximal is located at the larger solution (i.e., sol1 for a<0). + """ + chosen_sol = sol1_left + """ + The spline coefficients are designed such that 'x' in 'y + b*x + c*x^2 + d*x^3' is + equal to 'x_t - x_l' where 'x_l' is the left limit of that spline segment and 'x_t' + is where you want to get an interpolated value. This is necessary in 'splinefun' to + ensure that you get 'y' (i.e. the original data point) when 'x=0'. For our purposes, + the actual MLE corresponds to 'x_t' and is equal to 'solution + x_0'. + """ + if (chosen_sol > 0) and (chosen_sol < (x[maxed_at] - x[maxed_at - 1])): + temp = ((ld * chosen_sol + lc) * chosen_sol + lb) * chosen_sol + y[maxed_at - 1] + if temp > maxed: + maxed = temp + x_max = chosen_sol + x[maxed_at - 1] + + # Repeating for the segment on the right. + + if maxed_at < self.npts - 1: + rd = self.d[maxed_at] + rc = self.c[maxed_at] + rb = self.b[maxed_at] + sol1_right, sol2_right, solvable_right = quad_solver(3 * rd, 2 * rc, rb) + if solvable_right: + chosen_sol = sol1_right + if (chosen_sol > 0) and (chosen_sol < (x[maxed_at + 1] - x[maxed_at])): + temp = ((rd * chosen_sol + rc) * chosen_sol + rb) * chosen_sol + y[maxed_at] + if temp > maxed: + maxed = temp + x_max = chosen_sol + x[maxed_at] + + return x_max + + +def fmm_spline(n: int, x: np.ndarray, y: np.ndarray, b: np.ndarray, c: np.ndarray, d: np.ndarray): + """ + This code is a python derivative of fmm_spline in R core splines.c as implemented in edgeR. + """ + """ + Spline Interpolation + -------------------- + C code to perform spline fitting and interpolation. + There is code here for: + + 1. Splines with end-conditions determined by fitting + cubics in the start and end intervals (Forsythe et al). + + + Computational Techniques + ------------------------ + A special LU decomposition for symmetric tridiagonal matrices + is used for all computations, except for periodic splines where + Choleski is more efficient. + + + Splines a la Forsythe Malcolm and Moler + --------------------------------------- + In this case the end-conditions are determined by fitting + cubic polynomials to the first and last 4 points and matching + the third derivitives of the spline at the end-points to the + third derivatives of these cubics at the end-points. + """ + + i = 0 + t = 0 + + # Adjustment for 1-based arrays + """ + x -= 1 + y -= 1 + b -= 1 + c -= 1 + d -= 1 + """ + + if n < 2: + return x, y, b, c, d + + if n < 3: + t = y[1] - y[0] + b[0] = t / (x[1] - x[0]) + b[1] = b[0] + c[0] = 0.0 + c[1] = 0.0 + d[0] = 0.0 + d[1] = 0.0 + return x, y, b, c, d + + # Set up tridiagonal system + # b = diagonal, d = offdiagonal, c = right hand side + + d[0] = x[1] - x[0] + c[1] = (y[1] - y[0]) / d[0] # ;/* = +/- Inf for x[1]=x[2] -- problem? */ + for i in range(1, n - 1): + d[i] = x[i + 1] - x[i] + b[i] = 2.0 * (d[i - 1] + d[i]) + c[i + 1] = (y[i + 1] - y[i]) / d[i] + c[i] = c[i + 1] - c[i] + + """ + End conditions. + Third derivatives at x[0] and x[n-1] obtained + from divided differences + """ + + b[0] = -d[0] + + b[n - 1] = -d[n - 2] + c[0] = 0.0 + c[n - 1] = 0.0 + if n > 3: + c[0] = c[2] / (x[3] - x[1]) - c[1] / (x[2] - x[0]) + c[n - 1] = c[n - 2] / (x[n - 1] - x[n - 3]) - c[n - 3] / (x[n - 2] - x[n - 4]) + c[0] = c[0] * d[0] * d[0] / (x[3] - x[0]) + c[n - 1] = -c[n - 1] * d[n - 2] * d[n - 2] / (x[n - 1] - x[n - 4]) + + # Gaussian elimination + for i in range(1, n): + t = d[i - 1] / b[i - 1] + b[i] = b[i] - t * d[i - 1] + c[i] = c[i] - t * c[i - 1] + + # Backward substitution + + c[n - 1] = c[n - 1] / b[n - 1] + for i in range(n - 2, -1, -1): + c[i] = (c[i] - d[i] * c[i + 1]) / b[i] + + # c[i] is now the sigma[i-1] of the text + # Compute polynomial coefficients + + b[n - 1] = (y[n - 1] - y[n - 2]) / d[n - 2] + d[n - 2] * (c[n - 2] + 2.0 * c[n - 1]) + for i in range(0, n - 1): + b[i] = (y[i + 1] - y[i]) / d[i] - d[i] * (c[i + 1] + 2.0 * c[i]) + d[i] = (c[i + 1] - c[i]) / d[i] + c[i] = 3.0 * c[i] + + c[n - 1] = 3.0 * c[n - 1] + d[n - 1] = d[n - 2] + return x, y, b, c, d + + +def quad_solver(a: float, b: float, c: float): + """ + Find the two solutions for the formula x = (-b +- sqrt(b^2-4ac) / 2a + :return tuple(sol1, sol2, solvable). + """ + back = np.square(b) - 4 * a * c + if back < 0: + return None, None, False + front = -b / (2 * a) + back = np.sqrt(back) / (2 * a) + return front - back, front + back, True diff --git a/batchglm/external/edgeR/nbinomDeviance.py b/batchglm/external/edgeR/nbinomDeviance.py new file mode 100644 index 00000000..c422ccb8 --- /dev/null +++ b/batchglm/external/edgeR/nbinomDeviance.py @@ -0,0 +1,66 @@ +import time + +import numpy as np + +from .external import NumpyModelContainer + + +def nb_deviance(model: NumpyModelContainer, idx=...): + + """ + Python version of the method implemented in a C++ function in edgeR. + """ + + eps = 1e-8 + eps2 = 1e-4 + + y = model.x[:, idx].compute().copy() + mu = model.location[:, idx].compute().copy() + phi = 1 / model.scale[0, idx].compute() + + y += eps + mu += eps + + if isinstance(phi, float): + phi = np.full(y.shape[1], phi) + + deviance = np.zeros_like(y, dtype=float) + poisson_idx = phi < eps2 # .compute() + if np.any(poisson_idx): + deviance[:, poisson_idx] = _poisson_deviance(poisson_idx, y, mu, phi) + + non_poisson_idx = ~poisson_idx + y_non_poisson = y[:, non_poisson_idx] + mu_non_poisson = mu[:, non_poisson_idx] + phi_non_poisson = phi[non_poisson_idx] + product = mu_non_poisson * phi_non_poisson + + mask = product > 1e6 + + deviance[:, non_poisson_idx] = np.where( + mask, + _gamma_deviance(y_non_poisson, mu_non_poisson, product), + _nb_deviance(y_non_poisson, mu_non_poisson, phi_non_poisson), + ) + return np.sum(deviance, axis=0) + + +def _poisson_deviance(idx, y, mu, phi): + y_poisson = y[:, idx] + mu_poisson = mu[:, idx] + phi_poisson = phi + resid = y_poisson - mu_poisson + return 2 * ( + y_poisson * np.log(y_poisson / mu_poisson) + - resid + - 0.5 * resid * phi_poisson * (1 + phi_poisson * (2 / 3 * resid - y)) + ) + + +def _gamma_deviance(y, mu, product): + return 2 * ((y - mu) / mu - np.log(y / mu)) * mu / (1 + product) + + +def _nb_deviance(y, mu, phi): + inv_phi = 1 / phi + return 2 * (y * np.log(y / mu) + (y + inv_phi) * np.log((mu + inv_phi) / (y + inv_phi))) diff --git a/batchglm/external/edgeR/prior_df.py b/batchglm/external/edgeR/prior_df.py new file mode 100644 index 00000000..b163a67e --- /dev/null +++ b/batchglm/external/edgeR/prior_df.py @@ -0,0 +1,54 @@ +from typing import Optional, Tuple, Union + +import dask.array +import numpy as np + +from .c_utils import nb_deviance +from .estimator import NBEstimator +from .external import NBModel +from .limma import squeeze_var +from .residDF import resid_df + + +def calculate_prior_df( + model: NBModel, + robust: bool, + dispersion: Union[np.ndarray, float], + winsor_tail_p: Tuple[float, float], + avg_log_cpm: Optional[np.ndarray] = None, + tolerance: float = 1e-10, +): + """ + Calculates prior degrees of freedom. This is a wrapper function around limma's squeezeVar. + This is a python version of edgeR's priorDF function. + """ + estimator = NBEstimator(model, dispersion=dispersion) + estimator.train(maxit=250, tolerance=tolerance) + + fitted_model = estimator._model_container + loc = fitted_model.location + scale = fitted_model.scale + x = fitted_model.x + dloc = fitted_model.design_loc + + zerofit = (x < 1e-4) & (np.nan_to_num(loc) < 1e-4) + if isinstance(zerofit, dask.array.core.Array): + zerofit = zerofit.compute() # shape (obs, features) + if isinstance(dloc, dask.array.core.Array): + dloc = dloc.compute() + df_residual = resid_df(zerofit, dloc) + + # Empirical Bayes squeezing of the quasi-likelihood variance factors + if isinstance(x, dask.array.core.Array): + x = x.compute() + if isinstance(loc, dask.array.core.Array): + loc = loc.compute() + if isinstance(scale, dask.array.core.Array): + scale = scale.compute() + + with np.errstate(divide="ignore"): + s2 = nb_deviance(x, loc, scale, True) / df_residual + s2[df_residual == 0] = 0.0 + s2 = np.maximum(s2, 0) + + return squeeze_var(s2, df=df_residual, covariate=avg_log_cpm, robust=robust, winsor_tail_p=winsor_tail_p) diff --git a/batchglm/external/edgeR/qr_decomposition.py b/batchglm/external/edgeR/qr_decomposition.py new file mode 100644 index 00000000..d26b375e --- /dev/null +++ b/batchglm/external/edgeR/qr_decomposition.py @@ -0,0 +1,104 @@ +import dask.array +import numpy as np +from scipy.linalg.lapack import dgeqrf, dormqr, dtrtrs + +from .external import ModelGLM + + +class QRDecomposition: + def __init__(self, nrows: int, ncoefs: int, cur_x): + self.nr = nrows + self.nc = ncoefs + self.x = cur_x + self.weights = 1.0 # np.zeros(nrows) + self.lwork_geqrf = -1 + self.lwork_ormqr = -1 + self.trans_trtrs = 0 + self.trans_ormqr = "T" + self.side = "L" + + # workspace queries calling LAPACK subroutines via scipy.linalg.lapack + self.x_copy, self.tau, tmpwork, info = dgeqrf(a=np.zeros((self.nr, self.nc)), lwork=self.lwork_geqrf) + self.lwork_geqrf = tmpwork + 0.5 + if self.lwork_geqrf < 1: + self.lwork_geqrf = 1 + + self.effects, tmpwork, info = dormqr( + side=self.side, + trans=self.trans_ormqr, + a=self.x_copy, + tau=self.tau, + c=np.zeros((ncoefs, 1)), + lwork=self.lwork_ormqr, + ) + self.lwork_ormqr = tmpwork + 0.5 + if self.lwork_ormqr < 1: + self.lwork_ormqr = 1 + + def store_weights(self, w=None): + if w is None: + self.weights = 1.0 + else: + self.weights = np.sqrt(w) + + def decompose(self): + self.x_copy = self.x.copy() + self.x_copy *= self.weights + + self.x_copy, self.tau, tmpwork, info = dgeqrf(a=self.x_copy, lwork=self.lwork_geqrf) + if info != 0: + raise RuntimeError("QR decomposition failed") + + def solve(self, y): + self.effects = (y * self.weights)[..., None] + self.effects, tmpwork, info = dormqr( + side="L", trans="T", a=self.x_copy, tau=self.tau, c=self.effects, lwork=self.lwork_ormqr + ) + if info != 0: + raise RuntimeError("Q**T multiplication failed") + self.effects, info = dtrtrs(lower=0, trans=0, unitdiag=0, a=self.x_copy, b=self.effects) + if info != 0: + raise RuntimeError("failed to solve the triangular system") + + +def get_levenberg_start(model: ModelGLM, disp: np.ndarray, use_null: bool): + """ + Parameter initialisation of location parameters using QR decomposition. + This method is a python version of the C++ code in edgeR. + :param model: A GLM model object + :param disp: the fixed dispersion parameter used during the calculation. + :param use_null: ??? this must be true, the other is not implemented + """ + + n_obs = model.num_observations + n_features = model.num_features + n_parm = model.num_loc_params + model_weights = np.ones(n_features, dtype=float) # TODO ### integrate into model + + qr = QRDecomposition(n_obs, n_parm, model.design_loc) + output = np.zeros((n_parm, model.num_features), dtype=float) # shape (n_parm, n_features) + + if use_null: + + qr.store_weights(w=None) + qr.decompose() + + if model.size_factors is None: + sf_exp = np.ones((n_obs, 1), dtype=float) + else: + sf_exp = np.exp(model.size_factors) # shape (n_obs, 1) + weights = model_weights * sf_exp / (1.0 + disp * sf_exp) # shape (n_obs, n_features) + sum_norm_x = np.sum(model.x * weights / sf_exp, axis=0) # shape (n_features,) + sum_weights = np.sum(weights, axis=0) # shape (n_features,) + + values = np.broadcast_to(np.log(sum_norm_x / sum_weights), (n_obs, n_features)) + if isinstance(values, dask.array.core.Array): + values = values.compute() # shape(n_obs, n_features) + + for j in range(n_features): + qr.solve(values[:, j]) + output[:, j] = qr.effects[:n_parm, 0] + + else: + raise NotImplementedError("This method is not yet implemented.") + return output diff --git a/batchglm/external/edgeR/residDF.py b/batchglm/external/edgeR/residDF.py new file mode 100644 index 00000000..20fbd167 --- /dev/null +++ b/batchglm/external/edgeR/residDF.py @@ -0,0 +1,40 @@ +import numpy as np + + +def combo_groups(truths: np.ndarray): + """ + Function that returns a list of index lists, where each list refers to + the rows with the same combination of TRUE/FALSE values in 'truths'. + """ + uniq_cols, rev_index = np.unique(truths, axis=1, return_inverse=True) + return [np.where(rev_index == i)[0] for i in range(uniq_cols.shape[1])] + + +def resid_df(zero: np.ndarray, design: np.ndarray): + """ + Computes residual degrees of freedom. + :param zero: boolean np.ndarray of shape (n_obs x n_features). It yields True if both + the data and the fitted value of a GLM where close to zero within a small margin. + :param design: the design matrix used in the GLM. + """ + + n_obs = zero.shape[0] + n_param = design.shape[1] + n_zero = np.sum(zero, axis=0) # the number of zeros per feature; shape = (n_features, ) + + degrees_of_freedom = np.full(zero.shape[1], n_obs - n_param) # shape = (n_features, ) + degrees_of_freedom[n_zero == n_obs] = 0 # 0 if only zeros for specific feature + + some_zero_idx = (n_zero > 0) & (n_zero < n_obs) # shape = (n_features, ) + if np.any(some_zero_idx): + some_zero = zero[:, some_zero_idx] # shape = (n_obs, len(np.where(some_zero_idx))) + groupings = combo_groups(some_zero) # list of idx in some_zero with identical cols + + degrees_of_freedom_some_zero = n_obs - n_zero[some_zero_idx] + for group in groupings: + some_zero_group = some_zero[:, group[0]] # shape = (n_obs, ) + degrees_of_freedom_some_zero[group] -= np.linalg.matrix_rank(design[~some_zero_group]) + degrees_of_freedom_some_zero = np.max(degrees_of_freedom_some_zero, 0) + degrees_of_freedom[some_zero_idx] = degrees_of_freedom_some_zero + + return degrees_of_freedom diff --git a/batchglm/external/edgeR/wleb.py b/batchglm/external/edgeR/wleb.py new file mode 100644 index 00000000..a74ab08c --- /dev/null +++ b/batchglm/external/edgeR/wleb.py @@ -0,0 +1,111 @@ +from typing import Any, Optional, Union + +import dask.array +import numpy as np + +from .c_utils import loess_by_col +from .maximizeInterpolant import maximize_interpolant + + +def wleb( + theta: Any, + loglik: Any, + prior_n: int = 5, + covariate: Optional[np.ndarray] = None, + trend_method: Optional[str] = "loess", + span: Any = None, + overall: bool = True, + trend: bool = True, + individual: bool = True, + m0: Any = None, +): + """ + Weighted likelihood empirical Bayes for estimating a parameter vector theta + given log-likelihood values on a grid of theta values. + The method is taken over from edgeR's wleb method. + + :param theta: the parameter vector which is a grid of disperions values. + :param loglik: a log-likelihood matrix with shape (features, len(theta)) + containing the ll for each feature given a certain theta. + :param prior_n: ??? + :param covariate: the average log counts per million for each feature over + the observations + :param trend_method: The method to use for calculating the trend. Currently, + only loess as implemented in edgeR is supported. + :param span: Optional window size used during the trend estimation. + :param overall: If true, compute the overall prior ??? + :param trend: If true, compute the trend over all thetas + :param individual: If true, compute weighted empirical bayes posterior estimates. + :param m0: Optional output of a trend fitting procedure as specified + by trend_method. + + :return: Tuple(out_span, out_overall, m0, out_trend, out_individual) + """ + n_features, n_theta = loglik.shape + if covariate is None and trend_method is not None: + raise ValueError("covariate cannot be None if trend_method is given.") + + if span is None: + if n_features < 50: + span = 1 + else: + span = 0.25 + 0.75 * np.sqrt(50 / n_features) + out_span = span + + out_overall = None + out_trend = None + out_individual = None + + if overall: + out_overall = maximize_interpolant(theta, np.sum(loglik, axis=0, keepdims=True)) + + # calculate trended prior + if m0 is None: + if trend_method is None: + m0 = np.broadcast_to(np.sum(loglik, axis=0), loglik.shape) + elif trend_method == "loess": + m0, _ = loess(span=out_span, y=loglik, x=covariate) + else: + raise NotImplementedError(f"Method {trend_method} is not yet implemented.") + + if trend: + out_trend = maximize_interpolant(theta, m0) + + # weighted empirical Bayes posterior estimates + if individual: + assert np.all(np.isfinite(prior_n)), "prior_n must not contain infinite values." + l0a = loglik + prior_n * m0 + out_individual = maximize_interpolant(theta, l0a) + + return out_span, out_overall, m0, out_trend, out_individual + + +def loess(span: float, y: np.ndarray, x: Optional[Union[np.ndarray, dask.array.core.Array]] = None): + """ + Wrapper around loess as implemented in edgeR. This calls the C++ + function loess_by_col. + """ + n_features = y.shape[0] + if x is None: + x = np.arange(n_features) + elif isinstance(x, dask.array.core.Array): + x = x.compute() + if not isinstance(x, np.ndarray): + raise TypeError("x must be of type np.ndarray, None or dask.array.core.Array") + + order = np.argsort(x, kind="stable") + y = y[order] + x = x[order] + + n_span = int(np.minimum(np.floor(span * n_features), n_features)) + + if n_span <= 1: + y_smooth = y + leverages = np.arange(n_features) + return y_smooth, leverages + + y_smooth, leverages_smooth = loess_by_col(x, y, n_span) + y_smooth[order] = y_smooth.copy() + leverages_smooth[order] = leverages_smooth.copy() + + return y_smooth, leverages_smooth diff --git a/batchglm/models/base_glm/utils.py b/batchglm/models/base_glm/utils.py index 95c3e6fa..85648cc3 100644 --- a/batchglm/models/base_glm/utils.py +++ b/batchglm/models/base_glm/utils.py @@ -74,7 +74,7 @@ def generate_sample_description( def closedform_glm_mean( x: Union[np.ndarray, scipy.sparse.csr_matrix, dask.array.core.Array], dmat: Union[np.ndarray, dask.array.core.Array], - constraints: Optional[Union[np.ndarray, dask.array.core.Array]] = None, + constraints: Union[np.ndarray, dask.array.core.Array], size_factors: Optional[np.ndarray] = None, link_fn: Optional[Callable] = None, inv_link_fn: Optional[Callable] = None, @@ -118,7 +118,7 @@ def apply_fun(grouping): def closedform_glm_scale( x: Union[np.ndarray, scipy.sparse.csr_matrix, dask.array.core.Array], design_scale: Union[np.ndarray, dask.array.core.Array], - constraints: Optional[Union[np.ndarray, dask.array.core.Array]] = None, + constraints: Union[np.ndarray, dask.array.core.Array], size_factors: Optional[np.ndarray] = None, groupwise_means: Optional[np.ndarray] = None, link_fn: Optional[Callable] = None, diff --git a/batchglm/models/glm_beta/utils.py b/batchglm/models/glm_beta/utils.py index 1c8d8ded..9f8dcb77 100644 --- a/batchglm/models/glm_beta/utils.py +++ b/batchglm/models/glm_beta/utils.py @@ -9,7 +9,7 @@ def closedform_beta_glm_logitmean( x: Union[np.ndarray, scipy.sparse.csr_matrix], design_loc: np.ndarray, - constraints_loc, + constraints_loc: np.ndarray, size_factors=None, link_fn=lambda x: np.log(1 / (1 / x - 1)), inv_link_fn=lambda x: 1 / (1 + np.exp(-x)), @@ -39,7 +39,7 @@ def closedform_beta_glm_logitmean( def closedform_beta_glm_logsamplesize( x: Union[np.ndarray, scipy.sparse.csr_matrix], design_scale: np.ndarray, - constraints=None, + constraints: np.ndarray, size_factors=None, groupwise_means=None, link_fn=np.log, diff --git a/batchglm/models/glm_nb/model.py b/batchglm/models/glm_nb/model.py index 6d86d3c9..6abc910b 100644 --- a/batchglm/models/glm_nb/model.py +++ b/batchglm/models/glm_nb/model.py @@ -57,20 +57,20 @@ def phi(self) -> Union[np.ndarray, dask.array.core.Array]: def bounds(self, sf, dmax, dtype) -> Tuple[Dict[str, Any], Dict[str, Any]]: bounds_min = { - "theta_location": np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, - "theta_scale": np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, - "eta_loc": np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, - "eta_scale": np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, + "theta_location": -1e8, # np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, + "theta_scale": -1e8, # np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, + "eta_loc": -1e8, # np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, + "eta_scale": -1e8, # np.log(np.nextafter(0, np.inf, dtype=dtype)) / sf, "loc": np.nextafter(0, np.inf, dtype=dtype), "scale": np.nextafter(0, np.inf, dtype=dtype), "likelihood": dtype(0), - "ll": np.log(np.nextafter(0, np.inf, dtype=dtype)), + "ll": -1e8, # np.log(np.nextafter(0, np.inf, dtype=dtype)), } bounds_max = { - "theta_location": np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, - "theta_scale": np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, - "eta_loc": np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, - "eta_scale": np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, + "theta_location": 1e10, # np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, + "theta_scale": 1e10, # np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, + "eta_loc": 1e10, # np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, + "eta_scale": 1e10, # np.nextafter(np.log(dmax), -np.inf, dtype=dtype) / sf, "loc": np.nextafter(dmax, -np.inf, dtype=dtype) / sf, "scale": np.nextafter(dmax, -np.inf, dtype=dtype) / sf, "likelihood": dtype(1), diff --git a/batchglm/models/glm_nb/utils.py b/batchglm/models/glm_nb/utils.py index 2a0c78cc..dd292582 100644 --- a/batchglm/models/glm_nb/utils.py +++ b/batchglm/models/glm_nb/utils.py @@ -43,7 +43,7 @@ def closedform_nb_glm_logmu( def closedform_nb_glm_logphi( x: Union[np.ndarray, scipy.sparse.csr_matrix, dask.array.core.Array], design_scale: Union[np.ndarray, dask.array.core.Array], - constraints: Optional[Union[np.ndarray, dask.array.core.Array]] = None, + constraints: Union[np.ndarray, dask.array.core.Array], size_factors: Optional[np.ndarray] = None, groupwise_means: Optional[np.ndarray] = None, link_fn: Callable = np.log, diff --git a/batchglm/train/base/external.py b/batchglm/train/base/external.py new file mode 100644 index 00000000..1f38c7e5 --- /dev/null +++ b/batchglm/train/base/external.py @@ -0,0 +1 @@ +from batchglm.models.base_glm import ModelGLM diff --git a/batchglm/train/numpy/base_glm/estimator.py b/batchglm/train/numpy/base_glm/estimator.py index 913cdacc..7b9a9063 100644 --- a/batchglm/train/numpy/base_glm/estimator.py +++ b/batchglm/train/numpy/base_glm/estimator.py @@ -17,9 +17,17 @@ from .external import BaseEstimatorGlm, pkg_constants from .model_container import NumpyModelContainer from .training_strategies import TrainingStrategies +from .vst import bw_kde, geometric_mean, is_outlier, log_geometric_mean logger = logging.getLogger("batchglm") +try: + from skfda.preprocessing.smoothing.kernel_smoothers import NadarayaWatsonSmoother as NWSmoother + from skfda.representation.grid import FDataGrid +except ImportError: + FDataGrid = None + NWSmoother = None + class EstimatorGlm(BaseEstimatorGlm): """ @@ -86,9 +94,103 @@ def train_sequence(self, training_strategy, **kwargs): "overrding %s from training strategy with value %s with new value %s\n" % (x, str(d[x]), str(kwargs[x])) ) + + ds_method = d.get("dispersion_smoothing", "no_smoothing") + + # perform checks before starting the training procedure + if ds_method == "sctransform" and (FDataGrid is None or NWSmoother is None): + logger.error("Missing optional dependency scikit-fda.") + if ds_method not in ["sctransform", "no_smoothing"]: + raise AssertionError(f"Unknown dispersion smoothing method: {ds_method}") + + # now start the training self.train(**d, **kwargs) logger.debug("Training sequence #%d complete", idx + 1) + # perform dispersion smoothing after training if specified + if ds_method == "no_smoothing": + continue + elif ds_method == "sctransform": + self.perform_vst() + elif ds_method == "edger": + raise NotImplementedError() + elif ds_method == "deseq2": + raise NotImplementedError() + + def perform_vst( + self, + theta_regularization: str = "od_factor", + use_geometric_mean: bool = True, + gmean_eps: float = 1.0, + bw_adjust: float = 1.5, + ): + logger.info("Performing Dispersion smoothing with flavour sctransform...") + # compute geometric log mean counts + if use_geometric_mean: + featurewise_means = np.log10(geometric_mean(self.model_container.x, axis=0, eps=gmean_eps)) + else: + featurewise_means = np.log10(np.mean(self.model_container.x, axis=0)) + if isinstance(featurewise_means, dask.array.core.Array): + featurewise_means = featurewise_means.compute() + + # specify which kind of regularization is performed + scale_param = np.exp(self.model_container.theta_scale[0]) # TODO check if this is always correct + if theta_regularization == "log_theta": + dispersion_par = np.log10(scale_param) + elif theta_regularization == "od_factor": + dispersion_par = np.log10(1 + np.power(10, featurewise_means) / scale_param) + else: + raise ValueError(f"Unrecognized regularization method {theta_regularization}") + if isinstance(dispersion_par, dask.array.core.Array): + dispersion_par = dispersion_par.compute() + + # downsample because KDE and bandwidth selection would take too long if performed on the entire dataset. + # It is sufficient to get a general idea of the data distribution + if len(featurewise_means) > 2000: + logger.info("Sampling 2000 random features...") + idx = np.random.choice(np.arange(len(featurewise_means)), 2000) + featurewise_means_filtered = featurewise_means[idx] + dispersion_par_filtered = dispersion_par[idx] + else: + dispersion_par_filtered = dispersion_par + featurewise_means_filtered = featurewise_means + + # check for outliers in the function f(featurewise_means_filtered) = dispersion_par_filtered and remove them + logger.info("Searching for outliers...") + outliers = is_outlier(model_param=dispersion_par_filtered, means=featurewise_means_filtered) + if np.any(outliers): + # toss out the outliers + logger.info(f"Excluded {np.sum(outliers)} outliers.") + featurewise_means_filtered = featurewise_means_filtered[~outliers] + dispersion_par_filtered = dispersion_par_filtered[~outliers] + + # define a data grid with the downsampled and filtered values + domain_range = featurewise_means_filtered.min(), featurewise_means_filtered.max() + fd = FDataGrid( + data_matrix=dispersion_par_filtered, grid_points=featurewise_means_filtered, domain_range=domain_range + ) + # select bandwidth to be used for smoothing + bw = bw_kde(featurewise_means_filtered) * bw_adjust + + # define points for evaluation. Ensure x_points is within the range of featurewise_means_filtered + x_points = np.clip(featurewise_means, *domain_range) + # smooth the dispersion_par + logger.info("Performing smoothing...") + smoother = NWSmoother(smoothing_parameter=bw, output_points=x_points) + dispersion_par_smoothed = smoother.fit_transform(fd).data_matrix[0, :, 0] + + # transform back to scale param + if theta_regularization == "log_theta": + smoothed_scale = np.power(10, dispersion_par_smoothed) + elif theta_regularization == "od_factor": + smoothed_scale = np.power(10, featurewise_means) / (np.power(10, dispersion_par_smoothed) - 1) + else: + raise ValueError(f"Unrecognized regularization method {theta_regularization}") + + # store smoothed dispersion_par + self.model_container.theta_scale_smoothed = np.log(smoothed_scale) + logger.info("Done with dispersion smoothing.") + def initialize(self): pass diff --git a/batchglm/train/numpy/base_glm/model_container.py b/batchglm/train/numpy/base_glm/model_container.py index e39bb047..0df2c823 100644 --- a/batchglm/train/numpy/base_glm/model_container.py +++ b/batchglm/train/numpy/base_glm/model_container.py @@ -184,6 +184,16 @@ def theta_scale_j_setter(self, value: Union[np.ndarray, dask.array.core.Array], else: self.params[self.npar_location :, j] = value + # dispersion_smoothing + + @property + def theta_scale_smoothed(self) -> np.ndarray: + return self._theta_scale_smoothed + + @theta_scale_smoothed.setter + def theta_scale_smoothed(self, value): + self._theta_scale_smoothed = value + # jacobians @abc.abstractmethod diff --git a/batchglm/train/numpy/base_glm/training_strategies.py b/batchglm/train/numpy/base_glm/training_strategies.py index 6b8477bd..855ca99d 100644 --- a/batchglm/train/numpy/base_glm/training_strategies.py +++ b/batchglm/train/numpy/base_glm/training_strategies.py @@ -13,6 +13,25 @@ class TrainingStrategies(Enum): "max_iter_scale": 1000, }, ] - GD = [ - {"max_steps": 1000, "method_scale": "gd", "update_scale_freq": 5, "ftol_scale": 1e-6, "max_iter_scale": 100}, + GD = ( + [ + { + "max_steps": 1000, + "method_scale": "gd", + "update_scale_freq": 5, + "ftol_scale": 1e-6, + "max_iter_scale": 100, + }, + ], + ) + + SCTRANSFORM = [ + { + "max_steps": 1000, + "method_scale": "brent", + "update_scale_freq": 5, + "ftol_scale": 1e-6, + "max_iter_scale": 1000, + "dispersion_smoothing": "sctransform", + }, ] diff --git a/batchglm/train/numpy/base_glm/vst.py b/batchglm/train/numpy/base_glm/vst.py new file mode 100644 index 00000000..8220b2ae --- /dev/null +++ b/batchglm/train/numpy/base_glm/vst.py @@ -0,0 +1,99 @@ +from typing import Optional, Union + +import numpy as np +import pandas as pd +from scipy.stats import gaussian_kde + + +def log_geometric_mean(a: np.ndarray, axis: Optional[int] = None, eps: Union[int, float] = 1.0): + """ + Returns the log of the geometric mean defined as mean(log(a + eps)). + :param a: np.ndarray containing the data + :param axis: the axis over which the log geometric mean is calculated. If None, computes the log geometric mean + over the entire data. + :param eps: small value added to each value in order to avoid computing log(0). Default is 1, i.e. log(x) is + equivalent to np.log1p(x). + :return np.ndarray: An array with the same length as the axis not used for computation containing the log geometric + means. + """ + log_a = np.log(a + eps) + return np.mean(log_a, axis=axis) + + +def geometric_mean(a: np.ndarray, axis: Optional[int] = None, eps: Union[int, float] = 1.0): + r""" + Return the geometric mean defined as (\prod_{i=1}^{n}(x_{i} + eps))^{1/n} - eps computed in log space as + exp(1/n(sum_{i=1}^{n}(ln(x_{i} + eps)))) - eps for numerical stability. + :param a: np.ndarray containing the data + :param axis: the axis over which the geometric mean is calculated. If None, computes the geometric mean over the + entire data. + :param eps: small value added to each value in order to avoid computing log(0). Default is 1, i.e. log(x) is + equivalent to np.log1p(x). + :return np.ndarray: An array with the same length as the axis not used for computation containing the geometric + means. + """ + log_geo_mean = log_geometric_mean(a, axis, eps) + return np.exp(log_geo_mean) - eps + + +def bw_kde(x: np.ndarray, method: str = "silverman"): + """ + Performs gaussian kernel density estimation using a specified method and returns the estimated bandwidth. + :param x: np.ndarray of values for which the KDE is performed. + :param method: The method used for estimating an optimal bandwidth, see scipy gaussian_kde documentation for + available methods. + :return float: The estimated bandwidth + """ + return gaussian_kde(x, bw_method=method).factor * 0.37 + + +def robust_scale(x: pd.Series, c: float = 1.4826, eps: Optional[Union[int, float]] = None): + r""" + Compute a scale param using the formula scale_{i} = (x_{i} - median(x)) / mad(x) where + mad = c * median(abs(x_{i} - median(x))) + eps is the median absolute deviation. + This function is derived from sctransform's implementation of robust scale: + https://github.com/satijalab/sctransform/blob/7e9c9557222d1e34416e8854ed22da580e533e78/R/utils.R#L162-L163 + :param x: pd.Series containing the values used to compute the scale. + :param c: Scaling constant used in the computation of mad. The default value is equivalent to the R implementation + of mad: https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/mad + :param eps: Small value added to the mad. If None, it defaults to `np.finfo(float).eps`. This should be equivalent + to sctransform's `.Machine$double.eps`. + + :return pd.Series containing the computed scales. + """ + if eps is None: + eps = float(np.finfo(float).eps) + + deviation = x - x.median() + mad = c * deviation.abs().median() + eps + scale = deviation / mad + return scale + + +def is_outlier(model_param: np.ndarray, means: np.ndarray, threshold: Union[int, float] = 10): + """ + Compute outlier genes based on deviation of model_param from mean counts in individual bins. + This function is derived from sctransform's implementation of is_outlier: + https://github.com/satijalab/sctransform/blob/7e9c9557222d1e34416e8854ed22da580e533e78/R/utils.R#L120-L129 + :param model_param: np.ndarray of a specific model_param. This can be the intercept, any batch/condition or + loc/scale param. This is the param based on which it is determined if a specific gene is an outlier. + :param means: np.ndarray of genewise mean counts. The means are used to determine bins within outlier detection of + the model_param is performed. + :param threshold: The minimal score required for a model_param to be considered an outlier. + + :return np.ndarray of booleans indicating if a particular gene is an outlier (True) or not (False). + """ + bin_width = (means.max() - means.min()) * bw_kde(means) / 2 + eps = np.finfo(float).eps * 10 + + breaks1 = np.arange(means.min() - eps, means.max() + bin_width, bin_width) + breaks2 = np.arange(means.min() - eps - bin_width / 2, means.max() + bin_width, bin_width) + bins1 = pd.cut(means, bins=breaks1) + bins2 = pd.cut(means, bins=breaks2) + + df_tmp = pd.DataFrame({"param": model_param, "bins1": bins1, "bins2": bins2}) + df_tmp["score1"] = df_tmp.groupby("bins1")["param"].transform(robust_scale) + df_tmp["score2"] = df_tmp.groupby("bins2")["param"].transform(robust_scale) + df_tmp["outlier"] = df_tmp[["score1", "score2"]].abs().min(axis=1) > threshold + + return df_tmp["outlier"].to_numpy() diff --git a/poetry.lock b/poetry.lock index ac86e750..0d438f32 100644 --- a/poetry.lock +++ b/poetry.lock @@ -24,9 +24,9 @@ scipy = ">1.4" xlrd = "<2.0" [package.extras] -dev = ["setuptools-scm", "black (>=20.8b1)", "docutils"] -doc = ["sphinx (>=4.1,<4.2)", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.11.0)", "sphinx-issues", "scanpydoc (>=0.7.3)", "typing-extensions"] -test = ["loompy (>=3.0.5)", "pytest (>=6.0)", "pytest-cov (>=2.10)", "zarr", "matplotlib", "sklearn", "openpyxl", "joblib", "boltons", "scanpy"] +dev = ["black (>=20.8b1)", "docutils", "setuptools-scm"] +doc = ["scanpydoc (>=0.7.3)", "sphinx (>=4.1,<4.2)", "sphinx-autodoc-typehints (>=1.11.0)", "sphinx-issues", "sphinx-rtd-theme", "typing-extensions"] +test = ["boltons", "joblib", "loompy (>=3.0.5)", "matplotlib", "openpyxl", "pytest (>=6.0)", "pytest-cov (>=2.10)", "scanpy", "sklearn", "zarr"] [[package]] name = "appdirs" @@ -38,18 +38,18 @@ python-versions = "*" [[package]] name = "argcomplete" -version = "1.12.3" +version = "2.0.0" description = "Bash tab completion for argparse" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [package.extras] test = ["coverage", "flake8", "pexpect", "wheel"] [[package]] name = "arrow" -version = "1.2.2" +version = "1.2.3" description = "Better dates & times for Python" category = "dev" optional = false @@ -69,27 +69,19 @@ python-versions = ">=3.7" [package.dependencies] cached-property = "*" -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "attrs" -version = "21.4.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "babel" @@ -134,11 +126,11 @@ chardet = ">=3.0.2" [[package]] name = "black" -version = "22.6.0" +version = "22.10.0" description = "The uncompromising code formatter." category = "dev" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7" [package.dependencies] click = ">=8.0.0" @@ -164,7 +156,7 @@ python-versions = "*" [[package]] name = "certifi" -version = "2022.6.15" +version = "2022.9.24" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -199,7 +191,7 @@ python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "2.1.0" +version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -221,7 +213,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "cloudpickle" -version = "2.1.0" +version = "2.2.0" description = "Extended pickling support for Python objects" category = "main" optional = false @@ -237,7 +229,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "colorlog" -version = "6.6.0" +version = "6.7.0" description = "Add colours to the output of Python's logging module." category = "dev" optional = false @@ -260,6 +252,24 @@ python-versions = "*" [package.extras] test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] +[[package]] +name = "contourpy" +version = "1.0.5" +description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = ">=1.16" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["docutils (<0.18)", "sphinx", "sphinx-rtd-theme"] +test = ["flake8", "isort", "matplotlib", "pillow", "pytest"] +test-minimal = ["pytest"] +test-no-codebase = ["matplotlib", "pillow", "pytest"] + [[package]] name = "cookiecutter" version = "1.7.3" @@ -295,8 +305,8 @@ cryptography = ">=3.4.7,<37.0.0" GitPython = ">=3.1.17,<4.0.0" packaging = ">=20.9,<22.0" pygithub = ">=1.54.1,<2.0.0" -PyNaCl = "1.5.0" pynacl = ">=1.4.0,<2.0.0" +PyNaCl = "1.5.0" questionary = ">=1.9.0,<2.0.0" requests = ">=2.25.1,<3.0.0" rich = ">=10.2.2,<11.0.0" @@ -329,11 +339,11 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] -docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] sdist = ["setuptools_rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] [[package]] name = "cycler" @@ -386,11 +396,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] +dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "distlib" -version = "0.3.4" +version = "0.3.6" description = "Distribution utilities" category = "dev" optional = false @@ -406,7 +416,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "dparse" -version = "0.5.1" +version = "0.6.2" description = "A parser for Python dependency files" category = "dev" optional = false @@ -414,23 +424,23 @@ python-versions = ">=3.5" [package.dependencies] packaging = "*" -pyyaml = "*" toml = "*" [package.extras] +conda = ["pyyaml"] pipenv = ["pipenv"] [[package]] name = "filelock" -version = "3.7.1" +version = "3.8.0" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] -testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] +docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] +testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] [[package]] name = "flake8" @@ -499,7 +509,7 @@ flake8 = "*" [[package]] name = "flake8-rst-docstrings" -version = "0.2.6" +version = "0.2.7" description = "Python docstring reStructuredText (RST) validator" category = "dev" optional = false @@ -512,16 +522,16 @@ restructuredtext-lint = "*" [[package]] name = "fonttools" -version = "4.34.4" +version = "4.37.4" description = "Tools to manipulate font files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "uharfbuzz (>=0.23.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=14.0.0)", "xattr"] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=14.0.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["scipy", "munkres"] +interpolatable = ["munkres", "scipy"] lxml = ["lxml (>=4.0,<5)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] @@ -530,11 +540,11 @@ symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] unicode = ["unicodedata2 (>=14.0.0)"] -woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "fsspec" -version = "2022.5.0" +version = "2022.8.2" description = "File-system specification" category = "main" optional = false @@ -545,7 +555,7 @@ abfs = ["adlfs"] adl = ["adlfs"] arrow = ["pyarrow (>=1)"] dask = ["dask", "distributed"] -dropbox = ["dropboxdrivefs", "requests", "dropbox"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] entrypoints = ["importlib-metadata"] fuse = ["fusepy"] gcs = ["gcsfs"] @@ -554,7 +564,7 @@ github = ["requests"] gs = ["gcsfs"] gui = ["panel"] hdfs = ["pyarrow (>=1)"] -http = ["requests", "aiohttp"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] libarchive = ["libarchive-c"] oci = ["ocifs"] s3 = ["s3fs"] @@ -576,7 +586,7 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.27" +version = "3.1.28" description = "GitPython is a python library used to interact with Git repositories" category = "main" optional = false @@ -598,7 +608,7 @@ numpy = ">=1.14.5" [[package]] name = "identify" -version = "2.5.1" +version = "2.5.6" description = "File identification library for Python" category = "dev" optional = false @@ -609,7 +619,7 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.3" +version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false @@ -625,7 +635,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.12.0" +version = "5.0.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -635,9 +645,9 @@ python-versions = ">=3.7" zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" @@ -675,7 +685,7 @@ jinja2 = "*" [[package]] name = "kiwisolver" -version = "1.4.3" +version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" category = "main" optional = false @@ -695,11 +705,11 @@ tornado = {version = "*", markers = "python_version > \"2.7\""} [[package]] name = "llvmlite" -version = "0.36.0" +version = "0.39.1" description = "lightweight wrapper around basic LLVM functionality" category = "main" optional = false -python-versions = ">=3.6,<3.10" +python-versions = ">=3.7" [[package]] name = "locket" @@ -719,22 +729,23 @@ python-versions = ">=3.7" [[package]] name = "matplotlib" -version = "3.5.2" +version = "3.6.0" description = "Python plotting package" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] +contourpy = ">=1.0.1" cycler = ">=0.10" fonttools = ">=4.22.0" kiwisolver = ">=1.0.1" -numpy = ">=1.17" +numpy = ">=1.19" packaging = ">=20.0" pillow = ">=6.2.0" pyparsing = ">=2.2.1" python-dateutil = ">=2.7" -setuptools_scm = ">=4" +setuptools_scm = ">=7" [[package]] name = "mccabe" @@ -746,20 +757,21 @@ python-versions = "*" [[package]] name = "mypy" -version = "0.910" +version = "0.971" description = "Optional static typing for Python" category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.dependencies] -mypy-extensions = ">=0.4.3,<0.5.0" -toml = "*" -typing-extensions = ">=3.7.4" +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] -python2 = ["typed-ast (>=1.4.0,<1.5.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -771,7 +783,7 @@ python-versions = "*" [[package]] name = "natsort" -version = "8.1.0" +version = "8.2.0" description = "Simple yet flexible natural sorting in Python." category = "main" optional = false @@ -791,18 +803,18 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.* [[package]] name = "nox" -version = "2022.1.7" +version = "2022.8.7" description = "Flexible test automation." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -argcomplete = ">=1.9.4,<2.0" +argcomplete = ">=1.9.4,<3.0" colorlog = ">=2.6.1,<7.0.0" packaging = ">=20.9" -py = ">=1.4.0,<2.0.0" -virtualenv = ">=14.0.0" +py = ">=1.4,<2.0.0" +virtualenv = ">=14" [package.extras] tox_to_nox = ["jinja2", "tox"] @@ -822,19 +834,20 @@ tomlkit = ">=0.7.0,<0.8.0" [[package]] name = "numba" -version = "0.53.1" +version = "0.56.2" description = "compiling Python code using LLVM" category = "main" optional = false -python-versions = ">=3.6,<3.10" +python-versions = ">=3.7" [package.dependencies] -llvmlite = ">=0.36.0rc1,<0.37" -numpy = ">=1.15" +importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} +llvmlite = ">=0.39.0dev0,<0.40" +numpy = ">=1.18,<1.24" [[package]] name = "numpy" -version = "1.23.1" +version = "1.23.3" description = "NumPy is the fundamental package for array computing with Python." category = "main" optional = false @@ -853,18 +866,14 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pandas" -version = "1.4.3" +version = "1.5.0" description = "Powerful data structures for data analysis, time series, and statistics" category = "main" optional = false python-versions = ">=3.8" [package.dependencies] -numpy = [ - {version = ">=1.18.5", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, - {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, -] +numpy = {version = ">=1.20.3", markers = "python_version < \"3.10\""} python-dateutil = ">=2.8.1" pytz = ">=2020.1" @@ -873,26 +882,26 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] [[package]] name = "partd" -version = "1.2.0" +version = "1.3.0" description = "Appendable key-value storage" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" [package.dependencies] locket = "*" toolz = "*" [package.extras] -complete = ["numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq", "blosc"] +complete = ["blosc", "numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq"] [[package]] name = "pathspec" -version = "0.9.0" +version = "0.10.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" [[package]] name = "patsy" @@ -911,7 +920,7 @@ test = ["pytest", "pytest-cov", "scipy"] [[package]] name = "pbr" -version = "5.9.0" +version = "5.10.0" description = "Python Build Reasonableness" category = "main" optional = false @@ -949,8 +958,8 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] -test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] [[package]] name = "pluggy" @@ -1002,7 +1011,7 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} [[package]] name = "prompt-toolkit" -version = "3.0.30" +version = "3.0.31" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false @@ -1076,25 +1085,28 @@ integrations = ["cryptography"] [[package]] name = "pygments" -version = "2.12.0" +version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false python-versions = ">=3.6" +[package.extras] +plugins = ["importlib-metadata"] + [[package]] name = "pyjwt" -version = "2.4.0" +version = "2.5.0" description = "JSON Web Token implementation in Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -crypto = ["cryptography (>=3.3.1)"] -dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] +crypto = ["cryptography (>=3.3.1)", "types-cryptography (>=3.3.21)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "types-cryptography (>=3.3.21)", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pynacl" @@ -1109,7 +1121,7 @@ cffi = ">=1.4.1" [package.extras] docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] -tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] +tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] name = "pyparsing" @@ -1120,28 +1132,27 @@ optional = false python-versions = ">=3.6.8" [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.5" +version = "7.1.3" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "python-dateutil" @@ -1170,7 +1181,7 @@ unidecode = ["Unidecode (>=1.1.1)"] [[package]] name = "pytz" -version = "2022.1" +version = "2022.4" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -1196,7 +1207,7 @@ python-versions = ">=3.6,<4.0" prompt_toolkit = ">=2.0,<4.0" [package.extras] -docs = ["Sphinx (>=3.3,<4.0)", "sphinx-rtd-theme (>=0.5.0,<0.6.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphinx-copybutton (>=0.3.1,<0.4.0)", "sphinx-autodoc-typehints (>=1.11.1,<2.0.0)"] +docs = ["Sphinx (>=3.3,<4.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphinx-autodoc-typehints (>=1.11.1,<2.0.0)", "sphinx-copybutton (>=0.3.1,<0.4.0)", "sphinx-rtd-theme (>=0.5.0,<0.6.0)"] [[package]] name = "reorder-python-imports" @@ -1293,14 +1304,14 @@ requests = "*" [[package]] name = "scipy" -version = "1.8.1" +version = "1.9.1" description = "SciPy: Scientific Library for Python" category = "main" optional = false -python-versions = ">=3.8,<3.11" +python-versions = ">=3.8,<3.12" [package.dependencies] -numpy = ">=1.17.3,<1.25.0" +numpy = ">=1.18.5,<1.25.0" [[package]] name = "seaborn" @@ -1371,7 +1382,7 @@ numpy = "*" scipy = ">=0.19" [package.extras] -all = ["pytest (>=3.5)", "pytest-black", "pytest-cov", "tox", "sphinx", "sphinx-rtd-theme"] +all = ["pytest (>=3.5)", "pytest-black", "pytest-cov", "sphinx", "sphinx-rtd-theme", "tox"] docs = ["sphinx", "sphinx-rtd-theme"] tests = ["pytest (>=3.5)", "pytest-black", "pytest-cov"] tox = ["pytest (>=3.5)", "pytest-black", "pytest-cov", "tox"] @@ -1405,8 +1416,8 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"] -test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] [[package]] name = "sphinx-autobuild" @@ -1426,7 +1437,7 @@ test = ["pytest", "pytest-cov"] [[package]] name = "sphinx-autodoc-typehints" -version = "1.18.3" +version = "1.19.1" description = "Type hints (PEP 484) support for the Sphinx autodoc extension" category = "main" optional = false @@ -1476,7 +1487,7 @@ docutils = "<0.17" sphinx = "*" [package.extras] -dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] +dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] [[package]] name = "sphinxcontrib-applehelp" @@ -1487,7 +1498,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -1499,7 +1510,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -1511,8 +1522,8 @@ optional = false python-versions = ">=3.6" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest", "html5lib"] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] [[package]] name = "sphinxcontrib-jsmath" @@ -1523,7 +1534,7 @@ optional = false python-versions = ">=3.5" [package.extras] -test = ["pytest", "flake8", "mypy"] +test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-qthelp" @@ -1534,7 +1545,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -1546,7 +1557,7 @@ optional = false python-versions = ">=3.5" [package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] +lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] [[package]] @@ -1578,11 +1589,11 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.2.3" +version = "2.0.1" description = "A lil' TOML parser" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "tomlkit" @@ -1617,8 +1628,8 @@ optional = false python-versions = ">=3.5.3" [package.extras] -doc = ["sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["pytest", "typing-extensions", "mypy"] +doc = ["sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["mypy", "pytest", "typing-extensions"] [[package]] name = "types-attrs" @@ -1638,7 +1649,7 @@ python-versions = "*" [[package]] name = "types-requests" -version = "2.28.1" +version = "2.28.11.2" description = "Typing stubs for requests" category = "dev" optional = false @@ -1649,7 +1660,7 @@ types-urllib3 = "<1.27" [[package]] name = "types-urllib3" -version = "1.26.16" +version = "1.26.25" description = "Typing stubs for urllib3" category = "dev" optional = false @@ -1657,7 +1668,7 @@ python-versions = "*" [[package]] name = "typing-extensions" -version = "4.3.0" +version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -1665,34 +1676,33 @@ python-versions = ">=3.7" [[package]] name = "urllib3" -version = "1.26.10" +version = "1.26.12" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.15.1" +version = "20.16.5" description = "Virtual Python Environment builder" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" [package.dependencies] -distlib = ">=0.3.1,<1" -filelock = ">=3.2,<4" -platformdirs = ">=2,<3" -six = ">=1.9.0,<2" +distlib = ">=0.3.5,<1" +filelock = ">=3.4.1,<4" +platformdirs = ">=2.4,<3" [package.extras] -docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] -testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] +docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"] +testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] [[package]] name = "wcwidth" @@ -1724,11 +1734,11 @@ Pygments = {version = "*", optional = true, markers = "extra == \"colors\""} six = "*" [package.extras] -all = ["six", "codecov", "scikit-build", "cmake", "ninja", "pybind11", "pygments", "colorama", "pytest", "pytest", "pytest-cov", "pytest", "pytest", "pytest-cov", "typing", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel", "pytest", "pytest-cov"] -colors = ["pygments", "colorama"] -jupyter = ["nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] -optional = ["pygments", "colorama", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] -tests = ["codecov", "scikit-build", "cmake", "ninja", "pybind11", "pytest", "pytest", "pytest-cov", "pytest", "pytest", "pytest-cov", "typing", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel", "pytest", "pytest-cov"] +all = ["cmake", "codecov", "colorama", "ipykernel", "ipython", "jupyter-client", "nbconvert", "nbformat", "ninja", "pybind11", "pygments", "pytest", "pytest", "pytest", "pytest", "pytest", "pytest-cov", "pytest-cov", "pytest-cov", "scikit-build", "six", "typing"] +colors = ["colorama", "pygments"] +jupyter = ["ipykernel", "ipython", "jupyter-client", "nbconvert", "nbformat"] +optional = ["colorama", "ipykernel", "ipython", "jupyter-client", "nbconvert", "nbformat", "pygments"] +tests = ["cmake", "codecov", "ipykernel", "ipython", "jupyter-client", "nbconvert", "nbformat", "ninja", "pybind11", "pytest", "pytest", "pytest", "pytest", "pytest", "pytest-cov", "pytest-cov", "pytest-cov", "scikit-build", "typing"] [[package]] name = "xlrd" @@ -1747,13 +1757,13 @@ optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] +docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"] +testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.8.0, <3.10.0" -content-hash = "79989b3fc25ab2dc707b3296f21d131e2438a856695b509a33248643aeecb6dd" +content-hash = "f35e963cfa863727dec1c5410976077db2df3060ca603a083dc9ded652f447fc" [metadata.files] alabaster = [ @@ -1764,46 +1774,313 @@ anndata = [ {file = "anndata-0.7.8-py3-none-any.whl", hash = "sha256:cc098d46662230f91e421c707590337c3e16459c494f28d80b8ff5baae54e539"}, {file = "anndata-0.7.8.tar.gz", hash = "sha256:1efd7eb40839e0325bb066238280228a980d7dde6410793dbff2835f44a2d3ef"}, ] -appdirs = [] -argcomplete = [] -arrow = [] -"aspy.refactor-imports" = [] -atomicwrites = [] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +argcomplete = [ + {file = "argcomplete-2.0.0-py2.py3-none-any.whl", hash = "sha256:cffa11ea77999bb0dd27bb25ff6dc142a6796142f68d45b1a26b11f58724561e"}, + {file = "argcomplete-2.0.0.tar.gz", hash = "sha256:6372ad78c89d662035101418ae253668445b391755cfe94ea52f1b9d22425b20"}, +] +arrow = [ + {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, + {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, +] +"aspy.refactor-imports" = [ + {file = "aspy.refactor_imports-2.3.0-py2.py3-none-any.whl", hash = "sha256:a60432fc0c0b948aa371da520b896ddcbbee71b1820eeda6d2c04f039bac13b9"}, + {file = "aspy.refactor_imports-2.3.0.tar.gz", hash = "sha256:5a7775b31e55a762f807c218a3f9f1a7ff1313d766605a301f2ed937cdfa242a"}, +] attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] -babel = [] -bandit = [] -binaryornot = [] -black = [] -cached-property = [] -certifi = [] -cffi = [] + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, +] +babel = [ + {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, + {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, +] +bandit = [ + {file = "bandit-1.7.2-py3-none-any.whl", hash = "sha256:e20402cadfd126d85b68ed4c8862959663c8c372dbbb1fca8f8e2c9f55a067ec"}, + {file = "bandit-1.7.2.tar.gz", hash = "sha256:6d11adea0214a43813887bfe71a377b5a9955e4c826c8ffd341b494e3ab25260"}, +] +binaryornot = [ + {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, + {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, +] +black = [ + {file = "black-22.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7"}, + {file = "black-22.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66"}, + {file = "black-22.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b"}, + {file = "black-22.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d"}, + {file = "black-22.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650"}, + {file = "black-22.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d"}, + {file = "black-22.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87"}, + {file = "black-22.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395"}, + {file = "black-22.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383"}, + {file = "black-22.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de"}, + {file = "black-22.10.0-py3-none-any.whl", hash = "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458"}, + {file = "black-22.10.0.tar.gz", hash = "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1"}, +] +cached-property = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, +] +certifi = [ + {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, + {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, +] +cffi = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] cfgv = [ {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] -chardet = [] -charset-normalizer = [] +chardet = [ + {file = "chardet-5.0.0-py3-none-any.whl", hash = "sha256:d3e64f022d254183001eccc5db4040520c0f23b1a3f33d6413e099eb7f126557"}, + {file = "chardet-5.0.0.tar.gz", hash = "sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, + {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, +] click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] cloudpickle = [ - {file = "cloudpickle-2.1.0-py3-none-any.whl", hash = "sha256:b5c434f75c34624eedad3a14f2be5ac3b5384774d5b0e3caf905c21479e6c4b1"}, - {file = "cloudpickle-2.1.0.tar.gz", hash = "sha256:bb233e876a58491d9590a676f93c7a5473a08f747d5ab9df7f9ce564b3e7938e"}, + {file = "cloudpickle-2.2.0-py3-none-any.whl", hash = "sha256:7428798d5926d8fcbfd092d18d01a2a03daf8237d8fcdc8095d256b8490796f0"}, + {file = "cloudpickle-2.2.0.tar.gz", hash = "sha256:3f4219469c55453cfe4737e564b67c2a149109dabf7f242478948b895f61106f"}, +] +colorama = [ + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, +] +colorlog = [ + {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, + {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, ] -colorama = [] -colorlog = [] commonmark = [ {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, ] -cookiecutter = [] -cookietemple = [] -coverage = [] -cryptography = [] +contourpy = [ + {file = "contourpy-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:87121b9428ac568fb84fae4af5e7852fc34f02eadc4e3e91f6c8989327692186"}, + {file = "contourpy-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1fb782982c42cee667b892a0b0c52a9f6c7ecf1da5c5f4345845f04eaa862f93"}, + {file = "contourpy-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:689d7d2a840619915d0abd1ecc6e399fee202f8ad315acda2807f4ca420d0802"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d88814befbd1433152c5f6dd536905149ba028d795a22555b149ae0a36024d9e"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df65f4b2b4e74977f0336bef12a88051ab24e6a16873cd9249f34d67cb3e345d"}, + {file = "contourpy-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6b4c0c723664f65c2a47c8cb6ebbf660b0b2e2d936adf2e8503d4e93359465"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bcc98d397c3dea45d5b262029564b29cb8e945f2607a38bee6163694c0a8b4ef"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2bf5c846c257578b03d498b20f54f53551616a507d8e5463511c58bb58e9a9cf"}, + {file = "contourpy-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdacddb18d55ffec42d1907079cdc04ec4fa8a990cdf5b9d9fe67d281fc0d12e"}, + {file = "contourpy-1.0.5-cp310-cp310-win32.whl", hash = "sha256:434942fa2f9019b9ae525fb752dc523800c49a1a28fbd6d9240b0fa959573dcc"}, + {file = "contourpy-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:3b3082ade8849130203d461b98c2a061b382c46074b43b4edd5cefd81af92b8a"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:057114f698ffb9e54657e8fda6802e2f5c8fad609845cf6afaf31590ef6a33c0"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:218722a29c5c26677d37c44f5f8a372daf6f07870aad793a97d47eb6ad6b3290"}, + {file = "contourpy-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c02e22cf09996194bcb3a4784099975cf527d5c29caf759abadf29ebdb2fe27"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d5ee865b5fd16bf62d72122aadcc90aab296c30c1adb0a32b4b66bd843163e"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45822b0a2a452327ab4f95efe368d234d5294bbf89a99968be27c7938a21108"}, + {file = "contourpy-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dca5be83a6dfaf933a46e3bc2b9f2685e5ec61b22f6a38ad740aac9c16e9a0ff"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c3f2f6b898a40207843ae01970e57e33d22a26b22f23c6a5e07b4716751085f"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c2b4eab7c12f9cb460509bc34a3b086f9802f0dba27c89a63df4123819ad64af"}, + {file = "contourpy-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09ed9b63f4df8a7591b7a4a26c1ad066dcaafda1f846250fdcb534074a411692"}, + {file = "contourpy-1.0.5-cp311-cp311-win32.whl", hash = "sha256:f670686d99c867d0f24b28ce8c6f02429c6eef5e2674aab287850d0ee2d20437"}, + {file = "contourpy-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:c51568e94f7f232296de30002f2a50f77a7bd346673da3e4f2aaf9d2b833f2e5"}, + {file = "contourpy-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7c9e99aac7b430f6a9f15eebf058c742097cea3369f23a2bfc5e64d374b67e3a"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3210d93ad2af742b6a96cf39792f7181822edbb8fe11c3ef29d1583fe637a8d8"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128bd7acf569f8443ad5b2227f30ac909e4f5399ed221727eeacf0c6476187e6"}, + {file = "contourpy-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813c2944e940ef8dccea71305bacc942d4b193a021140874b3e58933ec44f5b6"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a74afd8d560eaafe0d9e3e1db8c06081282a05ca4de00ee416195085a79d7d3d"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d0ad9a85f208473b1f3613c45756c7aa6fcc288266a8c7b873f896aaf741b6b"}, + {file = "contourpy-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60f37acd4e4227c5a29f737d9a85ca3145c529a8dd4bf70af7f0637c61b49222"}, + {file = "contourpy-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:b50e481a4317a8efcfffcfddcd4c9b36eacba440440e70cbe0256aeb6fd6abae"}, + {file = "contourpy-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:0395ae71164bfeb2dedd136e03c71a2718a5aa9873a46f518f4133be0d63e1d2"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3ca40d7844b391d90b864c6a6d1bb6b88b09035fb4d866d64d43c4d26fb0ab64"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3109fa601d2a448cec4643abd3a31f972bf05b7c2f2e83df9d3429878f8c10ae"}, + {file = "contourpy-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:06c4d1dde5ee4f909a8a95ba1eb04040c6c26946b4f3b5beaf10d45f14e940ee"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f54dcc9bb9390fd0636301ead134d46d5229fe86da0db4d974c0fda349f560e"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46b8e24813e2fb5a3e598c1f8b9ae403e1438cb846a80cc2b33cddf19dddd7f2"}, + {file = "contourpy-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:061e1f066c419ffe25b615a1df031b4832ea1d7f2676937e69e8e00e24512005"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:19ea64fa0cf389d2ebc10974616acfa1fdecbd73d1fd9c72215b782f3c40f561"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dfe924e5a63861c82332a12adeeab955dc8c8009ddbbd80cc2fcca049ff89a49"}, + {file = "contourpy-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bed3a2a823a041e8d249b1a7ec132933e1505299329b5cfe1b2b5ec689ec7675"}, + {file = "contourpy-1.0.5-cp38-cp38-win32.whl", hash = "sha256:0389349875424aa8c5e61f757e894687916bc4e9616cc6afcbd8051aa2428952"}, + {file = "contourpy-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:2b5e334330d82866923015b455260173cb3b9e3b4e297052d758abd262031289"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:def9a01b73c9e27d70ea03b381fb3e7aadfac1f398dbd63751313c3a46747ef5"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:59c827e536bb5e3ef58e06da0faba61fd89a14f30b68bcfeca41f43ca83a1942"}, + {file = "contourpy-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f05d311c937da03b0cd26ac3e14cb991f6ff8fc94f98b3df9713537817539795"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:970a4be7ec84ccda7c27cb4ae74930bbbd477bc8d849ed55ea798084dd5fca8c"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f7672148f8fca48e4efc16aba24a7455b40c22d4f8abe42475dec6a12b0bb9a"}, + {file = "contourpy-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eba62b7c21a33e72dd8adab2b92dd5610d8527f0b2ac28a8e0770e71b21a13f9"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:dd084459ecdb224e617e4ab3f1d5ebe4d1c48facb41f24952b76aa6ba9712bb0"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c5158616ab39d34b76c50f40c81552ee180598f7825dc7a66fd187d29958820f"}, + {file = "contourpy-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f856652f9b533c6cd2b9ad6836a7fc0e43917d7ff15be46c5baf1350f8cdc5d9"}, + {file = "contourpy-1.0.5-cp39-cp39-win32.whl", hash = "sha256:f1cc623fd6855b25da52b3275e0c9e51711b86a9dccc75f8c9ab4432fd8e42c7"}, + {file = "contourpy-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:e67dcaa34dcd908fcccbf49194211d847c731b6ebaac661c1c889f1bf6af1e44"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfd634cb9685161b2a51f73a7fc4736fd0d67a56632d52319317afaa27f08243"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79908b9d02b1d6c1c71ff3b7ad127f3f82e14a8e091ab44b3c7e34b649fea733"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4963cf08f4320d98ae72ec7694291b8ab85cb7da3b0cd824bc32701bc992edf"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cfc067ddde78b76dcbc9684d82688b7d3c5158fa2254a085f9bcb9586c1e2d8"}, + {file = "contourpy-1.0.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9939796abcadb2810a63dfb26ff8ca4595fe7dd70a3ceae7f607a2639b714307"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d8150579bf30cdf896906baf256aa200cd50dbe6e565c17d6fd3d678e21ff5de"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed9c91bf4ce614efed5388c3f989a7cfe08728ab871d995a486ea74ff88993db"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b46a04588ceb7cf132568e0e564a854627ef87a1ed3bf536234540a79ced44b0"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b85553699862c09937a7a5ea14ee6229087971a7d51ae97d5f4b407f571a2c17"}, + {file = "contourpy-1.0.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:99a8071e351b50827ad976b92ed91845fb614ac67a3c41109b24f3d8bd3afada"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fb0458d74726937ead9e2effc91144aea5a58ecee9754242f8539a782bed685a"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f89f0608a5aa8142ed0e53957916623791a88c7f5e5f07ae530c328beeb888f"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce763369e646e59e4ca2c09735cd1bdd3048d909ad5f2bc116e83166a9352f3c"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c16fa267740d67883899e054cccb4279e002f3f4872873b752c1ba15045ff49"}, + {file = "contourpy-1.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a30e95274f5c0e007ccc759ec258aa5708c534ec058f153ee25ac700a2f1438b"}, + {file = "contourpy-1.0.5.tar.gz", hash = "sha256:896631cd40222aef3697e4e51177d14c3709fda49d30983269d584f034acc8a4"}, +] +cookiecutter = [ + {file = "cookiecutter-1.7.3-py2.py3-none-any.whl", hash = "sha256:f8671531fa96ab14339d0c59b4f662a4f12a2ecacd94a0f70a3500843da588e2"}, + {file = "cookiecutter-1.7.3.tar.gz", hash = "sha256:6b9a4d72882e243be077a7397d0f1f76fe66cf3df91f3115dbb5330e214fa457"}, +] +cookietemple = [ + {file = "cookietemple-1.4.1-py3-none-any.whl", hash = "sha256:7091b9698c9efff62ca84e97470dd1eeb3a91e535c4c0d95816cbaba48bb7931"}, + {file = "cookietemple-1.4.1.tar.gz", hash = "sha256:c6c0d2d129d56a4e5c0f42ef550de393f14be30e3f3bd4f877b1a0e73910547e"}, +] +coverage = [ + {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, + {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, + {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, + {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, + {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, + {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, + {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, + {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, + {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, + {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, + {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, + {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, + {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, + {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, + {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, + {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, + {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, + {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, + {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, + {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, + {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, + {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, + {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, + {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, + {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, + {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, + {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, + {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, + {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, + {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, + {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, + {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, + {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, + {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, + {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, + {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, + {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, + {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, + {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, + {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, + {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, + {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, + {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, + {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, + {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, + {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, + {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, + {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, + {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, +] +cryptography = [ + {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6"}, + {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d"}, + {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84"}, + {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815"}, + {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf"}, + {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf"}, + {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86"}, + {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2"}, + {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb"}, + {file = "cryptography-36.0.2-cp36-abi3-win32.whl", hash = "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6"}, + {file = "cryptography-36.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29"}, + {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7"}, + {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e"}, + {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0"}, + {file = "cryptography-36.0.2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b"}, + {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77"}, + {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85"}, + {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51"}, + {file = "cryptography-36.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3"}, + {file = "cryptography-36.0.2.tar.gz", hash = "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9"}, +] cycler = [ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, @@ -1812,27 +2089,41 @@ darglint = [ {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, ] -dask = [] +dask = [ + {file = "dask-2021.4.1-py3-none-any.whl", hash = "sha256:344c342d699466c3f742019b7a33caf2472b751f38370b200ede7d2f354aa1e4"}, + {file = "dask-2021.4.1.tar.gz", hash = "sha256:195e4eeb154222ea7a1c368119b5f321ee4ec9d78531471fe0145a527f744aa8"}, +] deprecated = [ {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, ] distlib = [ - {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, - {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, + {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, + {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, +] +docutils = [ + {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, + {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, ] -docutils = [] dparse = [ - {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, - {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, + {file = "dparse-0.6.2-py3-none-any.whl", hash = "sha256:8097076f1dd26c377f30d4745e6ec18fef42f3bf493933b842ac5bafad8c345f"}, + {file = "dparse-0.6.2.tar.gz", hash = "sha256:d45255bda21f998bc7ddf2afd5e62505ba6134756ba2d42a84c56b0826614dfe"}, ] filelock = [ - {file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"}, - {file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"}, + {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, + {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, +] +flake8 = [ + {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, + {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, +] +flake8-bandit = [ + {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"}, +] +flake8-bugbear = [ + {file = "flake8-bugbear-21.11.29.tar.gz", hash = "sha256:8b04cb2fafc6a78e1a9d873bd3988e4282f7959bb6b0d7c1ae648ec09b937a7b"}, + {file = "flake8_bugbear-21.11.29-py36.py37.py38-none-any.whl", hash = "sha256:179e41ddae5de5e3c20d1f61736feeb234e70958fbb56ab3c28a67739c8e9a82"}, ] -flake8 = [] -flake8-bandit = [] -flake8-bugbear = [] flake8-docstrings = [ {file = "flake8-docstrings-1.6.0.tar.gz", hash = "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b"}, {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"}, @@ -1842,21 +2133,24 @@ flake8-polyfill = [ {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, ] flake8-rst-docstrings = [ - {file = "flake8-rst-docstrings-0.2.6.tar.gz", hash = "sha256:7d9526a264a1c2827b3408ea5f921f12ee0689ac123fecfa95744988aea02e6c"}, - {file = "flake8_rst_docstrings-0.2.6-py3-none-any.whl", hash = "sha256:a7a9bd9008e763339b2e19dbece7767ac0887cfaeaf9a70b12eb4449d5df1849"}, + {file = "flake8-rst-docstrings-0.2.7.tar.gz", hash = "sha256:2740067ab9237559dd45a3434d8c987792c7b259ca563621a3b95efe201f5382"}, + {file = "flake8_rst_docstrings-0.2.7-py3-none-any.whl", hash = "sha256:5d56075dce360bcc9c6775bfe7cb431aa395de600ca7e8d40580a28d50b2a803"}, +] +fonttools = [ + {file = "fonttools-4.37.4-py3-none-any.whl", hash = "sha256:afae1b39555f9c3f0ad1f0f1daf678e5ad157e38c8842ecb567951bf1a9b9fd7"}, + {file = "fonttools-4.37.4.zip", hash = "sha256:86918c150c6412798e15a0de6c3e0d061ddefddd00f97b4f7b43dfa867ad315e"}, ] -fonttools = [] fsspec = [ - {file = "fsspec-2022.5.0-py3-none-any.whl", hash = "sha256:2c198c50eb541a80bbd03540b07602c4a957366f3fb416a1f270d34bd4ff0926"}, - {file = "fsspec-2022.5.0.tar.gz", hash = "sha256:7a5459c75c44e760fbe6a3ccb1f37e81e023cde7da8ba20401258d877ec483b4"}, + {file = "fsspec-2022.8.2-py3-none-any.whl", hash = "sha256:6374804a2c0d24f225a67d009ee1eabb4046ad00c793c3f6df97e426c890a1d9"}, + {file = "fsspec-2022.8.2.tar.gz", hash = "sha256:7f12b90964a98a7e921d27fb36be536ea036b73bf3b724ac0b0bd7b8e39c7c18"}, ] gitdb = [ {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, ] gitpython = [ - {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, - {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, + {file = "GitPython-3.1.28-py3-none-any.whl", hash = "sha256:77bfbd299d8709f6af7e0c70840ef26e7aff7cf0c1ed53b42dd7fc3a310fcb02"}, + {file = "GitPython-3.1.28.tar.gz", hash = "sha256:6bd3451b8271132f099ceeaf581392eaf6c274af74bb06144307870479d0697c"}, ] h5py = [ {file = "h5py-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d77af42cb751ad6cc44f11bae73075a07429a5cf2094dfde2b1e716e059b3911"}, @@ -1881,15 +2175,21 @@ h5py = [ {file = "h5py-3.7.0.tar.gz", hash = "sha256:3fcf37884383c5da64846ab510190720027dca0768def34dd8dcb659dbe5cbf3"}, ] identify = [ - {file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"}, - {file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"}, + {file = "identify-2.5.6-py2.py3-none-any.whl", hash = "sha256:b276db7ec52d7e89f5bc4653380e33054ddc803d25875952ad90b0f012cbcdaa"}, + {file = "identify-2.5.6.tar.gz", hash = "sha256:6c32dbd747aa4ceee1df33f25fed0b0f6e0d65721b15bd151307ff7056d50245"}, ] idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] +imagesize = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] +importlib-metadata = [ + {file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"}, + {file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"}, ] -imagesize = [] -importlib-metadata = [] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, @@ -1898,12 +2198,113 @@ jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] -jinja2-time = [] -kiwisolver = [] +jinja2-time = [ + {file = "jinja2-time-0.2.0.tar.gz", hash = "sha256:d14eaa4d315e7688daa4969f616f226614350c48730bfa1692d2caebd8c90d40"}, + {file = "jinja2_time-0.2.0-py2.py3-none-any.whl", hash = "sha256:d3eab6605e3ec8b7a0863df09cc1d23714908fa61aa6986a845c20ba488b4efa"}, +] +kiwisolver = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, ] -llvmlite = [] +llvmlite = [ + {file = "llvmlite-0.39.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6717c7a6e93c9d2c3d07c07113ec80ae24af45cde536b34363d4bcd9188091d9"}, + {file = "llvmlite-0.39.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ddab526c5a2c4ccb8c9ec4821fcea7606933dc53f510e2a6eebb45a418d3488a"}, + {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3f331a323d0f0ada6b10d60182ef06c20a2f01be21699999d204c5750ffd0b4"}, + {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c00ff204afa721b0bb9835b5bf1ba7fba210eefcec5552a9e05a63219ba0dc"}, + {file = "llvmlite-0.39.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16f56eb1eec3cda3a5c526bc3f63594fc24e0c8d219375afeb336f289764c6c7"}, + {file = "llvmlite-0.39.1-cp310-cp310-win32.whl", hash = "sha256:d0bfd18c324549c0fec2c5dc610fd024689de6f27c6cc67e4e24a07541d6e49b"}, + {file = "llvmlite-0.39.1-cp310-cp310-win_amd64.whl", hash = "sha256:7ebf1eb9badc2a397d4f6a6c8717447c81ac011db00064a00408bc83c923c0e4"}, + {file = "llvmlite-0.39.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6546bed4e02a1c3d53a22a0bced254b3b6894693318b16c16c8e43e29d6befb6"}, + {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1578f5000fdce513712e99543c50e93758a954297575610f48cb1fd71b27c08a"}, + {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3803f11ad5f6f6c3d2b545a303d68d9fabb1d50e06a8d6418e6fcd2d0df00959"}, + {file = "llvmlite-0.39.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50aea09a2b933dab7c9df92361b1844ad3145bfb8dd2deb9cd8b8917d59306fb"}, + {file = "llvmlite-0.39.1-cp37-cp37m-win32.whl", hash = "sha256:b1a0bbdb274fb683f993198775b957d29a6f07b45d184c571ef2a721ce4388cf"}, + {file = "llvmlite-0.39.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e172c73fccf7d6db4bd6f7de963dedded900d1a5c6778733241d878ba613980e"}, + {file = "llvmlite-0.39.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e31f4b799d530255aaf0566e3da2df5bfc35d3cd9d6d5a3dcc251663656c27b1"}, + {file = "llvmlite-0.39.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62c0ea22e0b9dffb020601bb65cb11dd967a095a488be73f07d8867f4e327ca5"}, + {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ffc84ade195abd4abcf0bd3b827b9140ae9ef90999429b9ea84d5df69c9058c"}, + {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0f158e4708dda6367d21cf15afc58de4ebce979c7a1aa2f6b977aae737e2a54"}, + {file = "llvmlite-0.39.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22d36591cd5d02038912321d9ab8e4668e53ae2211da5523f454e992b5e13c36"}, + {file = "llvmlite-0.39.1-cp38-cp38-win32.whl", hash = "sha256:4c6ebace910410daf0bebda09c1859504fc2f33d122e9a971c4c349c89cca630"}, + {file = "llvmlite-0.39.1-cp38-cp38-win_amd64.whl", hash = "sha256:fb62fc7016b592435d3e3a8f680e3ea8897c3c9e62e6e6cc58011e7a4801439e"}, + {file = "llvmlite-0.39.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa9b26939ae553bf30a9f5c4c754db0fb2d2677327f2511e674aa2f5df941789"}, + {file = "llvmlite-0.39.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e4f212c018db951da3e1dc25c2651abc688221934739721f2dad5ff1dd5f90e7"}, + {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39dc2160aed36e989610fc403487f11b8764b6650017ff367e45384dff88ffbf"}, + {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ec3d70b3e507515936e475d9811305f52d049281eaa6c8273448a61c9b5b7e2"}, + {file = "llvmlite-0.39.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60f8dd1e76f47b3dbdee4b38d9189f3e020d22a173c00f930b52131001d801f9"}, + {file = "llvmlite-0.39.1-cp39-cp39-win32.whl", hash = "sha256:03aee0ccd81735696474dc4f8b6be60774892a2929d6c05d093d17392c237f32"}, + {file = "llvmlite-0.39.1-cp39-cp39-win_amd64.whl", hash = "sha256:3fc14e757bc07a919221f0cbaacb512704ce5774d7fcada793f1996d6bc75f2a"}, + {file = "llvmlite-0.39.1.tar.gz", hash = "sha256:b43abd7c82e805261c425d50335be9a6c4f84264e34d6d6e475207300005d572"}, +] locket = [ {file = "locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3"}, {file = "locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632"}, @@ -1951,105 +2352,270 @@ markupsafe = [ {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] matplotlib = [ - {file = "matplotlib-3.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:03bbb3f5f78836855e127b5dab228d99551ad0642918ccbf3067fcd52ac7ac5e"}, - {file = "matplotlib-3.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49a5938ed6ef9dda560f26ea930a2baae11ea99e1c2080c8714341ecfda72a89"}, - {file = "matplotlib-3.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:77157be0fc4469cbfb901270c205e7d8adb3607af23cef8bd11419600647ceed"}, - {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5844cea45d804174bf0fac219b4ab50774e504bef477fc10f8f730ce2d623441"}, - {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c87973ddec10812bddc6c286b88fdd654a666080fbe846a1f7a3b4ba7b11ab78"}, - {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a05f2b37222319753a5d43c0a4fd97ed4ff15ab502113e3f2625c26728040cf"}, - {file = "matplotlib-3.5.2-cp310-cp310-win32.whl", hash = "sha256:9776e1a10636ee5f06ca8efe0122c6de57ffe7e8c843e0fb6e001e9d9256ec95"}, - {file = "matplotlib-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:b4fedaa5a9aa9ce14001541812849ed1713112651295fdddd640ea6620e6cf98"}, - {file = "matplotlib-3.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ee175a571e692fc8ae8e41ac353c0e07259113f4cb063b0ec769eff9717e84bb"}, - {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e8bda1088b941ead50caabd682601bece983cadb2283cafff56e8fcddbf7d7f"}, - {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9480842d5aadb6e754f0b8f4ebeb73065ac8be1855baa93cd082e46e770591e9"}, - {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6c623b355d605a81c661546af7f24414165a8a2022cddbe7380a31a4170fa2e9"}, - {file = "matplotlib-3.5.2-cp37-cp37m-win32.whl", hash = "sha256:a91426ae910819383d337ba0dc7971c7cefdaa38599868476d94389a329e599b"}, - {file = "matplotlib-3.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c4b82c2ae6d305fcbeb0eb9c93df2602ebd2f174f6e8c8a5d92f9445baa0c1d3"}, - {file = "matplotlib-3.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ebc27ad11df3c1661f4677a7762e57a8a91dd41b466c3605e90717c9a5f90c82"}, - {file = "matplotlib-3.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a32ea6e12e80dedaca2d4795d9ed40f97bfa56e6011e14f31502fdd528b9c89"}, - {file = "matplotlib-3.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a0967d4156adbd0d46db06bc1a877f0370bce28d10206a5071f9ecd6dc60b79"}, - {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2b696699386766ef171a259d72b203a3c75d99d03ec383b97fc2054f52e15cf"}, - {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7f409716119fa39b03da3d9602bd9b41142fab7a0568758cd136cd80b1bf36c8"}, - {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b8d3f4e71e26307e8c120b72c16671d70c5cd08ae412355c11254aa8254fb87f"}, - {file = "matplotlib-3.5.2-cp38-cp38-win32.whl", hash = "sha256:b6c63cd01cad0ea8704f1fd586e9dc5777ccedcd42f63cbbaa3eae8dd41172a1"}, - {file = "matplotlib-3.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:75c406c527a3aa07638689586343f4b344fcc7ab1f79c396699eb550cd2b91f7"}, - {file = "matplotlib-3.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4a44cdfdb9d1b2f18b1e7d315eb3843abb097869cd1ef89cfce6a488cd1b5182"}, - {file = "matplotlib-3.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d8e129af95b156b41cb3be0d9a7512cc6d73e2b2109f82108f566dbabdbf377"}, - {file = "matplotlib-3.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:364e6bca34edc10a96aa3b1d7cd76eb2eea19a4097198c1b19e89bee47ed5781"}, - {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea75df8e567743207e2b479ba3d8843537be1c146d4b1e3e395319a4e1a77fe9"}, - {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:44c6436868186564450df8fd2fc20ed9daaef5caad699aa04069e87099f9b5a8"}, - {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d7705022df2c42bb02937a2a824f4ec3cca915700dd80dc23916af47ff05f1a"}, - {file = "matplotlib-3.5.2-cp39-cp39-win32.whl", hash = "sha256:ee0b8e586ac07f83bb2950717e66cb305e2859baf6f00a9c39cc576e0ce9629c"}, - {file = "matplotlib-3.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:c772264631e5ae61f0bd41313bbe48e1b9bcc95b974033e1118c9caa1a84d5c6"}, - {file = "matplotlib-3.5.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:751d3815b555dcd6187ad35b21736dc12ce6925fc3fa363bbc6dc0f86f16484f"}, - {file = "matplotlib-3.5.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:31fbc2af27ebb820763f077ec7adc79b5a031c2f3f7af446bd7909674cd59460"}, - {file = "matplotlib-3.5.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fa28ca76ac5c2b2d54bc058b3dad8e22ee85d26d1ee1b116a6fd4d2277b6a04"}, - {file = "matplotlib-3.5.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:24173c23d1bcbaed5bf47b8785d27933a1ac26a5d772200a0f3e0e38f471b001"}, - {file = "matplotlib-3.5.2.tar.gz", hash = "sha256:48cf850ce14fa18067f2d9e0d646763681948487a8080ec0af2686468b4607a2"}, + {file = "matplotlib-3.6.0-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:6b98e098549d3aea2bfb93f38f0b2ecadcb423fa1504bbff902c01efdd833fd8"}, + {file = "matplotlib-3.6.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:798559837156b8e2e2df97cffca748c5c1432af6ec5004c2932e475d813f1743"}, + {file = "matplotlib-3.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e572c67958f7d55eae77f5f64dc7bd31968cc9f24c233926833efe63c60545f2"}, + {file = "matplotlib-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec2edf7f74829eae287aa53d64d83ad5d43ee51d29fb1d88e689d8b36028312"}, + {file = "matplotlib-3.6.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51092d13499be72e47c15c3a1ae0209edaca6be42b65ffbbefbe0c85f6153c6f"}, + {file = "matplotlib-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9295ca10a140c21e40d2ee43ef423213dc20767f6cea6b87c36973564bc51095"}, + {file = "matplotlib-3.6.0-cp310-cp310-win32.whl", hash = "sha256:1a4835c177821f3729be27ae9be7b8ae209fe75e83db7d9b2bfd319a998f0a42"}, + {file = "matplotlib-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:2b60d4abcb6a405ca7d909c80791b00637d22c62aa3bb0ffff7e589f763867f5"}, + {file = "matplotlib-3.6.0-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:66a0db13f77aa7806dba29273874cf862450c61c2e5158245d17ee85d983fe8e"}, + {file = "matplotlib-3.6.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:1739935d293d0348d7bf662e8cd0edb9c2aa8f20ccd646db755ce0f3456d24e4"}, + {file = "matplotlib-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1559213b803959a2b8309122585b5226d1c2fb66c933b1a2094cf1e99cb4fb90"}, + {file = "matplotlib-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5bd3b3ff191f81509d9a1afd62e1e3cda7a7889c35b5b6359a1241fe1511015"}, + {file = "matplotlib-3.6.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1954d71cdf15c19e7f3bf2235a4fe1600ba42f34d472c9495bcf54d75a43e4e"}, + {file = "matplotlib-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d840712f4b4c7d2a119f993d7e43ca9bcaa73aeaa24c322fa2bdf4f689a3ee09"}, + {file = "matplotlib-3.6.0-cp311-cp311-win32.whl", hash = "sha256:89e1978c3fbe4e3d4c6ad7db7e6f982607cb2546f982ccbe42708392437b1972"}, + {file = "matplotlib-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:9711ef291e184b5a73c9d3af3f2d5cfe25d571c8dd95aa498415f74ac7e221a8"}, + {file = "matplotlib-3.6.0-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:fbbceb0a0dfe9213f6314510665a32ef25fe29b50657567cd00115fbfcb3b20d"}, + {file = "matplotlib-3.6.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:62319d57dab5ad3e3494dd97a214e22079d3f72a0c8a2fd001829c2c6abbf8d1"}, + {file = "matplotlib-3.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:140316427a7c384e3dd37efb3a73cd67e14b0b237a6d277def91227f43cdcec2"}, + {file = "matplotlib-3.6.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ccea337fb9a44866c5300c594b13d4d87e827ebc3c353bff15d298bac976b654"}, + {file = "matplotlib-3.6.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:16a899b958dd76606b571bc7eaa38f09160c27dfb262e493584644cfd4a77f0f"}, + {file = "matplotlib-3.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd73a16a759865831be5a8fb6546f2a908c8d7d7f55c75f94ee7c2ca13cc95de"}, + {file = "matplotlib-3.6.0-cp38-cp38-win32.whl", hash = "sha256:2ed779a896b70c8012fe301fb91ee37e713e1dda1eb8f37de04cdbf506706983"}, + {file = "matplotlib-3.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:eca6f59cd0729edaeaa7032d582dffce518a420d4961ef3e8c93dce86be352c3"}, + {file = "matplotlib-3.6.0-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:408bbf968c15e9e38df9f25a588e372e28a43240cf5884c9bc6039a5021b7d5b"}, + {file = "matplotlib-3.6.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:7127e2b94571318531caf098dc9e8f60f5aba1704600f0b2483bf151d535674a"}, + {file = "matplotlib-3.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0d5b9b14ccc7f539143ac9eb1c6b57d26d69ca52d30c3d719a7bc4123579e44"}, + {file = "matplotlib-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa19508d8445f5648cd1ffe4fc6d4f7daf8b876f804e9a453df6c3708f6200b"}, + {file = "matplotlib-3.6.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ae1b9b555212c1e242666af80e7ed796705869581e2d749971db4e682ccc1f3"}, + {file = "matplotlib-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0958fc3fdc59c1b716ee1a5d14e73d03d541d873241a37c5c3a86f7ef6017923"}, + {file = "matplotlib-3.6.0-cp39-cp39-win32.whl", hash = "sha256:efe9e8037b989b14bb1887089ae763385431cc06fe488406413079cfd2a3a089"}, + {file = "matplotlib-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b0320f882214f6ffde5992081520b57b55450510bdaa020e96aacff9b7ae10e6"}, + {file = "matplotlib-3.6.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:11c1987b803cc2b26725659cfe817478f0a9597878e5c4bf374cfe4e12cbbd79"}, + {file = "matplotlib-3.6.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:802feae98addb9f21707649a7f229c90a59fad34511881f20b906a5e8e6ea475"}, + {file = "matplotlib-3.6.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd2e12f8964f8fb4ba1984df71d85d02ef0531e687e59f78ec8fc07271a3857"}, + {file = "matplotlib-3.6.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4eba6972b796d97c8fcc5266b6dc42ef27c2dce4421b846cded0f3af851b81c9"}, + {file = "matplotlib-3.6.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:df26a09d955b3ab9b6bc18658b9403ed839096c97d7abe8806194e228a485a3c"}, + {file = "matplotlib-3.6.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e01382c06ac3710155a0ca923047c5abe03c676d08f03e146c6a240d0a910713"}, + {file = "matplotlib-3.6.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4699bb671dbc4afdb544eb893e4deb8a34e294b7734733f65b4fd2787ba5fbc6"}, + {file = "matplotlib-3.6.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:657fb7712185f82211170ac4debae0800ed4f5992b8f7ebba2a9eabaf133a857"}, + {file = "matplotlib-3.6.0.tar.gz", hash = "sha256:c5108ebe67da60a9204497d8d403316228deb52b550388190c53a57394d41531"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] -mypy = [] +mypy = [ + {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"}, + {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"}, + {file = "mypy-0.971-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3"}, + {file = "mypy-0.971-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655"}, + {file = "mypy-0.971-cp310-cp310-win_amd64.whl", hash = "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103"}, + {file = "mypy-0.971-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca"}, + {file = "mypy-0.971-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417"}, + {file = "mypy-0.971-cp36-cp36m-win_amd64.whl", hash = "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09"}, + {file = "mypy-0.971-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8"}, + {file = "mypy-0.971-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0"}, + {file = "mypy-0.971-cp37-cp37m-win_amd64.whl", hash = "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2"}, + {file = "mypy-0.971-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27"}, + {file = "mypy-0.971-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856"}, + {file = "mypy-0.971-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71"}, + {file = "mypy-0.971-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27"}, + {file = "mypy-0.971-cp38-cp38-win_amd64.whl", hash = "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58"}, + {file = "mypy-0.971-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6"}, + {file = "mypy-0.971-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe"}, + {file = "mypy-0.971-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9"}, + {file = "mypy-0.971-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf"}, + {file = "mypy-0.971-cp39-cp39-win_amd64.whl", hash = "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0"}, + {file = "mypy-0.971-py3-none-any.whl", hash = "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9"}, + {file = "mypy-0.971.tar.gz", hash = "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] natsort = [ - {file = "natsort-8.1.0-py3-none-any.whl", hash = "sha256:f59988d2f24e77b6b56f8a8f882d5df6b3b637e09e075abc67b486d59fba1a4b"}, - {file = "natsort-8.1.0.tar.gz", hash = "sha256:c7c1f3f27c375719a4dfcab353909fe39f26c2032a062a8c80cc844eaaca0445"}, + {file = "natsort-8.2.0-py3-none-any.whl", hash = "sha256:04fe18fdd2b9e5957f19f687eb117f102ef8dde6b574764e536e91194bed4f5f"}, + {file = "natsort-8.2.0.tar.gz", hash = "sha256:57f85b72c688b09e053cdac302dd5b5b53df5f73ae20b4874fcbffd8bf783d11"}, +] +nodeenv = [ + {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, + {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, +] +nox = [ + {file = "nox-2022.8.7-py3-none-any.whl", hash = "sha256:96cca88779e08282a699d672258ec01eb7c792d35bbbf538c723172bce23212c"}, + {file = "nox-2022.8.7.tar.gz", hash = "sha256:1b894940551dc5c389f9271d197ca5d655d40bdc6ccf93ed6880e4042760a34b"}, +] +nox-poetry = [ + {file = "nox-poetry-0.9.0.tar.gz", hash = "sha256:ea48fa535cd048854da35af7c6c3e92046fbed9b9023bb81193fb4d2d3a47c92"}, + {file = "nox_poetry-0.9.0-py3-none-any.whl", hash = "sha256:33423c855fb47e2901faf9e15937326bc20c6e356eef825903eed4f8bbda69d3"}, ] -nodeenv = [] -nox = [] -nox-poetry = [] numba = [ - {file = "numba-0.53.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:b23de6b6837c132087d06b8b92d343edb54b885873b824a037967fbd5272ebb7"}, - {file = "numba-0.53.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:6545b9e9b0c112b81de7f88a3c787469a357eeff8211e90b8f45ee243d521cc2"}, - {file = "numba-0.53.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:8fa5c963a43855050a868106a87cd614f3c3f459951c8fc468aec263ef80d063"}, - {file = "numba-0.53.1-cp36-cp36m-win32.whl", hash = "sha256:aaa6ebf56afb0b6752607b9f3bf39e99b0efe3c1fa6849698373925ee6838fd7"}, - {file = "numba-0.53.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b08b3df38aab769df79ed948d70f0a54a3cdda49d58af65369235c204ec5d0f3"}, - {file = "numba-0.53.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:bf5c463b62d013e3f709cc8277adf2f4f4d8cc6757293e29c6db121b77e6b760"}, - {file = "numba-0.53.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:74df02e73155f669e60dcff07c4eef4a03dbf5b388594db74142ab40914fe4f5"}, - {file = "numba-0.53.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5165709bf62f28667e10b9afe6df0ce1037722adab92d620f59cb8bbb8104641"}, - {file = "numba-0.53.1-cp37-cp37m-win32.whl", hash = "sha256:2e96958ed2ca7e6d967b2ce29c8da0ca47117e1de28e7c30b2c8c57386506fa5"}, - {file = "numba-0.53.1-cp37-cp37m-win_amd64.whl", hash = "sha256:276f9d1674fe08d95872d81b97267c6b39dd830f05eb992608cbede50fcf48a9"}, - {file = "numba-0.53.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:4c4c8d102512ae472af52c76ad9522da718c392cb59f4cd6785d711fa5051a2a"}, - {file = "numba-0.53.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:691adbeac17dbdf6ed7c759e9e33a522351f07d2065fe926b264b6b2c15fd89b"}, - {file = "numba-0.53.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:94aab3e0e9e8754116325ce026e1b29ae72443c706a3104cf7f3368dc3012912"}, - {file = "numba-0.53.1-cp38-cp38-win32.whl", hash = "sha256:aabeec89bb3e3162136eea492cea7ee8882ddcda2201f05caecdece192c40896"}, - {file = "numba-0.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:1895ebd256819ff22256cd6fe24aa8f7470b18acc73e7917e8e93c9ac7f565dc"}, - {file = "numba-0.53.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:224d197a46a9e602a16780d87636e199e2cdef528caef084a4d8fd8909c2455c"}, - {file = "numba-0.53.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:aba7acb247a09d7f12bd17a8e28bbb04e8adef9fc20ca29835d03b7894e1b49f"}, - {file = "numba-0.53.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:bd126f1f49da6fc4b3169cf1d96f1c3b3f84a7badd11fe22da344b923a00e744"}, - {file = "numba-0.53.1-cp39-cp39-win32.whl", hash = "sha256:0ef9d1f347b251282ae46e5a5033600aa2d0dfa1ee8c16cb8137b8cd6f79e221"}, - {file = "numba-0.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:17146885cbe4e89c9d4abd4fcb8886dee06d4591943dc4343500c36ce2fcfa69"}, - {file = "numba-0.53.1.tar.gz", hash = "sha256:9cd4e5216acdc66c4e9dab2dfd22ddb5bef151185c070d4a3cd8e78638aff5b0"}, -] -numpy = [] + {file = "numba-0.56.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:e50d1de5291d1afd3d660ca149447c682d70b8d3c22f97ed9a3076e6344330b0"}, + {file = "numba-0.56.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c358fd4ef7c5efc09ee96432284d66df285bd68654e85c39cf6c570dc35429a"}, + {file = "numba-0.56.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6465f23beff2f6134f53da873d4202671cdbb02716a29f2b5f5c77102ece37c0"}, + {file = "numba-0.56.2-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2e4ac02b1bacea083e7cab5c02ded3bb5db7bb35d9c3a0a63da4f8c86691365a"}, + {file = "numba-0.56.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea7d286519eb575f66617805582391e6483e8b33968831331ecd46fe3c7f753f"}, + {file = "numba-0.56.2-cp310-cp310-win32.whl", hash = "sha256:590112ac60ff482f1d096e7574f9a781dff2f7bc91bfe388fe7d87e52630c0ec"}, + {file = "numba-0.56.2-cp310-cp310-win_amd64.whl", hash = "sha256:e998782d1e466ce5a61cce18f23fd69ba0eeb78069fd2ad59e1a2928a29f952f"}, + {file = "numba-0.56.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:c011436c8e0ec7e37fbb81953537ceb659e662f7c7f9850f2638a100e857bee4"}, + {file = "numba-0.56.2-cp37-cp37m-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d216a8957057afa43374eb9a11c69a874424d33e20f4270f80cef878c7efa500"}, + {file = "numba-0.56.2-cp37-cp37m-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2a1d81994bedc0e02f900ea4b81bdfd4929ee844f6ef9242e196c50f30f95449"}, + {file = "numba-0.56.2-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8a8e35d9b86d33c2f77e50fd8a610b984f57005e1cd1a2c8267d4cfd743d8f49"}, + {file = "numba-0.56.2-cp37-cp37m-win32.whl", hash = "sha256:bb3609bb76fd5b1d3adc9a7df40f27c3eb8c7e5d2c8a536c1bdc7b09c2fdc215"}, + {file = "numba-0.56.2-cp37-cp37m-win_amd64.whl", hash = "sha256:339e519f4091fab3a446b474e041c86eedd216334f8dd7febee4b43df112179c"}, + {file = "numba-0.56.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:63199334b9fedf3511369738fa8ef07411abc1cd9e8cd0e474cf671133b85180"}, + {file = "numba-0.56.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f112dcfcbcbb19da33e9218611c51208499d52d74e358f2160e64ccb46e50f07"}, + {file = "numba-0.56.2-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c4467aed831297473ec94f9f3d9795de551c447bf6ea17d7ac24b6a47fb687ea"}, + {file = "numba-0.56.2-cp38-cp38-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ae89056d1681c70b79bc9835c40672d4ba22cf4e75eacc0b8ff7f176c7233781"}, + {file = "numba-0.56.2-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:edbba200696c4be93a10020e4e0eab5ca0898dff4920f3dc2b4d39c14e40b993"}, + {file = "numba-0.56.2-cp38-cp38-win32.whl", hash = "sha256:45cefeefa78762753c2be9f64e7579a7523afff479642c3c661fb78bd740a352"}, + {file = "numba-0.56.2-cp38-cp38-win_amd64.whl", hash = "sha256:9eb56e7a23c4daa195cefba894671a45464533b0af9908483ba3de74a75fe682"}, + {file = "numba-0.56.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:faced8cc33ee6a272654bb3e570994e1949790ae06579ea485c25849f4e79008"}, + {file = "numba-0.56.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2713f161c51e0638dd4f92036999a523df5dcc498d39adb1559cf7cacb6f0fe9"}, + {file = "numba-0.56.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b885219eba813a4c70e68fce18339a3e575fb2b75e92d2babbcf04a40f74dee"}, + {file = "numba-0.56.2-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d87bdb704ef219c00844844a8ac9c6f1c518f2cee9c26d1971427b6bc3d2004d"}, + {file = "numba-0.56.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6184d0c125bdf2f19ad78e71e9ea873ad6c88c55f7609f987bd4354d15c54bb3"}, + {file = "numba-0.56.2-cp39-cp39-win32.whl", hash = "sha256:61d472e42ecad262857409a00f9f24d4609b190ba1fab5fc118e7a1ee43c9d39"}, + {file = "numba-0.56.2-cp39-cp39-win_amd64.whl", hash = "sha256:36903c24088aed9a768d7e8269f4ee4d3abc5662e2aeacacf524a7c5d1707b04"}, + {file = "numba-0.56.2.tar.gz", hash = "sha256:3492f0a5d09e257fc521f5377a6c6b907eec1920d14739f0b2458b9d29946a5a"}, +] +numpy = [ + {file = "numpy-1.23.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9f707b5bb73bf277d812ded9896f9512a43edff72712f31667d0a8c2f8e71ee"}, + {file = "numpy-1.23.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffcf105ecdd9396e05a8e58e81faaaf34d3f9875f137c7372450baa5d77c9a54"}, + {file = "numpy-1.23.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ea3f98a0ffce3f8f57675eb9119f3f4edb81888b6874bc1953f91e0b1d4f440"}, + {file = "numpy-1.23.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004f0efcb2fe1c0bd6ae1fcfc69cc8b6bf2407e0f18be308612007a0762b4089"}, + {file = "numpy-1.23.3-cp310-cp310-win32.whl", hash = "sha256:98dcbc02e39b1658dc4b4508442a560fe3ca5ca0d989f0df062534e5ca3a5c1a"}, + {file = "numpy-1.23.3-cp310-cp310-win_amd64.whl", hash = "sha256:39a664e3d26ea854211867d20ebcc8023257c1800ae89773cbba9f9e97bae036"}, + {file = "numpy-1.23.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1f27b5322ac4067e67c8f9378b41c746d8feac8bdd0e0ffede5324667b8a075c"}, + {file = "numpy-1.23.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ad3ec9a748a8943e6eb4358201f7e1c12ede35f510b1a2221b70af4bb64295c"}, + {file = "numpy-1.23.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdc9febce3e68b697d931941b263c59e0c74e8f18861f4064c1f712562903411"}, + {file = "numpy-1.23.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301c00cf5e60e08e04d842fc47df641d4a181e651c7135c50dc2762ffe293dbd"}, + {file = "numpy-1.23.3-cp311-cp311-win32.whl", hash = "sha256:7cd1328e5bdf0dee621912f5833648e2daca72e3839ec1d6695e91089625f0b4"}, + {file = "numpy-1.23.3-cp311-cp311-win_amd64.whl", hash = "sha256:8355fc10fd33a5a70981a5b8a0de51d10af3688d7a9e4a34fcc8fa0d7467bb7f"}, + {file = "numpy-1.23.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc6e8da415f359b578b00bcfb1d08411c96e9a97f9e6c7adada554a0812a6cc6"}, + {file = "numpy-1.23.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:22d43376ee0acd547f3149b9ec12eec2f0ca4a6ab2f61753c5b29bb3e795ac4d"}, + {file = "numpy-1.23.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a64403f634e5ffdcd85e0b12c08f04b3080d3e840aef118721021f9b48fc1460"}, + {file = "numpy-1.23.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd9d3abe5774404becdb0748178b48a218f1d8c44e0375475732211ea47c67e"}, + {file = "numpy-1.23.3-cp38-cp38-win32.whl", hash = "sha256:f8c02ec3c4c4fcb718fdf89a6c6f709b14949408e8cf2a2be5bfa9c49548fd85"}, + {file = "numpy-1.23.3-cp38-cp38-win_amd64.whl", hash = "sha256:e868b0389c5ccfc092031a861d4e158ea164d8b7fdbb10e3b5689b4fc6498df6"}, + {file = "numpy-1.23.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09f6b7bdffe57fc61d869a22f506049825d707b288039d30f26a0d0d8ea05164"}, + {file = "numpy-1.23.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c79d7cf86d049d0c5089231a5bcd31edb03555bd93d81a16870aa98c6cfb79d"}, + {file = "numpy-1.23.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d5420053bbb3dd64c30e58f9363d7a9c27444c3648e61460c1237f9ec3fa14"}, + {file = "numpy-1.23.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5422d6a1ea9b15577a9432e26608c73a78faf0b9039437b075cf322c92e98e7"}, + {file = "numpy-1.23.3-cp39-cp39-win32.whl", hash = "sha256:c1ba66c48b19cc9c2975c0d354f24058888cdc674bebadceb3cdc9ec403fb5d1"}, + {file = "numpy-1.23.3-cp39-cp39-win_amd64.whl", hash = "sha256:78a63d2df1d947bd9d1b11d35564c2f9e4b57898aae4626638056ec1a231c40c"}, + {file = "numpy-1.23.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:17c0e467ade9bda685d5ac7f5fa729d8d3e76b23195471adae2d6a6941bd2c18"}, + {file = "numpy-1.23.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91b8d6768a75247026e951dce3b2aac79dc7e78622fc148329135ba189813584"}, + {file = "numpy-1.23.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:94c15ca4e52671a59219146ff584488907b1f9b3fc232622b47e2cf832e94fb8"}, + {file = "numpy-1.23.3.tar.gz", hash = "sha256:51bf49c0cd1d52be0a240aa66f3458afc4b95d8993d2d04f0d91fa60c10af6cd"}, +] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] -pandas = [] +pandas = [ + {file = "pandas-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0d8d7433d19bfa33f11c92ad9997f15a902bda4f5ad3a4814a21d2e910894484"}, + {file = "pandas-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cc47f2ebaa20ef96ae72ee082f9e101b3dfbf74f0e62c7a12c0b075a683f03c"}, + {file = "pandas-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e8e5edf97d8793f51d258c07c629bd49d271d536ce15d66ac00ceda5c150eb3"}, + {file = "pandas-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41aec9f87455306496d4486df07c1b98c15569c714be2dd552a6124cd9fda88f"}, + {file = "pandas-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c76f1d104844c5360c21d2ef0e1a8b2ccf8b8ebb40788475e255b9462e32b2be"}, + {file = "pandas-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:1642fc6138b4e45d57a12c1b464a01a6d868c0148996af23f72dde8d12486bbc"}, + {file = "pandas-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:171cef540bfcec52257077816a4dbbac152acdb8236ba11d3196ae02bf0959d8"}, + {file = "pandas-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a68a9b9754efff364b0c5ee5b0f18e15ca640c01afe605d12ba8b239ca304d6b"}, + {file = "pandas-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:86d87279ebc5bc20848b4ceb619073490037323f80f515e0ec891c80abad958a"}, + {file = "pandas-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:207d63ac851e60ec57458814613ef4b3b6a5e9f0b33c57623ba2bf8126c311f8"}, + {file = "pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060"}, + {file = "pandas-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:de34636e2dc04e8ac2136a8d3c2051fd56ebe9fd6cd185581259330649e73ca9"}, + {file = "pandas-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1d34b1f43d9e3f4aea056ba251f6e9b143055ebe101ed04c847b41bb0bb4a989"}, + {file = "pandas-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b82ccc7b093e0a93f8dffd97a542646a3e026817140e2c01266aaef5fdde11b"}, + {file = "pandas-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e30a31039574d96f3d683df34ccb50bb435426ad65793e42a613786901f6761"}, + {file = "pandas-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62e61003411382e20d7c2aec1ee8d7c86c8b9cf46290993dd8a0a3be44daeb38"}, + {file = "pandas-1.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc987f7717e53d372f586323fff441263204128a1ead053c1b98d7288f836ac9"}, + {file = "pandas-1.5.0-cp38-cp38-win32.whl", hash = "sha256:e178ce2d7e3b934cf8d01dc2d48d04d67cb0abfaffdcc8aa6271fd5a436f39c8"}, + {file = "pandas-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:33a9d9e21ab2d91e2ab6e83598419ea6a664efd4c639606b299aae8097c1c94f"}, + {file = "pandas-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:73844e247a7b7dac2daa9df7339ecf1fcf1dfb8cbfd11e3ffe9819ae6c31c515"}, + {file = "pandas-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9c5049333c5bebf993033f4bf807d163e30e8fada06e1da7fa9db86e2392009"}, + {file = "pandas-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85a516a7f6723ca1528f03f7851fa8d0360d1d6121cf15128b290cf79b8a7f6a"}, + {file = "pandas-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:947ed9f896ee61adbe61829a7ae1ade493c5a28c66366ec1de85c0642009faac"}, + {file = "pandas-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7f38d91f21937fe2bec9449570d7bf36ad7136227ef43b321194ec249e2149d"}, + {file = "pandas-1.5.0-cp39-cp39-win32.whl", hash = "sha256:2504c032f221ef9e4a289f5e46a42b76f5e087ecb67d62e342ccbba95a32a488"}, + {file = "pandas-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a4fc04838615bf0a8d3a03ed68197f358054f0df61f390bcc64fbe39e3d71ec"}, + {file = "pandas-1.5.0.tar.gz", hash = "sha256:3ee61b881d2f64dd90c356eb4a4a4de75376586cd3c9341c6c0fcaae18d52977"}, +] partd = [ - {file = "partd-1.2.0-py3-none-any.whl", hash = "sha256:5c3a5d70da89485c27916328dc1e26232d0e270771bd4caef4a5124b6a457288"}, - {file = "partd-1.2.0.tar.gz", hash = "sha256:aa67897b84d522dcbc86a98b942afab8c6aa2f7f677d904a616b74ef5ddbc3eb"}, + {file = "partd-1.3.0-py3-none-any.whl", hash = "sha256:6393a0c898a0ad945728e34e52de0df3ae295c5aff2e2926ba7cc3c60a734a15"}, + {file = "partd-1.3.0.tar.gz", hash = "sha256:ce91abcdc6178d668bcaa431791a5a917d902341cb193f543fe445d494660485"}, ] pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, + {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, + {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, ] patsy = [ {file = "patsy-0.5.2-py2.py3-none-any.whl", hash = "sha256:cc80955ae8c13a7e7c4051eda7b277c8f909f50bc7d73e124bc38e2ee3d95041"}, {file = "patsy-0.5.2.tar.gz", hash = "sha256:5053de7804676aba62783dbb0f23a2b3d74e35e5bfa238b88b7cbf148a38b69d"}, ] pbr = [ - {file = "pbr-5.9.0-py2.py3-none-any.whl", hash = "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a"}, - {file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"}, + {file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"}, + {file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"}, +] +pep8-naming = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] +pillow = [ + {file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"}, + {file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544"}, + {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"}, + {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"}, + {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a"}, + {file = "Pillow-9.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1"}, + {file = "Pillow-9.2.0-cp311-cp311-win32.whl", hash = "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf"}, + {file = "Pillow-9.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c"}, + {file = "Pillow-9.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59"}, + {file = "Pillow-9.2.0-cp37-cp37m-win32.whl", hash = "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc"}, + {file = "Pillow-9.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1"}, + {file = "Pillow-9.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76"}, + {file = "Pillow-9.2.0-cp38-cp38-win32.whl", hash = "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f"}, + {file = "Pillow-9.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60"}, + {file = "Pillow-9.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4"}, + {file = "Pillow-9.2.0-cp39-cp39-win32.whl", hash = "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885"}, + {file = "Pillow-9.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927"}, + {file = "Pillow-9.2.0.tar.gz", hash = "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04"}, ] -pep8-naming = [] -pillow = [] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, @@ -2058,18 +2624,30 @@ pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] -poyo = [] -pre-commit = [] +poyo = [ + {file = "poyo-0.5.0-py2.py3-none-any.whl", hash = "sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a"}, + {file = "poyo-0.5.0.tar.gz", hash = "sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd"}, +] +pre-commit = [ + {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"}, + {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"}, +] pre-commit-hooks = [ {file = "pre_commit_hooks-4.3.0-py2.py3-none-any.whl", hash = "sha256:9ccaf7c98794659d345080ee1ea0256a55ae059675045eebdbbc17c0be8c7e4b"}, {file = "pre_commit_hooks-4.3.0.tar.gz", hash = "sha256:fda598a4c834d030727e6a615722718b47510f4bed72df4c949f95ba9f5aaf88"}, ] -prompt-toolkit = [] +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.31-py3-none-any.whl", hash = "sha256:9696f386133df0fc8ca5af4895afe5d78f5fcfe5258111c2a79a1c3e41ffa96d"}, + {file = "prompt_toolkit-3.0.31.tar.gz", hash = "sha256:9ada952c9d1787f52ff6d5f3484d0b4df8952787c087edf6a1f7c2cb1ea88148"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pycodestyle = [] +pycodestyle = [ + {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, + {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, +] pycparser = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, @@ -2078,42 +2656,111 @@ pydocstyle = [ {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, ] -pyflakes = [] -pygithub = [] +pyflakes = [ + {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, + {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, +] +pygithub = [ + {file = "PyGithub-1.55-py3-none-any.whl", hash = "sha256:2caf0054ea079b71e539741ae56c5a95e073b81fa472ce222e81667381b9601b"}, + {file = "PyGithub-1.55.tar.gz", hash = "sha256:1bbfff9372047ff3f21d5cd8e07720f3dbfdaf6462fcaed9d815f528f1ba7283"}, +] pygments = [ - {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, - {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, +] +pyjwt = [ + {file = "PyJWT-2.5.0-py3-none-any.whl", hash = "sha256:8d82e7087868e94dd8d7d418e5088ce64f7daab4b36db654cbaedb46f9d1ca80"}, + {file = "PyJWT-2.5.0.tar.gz", hash = "sha256:e77ab89480905d86998442ac5788f35333fa85f65047a534adc38edf3c88fc3b"}, +] +pynacl = [ + {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, + {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, ] -pyjwt = [] -pynacl = [] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] -pytest = [] +pytest = [ + {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, + {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, +] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] -python-slugify = [] +python-slugify = [ + {file = "python-slugify-6.1.2.tar.gz", hash = "sha256:272d106cb31ab99b3496ba085e3fea0e9e76dcde967b5e9992500d1f785ce4e1"}, + {file = "python_slugify-6.1.2-py2.py3-none-any.whl", hash = "sha256:7b2c274c308b62f4269a9ba701aa69a797e9bca41aeee5b3a9e79e36b6656927"}, +] pytz = [ - {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, - {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, + {file = "pytz-2022.4-py2.py3-none-any.whl", hash = "sha256:2c0784747071402c6e99f0bafdb7da0fa22645f06554c7ae06bf6358897e9c91"}, + {file = "pytz-2022.4.tar.gz", hash = "sha256:48ce799d83b6f8aab2020e369b627446696619e79645419610b9facd909b3174"}, +] +pyyaml = [ + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, +] +questionary = [ + {file = "questionary-1.10.0-py3-none-any.whl", hash = "sha256:fecfcc8cca110fda9d561cb83f1e97ecbb93c613ff857f655818839dac74ce90"}, + {file = "questionary-1.10.0.tar.gz", hash = "sha256:600d3aefecce26d48d97eee936fdb66e4bc27f934c3ab6dd1e292c4f43946d90"}, +] +reorder-python-imports = [ + {file = "reorder_python_imports-2.8.0-py2.py3-none-any.whl", hash = "sha256:03354608c610a25cba75a352ad86552849dcf3c90849fcb415298efc911a4ecf"}, + {file = "reorder_python_imports-2.8.0.tar.gz", hash = "sha256:435af2a6feb39de3c4b7a415079f85b4b0052d3a7ed9ea7b269b0aff725abdaf"}, +] +requests = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] -pyyaml = [] -questionary = [] -reorder-python-imports = [] -requests = [] restructuredtext-lint = [ {file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"}, ] -rich = [] +rich = [ + {file = "rich-10.16.2-py3-none-any.whl", hash = "sha256:c59d73bd804c90f747c8d7b1d023b88f2a9ac2454224a4aeaf959b21eeb42d03"}, + {file = "rich-10.16.2.tar.gz", hash = "sha256:720974689960e06c2efdb54327f8bf0cdbdf4eae4ad73b6c94213cad405c371b"}, +] "ruamel.yaml" = [ {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, ] "ruamel.yaml.clib" = [ {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, + {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:066f886bc90cc2ce44df8b5f7acfc6a7e2b2e672713f027136464492b0c34d7c"}, {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, @@ -2123,18 +2770,22 @@ rich = [] {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, + {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d3c620a54748a3d4cf0bcfe623e388407c8e85a4b06b8188e126302bcab93ea8"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, + {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:210c8fcfeff90514b7133010bf14e3bad652c8efde6b20e00c43854bf94fa5a6"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, + {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:61bc5e5ca632d95925907c569daa559ea194a4d16084ba86084be98ab1cec1c6"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, + {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1b4139a6ffbca8ef60fdaf9b33dec05143ba746a6f0ae0f9d11d38239211d335"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, @@ -2144,35 +2795,38 @@ safety = [ {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] scipy = [ - {file = "scipy-1.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:65b77f20202599c51eb2771d11a6b899b97989159b7975e9b5259594f1d35ef4"}, - {file = "scipy-1.8.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e013aed00ed776d790be4cb32826adb72799c61e318676172495383ba4570aa4"}, - {file = "scipy-1.8.1-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:02b567e722d62bddd4ac253dafb01ce7ed8742cf8031aea030a41414b86c1125"}, - {file = "scipy-1.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1da52b45ce1a24a4a22db6c157c38b39885a990a566748fc904ec9f03ed8c6ba"}, - {file = "scipy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0aa8220b89b2e3748a2836fbfa116194378910f1a6e78e4675a095bcd2c762d"}, - {file = "scipy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:4e53a55f6a4f22de01ffe1d2f016e30adedb67a699a310cdcac312806807ca81"}, - {file = "scipy-1.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28d2cab0c6ac5aa131cc5071a3a1d8e1366dad82288d9ec2ca44df78fb50e649"}, - {file = "scipy-1.8.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:6311e3ae9cc75f77c33076cb2794fb0606f14c8f1b1c9ff8ce6005ba2c283621"}, - {file = "scipy-1.8.1-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:3b69b90c9419884efeffaac2c38376d6ef566e6e730a231e15722b0ab58f0328"}, - {file = "scipy-1.8.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6cc6b33139eb63f30725d5f7fa175763dc2df6a8f38ddf8df971f7c345b652dc"}, - {file = "scipy-1.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c4e3ae8a716c8b3151e16c05edb1daf4cb4d866caa385e861556aff41300c14"}, - {file = "scipy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23b22fbeef3807966ea42d8163322366dd89da9bebdc075da7034cee3a1441ca"}, - {file = "scipy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:4b93ec6f4c3c4d041b26b5f179a6aab8f5045423117ae7a45ba9710301d7e462"}, - {file = "scipy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:70ebc84134cf0c504ce6a5f12d6db92cb2a8a53a49437a6bb4edca0bc101f11c"}, - {file = "scipy-1.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f3e7a8867f307e3359cc0ed2c63b61a1e33a19080f92fe377bc7d49f646f2ec1"}, - {file = "scipy-1.8.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:2ef0fbc8bcf102c1998c1f16f15befe7cffba90895d6e84861cd6c6a33fb54f6"}, - {file = "scipy-1.8.1-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:83606129247e7610b58d0e1e93d2c5133959e9cf93555d3c27e536892f1ba1f2"}, - {file = "scipy-1.8.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93d07494a8900d55492401917a119948ed330b8c3f1d700e0b904a578f10ead4"}, - {file = "scipy-1.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3b3c8924252caaffc54d4a99f1360aeec001e61267595561089f8b5900821bb"}, - {file = "scipy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70de2f11bf64ca9921fda018864c78af7147025e467ce9f4a11bc877266900a6"}, - {file = "scipy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:1166514aa3bbf04cb5941027c6e294a000bba0cf00f5cdac6c77f2dad479b434"}, - {file = "scipy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:9dd4012ac599a1e7eb63c114d1eee1bcfc6dc75a29b589ff0ad0bb3d9412034f"}, - {file = "scipy-1.8.1.tar.gz", hash = "sha256:9e3fb1b0e896f14a85aa9a28d5f755daaeeb54c897b746df7a55ccb02b340f33"}, + {file = "scipy-1.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c61b4a91a702e8e04aeb0bfc40460e1f17a640977c04dda8757efb0199c75332"}, + {file = "scipy-1.9.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d79da472015d0120ba9b357b28a99146cd6c17b9609403164b1a8ed149b4dfc8"}, + {file = "scipy-1.9.1-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:825951b88f56765aeb6e5e38ac9d7d47407cfaaeb008d40aa1b45a2d7ea2731e"}, + {file = "scipy-1.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f950a04b33e17b38ff561d5a0951caf3f5b47caa841edd772ffb7959f20a6af0"}, + {file = "scipy-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc81ac25659fec73599ccc52c989670e5ccd8974cf34bacd7b54a8d809aff1a"}, + {file = "scipy-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:8d3faa40ac16c6357aaf7ea50394ea6f1e8e99d75e927a51102b1943b311b4d9"}, + {file = "scipy-1.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a412c476a91b080e456229e413792bbb5d6202865dae963d1e6e28c2bb58691"}, + {file = "scipy-1.9.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:eb954f5aca4d26f468bbebcdc5448348eb287f7bea536c6306f62ea062f63d9a"}, + {file = "scipy-1.9.1-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:3c6f5d1d4b9a5e4fe5e14f26ffc9444fc59473bbf8d45dc4a9a15283b7063a72"}, + {file = "scipy-1.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bc4e2c77d4cd015d739e75e74ebbafed59ba8497a7ed0fd400231ed7683497c4"}, + {file = "scipy-1.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0419485dbcd0ed78c0d5bf234c5dd63e86065b39b4d669e45810d42199d49521"}, + {file = "scipy-1.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34441dfbee5b002f9e15285014fd56e5e3372493c3e64ae297bae2c4b9659f5a"}, + {file = "scipy-1.9.1-cp38-cp38-win32.whl", hash = "sha256:b97b479f39c7e4aaf807efd0424dec74bbb379108f7d22cf09323086afcd312c"}, + {file = "scipy-1.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8fe305d9d67a81255e06203454729405706907dccbdfcc330b7b3482a6c371d"}, + {file = "scipy-1.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:39ab9240cd215a9349c85ab908dda6d732f7d3b4b192fa05780812495536acc4"}, + {file = "scipy-1.9.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:71487c503e036740635f18324f62a11f283a632ace9d35933b2b0a04fd898c98"}, + {file = "scipy-1.9.1-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:3bc1ab68b9a096f368ba06c3a5e1d1d50957a86665fc929c4332d21355e7e8f4"}, + {file = "scipy-1.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f7c39f7dbb57cce00c108d06d731f3b0e2a4d3a95c66d96bce697684876ce4d4"}, + {file = "scipy-1.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47d1a95bd9d37302afcfe1b84c8011377c4f81e33649c5a5785db9ab827a6ade"}, + {file = "scipy-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d7cf7b25c9f23c59a766385f6370dab0659741699ecc7a451f9b94604938ce"}, + {file = "scipy-1.9.1-cp39-cp39-win32.whl", hash = "sha256:09412eb7fb60b8f00b328037fd814d25d261066ebc43a1e339cdce4f7502877e"}, + {file = "scipy-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:90c805f30c46cf60f1e76e947574f02954d25e3bb1e97aa8a07bc53aa31cf7d1"}, + {file = "scipy-1.9.1.tar.gz", hash = "sha256:26d28c468900e6d5fdb37d2812ab46db0ccd22c63baa095057871faa3a498bc9"}, ] seaborn = [ {file = "seaborn-0.11.2-py3-none-any.whl", hash = "sha256:85a6baa9b55f81a0623abddc4a26b334653ff4c6b18c418361de19dbba0ef283"}, {file = "seaborn-0.11.2.tar.gz", hash = "sha256:cf45e9286d40826864be0e3c066f98536982baf701a7caa386511792d61ff4f6"}, ] -setuptools-scm = [] +setuptools-scm = [ + {file = "setuptools_scm-7.0.5-py3-none-any.whl", hash = "sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02"}, + {file = "setuptools_scm-7.0.5.tar.gz", hash = "sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -2185,7 +2839,10 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -sparse = [] +sparse = [ + {file = "sparse-0.9.1-py2.py3-none-any.whl", hash = "sha256:5d7e9bab68b20f63ba6e8c593e46864ebef3a0842fa26fb32b71e743e6c5c99e"}, + {file = "sparse-0.9.1.tar.gz", hash = "sha256:6df8ef44f11c2d11891f3ea291211b169d34148e362e9152f7d9cee443e5ee11"}, +] sphinx = [ {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, @@ -2194,13 +2851,22 @@ sphinx-autobuild = [ {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, ] -sphinx-autodoc-typehints = [] -sphinx-click = [] +sphinx-autodoc-typehints = [ + {file = "sphinx_autodoc_typehints-1.19.1-py3-none-any.whl", hash = "sha256:9be46aeeb1b315eb5df1f3a7cb262149895d16c7d7dcd77b92513c3c3a1e85e6"}, + {file = "sphinx_autodoc_typehints-1.19.1.tar.gz", hash = "sha256:6c841db55e0e9be0483ff3962a2152b60e79306f4288d8c4e7e86ac84486a5ea"}, +] +sphinx-click = [ + {file = "sphinx-click-3.1.0.tar.gz", hash = "sha256:36dbf271b1d2600fb05bd598ddeed0b6b6acf35beaf8bc9d507ba7716b232b0e"}, + {file = "sphinx_click-3.1.0-py3-none-any.whl", hash = "sha256:8fb0b048a577d346d741782e44d041d7e908922858273d99746f305870116121"}, +] sphinx-rtd-dark-mode = [ {file = "sphinx_rtd_dark_mode-1.2.4-py3-none-any.whl", hash = "sha256:1d97c1e4f7902fb77ae86adcf72926c3b0e48a300f93eeba49266da5aeed8a29"}, {file = "sphinx_rtd_dark_mode-1.2.4.tar.gz", hash = "sha256:935bc1f3e62fc76eadd7d2760ac7f48bab907a97e44beda749a48a2706aeed63"}, ] -sphinx-rtd-theme = [] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-0.5.2-py2.py3-none-any.whl", hash = "sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f"}, + {file = "sphinx_rtd_theme-0.5.2.tar.gz", hash = "sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a"}, +] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, @@ -2225,16 +2891,43 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] -stevedore = [] -text-unidecode = [] +stevedore = [ + {file = "stevedore-4.0.0-py3-none-any.whl", hash = "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8"}, + {file = "stevedore-4.0.0.tar.gz", hash = "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786"}, +] +text-unidecode = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [] -tomlkit = [] -toolz = [] -tornado = [] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +tomlkit = [ + {file = "tomlkit-0.7.2-py2.py3-none-any.whl", hash = "sha256:173ad840fa5d2aac140528ca1933c29791b79a374a0861a80347f42ec9328117"}, + {file = "tomlkit-0.7.2.tar.gz", hash = "sha256:d7a454f319a7e9bd2e249f239168729327e4dd2d27b17dc68be264ad1ce36754"}, +] +toolz = [ + {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, + {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, +] +tornado = [ + {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, + {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, + {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, + {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, + {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, +] typeguard = [ {file = "typeguard-2.13.3-py3-none-any.whl", hash = "sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1"}, {file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"}, @@ -2246,11 +2939,26 @@ types-pkg-resources = [ {file = "types-pkg_resources-0.1.3.tar.gz", hash = "sha256:834a9b8d3dbea343562fd99d5d3359a726f6bf9d3733bccd2b4f3096fbab9dae"}, {file = "types_pkg_resources-0.1.3-py2.py3-none-any.whl", hash = "sha256:0cb9972cee992249f93fff1a491bf2dc3ce674e5a1926e27d4f0866f7d9b6d9c"}, ] -types-requests = [] -types-urllib3 = [] -typing-extensions = [] -urllib3 = [] -virtualenv = [] +types-requests = [ + {file = "types-requests-2.28.11.2.tar.gz", hash = "sha256:fdcd7bd148139fb8eef72cf4a41ac7273872cad9e6ada14b11ff5dfdeee60ed3"}, + {file = "types_requests-2.28.11.2-py3-none-any.whl", hash = "sha256:14941f8023a80b16441b3b46caffcbfce5265fd14555844d6029697824b5a2ef"}, +] +types-urllib3 = [ + {file = "types-urllib3-1.26.25.tar.gz", hash = "sha256:5aef0e663724eef924afa8b320b62ffef2c1736c1fa6caecfc9bc6c8ae2c3def"}, + {file = "types_urllib3-1.26.25-py3-none-any.whl", hash = "sha256:c1d78cef7bd581e162e46c20a57b2e1aa6ebecdcf01fd0713bb90978ff3e3427"}, +] +typing-extensions = [ + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, +] +urllib3 = [ + {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, + {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, +] +virtualenv = [ + {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"}, + {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"}, +] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, @@ -2321,9 +3029,15 @@ wrapt = [ {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] -xdoctest = [] +xdoctest = [ + {file = "xdoctest-0.15.10-py3-none-any.whl", hash = "sha256:7666bd0511df59275dfe94ef94b0fde9654afd14f00bf88902fdc9bcee77d527"}, + {file = "xdoctest-0.15.10.tar.gz", hash = "sha256:5f16438f2b203860e75ec594dbc38020df7524db0b41bb88467ea0a6030e6685"}, +] xlrd = [ {file = "xlrd-1.2.0-py2.py3-none-any.whl", hash = "sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"}, {file = "xlrd-1.2.0.tar.gz", hash = "sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2"}, ] -zipp = [] +zipp = [ + {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, + {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, +] diff --git a/pyproject.toml b/pyproject.toml index 0c625d62..9bb02ab5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ seaborn = "^0.11.2" bandit = "1.7.2" [tool.poetry.dev-dependencies] -pytest = "^6.2.3" +pytest = "^7.1.3" coverage = {extras = ["toml"], version = "^5.3"} safety = "^1.9.0" typeguard = "^2.12.0" @@ -63,7 +63,7 @@ types-requests = "^2.25.2" types-attrs = "^19.1.0" sphinx-rtd-dark-mode = "^1.2.3" Jinja2 = "^3.0.1" -mypy = "^0.910" +mypy = "^0.971" matplotlib = "^3.5.1" nox = "^2022.1.7" cookietemple = "^1.3.11" diff --git a/tests/numpy/test_accuracy.py b/tests/numpy/test_accuracy.py index 6a6c860d..95506640 100644 --- a/tests/numpy/test_accuracy.py +++ b/tests/numpy/test_accuracy.py @@ -1,6 +1,8 @@ import logging import unittest +from typing import Union +import dask.array import numpy as np from utils import get_estimator, get_generated_model @@ -29,7 +31,12 @@ def eval_estimation(self, estimator: EstimatorGlm): std_thres_location = 1 std_thres_scale = 1 - def deviation_theta(true: np.ndarray, pred: np.ndarray, mean_thres: float, std_thres: float) -> bool: + def deviation_theta( + true: Union[np.ndarray, dask.array.core.Array], + pred: Union[np.ndarray, dask.array.core.Array], + mean_thres: float, + std_thres: float, + ) -> bool: relative_deviation = (pred - true) / true mean = np.mean(relative_deviation) std = np.std(relative_deviation)