def test_positive_type(self): # testing Length as a positive integer attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field" } item = ODM.ItemDef(**attrs) self.assertEqual(item.Length, 1) # testing Length = 0 as a positive integer attrs["Length"] = 0 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) # testing Length = -1 as a positive integer attrs["Length"] = -1 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) # testing Length = float as a positive integer attrs["Length"] = 1.0 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs)
def test_non_negative_type(self): # testing SignificantDigits as a non-negative integer attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "SignificantDigits": 1 } item = ODM.ItemDef(**attrs) self.assertEqual(item.SignificantDigits, 1) # testing SignificantDigits = 0 as a non-negative integer attrs["SignificantDigits"] = 0 item = ODM.ItemDef(**attrs) self.assertEqual(item.SignificantDigits, 0) # testing SignificantDigits = -1 as a non-negative integer attrs["SignificantDigits"] = -1 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) # testing SignificantDigits = float as a non-negative integer attrs["SignificantDigits"] = 1.0 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs)
def test_sasname_type(self): # valid test attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "SignificantDigits": 1 } item = ODM.ItemDef(**attrs) self.assertEqual(item.SASFieldName, "AEYN") # start with an underscore attrs["SASFieldName"] = "_AETERM" item = ODM.ItemDef(**attrs) self.assertEqual(item.SASFieldName, "_AETERM") # start with a number attrs["SASFieldName"] = "9AETERM" with self.assertRaises(ValueError): item = ODM.ItemDef(**attrs) # end with a symbol attrs["SASFieldName"] = "AETERM%" with self.assertRaises(ValueError): item = ODM.ItemDef(**attrs) # test with none - does not throw an error when value is None attrs["SASFieldName"] = None item = ODM.ItemDef(**attrs) self.assertIsNone(item.SASFieldName)
def add_ITD(self): # ItemDef 1 ttd1 = ODM.TranslatedText(_content="Date of measurements", lang="en") ttq1 = ODM.TranslatedText(_content="Date", lang="en") desc1 = ODM.Description() desc1.TranslatedText = [ttd1] q1 = ODM.Question() q1.TranslatedText = [ttq1] a1 = ODM.Alias(Context="CDASH", Name="VSDAT") itd1 = ODM.ItemDef(OID="ODM.IT.VS.VSDAT", Name="Date", DataType="partialDate") itd1.Description = desc1 itd1.Question = q1 itd1.Alias = [a1] # ItemDef 2 ttd2 = ODM.TranslatedText( _content= "Result of the vital signs measurement as originally received or collected.", lang="en") ttq2 = ODM.TranslatedText(_content="Diastolic", lang="en") desc2 = ODM.Description() desc2.TranslatedText = [ttd2] q2 = ODM.Question() q2.TranslatedText = [ttq2] a2a = ODM.Alias(Context="CDASH", Name="BP.DIABP.VSORRES") a2b = ODM.Alias(Context="CDASH/SDTM", Name="VSORRES+VSORRESU") itd2 = ODM.ItemDef(OID="ODM.IT.VS.BP.VSORRESU", Name="BP Units", DataType="text") itd2.Description = desc2 itd2.Question = q2 itd2.Alias = [a2a, a2b] return [itd1, itd2]
def test_add_not_alias(self): item = ODM.ItemDef(OID="ODM.IT.VSPOS", Name="VS Position", DataType="text") with self.assertRaises(TypeError): self.formdef.Alias = [item] self.formdef.Alias.append(ODM.Alias(Context="SDTMIG", Name="VS")) # list accepts invalid objects self.formdef.Alias.append(ODM.ItemDef(OID="ODM.IT.VSDT", Name="VS Date", DataType="text")) self.assertEqual(len(self.formdef.Alias), 2) self.assertEqual(self.formdef.Alias[0].Context, "SDTMIG")
def test_ItemDef(self): attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": "1", "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field" } item = ODM.ItemDef(**attrs) item.Description.TranslatedText = [ ODM.TranslatedText(_content="this is the first test description", lang="en") ] item.Question.TranslatedText = [ ODM.TranslatedText(_content="Any AEs?", lang="en") ] item.CodeListRef = ODM.CodeListRef( CodeListOID="CL.NY_SUB_Y_N_2011-10-24") item_dict = item.to_dict() print(item_dict) is_valid = self.validator.verify_conformance(item_dict, "ItemDef") self.assertTrue(is_valid)
def test_insert_item_with_none_element(self): attrs = self.set_item_attributes() item = ODM.ItemDef(**attrs) # to support the test a null version of CodeListRef is created, but should be ignored on output if item.CodeListRef: self.assertIsNotNone(item.CodeListRef) if item.SignificantDigits: self.assertIsNotNone(item.SignificantDigits) self.loader.open_odm_document(self.odm_file) mdv = self.loader.MetaDataVersion() mdv.ItemDef.append(item) attrs = self.get_root_attributes() root = ODM.ODM(**attrs) study = self.add_study(mdv) root.Study = [study] root.write_xml(self.odm_file_out) loader = LD.ODMLoader(OL.XMLODMLoader()) loader.open_odm_document(self.odm_file_out) mdv = loader.MetaDataVersion() # is_found_inserted_item = False # for it in mdv.ItemDef: # if it.OID == "ODM.IT.AE.TEST": # is_found_inserted_item = True # self.assertTrue(is_found_inserted_item) itd = mdv.find("ItemDef", "OID", "ODM.IT.AE.TEST") self.assertEqual(itd.OID, "ODM.IT.AE.TEST") # comment was created as None and should not be part of the object self.assertIsNone(itd.Comment) itd_json = itd.to_json() self.assertNotIn("Comment", itd_json) odm_json = root.to_json()
def test_to_xml(self): attrs = self.set_item_attributes() item = ODM.ItemDef(**attrs) item.Description.TranslatedText = [ ODM.TranslatedText(_content="this is the first test description", lang="en") ] item.Question.TranslatedText = [ ODM.TranslatedText(_content="Any AEs?", lang="en") ] item.ExternalQuestion = ODM.ExternalQuestion(Dictionary="SF36", Version="12", Code="Walks 1-mile") item.CodeListRef = ODM.CodeListRef( CodeListOID="CL.NY_SUB_Y_N_2011-10-24") item.RangeCheck = [ODM.RangeCheck(Comparator="EQ", SoftHard="Soft")] item.RangeCheck[0].CheckValue = [ODM.CheckValue(_content="DIABP")] item.RangeCheck[0].FormalExpression = [ ODM.FormalExpression(Context="Python 3.7", _content="print('hello world')") ] item.RangeCheck[0].MeasurementUnitRef = ODM.MeasurementUnitRef( MeasurementUnitOID="ODM.MU.UNITS") item.RangeCheck[0].ErrorMessage.TranslatedText = [ ODM.TranslatedText(_content="invalid test code", lang="en") ] item_xml = item.to_xml() self.assertEqual(item_xml.attrib["OID"], "ODM.IT.AE.AEYN") cv = item_xml.find("*/CheckValue") self.assertEqual(cv.text, "DIABP") dt = item_xml.findall("Description/TranslatedText") self.assertEqual(len(dt), 1)
def test_required_attributes_only(self): attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text" } self.item = ODM.ItemDef(**attrs) self.assertEqual(self.item.OID, "ODM.IT.AE.AEYN")
def test_invalid_attribute_data_type(self): attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "SignificantDigits": "A" } with self.assertRaises(TypeError): self.item = ODM.ItemDef(**attrs)
def test_codelist_ref_exists_check(self): attrs = self.set_item_attributes() item = ODM.ItemDef(**attrs) codelistref_check_succeeds = False if not item.CodeListRef: codelistref_check_succeeds = True if item.CodeListRef: codelistref_check_succeeds = False self.assertTrue(codelistref_check_succeeds)
def setUp(self) -> None: current_datetime = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat() root = ODM.ODM(FileOID="ODM.DEMO.001", Granularity="Metadata", AsOfDateTime=current_datetime, CreationDateTime=current_datetime, ODMVersion="1.3.2", FileType="Snapshot", Originator="swhume", SourceSystem="odmlib", SourceSystemVersion="0.1") # create Study and add to ODM root.Study.append(ODM.Study(OID="ODM.GET.STARTED")) # create the global variables root.Study[0].GlobalVariables = ODM.GlobalVariables() root.Study[0].GlobalVariables.StudyName = ODM.StudyName(_content="Get Started with ODM XML") root.Study[0].GlobalVariables.StudyDescription = ODM.StudyDescription( _content="Demo to get started with odmlib") root.Study[0].GlobalVariables.ProtocolName = ODM.ProtocolName(_content="ODM XML Get Started") # create the MetaDataVersion root.Study[0].MetaDataVersion.append(ODM.MetaDataVersion(OID="MDV.DEMO-ODM-01", Name="Get Started MDV", Description="Get Started Demo")) # create Protocol p = ODM.Protocol() p.Description = ODM.Description() p.Description.TranslatedText.append(ODM.TranslatedText(_content="Get Started Protocol", lang="en")) p.StudyEventRef.append(ODM.StudyEventRef(StudyEventOID="BASELINE", OrderNumber=1, Mandatory="Yes")) root.Study[0].MetaDataVersion[0].Protocol = p # create a StudyEventDef sed = ODM.StudyEventDef(OID="BASELINE", Name="Baseline Visit", Repeating="No", Type="Scheduled") sed.FormRef.append(ODM.FormRef(FormOID="ODM.F.DM", Mandatory="Yes", OrderNumber=1)) root.Study[0].MetaDataVersion[0].StudyEventDef.append(sed) # create a FormDef fd = ODM.FormDef(OID="ODM.F.DM", Name="Demographics", Repeating="No") fd.ItemGroupRef.append(ODM.ItemGroupRef(ItemGroupOID="ODM.IG.DM", Mandatory="Yes", OrderNumber=2)) root.Study[0].MetaDataVersion[0].FormDef.append(fd) # create an ItemGroupDef igd = ODM.ItemGroupDef(OID="ODM.IG.DM", Name="Demographics", Repeating="No") igd.ItemRef.append(ODM.ItemRef(ItemOID="ODM.IT.DM.BRTHYR", Mandatory="Yes")) root.Study[0].MetaDataVersion[0].ItemGroupDef.append(igd) # create an ItemDef itd = ODM.ItemDef(OID="ODM.IT.DM.BRTHYR", Name="Birth Year", DataType="integer") itd.Description = ODM.Description() itd.Description.TranslatedText.append(ODM.TranslatedText(_content="Year of the subject's birth", lang="en")) itd.Question = ODM.Question() itd.Question.TranslatedText.append(ODM.TranslatedText(_content="Birth Year", lang="en")) itd.Alias.append(ODM.Alias(Context="CDASH", Name="BRTHYR")) itd.Alias.append(ODM.Alias(Context="SDTM", Name="BRTHDTC")) root.Study[0].MetaDataVersion[0].ItemDef.append(itd) # save the new ODM document to an ODM XML file root.write_xml(ODM_XML_FILE) # save the same ODM document to a JSON file root.write_json(ODM_JSON_FILE)
def test_string_type(self): attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "SignificantDigits": 1 } item = ODM.ItemDef(**attrs) self.assertEqual(item.Origin, "CRF") # integer attrs["Origin"] = 1 with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) attrs["Origin"] = None item = ODM.ItemDef(**attrs) self.assertIsNone(item.Origin)
def test_get_missing_undefined_attribute(self): itd = ODM.ItemDef(OID="IT.VS.VSORRES", Name="Vital Signs Results", DataType="text") self.assertEqual(itd.OID, "IT.VS.VSORRES") self.assertListEqual(itd.MeasurementUnitRef, []) result = itd.CodeListRef self.assertIsNone(result) itd.Alias.append(itd.CodeListRef) self.assertListEqual(itd.Alias, [None]) with self.assertRaises(TypeError): itd.new_thing = "hello"
def test_to_json(self): attrs = self.set_item_attributes() item = ODM.ItemDef(**attrs) item.Description.TranslatedText.append( ODM.TranslatedText(_content="this is the first test description", lang="en")) item.Question.TranslatedText = [ ODM.TranslatedText(_content="Any AEs?", lang="en") ] item.CodeListRef = ODM.CodeListRef( CodeListOID="CL.NY_SUB_Y_N_2011-10-24") item_json = item.to_json() item_dict = json.loads(item_json) self.assertEqual(item_dict["OID"], "ODM.IT.AE.AEYN")
def test_to_dict(self): attrs = self.set_item_attributes() item = ODM.ItemDef(**attrs) item.Description.TranslatedText = [ ODM.TranslatedText(_content="this is the first test description", lang="en") ] item.Question.TranslatedText = [ ODM.TranslatedText(_content="Any AEs?", lang="en") ] item.CodeListRef = ODM.CodeListRef( CodeListOID="CL.NY_SUB_Y_N_2011-10-24") item_dict = item.to_dict() expected_dict = { 'OID': 'ODM.IT.AE.AEYN', 'Name': 'Any AEs?', 'DataType': 'text', 'Length': 1, 'SASFieldName': 'AEYN', 'SDSVarName': 'AEYN', 'Origin': 'CRF', 'Comment': 'Data management field', 'Description': { 'TranslatedText': [{ '_content': 'this is the first test description', 'lang': 'en' }] }, 'Question': { 'TranslatedText': [{ '_content': 'Any AEs?', 'lang': 'en' }] }, 'CodeListRef': { 'CodeListOID': 'CL.NY_SUB_Y_N_2011-10-24' } } self.assertDictEqual(item_dict, expected_dict)
def test_get_missing_element_with_required(self): itd = ODM.ItemDef(OID="IT.VS.VSORRES", Name="Vital Signs Results", DataType="text") self.assertEqual(itd.OID, "IT.VS.VSORRES") self.assertIsNone(itd.CodeListRef)
def test_add_undefined_content(self): # use conformance rules to check for unknown objects being added after creation attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "SignificantDigits": 1 } item = ODM.ItemDef(**attrs) clr = ODM.CodeListRef(CodeListOID="CL.TEST") with self.assertRaises(TypeError): item.NewCodeList = clr # cannot add unknown attributes or elements during creation, but can afterwards; catch with conformance checks attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "SignificantDigits": 1 } item = ODM.ItemDef(**attrs) with self.assertRaises(TypeError): item.InSignificantDigits = 1 # can add all objects during creation and they are validated attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "CodeListRef": clr } item = ODM.ItemDef(**attrs) self.assertEqual(item.CodeListRef, clr) attrs["CodeListReference"] = clr with self.assertRaises(TypeError): # test shows that ItemDef fails the schema check because it has an unknown CodeListReference object item = ODM.ItemDef(**attrs) self.assertEqual(item.CodeListRef, clr) # test adding the wrong type of object to a list attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "Alias": [clr] } with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) # test adding the wrong type of object to a list alias = ODM.Alias(Context="CDASH", Name="AEYN") attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "Alias": alias } with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs) # assign wrong type of object to an element attrs = { "OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?", "DataType": "text", "Length": 1, "SASFieldName": "AEYN", "SDSVarName": "AEYN", "Origin": "CRF", "Comment": "Data management field", "CodeListRef": alias } with self.assertRaises(TypeError): item = ODM.ItemDef(**attrs)
def add_ITD_nonunique(self): # ItemDef 1 ttd1 = ODM.TranslatedText(_content="Date of measurements", lang="en") ttq1 = ODM.TranslatedText(_content="Date", lang="en") desc1 = ODM.Description() desc1.TranslatedText = [ttd1] q1 = ODM.Question() q1.TranslatedText = [ttq1] a1 = ODM.Alias(Context="CDASH", Name="VSDAT") itd1 = ODM.ItemDef(OID="ODM.IT.VS.VSDAT", Name="Date", DataType="partialDate") itd1.Description = desc1 itd1.Question = q1 itd1.Alias = [a1] # ItemDef 2 ttd2 = ODM.TranslatedText( _content= "Result of the vital signs measurement as originally received or collected.", lang="en") ttq2 = ODM.TranslatedText(_content="Diastolic", lang="en") desc2 = ODM.Description() desc2.TranslatedText = [ttd2] q2 = ODM.Question() q2.TranslatedText = [ttq2] a2a = ODM.Alias(Context="CDASH", Name="BP.DIABP.VSORRES") a2b = ODM.Alias(Context="CDASH/SDTM", Name="VSORRES+VSORRESU") itd2 = ODM.ItemDef(OID="ODM.IT.VS.BP.VSORRESU", Name="BP Units", DataType="text") itd2.Description = desc2 itd2.Question = q2 itd2.Alias = [a2a, a2b] # ItemDef 3 ttd3 = ODM.TranslatedText(_content="Adverse Event Term", lang="en") ttq3 = ODM.TranslatedText(_content="AE Term", lang="en") desc3 = ODM.Description() desc3.TranslatedText = [ttd3] q3 = ODM.Question() q3.TranslatedText = [ttq3] itd3 = ODM.ItemDef(OID="ODM.IT.AE.AETERM", Name="AE Term", DataType="text") itd3.Description = desc3 itd3.Question = q3 # ItemDef 4 ttd4 = ODM.TranslatedText(_content="Adverse Event Severity", lang="en") ttq4 = ODM.TranslatedText(_content="AE Severity", lang="en") desc4 = ODM.Description() desc4.TranslatedText = [ttd4] q4 = ODM.Question() q4.TranslatedText = [ttq4] itd4 = ODM.ItemDef(OID="ODM.IT.AE.AESEV", Name="AE Severity", DataType="text") itd4.Description = desc4 itd4.Question = q4 # ItemDef 5 ttd5 = ODM.TranslatedText(_content="Subject ID", lang="en") ttq5 = ODM.TranslatedText(_content="Subject ID", lang="en") desc5 = ODM.Description() desc5.TranslatedText = [ttd5] q5 = ODM.Question() q5.TranslatedText = [ttq5] itd5 = ODM.ItemDef(OID="ODM.IT.Common.SubjectID", Name="Subject ID", DataType="text") itd5.Description = desc5 itd5.Question = q5 # ItemDef 6 ttd6 = ODM.TranslatedText(_content="Diastolic Blood Pressure Result", lang="en") ttq6 = ODM.TranslatedText(_content="Diastolic BP", lang="en") desc6 = ODM.Description() desc6.TranslatedText = [ttd6] q6 = ODM.Question() q6.TranslatedText = [ttq6] itd6 = ODM.ItemDef(OID="ODM.IT.VS.BP.SYSBP.VSORRES", Name="DBP Result", DataType="text") itd6.Description = desc6 itd6.Question = q6 # ItemDef 7 ttd7 = ODM.TranslatedText(_content="Birth Year", lang="en") ttq7 = ODM.TranslatedText(_content="DOB Year", lang="en") desc7 = ODM.Description() desc7.TranslatedText = [ttd7] q7 = ODM.Question() q7.TranslatedText = [ttq7] itd7 = ODM.ItemDef(OID="ODM.IT.DM.BRTHYR", Name="Birth Year", DataType="text") itd7.Description = desc7 itd7.Question = q7 # ItemDef 8 ttd8 = ODM.TranslatedText(_content="Visit", lang="en") ttq8 = ODM.TranslatedText(_content="Visit", lang="en") desc8 = ODM.Description() desc8.TranslatedText = [ttd8] q8 = ODM.Question() q8.TranslatedText = [ttq8] itd8 = ODM.ItemDef(OID="ODM.IT.Common.Visit", Name="Visit", DataType="text") itd8.Description = desc8 itd8.Question = q8 # ItemDef 9 ttd9 = ODM.TranslatedText(_content="Sex", lang="en") ttq9 = ODM.TranslatedText(_content="Sex", lang="en") desc9 = ODM.Description() desc9.TranslatedText = [ttd9] q9 = ODM.Question() q9.TranslatedText = [ttq9] itd9 = ODM.ItemDef(OID="ODM.IT.DM.SEX", Name="Sex", DataType="text") itd9.Description = desc9 itd9.Question = q9 # ItemDef 10 ttd10 = ODM.TranslatedText(_content="Systolic Blood Pressure Result", lang="en") ttq10 = ODM.TranslatedText(_content="Systolic BP", lang="en") desc10 = ODM.Description() desc10.TranslatedText = [ttd10] q10 = ODM.Question() q10.TranslatedText = [ttq10] itd10 = ODM.ItemDef(OID="ODM.IT.VS.BP.SYSBP.VSORRES", Name="Systolic BP Result", DataType="text") itd10.Description = desc10 itd10.Question = q10 return [itd1, itd2, itd3, itd4, itd5, itd6, itd7, itd8, itd9, itd10]
def setUp(self) -> None: attrs = self.set_item_attributes() self.item = ODM.ItemDef(**attrs)
def test_missing_itemdef_attributes(self): attrs = {"OID": "ODM.IT.AE.AEYN", "Name": "Any AEs?"} with self.assertRaises(ValueError): ODM.ItemDef(**attrs)
def test_xml_to_string(self): current_datetime = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).isoformat() root = ODM.ODM(FileOID="ODM.DEMO.001", Granularity="Metadata", AsOfDateTime=current_datetime, CreationDateTime=current_datetime, ODMVersion="1.3.2", FileType="Snapshot", Originator="swhume", SourceSystem="odmlib", SourceSystemVersion="0.1") # create Study and add to ODM root.Study.append(ODM.Study(OID="ODM.GET.STARTED")) # create the global variables root.Study[0].GlobalVariables = ODM.GlobalVariables() root.Study[0].GlobalVariables.StudyName = ODM.StudyName(_content="Get Started with ODM XML") root.Study[0].GlobalVariables.StudyDescription = ODM.StudyDescription( _content="Demo to get started with odmlib") root.Study[0].GlobalVariables.ProtocolName = ODM.ProtocolName(_content="ODM XML Get Started") # create the MetaDataVersion root.Study[0].MetaDataVersion.append(ODM.MetaDataVersion(OID="MDV.DEMO-ODM-01", Name="Get Started MDV", Description="Get Started Demo")) # create Protocol p = ODM.Protocol() p.Description = ODM.Description() p.Description.TranslatedText.append(ODM.TranslatedText(_content="Get Started Protocol", lang="en")) p.StudyEventRef.append(ODM.StudyEventRef(StudyEventOID="BASELINE", OrderNumber=1, Mandatory="Yes")) root.Study[0].MetaDataVersion[0].Protocol = p # create a StudyEventDef sed = ODM.StudyEventDef(OID="BASELINE", Name="Baseline Visit", Repeating="No", Type="Scheduled") sed.FormRef.append(ODM.FormRef(FormOID="ODM.F.DM", Mandatory="Yes", OrderNumber=1)) root.Study[0].MetaDataVersion[0].StudyEventDef.append(sed) # create a FormDef fd = ODM.FormDef(OID="ODM.F.DM", Name="Demographics", Repeating="No") fd.ItemGroupRef.append(ODM.ItemGroupRef(ItemGroupOID="ODM.IG.DM", Mandatory="Yes", OrderNumber=2)) root.Study[0].MetaDataVersion[0].FormDef.append(fd) # create an ItemGroupDef igd = ODM.ItemGroupDef(OID="ODM.IG.DM", Name="Demographics", Repeating="No") igd.ItemRef.append(ODM.ItemRef(ItemOID="ODM.IT.DM.BRTHYR", Mandatory="Yes")) root.Study[0].MetaDataVersion[0].ItemGroupDef.append(igd) # create an ItemDef itd = ODM.ItemDef(OID="ODM.IT.DM.BRTHYR", Name="Birth Year", DataType="integer") itd.Description = ODM.Description() itd.Description.TranslatedText.append(ODM.TranslatedText(_content="Year of the subject's birth", lang="en")) itd.Question = ODM.Question() itd.Question.TranslatedText.append(ODM.TranslatedText(_content="Birth Year", lang="en")) itd.Alias.append(ODM.Alias(Context="CDASH", Name="BRTHYR")) itd.Alias.append(ODM.Alias(Context="SDTM", Name="BRTHDTC")) root.Study[0].MetaDataVersion[0].ItemDef.append(itd) odm_xml_string = root.to_xml_string() # add namespaces nsr = NS.NamespaceRegistry() odm_str = nsr.set_odm_namespace_attributes_string(odm_xml_string) with open("./data/simple_create_from_string.xml", "w") as xml_file: xml_file.write(odm_str) loader = LD.ODMLoader(OL.XMLODMLoader(model_package="odm_1_3_2", ns_uri="http://www.cdisc.org/ns/odm/v1.3")) loader.open_odm_document("./data/simple_create_from_string.xml") mdv = loader.MetaDataVersion() item_list = mdv.ItemDef item = item_list[0] self.assertEqual(item.OID, "ODM.IT.DM.BRTHYR")