Radni tokovi i šta s njima?

Upoznajte sa Common Workflow Language (CWL), osnovom bionformatičkih radnih tokova za samo 30 minuta. U ovom članku je dato kratko korisničko uputstvo koje će vam približiti koncepte dizajniranja analitičkih radnih tokova. Reprezentativni primeri namenjeni su i čitaocima koji nemaju prethodnog iskustva.

Šta su radni tokovi (workflows)?

Svaki posao koji obavljamo svesno ili nesvesno delimo na manje zadatke, koje izvršavamo u odgovarajućem redosledu kako bismo došli do krajnjeg cilja. Analitički radni tokovi nisu ništa drugo do savremena verzija ovog univerzalnog principa, prilagođena obradi i analizi podataka.

Podaci su postali nezamenljiva sirovina koja pokreće poslovanje, istraživanje i donošenje odluka. Sekvence za obradu podataka omogućavaju nam da podatke pretvorimo u znanje, identifikujemo obrasce i tendencije, i stvorimo vrednost iz mnoštva informacija. Podaci predstavljaju ključ za efikasno i precizno postizanje ciljeva.

Automatizacija tokova postaje sve važnija u današnjem brzom digitalnom okruženju. Analitički radni tokovi omogućavaju nam da automatizujemo složene zadatke, štedeći vreme i resurse. Možemo automatizovati procese kao što je obrada velikih količina podataka, izračunavanje statističkih parametara ili generisanje izveštaja.

U nastavku ćemo saznati kako se koriste alati kao što je Common Workflow Language (CWL) kako bismo definisali, izvršavali i optimizovali radne sekvence.

Šta je Common Workflow Language?

Common Workflow Language (CWL) je otvoren standardni jezik i format za opisivanje analitičkih radnih tokova i izvršavanje istih na različitim računarskim platformama. To znači da možete napisati radni tok u CWL formatu i izvršavati ga na različitim računarima ili u različitim analitičkim alatima bez potrebe za izmenama u kodu ili instalaciji zavisnosti.

CWL omogućava precizno definisanje koraka u radnom toku, uključujući ulaze, izlaze, komande i zavisnosti između koraka. Tokovi su način za definisanje i organizovanje sekvence koraka ili radnih zadataka kako biste postigli određeni cilj.

Ovo je posebno korisno u bioinformatici, istraživanjima i drugim oblastima gde se često koriste složeni radni tokovi za analizu podataka.

CWL se definišu u YAML (i/ili JSON) formatu.

Primena

U naučnim istraživanjima, CWL se često koristi za definisanje radnih tokova koji obuhvataju analizu podataka, obradu rezultata eksperimenata i generisanje izveštaja. CWL se često koristi u bioinformatici za automatizaciju analize genoma, sekvenciranje genoma i druge kompleksne bioinformatičke operacije. U laboratorijskim i eksperimentalnim postavkama, CWL može biti korišćen za automatizaciju eksperimenata, uključujući pripremu uzoraka, prikupljanje podataka i analizu rezultata.

Može se koristiti za definisanje i dokumentovanje procesa obrade podataka, uključujući čišćenje podataka, treniranje modela i evaluaciju performansi.

Opis i konfiguracija radnog toka

U sekciji koja sledi, istražićemo ključne aspekte opisa i konfiguracije radnih tokova kako biste stekli detaljnije razumevanje osnovnih zahteva i teorijskih koncepata potrebnih za implementaciju i pokretanje toka posla.

Instalacija cwltool-a

Prva stvar koja je potrebna za pokretanje CWL radnih tokova je CWL runner – cwltool. To je Python projekat otvorenog koda koji održava CWL zajednica. Može se instalirati pomoću pip komande:

pip install cwltool

Pokretanje

CWL specifikacija uz pomoć cwltool-a se moze pokrenuti na sledeći način:

cwltool naziv_cwl_skripte.cwl

Nekada će biti potrebno proslediti i dodatne parametre, ukoliko imamo pozivanje neke komande u terminalu, kao što je na primer echo.

Naredba cwltool ima opciju za validaciju CWL alata i opisa radnih tokova. Ona će analizirati CWL dokument, tražiti greške u sintaksi i proveriti da li su opisi u skladu sa CWL standardima, bez da izvršenja. Da biste validirali CWL radne tokove, koristite opciju –validate u naredbi cwltool:

cwltool --validate naziv_cwl_skripte.cwl

