Skip to content

Commit

Permalink
several fixes for xlsx io
Browse files Browse the repository at this point in the history
  • Loading branch information
HLWeil committed Oct 11, 2021
1 parent f60edbd commit 3fd7fca
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 90 deletions.
21 changes: 15 additions & 6 deletions src/ISADotNet.XLSX/AssayFile/MetaData.fs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,19 @@ module MetaData =
failwith "emptyInvestigationFile"


let rowOfSparseRow (vs : SparseRow) =
vs
|> Seq.fold (fun r (i,v) -> Row.insertValueAt None (uint32 (i+1)) v r) (Row.empty())

/// Diesen Block durch JS ersetzen ---->
/// Creates a new row from the given values.
let ofSparseValues rowIndex (vals : 'T option seq) =
let spans = Row.Spans.fromBoundaries 1u (Seq.length vals |> uint)
vals
|> Seq.mapi (fun i value ->
value
|> Option.map (Cell.fromValue None (i + 1 |> uint) rowIndex)
)
|> Seq.choose id
|> Row.create rowIndex spans

/// Append an assay metadata sheet with the given sheetname to an existing assay file excel spreadsheet
let init sheetName (doc: DocumentFormat.OpenXml.Packaging.SpreadsheetDocument) =

Expand All @@ -65,8 +72,10 @@ module MetaData =

toRows Assay.empty [personWithComment]
|> Seq.mapi (fun i row ->
rowOfSparseRow row
|> Row.updateRowIndex (i+1 |> uint))
row
|> SparseRow.getAllValues
|> ofSparseValues (i+1 |> uint)
)
|> Seq.fold (fun s r ->
SheetData.appendRow r s
) sheet
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/Assays.fs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ module Assays =
)

let toSparseTable (assays: Assay list) =
let matrix = SparseTable.Create (keys = labels,length=assays.Length)
let matrix = SparseTable.Create (keys = labels,length=assays.Length + 1)
let mutable commentKeys = []
assays
|> List.iteri (fun i a ->
let i = i + 1
let measurementType,measurementSource,measurementAccession = Option.defaultValue OntologyAnnotation.empty a.MeasurementType |> OntologyAnnotation.toString
let technologyType,technologySource,technologyAccession = Option.defaultValue OntologyAnnotation.empty a.TechnologyType |> OntologyAnnotation.toString
do matrix.Matrix.Add ((measurementTypeLabel,i), measurementType)
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/Contacts.fs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ module Contacts =
)

let toSparseTable (persons:Person list) =
let matrix = SparseTable.Create (keys = labels,length=persons.Length)
let matrix = SparseTable.Create (keys = labels,length=persons.Length + 1)
let mutable commentKeys = []
persons
|> List.iteri (fun i p ->
let i = i + 1
let role,rolesTermSourceREF,rolesTermAccessionNumber = Option.defaultValue [] p.Roles |> OntologyAnnotation.toAggregatedStrings ';'
do matrix.Matrix.Add ((lastNameLabel,i), (Option.defaultValue "" p.LastName ))
do matrix.Matrix.Add ((firstNameLabel,i), (Option.defaultValue "" p.FirstName ))
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/DesignDescriptors.fs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ module DesignDescriptors =
)

let toSparseTable (designs: OntologyAnnotation list) =
let matrix = SparseTable.Create (keys = labels,length=designs.Length)
let matrix = SparseTable.Create (keys = labels,length=designs.Length + 1)
let mutable commentKeys = []
designs
|> List.iteri (fun i d ->
let i = i + 1
let name,source,accession = OntologyAnnotation.toString d
do matrix.Matrix.Add ((designTypeLabel,i), name)
do matrix.Matrix.Add ((designTypeTermAccessionNumberLabel,i), accession)
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/Factors.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ module Factors =
)

