diff --git a/src/Spreadsheet/ArcAssay.fs b/src/Spreadsheet/ArcAssay.fs index 287ce5de..08703e7a 100644 --- a/src/Spreadsheet/ArcAssay.fs +++ b/src/Spreadsheet/ArcAssay.fs @@ -16,15 +16,51 @@ module ArcAssay = let [] obsoleteMetadataSheetName = "Assay" let [] metadataSheetName = "isa_assay" + let fromRows (rows : seq) = + let hasPrefix = + rows + |> Seq.exists (fun row -> row |> Seq.head |> snd |> fun s -> s.StartsWith(assaysPrefix)) + let aPrefix, cPrefix = + if hasPrefix then + Some assaysPrefix, Some contactsPrefix + else None, None + let en = rows.GetEnumerator() + let rec loop lastRow assays contacts rowNumber = + + match lastRow with + | Some prefix when prefix = assaysLabel || prefix = obsoleteAssaysLabel -> + let currentRow, rowNumber, _, assays = Assays.fromRows aPrefix (rowNumber + 1) en + loop currentRow assays contacts rowNumber + + | Some prefix when prefix = contactsLabel -> + let currentLine, rowNumber, _, contacts = Contacts.fromRows cPrefix (rowNumber + 1) en + loop currentLine assays contacts rowNumber + | _ -> + match assays, contacts with + | [], [] -> ArcAssay.create(Identifier.createMissingIdentifier()) + | assays, contacts -> + assays + |> Seq.tryHead + |> Option.defaultValue (ArcAssay.create(Identifier.createMissingIdentifier())) + |> ArcAssay.setPerformers (ResizeArray contacts) + + if en.MoveNext () then + let currentLine = en.Current |> SparseRow.tryGetValueAt 0 + loop currentLine [] [] 1 + + else + failwith "empty assay metadata sheet" + + let toRows (assay : ArcAssay) = + seq { + yield SparseRow.fromValues [assaysLabel] + yield! Assays.toRows (Some assaysPrefix) [assay] + + yield SparseRow.fromValues [contactsLabel] + yield! Contacts.toRows (Some contactsPrefix) (List.ofSeq assay.Performers) + } + let toMetadataSheet (assay : ArcAssay) : FsWorksheet = - let toRows (assay:ArcAssay) = - seq { - yield SparseRow.fromValues [assaysLabel] - yield! Assays.toRows (Some assaysPrefix) [assay] - - yield SparseRow.fromValues [contactsLabel] - yield! Contacts.toRows (Some contactsPrefix) (List.ofSeq assay.Performers) - } let sheet = FsWorksheet(metadataSheetName) assay |> toRows @@ -33,38 +69,6 @@ module ArcAssay = let fromMetadataSheet (sheet : FsWorksheet) : ArcAssay = try - let fromRows (usePrefixes : bool) (rows: seq) = - let aPrefix,cPrefix = - if usePrefixes then - Some assaysPrefix,Some contactsPrefix - else None,None - let en = rows.GetEnumerator() - let rec loop lastLine assays contacts lineNumber = - - match lastLine with - - | Some k when k = assaysLabel || k = obsoleteAssaysLabel -> - let currentLine,lineNumber,_,assays = Assays.fromRows aPrefix (lineNumber + 1) en - loop currentLine assays contacts lineNumber - - | Some k when k = contactsLabel -> - let currentLine,lineNumber,_,contacts = Contacts.fromRows cPrefix (lineNumber + 1) en - loop currentLine assays contacts lineNumber - | k -> - match assays, contacts with - | [], [] -> ArcAssay.create(Identifier.createMissingIdentifier()) - | assays, contacts -> - assays - |> Seq.tryHead - |> Option.defaultValue (ArcAssay.create(Identifier.createMissingIdentifier())) - |> ArcAssay.setPerformers (ResizeArray contacts) - - if en.MoveNext () then - let currentLine = en.Current |> SparseRow.tryGetValueAt 0 - loop currentLine [] [] 1 - - else - failwith "empty assay metadata sheet" let rows = sheet.Rows |> Seq.map SparseRow.fromFsRow @@ -72,17 +76,32 @@ module ArcAssay = rows |> Seq.exists (fun row -> row |> Seq.head |> snd |> fun s -> s.StartsWith(assaysPrefix)) rows - |> fromRows hasPrefix + |> fromRows + with + | err -> failwithf "Failed while parsing metadatasheet: %s" err.Message + + let toMetadataCollection (assay : ArcAssay) = + assay + |> toRows + |> Seq.map (fun row -> SparseRow.getAllValues row) + + let fromMetadataCollection (collection : seq>) : ArcAssay = + try + let rows = + collection + |> Seq.map SparseRow.fromAllValues + rows + |> fromRows with | err -> failwithf "Failed while parsing metadatasheet: %s" err.Message - let isMetadataSheetName (name:string) = + let isMetadataSheetName (name : string) = name = metadataSheetName || name = obsoleteMetadataSheetName let isMetadataSheet (sheet : FsWorksheet) = isMetadataSheetName sheet.Name - let tryGetMetadataSheet (doc:FsWorkbook) = + let tryGetMetadataSheet (doc : FsWorkbook) = doc.GetWorksheets() |> Seq.tryFind isMetadataSheet @@ -92,7 +111,7 @@ module ArcAssayExtensions = type ArcAssay with /// Reads an assay from a spreadsheet - static member fromFsWorkbook (doc:FsWorkbook) : ArcAssay = + static member fromFsWorkbook (doc : FsWorkbook) : ArcAssay = try // Reading the "Assay" metadata sheet. Here metadata let assayMetadata = @@ -122,7 +141,7 @@ module ArcAssayExtensions = /// /// /// Default: true - static member toFsWorkbook (assay : ArcAssay, ?datamapSheet: bool) = + static member toFsWorkbook (assay : ArcAssay, ?datamapSheet : bool) = let datamapSheet = defaultArg datamapSheet true let doc = new FsWorkbook() let metadataSheet = ArcAssay.toMetadataSheet (assay) @@ -140,5 +159,5 @@ module ArcAssayExtensions = /// Write an assay to a spreadsheet /// /// If datamapSheet is true, the datamap will be written to a worksheet inside assay workbook. - member this.ToFsWorkbook (?datamapSheet: bool) = + member this.ToFsWorkbook (?datamapSheet : bool) = ArcAssay.toFsWorkbook (this, ?datamapSheet = datamapSheet) \ No newline at end of file diff --git a/src/Spreadsheet/ArcInvestigation.fs b/src/Spreadsheet/ArcInvestigation.fs index 8e008d53..31959f65 100644 --- a/src/Spreadsheet/ArcInvestigation.fs +++ b/src/Spreadsheet/ArcInvestigation.fs @@ -27,28 +27,27 @@ module ArcInvestigation = let [] metadataSheetName = "isa_investigation" let [] obsoleteMetadataSheetName = "Investigation" - type InvestigationInfo = { - Identifier : string - Title : string - Description : string - SubmissionDate : string - PublicReleaseDate : string - Comments : Comment list + Identifier : string + Title : string + Description : string + SubmissionDate : string + PublicReleaseDate : string + Comments : Comment list } static member create identifier title description submissionDate publicReleaseDate comments = { - Identifier = identifier - Title = title - Description = description - SubmissionDate = submissionDate - PublicReleaseDate = publicReleaseDate - Comments = comments + Identifier = identifier + Title = title + Description = description + SubmissionDate = submissionDate + PublicReleaseDate = publicReleaseDate + Comments = comments } - static member Labels = [identifierLabel;titleLabel;descriptionLabel;submissionDateLabel;publicReleaseDateLabel] + static member Labels = [identifierLabel; titleLabel; descriptionLabel; submissionDateLabel; publicReleaseDateLabel] static member FromSparseTable (matrix : SparseTable) = @@ -57,51 +56,51 @@ module ArcInvestigation = let comments = matrix.CommentKeys |> List.map (fun k -> - Comment.fromString k (matrix.TryGetValueDefault("",(k,i)))) + Comment.fromString k (matrix.TryGetValueDefault("", (k, i)))) InvestigationInfo.create - (matrix.TryGetValueDefault("",(identifierLabel,i))) - (matrix.TryGetValueDefault("",(titleLabel,i))) - (matrix.TryGetValueDefault("",(descriptionLabel,i))) - (matrix.TryGetValueDefault("",(submissionDateLabel,i))) - (matrix.TryGetValueDefault("",(publicReleaseDateLabel,i))) + (matrix.TryGetValueDefault("", (identifierLabel, i))) + (matrix.TryGetValueDefault("", (titleLabel, i))) + (matrix.TryGetValueDefault("", (descriptionLabel, i))) + (matrix.TryGetValueDefault("", (submissionDateLabel, i))) + (matrix.TryGetValueDefault("", (publicReleaseDateLabel, i))) comments - static member ToSparseTable (investigation: ArcInvestigation) = + static member ToSparseTable (investigation : ArcInvestigation) = let i = 1 let matrix = SparseTable.Create (keys = InvestigationInfo.Labels,length=2) let mutable commentKeys = [] - do matrix.Matrix.Add ((identifierLabel,i), (investigation.Identifier)) - do matrix.Matrix.Add ((titleLabel,i), (Option.defaultValue "" investigation.Title)) - do matrix.Matrix.Add ((descriptionLabel,i), (Option.defaultValue "" investigation.Description)) - do matrix.Matrix.Add ((submissionDateLabel,i), (Option.defaultValue "" investigation.SubmissionDate)) - do matrix.Matrix.Add ((publicReleaseDateLabel,i), (Option.defaultValue "" investigation.PublicReleaseDate)) + do matrix.Matrix.Add ((identifierLabel, i), (investigation.Identifier)) + do matrix.Matrix.Add ((titleLabel, i), (Option.defaultValue "" investigation.Title)) + do matrix.Matrix.Add ((descriptionLabel, i), (Option.defaultValue "" investigation.Description)) + do matrix.Matrix.Add ((submissionDateLabel, i), (Option.defaultValue "" investigation.SubmissionDate)) + do matrix.Matrix.Add ((publicReleaseDateLabel, i), (Option.defaultValue "" investigation.PublicReleaseDate)) investigation.Comments |> ResizeArray.iter (fun comment -> - let n,v = comment |> Comment.toString + let n, v = comment |> Comment.toString commentKeys <- n :: commentKeys - matrix.Matrix.Add((n,i),v) + matrix.Matrix.Add((n, i), v) ) {matrix with CommentKeys = commentKeys |> List.distinct |> List.rev} static member fromRows lineNumber (rows : IEnumerator) = - SparseTable.FromRows(rows,InvestigationInfo.Labels,lineNumber) - |> fun (s,ln,rs,sm) -> (s,ln,rs, InvestigationInfo.FromSparseTable sm) + SparseTable.FromRows(rows, InvestigationInfo.Labels, lineNumber) + |> fun (s, ln, rs, sm) -> (s, ln, rs, InvestigationInfo.FromSparseTable sm) static member toRows (investigation : ArcInvestigation) = investigation |> InvestigationInfo.ToSparseTable |> SparseTable.ToRows - let fromParts (investigationInfo:InvestigationInfo) (ontologySourceReference:OntologySourceReference list) (publications: Publication list) (contacts: Person list) (studies: ArcStudy list) (assays: ArcAssay list) (remarks: Remark list) = + let fromParts (investigationInfo : InvestigationInfo) (ontologySourceReference : OntologySourceReference list) (publications : Publication list) (contacts : Person list) (studies : ArcStudy list) (assays : ArcAssay list) (remarks : Remark list) = let studyIdentifiers = studies |> List.map (fun s -> s.Identifier) ArcInvestigation.make - (investigationInfo.Identifier) + investigationInfo.Identifier (Option.fromValueWithDefault "" investigationInfo.Title) (Option.fromValueWithDefault "" investigationInfo.Description) (Option.fromValueWithDefault "" investigationInfo.SubmissionDate) @@ -115,8 +114,7 @@ module ArcInvestigation = (ResizeArray investigationInfo.Comments) (ResizeArray remarks) - - let fromRows (rows:seq) = + let fromRows (rows : seq) = let en = rows.GetEnumerator() let emptyInvestigationInfo = InvestigationInfo.create "" "" "" "" "" [] @@ -125,7 +123,7 @@ module ArcInvestigation = match lastLine with | Some k when k = ontologySourceReferenceLabel -> - let currentLine,lineNumber,newRemarks,ontologySourceReferences = OntologySourceReference.fromRows (lineNumber + 1) en + let currentLine, lineNumber, newRemarks, ontologySourceReferences = OntologySourceReference.fromRows (lineNumber + 1) en loop currentLine ontologySourceReferences investigationInfo publications contacts studies (List.append remarks newRemarks) lineNumber | Some k when k = investigationLabel -> @@ -137,21 +135,21 @@ module ArcInvestigation = loop currentLine ontologySourceReferences investigationInfo publications contacts studies (List.append remarks newRemarks) lineNumber | Some k when k = contactsLabel -> - let currentLine,lineNumber,newRemarks,contacts = Contacts.fromRows (Some contactsLabelPrefix) (lineNumber + 1) en + let currentLine,lineNumber, newRemarks, contacts = Contacts.fromRows (Some contactsLabelPrefix) (lineNumber + 1) en loop currentLine ontologySourceReferences investigationInfo publications contacts studies (List.append remarks newRemarks) lineNumber | Some k when k = studyLabel -> - let currentLine,lineNumber,newRemarks,study = Studies.fromRows (lineNumber + 1) en + let currentLine, lineNumber, newRemarks, study = Studies.fromRows (lineNumber + 1) en if study.IsSome then loop currentLine ontologySourceReferences investigationInfo publications contacts (study.Value::studies) (List.append remarks newRemarks) lineNumber else loop currentLine ontologySourceReferences investigationInfo publications contacts studies (List.append remarks newRemarks) lineNumber - | k -> - let studies,assays = + | _ -> + let studies, assays = studies |> List.unzip - |> fun (s,a) -> + |> fun (s, a) -> s |> List.rev, a |> List.concat |> List.distinctBy (fun a -> a.Identifier) fromParts investigationInfo ontologySourceReferences publications contacts studies assays remarks @@ -164,8 +162,8 @@ module ArcInvestigation = failwith "emptyInvestigationFile" - let toRows (investigation:ArcInvestigation) : seq = - let insertRemarks (remarks:Remark list) (rows:seq) = + let toRows (investigation : ArcInvestigation) : seq = + let insertRemarks (remarks : Remark list) (rows : seq) = try let rm = remarks |> List.map Remark.toTuple |> Map.ofList let rec loop i l nl = @@ -202,13 +200,22 @@ module ArcInvestigation = |> insertRemarks (List.ofSeq investigation.Remarks) |> seq + let toMetadataCollection (investigation : ArcInvestigation) = + toRows investigation + |> Seq.map (fun row -> SparseRow.getAllValues row) + + let fromMetadataCollection (collection : seq>) = + collection + |> Seq.map SparseRow.fromAllValues + |> fromRows + let isMetadataSheetName (name : string) = name = metadataSheetName || name = obsoleteMetadataSheetName let isMetadataSheet (sheet : FsWorksheet) = isMetadataSheetName sheet.Name - let tryGetMetadataSheet (doc:FsWorkbook) = + let tryGetMetadataSheet (doc : FsWorkbook) = doc.GetWorksheets() |> Seq.tryFind isMetadataSheet @@ -220,7 +227,7 @@ module ArcInvestigationExtensions = type ArcInvestigation with - static member fromFsWorkbook (doc:FsWorkbook) = + static member fromFsWorkbook (doc : FsWorkbook) = try match ArcInvestigation.tryGetMetadataSheet doc with | Some sheet -> sheet @@ -231,7 +238,7 @@ module ArcInvestigationExtensions = with | err -> failwithf "Could not read investigation from spreadsheet: %s" err.Message - static member toFsWorkbook (investigation:ArcInvestigation) : FsWorkbook = + static member toFsWorkbook (investigation : ArcInvestigation) : FsWorkbook = try let wb = new FsWorkbook() let sheet = FsWorksheet(metadataSheetName) diff --git a/src/Spreadsheet/ArcStudy.fs b/src/Spreadsheet/ArcStudy.fs index c8e7e321..eab64843 100644 --- a/src/Spreadsheet/ArcStudy.fs +++ b/src/Spreadsheet/ArcStudy.fs @@ -1,9 +1,8 @@ namespace ARCtrl.Spreadsheet open ARCtrl -open FsSpreadsheet - open ARCtrl.Helper +open FsSpreadsheet module ArcStudy = @@ -25,13 +24,14 @@ module ArcStudy = |> Seq.iteri (fun rowI r -> SparseRow.writeToSheet (rowI + 1) r sheet) sheet + let fromRows (rows : seq) = + let en = rows.GetEnumerator() + en.MoveNext() |> ignore + let _, _, _,study = Studies.fromRows 2 en + study + let fromMetadataSheet (sheet : FsWorksheet) : ArcStudy*ArcAssay list = - try - let fromRows (rows: seq) = - let en = rows.GetEnumerator() - en.MoveNext() |> ignore - let _,_,_,study = Studies.fromRows 2 en - study + try sheet.Rows |> Seq.map SparseRow.fromFsRow |> fromRows @@ -39,13 +39,27 @@ module ArcStudy = with | err -> failwithf "Failed while parsing metadatasheet: %s" err.Message + let toMetadataCollection (study : ArcStudy) (assays : ArcAssay list option) = + Studies.toRows study assays + |> Seq.append [SparseRow.fromValues [studiesLabel]] + |> Seq.map (fun row -> SparseRow.getAllValues row) + + let fromMetadataCollection (collection : seq>) : ArcStudy*ArcAssay list = + try + collection + |> Seq.map SparseRow.fromAllValues + |> fromRows + |> Option.defaultValue (ArcStudy.create(Identifier.createMissingIdentifier()),[]) + with + | err -> failwithf "Failed while parsing metadatasheet: %s" err.Message + let isMetadataSheetName (name : string) = name = metadataSheetName || name = obsoleteMetadataSheetName let isMetadataSheet (sheet : FsWorksheet) = isMetadataSheetName sheet.Name - let tryGetMetadataSheet (doc:FsWorkbook) = + let tryGetMetadataSheet (doc : FsWorkbook) = doc.GetWorksheets() |> Seq.tryFind isMetadataSheet @@ -55,7 +69,7 @@ module ArcStudyExtensions = type ArcStudy with /// Reads an assay from a spreadsheet - static member fromFsWorkbook (doc:FsWorkbook) = + static member fromFsWorkbook (doc : FsWorkbook) = try // Reading the "Assay" metadata sheet. Here metadata let studyMetadata,assays = @@ -97,7 +111,7 @@ module ArcStudyExtensions = /// /// /// - static member toFsWorkbook (study : ArcStudy, ?assays : ArcAssay list, ?datamapSheet: bool) = + static member toFsWorkbook (study : ArcStudy, ?assays : ArcAssay list, ?datamapSheet : bool) = let datamapSheet = defaultArg datamapSheet true let doc = new FsWorkbook() let metadataSheet = ArcStudy.toMetadataSheet study assays @@ -112,5 +126,5 @@ module ArcStudyExtensions = doc - member this.ToFsWorkbook (?assays : ArcAssay list, ?datamapSheet: bool) = + member this.ToFsWorkbook (?assays : ArcAssay list, ?datamapSheet : bool) = ArcStudy.toFsWorkbook (this, ?assays = assays, ?datamapSheet = datamapSheet) \ No newline at end of file diff --git a/src/Spreadsheet/DataMap.fs b/src/Spreadsheet/DataMap.fs index 0d3a4d4f..0e3076d3 100644 --- a/src/Spreadsheet/DataMap.fs +++ b/src/Spreadsheet/DataMap.fs @@ -4,9 +4,8 @@ open ARCtrl open ArcTable open FsSpreadsheet - /// Reads an datamap from a spreadsheet -let fromFsWorkbook (doc:FsWorkbook) = +let fromFsWorkbook (doc : FsWorkbook) = try let dataMapTable = doc.GetWorksheets() diff --git a/src/Spreadsheet/Template.fs b/src/Spreadsheet/Template.fs index 063b994d..bf4efd08 100644 --- a/src/Spreadsheet/Template.fs +++ b/src/Spreadsheet/Template.fs @@ -1,9 +1,9 @@ namespace ARCtrl.Spreadsheet open FsSpreadsheet +open ARCtrl open ARCtrl.Helper open ARCtrl.Spreadsheet -open ARCtrl open System.Collections.Generic exception TemplateReadError of string @@ -22,7 +22,7 @@ module Metadata = let fromSparseTable (matrix : SparseTable) = OntologyAnnotationSection.fromSparseTable erLabel erTermSourceREFLabel erTermAccessionNumberLabel matrix - let toSparseTable (designs: OntologyAnnotation list) = + let toSparseTable (designs : OntologyAnnotation list) = OntologyAnnotationSection.toSparseTable erLabel erTermSourceREFLabel erTermAccessionNumberLabel designs let fromRows (prefix : string option) (rows : IEnumerator) = @@ -38,12 +38,12 @@ module Metadata = let [] tagsTermAccessionNumberLabel = "Tags Term Accession Number" let [] tagsTermSourceREFLabel = "Tags Term Source REF" - let labels = [tagsLabel;tagsTermAccessionNumberLabel;tagsTermSourceREFLabel] + let labels = [tagsLabel; tagsTermAccessionNumberLabel; tagsTermSourceREFLabel] let fromSparseTable (matrix : SparseTable) = OntologyAnnotationSection.fromSparseTable tagsLabel tagsTermSourceREFLabel tagsTermAccessionNumberLabel matrix - let toSparseTable (designs: OntologyAnnotation list) = + let toSparseTable (designs : OntologyAnnotation list) = OntologyAnnotationSection.toSparseTable tagsLabel tagsTermSourceREFLabel tagsTermAccessionNumberLabel designs let fromRows (prefix : string option) (rows : IEnumerator) = @@ -80,23 +80,23 @@ module Metadata = type TemplateInfo = { - Id : string - Name : string - Version : string - Description : string - Organisation : string - Table : string - Comments : Comment list + Id : string + Name : string + Version : string + Description : string + Organisation : string + Table : string + Comments : Comment list } static member create id name version description organisation table comments = - {Id = id;Name = name;Version = version;Description = description;Organisation = organisation;Table = table;Comments = comments} + {Id = id; Name = name; Version = version; Description = description; Organisation = organisation; Table = table; Comments = comments} static member empty = TemplateInfo.create "" "" "" "" "" "" [] static member Labels = - [identifierLabel;nameLabel;versionLabel;descriptionLabel;organisationLabel;tableLabel] + [identifierLabel; nameLabel; versionLabel; descriptionLabel; organisationLabel; tableLabel] static member FromSparseTable (matrix : SparseTable) = @@ -105,38 +105,38 @@ module Metadata = let comments = matrix.CommentKeys |> List.map (fun k -> - Comment.fromString k (matrix.TryGetValueDefault("",(k,i)))) + Comment.fromString k (matrix.TryGetValueDefault("", (k, i)))) TemplateInfo.create - (matrix.TryGetValueDefault(Identifier.createMissingIdentifier(),(identifierLabel,i))) - (matrix.TryGetValueDefault("",(nameLabel,i))) - (matrix.TryGetValueDefault("",(versionLabel,i))) - (matrix.TryGetValueDefault("",(descriptionLabel,i))) - (matrix.TryGetValueDefault("",(organisationLabel,i))) - (matrix.TryGetValueDefault("",(tableLabel,i))) + (matrix.TryGetValueDefault(Identifier.createMissingIdentifier(), (identifierLabel, i))) + (matrix.TryGetValueDefault("", (nameLabel, i))) + (matrix.TryGetValueDefault("", (versionLabel, i))) + (matrix.TryGetValueDefault("", (descriptionLabel, i))) + (matrix.TryGetValueDefault("", (organisationLabel, i))) + (matrix.TryGetValueDefault("", (tableLabel, i))) comments - static member ToSparseTable (template: Template) = + static member ToSparseTable (template : Template) = let i = 1 - let matrix = SparseTable.Create (keys = TemplateInfo.Labels,length = 2) + let matrix = SparseTable.Create (keys = TemplateInfo.Labels, length = 2) let mutable commentKeys = [] let processedIdentifier = if template.Id.ToString().StartsWith(Identifier.MISSING_IDENTIFIER) then "" else template.Id.ToString() - do matrix.Matrix.Add ((identifierLabel,i), processedIdentifier) - do matrix.Matrix.Add ((nameLabel,i), (template.Name)) - do matrix.Matrix.Add ((versionLabel,i), (template.Version)) - do matrix.Matrix.Add ((descriptionLabel,i), (template.Description)) - do matrix.Matrix.Add ((organisationLabel,i), (template.Organisation.ToString())) - do matrix.Matrix.Add ((tableLabel,i), template.Table.Name) + do matrix.Matrix.Add ((identifierLabel, i), processedIdentifier) + do matrix.Matrix.Add ((nameLabel, i), (template.Name)) + do matrix.Matrix.Add ((versionLabel, i), (template.Version)) + do matrix.Matrix.Add ((descriptionLabel, i), (template.Description)) + do matrix.Matrix.Add ((organisationLabel, i), (template.Organisation.ToString())) + do matrix.Matrix.Add ((tableLabel, i), template.Table.Name) {matrix with CommentKeys = commentKeys |> List.distinct |> List.rev} static member fromRows (rows : IEnumerator) = - SparseTable.FromRows(rows,TemplateInfo.Labels,0) - |> fun (s,ln,rs,sm) -> (s,TemplateInfo.FromSparseTable sm) + SparseTable.FromRows(rows, TemplateInfo.Labels, 0) + |> fun (s, _, _, sm) -> (s, TemplateInfo.FromSparseTable sm) static member toRows (template : Template) = template @@ -148,28 +148,28 @@ module Metadata = rows |> Seq.map (fun r -> r - |> Seq.map (fun (k,v) -> + |> Seq.map (fun (k, v) -> if k = 0 then match v with - | v when v = obsoleteAuthorsLabel -> k,authorsLabel - | v when v = obsoleteErLabel -> k,erLabel - | v when v = obsoleteTagsLabel -> k,tagsLabel - - | v when v = Authors.obsoleteORCIDLabel -> k,$"Comment[{ARCtrl.Process.Conversion.Person.orcidKey}]" - - | v when v = "Authors Last Name" -> k,"Author Last Name" - | v when v = "Authors First Name" -> k,"Author First Name" - | v when v = "Authors Mid Initials" -> k,"Author Mid Initials" - | v when v = "Authors Email" -> k,"Author Email" - | v when v = "Authors Phone" -> k,"Author Phone" - | v when v = "Authors Fax" -> k,"Author Fax" - | v when v = "Authors Address" -> k,"Author Address" - | v when v = "Authors Affiliation" -> k,"Author Affiliation" - | v when v = "Authors Role" -> k,"Author Roles" - | v when v = "Authors Role Term Accession Number" -> k,"Author Roles Term Accession Number" - | v when v = "Authors Role Term Source REF" -> k,"Author Roles Term Source REF" - | v -> (k,v) - else (k,v) + | v when v = obsoleteAuthorsLabel -> k, authorsLabel + | v when v = obsoleteErLabel -> k, erLabel + | v when v = obsoleteTagsLabel -> k, tagsLabel + + | v when v = Authors.obsoleteORCIDLabel -> k, $"Comment[{ARCtrl.Process.Conversion.Person.orcidKey}]" + + | v when v = "Authors Last Name" -> k, "Author Last Name" + | v when v = "Authors First Name" -> k, "Author First Name" + | v when v = "Authors Mid Initials" -> k, "Author Mid Initials" + | v when v = "Authors Email" -> k, "Author Email" + | v when v = "Authors Phone" -> k, "Author Phone" + | v when v = "Authors Fax" -> k, "Author Fax" + | v when v = "Authors Address" -> k, "Author Address" + | v when v = "Authors Affiliation" -> k, "Author Affiliation" + | v when v = "Authors Role" -> k, "Author Roles" + | v when v = "Authors Role Term Accession Number" -> k, "Author Roles Term Accession Number" + | v when v = "Authors Role Term Source REF" -> k, "Author Roles Term Source REF" + | v -> (k, v) + else (k, v) ) ) |> fun s -> @@ -183,22 +183,22 @@ module Metadata = match lastLine with | Some k when k = erLabel -> - let currentLine,newERs = ER.fromRows None en + let currentLine, newERs = ER.fromRows None en loop en currentLine templateInfo (List.append ers newERs) tags authors | Some k when k = tagsLabel -> - let currentLine,newTags = Tags.fromRows None en + let currentLine, newTags = Tags.fromRows None en loop en currentLine templateInfo ers (List.append tags newTags) authors | Some k when k = authorsLabel -> - let currentLine,_,_,newAuthors = Contacts.fromRows (Some authorsLabelPrefix) 0 en + let currentLine, _, _, newAuthors = Contacts.fromRows (Some authorsLabelPrefix) 0 en loop en currentLine templateInfo ers tags (List.append authors newAuthors) | k -> - templateInfo,ers,tags,authors + templateInfo, ers, tags, authors let rows = mapDeprecatedKeys rows let en = rows.GetEnumerator() en.MoveNext() |> ignore - let currentLine,item = TemplateInfo.fromRows en + let currentLine, item = TemplateInfo.fromRows en loop en currentLine item [] [] [] @@ -226,22 +226,20 @@ module Template = let [] metaDataSheetName = "isa_template" let [] obsoletemetaDataSheetName = "SwateTemplateMetadata" - - let fromParts (templateInfo:TemplateInfo) (ers:OntologyAnnotation list) (tags: OntologyAnnotation list) (authors : Person list) (table : ArcTable) (lastUpdated : System.DateTime)= - Template.make - (System.Guid templateInfo.Id) - table - (templateInfo.Name) - (templateInfo.Description) - (Organisation.ofString templateInfo.Organisation) - (templateInfo.Version) - (ResizeArray authors) - (ResizeArray ers) - (ResizeArray tags) - (lastUpdated) - - let toMetadataSheet (template : Template) : FsWorksheet = - + let fromParts (templateInfo : TemplateInfo) (ers : OntologyAnnotation list) (tags : OntologyAnnotation list) (authors : Person list) (table : ArcTable) (lastUpdated : System.DateTime) = + Template.make + (System.Guid templateInfo.Id) + table + templateInfo.Name + templateInfo.Description + (Organisation.ofString templateInfo.Organisation) + templateInfo.Version + (ResizeArray authors) + (ResizeArray ers) + (ResizeArray tags) + lastUpdated + + let toMetadataSheet (template : Template) : FsWorksheet = let sheet = FsWorksheet(metaDataSheetName) Template.toRows template |> Seq.iteri (fun rowI r -> SparseRow.writeToSheet (rowI + 1) r sheet) @@ -252,10 +250,19 @@ module Template = |> Seq.map SparseRow.fromFsRow |> Template.fromRows + let toMetadataCollection (template : Template) = + Template.toRows template + |> Seq.map (fun row -> SparseRow.getAllValues row) + + let fromMetadataCollection (collection : seq>) = + collection + |> Seq.map SparseRow.fromAllValues + |> Template.fromRows + /// Reads an assay from a spreadsheet - let fromFsWorkbook (doc:FsWorkbook) = + let fromFsWorkbook (doc : FsWorkbook) = // Reading the "Assay" metadata sheet. Here metadata - let templateInfo,ers,tags,authors = + let templateInfo, ers, tags, authors = match doc.TryGetWorksheetByName metaDataSheetName with | Option.Some sheet -> @@ -265,7 +272,7 @@ module Template = | Option.Some sheet -> fromMetadataSheet sheet | None -> - Metadata.Template.TemplateInfo.empty,[],[],[] + Metadata.Template.TemplateInfo.empty, [], [], [] let tryTableNameMatches (ws : FsWorksheet) = if ws.Tables |> Seq.exists (fun t -> t.Name = templateInfo.Table) then Some ws else None diff --git a/tests/Spreadsheet/AssayFileTests.fs b/tests/Spreadsheet/AssayFileTests.fs index 23fb7d95..ec6f2aaa 100644 --- a/tests/Spreadsheet/AssayFileTests.fs +++ b/tests/Spreadsheet/AssayFileTests.fs @@ -1,4 +1,4 @@ -module ArcAssayTests +module ArcAssayTests open ARCtrl @@ -73,6 +73,20 @@ let testMetaDataFunctions = |> Seq.iter (fun c -> Expect.notEqual (c.ValueAsString().Trim()) "" $"Cell {c.Address.ToString()} should not contain empty string") ) + testCase "TestMetadataFromCollection" (fun () -> + + let assay = + Assay.Proteome.assayMetadataCollection + |> ArcAssay.fromMetadataCollection + + Expect.isSome assay.MeasurementType "protein expression profiling" + Expect.isSome assay.TechnologyPlatform "iTRAQ" + Expect.isSome assay.TechnologyType "mass spectrometry" + Expect.isSome (assay.Performers.Item 0).LastName "Oliver" + Expect.isSome (assay.Performers.Item 1).LastName "Juan" + Expect.isSome (assay.Performers.Item 2).LastName "Leo" + ) + testCase "WriterSuccessObsoleteSheetName" (fun () -> let a = ArcAssay.fromMetadataSheet Assay.Proteome.assayMetadataObsoleteSheetName diff --git a/tests/Spreadsheet/InvestigationFileTests.fs b/tests/Spreadsheet/InvestigationFileTests.fs index d34a35d2..fb66712c 100644 --- a/tests/Spreadsheet/InvestigationFileTests.fs +++ b/tests/Spreadsheet/InvestigationFileTests.fs @@ -1,4 +1,4 @@ -module ArcInvestigationTests +module ArcInvestigationTests open ARCtrl @@ -180,22 +180,26 @@ let private testInvestigationFile = let studyIdentifiers = ResizeArray ["MyStudy"] let i = - ArcInvestigation.create("Identifier",registeredStudyIdentifiers = studyIdentifiers) + ArcInvestigation.create("Identifier", registeredStudyIdentifiers = studyIdentifiers) |> ArcInvestigation.toFsWorkbook |> ArcInvestigation.fromFsWorkbook Expect.sequenceEqual i.RegisteredStudyIdentifiers studyIdentifiers "Registered study Identifier were not written and read correctly" ) - testCase "WriteWithAssayOnlyRegistered" (fun () -> - let studyIdentifier = "MyStudy" - let assayIdentifiers = ResizeArray ["MyAssay"] - let study = ArcStudy.create("MyStudy",registeredAssayIdentifiers = assayIdentifiers) - let i = - ArcInvestigation.create("Identifier") - |> ArcInvestigation.addRegisteredStudy study - |> ArcInvestigation.toFsWorkbook + testCase "TestMetadataCollection" (fun () -> + + let investigation = + Investigation.BII_I_1.fullInvestigation |> ArcInvestigation.fromFsWorkbook - Expect.sequenceEqual (i.GetStudy(studyIdentifier).RegisteredAssayIdentifiers) assayIdentifiers "Registered assay Identifier weres not written and read correctly" + |> ArcInvestigation.toMetadataCollection + |> ArcInvestigation.fromMetadataCollection + + Expect.isSome investigation.Description "Background Cell growth underlies many key cellular and developmental processes, yet a limited number of studies have been carried out on cell-growth regulation. Comprehensive studies at the transcriptional, proteomic and metabolic levels under defined controlled conditions are currently lacking. Results Metabolic control analysis is being exploited in a systems biology study of the eukaryotic cell. Using chemostat culture, we have measured the impact of changes in flux (growth rate) on the transcriptome, proteome, endometabolome and exometabolome of the yeast Saccharomyces cerevisiae. Each functional genomic level shows clear growth-rate-associated trends and discriminates between carbon-sufficient and carbon-limited conditions. Genes consistently and significantly upregulated with increasing growth rate are frequently essential and encode evolutionarily conserved proteins of known function that participate in many protein-protein interactions. In contrast, more unknown, and fewer essential, genes are downregulated with increasing growth rate; their protein products rarely interact with one another. A large proportion of yeast genes under positive growth-rate control share orthologs with other eukaryotes, including humans. Significantly, transcription of genes encoding components of the TOR complex (a major controller of eukaryotic cell growth) is not subject to growth-rate regulation. Moreover, integrative studies reveal the extent and importance of post-transcriptional control, patterns of control of metabolic fluxes at the level of enzyme synthesis, and the relevance of specific enzymatic reactions in the control of metabolic fluxes during cell growth. Conclusion This work constitutes a first comprehensive systems biology study on growth-rate control in the eukaryotic cell. The results have direct implications for advanced studies on cell growth, in vivo regulation of metabolic fluxes for comprehensive metabolic engineering, and for the design of genome-scale systems biology models of the eukaryotic cell." + Expect.equal investigation.Identifier "BII-I-1" "Identifier" + Expect.isSome investigation.Title "Growth control of the eukaryote cell: a systems biology study in yeast" + Expect.equal investigation.AssayCount 3 "AssayCount" + Expect.equal investigation.StudyCount 2 "StudyCount" ) + //testCase "OutputMatchesInputEmpty" (fun () -> // let i = diff --git a/tests/Spreadsheet/StudyFileTests.fs b/tests/Spreadsheet/StudyFileTests.fs index fe6520ba..7b3626db 100644 --- a/tests/Spreadsheet/StudyFileTests.fs +++ b/tests/Spreadsheet/StudyFileTests.fs @@ -1,4 +1,4 @@ -module ArcStudyTests +module ArcStudyTests open TestingUtils @@ -60,6 +60,21 @@ let testMetaDataFunctions = Expect.isOk writingSuccess (Result.getMessage writingSuccess) ) + testCase "TestMetadataFromCollection" (fun () -> + + let study, assays = + Study.BII_S_1.studyMetadataCollection + |> ArcStudy.fromMetadataCollection + + Expect.isSome study.Title "Study of the impact of changes in flux on the transcriptome, proteome, endometabolome and exometabolome of the yeast Saccharomyces cerevisiae under different nutrient limitations" + Expect.isSome study.Description "We wished to study the impact of growth rate on the total complement of mRNA molecules, proteins, and metabolites in S. cerevisiae, independent of any nutritional or other physiological effects. To achieve this, we carried out our analyses on yeast grown in steady-state chemostat culture under four different nutrient limitations (glucose, ammonium, phosphate, and sulfate) at three different dilution (that is, growth) rates (D = u = 0.07, 0.1, and 0.2/hour, equivalent to population doubling times (Td) of 10 hours, 7 hours, and 3.5 hours, respectively; u = specific growth rate defined as grams of biomass generated per gram of biomass present per unit time)." + Expect.isSome study.SubmissionDate "2007-04-30" + + Expect.isSome assays.[0].MeasurementType "protein expression profiling" + Expect.isSome assays.[1].MeasurementType "etabolite profiling" + Expect.isSome assays.[2].MeasurementType "transcription profiling" + ) + testCase "OutputMatchesInputEmpty" (fun () -> let o = diff --git a/tests/Spreadsheet/TemplateTests.fs b/tests/Spreadsheet/TemplateTests.fs index 773f43f9..24ff75b0 100644 --- a/tests/Spreadsheet/TemplateTests.fs +++ b/tests/Spreadsheet/TemplateTests.fs @@ -1,4 +1,4 @@ -module TemplateTests +module TemplateTests open ARCtrl @@ -51,6 +51,23 @@ let tests_Spreadsheet = testList "Template_Spreadsheet" [ let sheet = Spreadsheet.Template.toMetadataSheet template Expect.workSheetEqual sheet TestObjects.Spreadsheet.Template.templateMetadata "Metadata sheet should be equal" + testCase "TestMetadataFromCollection" (fun _ -> + + let table = ArcTable.init(TestObjects.Spreadsheet.Template.templateTableName) + let templateInfo, ers,tags,authors = Spreadsheet.Template.fromMetadataCollection (TestObjects.Spreadsheet.Template.templateetadataCollection table) + + let template = ARCtrl.Spreadsheet.Template.fromParts templateInfo ers tags authors table System.DateTime.Now + + Expect.stringEqual template.Name "Plant growth" "Name should be equal" + Expect.stringEqual template.Version "1.2.0" "Version should be equal" + + Expect.isSome (template.EndpointRepositories.Item 0).TermAccessionNumber (ARCtrl.Helper.Url.createOAUri "DPBO" "1000096") + Expect.isSome (template.EndpointRepositories.Item 0).TermAccessionNumber (ARCtrl.Helper.Url.createOAUri "NFDI4PSO" "1000097") + Expect.isSome (template.EndpointRepositories.Item 0).TermAccessionNumber (ARCtrl.Helper.Url.createOAUri "NFDI4PSO" "1000098") + Expect.isSome (template.EndpointRepositories.Item 0).TermAccessionNumber (ARCtrl.Helper.Url.createOAUri "NFDI4PSO" "0010002") + Expect.isSome (template.EndpointRepositories.Item 0).TermAccessionNumber (ARCtrl.Helper.Url.createOAUri "DPBO" "0010000") + + ) ] testList "fullFile" [ testCase "simple" <| fun _ -> diff --git a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Assay.fs b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Assay.fs index c03ddff7..35a4cbdf 100644 --- a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Assay.fs +++ b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Assay.fs @@ -1,4 +1,4 @@ -module TestObjects.Spreadsheet.Assay +module TestObjects.Spreadsheet.Assay open FsSpreadsheet @@ -87,6 +87,10 @@ module Proteome = row23.[4].Value <- "0000-0002-1825-0098" ws + let assayMetadataCollection = + let assay = ARCtrl.Spreadsheet.ArcAssay.fromMetadataSheet assayMetadata + ARCtrl.Spreadsheet.ArcAssay.toMetadataCollection assay + let assayMetadataDeprecatedKeys = let ws = FsWorksheet("isa_assay") let row1 = ws.Row(1) @@ -221,7 +225,6 @@ module Proteome = row22.[1].Value <- "Comment[Worksheet]" ws - let assayMetadataEmptyObsoleteSheetName = let cp = assayMetadataEmpty.Copy() cp.Name <- "Assay" diff --git a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.InvestigationFile.fs b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.InvestigationFile.fs index cd373af1..b5cd45d6 100644 --- a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.InvestigationFile.fs +++ b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.InvestigationFile.fs @@ -1,7 +1,8 @@ -module TestObjects.Spreadsheet.Investigation +module TestObjects.Spreadsheet.Investigation open FsSpreadsheet.DSL open FsSpreadsheet +open ARCtrl.Spreadsheet let emptyInvestigation = let wb = new FsWorkbook() diff --git a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Study.fs b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Study.fs index 9d799662..19f4dd9b 100644 --- a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Study.fs +++ b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Study.fs @@ -313,6 +313,15 @@ module BII_S_1 = row61.[1].Value <- "Comment[Study Person REF]" ws + let studyMetadataCollection = + let study, assays = ARCtrl.Spreadsheet.ArcStudy.fromMetadataSheet studyMetadata + + let assays = + if assays.IsEmpty then None + else Some assays + + ARCtrl.Spreadsheet.ArcStudy.toMetadataCollection study assays + let studyMetadataEmptyObsoleteSheetName = let cp = studyMetadataEmpty.Copy() cp.Name <- "Study" diff --git a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Template.fs b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Template.fs index 8dff37d7..e61dde86 100644 --- a/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Template.fs +++ b/tests/TestingUtils/TestObjects.Spreadsheet/Spreadsheet.Template.fs @@ -1,4 +1,4 @@ -module TestObjects.Spreadsheet.Template +module TestObjects.Spreadsheet.Template open FsSpreadsheet @@ -163,6 +163,11 @@ let templateMetadata = row28.[6].Value <- "" ws +let templateetadataCollection table = + let template, ers, tags, authors = ARCtrl.Spreadsheet.Template.fromMetadataSheet templateMetadata + ARCtrl.Spreadsheet.Template.fromParts template ers tags authors table System.DateTime.Now + |> ARCtrl.Spreadsheet.Template.toMetadataCollection + let templateMetadata_deprecatedKeys = let ws = FsWorksheet("SwateTemplateMetadata") let row1 = ws.Row(1)