Moguće je da je skripta potvrđena, ali i dalje dobija grešku. Ako naiđete na grešku, najbolja praksa je da pokrenete tok posla sa oznakom –debug. To će vam pružiti detaljne informacije o grešci na koju nailazite:

cwltool --debug naziv_cwl_skripte.cwl

YAML

YAML je format datoteke dizajniran da ga čitaju i računari i ljudi. U nastavku su predstavljeni osnovni koncepti YAML-a, koji će pomoći razumevanju primera koje obrađujemo. Ukoliko želite detaljnije da se upoznate sa konceptima YAML-a možete pogledati link: https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started

Parovi ključ-vrednost

U osnovi, datoteka napisana u YAML-u sastoji se od skupa parova ključ/vrednost. Svaki par je napisan kao ključ: vrednost. Imena ključeva u CWL datotekama ne bi trebalo da sadrže razmak. Vrednosti mogu biti stringovi, numeričke, logičke (tačno ili netačno), ili složeniji ugnježdeni tipovi.

first_name: Bilbo
last_name:  Baggins

U CWL-u svi delovi baseCommand-a moraju biti stringovi tako da, ako želite da navedete fiksnu numeričku vrednost komandi, uverite se da ste tu numeričku vrednost postavili u navodnike:

baseCommand: [echo, "42"]

Mape

Kada opisujete alatku ili tok posla sa CWL, obično je potrebno konstruisati složenije, ugnježdene reprezentacije. Ove hijerarhijske strukture, koje se nazivaju mapama, opisane su u YAML-u pružanjem dodatnih parova ključ-vrednost kao vrednosti bilo kog ključa. Ovi parovi („deca“) su napisani u posebnim redovima pod ključem kojem pripadaju („roditelj“) i treba da budu uvučeni sa dva razmaka (⇥tab znakovi nisu dozvoljeni).

inputs:
  - id: poruka
    type: string
    default: "Hello World"
    inputBinding:
      position: 1

Komentari

Komentari u CWL specifikaciji se dodaju sa #. Program koji tumači YAML ignoriše sve znakove desno od #.

Nizovi

U određenim okolnostima potrebno je obezbediti više vrednosti ili objekata za jedan ključ. To možemo postići pomoću niza, gde je svaka vrednost definisana u posebnoj liniji i prethodi . Na primer:

touchfiles:
  - foo.txt
  - bar.dat
  - baz.txt

što je analogno sa:

touchfiles: [foo.txt, bar.dat, baz.txt]

Klase CWL skripte

U Common Workflow Language-u, postoje tri osnovna tipa klasa koje možete koristiti za opisivanje radnih tokova i alatki:

  • CommandLineTool (Alatka za rad iz komandne linije): Ovo je osnovni tip klase u CWL-u. CommandLineTool definiše ulaze, izlaze, i komandu koja se izvršava. Primer je kompajliranje koda, obrada podataka ili bilo koja druga operacija koja se može pokrenuti iz komandne linije.
  • ExpressionTool (Alatka za izračunavanje izraza): Klasa se koristi za izračunavanje vrednosti na osnovu izraza ili skupa izraza. Ova alatka se često koristi za transformaciju i manipulaciju podacima. ExpressionTool koristi izraze napisane u skript jeziku (kao što je JavaScript), kako bi izračunao izlazne vrednosti na osnovu ulaznih podataka.
  • Workflow (Radni Tok): Omogućava kompoziciju CommandLineTool i ExpressionTool entiteta kako bi se definisali kompleksni radni tokovi. Workflow definiše kako se različite alatke i izrazi povezuju i međusobno zavise. Ovo omogućava opisivanje složenih operacija koje uključuju više koraka i izračunavanja.

Ulazi

Ulazi predstavljaju listu ulaznih parametara koji upravljaju načinom izvršavanja tog alata. Svaki parametar ima svoj identifikator za naziv parametra (id) i tip (type) koji opisuje koje vrste vrednosti su prihvatljive za taj parametar.

Uvodimo indetifikatore jer imena omogućavaju jasno razlikovanje između različitih ulaznih i izlaznih parametara u okviru radnog toka. Ovo je ključno kako bi se precizno definisalo šta se očekuje kao ulaz i šta će biti rezultat izvršavanja radnog toka. Dodatno omogućavaju drugim delovima radnog toka, kao što su drugi koraci ili operacije, da referenciraju fajlove. Na taj način se omogućava povezivanje između različitih koraka radnog toka i pravilan prenos podataka.

