Skip to content

Commit

Permalink
Add option to write process.json to Swate annotation table (Issue #84)…
Browse files Browse the repository at this point in the history
…. ✨
  • Loading branch information
Freymaurer committed Feb 10, 2021
1 parent 4bf33cb commit 262dae3
Show file tree
Hide file tree
Showing 10 changed files with 385 additions and 106 deletions.
5 changes: 3 additions & 2 deletions src/Client/Client.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<None Include="paket.references" />
<None Include="style.scss" />
<Compile Include="Version.fs" />
<Compile Include="ISADotNetHelpers.fs" />
<Compile Include="Routing.fs" />
<Compile Include="ExcelColors.fs" />
<Compile Include="OfficeJS.fs" />
Expand Down Expand Up @@ -37,11 +38,11 @@
<Compile Include="Views\AdvancedSearchView.fs" />
<Compile Include="Views\AddBuildingBlockView.fs" />
<Compile Include="Views\TermSearchView.fs" />
<Compile Include="Views\FilePickerView.fs" />
<Compile Include="Views\ValidationView.fs" />
<Compile Include="Views\FilePickerView.fs" />
<Compile Include="Views\ProtocolInsertView.fs" />
<Compile Include="Views\InfoView.fs" />
<Compile Include="Views\ActivityLogView.fs" />
<Compile Include="Views\ProtocolInsertView.fs" />
<Compile Include="Views\SettingsView.fs" />
<Compile Include="Views\NotFoundView.fs" />
<Compile Include="Client.fs" />
Expand Down
31 changes: 31 additions & 0 deletions src/Client/ISADotNetHelpers.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module ISADotNetHelpers

open ISADotNet
open Shared

let annotationValueToString (annoVal:ISADotNet.AnnotationValue) =
match annoVal with
| ISADotNet.AnnotationValue.Text v -> v
| ISADotNet.AnnotationValue.Float v -> string v
| ISADotNet.AnnotationValue.Int v -> string v

let termAccessionReduce (uri:ISADotNet.URI) =
let li = uri.LastIndexOf @"/"
uri.Remove(0,li+1).Replace("_",":")

let valueIsOntology (v:ISADotNet.Value) =
match v with
| ISADotNet.Value.Ontology o ->
let name = o.Name.Value |> annotationValueToString
let tsr = o.TermSourceREF.Value
let tan = o.TermAccessionNumber.Value |> termAccessionReduce
Some <| OntologyInfo.create name tan
| _ ->
None

let valueToString (v:ISADotNet.Value) =
match v with
| ISADotNet.Value.Float f -> string f
| ISADotNet.Value.Int i -> string i
| ISADotNet.Value.Name s -> s
| ISADotNet.Value.Ontology o -> failwith "This Function (valueToString) should not be used to parse ISADotNet.Value.Ontology"
5 changes: 3 additions & 2 deletions src/Client/Messages.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ type ExcelInteropMsg =
| SyncContext of activeAnnotationTable:TryFindAnnoTableResult*string
| InSync of string
| FillSelection of activeAnnotationTable:TryFindAnnoTableResult * string * (DbDomain.Term option)
| AddAnnotationBlock of activeAnnotationTable:TryFindAnnoTableResult * colname:string * colTermOpt:DbDomain.Term option * unitNameOpt:string option * unitTermOpt:DbDomain.Term option
| AddUnitToAnnotationBlock of tryFindActiveAnnotationTable:TryFindAnnoTableResult * format:string option * unitTermOpt:DbDomain.Term option
| AddAnnotationBlock of activeAnnotationTable:TryFindAnnoTableResult * OfficeInterop.Types.BuildingBlockTypes.MinimalBuildingBlock
//| AddAnnotationBlocks of activeAnnotationTable:TryFindAnnoTableResult * OfficeInterop.Types.BuildingBlockTypes.MinimalBuildingBlock list
| AddUnitToAnnotationBlock of tryFindActiveAnnotationTable:TryFindAnnoTableResult * format:string option * unitTermAccession:string option
| FormatColumn of activeAnnotationTable:TryFindAnnoTableResult * colname:string * formatString:string * prevmsg:string
/// This message does not need the active annotation table as `PipeCreateAnnotationTableInfo` checks if any annotationtables exist in the active worksheet, and if so, errors.
| CreateAnnotationTable of allTableNames:string [] * isDark:bool
Expand Down
2 changes: 1 addition & 1 deletion src/Client/Model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ type ProtocolInsertState = {
} with
static member init () = {
UploadData = ""
ProcessModel = Some ISADotNet.Process.empty
ProcessModel = None
}

type Model = {
Expand Down
24 changes: 12 additions & 12 deletions src/Client/OfficeInterop/HelperFunctions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ let createEmptyMatrixForTables (colCount:int) (rowCount:int) value =
/// This will create the column header attributes for a unit block.
/// as unit always has to be a term and cannot be for example "Source" or "Sample", both of which have a differen format than for exmaple "Parameter [TermName]",
/// we only need one function to generate id and attributes and bring the unit term in the right format.
let unitColAttributes (unitTermName:string) (unitTermOpt:DbDomain.Term option) (id:int) =
let unitColAttributes (unitTermName:string) (unitAccessionOptt:string option) (id:int) =
match id with
| 1 ->
match unitTermOpt with
| Some t -> sprintf "[%s] (#h; #t%s; #u)" unitTermName t.Accession
| None -> sprintf "[%s] (#h; #u)" unitTermName
match unitAccessionOptt with
| Some accession -> sprintf "[%s] (#h; #t%s; #u)" unitTermName accession
| None -> sprintf "[%s] (#h; #u)" unitTermName
| _ ->
match unitTermOpt with
| Some t -> sprintf "[%s] (#%i; #h; #t%s #u)" unitTermName id t.Accession
| None -> sprintf "[%s] (#%i; #h; #u)" unitTermName id
match unitAccessionOptt with
| Some accession -> sprintf "[%s] (#%i; #h; #t%s #u)" unitTermName id accession
| None -> sprintf "[%s] (#%i; #h; #u)" unitTermName id


let createUnitColumns (allColHeaders:string []) (annotationTable:Table) newBaseColIndex rowCount (format:string option) (unitTermOpt:DbDomain.Term option) =
let createUnitColumns (allColHeaders:string []) (annotationTable:Table) newBaseColIndex rowCount (format:string option) (unitAccessionOpt:string option) =
let col = createEmptyMatrixForTables 1 rowCount ""
if format.IsSome then
let findNewIdForUnit() =
Expand All @@ -46,7 +46,7 @@ let createUnitColumns (allColHeaders:string []) (annotationTable:Table) newBaseC
// Should a column with the same name already exist, then count up the id tag.
|> Array.exists (fun existingHeader ->
// We don't need to check TSR or TAN, because the main column always starts with "Unit"
existingHeader = sprintf "Unit %s" (unitColAttributes format.Value unitTermOpt int)
existingHeader = sprintf "Unit %s" (unitColAttributes format.Value unitAccessionOpt int)
)
if isExisting then
loopingCheck (int+1)
Expand All @@ -61,23 +61,23 @@ let createUnitColumns (allColHeaders:string []) (annotationTable:Table) newBaseC
annotationTable.columns.add(
index = newBaseColIndex+3.,
values = U4.Case1 col,
name = sprintf "Unit %s" (unitColAttributes format.Value unitTermOpt newUnitId)
name = sprintf "Unit %s" (unitColAttributes format.Value unitAccessionOpt newUnitId)
)

/// create unit TSR
let createdUnitCol2 =
annotationTable.columns.add(
index = newBaseColIndex+4.,
values = U4.Case1 col,
name = sprintf "Term Source REF %s" (unitColAttributes format.Value unitTermOpt newUnitId)
name = sprintf "Term Source REF %s" (unitColAttributes format.Value unitAccessionOpt newUnitId)
)

/// create unit TAN
let createdUnitCol3 =
annotationTable.columns.add(
index = newBaseColIndex+5.,
values = U4.Case1 col,
name = sprintf "Term Accession Number %s" (unitColAttributes format.Value unitTermOpt newUnitId)
name = sprintf "Term Accession Number %s" (unitColAttributes format.Value unitAccessionOpt newUnitId)
)

Some (
Expand Down
58 changes: 32 additions & 26 deletions src/Client/OfficeInterop/OfficeInterop.fs
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,11 @@ let getTableRepresentation(annotationTable) =
)

/// This function is used to add a new building block to the active annotationTable.
let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term option,format:string option, unitTermOpt:DbDomain.Term option) =
let addAnnotationBlock (annotationTable,buildingBlockInfo:MinimalBuildingBlock) =

/// The following cols are currently always singles (cannot have TSR, TAN, unit cols). For easier refactoring these names are saved in OfficeInterop.Types.
let isSingleCol =
match colName with
match buildingBlockInfo.MainColumnName with
| ColumnCoreNames.Shown.Sample | ColumnCoreNames.Shown.Source | ColumnCoreNames.Shown.Data -> true
| _ -> false

Expand All @@ -410,21 +410,21 @@ let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term

/// This is used to create the bracket information for reference (hidden) columns. Again this has two modi, one with id tag and one without.
/// This time no core name is needed as this will always be TSR or TAN.
let hiddenColAttributes (parsedColHeader:ColHeader) (columnTermOption: DbDomain.Term option) (id:int) =
let hiddenColAttributes (parsedColHeader:ColHeader) (columnAccessionOpt: string option) (id:int) =
let coreName =
match parsedColHeader.Ontology, parsedColHeader.CoreName with
| Some o , _ -> o.Name
| None, Some cn -> cn
| _ -> parsedColHeader.Header
match id with
| 1 ->
match columnTermOption with
| Some t -> sprintf "[%s] (#h; #t%s)" coreName t.Accession
| None -> sprintf "[%s] (#h)" coreName
match columnAccessionOpt with
| Some accession -> sprintf "[%s] (#h; #t%s)" coreName accession
| None -> sprintf "[%s] (#h)" coreName
| _ ->
match columnTermOption with
| Some t -> sprintf "[%s] (#%i; #h; #t%s)" coreName id t.Accession
| None -> sprintf "[%s] (#%i; #h)" coreName id
match columnAccessionOpt with
| Some accession -> sprintf "[%s] (#%i; #h; #t%s)" coreName id accession
| None -> sprintf "[%s] (#%i; #h)" coreName id

Excel.run(fun context ->
let sheet = context.workbook.worksheets.getActiveWorksheet()
Expand Down Expand Up @@ -506,7 +506,7 @@ let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term
|> Array.map string

/// This is necessary to check if the would be created col name already exists, to then tick up the id tag.
let parsedBaseHeader = parseColHeader colName
let parsedBaseHeader = parseColHeader buildingBlockInfo.MainColumnName
/// This function checks if the would be col names already exist. If they do it ticks up the id tag to keep col names unique.
let findNewIdForName() =
let rec loopingCheck int =
Expand All @@ -515,15 +515,15 @@ let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term
// Should a column with the same name already exist, then count up the id tag.
|> Array.exists (fun existingHeader ->
if isSingleCol then
existingHeader = mainColName colName int
existingHeader = mainColName buildingBlockInfo.MainColumnName int
else
existingHeader = mainColName colName int
existingHeader = mainColName buildingBlockInfo.MainColumnName int
// i think it is necessary to also check for "TSR" and "TAN" because of the following possibilities
// Parameter [instrument model] | "Term Source REF [instrument model] (#h) | ...
// Factor [instrument model] | "Term Source REF [instrument model] (#h) | ...
// in the example above the mainColumn name is different but "TSR" and "TAN" would be the same.
|| existingHeader = sprintf "Term Source REF %s" (hiddenColAttributes parsedBaseHeader colTermOpt int)
|| existingHeader = sprintf "Term Accession Number %s" (hiddenColAttributes parsedBaseHeader colTermOpt int)
|| existingHeader = sprintf "Term Source REF %s" (hiddenColAttributes parsedBaseHeader buildingBlockInfo.MainColumnTermAccession int)
|| existingHeader = sprintf "Term Accession Number %s" (hiddenColAttributes parsedBaseHeader buildingBlockInfo.MainColumnTermAccession int)
)
if isExisting then
loopingCheck (int+1)
Expand All @@ -537,30 +537,36 @@ let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term
let rowCount = tableRange.rowCount |> int

//create an empty column to insert
let col = createEmptyMatrixForTables 1 rowCount ""
let col value = createEmptyMatrixForTables 1 rowCount value

printfn "%A" buildingBlockInfo.Values

// create main column
let createdCol1() =
let mainColVal = if buildingBlockInfo.Values.IsSome then buildingBlockInfo.Values.Value.Name else ""
annotationTable.columns.add(
index = newBaseColIndex,
values = U4.Case1 col,
name = mainColName colName newId
values = U4.Case1 (col mainColVal),
name = mainColName buildingBlockInfo.MainColumnName newId
)

// create TSR
let createdCol2() =
let tsrColVal = if buildingBlockInfo.Values.IsSome && buildingBlockInfo.Values.Value.TermAccession <> "" then buildingBlockInfo.Values.Value.TermAccession.Split([|":"|],StringSplitOptions.None).[0] else ""
annotationTable.columns.add(
index = newBaseColIndex+1.,
values = U4.Case1 col,
name = sprintf "Term Source REF %s" (hiddenColAttributes parsedBaseHeader colTermOpt newId)
values = U4.Case1 (col tsrColVal),
name = sprintf "Term Source REF %s" (hiddenColAttributes parsedBaseHeader buildingBlockInfo.MainColumnTermAccession newId)
)

// create TAN
let createdCol3() =
let linkTermAccession() = buildingBlockInfo.Values.Value.TermAccession |> Shared.URLs.termAccessionUrlOfAccessionStr
let tanColVal = if buildingBlockInfo.Values.IsSome && buildingBlockInfo.Values.Value.TermAccession <> "" then linkTermAccession() else ""
annotationTable.columns.add(
index = newBaseColIndex+2.,
values = U4.Case1 col,
name = sprintf "Term Accession Number %s" (hiddenColAttributes parsedBaseHeader colTermOpt newId)
values = U4.Case1 (col tanColVal),
name = sprintf "Term Accession Number %s" (hiddenColAttributes parsedBaseHeader buildingBlockInfo.MainColumnTermAccession newId)
)

// Should the column be Data, Source or Sample then we do not add TSR and TAN
Expand All @@ -577,21 +583,21 @@ let addAnnotationBlock (annotationTable,colName:string,colTermOpt:DbDomain.Term
/// if format.isSome then we need to also add unit columns in the following scheme:
/// Unit [UnitTermName] (#id; #h; #u) | Term Source REF [UnitTermName] (#id; #h; #u) | Term Accession Number [UnitTermName] (#id; #h; #u)
let createUnitColsIfNeeded =
OfficeInterop.HelperFunctions.createUnitColumns allColHeaders annotationTable newBaseColIndex rowCount format unitTermOpt
OfficeInterop.HelperFunctions.createUnitColumns allColHeaders annotationTable newBaseColIndex rowCount buildingBlockInfo.UnitName buildingBlockInfo.UnitTermAccession

/// If unit block was added then return some msg information
let unitColCreationMsg = if createUnitColsIfNeeded.IsSome then fst createUnitColsIfNeeded.Value else ""
let unitColFormat = if createUnitColsIfNeeded.IsSome then snd createUnitColsIfNeeded.Value else "0.00"

r.enableEvents <- true
/// return main col names, unit column format and a message. The first two params are used in a follow up message (executing 'changeTableColumnFormat')
mainColName colName newId, unitColFormat, sprintf "%s column was added. %s" colName unitColCreationMsg
mainColName buildingBlockInfo.MainColumnName newId, unitColFormat, sprintf "%s column was added. %s" buildingBlockInfo.MainColumnName unitColCreationMsg
)

return res
}
)

