Skip to content

Commit 18d2ed7

Browse files
authored
Merge pull request #64 from cdisc-org/sdtm-define-xml
Updates
2 parents fca5542 + 9247e2a commit 18d2ed7

4 files changed

Lines changed: 53 additions & 39 deletions

File tree

src/define-xml/create_define_json.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ def _extract_usdm_data(self):
193193
expression_design = Jsonata(f'study.versions["{self.studyversion}"].studyDesigns["{self.studydesign}"]')
194194
self.studyDesignData = expression_design.evaluate(self.usdm_data)
195195

196-
197196
def process_biomedical_concepts(self):
198197
"""
199198
Process all biomedical concepts from USDM.
@@ -476,7 +475,7 @@ def build_vlm_lookup(self):
476475
tsparmcd_entry = {
477476
"dataType": "text",
478477
"length": 1,
479-
"codeList": "CL.YN",
478+
"codeList": "CL.NY",
480479
"originType": "Protocol",
481480
"originSource": "Sponsor",
482481
"WhereClause": [
@@ -678,7 +677,7 @@ def build_vlm_lookup(self):
678677
tsparmcd_entry = {
679678
"dataType": "text",
680679
"length": 1,
681-
"codeList": "CL.YN",
680+
"codeList": "CL.NY",
682681
"originType": "Protocol",
683682
"originSource": "Sponsor",
684683
"WhereClause": [
@@ -820,7 +819,7 @@ def build_vlm_lookup(self):
820819
tsparmcd_entry = {
821820
"dataType": "text",
822821
"length": 1,
823-
"codeList": "CL.YN",
822+
"codeList": "CL.NY",
824823
"originType": "Protocol",
825824
"originSource": "Sponsor",
826825
"WhereClause": [
@@ -845,7 +844,7 @@ def build_vlm_lookup(self):
845844
tsparmcd_entry = {
846845
"dataType": "text",
847846
"length": 1,
848-
"codeList": "CL.YN",
847+
"codeList": "CL.NY",
849848
"originType": "Protocol",
850849
"originSource": "Sponsor",
851850
"WhereClause": [
@@ -1374,7 +1373,7 @@ def build_vlm_lookup(self):
13741373
tsparmcd_entry = {
13751374
"dataType": "text",
13761375
"length": 1,
1377-
"codeList": "CL.YN",
1376+
"codeList": "CL.NY",
13781377
"originType": "Protocol",
13791378
"originSource": "Sponsor",
13801379
"WhereClause": [
@@ -1401,7 +1400,7 @@ def build_vlm_lookup(self):
14011400
tsparmcd_entry = {
14021401
"dataType": "text",
14031402
"length": 1,
1404-
"codeList": "CL.YN",
1403+
"codeList": "CL.NY",
14051404
"originType": "Protocol",
14061405
"originSource": "Sponsor",
14071406
"WhereClause": [
@@ -1963,6 +1962,7 @@ def update_datasets_dict(self):
19631962
"OID": f"CL.{armcd_codelist_name}",
19641963
"name": "ARM Code",
19651964
"dataType": "text",
1965+
"isNonStandard": True,
19661966
"codeListItems": armcd_terms
19671967
}
19681968

@@ -1980,6 +1980,7 @@ def update_datasets_dict(self):
19801980
"OID": f"CL.{arm_codelist_name}",
19811981
"name": "ARM",
19821982
"dataType": "text",
1983+
"isNonStandard": True,
19831984
"codeListItems": arm_terms
19841985
}
19851986

@@ -2001,6 +2002,7 @@ def update_datasets_dict(self):
20012002
"OID": f"CL.{ietest_codelist_name}",
20022003
"name": "Inclusion/Exclusion Test Name",
20032004
"dataType": "text",
2005+
"isNonStandard": True,
20042006
"codeListItems": ietest_terms
20052007
}
20062008

@@ -2022,6 +2024,7 @@ def update_datasets_dict(self):
20222024
"OID": f"CL.{ietestcd_codelist_name}",
20232025
"name": "Inclusion/Exclusion Test Code",
20242026
"dataType": "text",
2027+
"isNonStandard": True,
20252028
"codeListItems": ietestcd_terms
20262029
}
20272030

@@ -2041,6 +2044,7 @@ def update_datasets_dict(self):
20412044
"OID": f"CL.{element_codelist_name}",
20422045
"name": "Description of Element",
20432046
"dataType": "text",
2047+
"isNonStandard": True,
20442048
"codeListItems": element_terms
20452049
}
20462050

@@ -2062,6 +2066,7 @@ def update_datasets_dict(self):
20622066
"OID": f"CL.{etcd_codelist_name}",
20632067
"name": "Element Code",
20642068
"dataType": "text",
2069+
"isNonStandard": True,
20652070
"codeListItems": etcd_terms
20662071
}
20672072

@@ -2092,6 +2097,10 @@ def update_datasets_dict(self):
20922097
"name": "Epoch",
20932098
"dataType": "text",
20942099
"standard": "STD.SDTMCT",
2100+
"coding": [{
2101+
"code": "C99079",
2102+
"codeSystem": "nci:ExtCodeID"
2103+
}],
20952104
"codeListItems": epoch_terms,
20962105
}
20972106

src/generators/define/codeLists.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ def create_define_objects(
3030
for cl in template:
3131
# TODO template missing the NCI c-codes for codelists and terms
3232
cl_defn = self._create_codelist_object(cl)
33-
cl_c_code = cl.get("nciCodelistCode")
33+
coding = cl.get("coding", [])
34+
cl_c_code = coding[0].get("code") if coding else None
3435
cl_name = cl.get("name", "unknown")
3536
codelist_items = self.require_key(cl, "codeListItems", f"CodeList {cl_name}")
3637
for term in codelist_items:
37-
cl_item = self._create_codelistitem_object(term)
38-
cl_defn.CodeListItem.append(cl_item)
38+
if "decode" in term:
39+
cl_item = self._create_codelistitem_object(term)
40+
cl_defn.CodeListItem.append(cl_item)
41+
else:
42+
en_item = self._create_enumerateditem_object(term)
43+
cl_defn.EnumeratedItem.append(en_item)
3944
# TODO no indicator that a codelist is a dictionary with an external codelist reference
4045
if len(cl["codeListItems"]) == 0:
4146
self._create_external_code_list(cl_defn, cl)
@@ -64,29 +69,30 @@ def _create_codelist_object(self, obj):
6469
attr = {"OID": oid, "Name": name, "DataType": data_type}
6570
if obj.get("comment"):
6671
attr["CommentOID"] = obj["comment"]
67-
if obj.get("isNonStandard"):
68-
attr["IsNonStandard"] = obj["isNonStandard"]
69-
if obj.get("standardOID"):
70-
attr["StandardOID"] = obj["standardOID"]
72+
if "isNonStandard" in obj:
73+
attr["IsNonStandard"] = "Yes"
74+
if obj.get("standard"):
75+
attr["StandardOID"] = obj["standard"]
7176
cl = DEFINE.CodeList(**attr)
7277
return cl
7378

74-
@staticmethod
75-
def _create_enumerateditem_object(obj):
76-
attr = {"CodedValue": obj["Term"]}
77-
if obj.get("Order"):
78-
attr["OrderNumber"] = obj["Order"]
79+
def _create_enumerateditem_object(self, obj):
80+
coded_value = self.require_key(obj, "codedValue", "CodeListItem")
81+
attr = {"CodedValue": coded_value}
82+
# if obj.get("Order"):
83+
# attr["OrderNumber"] = obj["Order"]
7984
en_item = DEFINE.EnumeratedItem(**attr)
80-
if obj.get("NCI Term Code"):
81-
alias = DEFINE.Alias(Context="nci:ExtCodeID", Name=obj["NCI Term Code"])
85+
coding = obj.get("coding", {})
86+
if coding:
87+
alias = DEFINE.Alias(Context="nci:ExtCodeID", Name=coding.get("code"))
8288
en_item.Alias.append(alias)
8389
return en_item
8490

8591
def _create_codelistitem_object(self, obj):
8692
coded_value = self.require_key(obj, "codedValue", "CodeListItem")
8793
attr = {"CodedValue": coded_value}
88-
if obj.get("order"):
89-
attr["OrderNumber"] = obj["order"]
94+
# if obj.get("order"):
95+
# attr["OrderNumber"] = obj["order"]
9096
cl_item = DEFINE.CodeListItem(**attr)
9197
decode = DEFINE.Decode()
9298
if obj.get("decode", None):
@@ -97,7 +103,8 @@ def _create_codelistitem_object(self, obj):
97103
decode.TranslatedText.append(tt)
98104
cl_item.Decode = decode
99105
# TODO NCI c-codes for terms or codelists not available in template
100-
if obj.get("nciTermCode"):
101-
alias = DEFINE.Alias(Context="nci:ExtCodeID", Name=obj["nciTermCode"])
106+
coding = obj.get("coding", {})
107+
if coding:
108+
alias = DEFINE.Alias(Context="nci:ExtCodeID", Name=coding.get("code"))
102109
cl_item.Alias.append(alias)
103110
return cl_item

src/generators/define/itemGroups.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ def _generate_dataset(self, dataset, define_objects, lang, acrf):
6363
def _create_itemgroupdef_object(self, obj):
6464
name = self.require_key(obj, "name", "ItemGroupDef")
6565
oid = self.generate_oid(["IG", name])
66-
attr = {"OID": oid, "Name": name, "Domain": name}
66+
attr = {"OID": oid, "Name": name, "Domain": name, "SASDatasetName": name}
6767
if obj.get("archiveLocationID"):
6868
attr["ArchiveLocationID"] = ".".join(["LF", obj["archiveLocationID"]])
6969
attr["Structure"] = obj.get("structure", "NA")
70-
if obj.get("sasDatasetName"):
71-
attr["SASDatasetName"] = obj["sasDatasetName"]
70+
# if obj.get("sasDatasetName"):
71+
# attr["SASDatasetName"] = obj["sasDatasetName"]
7272
if "isReferenceData" in obj:
7373
attr["IsReferenceData"] = "Yes" if obj["isReferenceData"] else "No"
7474
# else:
@@ -86,11 +86,10 @@ def _create_itemgroupdef_object(self, obj):
8686
attr["Purpose"] = obj["purpose"]
8787
else:
8888
attr["Purpose"] = DEFAULT_PURPOSE
89-
9089
if obj.get("comment"):
9190
attr["CommentOID"] = obj["comment"]
92-
if obj.get("isNonStandard"):
93-
attr["IsNonStandard"] = obj["isNonStandard"]
91+
if "isNonStandard" in obj:
92+
attr["IsNonStandard"] = "Yes"
9493
if obj.get("standard"):
9594
attr["StandardOID"] = obj["standard"]
9695
if obj.get("hasNoData"):

src/generators/define/items.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,17 @@ def _add_optional_itemdef_elements(self, item, obj, it_oid, slice):
5555
"""
5656
use the values from the Variables section in the define-template to add the optional ELEMENTS to the ItemDef
5757
"""
58+
# TODO do not find codeList in define.json example for items
59+
if obj.get("codeList"):
60+
cl_oid = self.generate_oid(["CL", obj["codeList"].split(".")[1]])
61+
cl = DEFINE.CodeListRef(CodeListOID=cl_oid)
62+
item.CodeListRef = cl
5863
for s in slice or []:
5964
if s.get("type") == "ValueList":
6065
if s.get("wasDerivedFrom") == it_oid:
6166
vl_oid = s["OID"]
6267
vl_ref = DEFINE.ValueListRef(ValueListOID=vl_oid)
6368
item.ValueListRef = vl_ref
64-
65-
# TODO do not find codeList in define.json example for items
66-
if obj.get("codeList"):
67-
cl_oid = self.generate_oid(["CL", obj["codeList"].split(".")[1]])
68-
cl = DEFINE.CodeListRef(CodeListOID=cl_oid)
69-
item.CodeListRef = cl
7069
# TODO do not find origin content in define.json example for items (nice to have that information)
7170
attr = {}
7271
if obj.get("origin"):
@@ -100,8 +99,8 @@ def _add_optional_itemdef_attributes(attr, obj):
10099
if obj.get("significantDigits"):
101100
attr["SignificantDigits"] = obj["significantDigits"]
102101
# TODO do not find format content in define.json example for items
103-
if obj.get("format"):
104-
attr["DisplayFormat"] = obj["format"]
102+
if obj.get("displayFormat"):
103+
attr["DisplayFormat"] = obj["displayFormat"]
105104
if obj.get("comment"):
106105
attr["CommentOID"] = obj["comment"]
107106

0 commit comments

Comments
 (0)