SlideShare una empresa de Scribd logo
1 de 54
Descargar para leer sin conexión
Using Flow-based programming
... to write Tools and Workflows
for Scientific Computing
Go Stockholm Conference Oct 6, 2018
Samuel Lampa | bionics.it | @saml (slack) | @smllmp (twitter)
Ex - Dept. of Pharm. Biosci, Uppsala University | www.farmbio.uu.se | pharmb.io
Savantic AB savantic.se | RIL Partner AB rilpartner.com
About the speaker
● Name: Samuel Lampa
● PhD in Pharm. Bioinformatics from UU / pharmb.io (since 1 week)
● Researched: Flow-based programming-based workflow tools to build
predictive models for drug discovery
● Previously: HPC sysadmin & developer,Web developer,etc,
M.Sc. in molecular biotechnology engineering
● Next week: R&D Engineer at Savantic AB (savanticab.com)
● (Also:AfricArxiv (africarxiv.org) and RIL Partner AB (rilpartner.com))
Read more about my research
bit.ly/samlthesis →
(bionics.it/posts/phdthesis)
Flow-based … what?
Flow-based programming (FBP)
Note: Doesn’t need to
be done visaully though!
● Black box, asynchronously running processes
● Data exchange across predefined connections
between named ports (with bounded buffers) by
message passing only
● Connections specified separately from processes
● Processes can be reconnected endlessly to form
different applications without having being changed
internally
FBP in brief
Flow-based programming (FBP)
Note: Doesn’t need to
be done visaully though!
The Central Dogma of Biology …
… from DNA to RNA to Proteins
DNA
mRNA
Protein
Image credits: Nicolle Rager, National Science Foundation. License: Public domain
Amino acids
Ribosome
RNA
polymerase
Cell nucleus
Cell
“FBP is a particular form of dataflow
programming based on bounded buffers,
information packets with defined lifetimes,
named ports, and separate definition
of connections”
FBP vs Dataflow
● Change of connection wiring
without rewriting components
● Inherently concurrent - suited
for the multi-core CPU world
● Testing, monitoring and logging very
easy: Just plug in a mock-, logging-
or debugging component.
● Etc etc ...
Benefits abound
jpaulmorrison.com(/fbp)
Invented by J. Paul Morrison at IBM in late 60’s
github.com/trustmaster/goflow
by Vladimir Sibirov @sibiroff (twitter)
FBP in Go: GoFlow
FBP in plain Go
(almost) without frameworks?
Generator functions
Adapted from Rob Pike’s slides: talks.golang.org/2012/concurrency.slide#25
func main() {
c := generateInts(10) // Call function to get a channel
for v := range c { // … and loop over it
fmt.Println(v)
}
}
func generateInts(max int) <-chan int { // Return a channel of ints
c := make(chan int)
go func() { // Init go-routine inside function
defer close(c)
for i := 0; i <= max; i++ {
c <- i
}
}()
return c // Return the channel
}
Chaining generator functions 1/2
func reverse(cin chan string) chan string {
cout := make(chan string)
go func() {
defer close(cout)
for s := range cin { // Loop over in-chan
cout <- reverse(s) // Send on out-chan
}
}()
return cout
}
Chaining generator functions 2/2
// Chain the generator functions
dna := generateDNA() // Generator func of strings
rev := reverse(dna)
compl := complement(rev)
// Drive the chain by reading from last channel
for dnaString := range compl {
fmt.Println(dnaString)
}
Chaining generator functions 2/2
// Chain the generator functions
dna := generateDNA() // Generator func of strings
rev := reverse(dna)
compl := complement(rev)
// Drive the chain by reading from last channel
for dnaString := range compl {
fmt.Println(dnaString)
}
Problems with the generator approach
● Inputs not named in connection code (no keyword arguments)
● Multiple return values depend on positional arguments:
leftPart, rightPart := splitInHalves(chanOfStrings)
Could we emulate named ports?
type P struct {
in chan string // Channels as struct fields, to act as “named ports”
out chan string
}
func NewP() *P { // Initialize a new component
return &P{
in: make(chan string, 16),
out: make(chan string, 16),
}
}
func (p *P) Run() {
defer close(p.out)
for s := range p.in { // Refer to struct fields when reading ...
p.out <- s // ... and writing
}
}
Could we emulate named ports?
func main() {
p1 := NewP()
p2 := NewP()
p2.in = p1.out // Connect dependencies here, by assigning to same chan
go p1.Run()
go p2.Run()
go func() { // Feed the input of the network
defer close(p1.in)
for i := 0; i <= 10; i++ {
p1.in <- "Hej"
}
}()
for s := range p2.out { // Drive the chain from the main go-routine
fmt.Println(s)
}
}
Add almost no additional code, and get:
flowbase.org
Real-world use of FlowBase
● RDF (Semantic) MediaWiki XML→
● Import via MediaWiki XML import
● Code: github.com/rdfio/rdf2smw
● Paper: bit.ly/rdfiopub
Connecting dependencies with FlowBase
ttlFileRead.OutTriple = aggregator.In
aggregator.Out = indexCreator.In
indexCreator.Out = indexFanOut.In
indexFanOut.Out["serialize"] = indexToAggr.In
indexFanOut.Out["conv"] = triplesToWikiConverter.InIndex
indexToAggr.Out = triplesToWikiConverter.InAggregate
triplesToWikiConverter.OutPage = xmlCreator.InWikiPage
xmlCreator.OutTemplates = templateWriter.In
xmlCreator.OutProperties = propertyWriter.In
xmlCreator.OutPages = pageWriter.In
github.com/rdfio/rdf2smw/blob/e7e2b3/main.go#L100-L125
Taking it further: Port structs
ttlFileRead.OutTriple().To(aggregator.In())
aggregator.Out().To(indexCreator.In())
indexCreator.Out().To(indexToAggr.In())
indexCreator.Out().To(triplesToWikiConverter.InIndex())
indexToAggr.Out().To(triplesToWikiConverter.InAggregate())
triplesToWikiConverter.OutPage().To(xmlCreator.InWikiPage())
xmlCreator.OutTemplates().To(templateWriter.In())
xmlCreator.OutProperties().To(propertyWriter.In())
xmlCreator.OutPages().To(pageWriter.In())
(So far only used in SciPipe, not yet FlowBase)
SciPipe
Write Scientific Workflows in Go
● Define processes with shell command patterns
● Atomic writes, Restartable workflows, Caching
● Automatic file naming
● Audit logging
● Workflow graph plotting
● Intro & Docs: scipipe.org
● Preprint paper: doi.org/10.1101/380808
SciPipe
● Workflow
● Keeps track of dependency graph
● Process
● Added to workflows
● Long-running
● Typically one per operation
● Task
● Spawned by processes
● Executes just one shell command or custom Go function
● Typically one task spawned per operation on a set of input files
● Information Packet (IP)
● Most common data type passed between processes
Workflow
Process
File IP
Task
Task
Task
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs & inputs
(dependencies / data flow)
● Run the workflow
“Hello World” in SciPipe
package main
import (
// Import the SciPipe package, aliased to 'sp'
sp "github.com/scipipe/scipipe"
)
func main() {
// Init workflow with a name, and max concurrent tasks
wf := sp.NewWorkflow("hello_world", 4)
// Initialize processes and set output file paths
hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}")
hello.SetOut("out", "hello.txt")
world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}")
world.SetOut("out", "{i:in|%.txt}_world.txt")
// Connect network
world.In("in").From(hello.Out("out"))
// Run workflow
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Writing SciPipe workflows
package main
import (
"github.com/scipipe/scipipe"
)
const dna = "AAAGCCCGTGGGGGACCTGTTC"
func main() {
wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4)
makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}")
makeDNA.SetOut("dna", "dna.txt")
complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}")
complmt.SetOut("compl", "{i:in|%.txt}.compl.txt")
reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}")
reverse.SetOut("rev", "{i:in|%.txt}.rev.txt")
complmt.In("in").From(makeDNA.Out("dna"))
reverse.In("in").From(complmt.Out("compl"))
wf.Run()
}
● Import SciPipe
● Set up any default variables
or data, handle flags etc
● Initiate workflow
● Create processes
● Define outputs and paths
● Connect outputs to inputs
(dependencies / data flow)
● Run the workflow
Running it
go run revcompl.go
Dependency graph plotting
Structured audit log
(Hierarchical JSON)
Turn Audit log into TeX/PDF report
TeX template by Jonathan Alvarsson @jonalv
● Intuitive behaviour: Like conveyor belts & stations in a factory.
● Flexible: Combine command-line programs with Go components
● Custom file naming: Easy to manually browse output files
● Portable: Distribute as Go code or as compiled executable files
● Easy to debug: Use any Go debugging tools or even just println()
● Powerful audit logging: Stream outputs via UNIX FIFO files
● Efficient & Parallel: Fast code + Efficient use of multi-core CPU
Benefits of SciPipe - Thanks to Go + FBP
More info at:
scipipe.org
Thank you for your time!
Using Flow-based programming
... to write Tools and Workflows for Scientific Computing
Talk at Go Stockholm Conference Oct 6, 2018
Samuel Lampa | bionics.it | @saml (slack) | @smllmp (twitter)
Dept. of Pharm. Biosci, Uppsala University | www.farmbio.uu.se | pharmb.io