Dostupni osnovni tipovi su string, int, long, float, double i null; složeni tipovi su array i record; pored toga, postoje posebni tipovi File, Directory i Any. Evo jednog od načina za definisanje ulaza:

baseCommand: echo
inputs:
  poruka:
    type: string
    default: "Hello World"
    inputBinding:
      position: 1

Polje inputBinding je opcino i označava da li i kako ulazni parametar treba da se pojavi na komandnoj liniji alata. Ako inputBinding nedostaje, parametar se neće pojaviti na komandnoj liniji. Ovde polje pozicije (position) pokazuje na kojoj poziciji će biti ulaz na komandnoj liniji. Na primer, posle komandne echo (navedeno u baseCommand).

Šta ako nemam ulazne podatke?

Naravno postoje slučajevi kada nećete imati nikav ulaz potreban za izvršavanje CWL skripte. Tada je dovoljno da opišete input na sledeci nacin:

inputs: []

Analogno ćete uraditi i za izlaze (outputs), ali je važno da polja inputs i outputs postoje u skripti.

Izlazi

Izlazi predstavljaju listu izlaznih parametara koji bi trebali biti vraćeni nakon izvršavanja CWL skripte. Svaki parametar ima svoj identifikator koji predstavlja njegovo ime (id), i tip (type) koji opisuje koje vrste vrednosti su valjane za taj parametar.

Kada se alat izvršava u okviru CWL-a, radni direktorijum u kojem alat počinje raditi postaje odredišni izlazni direktorijum. Osnovni alat ili skripta moraju zabeležiti svoje rezultate u obliku fajlova koji se kreiraju u izlaznom direktorijumu. CWL alat može vratiti datoteke koje su kreirane tokom izvršavanja, ili može analizirati sadržaj tih datoteka i vratiti druge vrednosti koje proizilaze iz te analize.

outputs:
  - id: kompresovan_fajl
    type: File
    outputBinding:
      glob: "*.gz"

stdout: output.txt.gz

Polje outputBinding opisuje kako postaviti vrednost svakog izlaznog parametra. Prikazana sekcija definiše kako će se izlazna datoteka povezati sa rezultirajućim izlazom. U ovom slučaju, koristi se glob: "*.gz", što znači da će se izlazna datoteka imenovati tako da ima ekstenziju „.gz“. Polje glob predstavlja imena datoteke u izlaznom direktorijumu. Ukoliko nije unapred poznato ime datoteke mogu se koristiti šeme “*.gz”, “*.txt”, i drugo.

Stdout

Da biste uhvatili standardni izlaz alata, dodajte polje stdout sa imenom datoteke gde bi trebao ići izlazni tok. Zatim dodajte type: stdout na odgovarajući izlazni parametar.

outputs:
  - id: output_file
    type: stdout

stdout: brojevi.txt

type: stdout:Ova opcija se koristi kada želite preuzeti standardni izlaz i koristiti ga kao izlazni parametar u radnom toku.

stdout: brojevi.txt: Ovde se određuje ime fajla u koji će biti preusmeren standardni izlaz alata. Ovo se obično koristi kada želite sačuvati standardni izlaz u datoteku kako biste ga kasnije koristili ili analizirali.

Izlaz kao niz

Takođe moguce je postaviti više izlaznih datoteka u niz datoteka koristeći glob.

niz_fajlova.cwl

cwlVersion: v1.0
class: CommandLineTool
baseCommand: touch
inputs:
  touchfiles:
    type:
      type: array
      items: string
    inputBinding:
      position: 1
outputs:
  output:
    type:
      type: array
      items: File
    outputBinding:
      glob: "*.txt"

Primer ulaza:

touchfiles:
  - foo.txt
  - bar.dat
  - baz.txt

Podsetnik: U sekciji YAML smo objasnili na ovom primeru ulaza, kako definišemo nizove.

Kao rezultat izvršavanja niz_fajlova.cwl sa zadatim ulazom kreiraju se fajlovi foo.txt i baz.txt

Izrazi

Alat za izvršavanje izraza (expression tool) je vrsta skripte koja može da se izvršava samostalno ili kao korak u radnom toku. On izvršava čist izraz u JavaScriptu. Koristi se kao način izolacije kompleksnih JavaScript izraza koji treba da operišu nad ulaznim podacima i proizvedu neki rezultat kao izlaz.

