Skip to content

Commit 23ffa64

Browse files
committed
add workflowgraph core
1 parent 96f47ee commit 23ffa64

10 files changed

Lines changed: 1255 additions & 1 deletion

Directory.Packages.props

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<PackageVersion Include="Fable.Node" Version="1.2.0" />
2222
<PackageVersion Include="Fable.Promise" Version="3.2.0" />
2323
<PackageVersion Include="Fable.Pyxpecto" Version="1.3.0" />
24+
<PackageVersion Include="Siren" Version="0.3.2" />
2425
<PackageVersion Include="NJsonSchema" Version="10.8.0" />
2526
</ItemGroup>
26-
</Project>
27+
</Project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<Description>Graph extraction and visualization helpers for CWL processing units used in ARCtrl.</Description>
5+
<PackageProjectUrl>https://github.com/nfdi4plants/ARCtrl/tree/main/src/WorkflowGraph</PackageProjectUrl>
6+
<PackageTags>ARC;F#;FSharp;dotnet;fable-library;workflow;graph;cwl;mermaid</PackageTags>
7+
</PropertyGroup>
8+
<Import Project="../Package.Metadata.props" />
9+
10+
<ItemGroup>
11+
<Compile Include="GraphTypes.fs" />
12+
<Compile Include="ReferenceParsing.fs" />
13+
<Compile Include="BuildOptions.fs" />
14+
<Compile Include="QueryHelpers.fs" />
15+
<Compile Include="Builder.fs" />
16+
<Compile Include="Adapters.fs" />
17+
<Compile Include="Visualization.Siren.fs" />
18+
<Compile Include="WorkflowGraph.fs" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<PackageReference Include="Siren" />
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<ProjectReference Include="..\CWL\ARCtrl.CWL.fsproj" />
27+
<ProjectReference Include="..\Core\ARCtrl.Core.fsproj" />
28+
<ProjectReference Include="..\FileSystem\ARCtrl.FileSystem.fsproj" />
29+
</ItemGroup>
30+
</Project>