Más contenido relacionado

La actualidad más candente

Migrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifierMigrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifierClayton Parker
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Futureemptysquare
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with TransmogrifierClayton Parker
 
Euro python2011 High Performance Python
Euro python2011 High Performance PythonEuro python2011 High Performance Python
Euro python2011 High Performance PythonIan Ozsvald
 
Transmogrifier: Migrating to Plone with less pain
Transmogrifier: Migrating to Plone with less painTransmogrifier: Migrating to Plone with less pain
Transmogrifier: Migrating to Plone with less painLennart Regebro
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)Subhas Kumar Ghosh
 
When RegEx is not enough
When RegEx is not enoughWhen RegEx is not enough
When RegEx is not enoughNati Cohen
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes
 
Reversing the dropbox client on windows
Reversing the dropbox client on windowsReversing the dropbox client on windows
Reversing the dropbox client on windowsextremecoders
 
Naughty And Nice Bash Features
Naughty And Nice Bash FeaturesNaughty And Nice Bash Features
Naughty And Nice Bash FeaturesNati Cohen
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinAhmad Arif Faizin
 
Go Concurrency Basics
Go Concurrency Basics Go Concurrency Basics
Go Concurrency Basics ElifTech
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionEleanor McHugh
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Steven Francia
 
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...Journeys with Transmogrifier and friends or How not to get stuck in the Plone...
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...Daniel Jowett
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrencyjgrahamc
 
