Skip to content

Commit 2d9967d

Browse files
authored
Merge pull request #20 from CSBiology/feature-ontology-#6
Additional functionality & bugfixes
2 parents 73a0caf + 0e4fe27 commit 2d9967d

File tree

9 files changed

+708
-109
lines changed

9 files changed

+708
-109
lines changed

src/Ontology.NET/OBO/OboOntology.fs

Lines changed: 190 additions & 1 deletion
Large diffs are not rendered by default.

src/Ontology.NET/OBO/OboTerm.fs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
namespace Ontology.NET.OBO
22

33

4+
open System
5+
open System.Text.RegularExpressions
6+
47
open DBXref
58
open TermSynonym
69

7-
open System
8-
910
open ControlledVocabulary
1011
open FSharpAux
1112

@@ -517,10 +518,21 @@ type OboTerm =
517518

518519
/// Takes a relationship and returns a tuple consisting of the name of the relationship and the ID of the OboTerm it matches.
519520
static member deconstructRelationship relationship =
520-
let pattern = System.Text.RegularExpressions.Regex @"^(?<relName>.+?) (?<id>[^ ]+:\d+)(?: .*)?$"
521+
let pattern = Regex @"^(?<relName>.+?) (?<id>[^ ]+:\d+)(?: .*)?$"
521522
let regexMatch = pattern.Match relationship
522523
regexMatch.Groups["relName"].Value, regexMatch.Groups["id"].Value
523524

525+
/// <summary>
526+
/// Takes the ID of a target term and the name of a relationship and constructs the relationship from them.
527+
/// </summary>
528+
/// <param name="targetTermId">The ID of the term that the relationship targets.</param>
529+
/// <param name="relationshipName">The name of the relationship, e.g. "part_of".</param>
530+
static member constructRelationship targetTermId relationshipName =
531+
let whiteSpacePattern = Regex(@"\s")
532+
if whiteSpacePattern.Match(relationshipName).Success then
533+
raise (System.ArgumentException($"relationshipName {relationshipName} must not contain white spaces.", relationshipName))
534+
$"{targetTermId} {relationshipName}"
535+
524536
/// Returns the OboTerm's relationships as a triple consisting of the term's ID, the name of the relationship, and the related term's ID.
525537
member this.GetRelatedTermIds() =
526538
this.Relationships

src/Ontology.NET/Ontology.fs

Lines changed: 225 additions & 60 deletions
Large diffs are not rendered by default.

src/Ontology.NET/OntologyRelation.fs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,37 @@ type RelationType =
1111
| Term of CvTerm
1212
| Custom of string
1313

14+
with
15+
/// <summary>
16+
/// Creates a RelationType from a given string.
17+
/// </summary>
18+
/// <param name="str">The string that is used to create a RelationType.</param>
19+
static member fromString (str : string) =
20+
match str.ToLower() with
21+
| "is_a"
22+
| "is a"
23+
| "isa" -> IsA
24+
| "xref"
25+
| "x_ref"
26+
| "x ref" -> Xref
27+
| _ -> Custom str
28+
29+
/// <summary>
30+
/// Returns the RelationType as a string.
31+
/// </summary>
32+
override this.ToString() : string =
33+
match this with
34+
| IsA -> "is_a"
35+
| Xref -> "xref"
36+
| Custom r -> r
37+
| Term cvt -> cvt.Name
38+
39+
/// <summary>
40+
/// Returns a RelationType as a string.
41+
/// </summary>
42+
static member toString (rt : RelationType) =
43+
rt.ToString()
44+
1445

