Skip to content

Commit 1c66f1f

Browse files
committed
refactor return values of assay and study xlsx file readers
1 parent 1a981e9 commit 1c66f1f

5 files changed

Lines changed: 119 additions & 55 deletions

File tree

src/ISADotNet.XLSX/AssayFile/AnnotationTable.fs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open ISADotNet
77
module AnnotationTable =
88

99
/// Returns the protocol described by the headers and a function for parsing the values of the matrix to the processes of this protocol
10-
let getProcessGetter protocolMetaData (nodes : seq<seq<string>>) =
10+
let getProcessGetter (processNameRoot : string) (nodes : seq<seq<string>>) =
1111

1212
let valueNodes =
1313
nodes
@@ -27,6 +27,19 @@ module AnnotationTable =
2727
|> Seq.fold (fun (pl,pvl) (p,pv) -> p.Value :: pl, pv :: pvl) ([],[])
2828
|> fun (l1,l2) -> List.rev l1, List.rev l2
2929

30+
let componentGetters =
31+
valueNodes
32+
|> Seq.choose (fun (i,n) -> AnnotationNode.tryGetComponentGetter i n)
33+
|> Seq.toList
34+
35+
let protocolTypeGetter =
36+
valueNodes
37+
|> Seq.tryPick (fun (i,n) -> AnnotationNode.tryGetProtocolTypeGetter i n)
38+
39+
let protocolREFGetter =
40+
valueNodes
41+
|> Seq.tryPick (fun (i,n) -> AnnotationNode.tryGetProtocolREFGetter i n)
42+
3043
let dataFileGetter = nodes |> Seq.tryPick AnnotationNode.tryGetDataFileGetter
3144

3245
let inputGetter,outputGetter =
@@ -113,15 +126,27 @@ module AnnotationTable =
113126
[ProcessOutput.Sample sample]
114127
inputGetter,outputGetter
115128

116-
let protocol = {protocolMetaData with Parameters = Option.fromValueWithDefault [] parameters}
117-
118-
characteristics,
119-
factors,
120-
protocol,
129+
130+
121131
fun (matrix : System.Collections.Generic.Dictionary<(int * string),string>) i ->
132+
133+
let pn = processNameRoot |> Option.fromValueWithDefault ""
134+
135+
let protocol : Protocol =
136+
Protocol.make
137+
None
138+
(protocolREFGetter |> Option.mapOrDefault pn (fun f -> f matrix i))
139+
(protocolTypeGetter |> Option.map (fun f -> f matrix i))
140+
None
141+
None
142+
None
143+
(Option.fromValueWithDefault [] parameters)
144+
(componentGetters |> List.map (fun f -> f matrix i) |> Option.fromValueWithDefault [])
145+
None
146+
122147
Process.make
123148
None
124-
None
149+
pn
125150
(Some protocol)
126151
(parameterValueGetters |> List.map (fun f -> f matrix i) |> Option.fromValueWithDefault [])
127152
None
@@ -152,9 +177,12 @@ module AnnotationTable =
152177
|> Seq.collect (fun (protocol,processGroup) ->
153178
processGroup
154179
|> Seq.mapi (fun i p ->
155-
{p with Name =
156-
protocol.Value.Name |> Option.map (fun s -> sprintf "%s_%i" s i)
157-
}
180+
let name =
181+
match p.Name with
182+
| Some n -> Some n
183+
| None | Some "" -> protocol |> Option.bind (fun p -> p.Name)
184+
|> Option.map (fun s -> sprintf "%s_%i" s i)
185+
{p with Name = name}
158186
)
159187
)
160188

src/ISADotNet.XLSX/AssayFile/Assay.fs

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ module Process =
2222
let j = kv.Key |> fst
2323
if j > i then i <- j
2424
i + 1
25-
let characteristic,factors,protocol,processGetter =
25+
let processGetter =
2626
AnnotationNode.splitIntoNodes matrixHeaders
27-
|> AnnotationTable.getProcessGetter ({Protocol.empty with Name = Some processNameRoot})
28-
characteristic,factors,protocol,
29-
27+
|> AnnotationTable.getProcessGetter processNameRoot
28+
3029
Seq.init len (processGetter sparseMatrix)
3130
|> AnnotationTable.mergeIdenticalProcesses
3231
|> AnnotationTable.indexRelatedProcessesByProtocolName
@@ -54,25 +53,22 @@ module Assay =
5453
/// sparseMatrix is a sparse representation of the sheet table, with the first part of the key being the column header and the second part being a zero based row index
5554
let fromSparseMatrix (processNameRoot:string) matrixHeaders (sparseMatrix : Dictionary<int*string,string>) =
5655