06 file processing
06 file processing06 file processing
06 file processingIssay Meii
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistAnton Arhipov
 

La actualidad más candente (20)

Migrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifierMigrating from drupal to plone with transmogrifier
Migrating from drupal to plone with transmogrifier
 
Python Coroutines, Present and Future
Python Coroutines, Present and FuturePython Coroutines, Present and Future
Python Coroutines, Present and Future
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
 
Euro python2011 High Performance Python
Euro python2011 High Performance PythonEuro python2011 High Performance Python
Euro python2011 High Performance Python
 
Transmogrifier: Migrating to Plone with less pain
Transmogrifier: Migrating to Plone with less painTransmogrifier: Migrating to Plone with less pain
Transmogrifier: Migrating to Plone with less pain
 
Don't do this
Don't do thisDon't do this
Don't do this
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)
 
When RegEx is not enough
When RegEx is not enoughWhen RegEx is not enough
When RegEx is not enough
 
Geeks Anonymes - Le langage Go
Geeks Anonymes - Le langage GoGeeks Anonymes - Le langage Go
Geeks Anonymes - Le langage Go
 
Reversing the dropbox client on windows
Reversing the dropbox client on windowsReversing the dropbox client on windows
Reversing the dropbox client on windows
 
Naughty And Nice Bash Features
Naughty And Nice Bash FeaturesNaughty And Nice Bash Features
Naughty And Nice Bash Features
 
Dts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlinDts x dicoding #2 memulai pemrograman kotlin
Dts x dicoding #2 memulai pemrograman kotlin
 
Go Concurrency Basics
Go Concurrency Basics Go Concurrency Basics
Go Concurrency Basics
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go
 
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...Journeys with Transmogrifier and friends or How not to get stuck in the Plone...
Journeys with Transmogrifier and friends or How not to get stuck in the Plone...
 
Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
06 file processing
06 file processing06 file processing
06 file processing
 
JavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with JavassistJavaOne 2015 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
 

Similar a Using Flow-based programming to write tools and workflows for Scientific Computing in Go

scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scalaRuslan Shevchenko
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Robert Stern
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOMykola Novik
 