CWL kao alat za izvršavanje izraza

Slično kao i alati za rad iz komandne linije, alat za izraze zahteva ulaze (inputs) i izlaze (outputs). Međutim, umesto baseCommand, zahteva atribut ExpressionTool.

kvadriranje.cwl

cwlVersion: v1.0
class: ExpressionTool

requirements:
  InlineJavascriptRequirement: {}

inputs:
  broj:
    type: int

outputs:
  kvadrirano:
    type: int

expression: |
 ${return (inputs.broj * inputs.broj)}

InlineJavascriptRequirement je zahtev u CWL-u koji omogućava izvršavanje JavaScript koda unutar skripte. Ovo je korisno kada je potrebno izvršiti složene izračune, manipulisati podacima ili primeniti logiku koja nije podržana standardnim CWL operacijama ili alatkama.

Pokretanje: cwltool kvadriranje.cwl --broj 10

Zadatak:

Pokušajte na osnovu prethodnog primera da sami napišete skriptu koja će poruku koja se prosledi kao ulazni parametar da transformiše tako da ima sva velika slova. Važno je da koristite InlineJavascriptRequirement. Pristupite poruci preko ulaza (inputs.message na primer) i iskoristite Javascript funkciju toUpperCase().

Proverite svoje rešenje na: https://www.commonwl.org/user_guide/topics/expression-tool.html

Napomena: U CWL-u, ako želite definisati ulazni ili izlazni parametar, možete koristiti - id: naziv ili samo naziv: da biste naznačili identifikator parametra. Obe sintakse su ispravne i CWL će ih prepoznati i tretirati na isti način.

Radni tokovi

Radni tok (workflow) je procesna jedinica u CWL-u koja izvršava alate komandne linije (command-line tools), alate za izraze (expression tools) ili druge radne tokove (sub-workflows) kao korake. Moraju biti definisani ulazi, izlazi i koraci u CWL dokumentu.

CWL radni tok

Primer radnog toka:

cwlVersion: v1.2
class: Workflow

inputs:
  - id: ulaz1
    type: neki_tip
   
outputs:
  - id: final_output
    type: tip
    outputSource: korak3/output_korak3

steps:
  - id: korak1
    run: korak1.cwl
    in:
      input_text: ulaz1
    out: [output_korak1]

  - id: korak2
    run: korak2.cwl
    in:
      input_text: korak1/output_korak1
    out: [output_korak2]

  - id: korak3
    run: korak3.cwl
    in:
      input_text: korak2/output_korak2
    out: [output_korak3]

Deo inputs opisuje ulaze radnog toka. To je lista ulaznih parametara gde svaki parametar sadrži indentifikator i tip podataka. Ovi parametri se mogu koristiti kao izvori ulaza za određene korake u radnom toku. Polje steps je obavezno. U ovom polju se navedeni koraci radnog toka.

Koraci se ne izvršavaju nužno u redosledu kako su navedeni, već se redosled određuje zavisnostima između koraka. Osim toga, delovi radnog toka koji nisu međusobno zavisni mogu se izvršavati paralelno. Navodimo svaki korak sa specifičnim imenom i u njemu postavljamo sledeće:

  • run: Ovde se navodi ime CWL skripte koja će biti izvršena kao deo ove faze. To znači da će se sadržaj ove skripte izvršiti u okviru ovog koraka radnog toka.
  • in: ulazni parametar za navedenu skriptu.
  • out: izlazni parametar za navedenu skriptu.

Kao što možete primetiti ulazi i izlazi pojedinačnih delova se referenciraju međusobno. Šta to znači? Već smo rekli da moramo da dajemo imena i koracima i ulaznim/izlaznim parametrima. Tako pretpostavljamo da nam za ulaz korak2 treba izlaz iz korak1. Stoga navodimo naziv_potrebnog_koraka/naziv_izlaznog_parametra: korak1/output_korak1

Deo outputs opisuje izlazne parametre radnog toka. To je lista izlaznih parametara gde svaki sadrži identifikator i tip podataka. Polje outputSource služi za povezivanje izlaznog parametra određenog koraka sa krajnjim izlaznim parametrom radnog toka.

Radni pod-tokovi

Radni tokovi su način za kombinovanje više alatki kako bi se izvršile veće operacije. Takođe možemo razmatrati radni tok kao sam alat; CWL radni tok može se koristiti kao korak u drugom CWL radnom toku.