let toSparseTable (factors: Factor list) =
let matrix = SparseTable.Create (keys = labels,length=factors.Length)
let matrix = SparseTable.Create (keys = labels,length=factors.Length + 1)
let mutable commentKeys = []
factors
|> List.iteri (fun i f ->
let i = i + 1
let factorType,source,accession = f.FactorType |> Option.defaultValue OntologyAnnotation.empty |> OntologyAnnotation.toString
do matrix.Matrix.Add ((nameLabel,i), (Option.defaultValue "" f.Name))
do matrix.Matrix.Add ((factorTypeLabel,i), factorType)
Expand Down
23 changes: 16 additions & 7 deletions src/ISADotNet.XLSX/InvestigationFile/Investigation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ module Investigation =


static member ToSparseTable (investigation: Investigation) =
let i = 0
let matrix = SparseTable.Create (keys = InvestigationInfo.Labels,length=1)
let i = 1
let matrix = SparseTable.Create (keys = InvestigationInfo.Labels,length=2)
let mutable commentKeys = []

do matrix.Matrix.Add ((identifierLabel,i), (Option.defaultValue "" investigation.Identifier))
Expand Down Expand Up @@ -191,9 +191,16 @@ module Investigation =

/// Diesen Block durch JS ersetzen ---->
let rowOfSparseRow (vs : SparseRow) =
vs
|> Seq.fold (fun r (i,v) -> Row.insertValueAt None (uint32 (i+1)) v r) (Row.empty())
/// Creates a new row from the given values.
let ofSparseValues rowIndex (vals : 'T option seq) =
let spans = Row.Spans.fromBoundaries 1u (Seq.length vals |> uint)
vals
|> Seq.mapi (fun i value ->
value
|> Option.map (Cell.fromValue None (i + 1 |> uint) rowIndex)
)
|> Seq.choose id
|> Row.create rowIndex spans

let fromSpreadsheet (doc:DocumentFormat.OpenXml.Packaging.SpreadsheetDocument) =
doc
Expand Down Expand Up @@ -224,8 +231,10 @@ module Investigation =
investigation
|> toRows
|> Seq.mapi (fun i row ->
rowOfSparseRow row
|> Row.updateRowIndex (i+1 |> uint))
row
|> SparseRow.getAllValues
|> ofSparseValues (i+1 |> uint)
)
|> Seq.fold (fun s r ->
SheetData.appendRow r s
) sheet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ module OntologySourceReference =
)

let toSparseTable (ontologySources: OntologySourceReference list) =
let matrix = SparseTable.Create (keys = labels,length=ontologySources.Length)
let matrix = SparseTable.Create (keys = labels,length=ontologySources.Length + 1)
let mutable commentKeys = []
ontologySources
|> List.iteri (fun i o ->
let i = i + 1
do matrix.Matrix.Add ((nameLabel,i), (Option.defaultValue "" o.Name))
do matrix.Matrix.Add ((fileLabel,i), (Option.defaultValue "" o.File))
do matrix.Matrix.Add ((versionLabel,i), (Option.defaultValue "" o.Version))
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/Protocols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ module Protocols =
)

let toSparseTable (protocols: Protocol list) =
let matrix = SparseTable.Create (keys = labels,length=protocols.Length)
let matrix = SparseTable.Create (keys = labels,length=protocols.Length + 1)
let mutable commentKeys = []
protocols
|> List.iteri (fun i p ->
let i = i + 1
let protocolType,protocolSource,protocolAccession = p.ProtocolType |> Option.defaultValue OntologyAnnotation.empty |> OntologyAnnotation.toString
let parameterType,parameterSource,parameterAccession = p.Parameters |> Option.defaultValue [] |> ProtocolParameter.toAggregatedStrings ';'
let componentName,componentType,componentSource,componentAccession = p.Components |> Option.defaultValue [] |> Component.toAggregatedStrings ';'
Expand Down
3 changes: 2 additions & 1 deletion src/ISADotNet.XLSX/InvestigationFile/Publication.fs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ module Publications =
)