Dev8d 2011-pipe2 py
Dev8d 2011-pipe2 pyDev8d 2011-pipe2 py
Dev8d 2011-pipe2 pyTony Hirst
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionPaulo Morgado
 
Future vs. Monix Task
Future vs. Monix TaskFuture vs. Monix Task
Future vs. Monix TaskHermann Hueck
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generatorsdantleech
 
PySpark with Juypter
PySpark with JuypterPySpark with Juypter
PySpark with JuypterLi Ming Tsai
 
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides:  Let's build macOS CLI Utilities using SwiftMobileConf 2021 Slides:  Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using SwiftDiego Freniche Brito
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoMatt Stine
 
Diseño y Desarrollo de APIs
Diseño y Desarrollo de APIsDiseño y Desarrollo de APIs
Diseño y Desarrollo de APIsRaúl Neis
 
Go serving: Building server app with go
Go serving: Building server app with goGo serving: Building server app with go
Go serving: Building server app with goHean Hong Leong
 
Node.js basics
Node.js basicsNode.js basics
Node.js basicsBen Lin
 
모던자바의 역습
모던자바의 역습모던자바의 역습
모던자바의 역습DoHyun Jung
 
CP3108B (Mozilla) Sharing Session on Add-on SDK
CP3108B (Mozilla) Sharing Session on Add-on SDKCP3108B (Mozilla) Sharing Session on Add-on SDK
CP3108B (Mozilla) Sharing Session on Add-on SDKMifeng
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 

Similar a Using Flow-based programming to write tools and workflows for Scientific Computing in Go (20)

scala-gopher: async implementation of CSP for scala
scala-gopher:  async implementation of CSP  for  scalascala-gopher:  async implementation of CSP  for  scala
scala-gopher: async implementation of CSP for scala
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1
 
Os lab final
Os lab finalOs lab final
Os lab final
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIO
 
Dev8d 2011-pipe2 py
Dev8d 2011-pipe2 pyDev8d 2011-pipe2 py
Dev8d 2011-pipe2 py
 
Gore: Go REPL
Gore: Go REPLGore: Go REPL
Gore: Go REPL
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
 
Future vs. Monix Task
Future vs. Monix TaskFuture vs. Monix Task
Future vs. Monix Task
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
PySpark with Juypter
PySpark with JuypterPySpark with Juypter
PySpark with Juypter
 
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides:  Let's build macOS CLI Utilities using SwiftMobileConf 2021 Slides:  Let's build macOS CLI Utilities using Swift
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
 
Puppi. Puppet strings to the shell
Puppi. Puppet strings to the shellPuppi. Puppet strings to the shell
Puppi. Puppet strings to the shell
 
Apache Beam de A à Z
 Apache Beam de A à Z Apache Beam de A à Z
Apache Beam de A à Z
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Diseño y Desarrollo de APIs
Diseño y Desarrollo de APIsDiseño y Desarrollo de APIs
Diseño y Desarrollo de APIs
 
Go serving: Building server app with go
Go serving: Building server app with goGo serving: Building server app with go
Go serving: Building server app with go
 
Node.js basics
Node.js basicsNode.js basics
Node.js basics
 
모던자바의 역습
모던자바의 역습모던자바의 역습
모던자바의 역습
 
CP3108B (Mozilla) Sharing Session on Add-on SDK
CP3108B (Mozilla) Sharing Session on Add-on SDKCP3108B (Mozilla) Sharing Session on Add-on SDK
CP3108B (Mozilla) Sharing Session on Add-on SDK
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 

Más de Samuel Lampa

Linked Data for improved organization of research data
Linked Data  for improved organization  of research dataLinked Data  for improved organization  of research data
Linked Data for improved organization of research dataSamuel Lampa
 
How to document computational research projects
How to document computational research projectsHow to document computational research projects
How to document computational research projectsSamuel Lampa
 
Reproducibility in Scientific Data Analysis - BioScience Seminar
Reproducibility in Scientific Data Analysis - BioScience SeminarReproducibility in Scientific Data Analysis - BioScience Seminar
Reproducibility in Scientific Data Analysis - BioScience SeminarSamuel Lampa
 
Batch import of large RDF datasets into Semantic MediaWiki
Batch import of large RDF datasets into Semantic MediaWikiBatch import of large RDF datasets into Semantic MediaWiki
Batch import of large RDF datasets into Semantic MediaWikiSamuel Lampa
 