Vizuelizacija toka

Benten je ekstenzija u Visual Studio Code (VSCode) koje, između ostalog, vizuelizuje tok posla u grafikonu. Kada je Benten instaliran u VSCode, alatka se može koristiti za vizuelizaciju toka posla. U gornjem desnom uglu prozora VSCode može se otvoriti CWL pregledač, pogledajte snimak ekrana ispod.

CWL pregled

I naravno u zavisnosti složenosti samog toka, broja ugnježdenih tokova dobijamo različite i grafičke prikaze.

Radni tok

Docker i radni tokovi

„Ponovljivost“ je ključni pojam u svetu bioinformatičkih i drugih radnih tokova. Ona se odnosi na sposobnost ponovnog izvođenja istog eksperimenta ili analize sa istim rezultatom, bez obzira na vreme i mesto izvođenja.

Docker igra ključnu ulogu u postizanju ponovljivosti u naučnim radnim tokovima. Evo nekoliko načina na koje Docker doprinosi ovom aspektu:

  • Izolacija okoline: Docker omogućava kreiranje izolovanih okolina (environment) za izvršavanje radnih tokova. Svaki alat može biti „zapakovan“ u Docker kontejner koji sadrži sve potrebne zavisnosti, alate i biblioteke. Ovo sprečava probleme usled različitih verzija softvera.
  • Pouzdanost i doslednost: Docker kontejneri garantuju doslednost između izvršavanja. Ako je zadatak uspešno izvršen u jednom Docker kontejneru, isti kontejner može biti kloniran i izvršen na drugom mestu sa identičnim rezultatom.
  • Lakoća deljenja: Docker kontejneri se mogu lako deliti sa drugim istraživačima ili članovima tima.

Kontejneri su namerno izolovani od host sistema, pa je potrebno dodatno se obezbediti da ulazne datoteke budu dostupne unutar kontejnera i da se izlazne datoteke mogu povratiti iz kontejnera. CWL runner može automatski obavljati ovu radnju.

Jedna od odgovornosti CWL runner-a je da prilagodi putanje ulaznih datoteka kako bi odražavale lokaciju na kojoj se one nalaze unutar kontejnera.

U CWL skripti možemo naznačiti koju komandu želimo da izvršimo unutar kontejnera na sledeći način:

baseCommand: [gzip, '-c']
hints:
  DockerRequirement:
    dockerPull: naziv_slike:oznaka

baseCommand: [gzip, '-c'] obaveštava CWL da ćemo izvršavati ovu komandu unutar kontejnera. Parametar dockerPull: uzima istu vrednost koju biste prosledili docker pull komandi.

Primeri

Na osnovu prethodnih postavki, dati su konkretni primeri sa objašjenjima. Sve skripte su kompletne i mogu se pokrenuti.

Napomena: Podrazumeva se da su svi fajlovi koji su vezani za isti primer smešteni u zajednički direktorijum.

Primer 1: Hello world

Pokazaćemo jednostavan primer gde ćemo echo komadnu zameniti CWL specifikacijom. Kada pokrenemo ovaj kod dobićemo isti efekat kao da smo izvršili echo “Hello world”.

hello_world.cwl

cwlVersion: v1.2
class: CommandLineTool
baseCommand: echo
inputs:
  poruka:
    type: string
    default: "Hello World"
    inputBinding:
      position: 1
outputs: []

Kao što možete primetiti, neki delovi su objašnjeni u prethodnim sekcijama. Ali sada ćemo objasniti nove elemente kao i dati celokupan pregled ovog i narednih kodova.

String cwlVersion definiše koji je standard jezika potreban za alatku ili tok posla. Najnovija verzija je v1.2. Inače prva dva reda su uvek ista, CWL verzija i klasa skripte su definisani. Sledeći red, baseCommand, sadrži komandu koja će biti pokrenuta (echo).

Kao ulaz (inputs) se navodi stringovni parametar sa id-em "poruka". Da bismo pokrenuli ovaj primer, moraćemo da obezbedimo string koji će biti uključen u komandnu liniju i to na poziciji 1 posle baseCommand na sledeći način:

cwltool hello_world.cwl --poruka "Operativni sistemi"

