From aa9967d015ffc5c453bd64b5cad9ac3eb15fcc71 Mon Sep 17 00:00:00 2001 From: Marion Date: Tue, 9 Apr 2024 09:09:00 -0700 Subject: [PATCH] Stable candidate v2.2.0 (#62) * Improve output, save validation results to file, add more date validations (#61) * validation exception on failure * add more date validations * add progress bar req * tidier stdout, save big errors to file * add date error checking * update tests * add info method, formatting * always save validation results * fix validation output * add tqdm to dependencies * remove errors from map json * add new output file to readme * put back errors and warnings * fix bugs, change to validation in json * update readme * update validation results comments * add missing test error * update files for new release --- .gitignore | 3 +- README.md | 9 +- dist/clinical_ETL-2.0.0-py3-none-any.whl | Bin 36553 -> 0 bytes dist/clinical_ETL-2.2.0-py3-none-any.whl | Bin 0 -> 40567 bytes dist/clinical_ETL-2.2.0.tar.gz | Bin 0 -> 39025 bytes pyproject.toml | 5 +- requirements.txt | 1 + src/clinical_ETL.egg-info/PKG-INFO | 12 +-- src/clinical_ETL.egg-info/requires.txt | 1 + src/clinical_etl/CSVConvert.py | 106 +++++++++++++------- src/clinical_etl/mappings.py | 11 +++ src/clinical_etl/mohschema.py | 117 +++++++++++++++++++---- tests/raw_data/Donor.csv | 2 +- tests/raw_data/Treatment.csv | 2 +- tests/test_data_ingest.py | 10 +- 15 files changed, 206 insertions(+), 73 deletions(-) delete mode 100644 dist/clinical_ETL-2.0.0-py3-none-any.whl create mode 100644 dist/clinical_ETL-2.2.0-py3-none-any.whl create mode 100644 dist/clinical_ETL-2.2.0.tar.gz diff --git a/.gitignore b/.gitignore index d46fa3f..d8d6060 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ __pycache__/* _local .idea .~lock* -build/ \ No newline at end of file +build/ +tests/raw_data_* diff --git a/README.md b/README.md index 692ad41..93933b4 100644 --- a/README.md +++ b/README.md @@ -162,14 +162,6 @@ A summarised example of the output is below: "openapi_url": "https://raw.githubusercontent.com/CanDIG/katsu/develop/chord_metadata_service/mohpackets/docs/schema.yml", "katsu_sha": < git sha of the katsu version used for the schema >, "donors": < An array of JSON objects, each one representing a DonorWithClinicalData in katsu >, - "validation_warnings": [ - < any validation warnings, e.g. > - "DONOR_5: cause_of_death required if is_deceased = Yes" - ], - "validation_errors": [ - < any validation errors, e.g. > - "DONOR_5 > PD_5 > TR_5 > Radiation 1: Only one radiation is allowed per treatment" - ], "statistics": { "required_but_missing": { < for each schema in the model, a list of required fields and how many cases are missing this value (out of the total number of occurrences) > @@ -196,6 +188,7 @@ A summarised example of the output is below: } } ``` +`_validation_results.json` contains all validation warnings and errors. `_indexed.json` contains information about how the ETL is looking up the mappings and can be useful for debugging. It is only generated if the `--index` argument is specified when CSVConvert is run. Note: This file can be very large if the input data is large. diff --git a/dist/clinical_ETL-2.0.0-py3-none-any.whl b/dist/clinical_ETL-2.0.0-py3-none-any.whl deleted file mode 100644 index 299e4bfa314c816d772f09f15cb8617b5c018963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36553 zcmZs?W2`VdxGcJC+qP}nwr$(CZQHhO+iShcwt2skoa|(u+$QahChd<-o|#NLRgeY- zK>+{&fB=}LN>;b^zebwH2LM3u006-HZ`Rnx($3P@&_>_X#fDy3Sxwm9&dt=xh0eiq zme<<(s3URzhq}R~isZ(kqh9B7N?XqA@PW)Z^FhY5CtZ4y50zGsZ5^pHAqD?z*}vcK zV39y@Gf(zbPPLmjQJ{En_Z%JT{#Sk9=JGOoy60UCz1`|(K_`85uP-b0si%WWA=~WX zQ~&K1O|>(~{0cm^e$8~XqI1pqyVu;fb+-Kz?ITfS9K& zK!KNq;asv54ma&0`_ig;N%Sdl4@SI5Gi&y2BYO`Xyk7ro)N2`Ltjbg4YPhR%Odz)3 z{!wZke!eOeuiCm-2cImz=~Rogbji~hHrO<@OMmUnDv`dG>R)@7aJr_l8hn)wf$fEA zE!sVjS@{*2As}^pm^ABbAu7&hkUZ9$0B7MO7 zytzY}4Zhi}&U!Odc&blnz>}Jm@{6XmtJnAGO}Md;v#J^v29UnGW^($dT?>{NyRP%<}r1gugU^YW)k1{&5zDeIk#-lM*Uv-9J^&Xx}U<zQg3J$G8aaOZjRm<(0}o z*mOo3o!}y!t>><#*)pn%RLviO-wPh=CQD_xE6p~Il=soKH~iOd3gCbvitqqoM2W4@aq&RdC|wf?nVv4 z;}kJB0UU?=ecsUZdq2;&?=DwrWCd>J-~=txO+AEdtQD(GRZ|k7sp$(CAaG)*1@?odm{nLiu{|%3R~TJ31}}4? zC3qiKZZ&v_5Wmv~H13~@cg8{>o8z_KVM_sK!w%%3cXM7_@JxW)I7ZV4vvP#DZu%tg z@5b4DLwB}FEh5jcG$QH`AYD2!v=Ep3q>Y1-1~(&+kZ#YXKa2Bs`#HG%vK6G2a@{lv zX7T%S`+c0=%#sL&$3@Vf{M_9##{}qvC!kb`tM4>1Lihbx{gNQ@ekF;e^x{lhWBlOG zNf-kDPK$tl@PN5RY4oSUDQ%1CiWX{g?A1kngm*gixXeD80pSS#piF6GPS&C5g>)1}y3)Bbg$7mYlfICoj zSY9Aj0|nKIyhHi^9WMWE^)B9!gm%dWF&5im$*Sgje;&TrWg(> zEM_z2%VZ|iA&ipemQIUS+WOYJE?Y~>a@yj74UB)*T34pDxIHxC3McP=W$Pr0(Z{le zr6yWM5o{ zZrBF^!O@Wc#4W}lijMKd`hpRo9B7|&v?!Ng{Q?@eO#+x%D#^NZt^mg$7-O<&331VA z=(`-Uoq2RsFezJw`1W0EpJrLC%0Ak3WeDA~c41+hJiYmQxqf`g`FlRUJ_WaRf~G@G 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 HuUG#8f^i>Q diff --git a/dist/clinical_ETL-2.2.0-py3-none-any.whl b/dist/clinical_ETL-2.2.0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..c4de356a168811081c9ca8c8d9dce6fab8c64892 GIT binary patch literal 40567 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 WLm372=bP|u@5{&lKw#R>SN{dQSN)a% literal 0 HcmV?d00001 diff --git a/dist/clinical_ETL-2.2.0.tar.gz b/dist/clinical_ETL-2.2.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..4033b056d978ec3962b3095b5e9d64bed7942070 GIT binary patch literal 39025 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 Y?4SL!fA-J*`Db|k4|bjx1^~bV02i?~ivR!s literal 0 HcmV?d00001 diff --git a/pyproject.toml b/pyproject.toml index caa1004..062215f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools >= 61.0"] build-backend = "setuptools.build_meta" [project] -version = "2.0.0" +version = "2.2.0" name = "clinical_ETL" dependencies = [ "pandas>=2.1.0", @@ -14,7 +14,8 @@ dependencies = [ "requests>=2.29.0", "jsonschema~=4.19.2", "openapi-spec-validator>=0.7.1", - "pdoc3>=0.10.0" + "pdoc3>=0.10.0", + "tqdm>=4.66.2" ] requires-python = ">= 3.10" description = "ETL module for transforming clinical CSV data into properly-formatted packets for ingest into Katsu" diff --git a/requirements.txt b/requirements.txt index f44f69b..1a62a51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ requests~=2.29 jsonschema~=4.19.1 openapi-spec-validator~=0.7.1 pdoc3>=0.10.0 +tqdm>=4.66.2 diff --git a/src/clinical_ETL.egg-info/PKG-INFO b/src/clinical_ETL.egg-info/PKG-INFO index 4b31839..e47670e 100644 --- a/src/clinical_ETL.egg-info/PKG-INFO +++ b/src/clinical_ETL.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: clinical_ETL -Version: 2.0.0 +Version: 2.2.0 Summary: ETL module for transforming clinical CSV data into properly-formatted packets for ingest into Katsu Project-URL: Repository, https://github.com/CanDIG/clinical_ETL_code Requires-Python: >=3.10 @@ -15,6 +15,7 @@ Requires-Dist: requests>=2.29.0 Requires-Dist: jsonschema~=4.19.2 Requires-Dist: openapi-spec-validator>=0.7.1 Requires-Dist: pdoc3>=0.10.0 +Requires-Dist: tqdm>=4.66.2 # clinical_ETL_code @@ -180,14 +181,6 @@ A summarised example of the output is below: "openapi_url": "https://raw.githubusercontent.com/CanDIG/katsu/develop/chord_metadata_service/mohpackets/docs/schema.yml", "katsu_sha": < git sha of the katsu version used for the schema >, "donors": < An array of JSON objects, each one representing a DonorWithClinicalData in katsu >, - "validation_warnings": [ - < any validation warnings, e.g. > - "DONOR_5: cause_of_death required if is_deceased = Yes" - ], - "validation_errors": [ - < any validation errors, e.g. > - "DONOR_5 > PD_5 > TR_5 > Radiation 1: Only one radiation is allowed per treatment" - ], "statistics": { "required_but_missing": { < for each schema in the model, a list of required fields and how many cases are missing this value (out of the total number of occurrences) > @@ -214,6 +207,7 @@ A summarised example of the output is below: } } ``` +`_validation_results.json` contains all validation warnings and errors. `_indexed.json` contains information about how the ETL is looking up the mappings and can be useful for debugging. It is only generated if the `--index` argument is specified when CSVConvert is run. Note: This file can be very large if the input data is large. diff --git a/src/clinical_ETL.egg-info/requires.txt b/src/clinical_ETL.egg-info/requires.txt index e243be7..ec71569 100644 --- a/src/clinical_ETL.egg-info/requires.txt +++ b/src/clinical_ETL.egg-info/requires.txt @@ -7,3 +7,4 @@ requests>=2.29.0 jsonschema~=4.19.2 openapi-spec-validator>=0.7.1 pdoc3>=0.10.0 +tqdm>=4.66.2 diff --git a/src/clinical_etl/CSVConvert.py b/src/clinical_etl/CSVConvert.py index 7e5ee3e..6b97be6 100644 --- a/src/clinical_etl/CSVConvert.py +++ b/src/clinical_etl/CSVConvert.py @@ -11,11 +11,12 @@ import re import yaml import argparse +from tqdm import tqdm +from clinical_etl import mappings # Include clinical_etl parent directory in the module search path. current_dir = os.path.dirname(os.path.abspath(__file__)) parent_dir = os.path.dirname(current_dir) sys.path.append(parent_dir) -from clinical_etl import mappings def verbose_print(message): @@ -38,6 +39,18 @@ def parse_args(): return args +class Bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + def map_data_to_scaffold(node, line, rownum): """ Given a particular individual's data, and a node in the schema, return the node with mapped data. Recursive. @@ -311,14 +324,14 @@ def ingest_raw_data(input_path): return raw_csv_dfs, output_file -def process_data(raw_csv_dfs): +def process_data(raw_csv_dfs, verbose): """Takes a set of raw dataframes with a common identifier and merges into a JSON data structure.""" final_merged = {} cols_index = {} individuals = [] - + print(f"\n{Bcolors.OKBLUE}Processing sheets: {Bcolors.ENDC}") for page in raw_csv_dfs.keys(): - print(f"Processing sheet {page}...") + print(f"{Bcolors.OKBLUE}{page} {Bcolors.ENDC}", end="") df = raw_csv_dfs[page].dropna(axis='index', how='all') \ .dropna(axis='columns', how='all') \ .map(str) \ @@ -359,8 +372,8 @@ def process_data(raw_csv_dfs): if val == 'nan': val = None merged_dict[i][k.strip()].append(val) - if len(row_to_merge) > 0: - mappings._warn(f"Duplicate row for {merged_dict[i][mappings.IDENTIFIER_FIELD][0]} in {page}") + if len(row_to_merge) > 0 and verbose: + mappings._info(f"Duplicate row for {merged_dict[i][mappings.IDENTIFIER_FIELD][0]} in {page}") # Now we can clean up the dicts: index them by identifier instead of int indexed_merged_dict = {} @@ -548,9 +561,9 @@ def check_for_sheet_inconsistencies(template_sheets, csv_sheets): csv_template_diff = csv_sheets.difference(template_sheets) if len(template_csv_diff) > 0: # Print a warning if verbose enabled, it is possible that the template sheet has more than is required - print("WARNING: The following csv/sheet names are in the mapping template but were not found in the input sheets" - "/csvs:" + nl + nl.join(template_csv_diff) + nl + - "If this is an error please correct it as it may result in errors with mapping your data." + nl) + print(nl + f"{Bcolors.WARNING}WARNING: The following csv/sheet names are in the mapping template but were not found in the input sheets/csvs:{Bcolors.ENDC}" + + nl + nl.join(template_csv_diff) + nl + + f"{Bcolors.WARNING}If this is an error please correct it as it may result in errors with mapping your data.{Bcolors.ENDC}") if len(csv_template_diff) > 0: # Exit here because if we can't find a mapping for a field we can't properly map the inputs sys.exit("The following sheet names are in the input csvs but not found in the mapping template:" + nl + @@ -624,7 +637,7 @@ def load_manifest(manifest_file): def csv_convert(input_path, manifest_file, minify=False, index_output=False, verbose=False): mappings.VERBOSE = verbose # read manifest data - print("Starting conversion") + print(f"{Bcolors.OKGREEN}Starting conversion...{Bcolors.ENDC}", end="") manifest = load_manifest(manifest_file) mappings.IDENTIFIER_FIELD = manifest["identifier"] if mappings.IDENTIFIER_FIELD is None: @@ -633,7 +646,7 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver # read the schema (from the url specified in the manifest) and generate # a scaffold - print("Loading schema") + print(f"{Bcolors.OKGREEN}loading schema...{Bcolors.ENDC}", end="") schema = manifest["schema"] if schema.json_schema is None: sys.exit(f"Could not read an openapi schema at {manifest['schema']};\n" @@ -644,15 +657,15 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver template_lines = read_mapping_template(manifest["mapping"]) # read the raw data - print("Reading raw data") + print(f"{Bcolors.OKGREEN}reading raw data...{Bcolors.ENDC}", end="") raw_csv_dfs, mappings.OUTPUT_FILE = ingest_raw_data(input_path) if not raw_csv_dfs: sys.exit(f"No ingestable files (csv or xlsx) were found at {input_path}. Check path and try again.") check_for_sheet_inconsistencies(set([re.findall(r"\(([\w\" ]+)", x)[0].replace('"',"") for x in template_lines]), set(raw_csv_dfs.keys())) - print("Indexing data") - mappings.INDEXED_DATA = process_data(raw_csv_dfs) + print(f"{Bcolors.OKGREEN}indexing data{Bcolors.ENDC}") + mappings.INDEXED_DATA = process_data(raw_csv_dfs, verbose) if index_output: with open(f"{mappings.OUTPUT_FILE}_indexed.json", 'w') as f: if minify: @@ -661,10 +674,11 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver json.dump(mappings.INDEXED_DATA, f, indent=4) # if verbose flag is set, warn if column name is present in multiple sheets: - for col in mappings.INDEXED_DATA["columns"]: - if col != mappings.IDENTIFIER_FIELD and len(mappings.INDEXED_DATA["columns"][col]) > 1: - mappings._warn( - f"Column name {col} present in multiple sheets: {', '.join(mappings.INDEXED_DATA['columns'][col])}") + if verbose: + for col in mappings.INDEXED_DATA["columns"]: + if col != mappings.IDENTIFIER_FIELD and len(mappings.INDEXED_DATA["columns"][col]) > 1: + mappings._info( + f"Column name {col} present in multiple sheets: {', '.join(mappings.INDEXED_DATA['columns'][col])}") # warn if any template lines map the same column to multiple lines: scan_template_for_duplicate_mappings(template_lines) @@ -676,8 +690,11 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver packets = [] # for each identifier's row, make a packet - for indiv in mappings.INDEXED_DATA["individuals"]: - print(f"Creating packet for {indiv}") + print(f"\n{Bcolors.OKGREEN}Creating packets: {Bcolors.ENDC}") + progress = tqdm(mappings.INDEXED_DATA["individuals"]) + for indiv in progress: + progress.set_postfix_str(indiv) + # print(f"{Bcolors.OKGREEN}{indiv} {Bcolors.ENDC}", end="\r") mappings.IDENTIFIER = indiv # If there is a reference_date in the manifest, we need to calculate that and add CALCULATED.REFERENCE_DATE to the INDEXED_DATA @@ -715,6 +732,7 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver } if schema.katsu_sha is not None: result["katsu_sha"] = schema.katsu_sha + print(f"{Bcolors.OKGREEN}Saving packets to file.{Bcolors.ENDC}") with open(f"{mappings.OUTPUT_FILE}_map.json", 'w') as f: # write to json file for ingestion if minify: json.dump(result, f) @@ -722,32 +740,56 @@ def csv_convert(input_path, manifest_file, minify=False, index_output=False, ver json.dump(result, f, indent=4) # add validation data: + print(f"\n{Bcolors.OKGREEN}Starting validation...{Bcolors.ENDC}") schema.validate_ingest_map(result) - result["validation_errors"] = schema.validation_errors - result["validation_warnings"] = schema.validation_warnings + validation_results = {"validation_errors": schema.validation_errors, + "validation_warnings": schema.validation_warnings} result["statistics"] = schema.statistics with open(f"{mappings.OUTPUT_FILE}_map.json", 'w') as f: # write to json file for ingestion if minify: json.dump(result, f) else: json.dump(result, f, indent=4) + errors_present = False + with open(f"{input_path}_validation_results.json", 'w') as f: + json.dump(validation_results, f, indent=4) + print(f"Warnings written to {input_path}_validation_results.json.") + if len(validation_results["validation_warnings"]) > 0: + if len(validation_results["validation_warnings"]) > 20: + print(f"\n{Bcolors.WARNING}WARNING: There are {len(validation_results['validation_warnings'])} validation " + f"warnings in your data. It can be ingested but will not be considered complete until the warnings in " + f"{input_path}_validation_results.json are fixed.{Bcolors.ENDC}") + else: + print(f"\n{Bcolors.WARNING}WARNING: Your data is missing required fields from the MoHCCN data model! It can" + f" be ingested but will not be considered complete until the following problems are fixed:{Bcolors.ENDC}") + print("\n".join(validation_results["validation_warnings"])) + + if len(validation_results["validation_errors"]) > 0: + if len(validation_results["validation_errors"]) > 20: + print(f"\n{Bcolors.FAIL}FAILURE: Your data has failed validation. There are " + f"{len(validation_results['validation_errors'])} validation errors in your data, it cannot be " + f"ingested until the errors in {input_path}_validation_results.json are corrected. {Bcolors.ENDC}") + else: + print(f"\n{Bcolors.FAIL}FAILURE: Your data has failed validation against the MoHCCN data model! It cannot " + f"be ingested until the following errors are fixed:{Bcolors.ENDC}") + print("\n".join(validation_results["validation_errors"])) - if len(result["validation_warnings"]) > 0: - print( - "\n\nWARNING: Your data is missing required data for the MoHCCN data model! The following problems were found:") - print("\n".join(result["validation_warnings"])) - if len(result["validation_errors"]) > 0: - print("\n\nWARNING: Your data is not valid for the MoHCCN data model! The following errors were found:") - print("\n".join(result["validation_errors"])) - - return packets + errors_present = True + return packets, errors_present def main(): args = parse_args() input_path = args.input manifest_file = args.manifest - csv_convert(input_path, manifest_file, minify=args.minify, index_output=args.index, verbose=args.verbose) + packets, errors = csv_convert(input_path, manifest_file, minify=args.minify, index_output=args.index, + verbose=args.verbose) + print(f"{Bcolors.OKGREEN}\nConverted file written to {mappings.OUTPUT_FILE}_map.json{Bcolors.ENDC}") + if errors: + print(f"{Bcolors.WARNING}WARNING: this file cannot be ingested until all errors are fixed.{Bcolors.ENDC}") + else: + print(f"{Bcolors.OKGREEN}INFO: this file can be ingested.{Bcolors.ENDC}") + sys.exit(0) if __name__ == '__main__': diff --git a/src/clinical_etl/mappings.py b/src/clinical_etl/mappings.py index 2cf0b44..077864f 100644 --- a/src/clinical_etl/mappings.py +++ b/src/clinical_etl/mappings.py @@ -456,6 +456,17 @@ def _warn(message, input_values=None): print(f"WARNING: {message}. Input data: {input_values}") +def _info(message, input_values=None): + """Provides information to a user when there may be an issue, along with the IDENTIFIER and FIELD.""" + global IDENTIFIER + if IDENTIFIER is not None and input_values is not None: + print(f"INFO for {IDENTIFIER_FIELD}={IDENTIFIER}: {message}. Input data: {input_values}") + else: + print(f"INFO: {message}") + if input_values is not None: + print(f"INFO: {message}. Input data: {input_values}") + + def _push_to_stack(sheet, id, rownum): INDEX_STACK.append( { diff --git a/src/clinical_etl/mohschema.py b/src/clinical_etl/mohschema.py index 2256363..4aae98e 100644 --- a/src/clinical_etl/mohschema.py +++ b/src/clinical_etl/mohschema.py @@ -185,7 +185,6 @@ class MoHSchema(BaseSchema): } } - def validate_donors(self, map_json): for prop in map_json: match prop: @@ -198,39 +197,114 @@ def validate_donors(self, map_json): case "lost_to_followup_after_clinical_event_identifier": if map_json["lost_to_followup_after_clinical_event_identifier"] is not None: if map_json["is_deceased"]: - self.fail("lost_to_followup_after_clinical_event_identifier cannot be present if is_deceased = Yes") + self.fail( + "lost_to_followup_after_clinical_event_identifier cannot be present if is_deceased = Yes") case "lost_to_followup_reason": if map_json["lost_to_followup_reason"] is not None: if "lost_to_followup_after_clinical_event_identifier" not in map_json: - self.fail("lost_to_followup_reason should only be submitted if lost_to_followup_after_clinical_event_identifier is submitted") + self.fail( + "lost_to_followup_reason should only be submitted if lost_to_followup_after_clinical_event_identifier is submitted") case "date_alive_after_lost_to_followup": if map_json["date_alive_after_lost_to_followup"] is not None: if "lost_to_followup_after_clinical_event_identifier" not in map_json: - self.warn("lost_to_followup_after_clinical_event_identifier is required if date_alive_after_lost_to_followup is submitted") + self.warn( + "lost_to_followup_after_clinical_event_identifier is required if date_alive_after_lost_to_followup is submitted") case "cause_of_death": if map_json["cause_of_death"] is not None: if not map_json["is_deceased"]: self.fail("cause_of_death should only be submitted if is_deceased = Yes") + case "primary_diagnoses": + birth = None + death = None + if len(map_json["primary_diagnoses"]) > 0: + if "date_of_birth" in map_json and map_json["date_of_birth"] not in [None, '']: + if "dict" in str(type(map_json["date_of_birth"])): + birth = map_json["date_of_birth"]["month_interval"] + else: + birth = dateparser.parse(map_json["date_of_birth"]).date() + if "date_of_death" in map_json and map_json["date_of_death"] not in [None, '']: + if "dict" in str(type(map_json["date_of_death"])): + death = map_json["date_of_death"]["month_interval"] + else: + death = dateparser.parse(map_json["date_of_death"]).date() + diagnoses_dates = {} + for diagnosis in map_json["primary_diagnoses"]: + diagnosis_date = None + if "date_of_diagnosis" in diagnosis and diagnosis["date_of_diagnosis"] not in [None, '']: + if "dict" in str(type(diagnosis["date_of_diagnosis"])): + diagnosis_date = diagnosis["date_of_diagnosis"]["month_interval"] + else: + diagnosis_date = dateparser.parse(diagnosis["date_of_diagnosis"]).date() + diagnoses_dates[diagnosis['submitter_primary_diagnosis_id']] = diagnosis_date + if 'death' in locals() and death not in [None, ''] and diagnosis_date > death: + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']}: date_of_death cannot be earlier than date_of_diagnosis") + if 'birth' in locals() and birth not in [None, ''] and diagnosis_date < birth: + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']}: date_of_birth cannot be later than date_of_diagnosis") + if "treatments" in diagnosis and len(diagnosis["treatments"]) > 0: + for treatment in diagnosis["treatments"]: + treatment_start = None + treatment_end = None + if "treatment_start_date" in treatment and treatment["treatment_start_date"] not in [None, '']: + if "dict" in str(type(treatment["treatment_start_date"])): + treatment_start = treatment["treatment_start_date"]['month_interval'] + + else: + treatment_start = dateparser.parse(treatment["treatment_start_date"]).date() + if "treatment_end_date" in treatment and treatment["treatment_end_date"] not in [None, '']: + if "dict" in str(type(treatment["treatment_end_date"])): + treatment_end = treatment["treatment_end_date"]['month_interval'] + else: + treatment_end = dateparser.parse(treatment["treatment_end_date"]).date() + if ('death' in locals() and death not in [None, ''] and + 'treatment_end' in locals() and treatment_end not in [None, ''] + and treatment_end > death): + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']} > {treatment['submitter_treatment_id']}: date_of_death cannot be earlier than treatment_end_date ") + if ('diagnosis_date' in locals() and diagnosis_date not in [None, ''] and + treatment_end not in [None, ''] and 'treatment_end' in locals() and + treatment_end < diagnosis_date): + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']} > {treatment['submitter_treatment_id']}: date_of_diagnosis must be earlier than treatment_end_date ") + if 'treatment_start' in locals() and treatment_start not in [None, '']: + if 'death' in locals() and death not in [None, ''] and treatment_start > death: + self.fail( + f"{diagnosis['submitter_primary_diagnosis_id']} > {treatment['submitter_treatment_id']}: treatment_start_date cannot be after date_of_death ") + if 'birth' in locals() and birth not in [None, ''] and treatment_start < birth and treatment_start is not None: + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']} > {treatment['submitter_treatment_id']}: treatment_start_date cannot be before date_of_birth") + if 'diagnosis_date' in locals() and diagnosis_date not in [None, ''] and treatment_start < diagnosis_date: + self.fail(f"{diagnosis['submitter_primary_diagnosis_id']} > {treatment['submitter_treatment_id']}: treatment_start_date cannot be before date_of_diagnosis") + diagnosis_values_list = list(diagnoses_dates.values()) + if (len(diagnosis_values_list) > 0 and "int" in str(type(diagnosis_values_list[0])) and + 0 not in diagnosis_values_list): + self.warn(f"Earliest primary_diagnosis.date_of_diagnosis.month_interval should be 0, current " + f"month_intervals: {diagnoses_dates}") case "date_of_death": if map_json["date_of_death"] is not None: if not map_json["is_deceased"]: self.fail("date_of_death should only be submitted if is_deceased = Yes") + if map_json["date_of_birth"] is not None and map_json["date_of_death"] is not None: + if "dict" in str(type(map_json["date_of_birth"])): + death = map_json["date_of_death"]["month_interval"] + birth = map_json["date_of_birth"]["month_interval"] + if ("date_alive_after_lost_to_followup" in map_json and + map_json["date_alive_after_lost_to_followup"] is not None): + date_alive = map_json["date_alive_after_lost_to_followup"]["month_interval"] else: - if map_json["date_of_birth"] is not None: - if "dict" in str(type(map_json["date_of_birth"])): - death = map_json["date_of_death"]["month_interval"] - birth = map_json["date_of_birth"]["month_interval"] - else: - death = dateparser.parse(map_json["date_of_death"]).date() - birth = dateparser.parse(map_json["date_of_birth"]).date() - if birth > death: - self.fail("date_of_death cannot be earlier than date_of_birth") + death = dateparser.parse(map_json["date_of_death"]).date() + birth = dateparser.parse(map_json["date_of_birth"]).date() + if ("date_alive_after_lost_to_followup" in map_json and + map_json["date_alive_after_lost_to_followup"] is not None): + date_alive = dateparser.parse( + map_json["date_alive_after_lost_to_followup"]).date() + if birth > death: + self.fail("date_of_death cannot be earlier than date_of_birth") + if "date_alive_after_lost_to_followup" in map_json and date_alive > death: + self.fail("date_alive_after_lost_to_followup cannot be after date_of death") + if "date_alive_after_lost_to_followup" in map_json and date_alive < birth: + self.fail("date_alive_after_lost_to_followup cannot be before date_of birth") case "biomarkers": for x in map_json["biomarkers"]: if "test_date" not in x or x["test_date"] is None: self.warn("test_date is required for biomarkers not associated with nested events") - def validate_primary_diagnoses(self, map_json): # check to see if this primary_diagnosis is a tumour: specimen_ids = [] @@ -324,8 +398,8 @@ def validate_treatments(self, map_json): match prop: case "treatment_type": if map_json["treatment_type"] is not None: - for type in map_json["treatment_type"]: - match type: + for t_type in map_json["treatment_type"]: + match t_type: case "Chemotherapy": if "chemotherapies" not in map_json or len(map_json["chemotherapies"]) == 0: self.warn("treatment type Chemotherapy should have one or more chemotherapies submitted") @@ -341,6 +415,17 @@ def validate_treatments(self, map_json): case "Surgery": if "surgeries" not in map_json or len(map_json["surgeries"]) == 0: self.warn("treatment type Surgery should have one or more surgery submitted") + case "treatment_start_date": + if map_json["treatment_start_date"] is not None: + if "treatment_end_date" in map_json and map_json["treatment_end_date"] is not None: + if "dict" in str(type(map_json["treatment_start_date"])): + start = map_json["treatment_start_date"]["month_interval"] + end = map_json["treatment_end_date"]["month_interval"] + else: + start = dateparser.parse(map_json["treatment_start_date"]).date() + end = dateparser.parse(map_json["treatment_end_date"]).date() + if start > end: + self.fail("Treatment start cannot be after treatment end.") def validate_chemotherapies(self, map_json): diff --git a/tests/raw_data/Donor.csv b/tests/raw_data/Donor.csv index ef65a69..3cdb277 100644 --- a/tests/raw_data/Donor.csv +++ b/tests/raw_data/Donor.csv @@ -1,6 +1,6 @@ submitter_donor_id, program_id, lost_to_followup_after_clinical_event_identifier, lost_to_followup_reason, date_alive_after_lost_to_followup, is_deceased, cause_of_death, date_of_birth, date_of_death, gender, sex_at_birth, primary_site,date_resolution DONOR_1,TEST_1,,,,Yes,Died of cancer,6 Jan 1954,35,Man,Male,Esophagus,month -DONOR_2,TEST_1,,,,Yes,Died of other reasons,12 Feb 1982,239,Woman,Female,Eye and adnexa,day +DONOR_2,TEST_1,,,,Yes,Died of other reasons,12 Feb 1982,1675,Woman,Female,Eye and adnexa,day DONOR_3,TEST_1,PD_3,Lost contact,6/2022,No,,7/12/1945,,Non-binary,Other,Floor of mouth,month DONOR_4,TEST_1,,,,Yes,Unknown,6/1984,239,Man,Male,Gallbladder,month DONOR_5,TEST_2,PD_5,Unknown,6/2022,Yes,,2/1984,,Woman,Female,Gum,month diff --git a/tests/raw_data/Treatment.csv b/tests/raw_data/Treatment.csv index cf94763..723ff1b 100644 --- a/tests/raw_data/Treatment.csv +++ b/tests/raw_data/Treatment.csv @@ -1,6 +1,6 @@ submitter_treatment_id,submitter_donor_id, submitter_primary_diagnosis_id, treatment_type, is_primary_treatment, line_of_treatment, treatment_start_date, treatment_end_date, treatment_setting, treatment_intent, days_per_cycle, number_of_cycles, response_to_treatment_criteria_method, response_to_treatment, status_of_treatment TR_1,DONOR_1,PD_1,Bone marrow transplant,Yes,,2021-09,2022-09,Adjuvant,Palliative,4,2,RECIST 1.1,Complete response,Treatment completed as prescribed -TR_2,DONOR_2,PD_2,Chemotherapy,No,,2021-12,2022-12,Advanced/Metastatic,Guidance,5,2,iRECIST,Partial response,Treatment incomplete due to technical or organizational problems +TR_2,DONOR_2,PD_2,Chemotherapy,No,,2021-12,2024-01,Advanced/Metastatic,Guidance,5,2,iRECIST,Partial response,Treatment incomplete due to technical or organizational problems TR_3,DONOR_3,PD_3,Hormonal therapy,Yes,,2021-01,2022-01,Neoadjuvant,Diagnostic,6,3,Cheson CLL 2012 Oncology Response Criteria,Progressive disease,Treatment incomplete because patient died TR_4,DONOR_4,PD_4,Immunotherapy,No,,2021-02,2022-02,Conditioning,Forensic,6,2,Response Assessment in Neuro-Oncology (RANO),Stable disease,Patient choice (stopped or interrupted treatment) TR_5,DONOR_5,PD_5,Radiation therapy,Yes,,2021-09,2022-09,Induction,Preventive,7,1,AML Response Criteria,Immune complete response (iCR),Physician decision (stopped or interrupted treatment) diff --git a/tests/test_data_ingest.py b/tests/test_data_ingest.py index 65d4a16..857e494 100644 --- a/tests/test_data_ingest.py +++ b/tests/test_data_ingest.py @@ -28,7 +28,8 @@ def packets(): input_path = f"{REPO_DIR}/raw_data" manifest_file = f"{REPO_DIR}/manifest.yml" mappings.INDEX_STACK = [] - return CSVConvert.csv_convert(input_path, manifest_file, verbose=False) + return_values = CSVConvert.csv_convert(input_path, manifest_file, verbose=False) + return return_values[0] def test_csv_convert(packets): @@ -100,8 +101,11 @@ def test_validation(packets, schema): non_interval_errors.append(e) schema.validation_errors = non_interval_errors - assert len(schema.validation_errors) == 2 - # should be the following 2 errors: + assert len(schema.validation_errors) == 5 + # should be the following 5 errors: + # DONOR_1: PD_1 > TR_1: date_of_death cannot be earlier than treatment_end_date + # DONOR_1: PD_1 > TR_1: treatment_start_date cannot be after date_of_death + # DONOR_2: PD_2 > TR_2: date_of_death cannot be earlier than treatment_end_date # DONOR_6 > PD_6 > TR_9 > Surgery 0: submitter_specimen_id SPECIMEN_43 does not correspond to one of the available specimen_ids ['SPECIMEN_3'] # Duplicated IDs: in schema followups, FOLLOW_UP_4 occurs 2 times