SciPipe - A light-weight workflow library inspired by flow-based programming
SciPipe - A light-weight workflow library inspired by flow-based programmingSciPipe - A light-weight workflow library inspired by flow-based programming
SciPipe - A light-weight workflow library inspired by flow-based programmingSamuel Lampa
 
Vagrant, Ansible and Docker - How they fit together for productive flexible d...
Vagrant, Ansible and Docker - How they fit together for productive flexible d...Vagrant, Ansible and Docker - How they fit together for productive flexible d...
Vagrant, Ansible and Docker - How they fit together for productive flexible d...Samuel Lampa
 
iRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetiRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetSamuel Lampa
 
AddisDev Meetup ii: Golang and Flow-based Programming
AddisDev Meetup ii: Golang and Flow-based ProgrammingAddisDev Meetup ii: Golang and Flow-based Programming
AddisDev Meetup ii: Golang and Flow-based ProgrammingSamuel Lampa
 
First encounter with Elixir - Some random things
First encounter with Elixir - Some random thingsFirst encounter with Elixir - Some random things
First encounter with Elixir - Some random thingsSamuel Lampa
 
Profiling go code a beginners tutorial
Profiling go code   a beginners tutorialProfiling go code   a beginners tutorial
Profiling go code a beginners tutorialSamuel Lampa
 
Flow based programming an overview
Flow based programming   an overviewFlow based programming   an overview
Flow based programming an overviewSamuel Lampa
 
Python Generators - Talk at PySthlm meetup #15
Python Generators - Talk at PySthlm meetup #15Python Generators - Talk at PySthlm meetup #15
Python Generators - Talk at PySthlm meetup #15Samuel Lampa
 
The RDFIO Extension - A Status update
The RDFIO Extension - A Status updateThe RDFIO Extension - A Status update
The RDFIO Extension - A Status updateSamuel Lampa
 
My lightning talk at Go Stockholm meetup Aug 6th 2013
My lightning talk at Go Stockholm meetup Aug 6th 2013My lightning talk at Go Stockholm meetup Aug 6th 2013
My lightning talk at Go Stockholm meetup Aug 6th 2013Samuel Lampa
 
Hooking up Semantic MediaWiki with external tools via SPARQL
Hooking up Semantic MediaWiki with external tools via SPARQLHooking up Semantic MediaWiki with external tools via SPARQL
Hooking up Semantic MediaWiki with external tools via SPARQLSamuel Lampa
 
Thesis presentation Samuel Lampa
Thesis presentation Samuel LampaThesis presentation Samuel Lampa
Thesis presentation Samuel LampaSamuel Lampa
 
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in BioclipseSamuel Lampa
 
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in BioclipseSamuel Lampa
 

Más de Samuel Lampa (18)

Linked Data for improved organization of research data
Linked Data  for improved organization  of research dataLinked Data  for improved organization  of research data
Linked Data for improved organization of research data
 
How to document computational research projects
How to document computational research projectsHow to document computational research projects
How to document computational research projects
 
Reproducibility in Scientific Data Analysis - BioScience Seminar
Reproducibility in Scientific Data Analysis - BioScience SeminarReproducibility in Scientific Data Analysis - BioScience Seminar
Reproducibility in Scientific Data Analysis - BioScience Seminar
 
Batch import of large RDF datasets into Semantic MediaWiki
Batch import of large RDF datasets into Semantic MediaWikiBatch import of large RDF datasets into Semantic MediaWiki
Batch import of large RDF datasets into Semantic MediaWiki
 
SciPipe - A light-weight workflow library inspired by flow-based programming
SciPipe - A light-weight workflow library inspired by flow-based programmingSciPipe - A light-weight workflow library inspired by flow-based programming
SciPipe - A light-weight workflow library inspired by flow-based programming
 
Vagrant, Ansible and Docker - How they fit together for productive flexible d...
Vagrant, Ansible and Docker - How they fit together for productive flexible d...Vagrant, Ansible and Docker - How they fit together for productive flexible d...
Vagrant, Ansible and Docker - How they fit together for productive flexible d...
 
iRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat SheetiRODS Rule Language Cheat Sheet
iRODS Rule Language Cheat Sheet
 
