diff --git a/src/Json/Process/Material.fs b/src/Json/Process/Material.fs index 193b441c..2c3a852f 100644 --- a/src/Json/Process/Material.fs +++ b/src/Json/Process/Material.fs @@ -20,6 +20,7 @@ module Material = [ "@id", Encode.string (oa |> genID) |> Some "@type", (Encode.list [Encode.string "Material"]) |> Some + "additionalType", Encode.string "Material" |> Some Encode.tryInclude "name" Encode.string oa.Name Encode.tryInclude "type" MaterialType.ROCrate.encoder oa.MaterialType Encode.tryIncludeListOpt "characteristics" MaterialAttributeValue.ROCrate.encoder oa.Characteristics @@ -31,7 +32,10 @@ module Material = let decoder : Decoder = let rec decode() = - Decode.object (fun get -> + Decode.object (fun get -> + match get.Optional.Field "additionalType" Decode.uri with + | Some "Material" | None -> () + | Some _ -> get.Required.Field "FailBecauseNotSample" Decode.unit { ID = get.Optional.Field "@id" Decode.uri Name = get.Optional.Field "name" Decode.string diff --git a/src/Json/Process/ProcessInput.fs b/src/Json/Process/ProcessInput.fs index 16a56b09..de693bf9 100644 --- a/src/Json/Process/ProcessInput.fs +++ b/src/Json/Process/ProcessInput.fs @@ -22,8 +22,8 @@ module ProcessInput = let decoder : Decoder = Decode.oneOf [ - Decode.map ProcessInput.Source Source.ROCrate.decoder Decode.map ProcessInput.Sample Sample.ROCrate.decoder + Decode.map ProcessInput.Source Source.ROCrate.decoder Decode.map ProcessInput.Data Data.ROCrate.decoder Decode.map ProcessInput.Material Material.ROCrate.decoder ] diff --git a/src/Json/Process/Sample.fs b/src/Json/Process/Sample.fs index 71faf850..1462abe6 100644 --- a/src/Json/Process/Sample.fs +++ b/src/Json/Process/Sample.fs @@ -24,6 +24,7 @@ module Sample = [ "@id", Encode.string (oa |> genID) |> Some "@type", (Encode.list [ Encode.string "Sample"]) |> Some + "additionalType", Encode.string "Sample" |> Some Encode.tryInclude "name" Encode.string (oa.Name) Encode.tryIncludeList "additionalProperties" id additionalProperties "@context", ROCrateContext.Sample.context_jsonvalue |> Some @@ -64,6 +65,9 @@ module Sample = additionalProperties |> List.choose snd |> Helper.Option.fromValueWithDefault [] + match get.Optional.Field "additionalType" Decode.uri with + | Some "Sample" | None -> () + | Some _ -> get.Required.Field "FailBecauseNotSample" Decode.unit { ID = get.Optional.Field "@id" Decode.uri Name = get.Optional.Field "name" Decode.string diff --git a/src/Json/Process/Source.fs b/src/Json/Process/Source.fs index bb200a6f..17a740e3 100644 --- a/src/Json/Process/Source.fs +++ b/src/Json/Process/Source.fs @@ -20,6 +20,7 @@ module Source = [ "@id", Encode.string (oa |> genID) |> Some "@type", (Encode.list [ Encode.string "Source"]) |> Some + "additionalType", Encode.string "Source" |> Some Encode.tryInclude "name" Encode.string (oa.Name) Encode.tryIncludeListOpt "characteristics" MaterialAttributeValue.ROCrate.encoder (oa.Characteristics) "@context", ROCrateContext.Source.context_jsonvalue |> Some @@ -29,7 +30,9 @@ module Source = let rec decoder : Decoder = Decode.object (fun get -> - + match get.Optional.Field "additionalType" Decode.uri with + | Some "Source" | None -> () + | Some _ -> get.Required.Field "FailBecauseNotSample" Decode.unit { ID = get.Optional.Field "@id" Decode.uri Name = get.Optional.Field "name" Decode.string diff --git a/src/Json/context/rocrate/isa_assay_context.fs b/src/Json/context/rocrate/isa_assay_context.fs index bc1907f9..cbe4b5a1 100644 --- a/src/Json/context/rocrate/isa_assay_context.fs +++ b/src/Json/context/rocrate/isa_assay_context.fs @@ -19,7 +19,7 @@ module Assay = otherMaterials: string samples: string characteristicCategories: string - processSequences: string + processSequence: string unitCategories: string comments: string @@ -38,7 +38,7 @@ module Assay = "technologyPlatform", Encode.string "sdo:measurementMethod" "dataFiles", Encode.string "sdo:hasPart" "performers", Encode.string "sdo:creator" - "processSequences", Encode.string "sdo:about" + "processSequence", Encode.string "sdo:about" "comments", Encode.string "sdo:comment" "filename", Encode.string "sdo:url" diff --git a/tests/Json/Process/ProcessInput.Tests.fs b/tests/Json/Process/ProcessInput.Tests.fs index 953ba597..e1633172 100644 --- a/tests/Json/Process/ProcessInput.Tests.fs +++ b/tests/Json/Process/ProcessInput.Tests.fs @@ -1,4 +1,4 @@ -module Tests.Process.ProcessInput +module Tests.Process.ProcessInput open ARCtrl open ARCtrl.Process @@ -22,7 +22,23 @@ let private tests_source = let actual = o_out Expect.stringEqual actual expected "Written processInput does not match read process input" ) + testCase "LD_WriteReadWithCharacteristics" (fun () -> + let charaHeader = Process.MaterialAttribute.create(CharacteristicType = OntologyAnnotation.create("MyAnnotation","NCIT","http://purl.obolibrary.org/obo/NCIT_C42781")) + let charaValue = OntologyAnnotation.create("MyAnnotationValue","NCIT","http://purl.obolibrary.org/obo/NCIT_C42782") + let chara = Process.MaterialAttributeValue.create(Category = charaHeader, Value = Value.Ontology charaValue) + let source = Source.create(Name = "#sample/sample-P-0.1-aliquot7", Characteristics = [chara]) + let o_out = ProcessInput.ROCrate.encoder (ProcessInput.Source source) |> Encode.toJsonString 0 + let inputPI = Decode.fromJsonString ProcessInput.ROCrate.decoder o_out + let inputSourceOpt = ProcessInput.trySource inputPI + let inputSource = Expect.wantSome inputSourceOpt "Input is not a sample" + Expect.equal inputSource.Name source.Name "Sample name did not match" + let characteristics = Expect.wantSome inputSource.Characteristics "No characteristics found" + Expect.hasLength characteristics 1 "Sample characteristics length did not match" + let inputChara = characteristics.[0] + Expect.equal inputChara chara "Sample characteristic did not match" + ) ] + let private tests_material = testList "Material" [ testCase "ReaderSuccess" (fun () -> @@ -75,6 +91,21 @@ let private tests_sample = let actual = o_out Expect.stringEqual actual expected "Written processInput does not match read process input" ) + testCase "LD_WriteReadWithCharacteristics" (fun () -> + let charaHeader = Process.MaterialAttribute.create(CharacteristicType = OntologyAnnotation.create("MyAnnotation","NCIT","http://purl.obolibrary.org/obo/NCIT_C42781")) + let charaValue = OntologyAnnotation.create("MyAnnotationValue","NCIT","http://purl.obolibrary.org/obo/NCIT_C42782") + let chara = Process.MaterialAttributeValue.create(Category = charaHeader, Value = Value.Ontology charaValue) + let sample = Sample.create(Name = "#sample/sample-P-0.1-aliquot7", Characteristics = [chara]) + let o_out = ProcessInput.ROCrate.encoder (ProcessInput.Sample sample) |> Encode.toJsonString 0 + let inputPI = Decode.fromJsonString ProcessInput.ROCrate.decoder o_out + let inputSampleOpt = ProcessInput.trySample inputPI + let inputSample = Expect.wantSome inputSampleOpt "Input is not a sample" + Expect.equal inputSample.Name sample.Name "Sample name did not match" + let characteristics = Expect.wantSome inputSample.Characteristics "No characteristics found" + Expect.hasLength characteristics 1 "Sample characteristics length did not match" + let inputChara = characteristics.[0] + Expect.equal inputChara chara "Sample characteristic did not match" + ) ]