let changeTableColumnFormat annotationTable (colName:string) (format:string) =
Excel.run(fun context ->

Expand Down Expand Up @@ -1189,7 +1195,7 @@ let writeTableValidationToXml(tableValidation:ValidationTypes.TableValidation,cu
)

/// This function is used to add unit reference columns to an existing building block without unit reference columns
let addUnitToExistingBuildingBlock (annotationTable:string,format:string option,unitTermOpt:DbDomain.Term option) =
let addUnitToExistingBuildingBlock (annotationTable:string,format:string option,unitAccessionOpt:string option) =
Excel.run(fun context ->

let annotationTableName = annotationTable
Expand Down Expand Up @@ -1263,7 +1269,7 @@ let addUnitToExistingBuildingBlock (annotationTable:string,format:string option,
|> Array.map string

let unitColumnResult =
createUnitColumns allColHeaders annotationTable (float findLeftClosestBuildingBlock.MainColumn.Index) (int tableRange.rowCount) format unitTermOpt
createUnitColumns allColHeaders annotationTable (float findLeftClosestBuildingBlock.MainColumn.Index) (int tableRange.rowCount) format unitAccessionOpt

let maincolName = findLeftClosestBuildingBlock.MainColumn.Header.Value.Header

Expand Down
Loading

0 comments on commit 262dae3

Please sign in to comment.