AddisDev Meetup ii: Golang and Flow-based Programming
AddisDev Meetup ii: Golang and Flow-based ProgrammingAddisDev Meetup ii: Golang and Flow-based Programming
AddisDev Meetup ii: Golang and Flow-based Programming
 
First encounter with Elixir - Some random things
First encounter with Elixir - Some random thingsFirst encounter with Elixir - Some random things
First encounter with Elixir - Some random things
 
Profiling go code a beginners tutorial
Profiling go code   a beginners tutorialProfiling go code   a beginners tutorial
Profiling go code a beginners tutorial
 
Flow based programming an overview
Flow based programming   an overviewFlow based programming   an overview
Flow based programming an overview
 
Python Generators - Talk at PySthlm meetup #15
Python Generators - Talk at PySthlm meetup #15Python Generators - Talk at PySthlm meetup #15
Python Generators - Talk at PySthlm meetup #15
 
The RDFIO Extension - A Status update
The RDFIO Extension - A Status updateThe RDFIO Extension - A Status update
The RDFIO Extension - A Status update
 
My lightning talk at Go Stockholm meetup Aug 6th 2013
My lightning talk at Go Stockholm meetup Aug 6th 2013My lightning talk at Go Stockholm meetup Aug 6th 2013
My lightning talk at Go Stockholm meetup Aug 6th 2013
 
Hooking up Semantic MediaWiki with external tools via SPARQL
Hooking up Semantic MediaWiki with external tools via SPARQLHooking up Semantic MediaWiki with external tools via SPARQL
Hooking up Semantic MediaWiki with external tools via SPARQL
 
Thesis presentation Samuel Lampa
Thesis presentation Samuel LampaThesis presentation Samuel Lampa
Thesis presentation Samuel Lampa
 
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
3rd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
 
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
2nd Proj. Update: Integrating SWI-Prolog for Semantic Reasoning in Bioclipse
 

Último

Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingrakeshbaidya232001
 
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...RajaP95
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...Soham Mondal
 
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...ranjana rawat
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxhumanexperienceaaa
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130Suhani Kapoor
 
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCollege Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVRajaP95
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSKurinjimalarL3
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)Suman Mia
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Serviceranjana rawat
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations120cr0395
 

Último (20)

Porous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writingPorous Ceramics seminar and technical writing
Porous Ceramics seminar and technical writing
 
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
IMPLICATIONS OF THE ABOVE HOLISTIC UNDERSTANDING OF HARMONY ON PROFESSIONAL E...
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
 
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...
(TARA) Talegaon Dabhade Call Girls Just Call 7001035870 [ Cash on Delivery ] ...
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
 
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
9953056974 Call Girls In South Ex, Escorts (Delhi) NCR.pdf
 
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
VIP Call Girls Service Kondapur Hyderabad Call +91-8250192130
 
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service NashikCollege Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
College Call Girls Nashik Nehal 7001305949 Independent Escort Service Nashik
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
 
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICSAPPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
APPLICATIONS-AC/DC DRIVES-OPERATING CHARACTERISTICS
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations
 

