diff --git a/pointblank/data/conformance/rules/sdtmig-3-4.json b/pointblank/data/conformance/rules/sdtmig-3-4.json index a116b4dc8..6777e4a58 100644 --- a/pointblank/data/conformance/rules/sdtmig-3-4.json +++ b/pointblank/data/conformance/rules/sdtmig-3-4.json @@ -3,7 +3,7 @@ "version": "3.4", "generated": "2026-07-14T00:00:00Z", "source": "CDISC SDTM Implementation Guide 3.4, hand-curated from public specification", - "checksum": "d30d87abb0157429", + "checksum": "35364c22f2effabc", "rules": [ { "core_id": "SDTM-001", @@ -1310,7 +1310,7 @@ "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "DM domain must contain required demographic variables (SEX, RACE, ETHNIC, COUNTRY).", + "description": "DM domain must contain required demographic variables (SEX, RACE, COUNTRY).", "authority": "CDISC", "standards": [ "sdtmig" @@ -1329,7 +1329,6 @@ "variables": [ "SEX", "RACE", - "ETHNIC", "COUNTRY" ] } @@ -1347,11 +1346,6 @@ "operator": "equal_to", "value": false }, - { - "name": "_pb_ETHNIC_present", - "operator": "equal_to", - "value": false - }, { "name": "_pb_COUNTRY_present", "operator": "equal_to", @@ -1362,7 +1356,7 @@ "actions": { "id": "generate_variable_error", "params": { - "message": "DM domain is missing one or more required demographic variables (SEX, RACE, ETHNIC, COUNTRY)." + "message": "DM domain is missing one or more required demographic variables (SEX, RACE, COUNTRY)." } } }, @@ -1652,7 +1646,7 @@ "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "AE domain must contain severity, seriousness, and outcome variables.", + "description": "AE domain must contain the seriousness variable (AESER).", "authority": "CDISC", "standards": [ "sdtmig" @@ -1669,36 +1663,24 @@ "operator": "has_required_variables", "params": { "variables": [ - "AESEV", - "AESER", - "AEOUT" + "AESER" ] } } ], "conditions": { "any": [ - { - "name": "_pb_AESEV_present", - "operator": "equal_to", - "value": false - }, { "name": "_pb_AESER_present", "operator": "equal_to", "value": false - }, - { - "name": "_pb_AEOUT_present", - "operator": "equal_to", - "value": false } ] }, "actions": { "id": "generate_variable_error", "params": { - "message": "AE domain must include AESEV (severity), AESER (serious flag), and AEOUT (outcome)." + "message": "AE domain must include AESER (serious flag)." } } }, @@ -4022,40 +4004,6 @@ } } }, - { - "core_id": "SDTM-088", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "AEBODSYS must not be null in AE.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Events" - ], - "domains": [ - "AE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "AEBODSYS", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "AEBODSYS must not be null in AE." - } - } - }, { "core_id": "SDTM-089", "rule_type": "RECORD_CHECK", @@ -5019,55 +4967,6 @@ } } }, - { - "core_id": "SDTM-111", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "CM domain must contain timing variables CMSTDTC and CMENDTC.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Interventions" - ], - "domains": [ - "CM" - ], - "datasets": [], - "operations": [ - { - "operator": "has_required_variables", - "params": { - "variables": [ - "CMSTDTC", - "CMENDTC" - ] - } - } - ], - "conditions": { - "any": [ - { - "name": "_pb_CMSTDTC_present", - "operator": "equal_to", - "value": false - }, - { - "name": "_pb_CMENDTC_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "CM domain is missing one or more required timing variables (CMSTDTC, CMENDTC)." - } - } - }, { "core_id": "SDTM-112", "rule_type": "VARIABLE_METADATA_CHECK", @@ -5916,40 +5815,6 @@ } } }, - { - "core_id": "SDTM-130", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VISIT must not be null in TV.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TV" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "VISIT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "VISIT must not be null in TV." - } - } - }, { "core_id": "SDTM-131", "rule_type": "RECORD_CHECK", @@ -6940,7 +6805,7 @@ "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "TA must contain required variables: STUDYID, DOMAIN, ARMCD, ARM, TAETORD, EPOCH, ELEMENT.", + "description": "TA must contain required variables: STUDYID, DOMAIN, ARMCD, ARM, TAETORD, EPOCH.", "authority": "CDISC", "standards": [ "sdtmig" @@ -6962,8 +6827,7 @@ "ARMCD", "ARM", "TAETORD", - "EPOCH", - "ELEMENT" + "EPOCH" ] } } @@ -6999,18 +6863,13 @@ "name": "_pb_EPOCH_present", "operator": "equal_to", "value": false - }, - { - "name": "_pb_ELEMENT_present", - "operator": "equal_to", - "value": false } ] }, "actions": { "id": "generate_variable_error", "params": { - "message": "TA is missing one or more required variables: STUDYID, DOMAIN, ARMCD, ARM, TAETORD, EPOCH, ELEMENT." + "message": "TA is missing one or more required variables: STUDYID, DOMAIN, ARMCD, ARM, TAETORD, EPOCH." } } }, @@ -7080,7 +6939,7 @@ "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "TV must contain required variables: STUDYID, DOMAIN, VISITNUM, VISIT.", + "description": "TV must contain required variables: STUDYID, DOMAIN, VISITNUM.", "authority": "CDISC", "standards": [ "sdtmig" @@ -7099,8 +6958,7 @@ "variables": [ "STUDYID", "DOMAIN", - "VISITNUM", - "VISIT" + "VISITNUM" ] } } @@ -7121,18 +6979,13 @@ "name": "_pb_VISITNUM_present", "operator": "equal_to", "value": false - }, - { - "name": "_pb_VISIT_present", - "operator": "equal_to", - "value": false } ] }, "actions": { "id": "generate_variable_error", "params": { - "message": "TV is missing one or more required variables: STUDYID, DOMAIN, VISITNUM, VISIT." + "message": "TV is missing one or more required variables: STUDYID, DOMAIN, VISITNUM." } } }, @@ -8476,40 +8329,6 @@ } } }, - { - "core_id": "SDTM-196", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "DMSEQ must not be null in the DM dataset.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Special-Purpose" - ], - "domains": [ - "DM" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "DMSEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "DMSEQ must not be null in DM." - } - } - }, { "core_id": "SDTM-197", "rule_type": "RECORD_CHECK", @@ -8698,40 +8517,6 @@ } } }, - { - "core_id": "SDTM-201", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "MHDECOD (dictionary-derived term) must not be null in MH.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Events" - ], - "domains": [ - "MH" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "MHDECOD", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "MHDECOD must not be null in MH." - } - } - }, { "core_id": "SDTM-202", "rule_type": "RECORD_CHECK", @@ -9046,40 +8831,6 @@ } } }, - { - "core_id": "SDTM-209", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "DSCAT (category) must not be null in the DS dataset.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Events" - ], - "domains": [ - "DS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "DSCAT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "DSCAT must not be null in DS." - } - } - }, { "core_id": "SDTM-210", "rule_type": "VARIABLE_METADATA_CHECK", @@ -9362,40 +9113,6 @@ } } }, - { - "core_id": "SDTM-217", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "TSVAL (parameter value) must not be null in the TS dataset.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TSVAL", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TSVAL must not be null in TS." - } - } - }, { "core_id": "SDTM-218", "rule_type": "VARIABLE_METADATA_CHECK", @@ -10189,61 +9906,20 @@ } }, { - "core_id": "SDTM-237", - "rule_type": "VARIABLE_METADATA_CHECK", + "core_id": "SDTM-238", + "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "MHSTDTC (start date/time of medical history event) must be present as a variable in the MH dataset.", + "description": "DOMAIN column value must equal 'TV' in the TV dataset.", "authority": "CDISC", "standards": [ "sdtmig" ], "classes": [ - "Events" + "Trial Design" ], "domains": [ - "MH" - ], - "datasets": [], - "operations": [ - { - "operator": "column_presence", - "params": { - "column": "MHSTDTC" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_MHSTDTC_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "MHSTDTC must be present in MH." - } - } - }, - { - "core_id": "SDTM-238", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "DOMAIN column value must equal 'TV' in the TV dataset.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TV" + "TV" ], "datasets": [], "operations": [], @@ -11021,74 +10697,6 @@ } } }, - { - "core_id": "SDTM-266", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VSORRES (original result) must not be null in VS.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "VS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "VSORRES", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "VSORRES must not be null in VS." - } - } - }, - { - "core_id": "SDTM-267", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "LBORRES (original result) must not be null in LB.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "LB" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "LBORRES", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "LBORRES must not be null in LB." - } - } - }, { "core_id": "SDTM-268", "rule_type": "RECORD_CHECK", @@ -12183,48 +11791,6 @@ } } }, - { - "core_id": "SDTM-297", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "SVSEQ must be a numeric variable in SV.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "SV" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "SVSEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_SVSEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "SVSEQ must be a numeric variable in SV." - } - } - }, { "core_id": "SDTM-298", "rule_type": "VARIABLE_METADATA_CHECK", @@ -12403,40 +11969,6 @@ } } }, - { - "core_id": "SDTM-303", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "AEBODSYS (body system or organ class) must not be null in AE.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Events" - ], - "domains": [ - "AE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "AEBODSYS", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "AEBODSYS must not be null in AE." - } - } - }, { "core_id": "SDTM-304", "rule_type": "RECORD_CHECK", @@ -12471,40 +12003,6 @@ } } }, - { - "core_id": "SDTM-305", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "CMDECOD (standardized medication name) must not be null in CM.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Interventions" - ], - "domains": [ - "CM" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "CMDECOD", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "CMDECOD must not be null in CM." - } - } - }, { "core_id": "SDTM-306", "rule_type": "RECORD_CHECK", @@ -12642,27 +12140,27 @@ } }, { - "core_id": "SDTM-310", + "core_id": "SDTM-313", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "EXDOSE (dose per administration) must not be null in EX.", + "description": "EGSTRESC (standardized result in character format) must not be null in EG.", "authority": "CDISC", "standards": [ "sdtmig" ], "classes": [ - "Interventions" + "Findings" ], "domains": [ - "EX" + "EG" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "EXDOSE", + "name": "EGSTRESC", "operator": "is_null", "value": null } @@ -12671,16 +12169,16 @@ "actions": { "id": "generate_record_error", "params": { - "message": "EXDOSE must not be null in EX." + "message": "EGSTRESC must not be null in EG." } } }, { - "core_id": "SDTM-311", + "core_id": "SDTM-314", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "VSSTRESC (standardized result in character format) must not be null in VS.", + "description": "PESTRESC (standardized result in character format) must not be null in PE.", "authority": "CDISC", "standards": [ "sdtmig" @@ -12689,14 +12187,14 @@ "Findings" ], "domains": [ - "VS" + "PE" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "VSSTRESC", + "name": "PESTRESC", "operator": "is_null", "value": null } @@ -12705,16 +12203,16 @@ "actions": { "id": "generate_record_error", "params": { - "message": "VSSTRESC must not be null in VS." + "message": "PESTRESC must not be null in PE." } } }, { - "core_id": "SDTM-312", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-315", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "LBSTRESC (standardized result in character format) must not be null in LB.", + "description": "VSSTRESU column must be present in VS.", "authority": "CDISC", "standards": [ "sdtmig" @@ -12723,32 +12221,39 @@ "Findings" ], "domains": [ - "LB" + "VS" ], "datasets": [], - "operations": [], + "operations": [ + { + "operator": "column_presence", + "params": { + "column": "VSSTRESU" + } + } + ], "conditions": { "all": [ { - "name": "LBSTRESC", - "operator": "is_null", - "value": null + "name": "_pb_VSSTRESU_present", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "LBSTRESC must not be null in LB." + "message": "VSSTRESU must be present in VS." } } }, { - "core_id": "SDTM-313", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-316", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "EGSTRESC (standardized result in character format) must not be null in EG.", + "description": "LBSTRESU column must be present in LB.", "authority": "CDISC", "standards": [ "sdtmig" @@ -12757,137 +12262,28 @@ "Findings" ], "domains": [ - "EG" + "LB" ], "datasets": [], - "operations": [], + "operations": [ + { + "operator": "column_presence", + "params": { + "column": "LBSTRESU" + } + } + ], "conditions": { "all": [ { - "name": "EGSTRESC", - "operator": "is_null", - "value": null + "name": "_pb_LBSTRESU_present", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", - "params": { - "message": "EGSTRESC must not be null in EG." - } - } - }, - { - "core_id": "SDTM-314", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "PESTRESC (standardized result in character format) must not be null in PE.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "PE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "PESTRESC", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "PESTRESC must not be null in PE." - } - } - }, - { - "core_id": "SDTM-315", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VSSTRESU column must be present in VS.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "VS" - ], - "datasets": [], - "operations": [ - { - "operator": "column_presence", - "params": { - "column": "VSSTRESU" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_VSSTRESU_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "VSSTRESU must be present in VS." - } - } - }, - { - "core_id": "SDTM-316", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "LBSTRESU column must be present in LB.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "LB" - ], - "datasets": [], - "operations": [ - { - "operator": "column_presence", - "params": { - "column": "LBSTRESU" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_LBSTRESU_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", + "id": "generate_variable_error", "params": { "message": "LBSTRESU must be present in LB." } @@ -13128,108 +12524,6 @@ } } }, - { - "core_id": "SDTM-323", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "ELEMENT (trial element name) must not be null in TA.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TA" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "ELEMENT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "ELEMENT must not be null in TA." - } - } - }, - { - "core_id": "SDTM-324", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "TEENRL (trial element end rule) must not be null in TE.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TEENRL", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TEENRL must not be null in TE." - } - } - }, - { - "core_id": "SDTM-325", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VISIT (visit description) must not be null in TV.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "TV" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "VISIT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "VISIT must not be null in TV." - } - } - }, { "core_id": "SDTM-328", "rule_type": "RECORD_CHECK", @@ -13366,40 +12660,6 @@ } } }, - { - "core_id": "SDTM-332", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VISIT must not be null in SV.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Trial Design" - ], - "domains": [ - "SV" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "VISIT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "VISIT must not be null in SV." - } - } - }, { "core_id": "SDTM-333", "rule_type": "RECORD_CHECK", @@ -13493,11 +12753,11 @@ } }, { - "core_id": "SDTM-336", + "core_id": "SDTM-337", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "VISITNUM must not be null in LB.", + "description": "VISITNUM must not be null in EG.", "authority": "CDISC", "standards": [ "sdtmig" @@ -13506,7 +12766,7 @@ "Findings" ], "domains": [ - "LB" + "EG" ], "datasets": [], "operations": [], @@ -13522,16 +12782,16 @@ "actions": { "id": "generate_record_error", "params": { - "message": "VISITNUM must not be null in LB." + "message": "VISITNUM must not be null in EG." } } }, { - "core_id": "SDTM-337", + "core_id": "SDTM-338", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "VISITNUM must not be null in EG.", + "description": "VISITNUM must not be null in PE.", "authority": "CDISC", "standards": [ "sdtmig" @@ -13540,7 +12800,7 @@ "Findings" ], "domains": [ - "EG" + "PE" ], "datasets": [], "operations": [], @@ -13556,50 +12816,16 @@ "actions": { "id": "generate_record_error", "params": { - "message": "VISITNUM must not be null in EG." + "message": "VISITNUM must not be null in PE." } } }, { - "core_id": "SDTM-338", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-339", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", - "description": "VISITNUM must not be null in PE.", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "classes": [ - "Findings" - ], - "domains": [ - "PE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "VISITNUM", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "VISITNUM must not be null in PE." - } - } - }, - { - "core_id": "SDTM-339", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "description": "VISITNUM must be numeric type in VS.", + "description": "VISITNUM must be numeric type in VS.", "authority": "CDISC", "standards": [ "sdtmig" @@ -14844,88 +14070,6 @@ } } }, - { - "core_id": "SDTM-372", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "CMROUTE (route of administration) column must be present in the CM domain.", - "classes": [ - "Interventions" - ], - "domains": [ - "CM" - ], - "datasets": [], - "operations": [ - { - "operator": "column_presence", - "params": { - "column": "CMROUTE" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_CMROUTE_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "CMROUTE must be present in CM." - } - } - }, - { - "core_id": "SDTM-373", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "EXROUTE (route of administration) column must be present in the EX domain.", - "classes": [ - "Interventions" - ], - "domains": [ - "EX" - ], - "datasets": [], - "operations": [ - { - "operator": "column_presence", - "params": { - "column": "EXROUTE" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_EXROUTE_present", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "EXROUTE must be present in EX." - } - } - }, { "core_id": "SDTM-374", "rule_type": "VARIABLE_METADATA_CHECK", @@ -14967,74 +14111,6 @@ } } }, - { - "core_id": "SDTM-375", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "LBSPEC must not be null in LB; specimen type is required for each lab result record.", - "classes": [ - "Findings" - ], - "domains": [ - "LB" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "LBSPEC", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "LBSPEC must not be null in LB." - } - } - }, - { - "core_id": "SDTM-376", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "AESER must not be null in AE; the serious adverse event flag is required for each AE record.", - "classes": [ - "Events" - ], - "domains": [ - "AE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "AESER", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "AESER must not be null in AE." - } - } - }, { "core_id": "SDTM-377", "rule_type": "VARIABLE_METADATA_CHECK", @@ -15374,7 +14450,7 @@ } }, { - "core_id": "SDTM-386", + "core_id": "SDTM-394", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", @@ -15382,19 +14458,19 @@ "standards": [ "sdtmig" ], - "description": "IDVAR must not be null in SUPPDM; the linking variable name is required to connect supplemental records to the parent dataset.", + "description": "TSPARM must not be null in TS; the parameter name is required for every trial summary record.", "classes": [ - "Relationship" + "Trial Design" ], "domains": [ - "SUPPDM" + "TS" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "IDVAR", + "name": "TSPARM", "operator": "is_null", "value": null } @@ -15403,12 +14479,12 @@ "actions": { "id": "generate_record_error", "params": { - "message": "IDVAR must not be null in SUPPDM." + "message": "TSPARM must not be null in TS." } } }, { - "core_id": "SDTM-387", + "core_id": "SDTM-395", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", @@ -15416,19 +14492,19 @@ "standards": [ "sdtmig" ], - "description": "IDVARVAL must not be null in SUPPDM; the linking variable value is required to connect supplemental records to the parent dataset.", + "description": "IECAT must not be null in TI; the inclusion/exclusion category is required for each criterion record.", "classes": [ - "Relationship" + "Trial Design" ], "domains": [ - "SUPPDM" + "TI" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "IDVARVAL", + "name": "IECAT", "operator": "is_null", "value": null } @@ -15437,12 +14513,12 @@ "actions": { "id": "generate_record_error", "params": { - "message": "IDVARVAL must not be null in SUPPDM." + "message": "IECAT must not be null in TI." } } }, { - "core_id": "SDTM-388", + "core_id": "SDTM-396", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", @@ -15450,19 +14526,19 @@ "standards": [ "sdtmig" ], - "description": "IDVAR must not be null in SUPPAE; the linking variable name is required to connect supplemental records to the parent AE dataset.", + "description": "ARMCD must not be null in TA; the arm code is required for every trial arm record.", "classes": [ - "Relationship" + "Trial Design" ], "domains": [ - "SUPPAE" + "TA" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "IDVAR", + "name": "ARMCD", "operator": "is_null", "value": null } @@ -15471,12 +14547,12 @@ "actions": { "id": "generate_record_error", "params": { - "message": "IDVAR must not be null in SUPPAE." + "message": "ARMCD must not be null in TA." } } }, { - "core_id": "SDTM-389", + "core_id": "SDTM-397", "rule_type": "RECORD_CHECK", "executability": "Fully Executable", "sensitivity": "Error", @@ -15484,19 +14560,19 @@ "standards": [ "sdtmig" ], - "description": "IDVARVAL must not be null in SUPPAE; the linking variable value is required to connect supplemental records to the parent AE dataset.", + "description": "TAETORD must not be null in TA; the planned element order within the arm is required.", "classes": [ - "Relationship" + "Trial Design" ], "domains": [ - "SUPPAE" + "TA" ], "datasets": [], "operations": [], "conditions": { "all": [ { - "name": "IDVARVAL", + "name": "TAETORD", "operator": "is_null", "value": null } @@ -15505,1141 +14581,259 @@ "actions": { "id": "generate_record_error", "params": { - "message": "IDVARVAL must not be null in SUPPAE." + "message": "TAETORD must not be null in TA." } } }, { - "core_id": "SDTM-390", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-407", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "IDVAR must not be null in SUPPLB; the linking variable name is required to connect supplemental records to the parent LB dataset.", + "description": "PESEQ in PE must be a numeric type variable.", "classes": [ - "Relationship" + "Findings" ], "domains": [ - "SUPPLB" + "PE" ], "datasets": [], - "operations": [], + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "PESEQ", + "expected_type": "numeric" + } + } + ], "conditions": { "all": [ { - "name": "IDVAR", - "operator": "is_null", - "value": null + "name": "_pb_PESEQ_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "IDVAR must not be null in SUPPLB." + "message": "PESEQ must be numeric in PE." } } }, { - "core_id": "SDTM-391", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-408", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "IDVARVAL must not be null in SUPPLB; the linking variable value is required to connect supplemental records to the parent LB dataset.", + "description": "IESEQ in IE must be a numeric type variable.", "classes": [ - "Relationship" + "Special-Purpose" ], "domains": [ - "SUPPLB" + "IE" ], "datasets": [], - "operations": [], + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "IESEQ", + "expected_type": "numeric" + } + } + ], "conditions": { "all": [ { - "name": "IDVARVAL", - "operator": "is_null", - "value": null + "name": "_pb_IESEQ_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "IDVARVAL must not be null in SUPPLB." + "message": "IESEQ must be numeric in IE." } } }, { - "core_id": "SDTM-392", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-409", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "IDVAR must not be null in SUPPVS; the linking variable name is required to connect supplemental records to the parent VS dataset.", + "description": "PEENDY in PE must be a numeric type variable.", "classes": [ - "Relationship" + "Findings" ], "domains": [ - "SUPPVS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "IDVAR", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "IDVAR must not be null in SUPPVS." - } - } - }, - { - "core_id": "SDTM-393", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IDVARVAL must not be null in SUPPVS; the linking variable value is required to connect supplemental records to the parent VS dataset.", - "classes": [ - "Relationship" - ], - "domains": [ - "SUPPVS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "IDVARVAL", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "IDVARVAL must not be null in SUPPVS." - } - } - }, - { - "core_id": "SDTM-394", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TSPARM must not be null in TS; the parameter name is required for every trial summary record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TS" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TSPARM", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TSPARM must not be null in TS." - } - } - }, - { - "core_id": "SDTM-395", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IECAT must not be null in TI; the inclusion/exclusion category is required for each criterion record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TI" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "IECAT", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "IECAT must not be null in TI." - } - } - }, - { - "core_id": "SDTM-396", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "ARMCD must not be null in TA; the arm code is required for every trial arm record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TA" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "ARMCD", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "ARMCD must not be null in TA." - } - } - }, - { - "core_id": "SDTM-397", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TAETORD must not be null in TA; the planned element order within the arm is required.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TA" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TAETORD", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TAETORD must not be null in TA." - } - } - }, - { - "core_id": "SDTM-398", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TVSEQ must not be null in TV; the sequence number is required for every trial visit record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TV" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TVSEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TVSEQ must not be null in TV." - } - } - }, - { - "core_id": "SDTM-399", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TVSEQ in TV must be a numeric type variable.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TV" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "TVSEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_TVSEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "TVSEQ must be numeric in TV." - } - } - }, - { - "core_id": "SDTM-400", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TISEQ must not be null in TI; the sequence number is required for every trial inclusion/exclusion criteria record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TI" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TISEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TISEQ must not be null in TI." - } - } - }, - { - "core_id": "SDTM-401", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TISEQ in TI must be a numeric type variable.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TI" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "TISEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_TISEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "TISEQ must be numeric in TI." - } - } - }, - { - "core_id": "SDTM-402", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TASEQ must not be null in TA; the sequence number is required for every trial arm record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TA" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TASEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TASEQ must not be null in TA." - } - } - }, - { - "core_id": "SDTM-403", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TASEQ in TA must be a numeric type variable.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TA" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "TASEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_TASEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "TASEQ must be numeric in TA." - } - } - }, - { - "core_id": "SDTM-404", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TESEQ must not be null in TE; the sequence number is required for every trial element record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TE" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "TESEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "TESEQ must not be null in TE." - } - } - }, - { - "core_id": "SDTM-405", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "TESEQ in TE must be a numeric type variable.", - "classes": [ - "Trial Design" - ], - "domains": [ - "TE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "TESEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_TESEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "TESEQ must be numeric in TE." - } - } - }, - { - "core_id": "SDTM-406", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "SVSEQ must not be null in SV; the sequence number is required for every subject visit record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "SV" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "SVSEQ", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "SVSEQ must not be null in SV." - } - } - }, - { - "core_id": "SDTM-407", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "PESEQ in PE must be a numeric type variable.", - "classes": [ - "Findings" - ], - "domains": [ - "PE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "PESEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_PESEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "PESEQ must be numeric in PE." - } - } - }, - { - "core_id": "SDTM-408", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IESEQ in IE must be a numeric type variable.", - "classes": [ - "Special-Purpose" - ], - "domains": [ - "IE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "IESEQ", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_IESEQ_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "IESEQ must be numeric in IE." - } - } - }, - { - "core_id": "SDTM-409", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "PEENDY in PE must be a numeric type variable.", - "classes": [ - "Findings" - ], - "domains": [ - "PE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "PEENDY", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_PEENDY_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "PEENDY must be numeric in PE." - } - } - }, - { - "core_id": "SDTM-410", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IESTDY in IE must be a numeric type variable.", - "classes": [ - "Special-Purpose" - ], - "domains": [ - "IE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "IESTDY", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_IESTDY_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "IESTDY must be numeric in IE." - } - } - }, - { - "core_id": "SDTM-411", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IEENDY in IE must be a numeric type variable.", - "classes": [ - "Special-Purpose" - ], - "domains": [ - "IE" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "IEENDY", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_IEENDY_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "IEENDY must be numeric in IE." - } - } - }, - { - "core_id": "SDTM-412", - "rule_type": "VARIABLE_METADATA_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "DSENDY in DS must be a numeric type variable.", - "classes": [ - "Events" - ], - "domains": [ - "DS" - ], - "datasets": [], - "operations": [ - { - "operator": "variable_type_check", - "params": { - "column": "DSENDY", - "expected_type": "numeric" - } - } - ], - "conditions": { - "all": [ - { - "name": "_pb_DSENDY_type_valid", - "operator": "equal_to", - "value": false - } - ] - }, - "actions": { - "id": "generate_variable_error", - "params": { - "message": "DSENDY must be numeric in DS." - } - } - }, - { - "core_id": "SDTM-413", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "EXDOSFRM must not be null in EX; the dose form is required for each exposure record.", - "classes": [ - "Interventions" - ], - "domains": [ - "EX" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "EXDOSFRM", - "operator": "is_null", - "value": null + "PE" + ], + "datasets": [], + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "PEENDY", + "expected_type": "numeric" } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "EXDOSFRM must not be null in EX." } - } - }, - { - "core_id": "SDTM-414", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "EXROUTE must not be null in EX; the route of administration is required for each exposure record.", - "classes": [ - "Interventions" - ], - "domains": [ - "EX" ], - "datasets": [], - "operations": [], "conditions": { "all": [ { - "name": "EXROUTE", - "operator": "is_null", - "value": null + "name": "_pb_PEENDY_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "EXROUTE must not be null in EX." + "message": "PEENDY must be numeric in PE." } } }, { - "core_id": "SDTM-415", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-410", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "CMROUTE must not be null in CM; the route of administration is required for each concomitant medication record.", + "description": "IESTDY in IE must be a numeric type variable.", "classes": [ - "Interventions" + "Special-Purpose" ], "domains": [ - "CM" + "IE" ], "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "CMROUTE", - "operator": "is_null", - "value": null + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "IESTDY", + "expected_type": "numeric" } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "CMROUTE must not be null in CM." } - } - }, - { - "core_id": "SDTM-416", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "AEACN must not be null in AE; the action taken with study treatment is required for each adverse event record.", - "classes": [ - "Events" - ], - "domains": [ - "AE" ], - "datasets": [], - "operations": [], "conditions": { "all": [ { - "name": "AEACN", - "operator": "is_null", - "value": null + "name": "_pb_IESTDY_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "AEACN must not be null in AE." + "message": "IESTDY must be numeric in IE." } } }, { - "core_id": "SDTM-417", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-411", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "AESTDTC must not be null in AE; the adverse event start date/time is required.", + "description": "IEENDY in IE must be a numeric type variable.", "classes": [ - "Events" + "Special-Purpose" ], "domains": [ - "AE" + "IE" ], "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "AESTDTC", - "operator": "is_null", - "value": null + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "IEENDY", + "expected_type": "numeric" } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "AESTDTC must not be null in AE." } - } - }, - { - "core_id": "SDTM-418", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "DSSTDTC must not be null in DS; the disposition date/time is required for each disposition record.", - "classes": [ - "Events" - ], - "domains": [ - "DS" ], - "datasets": [], - "operations": [], "conditions": { "all": [ { - "name": "DSSTDTC", - "operator": "is_null", - "value": null + "name": "_pb_IEENDY_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "DSSTDTC must not be null in DS." + "message": "IEENDY must be numeric in IE." } } }, { - "core_id": "SDTM-419", - "rule_type": "RECORD_CHECK", + "core_id": "SDTM-412", + "rule_type": "VARIABLE_METADATA_CHECK", "executability": "Fully Executable", "sensitivity": "Error", "authority": "CDISC", "standards": [ "sdtmig" ], - "description": "EXSTDTC must not be null in EX; the exposure start date/time is required for each exposure record.", + "description": "DSENDY in DS must be a numeric type variable.", "classes": [ - "Interventions" + "Events" ], "domains": [ - "EX" + "DS" ], "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "EXSTDTC", - "operator": "is_null", - "value": null + "operations": [ + { + "operator": "variable_type_check", + "params": { + "column": "DSENDY", + "expected_type": "numeric" } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "EXSTDTC must not be null in EX." } - } - }, - { - "core_id": "SDTM-420", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "SVSTDTC must not be null in SV; the subject visit start date/time is required for each subject visit record.", - "classes": [ - "Trial Design" - ], - "domains": [ - "SV" ], - "datasets": [], - "operations": [], "conditions": { "all": [ { - "name": "SVSTDTC", - "operator": "is_null", - "value": null + "name": "_pb_DSENDY_type_valid", + "operator": "equal_to", + "value": false } ] }, "actions": { - "id": "generate_record_error", + "id": "generate_variable_error", "params": { - "message": "SVSTDTC must not be null in SV." + "message": "DSENDY must be numeric in DS." } } }, @@ -16955,74 +15149,6 @@ } } }, - { - "core_id": "SDTM-429", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IDVAR must not be null in SUPPEG; the identifier variable name is required to link each supplemental qualifier record back to its parent EG record.", - "classes": [ - "Relationship" - ], - "domains": [ - "SUPPEG" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "IDVAR", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "IDVAR must not be null in SUPPEG." - } - } - }, - { - "core_id": "SDTM-430", - "rule_type": "RECORD_CHECK", - "executability": "Fully Executable", - "sensitivity": "Error", - "authority": "CDISC", - "standards": [ - "sdtmig" - ], - "description": "IDVARVAL must not be null in SUPPEG; the identifier variable value is required to link each supplemental qualifier record back to its parent EG record.", - "classes": [ - "Relationship" - ], - "domains": [ - "SUPPEG" - ], - "datasets": [], - "operations": [], - "conditions": { - "all": [ - { - "name": "IDVARVAL", - "operator": "is_null", - "value": null - } - ] - }, - "actions": { - "id": "generate_record_error", - "params": { - "message": "IDVARVAL must not be null in SUPPEG." - } - } - }, { "core_id": "SDTM-432", "rule_type": "RECORD_CHECK", diff --git a/pointblank/metadata/_submission.py b/pointblank/metadata/_submission.py index 99c9ac5a9..86d6b956a 100644 --- a/pointblank/metadata/_submission.py +++ b/pointblank/metadata/_submission.py @@ -2049,7 +2049,7 @@ def validate_sdtmig( ) -> ConformanceReport: """Validate SDTM datasets against the SDTMIG rule catalog and return a conformance report. - Runs the bundled SDTMIG 3.4 rule catalog (414 rules) against the provided SDTM domain + Runs the bundled SDTMIG 3.4 rule catalog (362 rules) against the provided SDTM domain datasets using Pointblank's built-in conformance engine. No external tools, subprocesses, network calls, or CDISC CORE installation are required. diff --git a/tests/metadata_fixtures/sdtmig_3_4_core.tsv b/tests/metadata_fixtures/sdtmig_3_4_core.tsv new file mode 100644 index 000000000..f4427dada --- /dev/null +++ b/tests/metadata_fixtures/sdtmig_3_4_core.tsv @@ -0,0 +1,499 @@ +# SDTMIG 3.4 core designations (Req/Exp/Perm) of the variables in the domains listed; +# from trialforge's variables.tsv, checked against 49 known designations (BUGS.md #45) +dataset variable core +AE AEACN Exp +AE AEBODSYS Exp +AE AECONTRT Perm +AE AEDECOD Req +AE AEENDTC Exp +AE AEENDY Perm +AE AEENRTPT Perm +AE AEENTPT Perm +AE AEOUT Perm +AE AEREL Exp +AE AESCONG Perm +AE AESDISAB Perm +AE AESDTH Perm +AE AESEQ Req +AE AESER Exp +AE AESEV Perm +AE AESHOSP Perm +AE AESLIFE Perm +AE AESMIE Perm +AE AESOC Exp +AE AESTDTC Exp +AE AESTDY Perm +AE AETERM Req +AE DOMAIN Req +AE EPOCH Perm +AE STUDYID Req +AE USUBJID Req +CE CEBODSYS Perm +CE CECAT Perm +CE CEDECOD Perm +CE CEENDTC Perm +CE CEENDY Perm +CE CEEVINTX Perm +CE CELAT Perm +CE CELNKGRP Perm +CE CELOC Perm +CE CEOCCUR Perm +CE CEOUT Perm +CE CEPRESP Perm +CE CEREL Perm +CE CERFTDTC Perm +CE CESCAT Perm +CE CESEQ Req +CE CESEV Perm +CE CESTDTC Exp +CE CESTDY Perm +CE CETERM Req +CE CETPT Perm +CE CETPTNUM Perm +CE CETPTREF Perm +CE DOMAIN Req +CE EPOCH Perm +CE STUDYID Req +CE USUBJID Req +CM CMCLAS Perm +CM CMDECOD Perm +CM CMDOSE Perm +CM CMDOSFRQ Perm +CM CMDOSU Perm +CM CMENDTC Perm +CM CMENDY Perm +CM CMENRTPT Perm +CM CMENTPT Perm +CM CMINDC Perm +CM CMROUTE Perm +CM CMSEQ Req +CM CMSTDTC Perm +CM CMSTDY Perm +CM CMTRT Req +CM DOMAIN Req +CM EPOCH Perm +CM STUDYID Req +CM USUBJID Req +DM ACTARM Exp +DM ACTARMCD Exp +DM AGE Exp +DM AGEU Exp +DM ARM Exp +DM ARMCD Exp +DM BRTHDTC Perm +DM COUNTRY Req +DM DMDTC Perm +DM DMDY Perm +DM DOMAIN Req +DM DTHDTC Exp +DM DTHFL Exp +DM ETHNIC Perm +DM RACE Exp +DM RFENDTC Exp +DM RFICDTC Exp +DM RFPENDTC Exp +DM RFSTDTC Exp +DM RFXENDTC Exp +DM RFXSTDTC Exp +DM SEX Req +DM SITEID Req +DM STUDYID Req +DM SUBJID Req +DM USUBJID Req +DS DOMAIN Req +DS DSCAT Exp +DS DSDECOD Req +DS DSSCAT Perm +DS DSSEQ Req +DS DSSTDTC Exp +DS DSSTDY Perm +DS DSTERM Req +DS EPOCH Perm +DS STUDYID Req +DS USUBJID Req +EX DOMAIN Req +EX EPOCH Perm +EX EXDOSE Exp +EX EXDOSFRM Exp +EX EXDOSFRQ Perm +EX EXDOSU Exp +EX EXENDTC Exp +EX EXENDY Perm +EX EXLAT Perm +EX EXLNKGRP Perm +EX EXLNKID Perm +EX EXLOC Perm +EX EXROUTE Perm +EX EXSEQ Req +EX EXSTDTC Exp +EX EXSTDY Perm +EX EXTRT Req +EX STUDYID Req +EX USUBJID Req +EX VISIT Perm +EX VISITDY Perm +EX VISITNUM Perm +FACE DOMAIN Req +FACE EPOCH Perm +FACE FACAT Perm +FACE FADTC Perm +FACE FADY Perm +FACE FAEVAL Perm +FACE FALAT Perm +FACE FALNKGRP Perm +FACE FALNKID Perm +FACE FALOC Perm +FACE FAOBJ Req +FACE FAORRES Exp +FACE FAORRESU Perm +FACE FARFTDTC Perm +FACE FASCAT Perm +FACE FASEQ Req +FACE FASTRESC Exp +FACE FASTRESN Perm +FACE FASTRESU Perm +FACE FATEST Req +FACE FATESTCD Req +FACE FATPT Perm +FACE FATPTNUM Perm +FACE FATPTREF Perm +FACE STUDYID Req +FACE USUBJID Req +FT DOMAIN Req +FT EPOCH Perm +FT FTCAT Exp +FT FTDTC Exp +FT FTDY Perm +FT FTLOBXFL Exp +FT FTORRES Exp +FT FTREASND Perm +FT FTSEQ Req +FT FTSTAT Perm +FT FTSTRESC Exp +FT FTSTRESN Exp +FT FTTEST Req +FT FTTESTCD Req +FT STUDYID Req +FT USUBJID Req +FT VISIT Perm +FT VISITDY Perm +FT VISITNUM Exp +IS DOMAIN Req +IS EPOCH Perm +IS ISBDAGNT Perm +IS ISBLFL Perm +IS ISCAT Perm +IS ISDTC Exp +IS ISDY Perm +IS ISLLOQ Perm +IS ISLOBXFL Exp +IS ISMETHOD Perm +IS ISORRES Exp +IS ISORRESU Exp +IS ISSEQ Req +IS ISSPEC Perm +IS ISSTRESC Exp +IS ISSTRESN Exp +IS ISSTRESU Exp +IS ISTEST Req +IS ISTESTCD Req +IS ISULOQ Perm +IS STUDYID Req +IS USUBJID Req +IS VISIT Perm +IS VISITDY Perm +IS VISITNUM Exp +LB DOMAIN Req +LB EPOCH Perm +LB LBBLFL Perm +LB LBCAT Exp +LB LBDTC Exp +LB LBDY Perm +LB LBLOBXFL Exp +LB LBNRIND Exp +LB LBORNRHI Exp +LB LBORNRLO Exp +LB LBORRES Exp +LB LBORRESU Exp +LB LBSEQ Req +LB LBSPEC Perm +LB LBSTNRHI Exp +LB LBSTNRLO Exp +LB LBSTRESC Exp +LB LBSTRESN Exp +LB LBSTRESU Exp +LB LBTEST Req +LB LBTESTCD Req +LB STUDYID Req +LB USUBJID Req +LB VISIT Perm +LB VISITDY Perm +LB VISITNUM Exp +MH DOMAIN Req +MH MHBODSYS Perm +MH MHCAT Perm +MH MHDECOD Perm +MH MHENDTC Perm +MH MHENRTPT Perm +MH MHENTPT Perm +MH MHSEQ Req +MH MHSTDTC Perm +MH MHTERM Req +MH STUDYID Req +MH USUBJID Req +OE DOMAIN Req +OE EPOCH Perm +OE FOCID Perm +OE OECAT Perm +OE OEDTC Exp +OE OEDY Perm +OE OELAT Exp +OE OELOBXFL Exp +OE OELOC Perm +OE OEMETHOD Perm +OE OEORRES Exp +OE OEORRESU Perm +OE OESEQ Req +OE OESTRESC Exp +OE OESTRESN Perm +OE OESTRESU Perm +OE OETEST Req +OE OETESTCD Req +OE OETSTDTL Perm +OE STUDYID Req +OE USUBJID Req +OE VISIT Perm +OE VISITDY Perm +OE VISITNUM Exp +PC DOMAIN Req +PC EPOCH Perm +PC PCDTC Exp +PC PCDY Perm +PC PCELTM Perm +PC PCLLOQ Exp +PC PCNAM Exp +PC PCORRES Exp +PC PCORRESU Exp +PC PCRFTDTC Perm +PC PCSEQ Req +PC PCSPEC Req +PC PCSTRESC Exp +PC PCSTRESN Exp +PC PCSTRESU Exp +PC PCTEST Req +PC PCTESTCD Req +PC PCTPT Perm +PC PCTPTNUM Perm +PC PCTPTREF Perm +PC STUDYID Req +PC USUBJID Req +PC VISIT Perm +PC VISITDY Perm +PC VISITNUM Exp +PP DOMAIN Req +PP PPCAT Exp +PP PPENINT Perm +PP PPORRES Exp +PP PPORRESU Exp +PP PPRFTDTC Exp +PP PPSEQ Req +PP PPSPEC Exp +PP PPSTINT Perm +PP PPSTRESC Exp +PP PPSTRESN Exp +PP PPSTRESU Exp +PP PPTEST Req +PP PPTESTCD Req +PP STUDYID Req +PP USUBJID Req +RE DOMAIN Req +RE EPOCH Perm +RE REDTC Exp +RE REDY Perm +RE RELOBXFL Exp +RE REMETHOD Perm +RE REORRES Exp +RE REORRESU Exp +RE RESEQ Req +RE RESTRESC Exp +RE RESTRESN Exp +RE RESTRESU Exp +RE RETEST Req +RE RETESTCD Req +RE STUDYID Req +RE USUBJID Req +RE VISIT Perm +RE VISITDY Perm +RE VISITNUM Exp +RS DOMAIN Req +RS EPOCH Perm +RS RSCAT Exp +RS RSDTC Exp +RS RSDY Perm +RS RSEVAL Exp +RS RSLNKGRP Perm +RS RSORRES Exp +RS RSSCAT Perm +RS RSSEQ Req +RS RSSTRESC Exp +RS RSTEST Req +RS RSTESTCD Req +RS STUDYID Req +RS USUBJID Req +RS VISIT Perm +RS VISITNUM Exp +SC DOMAIN Req +SC EPOCH Perm +SC SCCAT Perm +SC SCDTC Perm +SC SCDY Perm +SC SCORRES Exp +SC SCSEQ Req +SC SCSTRESC Exp +SC SCTEST Req +SC SCTESTCD Req +SC STUDYID Req +SC USUBJID Req +SE DOMAIN Req +SE ELEMENT Perm +SE EPOCH Perm +SE ETCD Req +SE SEENDTC Exp +SE SEENDY Perm +SE SESEQ Req +SE SESTDTC Req +SE SESTDY Perm +SE STUDYID Req +SE TAETORD Perm +SE USUBJID Req +SUPPAE IDVAR Exp +SUPPAE IDVARVAL Exp +SUPPAE QEVAL Exp +SUPPAE QLABEL Req +SUPPAE QNAM Req +SUPPAE QORIG Req +SUPPAE QVAL Req +SUPPAE RDOMAIN Req +SUPPAE STUDYID Req +SUPPAE USUBJID Req +SV DOMAIN Req +SV EPOCH Perm +SV STUDYID Req +SV SVENDTC Exp +SV SVENDY Perm +SV SVSTDTC Exp +SV SVSTDY Perm +SV USUBJID Req +SV VISIT Perm +SV VISITDY Perm +SV VISITNUM Req +TA ARM Req +TA ARMCD Req +TA DOMAIN Req +TA ELEMENT Perm +TA EPOCH Req +TA ETCD Req +TA STUDYID Req +TA TABRANCH Exp +TA TAETORD Req +TA TATRANS Exp +TE DOMAIN Req +TE ELEMENT Req +TE ETCD Req +TE STUDYID Req +TE TEDUR Perm +TE TEENRL Perm +TE TESTRL Req +TI DOMAIN Req +TI IECAT Req +TI IETEST Req +TI IETESTCD Req +TI STUDYID Req +TI TIVERS Perm +TR DOMAIN Req +TR EPOCH Perm +TR STUDYID Req +TR TRDTC Exp +TR TRDY Perm +TR TREVAL Perm +TR TRGRPID Perm +TR TRLNKGRP Perm +TR TRLNKID Exp +TR TRMETHOD Exp +TR TRORRES Exp +TR TRORRESU Exp +TR TRREASND Perm +TR TRSEQ Req +TR TRSTAT Perm +TR TRSTRESC Exp +TR TRSTRESN Exp +TR TRSTRESU Exp +TR TRTEST Req +TR TRTESTCD Req +TR USUBJID Req +TR VISIT Perm +TR VISITNUM Exp +TS DOMAIN Req +TS STUDYID Req +TS TSPARM Req +TS TSPARMCD Req +TS TSSEQ Req +TS TSVAL Exp +TS TSVALCD Exp +TS TSVALNF Perm +TS TSVCDREF Exp +TS TSVCDVER Exp +TU DOMAIN Req +TU EPOCH Perm +TU STUDYID Req +TU TUDTC Exp +TU TUDY Perm +TU TUEVAL Perm +TU TULAT Perm +TU TULNKID Exp +TU TULOC Exp +TU TUMETHOD Exp +TU TUORRES Exp +TU TUSEQ Req +TU TUSTRESC Exp +TU TUTEST Req +TU TUTESTCD Req +TU USUBJID Req +TU VISIT Perm +TU VISITNUM Exp +TV ARM Perm +TV ARMCD Exp +TV DOMAIN Req +TV STUDYID Req +TV TVENRL Perm +TV TVSTRL Req +TV VISIT Perm +TV VISITDY Perm +TV VISITNUM Req +VS DOMAIN Req +VS EPOCH Perm +VS STUDYID Req +VS USUBJID Req +VS VISIT Perm +VS VISITDY Perm +VS VISITNUM Exp +VS VSBLFL Perm +VS VSCAT Perm +VS VSDTC Exp +VS VSDY Perm +VS VSEVAL Perm +VS VSLOBXFL Exp +VS VSORRES Exp +VS VSORRESU Exp +VS VSPOS Perm +VS VSRFTDTC Perm +VS VSSCAT Perm +VS VSSEQ Req +VS VSSTRESC Exp +VS VSSTRESN Exp +VS VSSTRESU Exp +VS VSTEST Req +VS VSTESTCD Req +VS VSTPT Perm +VS VSTPTNUM Perm +VS VSTPTREF Perm diff --git a/tests/test_cdiscpilot01_smoke.py b/tests/test_cdiscpilot01_smoke.py index 138a6f2cb..a5712de24 100644 --- a/tests/test_cdiscpilot01_smoke.py +++ b/tests/test_cdiscpilot01_smoke.py @@ -21,7 +21,7 @@ These tests are skipped automatically when CDISCPILOT01_PATH is not set. -Validated against: SDTMIG 3.4 conformance catalog, 414 rules, CT 2024-09-27. +Validated against: SDTMIG 3.4 conformance catalog, 362 rules, CT 2024-09-27. Study: CDISCPILOT01, Alzheimer's disease study, 306 subjects, 18 SDTM + 4 SUPP-- domains. """ @@ -135,8 +135,8 @@ def test_report_is_rules_type(pilot_report): def test_report_has_expected_rule_count(pilot_report): - """414 rules in the SDTMIG 3.4 catalog (after removing rules that contradict the IG).""" - assert len(pilot_report.native_result.rule_results) == 414 + """362 rules in the SDTMIG 3.4 catalog (after removing rules that contradict the IG).""" + assert len(pilot_report.native_result.rule_results) == 362 def test_report_overall_pass_rate(pilot_report): diff --git a/tests/test_native_conformance.py b/tests/test_native_conformance.py index 195491360..8e6aaef7a 100644 --- a/tests/test_native_conformance.py +++ b/tests/test_native_conformance.py @@ -470,7 +470,7 @@ def test_engine_clean_dm_zero_issues(clean_result): def test_engine_rule_count(clean_result): - assert len(clean_result.rule_results) == 414 + assert len(clean_result.rule_results) == 362 def test_engine_result_types(clean_result): @@ -1255,7 +1255,7 @@ def test_variable_metadata_check_fails_missing_sex(): engine = NativeConformanceEngine("sdtmig", "3.4", rule_types=["VARIABLE_METADATA_CHECK"]) result = engine.run({"DM": dm}) vmc = {r.rule_id: r for r in result.rule_results if r.rule_type == "VARIABLE_METADATA_CHECK"} - # SDTM-032 checks SEX, RACE, ETHNIC, COUNTRY. + # SDTM-032 checks SEX, RACE, COUNTRY (ETHNIC is Permissible). assert vmc["SDTM-032"].status == "fail" @@ -1614,7 +1614,7 @@ def test_engine_accepts_metadata_import_directly(): def test_engine_rule_count_phase3(): engine = NativeConformanceEngine("sdtmig", "3.4") result = engine.run({"DM": _clean_dm()}) - assert len(result.rule_results) == 414 + assert len(result.rule_results) == 362 _FIXTURES_DIR = Path(__file__).parent / "metadata_fixtures" diff --git a/tests/test_sdtm_conformant_package.py b/tests/test_sdtm_conformant_package.py index 85abd968d..8142d5db6 100644 --- a/tests/test_sdtm_conformant_package.py +++ b/tests/test_sdtm_conformant_package.py @@ -90,31 +90,34 @@ def conformant_sdtm_package() -> dict[str, pl.DataFrame]: "EXENDY": [57, 57], } ) - # LB: original-unit reference ranges are Char (LBORNRLO/LBORNRHI); standard ones are Num + # LB: original-unit reference ranges are Char (LBORNRLO/LBORNRHI); standard ones are Num. The + # third record is a test that wasn't done, so its Expected results are null lb = pl.DataFrame( { - "STUDYID": [STUDY] * 2, - "DOMAIN": ["LB"] * 2, - "USUBJID": SUBJ, - "LBSEQ": [1, 1], - "LBTESTCD": ["HGB", "HGB"], - "LBTEST": ["Hemoglobin", "Hemoglobin"], - "LBCAT": ["HEMATOLOGY"] * 2, - "LBORRES": ["14.1", "12.9"], - "LBORRESU": ["g/dL"] * 2, - "LBORNRLO": ["13.5", "12.0"], - "LBORNRHI": ["17.5", "15.5"], - "LBSTRESC": ["14.1", "12.9"], - "LBSTRESN": [14.1, 12.9], - "LBSTRESU": ["g/dL"] * 2, - "LBSTNRLO": [13.5, 12.0], - "LBSTNRHI": [17.5, 15.5], - "LBNRIND": ["NORMAL", "NORMAL"], - "VISITNUM": [1.0, 1.0], - "VISIT": ["SCREENING"] * 2, - "EPOCH": ["SCREENING"] * 2, - "LBDTC": ["2024-01-02", "2024-01-03"], - "LBDY": [-6, -6], + "STUDYID": [STUDY] * 3, + "DOMAIN": ["LB"] * 3, + "USUBJID": [SUBJ[0], SUBJ[1], SUBJ[0]], + "LBSEQ": [1, 1, 2], + "LBTESTCD": ["HGB", "HGB", "PLAT"], + "LBTEST": ["Hemoglobin", "Hemoglobin", "Platelets"], + "LBCAT": ["HEMATOLOGY"] * 3, + "LBORRES": ["14.1", "12.9", None], + "LBORRESU": ["g/dL", "g/dL", None], + "LBORNRLO": ["13.5", "12.0", None], + "LBORNRHI": ["17.5", "15.5", None], + "LBSTRESC": ["14.1", "12.9", None], + "LBSTRESN": [14.1, 12.9, None], + "LBSTRESU": ["g/dL", "g/dL", None], + "LBSTNRLO": [13.5, 12.0, None], + "LBSTNRHI": [17.5, 15.5, None], + "LBNRIND": ["NORMAL", "NORMAL", None], + "LBSTAT": [None, None, "NOT DONE"], + "LBREASND": [None, None, "SAMPLE HEMOLYZED"], + "VISITNUM": [1.0, 1.0, 1.0], + "VISIT": ["SCREENING"] * 3, + "EPOCH": ["SCREENING"] * 3, + "LBDTC": ["2024-01-02", "2024-01-03", "2024-01-02"], + "LBDY": [-6, -6, -6], } ) # VS: VISITNUM is Expected, so it's null for an unscheduled record @@ -233,6 +236,9 @@ def test_incorrect_rules_are_not_in_the_catalog(report): "SDTM-371", # LBSPEC required in LB (Permissible) "SDTM-435", # duplicate of SDTM-066 "SDTM-087", # AETOXGR has no CDISC codelist (the grading scale is the sponsor's) + "SDTM-336", # VISITNUM not null in LB (Expected) + "SDTM-266", # VSORRES not null (Expected; null when not done) + "SDTM-196", # DMSEQ (not an SDTMIG variable) "SDTM-135", # AEREL has no CDISC codelist (SDTMIG only gives ICH examples) } assert not removed & rule_ids @@ -429,3 +435,69 @@ def test_define_xml_extended_values_are_parsed(tmp_path): codelist = _read_define_xml_metadata(str(path)).codelists["EPOCH"] assert codelist.extended_values() == ["TREATMENT 1"] + + +# ── Core designations (Req/Exp/Perm) ───────────────────────────────────────── + + +def _sdtmig_core() -> dict[tuple[str, str], str]: + from pathlib import Path + + path = Path(__file__).parent / "metadata_fixtures" / "sdtmig_3_4_core.tsv" + lines = [ln for ln in path.read_text().splitlines() if not ln.startswith("#")][1:] + return {(ds, var): core for ds, var, core in (ln.split("\t") for ln in lines)} + + +def _plain_not_null_rules(rules): + """Rules that only say "X must not be null" (a single `is_null` condition on a variable).""" + for rule in rules: + conds = rule["conditions"] + items = conds.get("all") or conds.get("any") or [] + if rule["rule_type"] == "RECORD_CHECK" and len(items) == 1: + cond = items[0] + if cond.get("operator") == "is_null" and not cond["name"].startswith("_pb_"): + yield rule, cond["name"] + + +def test_rules_match_sdtmig_core_designations(): + """Presence rules may only require Required/Expected variables, and not-null rules only + Required ones: Expected values may be null, and Permissible variables may be absent.""" + import json + + from pointblank.metadata._conformance.rule_loader import _DATA_DIR + + core = _sdtmig_core() + covered = {ds for ds, _ in core} + rules = json.loads((_DATA_DIR / "sdtmig-3-4.json").read_text(encoding="utf-8"))["rules"] + + wrong = [] + for rule in rules: + for op in rule["operations"]: + if op["operator"] in ("column_presence", "has_required_variables"): + variables = op["params"].get("variables") or [op["params"]["column"]] + for ds in rule["domains"]: + for var in variables: + if ds in covered and core.get((ds, var)) not in ("Req", "Exp"): + wrong.append(f"{rule['core_id']}: {ds}.{var} ({core.get((ds, var))})") + for rule, var in _plain_not_null_rules(rules): + for ds in rule["domains"]: + if ds in covered and core.get((ds, var)) != "Req": + wrong.append(f"{rule['core_id']}: non-null {ds}.{var} ({core.get((ds, var))})") + + assert wrong == [] + + +def test_permissible_variables_can_be_left_out(): + package = conformant_sdtm_package() + for ds, cols in { + "DM": ["ETHNIC"], + "AE": ["AESEV", "AEOUT"], + "EX": ["EXROUTE"], + "TA": ["ELEMENT"], + "TV": ["VISITDY"], + }.items(): + package[ds] = package[ds].drop(cols) + + report = pb.validate_sdtmig(package) + + assert [r.rule_id for r in report.native_result.rule_results if r.status == "fail"] == [] diff --git a/user_guide/11-metadata-import/04-cdisc-submission-conformance.qmd b/user_guide/11-metadata-import/04-cdisc-submission-conformance.qmd index 086b4693f..c628e7662 100644 --- a/user_guide/11-metadata-import/04-cdisc-submission-conformance.qmd +++ b/user_guide/11-metadata-import/04-cdisc-submission-conformance.qmd @@ -19,7 +19,7 @@ those preparing a final submission gate, Pointblank can also delegate to the ext Two engines are available: -- **Built-in** (primary): Pointblank's own engine runs 414 SDTMIG 3.4 rules against your datasets +- **Built-in** (primary): Pointblank's own engine runs 362 SDTMIG 3.4 rules against your datasets in-process. Results are immediately renderable in a notebook. No installation beyond Pointblank is required. - **CORE** (advanced): delegates to the open-source CDISC CORE CLI, which runs the authoritative @@ -189,7 +189,7 @@ CORE engine, or to generate a custom summary report tailored to your team's work ### What the Rule Catalog Covers -The bundled SDTMIG 3.4 catalog contains 414 rules across seven types: +The bundled SDTMIG 3.4 catalog contains 362 rules across seven types: | Type | Description | Examples | |---|---|---|