diff --git a/pgscatalog_utils/aggregate/aggregate_scores.py b/pgscatalog_utils/aggregate/aggregate_scores.py index d57943d..d30a783 100644 --- a/pgscatalog_utils/aggregate/aggregate_scores.py +++ b/pgscatalog_utils/aggregate/aggregate_scores.py @@ -1,5 +1,6 @@ import argparse import logging +import pathlib import textwrap import pandas as pd @@ -16,14 +17,14 @@ def aggregate_scores(): if args.split: logger.debug("Splitting aggregated scores by sampleset") - for sampleset, group in df.groupby('sampleset'): - fout = f"{sampleset}_pgs.txt.gz" + for sampleset, group in df.groupby("sampleset"): + fout = pathlib.Path(args.outdir) / f"{sampleset}_pgs.txt.gz" logger.debug(f"Compressing sampleset {sampleset}, writing to {fout}") - group.to_csv(fout, sep='\t', compression='gzip') + group.to_csv(fout, sep="\t", compression="gzip") else: - fout = "aggregated_scores.txt.gz" + fout = pathlib.Path(args.outdir) / "aggregated_scores.txt.gz" logger.info(f"Compressing all samplesets and writing combined scores to {fout}") - df.to_csv(fout, sep='\t', compression='gzip') + df.to_csv(fout, sep="\t", compression="gzip") def aggregate(scorefiles: list[str]): @@ -33,11 +34,13 @@ def aggregate(scorefiles: list[str]): for i, path in enumerate(scorefiles): logger.debug(f"Reading {path}") # pandas can automatically detect zst compression, neat! - df = (pd.read_table(path, converters={"#IID": str}, header=0) - .assign(sampleset=path.split('_')[0]) - .set_index(['sampleset', '#IID'])) + df = ( + pd.read_table(path, converters={"#IID": str}, header=0) + .assign(sampleset=path.split("_")[0]) + .set_index(["sampleset", "#IID"]) + ) - df.index.names = ['sampleset', 'IID'] + df.index.names = ["sampleset", "IID"] # Subset to aggregatable columns df = df[_select_agg_cols(df.columns)] @@ -45,31 +48,57 @@ def aggregate(scorefiles: list[str]): # Combine DFs if i == 0: - logger.debug('Initialising combined DF') + logger.debug("Initialising combined DF") combined = df.copy() else: - logger.debug('Adding to combined DF') + logger.debug("Adding to combined DF") combined = combined.add(df, fill_value=0) - assert all([x in combined.columns for x in aggcols]), "All Aggregatable Columns are present in the final DF" + assert all( + [x in combined.columns for x in aggcols] + ), "All Aggregatable Columns are present in the final DF" - return combined.pipe(_calculate_average) + sum_df, avg_df = combined.pipe(_calculate_average) + # need to melt sum and avg separately to give correct value_Name to melt + dfs = [_melt(x, y) for x, y in zip([sum_df, avg_df], ["SUM", "AVG"])] + # add melted average back + combined = pd.concat([dfs[0], dfs[1]["AVG"]], axis=1) + return combined[["PGS", "SUM", "DENOM", "AVG"]] + + +def _melt(df, value_name): + df = df.melt( + id_vars=["DENOM"], + value_name=value_name, + var_name="PGS", + ignore_index=False, + ) + df["PGS"] = df["PGS"].str.replace(f"_{value_name}", "") + return df def _calculate_average(combined: pd.DataFrame): logger.debug("Averaging data") - avgs = combined.loc[:, combined.columns.str.endswith('_SUM')].divide(combined['DENOM'], axis=0) - avgs.columns = avgs.columns.str.replace('_SUM', '_AVG') - return pd.concat([combined, avgs], axis=1) + avgs = combined.loc[:, combined.columns.str.endswith("_SUM")].divide( + combined["DENOM"], axis=0 + ) + avgs.columns = avgs.columns.str.replace("_SUM", "_AVG") + avgs["DENOM"] = combined["DENOM"] + return combined, avgs def _select_agg_cols(cols): - keep_cols = ['DENOM'] - return [x for x in cols if (x.endswith('_SUM') and (x != 'NAMED_ALLELE_DOSAGE_SUM')) or (x in keep_cols)] + keep_cols = ["DENOM"] + return [ + x + for x in cols + if (x.endswith("_SUM") and (x != "NAMED_ALLELE_DOSAGE_SUM")) or (x in keep_cols) + ] def _description_text() -> str: - return textwrap.dedent(''' + return textwrap.dedent( + """ Aggregate plink .sscore files into a combined TSV table. This aggregation sums scores that were calculated from plink @@ -80,20 +109,45 @@ def _description_text() -> str: Input .sscore files can be optionally compressed with zstd or gzip. The aggregated output scores are compressed with gzip. - ''') + """ + ) def _parse_args(args=None) -> argparse.Namespace: - parser = argparse.ArgumentParser(description=_description_text(), - formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('-s', '--scores', dest='scores', required=True, nargs='+', - help=' List of scorefile paths. Use a wildcard (*) to select multiple files.') - parser.add_argument('-o', '--outdir', dest='outdir', required=True, - default='scores/', help=' Output directory to store downloaded files') - parser.add_argument('--split', dest='split', required=False, action=argparse.BooleanOptionalAction, - help=' Make one aggregated file per sampleset') - parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', - help=' Extra logging information') + parser = argparse.ArgumentParser( + description=_description_text(), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "-s", + "--scores", + dest="scores", + required=True, + nargs="+", + help=" List of scorefile paths. Use a wildcard (*) to select multiple files.", + ) + parser.add_argument( + "-o", + "--outdir", + dest="outdir", + required=True, + default="scores/", + help=" Output directory to store downloaded files", + ) + parser.add_argument( + "--split", + dest="split", + required=False, + action=argparse.BooleanOptionalAction, + help=" Make one aggregated file per sampleset", + ) + parser.add_argument( + "-v", + "--verbose", + dest="verbose", + action="store_true", + help=" Extra logging information", + ) return parser.parse_args(args) diff --git a/pgscatalog_utils/ancestry/ancestry_analysis.py b/pgscatalog_utils/ancestry/ancestry_analysis.py index 2371c91..a7dbd8e 100644 --- a/pgscatalog_utils/ancestry/ancestry_analysis.py +++ b/pgscatalog_utils/ancestry/ancestry_analysis.py @@ -8,8 +8,14 @@ import pgscatalog_utils.config as config from pgscatalog_utils.ancestry.read import read_pcs, read_pgs, extract_ref_psam_cols -from pgscatalog_utils.ancestry.tools import compare_ancestry, comparison_method_threshold, choose_pval_threshold, \ - pgs_adjust, normalization_methods, write_model +from pgscatalog_utils.ancestry.tools import ( + compare_ancestry, + comparison_method_threshold, + choose_pval_threshold, + pgs_adjust, + normalization_methods, + write_model, +) logger = logging.getLogger(__name__) @@ -20,53 +26,76 @@ def ancestry_analysis(): config.OUTDIR = args.outdir # Load PCA data - maxPCs = max([10, args.nPCs_popcomp, args.nPCs_normalization]) # save memory by not using all PCs + maxPCs = max( + [10, args.nPCs_popcomp, args.nPCs_normalization] + ) # save memory by not using all PCs loc_ref_pcs = args.ref_pcs - reference_df = read_pcs(loc_pcs=loc_ref_pcs, dataset=args.d_ref, - loc_related_ids=args.ref_related, nPCs=maxPCs) + reference_df = read_pcs( + loc_pcs=loc_ref_pcs, + dataset=args.d_ref, + loc_related_ids=args.ref_related, + nPCs=maxPCs, + ) loc_ref_psam = args.psam - reference_df = extract_ref_psam_cols(loc_ref_psam, args.d_ref, reference_df, keepcols=[args.ref_label]) - assert reference_df.shape[0] > 100, "Error: too few reference panel samples. This is an arbitrary threshold " \ - "for input QC; however, it is inadvisable to run this analysis with limited " \ - "reference panel diversity as empirical percentiles are calculated." + reference_df = extract_ref_psam_cols( + loc_ref_psam, args.d_ref, reference_df, keepcols=[args.ref_label] + ) + assert reference_df.shape[0] > 100, ( + "Error: too few reference panel samples. This is an arbitrary threshold " + "for input QC; however, it is inadvisable to run this analysis with limited " + "reference panel diversity as empirical percentiles are calculated." + ) loc_target_sscores = args.target_pcs target_df = read_pcs(loc_pcs=loc_target_sscores, dataset=args.d_target, nPCs=maxPCs) assert target_df.shape[0] >= 1, "Error: NO target samples found in PCs file." # Load PGS data & merge with PCA data - pgs = read_pgs(args.scorefile, onlySUM=True) + pgs = read_pgs(args.scorefile) scorecols = list(pgs.columns) ## There should be perfect target sample overlap - assert all([x in pgs.loc['reference'].index for x in reference_df.index.get_level_values(1)]), \ - "Error: PGS data missing for reference samples with PCA data." + assert all( + [ + x in pgs.loc["reference"].index + for x in reference_df.index.get_level_values(1) + ] + ), "Error: PGS data missing for reference samples with PCA data." reference_df = pd.merge(reference_df, pgs, left_index=True, right_index=True) - assert all([x in pgs.loc[args.d_target].index for x in target_df.index.get_level_values(1)]), \ - "Error: PGS data missing for reference samples with PCA data." + assert all( + [x in pgs.loc[args.d_target].index for x in target_df.index.get_level_values(1)] + ), "Error: PGS data missing for reference samples with PCA data." target_df = pd.merge(target_df, pgs, left_index=True, right_index=True) del pgs # clear raw PGS from memory # Compare target sample ancestry/PCs to reference panel assignment_threshold_p = choose_pval_threshold(args) - ancestry_ref, ancestry_target, compare_info = compare_ancestry(ref_df=reference_df, - ref_pop_col=args.ref_label, ref_train_col='Unrelated', - target_df=target_df, - n_pcs=args.nPCs_popcomp, - method=args.method_compare, - p_threshold=assignment_threshold_p) + ancestry_ref, ancestry_target, compare_info = compare_ancestry( + ref_df=reference_df, + ref_pop_col=args.ref_label, + ref_train_col="Unrelated", + target_df=target_df, + n_pcs=args.nPCs_popcomp, + method=args.method_compare, + p_threshold=assignment_threshold_p, + ) reference_df = pd.concat([reference_df, ancestry_ref], axis=1) target_df = pd.concat([target_df, ancestry_target], axis=1) del ancestry_ref, ancestry_target # Adjust PGS values - adjpgs_ref, adjpgs_target, adjpgs_models = pgs_adjust(reference_df, target_df, scorecols, - args.ref_label, 'MostSimilarPop', - use_method=args.method_normalization, - ref_train_col='Unrelated', - n_pcs=args.nPCs_normalization) + adjpgs_ref, adjpgs_target, adjpgs_models = pgs_adjust( + reference_df, + target_df, + scorecols, + args.ref_label, + "MostSimilarPop", + use_method=args.method_normalization, + ref_train_col="Unrelated", + n_pcs=args.nPCs_normalization, + ) adjpgs = pd.concat([adjpgs_ref, adjpgs_target], axis=0) del adjpgs_ref, adjpgs_target @@ -74,86 +103,176 @@ def ancestry_analysis(): dout = os.path.abspath(config.OUTDIR) if os.path.isdir(dout) is False: os.mkdir(dout) - reference_df['REFERENCE'] = True - target_df['REFERENCE'] = False + reference_df["REFERENCE"] = True + target_df["REFERENCE"] = False final_df = pd.concat([target_df, reference_df], axis=0) del reference_df, target_df # Write Models - write_model({'pgs': adjpgs_models, 'compare_pcs': compare_info}, os.path.join(dout, f"{args.d_target}_info.json.gz")) + write_model( + {"pgs": adjpgs_models, "compare_pcs": compare_info}, + os.path.join(dout, f"{args.d_target}_info.json.gz"), + ) # Melt & write PGS # Currently each PGS will have it's own row... but it might be more optimal for each normalization method # to be on separate rows? My logic is that you might want to check correaltion between methods and it is easiest # in this format. loc_pgs_out = os.path.join(dout, f"{args.d_target}_pgs.txt.gz") - with gzip.open(loc_pgs_out, 'wt') as outf: - logger.debug('Writing adjusted PGS values (long format) to: {}'.format(loc_pgs_out)) + with gzip.open(loc_pgs_out, "wt") as outf: + logger.debug( + "Writing adjusted PGS values (long format) to: {}".format(loc_pgs_out) + ) for i, pgs_id in enumerate(scorecols): - df_pgs = adjpgs.loc[:, adjpgs.columns.str.endswith(pgs_id)].melt(ignore_index=False) # filter to 1 PGS - df_pgs[['method', 'PGS']] = df_pgs.variable.str.split("|", expand=True) - df_pgs = df_pgs.drop('variable', axis=1).reset_index().pivot(index=['sampleset', 'IID', 'PGS'], - columns='method', values='value') + df_pgs = adjpgs.loc[:, adjpgs.columns.str.endswith(pgs_id)].melt( + ignore_index=False + ) # filter to 1 PGS + df_pgs[["method", "PGS"]] = df_pgs.variable.str.split("|", expand=True) + df_pgs = ( + df_pgs.drop("variable", axis=1) + .reset_index() + .pivot( + index=["sampleset", "IID", "PGS"], columns="method", values="value" + ) + ) if i == 0: - logger.debug('{}/{}: Writing {}'.format(i+1, len(scorecols), pgs_id)) + logger.debug("{}/{}: Writing {}".format(i + 1, len(scorecols), pgs_id)) colorder = list(df_pgs.columns) # to ensure sort order - df_pgs.to_csv(outf, sep='\t') + df_pgs.to_csv(outf, sep="\t") else: - logger.debug('{}/{}: Appending {}'.format(i+1, len(scorecols), pgs_id)) - df_pgs[colorder].to_csv(outf, sep='\t', header=False) + logger.debug( + "{}/{}: Appending {}".format(i + 1, len(scorecols), pgs_id) + ) + df_pgs[colorder].to_csv(outf, sep="\t", header=False) # Write results of PCA & population similarity loc_popsim_out = os.path.join(dout, f"{args.d_target}_popsimilarity.txt.gz") - logger.debug('Writing PCA and popsim results to: {}'.format(loc_popsim_out)) - final_df.drop(scorecols, axis=1).to_csv(loc_popsim_out, sep='\t') + logger.debug("Writing PCA and popsim results to: {}".format(loc_popsim_out)) + final_df.drop(scorecols, axis=1).to_csv(loc_popsim_out, sep="\t") logger.info("Finished ancestry analysis") def _description_text() -> str: - return textwrap.dedent('Program to analyze ancestry outputs of the pgscatalog/pgsc_calc pipeline. Current inputs: ' - '\n - PCA projections from reference and target datasets (*.pcs)' - '\n - calculated polygenic scores (e.g. aggregated_scores.txt.gz), ' - '\n - information about related samples in the reference dataset (e.g. ' - 'deg2_hg38.king.cutoff.out.id).') + return textwrap.dedent( + "Program to analyze ancestry outputs of the pgscatalog/pgsc_calc pipeline. Current inputs: " + "\n - PCA projections from reference and target datasets (*.pcs)" + "\n - calculated polygenic scores (e.g. aggregated_scores.txt.gz), " + "\n - information about related samples in the reference dataset (e.g. " + "deg2_hg38.king.cutoff.out.id)." + ) def _parse_args(args=None): - parser = argparse.ArgumentParser(description=_description_text(), - formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('-d', '--dataset', dest='d_target', required=True, - help=' Label of the TARGET genomic dataset') - parser.add_argument('-r', '--reference', dest='d_ref', required=True, - help=' Label of the REFERENCE genomic dataset') - parser.add_argument('--ref_pcs', dest='ref_pcs', required=True, nargs='+', - help=' Principal components path (output from fraposa_pgsc)') - parser.add_argument('--target_pcs', dest='target_pcs', required=True, nargs='+', - help=' Principal components path (output from fraposa_pgsc)') - parser.add_argument('--psam', dest='psam', required=True, - help=' Reference sample information file path in plink2 psam format)') - parser.add_argument('-x', '--reference_related', dest='ref_related', - help='File of related sample IDs (excluded from training ancestry assignments)') - parser.add_argument('-p', '--pop_label', dest='ref_label', default='SuperPop', - help='Population labels in REFERENCE psam to use for assignment') - parser.add_argument('-s', '--agg_scores', dest='scorefile', default='aggregated_scores.txt.gz', - help='Aggregated scores in PGS Catalog format ([sampleset, IID] indexed)') - parser.add_argument('-a', '--ancestry_method', dest='method_compare', - choices=comparison_method_threshold.keys(), default='RandomForest', - help='Method used for population/ancestry assignment') - parser.add_argument('--n_popcomp', dest='nPCs_popcomp', type=int, metavar="[1-20]", choices=range(1, 21), - default=5, - help='Number of PCs used for population comparison (default = 5)') - parser.add_argument('-t', '--pval_threshold', dest='pThreshold', type=float, - help='p-value threshold used to identify low-confidence ancestry similarities') - parser.add_argument('-n', '--normalization_method', nargs='+', dest='method_normalization', - choices=normalization_methods, default=["empirical", "mean", "mean+var"], - help='Method used for adjustment of PGS using genetic ancestry') - parser.add_argument('--n_normalization', dest='nPCs_normalization', type=int, metavar="[1-20]", - choices=range(1, 21), default=4, - help='Number of PCs used for population NORMALIZATION (default = 4)') - parser.add_argument('--outdir', dest='outdir', required=True, - help=' Output directory') - parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', - help=' Extra logging information') + parser = argparse.ArgumentParser( + description=_description_text(), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "-d", + "--dataset", + dest="d_target", + required=True, + help=" Label of the TARGET genomic dataset", + ) + parser.add_argument( + "-r", + "--reference", + dest="d_ref", + required=True, + help=" Label of the REFERENCE genomic dataset", + ) + parser.add_argument( + "--ref_pcs", + dest="ref_pcs", + required=True, + nargs="+", + help=" Principal components path (output from fraposa_pgsc)", + ) + parser.add_argument( + "--target_pcs", + dest="target_pcs", + required=True, + nargs="+", + help=" Principal components path (output from fraposa_pgsc)", + ) + parser.add_argument( + "--psam", + dest="psam", + required=True, + help=" Reference sample information file path in plink2 psam format)", + ) + parser.add_argument( + "-x", + "--reference_related", + dest="ref_related", + help="File of related sample IDs (excluded from training ancestry assignments)", + ) + parser.add_argument( + "-p", + "--pop_label", + dest="ref_label", + default="SuperPop", + help="Population labels in REFERENCE psam to use for assignment", + ) + parser.add_argument( + "-s", + "--agg_scores", + dest="scorefile", + default="aggregated_scores.txt.gz", + help="Aggregated scores in PGS Catalog format ([sampleset, IID] indexed)", + ) + parser.add_argument( + "-a", + "--ancestry_method", + dest="method_compare", + choices=comparison_method_threshold.keys(), + default="RandomForest", + help="Method used for population/ancestry assignment", + ) + parser.add_argument( + "--n_popcomp", + dest="nPCs_popcomp", + type=int, + metavar="[1-20]", + choices=range(1, 21), + default=5, + help="Number of PCs used for population comparison (default = 5)", + ) + parser.add_argument( + "-t", + "--pval_threshold", + dest="pThreshold", + type=float, + help="p-value threshold used to identify low-confidence ancestry similarities", + ) + parser.add_argument( + "-n", + "--normalization_method", + nargs="+", + dest="method_normalization", + choices=normalization_methods, + default=["empirical", "mean", "mean+var"], + help="Method used for adjustment of PGS using genetic ancestry", + ) + parser.add_argument( + "--n_normalization", + dest="nPCs_normalization", + type=int, + metavar="[1-20]", + choices=range(1, 21), + default=4, + help="Number of PCs used for population NORMALIZATION (default = 4)", + ) + parser.add_argument( + "--outdir", dest="outdir", required=True, help=" Output directory" + ) + parser.add_argument( + "-v", + "--verbose", + dest="verbose", + action="store_true", + help=" Extra logging information", + ) return parser.parse_args(args) diff --git a/pgscatalog_utils/ancestry/read.py b/pgscatalog_utils/ancestry/read.py index 8763e07..bb83273 100644 --- a/pgscatalog_utils/ancestry/read.py +++ b/pgscatalog_utils/ancestry/read.py @@ -1,12 +1,10 @@ import logging import pandas as pd -import numpy as np -import os logger = logging.getLogger(__name__) -def read_pcs(loc_pcs: list[str],dataset: str, loc_related_ids=None, nPCs=None): +def read_pcs(loc_pcs: list[str], dataset: str, loc_related_ids=None, nPCs=None): """ Read the .pc file outputs of the fraposa_pgsc projection :param loc_pcs: list of locations for .pcs files @@ -18,20 +16,20 @@ def read_pcs(loc_pcs: list[str],dataset: str, loc_related_ids=None, nPCs=None): for i, path in enumerate(loc_pcs): logger.debug("Reading PCA projection: {}".format(path)) - df = pd.read_csv(path, sep='\t', converters={"IID": str}, header=0) - df['sampleset'] = dataset - df.set_index(['sampleset', 'IID'], inplace=True) + df = pd.read_csv(path, sep="\t", converters={"IID": str}, header=0) + df["sampleset"] = dataset + df.set_index(["sampleset", "IID"], inplace=True) if i == 0: - logger.debug('Initialising combined DF') + logger.debug("Initialising combined DF") proj = df.copy() else: - logger.debug('Appending to combined DF') + logger.debug("Appending to combined DF") proj = pd.concat([proj, df]) # Drop PCs if nPCs: - logger.debug('Filtering to relevant PCs') + logger.debug("Filtering to relevant PCs") dropcols = [] for x in proj.columns: if int(x[2:]) > nPCs: @@ -41,47 +39,55 @@ def read_pcs(loc_pcs: list[str],dataset: str, loc_related_ids=None, nPCs=None): # Read/process IDs for unrelated samples (usually reference dataset) if loc_related_ids: logger.debug("Flagging related samples with: {}".format(loc_related_ids)) - proj['Unrelated'] = True - with open(loc_related_ids, 'r') as infile: + proj["Unrelated"] = True + with open(loc_related_ids, "r") as infile: IDs_related = [x.strip() for x in infile.readlines()] - proj.loc[proj.index.get_level_values(level=1).isin(IDs_related), 'Unrelated'] = False + proj.loc[ + proj.index.get_level_values(level=1).isin(IDs_related), "Unrelated" + ] = False else: # if unrelated is all nan -> dtype is float64 # if unrelated is only true / false -> dtype is bool # if unrelated contains None, dtype stays bool, and pd.concat warning disappears - proj['Unrelated'] = None + proj["Unrelated"] = None return proj -def extract_ref_psam_cols(loc_psam, dataset: str, df_target, keepcols=['SuperPop', 'Population']): - psam = pd.read_csv(loc_psam, sep='\t', header=0) +def extract_ref_psam_cols( + loc_psam, dataset: str, df_target, keepcols=["SuperPop", "Population"] +): + psam = pd.read_csv(loc_psam, sep="\t", header=0) - match (psam.columns[0]): + match psam.columns[0]: # handle case of #IID -> IID (happens when #FID is present) - case '#IID': - psam.rename({'#IID': 'IID'}, axis=1, inplace=True) - case '#FID': - psam.drop(['#FID'], axis=1, inplace=True) + case "#IID": + psam.rename({"#IID": "IID"}, axis=1, inplace=True) + case "#FID": + psam.drop(["#FID"], axis=1, inplace=True) case _: assert False, "Invalid columns" - psam['sampleset'] = dataset - psam.set_index(['sampleset', 'IID'], inplace=True) + psam["sampleset"] = dataset + psam.set_index(["sampleset", "IID"], inplace=True) return pd.merge(df_target, psam[keepcols], left_index=True, right_index=True) -def read_pgs(loc_aggscore, onlySUM: bool): +def read_pgs(loc_aggscore): """ - Function to read the output of aggreagte_scores + Function to read the PGS SUM from the output of aggreagte_scores :param loc_aggscore: path to aggregated scores output - :param onlySUM: whether to return only _SUM columns (e.g. not _AVG) - :return: + :return: df with PGS SUM indexed by sampleset and IID """ - logger.debug('Reading aggregated score data: {}'.format(loc_aggscore)) - df = pd.read_csv(loc_aggscore, sep='\t', index_col=['sampleset', 'IID'], converters={"IID": str}, header=0) - if onlySUM: - df = df[[x for x in df.columns if x.endswith('_SUM')]] - rn = [x.rstrip('_SUM') for x in df.columns] - df.columns = rn - return df \ No newline at end of file + logger.debug("Reading aggregated score data: {}".format(loc_aggscore)) + df = pd.read_csv( + loc_aggscore, + sep="\t", + index_col=["sampleset", "IID"], + converters={"IID": str}, + header=0, + ).pivot(columns=["PGS"], values=["SUM"]) + # rename to PGS only + df.columns = [f"{j}" for i, j in df.columns] + + return df diff --git a/poetry.lock b/poetry.lock index 05b2c77..a5c92f1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "anyio" @@ -753,59 +753,67 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "fonttools" -version = "4.42.1" +version = "4.49.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c"}, - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd"}, - {file = "fonttools-4.42.1-cp310-cp310-win32.whl", hash = "sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca"}, - {file = "fonttools-4.42.1-cp310-cp310-win_amd64.whl", hash = "sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861"}, - {file = "fonttools-4.42.1-cp311-cp311-win32.whl", hash = "sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a"}, - {file = "fonttools-4.42.1-cp311-cp311-win_amd64.whl", hash = "sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4"}, - {file = "fonttools-4.42.1-cp38-cp38-win32.whl", hash = "sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d"}, - {file = "fonttools-4.42.1-cp38-cp38-win_amd64.whl", hash = "sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967"}, - {file = "fonttools-4.42.1-cp39-cp39-win32.whl", hash = "sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64"}, - {file = "fonttools-4.42.1-cp39-cp39-win_amd64.whl", hash = "sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b"}, - {file = "fonttools-4.42.1-py3-none-any.whl", hash = "sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853"}, - {file = "fonttools-4.42.1.tar.gz", hash = "sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] + {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"}, + {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"}, + {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559"}, + {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29"}, + {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532"}, + {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828"}, + {file = "fonttools-4.49.0-cp310-cp310-win32.whl", hash = "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b"}, + {file = "fonttools-4.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf"}, + {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e"}, + {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814"}, + {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22"}, + {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942"}, + {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a"}, + {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86"}, + {file = "fonttools-4.49.0-cp311-cp311-win32.whl", hash = "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e"}, + {file = "fonttools-4.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6"}, + {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075"}, + {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e"}, + {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff"}, + {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5"}, + {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb"}, + {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7"}, + {file = "fonttools-4.49.0-cp312-cp312-win32.whl", hash = "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880"}, + {file = "fonttools-4.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034"}, + {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb"}, + {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4"}, + {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75"}, + {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9"}, + {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd"}, + {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036"}, + {file = "fonttools-4.49.0-cp38-cp38-win32.whl", hash = "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844"}, + {file = "fonttools-4.49.0-cp38-cp38-win_amd64.whl", hash = "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a"}, + {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc"}, + {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"}, + {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2"}, + {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42"}, + {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be"}, + {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c"}, + {file = "fonttools-4.49.0-cp39-cp39-win32.whl", hash = "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133"}, + {file = "fonttools-4.49.0-cp39-cp39-win_amd64.whl", hash = "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836"}, + {file = "fonttools-4.49.0-py3-none-any.whl", hash = "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18"}, + {file = "fonttools-4.49.0.tar.gz", hash = "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "scipy"] -lxml = ["lxml (>=4.0,<5)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] repacker = ["uharfbuzz (>=0.23.0)"] symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.0.0)"] +unicode = ["unicodedata2 (>=15.1.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] @@ -819,6 +827,62 @@ files = [ {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, ] +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.3" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"}, + {file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.24.0)"] + +[[package]] +name = "httpx" +version = "0.26.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + [[package]] name = "identify" version = "2.5.31" @@ -1284,13 +1348,13 @@ test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "p [[package]] name = "jupyter-lsp" -version = "2.2.0" +version = "2.2.2" description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter-lsp-2.2.0.tar.gz", hash = "sha256:8ebbcb533adb41e5d635eb8fe82956b0aafbf0fd443b6c4bfa906edeeb8635a1"}, - {file = "jupyter_lsp-2.2.0-py3-none-any.whl", hash = "sha256:9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f"}, + {file = "jupyter-lsp-2.2.2.tar.gz", hash = "sha256:256d24620542ae4bba04a50fc1f6ffe208093a07d8e697fea0a8d1b8ca1b7e5b"}, + {file = "jupyter_lsp-2.2.2-py3-none-any.whl", hash = "sha256:3b95229e4168355a8c91928057c1621ac3510ba98b2a925e82ebd77f078b1aa5"}, ] [package.dependencies] @@ -1353,17 +1417,18 @@ test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", [[package]] name = "jupyterlab" -version = "4.0.6" +version = "4.1.2" description = "JupyterLab computational environment" optional = false python-versions = ">=3.8" files = [ - {file = "jupyterlab-4.0.6-py3-none-any.whl", hash = "sha256:7d9dacad1e3f30fe4d6d4efc97fda25fbb5012012b8f27cc03a2283abcdee708"}, - {file = "jupyterlab-4.0.6.tar.gz", hash = "sha256:6c43ae5a6a1fd2fdfafcb3454004958bde6da76331abb44cffc6f9e436b19ba1"}, + {file = "jupyterlab-4.1.2-py3-none-any.whl", hash = "sha256:aa88193f03cf4d3555f6712f04d74112b5eb85edd7d222c588c7603a26d33c5b"}, + {file = "jupyterlab-4.1.2.tar.gz", hash = "sha256:5d6348b3ed4085181499f621b7dfb6eb0b1f57f3586857aadfc8e3bf4c4885f9"}, ] [package.dependencies] async-lru = ">=1.0.0" +httpx = ">=0.25.0" ipykernel = "*" jinja2 = ">=3.0.3" jupyter-core = "*" @@ -1377,9 +1442,9 @@ tornado = ">=6.2.0" traitlets = "*" [package.extras] -dev = ["black[jupyter] (==23.7.0)", "build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.0.286)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8,<7.2.0)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.0.1)", "ipython (==8.14.0)", "ipywidgets (==8.0.6)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post0)", "matplotlib (==3.7.1)", "nbconvert (>=7.0.0)", "pandas (==2.0.2)", "scipy (==1.10.1)", "vega-datasets (==0.9.0)"] +dev = ["build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.2.0)"] +docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-jupyter", "sphinx (>=1.8,<7.3.0)", "sphinx-copybutton"] +docs-screenshots = ["altair (==5.2.0)", "ipython (==8.16.1)", "ipywidgets (==8.1.1)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post6)", "matplotlib (==3.8.2)", "nbconvert (>=7.0.0)", "pandas (==2.2.0)", "scipy (==1.12.0)", "vega-datasets (==0.9.0)"] test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] [[package]] @@ -1805,18 +1870,18 @@ setuptools = "*" [[package]] name = "notebook" -version = "7.0.4" +version = "7.1.0" description = "Jupyter Notebook - A web-based notebook environment for interactive computing" optional = false python-versions = ">=3.8" files = [ - {file = "notebook-7.0.4-py3-none-any.whl", hash = "sha256:ee738414ac01773c1ad6834cf76cc6f1ce140ac8197fd13b3e2d44d89e257f72"}, - {file = "notebook-7.0.4.tar.gz", hash = "sha256:0c1b458f72ce8774445c8ef9ed2492bd0b9ce9605ac996e2b066114f69795e71"}, + {file = "notebook-7.1.0-py3-none-any.whl", hash = "sha256:a8fa4ccb5e5fe220f29d9900337efd7752bc6f2efe004d6f320db01f7743adc9"}, + {file = "notebook-7.1.0.tar.gz", hash = "sha256:99caf01ff166b1cc86355c9b37c1ba9bf566c1d7fc4ab57bb6f8f24e36c4260e"}, ] [package.dependencies] jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.0.2,<5" +jupyterlab = ">=4.1.1,<4.2" jupyterlab-server = ">=2.22.1,<3" notebook-shim = ">=0.2,<0.3" tornado = ">=6.2.0" @@ -2026,70 +2091,88 @@ files = [ [[package]] name = "pillow" -version = "10.0.1" +version = "10.2.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "Pillow-10.0.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:8f06be50669087250f319b706decf69ca71fdecd829091a37cc89398ca4dc17a"}, - {file = "Pillow-10.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50bd5f1ebafe9362ad622072a1d2f5850ecfa44303531ff14353a4059113b12d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6a90167bcca1216606223a05e2cf991bb25b14695c518bc65639463d7db722d"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11c9102c56ffb9ca87134bd025a43d2aba3f1155f508eff88f694b33a9c6d19"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:186f7e04248103482ea6354af6d5bcedb62941ee08f7f788a1c7707bc720c66f"}, - {file = "Pillow-10.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0462b1496505a3462d0f35dc1c4d7b54069747d65d00ef48e736acda2c8cbdff"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d889b53ae2f030f756e61a7bff13684dcd77e9af8b10c6048fb2c559d6ed6eaf"}, - {file = "Pillow-10.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552912dbca585b74d75279a7570dd29fa43b6d93594abb494ebb31ac19ace6bd"}, - {file = "Pillow-10.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:787bb0169d2385a798888e1122c980c6eff26bf941a8ea79747d35d8f9210ca0"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fd2a5403a75b54661182b75ec6132437a181209b901446ee5724b589af8edef1"}, - {file = "Pillow-10.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d7e91b4379f7a76b31c2dda84ab9e20c6220488e50f7822e59dac36b0cd92b1"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19e9adb3f22d4c416e7cd79b01375b17159d6990003633ff1d8377e21b7f1b21"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93139acd8109edcdeffd85e3af8ae7d88b258b3a1e13a038f542b79b6d255c54"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:92a23b0431941a33242b1f0ce6c88a952e09feeea9af4e8be48236a68ffe2205"}, - {file = "Pillow-10.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cbe68deb8580462ca0d9eb56a81912f59eb4542e1ef8f987405e35a0179f4ea2"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:522ff4ac3aaf839242c6f4e5b406634bfea002469656ae8358644fc6c4856a3b"}, - {file = "Pillow-10.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:84efb46e8d881bb06b35d1d541aa87f574b58e87f781cbba8d200daa835b42e1"}, - {file = "Pillow-10.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:898f1d306298ff40dc1b9ca24824f0488f6f039bc0e25cfb549d3195ffa17088"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:bcf1207e2f2385a576832af02702de104be71301c2696d0012b1b93fe34aaa5b"}, - {file = "Pillow-10.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d6c9049c6274c1bb565021367431ad04481ebb54872edecfcd6088d27edd6ed"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28444cb6ad49726127d6b340217f0627abc8732f1194fd5352dec5e6a0105635"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de596695a75496deb3b499c8c4f8e60376e0516e1a774e7bc046f0f48cd620ad"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:2872f2d7846cf39b3dbff64bc1104cc48c76145854256451d33c5faa55c04d1a"}, - {file = "Pillow-10.0.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ce90f8a24e1c15465048959f1e94309dfef93af272633e8f37361b824532e91"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ee7810cf7c83fa227ba9125de6084e5e8b08c59038a7b2c9045ef4dde61663b4"}, - {file = "Pillow-10.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1be1c872b9b5fcc229adeadbeb51422a9633abd847c0ff87dc4ef9bb184ae08"}, - {file = "Pillow-10.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:98533fd7fa764e5f85eebe56c8e4094db912ccbe6fbf3a58778d543cadd0db08"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:764d2c0daf9c4d40ad12fbc0abd5da3af7f8aa11daf87e4fa1b834000f4b6b0a"}, - {file = "Pillow-10.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcb59711009b0168d6ee0bd8fb5eb259c4ab1717b2f538bbf36bacf207ef7a68"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:697a06bdcedd473b35e50a7e7506b1d8ceb832dc238a336bd6f4f5aa91a4b500"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f665d1e6474af9f9da5e86c2a3a2d2d6204e04d5af9c06b9d42afa6ebde3f21"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:2fa6dd2661838c66f1a5473f3b49ab610c98a128fc08afbe81b91a1f0bf8c51d"}, - {file = "Pillow-10.0.1-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:3a04359f308ebee571a3127fdb1bd01f88ba6f6fb6d087f8dd2e0d9bff43f2a7"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:723bd25051454cea9990203405fa6b74e043ea76d4968166dfd2569b0210886a"}, - {file = "Pillow-10.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:71671503e3015da1b50bd18951e2f9daf5b6ffe36d16f1eb2c45711a301521a7"}, - {file = "Pillow-10.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:44e7e4587392953e5e251190a964675f61e4dae88d1e6edbe9f36d6243547ff3"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:3855447d98cced8670aaa63683808df905e956f00348732448b5a6df67ee5849"}, - {file = "Pillow-10.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ed2d9c0704f2dc4fa980b99d565c0c9a543fe5101c25b3d60488b8ba80f0cce1"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5bb289bb835f9fe1a1e9300d011eef4d69661bb9b34d5e196e5e82c4cb09b37"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0d3e54ab1df9df51b914b2233cf779a5a10dfd1ce339d0421748232cea9876"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:2cc6b86ece42a11f16f55fe8903595eff2b25e0358dec635d0a701ac9586588f"}, - {file = "Pillow-10.0.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ca26ba5767888c84bf5a0c1a32f069e8204ce8c21d00a49c90dabeba00ce0145"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f0b4b06da13275bc02adfeb82643c4a6385bd08d26f03068c2796f60d125f6f2"}, - {file = "Pillow-10.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bc2e3069569ea9dbe88d6b8ea38f439a6aad8f6e7a6283a38edf61ddefb3a9bf"}, - {file = "Pillow-10.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8b451d6ead6e3500b6ce5c7916a43d8d8d25ad74b9102a629baccc0808c54971"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:32bec7423cdf25c9038fef614a853c9d25c07590e1a870ed471f47fb80b244db"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cf63d2c6928b51d35dfdbda6f2c1fddbe51a6bc4a9d4ee6ea0e11670dd981e"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f6d3d4c905e26354e8f9d82548475c46d8e0889538cb0657aa9c6f0872a37aa4"}, - {file = "Pillow-10.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:847e8d1017c741c735d3cd1883fa7b03ded4f825a6e5fcb9378fd813edee995f"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7f771e7219ff04b79e231d099c0a28ed83aa82af91fd5fa9fdb28f5b8d5addaf"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459307cacdd4138edee3875bbe22a2492519e060660eaf378ba3b405d1c66317"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b059ac2c4c7a97daafa7dc850b43b2d3667def858a4f112d1aa082e5c3d6cf7d"}, - {file = "Pillow-10.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6caf3cd38449ec3cd8a68b375e0c6fe4b6fd04edb6c9766b55ef84a6e8ddf2d"}, - {file = "Pillow-10.0.1.tar.gz", hash = "sha256:d72967b06be9300fed5cfbc8b5bafceec48bf7cdc7dab66b1d2549035287191d"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, + {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"}, + {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"}, + {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"}, + {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"}, + {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"}, + {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"}, + {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"}, + {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"}, + {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"}, + {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"}, + {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"}, + {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"}, + {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"}, + {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"}, + {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"}, + {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"}, + {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"}, + {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"}, + {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"}, + {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"}, + {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"}, + {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"}, + {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"}, + {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"}, + {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"}, + {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"}, + {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"}, + {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"}, + {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"}, + {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"}, + {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"}, + {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"}, + {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"}, ] [package.extras] docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] [[package]] name = "platformdirs" diff --git a/pyproject.toml b/pyproject.toml index 098283f..88134e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pgscatalog_utils" -version = "0.5.0" +version = "0.5.1" description = "Utilities for working with PGS Catalog API and scoring files" homepage = "https://github.com/PGScatalog/pgscatalog_utils" authors = ["Benjamin Wingfield ", "Samuel Lambert ", "Laurent Gil "] diff --git a/tests/data/cineca_22_additive_0.sscore.zst b/tests/data/cineca_22_additive_0.sscore.zst new file mode 100644 index 0000000..1b24681 Binary files /dev/null and b/tests/data/cineca_22_additive_0.sscore.zst differ diff --git a/tests/test_aggregate.py b/tests/test_aggregate.py new file mode 100644 index 0000000..76f5d86 --- /dev/null +++ b/tests/test_aggregate.py @@ -0,0 +1,22 @@ +import importlib.resources +import os +import pandas as pd +from unittest.mock import patch + +from pgscatalog_utils.aggregate.aggregate_scores import aggregate_scores +from . import data + + +def test_aggregate(tmp_path_factory): + out_dir = tmp_path_factory.mktemp("aggregated") + score_path = importlib.resources.files(data) / "cineca_22_additive_0.sscore.zst" + + args = ["aggregate_scores", "-s", str(score_path), "-o", str(out_dir)] + + with patch("sys.argv", args): + aggregate_scores() + + assert os.listdir(out_dir) == ["aggregated_scores.txt.gz"] + df = pd.read_csv(out_dir / "aggregated_scores.txt.gz", delimiter="\t") + assert list(df.columns) == ["sampleset", "IID", "PGS", "SUM", "DENOM", "AVG"] + assert df.shape == (2504, 6)