Using Flow-based programming to write tools and workflows for Scientific Computing in Go

  • 1. Using Flow-based programming ... to write Tools and Workflows for Scientific Computing Go Stockholm Conference Oct 6, 2018 Samuel Lampa | bionics.it | @saml (slack) | @smllmp (twitter) Ex - Dept. of Pharm. Biosci, Uppsala University | www.farmbio.uu.se | pharmb.io Savantic AB savantic.se | RIL Partner AB rilpartner.com
  • 2. About the speaker ● Name: Samuel Lampa ● PhD in Pharm. Bioinformatics from UU / pharmb.io (since 1 week) ● Researched: Flow-based programming-based workflow tools to build predictive models for drug discovery ● Previously: HPC sysadmin & developer,Web developer,etc, M.Sc. in molecular biotechnology engineering ● Next week: R&D Engineer at Savantic AB (savanticab.com) ● (Also:AfricArxiv (africarxiv.org) and RIL Partner AB (rilpartner.com))
  • 3. Read more about my research bit.ly/samlthesis → (bionics.it/posts/phdthesis)
  • 5.
  • 6.
  • 7.
  • 8.
  • 9. Flow-based programming (FBP) Note: Doesn’t need to be done visaully though!
  • 10. ● Black box, asynchronously running processes ● Data exchange across predefined connections between named ports (with bounded buffers) by message passing only ● Connections specified separately from processes ● Processes can be reconnected endlessly to form different applications without having being changed internally FBP in brief
  • 11. Flow-based programming (FBP) Note: Doesn’t need to be done visaully though!
  • 12.
  • 13.
  • 14. The Central Dogma of Biology … … from DNA to RNA to Proteins DNA mRNA Protein Image credits: Nicolle Rager, National Science Foundation. License: Public domain Amino acids Ribosome RNA polymerase Cell nucleus Cell
  • 15. “FBP is a particular form of dataflow programming based on bounded buffers, information packets with defined lifetimes, named ports, and separate definition of connections” FBP vs Dataflow
  • 16. ● Change of connection wiring without rewriting components ● Inherently concurrent - suited for the multi-core CPU world ● Testing, monitoring and logging very easy: Just plug in a mock-, logging- or debugging component. ● Etc etc ... Benefits abound
  • 17. jpaulmorrison.com(/fbp) Invented by J. Paul Morrison at IBM in late 60’s
  • 18. github.com/trustmaster/goflow by Vladimir Sibirov @sibiroff (twitter) FBP in Go: GoFlow
  • 19. FBP in plain Go (almost) without frameworks?
  • 20. Generator functions Adapted from Rob Pike’s slides: talks.golang.org/2012/concurrency.slide#25 func main() { c := generateInts(10) // Call function to get a channel for v := range c { // … and loop over it fmt.Println(v) } } func generateInts(max int) <-chan int { // Return a channel of ints c := make(chan int) go func() { // Init go-routine inside function defer close(c) for i := 0; i <= max; i++ { c <- i } }() return c // Return the channel }
  • 21. Chaining generator functions 1/2 func reverse(cin chan string) chan string { cout := make(chan string) go func() { defer close(cout) for s := range cin { // Loop over in-chan cout <- reverse(s) // Send on out-chan } }() return cout }
  • 22. Chaining generator functions 2/2 // Chain the generator functions dna := generateDNA() // Generator func of strings rev := reverse(dna) compl := complement(rev) // Drive the chain by reading from last channel for dnaString := range compl { fmt.Println(dnaString) }
  • 23. Chaining generator functions 2/2 // Chain the generator functions dna := generateDNA() // Generator func of strings rev := reverse(dna) compl := complement(rev) // Drive the chain by reading from last channel for dnaString := range compl { fmt.Println(dnaString) }
  • 24. Problems with the generator approach ● Inputs not named in connection code (no keyword arguments) ● Multiple return values depend on positional arguments: leftPart, rightPart := splitInHalves(chanOfStrings)
  • 25. Could we emulate named ports? type P struct { in chan string // Channels as struct fields, to act as “named ports” out chan string } func NewP() *P { // Initialize a new component return &P{ in: make(chan string, 16), out: make(chan string, 16), } } func (p *P) Run() { defer close(p.out) for s := range p.in { // Refer to struct fields when reading ... p.out <- s // ... and writing } }
  • 26. Could we emulate named ports? func main() { p1 := NewP() p2 := NewP() p2.in = p1.out // Connect dependencies here, by assigning to same chan go p1.Run() go p2.Run() go func() { // Feed the input of the network defer close(p1.in) for i := 0; i <= 10; i++ { p1.in <- "Hej" } }() for s := range p2.out { // Drive the chain from the main go-routine fmt.Println(s) } }
  • 27. Add almost no additional code, and get: flowbase.org
  • 28. Real-world use of FlowBase ● RDF (Semantic) MediaWiki XML→ ● Import via MediaWiki XML import ● Code: github.com/rdfio/rdf2smw ● Paper: bit.ly/rdfiopub
  • 29. Connecting dependencies with FlowBase ttlFileRead.OutTriple = aggregator.In aggregator.Out = indexCreator.In indexCreator.Out = indexFanOut.In indexFanOut.Out["serialize"] = indexToAggr.In indexFanOut.Out["conv"] = triplesToWikiConverter.InIndex indexToAggr.Out = triplesToWikiConverter.InAggregate triplesToWikiConverter.OutPage = xmlCreator.InWikiPage xmlCreator.OutTemplates = templateWriter.In xmlCreator.OutProperties = propertyWriter.In xmlCreator.OutPages = pageWriter.In github.com/rdfio/rdf2smw/blob/e7e2b3/main.go#L100-L125
  • 30. Taking it further: Port structs ttlFileRead.OutTriple().To(aggregator.In()) aggregator.Out().To(indexCreator.In()) indexCreator.Out().To(indexToAggr.In()) indexCreator.Out().To(triplesToWikiConverter.InIndex()) indexToAggr.Out().To(triplesToWikiConverter.InAggregate()) triplesToWikiConverter.OutPage().To(xmlCreator.InWikiPage()) xmlCreator.OutTemplates().To(templateWriter.In()) xmlCreator.OutProperties().To(propertyWriter.In()) xmlCreator.OutPages().To(pageWriter.In()) (So far only used in SciPipe, not yet FlowBase)
  • 31. SciPipe Write Scientific Workflows in Go ● Define processes with shell command patterns ● Atomic writes, Restartable workflows, Caching ● Automatic file naming ● Audit logging ● Workflow graph plotting ● Intro & Docs: scipipe.org ● Preprint paper: doi.org/10.1101/380808
  • 32. SciPipe ● Workflow ● Keeps track of dependency graph ● Process ● Added to workflows ● Long-running ● Typically one per operation ● Task ● Spawned by processes ● Executes just one shell command or custom Go function ● Typically one task spawned per operation on a set of input files ● Information Packet (IP) ● Most common data type passed between processes Workflow Process File IP Task Task Task
  • 33. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() }
  • 34. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 35. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 36. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 37. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 38. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 39. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs & inputs (dependencies / data flow) ● Run the workflow
  • 40. “Hello World” in SciPipe package main import ( // Import the SciPipe package, aliased to 'sp' sp "github.com/scipipe/scipipe" ) func main() { // Init workflow with a name, and max concurrent tasks wf := sp.NewWorkflow("hello_world", 4) // Initialize processes and set output file paths hello := wf.NewProc("hello", "echo 'Hello ' > {o:out}") hello.SetOut("out", "hello.txt") world := wf.NewProc("world", "echo $(cat {i:in}) World >> {o:out}") world.SetOut("out", "{i:in|%.txt}_world.txt") // Connect network world.In("in").From(hello.Out("out")) // Run workflow wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 41. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 42. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 43. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 44. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 45. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 46. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 47. Writing SciPipe workflows package main import ( "github.com/scipipe/scipipe" ) const dna = "AAAGCCCGTGGGGGACCTGTTC" func main() { wf := scipipe.NewWorkflow("DNA Base Complement Workflow", 4) makeDNA := wf.NewProc("Make DNA", "echo "+dna+" > {o:dna}") makeDNA.SetOut("dna", "dna.txt") complmt := wf.NewProc("Base Complement", "cat {i:in} | tr ATCG TAGC > {o:compl}") complmt.SetOut("compl", "{i:in|%.txt}.compl.txt") reverse := wf.NewProc("Reverse", "cat {i:in} | rev > {o:rev}") reverse.SetOut("rev", "{i:in|%.txt}.rev.txt") complmt.In("in").From(makeDNA.Out("dna")) reverse.In("in").From(complmt.Out("compl")) wf.Run() } ● Import SciPipe ● Set up any default variables or data, handle flags etc ● Initiate workflow ● Create processes ● Define outputs and paths ● Connect outputs to inputs (dependencies / data flow) ● Run the workflow
  • 48. Running it go run revcompl.go
  • 51. Turn Audit log into TeX/PDF report TeX template by Jonathan Alvarsson @jonalv
  • 52. ● Intuitive behaviour: Like conveyor belts & stations in a factory. ● Flexible: Combine command-line programs with Go components ● Custom file naming: Easy to manually browse output files ● Portable: Distribute as Go code or as compiled executable files ● Easy to debug: Use any Go debugging tools or even just println() ● Powerful audit logging: Stream outputs via UNIX FIFO files ● Efficient & Parallel: Fast code + Efficient use of multi-core CPU Benefits of SciPipe - Thanks to Go + FBP
  • 54. Thank you for your time! Using Flow-based programming ... to write Tools and Workflows for Scientific Computing Talk at Go Stockholm Conference Oct 6, 2018 Samuel Lampa | bionics.it | @saml (slack) | @smllmp (twitter) Dept. of Pharm. Biosci, Uppsala University | www.farmbio.uu.se | pharmb.io