57-
let characteristics,factors,protocols,processes = Process.fromSparseMatrix processNameRoot matrixHeaders sparseMatrix
58-
factors,protocols,Assay.create(CharacteristicCategories = characteristics,ProcessSequence = Seq.toList processes)
56+
let processes = Process.fromSparseMatrix processNameRoot matrixHeaders sparseMatrix
57+
let characteristics = API.ProcessSequence.getCharacteristics processes
58+
Assay.create(CharacteristicCategories = characteristics,ProcessSequence = Seq.toList processes)
5959

6060

6161
/// Returns an assay from a sequence of sparseMatrix representations of assay.xlsx sheets
6262
///
6363
/// See "fromSparseMatrix" function for parameter documentation
6464
let fromSparseMatrices (sheets : (string*(string seq)*Dictionary<int*string,string>) seq) =
65-
let characteristics,factors,protocols,processes =
65+
let processes =
6666
sheets
67-
|> Seq.map (fun (name,matrixHeaders,matrix) -> Process.fromSparseMatrix name matrixHeaders matrix)
68-
|> Seq.fold (fun (characteristics',factors',protocols',processes') (characteristics,factors,protocol,processes) ->
69-
List.append characteristics' characteristics |> List.distinct,
70-
List.append factors' factors |> List.distinct,
71-
Seq.append protocols' (Seq.singleton protocol),
72-
Seq.append processes' processes
73-
) (List.empty,List.empty,Seq.empty,Seq.empty)
67+
|> Seq.collect (fun (name,matrixHeaders,matrix) -> Process.fromSparseMatrix name matrixHeaders matrix)
68+
|> AnnotationTable.updateSamplesByThemselves
69+
|> Seq.toList
7470

75-
let processes = AnnotationTable.updateSamplesByThemselves processes |> Seq.toList
71+
let characteristics = API.ProcessSequence.getCharacteristics processes
7672

7773
let assay =
7874
match characteristics,processes with
@@ -81,7 +77,7 @@ module Assay =
8177
| cs,[] -> Assay.create(CharacteristicCategories = cs)
8278
| cs,ps -> Assay.create(CharacteristicCategories = cs,ProcessSequence = ps)
8379

84-
factors,protocols,assay
80+
assay
8581

8682
/// Diesen Block durch JS ersetzen ---->
8783
@@ -131,7 +127,7 @@ module Assay =
131127
|> Sheet.Sheets.getSheets
132128
|> Seq.map Sheet.getName
133129

134-
let factors,protocols,assay =
130+
let assay =
135131
sheetNames
136132
|> Seq.collect (fun sheetName ->
137133
match Spreadsheet.tryGetWorksheetPartBySheetName sheetName doc with
@@ -148,8 +144,6 @@ module Assay =
148144
)
149145
|> fromSparseMatrices // Feed the sheets (represented as sparse matrices) into the assay parser function
150146

151-
factors,
152-
protocols |> Seq.toList,
153147
contacts,
154148
API.Update.UpdateByExisting.updateRecordType assayMetaData assay // Merges the assay containing the assay meta data and the assay containing the processes retrieved from the sheets
155149
with

src/ISADotNet.XLSX/StudyFile/Study.fs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,24 @@ module Study =
2525
///
2626
/// sparseMatrix is a sparse representation of the sheet table, with the first part of the key being the column header and the second part being a zero based row index
2727
let fromSparseMatrix (processNameRoot:string) matrixHeaders (sparseMatrix : Dictionary<int*string,string>) =
28-
let characteristics,factors,protocol,processes = ISADotNet.XLSX.AssayFile.Process.fromSparseMatrix processNameRoot matrixHeaders sparseMatrix
29-
Study.create(CharacteristicCategories = characteristics,Factors = factors, Protocols = [protocol], ProcessSequence = processes)
28+
let processes = ISADotNet.XLSX.AssayFile.Process.fromSparseMatrix processNameRoot matrixHeaders sparseMatrix
29+
let characteristics = API.ProcessSequence.getCharacteristics processes
30+
let factors = API.ProcessSequence.getFactors processes
31+
let protocols = API.ProcessSequence.getProtocols processes
32+
Study.create(CharacteristicCategories = characteristics,Factors = factors, Protocols = protocols, ProcessSequence = processes)
3033