let toSparseTable (publications: Publication list) =
let matrix = SparseTable.Create (keys = labels,length=publications.Length)
let matrix = SparseTable.Create (keys = labels,length=publications.Length + 1)
let mutable commentKeys = []
publications
|> List.iteri (fun i p ->
let i = i + 1
let status,source,accession = Option.defaultValue OntologyAnnotation.empty p.Status |> OntologyAnnotation.toString
do matrix.Matrix.Add ((pubMedIDLabel,i), (Option.defaultValue "" p.PubMedID))
do matrix.Matrix.Add ((doiLabel,i), (Option.defaultValue "" p.DOI))
Expand Down
32 changes: 14 additions & 18 deletions src/ISADotNet.XLSX/InvestigationFile/SparseTable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type SparseTable =
Matrix : Dictionary<string*int,string>
Keys : string list
CommentKeys : string list
///Column Count
Length : int
}

Expand All @@ -51,14 +52,11 @@ type SparseTable =
}

static member AddRow key (values:seq<int*string>) (matrix : SparseTable) =
let values =
values
|> Seq.map (fun (i,v) ->
let i = i-1
matrix.Matrix.Add((key,i),v)
i,v
)
|> Seq.toArray

values
|> Seq.iter (fun (i,v) ->
matrix.Matrix.Add((key,i),v)
)

let length =
if Seq.isEmpty values then 0
Expand All @@ -70,14 +68,12 @@ type SparseTable =
}

static member AddComment key (values:seq<int*string>) (matrix : SparseTable) =
let values =
values
|> Seq.map (fun (i,v) ->
let i = i-1
matrix.Matrix.Add((key,i),v)
i,v
)
|> Seq.toArray

values
|> Seq.iter (fun (i,v) ->
matrix.Matrix.Add((key,i),v)
)

let length =
if Seq.isEmpty values then 0
else Seq.maxBy fst values |> fst |> (+) 1
Expand Down Expand Up @@ -115,8 +111,8 @@ type SparseTable =
let prefix = match prefix with | Some p -> p + " " | None -> ""
seq {
for key in matrix.Keys do
(SparseRow.fromValues (prefix + key :: List.init matrix.Length (fun i -> matrix.TryGetValueDefault("",(key,i)))))
(SparseRow.fromValues (prefix + key :: List.init (matrix.Length - 1) (fun i -> matrix.TryGetValueDefault("",(key,i + 1)))))
for key in matrix.CommentKeys do
(SparseRow.fromValues (Comment.wrapCommentKey key :: List.init matrix.Length (fun i -> matrix.TryGetValueDefault("",(key,i)))))
(SparseRow.fromValues (Comment.wrapCommentKey key :: List.init (matrix.Length - 1) (fun i -> matrix.TryGetValueDefault("",(key,i + 1)))))
}

4 changes: 2 additions & 2 deletions src/ISADotNet.XLSX/InvestigationFile/Study.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ module Study =


static member ToSparseTable (study: Study) =
let i = 0
let matrix = SparseTable.Create (keys = StudyInfo.Labels,length = 1)
let i = 1
let matrix = SparseTable.Create (keys = StudyInfo.Labels,length = 2)
let mutable commentKeys = []

do matrix.Matrix.Add ((identifierLabel,i), (Option.defaultValue "" study.Identifier))
Expand Down
98 changes: 49 additions & 49 deletions tests/ISADotNet.Tests/ISADotNet.XLSX/InvestigationFileTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -340,21 +340,21 @@ let testStringConversions =
|> testSequenced

[<Tests>]
let testSparseMatrix =
let testSparseTable =