Još jedna stvar na koju bi trebalo obratiti pažnju jeste polje default, kojim se definiše podrazumevana poruka, tako da i ukoliko ne dodamo nikakve parametre skripta će biti pokrenuta i „Hello world“ će biti ispisano u terminalu. Ali ukoliko želimo da promenimo poruku možemo to uraditi kao sa porukom „Operativni sistemi“ ili prosleđivanjem ulaznog json fajla u kome je poruka ispisana.

Neka ovako izgleda json fajl, gde ključ u fajlu mora odgovarati indetifikatoru ulaza u cwl skripti.

zadat_ulaz.json

{
  "poruka": "Hola mundo"
}

Sada pokrećemo na sledeći način i ispisuje se poruka „Hola mundo“.

cwltool hello_world.cwl zadat_ulaz.json

Cilj je samo simulirati komandu echo i ispisati poruku, tako da nemamo izlazne parametre i onda outputs: [].

Napomena: Da bi skripta bila čitljivija, polje za ulaz se stavlja ispred polja za izlaz. Međutim, CWL sintaksa zahteva samo da svako polje bude pravilno definisano, a ne zahteva da budu u određenom redosledu.

Primer 2: Kompresija datoteke

Kompresija je nešto što svakako često radimo i u narednom kodu ćemo uz pomoć CWL skripte izvršiti gzip komandu nad određenim fajlom.

kompresija.cwl

cwlVersion: v1.2
class: CommandLineTool
baseCommand: [gzip, '-c']
# hints:
#   DockerRequirement:
#     dockerPull: naziv_slike:oznaka

inputs:
  - id: input_file
    type: File
    inputBinding:
      position: 1

outputs:
  - id: kompresovan_fajl
    type: File
    outputBinding:
      glob: "*.gz"

stdout: output.txt.gz

baseCommand: [gzip, '-c']: Ovde se definiše osnovna komanda koja će se izvršiti.

inputs: Ovo je sekcija koja definiše ulazni fajl koji ce se koristiti kao ulaz. Tip je "File".

U ovom slučaju, koristi se "glob: '*.gz'", što znači da će se izlazna datoteka imenovati tako da ima ekstenziju „.gz“.

stdout: output.txt.gz: Ovo definiše standardni izlaz i daje ime izlazne datoteke.

Ukoliko želite da kompresiju obavite unutar docker kontejnera, možete iskoristiti zakomentarisani deo i zameniti naziv docker slike i oznaku odgovarajućim.

Dodatno ćemo kreirati YAML fajl u kome ćemo definisati ulazne parametre za pokretanje.

input_file.yml

input_file:
  class: File
  path: proba.txt

gde je input_file ključ sa kojim određujemo naš ulazni fajl i isti je i u input_file.yml i kompresija.cwl. Ovde se komprimuje fajl proba.txt.

Primer 3: Kreiranje radnog toka

Kako smo razmotrili jednostavnije primere, u ovom delu ćemo da objasnimo kako kreirati jedan radni tok, koji u sebi sadrži više zasebnih koraka. Obradićemo situacije u kojima izlaz iz jednog koraka je ulaz u drugi, gde svaki obavlja nezavisne operacije nad podacima.

Naš zadatak je da u prvom delu pokrenemo python skriptu, koja generiše 200 nasumičnih brojeva i to upisuje u datoteku brojevi.txt. U drugoj fazi potrebno je da brojeve u fajlu sortiramo. Poslednji korak je da tako izmenjenu brojevi.txt komprimujemo. Svaki ovaj deo, naravno, mogli bismo da odradimo pojedinačno i ručno, ali sada možemo pokretanjem jednog toka da sačekamo par sekundi i dobijemo sve odjednom.

U nastavku su date CWL skripta i Python skripta koju je potrebno pokrenuti.

generisanje_brojeva.cwl

class: CommandLineTool
cwlVersion: v1.0
inputs:
  script:
    type: File
    default:
      class: File
      contents:
        $include: generisanje_brojeva.py
    inputBinding:
      position: 1

outputs:
  - id: generisani_brojevi
    type: stdout

stdout: brojevi.txt

baseCommand: python

generisanje_brojeva.cwl

generisanje_brojeva.py

import random

with open('brojevi.txt', 'w') as output_file:
    for _ in range(200):
        broj = random.randint(1, 1000)  
        output_file.write(str(broj) + '\n')  

generisanje_brojeva.py