3134
/// Returns a study from a sequence of sparseMatrix representations of study.xlsx sheets
3235
///
3336
/// See "fromSparseMatrix" function for parameter documentation
3437
let fromSparseMatrices (sheets : (string*(string seq)*Dictionary<int*string,string>) seq) =
35-
let characteristics,factors,protocols,processes =
38+
let processes =
3639
sheets
37-
|> Seq.map (fun (name,matrixHeaders,matrix) -> ISADotNet.XLSX.AssayFile.Process.fromSparseMatrix name matrixHeaders matrix)
38-
|> Seq.fold (fun (characteristics',factors',protocols',processes') (characteristics,factors,protocol,processes) ->
39-
List.append characteristics' characteristics |> List.distinct,
40-
List.append factors' factors |> List.distinct,
41-
List.append protocols' (List.singleton protocol),
42-
List.append processes' processes
43-
) (List.empty,List.empty,List.empty,List.empty)
44-
45-
let processes = ISADotNet.XLSX.AssayFile.AnnotationTable.updateSamplesByThemselves processes |> Seq.toList
46-
40+
|> Seq.collect (fun (name,matrixHeaders,matrix) -> ISADotNet.XLSX.AssayFile.Process.fromSparseMatrix name matrixHeaders matrix)
41+
|> ISADotNet.XLSX.AssayFile.AnnotationTable.updateSamplesByThemselves
42+
|> Seq.toList
43+
let characteristics = API.ProcessSequence.getCharacteristics processes
44+
let factors = API.ProcessSequence.getFactors processes
45+
let protocols = API.ProcessSequence.getProtocols processes
4746
Study.create(CharacteristicCategories = characteristics,Factors = factors, Protocols = protocols, ProcessSequence = processes)
4847

4948
// Diesen Block durch JS ersetzen ---->

src/ISADotnet/API/Assay.fs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,9 @@ module Assay =
208208
/// Returns the factors implemented by the processes contained in this assay
209209
let getFactors (assay : Assay) =
210210
assay.ProcessSequence
211-
|> Option.map ProcessSequence.getFactors
211+
|> Option.map ProcessSequence.getFactors
212+
213+
/// Returns the protocols implemented by the processes contained in this assay
214+
let getProtocols (assay : Assay) =
215+
assay.ProcessSequence
216+
|> Option.map ProcessSequence.getProtocols

src/ISADotnet/API/Process.fs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,18 @@ module ProcessInput =
108108
| _ -> None
109109

110110
/// If given process input contains characteristics, returns them
111-
let tryGetCharacteristics (pi : ProcessInput) =
111+
let tryGetCharacteristicValues (pi : ProcessInput) =
112112
match pi with
113113
| ProcessInput.Sample s -> s.Characteristics
114114
| ProcessInput.Source s -> s.Characteristics
115115
| ProcessInput.Material m -> m.Characteristics
116116
| ProcessInput.Data _ -> None
117117

118+
/// If given process input contains characteristics, returns them
119+
let tryGetCharacteristics (pi : ProcessInput) =
120+
tryGetCharacteristicValues pi
121+
|> Option.map (List.choose (fun c -> c.Category))
122+
118123
/// Functions for handling the ProcessOutput Type
119124
module ProcessOutput =
120125

@@ -174,12 +179,18 @@ module ProcessOutput =
174179

175180

176181
/// If given process output contains characteristics, returns them
177-
let tryGetCharacteristics (po : ProcessOutput) =
182+
let tryGetCharacteristicValues (po : ProcessOutput) =
178183
match po with
179184
| ProcessOutput.Sample s -> s.Characteristics
180185
| ProcessOutput.Material m -> m.Characteristics
181186
| ProcessOutput.Data _ -> None
182187

188+
/// If given process output contains characteristics, returns them
189+
let tryGetCharacteristics (po : ProcessOutput) =
190+
tryGetCharacteristicValues po
191+
|> Option.map (List.choose (fun c -> c.Category))
192+
193+
183194
/// If given process output contains factors, returns them
184195
let tryGetFactorValues (po : ProcessOutput) =
185196
match po with
@@ -209,6 +220,29 @@ module Process =
209220
|> List.choose (fun pv -> pv.Category)
210221
| None -> []
211222