testList "SparseMatrixTests" [
testList "SparseTableTests" [

testCase "Create" (fun () ->

let keys = ["A";"B"]
let length = 2

let sparseMatrix = SparseMatrix.Create(keys = keys,length = length)
let sparseTable = SparseTable.Create(keys = keys,length = length)

Expect.equal sparseMatrix.Matrix.Count 0 "Dictionary was not empty"
Expect.equal sparseMatrix.Keys keys "Keys were not taken properly"
Expect.equal sparseMatrix.CommentKeys [] "Comment keys should be empty"
Expect.equal sparseMatrix.Length length "Length did not match"
Expect.equal sparseTable.Matrix.Count 0 "Dictionary was not empty"
Expect.equal sparseTable.Keys keys "Keys were not taken properly"
Expect.equal sparseTable.CommentKeys [] "Comment keys should be empty"
Expect.equal sparseTable.Length length "Length did not match"

)

Expand All @@ -363,23 +363,23 @@ let testSparseMatrix =
let firstKey,firstRow = "Greetings",[1,"Hello";2,"Bye"]
let secondKey,secondRow = "AndAgain",[4,"Hello Again"]

let sparseMatrixFirstRow =
SparseMatrix.Create()
|> SparseMatrix.AddRow firstKey firstRow
let sparseTableFirstRow =
SparseTable.Create()
|> SparseTable.AddRow firstKey firstRow

Expect.equal sparseMatrixFirstRow.Matrix.Count 2 "FirstRowAdded: Dictionary was not empty"
Expect.equal sparseMatrixFirstRow.Keys [firstKey] "FirstRowAdded: Keys were not updated properly"
Expect.equal sparseMatrixFirstRow.CommentKeys [] "FirstRowAdded: Comment keys should be empty"
Expect.equal sparseMatrixFirstRow.Length 2 "FirstRowAdded: Length did not update according to item count"
Expect.equal sparseTableFirstRow.Matrix.Count 2 "FirstRowAdded: Dictionary was not empty"
Expect.equal sparseTableFirstRow.Keys [firstKey] "FirstRowAdded: Keys were not updated properly"
Expect.equal sparseTableFirstRow.CommentKeys [] "FirstRowAdded: Comment keys should be empty"
Expect.equal sparseTableFirstRow.Length 3 "FirstRowAdded: Length did not update according to item count"

let sparseMatrixSecondRow =
sparseMatrixFirstRow
|> SparseMatrix.AddRow secondKey secondRow
let sparseTableSecondRow =
sparseTableFirstRow
|> SparseTable.AddRow secondKey secondRow

Expect.equal sparseMatrixSecondRow.Matrix.Count 3 "SecondRowAdded: Dictionary was not empty"
Expect.equal sparseMatrixSecondRow.Keys [firstKey;secondKey] "SecondRowAdded: Keys were not updated properly"
Expect.equal sparseMatrixSecondRow.CommentKeys [] "SecondRowAdded: Comment keys should be empty"
Expect.equal sparseMatrixSecondRow.Length 4 "SecondRowAdded: Length did not update according to item count"
Expect.equal sparseTableSecondRow.Matrix.Count 3 "SecondRowAdded: Dictionary was not empty"
Expect.equal sparseTableSecondRow.Keys [firstKey;secondKey] "SecondRowAdded: Keys were not updated properly"
Expect.equal sparseTableSecondRow.CommentKeys [] "SecondRowAdded: Comment keys should be empty"
Expect.equal sparseTableSecondRow.Length 5 "SecondRowAdded: Length did not update according to item count"

)

Expand All @@ -390,25 +390,25 @@ let testSparseMatrix =
let firstComment,firstCommentRow = "CommentSameLength",[1,"Lel";2,"Lal";3,"Lul"]
let secondComment,secondCommentRow = "CommentLonger",[2,"Lal";5,"Sho"]

let sparseMatrixFirstComment =
SparseMatrix.Create()
|> SparseMatrix.AddRow firstKey firstRow
|> SparseMatrix.AddRow secondKey secondRow
|> SparseMatrix.AddComment firstComment firstCommentRow

Expect.equal sparseMatrixFirstComment.Matrix.Count 6 "FirstCommentAdded: Dictionary was not empty"
Expect.equal sparseMatrixFirstComment.Keys [firstKey;secondKey] "FirstCommentAdded: Keys were not updated properly"
Expect.equal sparseMatrixFirstComment.CommentKeys [firstComment] "FirstCommentAdded: Comment keys should be empty"
Expect.equal sparseMatrixFirstComment.Length 4 "FirstCommentAdded: Length did not update according to item count"

let sparseMatrixSecondComment =
sparseMatrixFirstComment
|> SparseMatrix.AddComment secondComment secondCommentRow

Expect.equal sparseMatrixSecondComment.Matrix.Count 8 "SecondCommentAdded: Dictionary was not empty"
Expect.equal sparseMatrixSecondComment.Keys [firstKey;secondKey] "SecondCommentAdded: Keys were not update properly"
Expect.equal sparseMatrixSecondComment.CommentKeys [firstComment;secondComment] "SecondCommentAdded: Comment keys should be empty"
Expect.equal sparseMatrixSecondComment.Length 5 "SecondCommentAdded: Length did not update according to item count"
let sparseTableFirstComment =
SparseTable.Create()
|> SparseTable.AddRow firstKey firstRow
|> SparseTable.AddRow secondKey secondRow
|> SparseTable.AddComment firstComment firstCommentRow

Expect.equal sparseTableFirstComment.Matrix.Count 6 "FirstCommentAdded: Dictionary was not empty"
Expect.equal sparseTableFirstComment.Keys [firstKey;secondKey] "FirstCommentAdded: Keys were not updated properly"
Expect.equal sparseTableFirstComment.CommentKeys [firstComment] "FirstCommentAdded: Comment keys should be empty"
Expect.equal sparseTableFirstComment.Length 5 "FirstCommentAdded: Length did not update according to item count"

let sparseTableSecondComment =
sparseTableFirstComment
|> SparseTable.AddComment secondComment secondCommentRow

Expect.equal sparseTableSecondComment.Matrix.Count 8 "SecondCommentAdded: Dictionary was not empty"
Expect.equal sparseTableSecondComment.Keys [firstKey;secondKey] "SecondCommentAdded: Keys were not update properly"
Expect.equal sparseTableSecondComment.CommentKeys [firstComment;secondComment] "SecondCommentAdded: Comment keys should be empty"
Expect.equal sparseTableSecondComment.Length 6 "SecondCommentAdded: Length did not update according to item count"
)
|> testSequenced