src/WorkflowGraph/Adapters.fs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
namespace ARCtrl.WorkflowGraph
2+
3+
open ARCtrl
4+
open ARCtrl.Helper
5+
open ARCtrl.CWL
6+
7+
[<RequireQualifiedAccess>]
8+
module Adapters =
9+
10+
let private createCwlLookupFromInvestigation (investigation: ArcInvestigation option) =
11+
match investigation with
12+
| None ->
13+
Map.empty
14+
| Some inv ->
15+
seq {
16+
for workflow in inv.Workflows do
17+
match workflow.CWLDescription with
18+
| Some cwl ->
19+
yield Identifier.Workflow.cwlFileNameFromIdentifier workflow.Identifier, cwl
20+
| None ->
21+
()
22+
for run in inv.Runs do
23+
match run.CWLDescription with
24+
| Some cwl ->
25+
yield Identifier.Run.cwlFileNameFromIdentifier run.Identifier, cwl
26+
| None ->
27+
()
28+
}
29+
|> Seq.map (fun (path, cwl) -> ArcPathHelper.normalizePathKey path, cwl)
30+
|> Map.ofSeq
31+
32+
let private createResolver (lookup: Map<string, CWLProcessingUnit>) =
33+
if Map.isEmpty lookup then
34+
None
35+
else
36+
Some (fun (path: string) -> lookup |> Map.tryFind (ArcPathHelper.normalizePathKey path))
37+
38+
let private createMissingDescriptionError identifier scopeType =
39+
{
40+
Kind = GraphIssueKind.MissingCwlDescription
41+
Message = $"No CWLDescription available for {scopeType} '{identifier}'."
42+
Scope = Some identifier
43+
Reference = None
44+
}
45+
46+
let ofWorkflow (workflow: ArcWorkflow) : Result<WorkflowGraph, GraphBuildIssue> =
47+
match workflow.CWLDescription with
48+
| None ->
49+
Error (createMissingDescriptionError workflow.Identifier "workflow")
50+
| Some processingUnit ->
51+
let cwlLookup = createCwlLookupFromInvestigation workflow.Investigation
52+
let options =
53+
WorkflowGraphBuildOptions.defaultOptions
54+
|> WorkflowGraphBuildOptions.withRootScope workflow.Identifier
55+
|> WorkflowGraphBuildOptions.withRootWorkflowFilePath (Some (Identifier.Workflow.cwlFileNameFromIdentifier workflow.Identifier))
56+
|> WorkflowGraphBuildOptions.withTryResolveRunPath (createResolver cwlLookup)
57+
Builder.buildWith options processingUnit
58+
|> Ok
59+
60+
let ofRun (run: ArcRun) : Result<WorkflowGraph, GraphBuildIssue> =
61+
match run.CWLDescription with
62+
| None ->
63+
Error (createMissingDescriptionError run.Identifier "run")
64+
| Some processingUnit ->
65+
let cwlLookup = createCwlLookupFromInvestigation run.Investigation
66+
let options =
67+
WorkflowGraphBuildOptions.defaultOptions
68+
|> WorkflowGraphBuildOptions.withRootScope run.Identifier
69+
|> WorkflowGraphBuildOptions.withRootWorkflowFilePath (Some (Identifier.Run.cwlFileNameFromIdentifier run.Identifier))
70+
|> WorkflowGraphBuildOptions.withTryResolveRunPath (createResolver cwlLookup)
71+
Builder.buildWith options processingUnit
72+
|> Ok
73+
74+
let ofInvestigation (investigation: ArcInvestigation) : WorkflowGraphIndex =
75+
let workflowGraphs = ResizeArray()
76+
let runGraphs = ResizeArray()
77+
78+
for workflow in investigation.Workflows do
79+
workflowGraphs.Add(workflow.Identifier, ofWorkflow workflow)
80+
for run in investigation.Runs do
81+
runGraphs.Add(run.Identifier, ofRun run)
82+
83+
{
84+
WorkflowGraphs = workflowGraphs
85+
RunGraphs = runGraphs
86+
}

src/WorkflowGraph/BuildOptions.fs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
namespace ARCtrl.WorkflowGraph
2+
3+
open ARCtrl.CWL
4+
5+
type WorkflowGraphBuildOptions = {
6+
RootScope: string
7+
RootWorkflowFilePath: string option
8+
TryResolveRunPath: (string -> CWLProcessingUnit option) option
9+
StrictUnresolvedRunReferences: bool
10+
ExpandNestedWorkflows: bool
11+
}
12+
13+
[<RequireQualifiedAccess>]
14+
module WorkflowGraphBuildOptions =
15+
16+
let defaultOptions =
17+
{
18+
RootScope = "root"
19+
RootWorkflowFilePath = None
20+
TryResolveRunPath = None
21+
StrictUnresolvedRunReferences = false
22+
ExpandNestedWorkflows = true
23+
}
24+
25+
let withRootScope (rootScope: string) (options: WorkflowGraphBuildOptions) =
26+
{ options with RootScope = rootScope }
27+
28+
let withRootWorkflowFilePath (rootWorkflowFilePath: string option) (options: WorkflowGraphBuildOptions) =
29+
{ options with RootWorkflowFilePath = rootWorkflowFilePath }
30+
31+
let withTryResolveRunPath (tryResolveRunPath: (string -> CWLProcessingUnit option) option) (options: WorkflowGraphBuildOptions) =
32+
{ options with TryResolveRunPath = tryResolveRunPath }
33+
34+
let withStrictUnresolvedRunReferences (strict: bool) (options: WorkflowGraphBuildOptions) =
35+
{ options with StrictUnresolvedRunReferences = strict }
36+
37+
let withExpandNestedWorkflows (expandNestedWorkflows: bool) (options: WorkflowGraphBuildOptions) =
38+
{ options with ExpandNestedWorkflows = expandNestedWorkflows }

0 commit comments

Comments
 (0)