223+
/// Returns the characteristics describing the inputs of the process
224+
let getInputCharacteristics (p: Process) =
225+
match p.Inputs with
226+
| Some ins ->
227+
ins
228+
|> List.collect (fun inp -> ProcessInput.tryGetCharacteristics inp |> Option.defaultValue [])
229+
|> List.distinct
230+
| None -> []
231+
232+
/// Returns the characteristics describing the outputs of the process
233+
let getOutputCharacteristics (p: Process) =
234+
match p.Outputs with
235+
| Some outs ->
236+
outs
237+
|> List.collect (fun out -> ProcessOutput.tryGetCharacteristics out |> Option.defaultValue [])
238+
|> List.distinct
239+
| None -> []
240+
241+
/// Returns the characteristics describing the inputs and outputs of the process
242+
let getCharacteristics (p: Process) =
243+
getInputCharacteristics p @ getOutputCharacteristics p
244+
|> List.distinct
245+
212246
/// If the process implements the given parameter, return the list of input files together with their according parameter values of this parameter
213247
let tryGetInputsWithParameterBy (predicate : ProtocolParameter -> bool) (p : Process) =
214248
match p.ParameterValues with
@@ -232,21 +266,13 @@ module Process =
232266
| None -> None
233267
| None -> None
234268

235-
/// Returns the characteristics of the samples of the process
236-
let getCharacteristics (p : Process) =
237-
let materialAttributesOfValues (mvs : (MaterialAttributeValue list) Option) =
238-
mvs |> Option.defaultValue [] |> List.choose (fun mv -> mv.Category)
239-
p.Inputs |> Option.defaultValue [] |> List.collect (ProcessInput.tryGetCharacteristics >> materialAttributesOfValues)
240-
|> List.append (p.Outputs |> Option.defaultValue [] |> List.collect (ProcessOutput.tryGetCharacteristics >> materialAttributesOfValues))
241-
|> List.distinct
242-
243269
/// If the process implements the given characteristic, return the list of input files together with their according characteristic values of this characteristic
244270
let tryGetInputsWithCharacteristicBy (predicate : MaterialAttribute -> bool) (p : Process) =
245271
match p.Inputs with
246272
| Some is ->
247273
is
248274
|> List.choose (fun i ->
249-
ProcessInput.tryGetCharacteristics i
275+
ProcessInput.tryGetCharacteristicValues i
250276
|> Option.defaultValue []
251277
|> List.tryPick (fun mv ->
252278
match mv.Category with
@@ -264,7 +290,7 @@ module Process =
264290
| Some is,Some os ->
265291
List.zip is os
266292
|> List.choose (fun (i,o) ->
267-
ProcessInput.tryGetCharacteristics i
293+
ProcessInput.tryGetCharacteristicValues i
268294
|> Option.defaultValue []
269295
|> List.tryPick (fun mv ->
270296
match mv.Category with
@@ -320,6 +346,12 @@ module ProcessSequence =
320346
)
321347
)
322348
|> List.distinct
349+
350+
/// Returns the protocols the given processes impelement
351+
let getProtocols (processSequence : Process list) =
352+
processSequence
353+
|> List.choose (fun p -> p.ExecutesProtocol)
354+
|> List.distinct
323355

324356
/// Returns a list of the processes, containing only the ones executing a protocol for which the predicate returns true
325357
let filterByProtocolBy (predicate : Protocol -> bool) (processSequence : Process list) =
@@ -352,6 +384,12 @@ module ProcessSequence =
352384
|> List.collect Process.getParameters
353385
|> List.distinct
354386

387+
/// Returns the characteristics describing the inputs and outputs of the processssequence
388+
let getCharacteristics (processSequence : Process list) =
389+
processSequence
390+
|> List.collect Process.getCharacteristics
391+
|> List.distinct
392+
355393
/// If the processes contain a process implementing the given parameter, return the list of input files together with their according parameter values of this parameter
356394
let getInputsWithCharacteristicBy (predicate:MaterialAttribute -> bool) (processSequence : Process list) =
357395
processSequence

0 commit comments

Comments
 (0)