1546
/// Model for a generic ontological relation. Consists of fields RelationType that inhabits the type of the relation, and Target for the targeted CvTerm of the relation.
1647
type OntologyRelation = {

tests/Ontology.NET.Tests/OBO/OboOntology.Tests.fs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,25 +71,25 @@ module OboOntologyTests =
7171
Expect.isSome testFile2 $"Could not read testFile2: {testFile2Path}"
7272
Expect.isSome testFile3 $"Could not read testFile3: {testFile3Path}"
7373
testCase "reads correct headers correctly" <| fun _ ->
74-
let formatVersionActual = Option.map (fun o -> o.FormatVersion) testFile1
75-
let dataVersionActual = Option.map (fun o -> o.DataVersion) testFile1 |> Option.flatten
76-
let ontologyActual = Option.map (fun o -> o.Ontology) testFile1 |> Option.flatten
77-
let dateActual = Option.map (fun o -> o.Date) testFile1 |> Option.flatten
78-
let savedByActual = Option.map (fun o -> o.SavedBy) testFile1 |> Option.flatten
79-
let autoGeneratedByActual = Option.map (fun o -> o.AutoGeneratedBy) testFile1 |> Option.flatten
80-
let subsetdefsActual = Option.map (fun o -> o.Subsetdefs) testFile1
81-
let importsActual = Option.map (fun o -> o.Imports) testFile1
82-
let synonymtypedefsActual = Option.map (fun o -> o.Synonymtypedefs) testFile1
83-
let idSpacesActual = Option.map (fun o -> o.Idspaces) testFile1
84-
let defaultRelationshipIdPrefixActual = Option.map (fun o -> o.DefaultRelationshipIdPrefix) testFile1 |> Option.flatten
85-
let idMappingsActual = Option.map (fun o -> o.IdMappings) testFile1
86-
let remarksActual = Option.map (fun o -> o.Remarks) testFile1
87-
let treatXrefsAsEquivalentsActual = Option.map (fun o -> o.TreatXrefsAsEquivalents) testFile1
88-
let treatXrefsAsGenusDifferentiasActual = Option.map (fun o -> o.TreatXrefsAsGenusDifferentias) testFile1
89-
let treatXrefsAsRelationshipsActual = Option.map (fun o -> o.TreatXrefsAsRelationships) testFile1
90-
let treatXrefsAsIsAsActual = Option.map (fun o -> o.TreatXrefsAsIsAs) testFile1
91-
let relaxUniqueIdentifierAssumptionForNamespacesActual = Option.map (fun o -> o.RelaxUniqueIdentifierAssumptionForNamespaces) testFile1
92-
let relaxUniqueLabelAssumptionForNamespacesActual = Option.map (fun o -> o.RelaxUniqueLabelAssumptionForNamespaces) testFile1
74+
let formatVersionActual = testFile1 |> Option.map (fun o -> o.FormatVersion)
75+
let dataVersionActual = testFile1 |> Option.map (fun o -> o.DataVersion) |> Option.flatten
76+
let ontologyActual = testFile1 |> Option.map (fun o -> o.Ontology) |> Option.flatten
77+
let dateActual = testFile1 |> Option.map (fun o -> o.Date) |> Option.flatten
78+
let savedByActual = testFile1 |> Option.map (fun o -> o.SavedBy) |> Option.flatten
79+
let autoGeneratedByActual = testFile1 |> Option.map (fun o -> o.AutoGeneratedBy) |> Option.flatten
80+
let subsetdefsActual = testFile1 |> Option.map (fun o -> o.Subsetdefs)
81+
let importsActual = testFile1 |> Option.map (fun o -> o.Imports)
82+
let synonymtypedefsActual = testFile1 |> Option.map (fun o -> o.Synonymtypedefs)
83+
let idSpacesActual = testFile1 |> Option.map (fun o -> o.Idspaces)
84+
let defaultRelationshipIdPrefixActual = testFile1 |> Option.map (fun o -> o.DefaultRelationshipIdPrefix) |> Option.flatten
85+
let idMappingsActual = testFile1 |> Option.map (fun o -> o.IdMappings)
86+
let remarksActual = testFile1 |> Option.map (fun o -> o.Remarks)
87+
let treatXrefsAsEquivalentsActual = testFile1 |> Option.map (fun o -> o.TreatXrefsAsEquivalents)
88+
let treatXrefsAsGenusDifferentiasActual = testFile1 |> Option.map (fun o -> o.TreatXrefsAsGenusDifferentias)
89+
let treatXrefsAsRelationshipsActual = testFile1 |> Option.map (fun o -> o.TreatXrefsAsRelationships)
90+
let treatXrefsAsIsAsActual = testFile1 |> Option.map (fun o -> o.TreatXrefsAsIsAs)
91+
let relaxUniqueIdentifierAssumptionForNamespacesActual = testFile1 |> Option.map (fun o -> o.RelaxUniqueIdentifierAssumptionForNamespaces)
92+
let relaxUniqueLabelAssumptionForNamespacesActual = testFile1 |> Option.map (fun o -> o.RelaxUniqueLabelAssumptionForNamespaces)
9393
let formatVersionExpected = "0.0.1" |> Some
9494
let dataVersionExpected = "0.0.1" |> Some
9595
let ontologyExpected = "CL" |> Some
@@ -129,7 +129,7 @@ module OboOntologyTests =
129129
Expect.equal relaxUniqueIdentifierAssumptionForNamespacesActual relaxUniqueIdentifierAssumptionForNamespaceExpected "relax-unique-identifier-assumption-for-namespaces are not identical"
130130
Expect.equal relaxUniqueLabelAssumptionForNamespacesActual relaxUniqueLabelAssumptionForNamespaceExpected "relax-unique-label-assumption-for-namespaces are not identical"
131131
testCase "reads incorrect headers correctly" <| fun _ ->
132-
Expect.isNone (Option.map (fun o -> o.Date) testFile2 |> Option.flatten) "Date should be missing but was still parsed"
132+
Expect.isNone (testFile2 |> Option.map (fun o -> o.Date) |> Option.flatten) "Date should be missing but was still parsed"
133133
testCase "reads Terms correctly" <| fun _ ->
134134
let termsExpected = List.init 2 (fun i -> OboTerm.Create $"Test:000{i + 1}") |> Some
135135
Expect.equal (Option.map (fun o -> o.Terms) testFile1) termsExpected "Terms did not match"

tests/Ontology.NET.Tests/OBO/OboTerm.Tests.fs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,14 @@ module OboTermTests =
5656
Expect.equal actual.Name expected.Name "Names are different"
5757
Expect.equal actual.Accession expected.Accession "TANs are different"
5858
]
59+
60+
testList "constructRelationship" [
61+
testCase "returns correct relationship string" <| fun _ ->
62+
let actual = OboTerm.constructRelationship "part_of" "TGMA:0000002"
63+
let expected = "part_of TGMA:0000002"
64+
Expect.equal actual expected "relationship strings differ"
65+
66+
testCase "throws when expected" <| fun _ ->
67+
Expect.throws (fun _ -> OboTerm.constructRelationship "TGMA:0000002" "part of" |> ignore) "Did not throw though expected"
68+
]
5969
]

tests/Ontology.NET.Tests/Ontology.NET.Tests.fsproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@
3434
<Compile Include="OBO\OboOntology.Tests.fs" />
3535
<Compile Include="OBO\OboTypeProvider.Tests.fs" />
3636
<Compile Include="ReferenceObjects.fs" />
37+
<Compile Include="RelationType.Tests.fs" />
3738
<Compile Include="Ontology.Tests.fs" />
3839
<Compile Include="Main.fs" />
3940
</ItemGroup>
4041

41-
<ItemGroup />
42-
4342
</Project>

0 commit comments

Comments
 (0)