U generisanje_brojeva.cwl dat je kod za pokretanje python skripte. Klasa je CommandLineTool što znači da želimo da iskoristimo komadu python u terminalu i da simuliramo situaciju kao da smo pokrenuli python generisanje_brojeva.py, pa shodno tome imamo python kao baseCommand. Što se tiče ulaza, dat je parametar script. U ovom slučaju, podrazumevana vrednost je definisana kao File sa sadržajem koji se uključuje iz generisanje_brojeva.py. Polje inputBinding, standardno, definiše kako će se ulazni parametar povezati sa komandom. Zatim se definiše da će standardni izlaz alatke biti preusmeren u datoteku brojevi.txt.

U nastavku je dat kod za sortiranje brojeva.

sortiranje.cwl

cwlVersion: v1.0
class: CommandLineTool
baseCommand: [sort, '-n']

inputs:
  - id: input_file
    type: File
    inputBinding:
      position: 1

outputs:
  - id: sortirani_izlaz
    type: File
    outputBinding:
      glob: sortirano.txt
  
stdout: sortirano.txt

I u ovom slučaju data je skripta klase CommandLineTool, gde je komanda sort -n, koja se koristi kada želite da sortirate brojeve. Ulaz je tipa File, sto će zapravo biti generisana datoteka u prethodnom koraku. A zatim se sortirani brojevi smeštaju u sortirano.txt.

Napomenuli smo da je poslednji korak kompresija fajla i taj kod se može iskoristiti iz prethodnog primera.

Sada kada imamo implementirane manje akcije, možemo da probamo da ih sve spojimo kroz jedan radni tok. Razmotrimo narednu skriptu:

svi_koraci.cwl

cwlVersion: v1.2
class: Workflow

inputs: []

outputs:
  - id: final_output
    type: File
    outputSource: kompresovanje/kompresovan_fajl
   
steps:
  - id: generisanje_brojeva
    run: generisanje_brojeva.cwl
    in: []
    out: [generisani_brojevi]

  - id: sort
    run: sortiranje.cwl
    in:
      input_file: generisanje_brojeva/generisani_brojevi
    out: [sortirani_izlaz]

  - id: kompresovanje
    run: kompresija.cwl
    in:
      input_file: sort/sortirani_izlaz
    out: [kompresovan_fajl]

Kako kreiramo tok, menjamo i samu klasu (class: Workflow). Ulaz u celu sekvencu nemamo, tj. ne zadajemo ga prilikom pokretanja skripte, već se kroz izvršavanje koraka generiše. Steps, kao što smo napomenuli ranije jeste obavezno polje.

Za sortiranje nam je potreban fajl iz koraka "generisanje_brojeva". Za kompresiju je potreban sortirani fajl (sortirani_izlaz) koji se dobija kao izlaz iz faze sort. Iskoristimo nazive koraka i izlaznih fajlova i povežemo ih na način kako je objašnjeno u delu Radni tokovi. Izlaz iz poslednjeg koraka je kompresovan_fajl što je istovremeno izlaz i iz celog toka pa zato definišemo outputSource: kompresovanje/kompresovan_fajl u outputs.

Važno je napomenuti da se nazivi izlaza koraka i nazivi u CWL skriptama na koje se odnose moraju poklapati. Primetite da je u kompresija.cwl izlaz kompresovan_fajl, a izlaz iz faze kompreosvanje u radnom toku je takođe kompresovan_fajl.

Možemo pogledati i vizuelni pregled našeg toka. Kako nemamo puno koraka i pod-tokova i sam prikaz neće biti komplikovan.

 
CWL pregled za primer 3

Zaključak

CWL predstavlja moćan alat za definisanje, izvođenje i deljenje računarskih radnih tokova. Ova standardizovana specifikacija omogućava korisnicima da jednostavno opišu složene radne tokove, koristeći raznovrsne alatke i resurse, bez obzira na platformu na kojoj se izvršavaju.

CWL zahteva jasno definisanje svih ulaza, izlaza i koraka u radnom toku. Može biti integrisan sa različitim alatima za upravljanje radnim sekvencama, što omogućava automatizaciju njihovog izvršavanja.

Korisni linkovi

Dodatna objašnjenja, primere možete pogledati na:

Autor: Rijalda Bajraktarevic

Studentkinja završne godine osnovnih studija Informatike na Prirodno-matematičkom fakultetu u Kragujevcu.

Rijalda Bajraktarevic

Studentkinja završne godine osnovnih studija Informatike na Prirodno-matematičkom fakultetu u Kragujevcu.