Expand All @@ -419,12 +419,12 @@ let testSparseMatrix =
let firstComment,firstCommentRow = "CommentSameLength",[1,"Lel";2,"Lal";3,"Lul"]
let secondComment,secondCommentRow = "CommentLonger",[2,"Lal";5,"Sho"]

let sparseMatrix =
SparseMatrix.Create()
|> SparseMatrix.AddRow firstKey firstRow
|> SparseMatrix.AddRow secondKey secondRow
|> SparseMatrix.AddComment firstComment firstCommentRow
|> SparseMatrix.AddComment secondComment secondCommentRow
let sparseTable =
SparseTable.Create()
|> SparseTable.AddRow firstKey firstRow
|> SparseTable.AddRow secondKey secondRow
|> SparseTable.AddComment firstComment firstCommentRow
|> SparseTable.AddComment secondComment secondCommentRow


let testRows =
Expand All @@ -435,11 +435,11 @@ let testSparseMatrix =
Comment.wrapCommentKey secondComment :: List.init 5 (fun i -> match Seq.tryFind (fst >> (=) (i+1)) secondCommentRow with | Some (_,v) -> v | None -> "")
]

sparseMatrix
|> SparseMatrix.ToRows
sparseTable
|> SparseTable.ToRows
|> Seq.iteri (fun i r ->
let testSeq = Seq.item i testRows
Expect.sequenceEqual (Row.getRowValues None r) testSeq ""
Expect.sequenceEqual (SparseRow.getValues r) testSeq ""

)

Expand Down
Loading

0 comments on commit 3fd7fca

Please sign in to comment.