Część 1: Podstawowe operacje¶
Tłumaczenie wspomagane przez AI - dowiedz się więcej i zasugeruj ulepszenia
W tej pierwszej części kursu szkoleniowego Nextflow Run łagodnie wprowadzamy temat za pomocą bardzo prostego przykładu Hello World. Ten niezależny od dziedziny przykład posłuży do zademonstrowania podstawowych operacji i wskazania odpowiednich komponentów kodu Nextflow.
Czym jest przykład Hello World?
"Hello World!" to minimalistyczny przykład, który ma na celu zademonstrowanie podstawowej składni i struktury języka programowania lub frameworka oprogramowania. Przykład zazwyczaj polega na wypisaniu frazy "Hello, World!" na urządzenie wyjściowe, takie jak konsola lub terminal, lub zapisaniu jej do pliku.
1. Uruchom Hello World bezpośrednio¶
Zademonstrujmy tę koncepcję prostym poleceniem, które uruchamiamy bezpośrednio w terminalu, aby pokazać, co robi, zanim opakujemy je w Nextflow.
Wskazówka
Pamiętaj, że powinieneś teraz znajdować się w katalogu nextflow-run/, jak opisano na stronie Rozpoczęcie pracy.
1.1. Spraw, aby terminal powiedział cześć¶
Uruchom następujące polecenie w terminalu.
To wypisuje tekst 'Hello World' bezpośrednio w terminalu.
1.2. Zapisz wyjście do pliku¶
Uruchamianie pipeline'ów głównie polega na odczytywaniu danych z plików i zapisywaniu wyników do innych plików, więc zmodyfikujmy polecenie, aby zapisać wyjście tekstowe do pliku, co uczyni przykład bardziej odpowiednim.
To nie wypisuje niczego do terminala.
1.3. Znajdź wyjście¶
Tekst 'Hello World' powinien teraz znajdować się w pliku wyjściowym, który określiliśmy, o nazwie output.txt.
Możesz go otworzyć w eksploratorze plików lub z wiersza poleceń, używając na przykład narzędzia cat.
Zawartość pliku
| output.txt | |
|---|---|
To jest to, co będziemy próbowali odtworzyć za pomocą naszego pierwszego workflow'u Nextflow.
Podsumowanie¶
Teraz wiesz, jak uruchomić proste polecenie w terminalu, które wypisuje tekst, i opcjonalnie, jak sprawić, aby zapisało wyjście do pliku.
Co dalej?¶
Dowiedz się, co trzeba zrobić, aby uruchomić workflow Nextflow, który osiąga ten sam wynik.
2. Uruchom workflow¶
Dostarczamy skrypt workflow'u o nazwie 1-hello.nf, który przyjmuje powitanie wejściowe przez argument wiersza poleceń o nazwie --input i produkuje plik tekstowy zawierający to powitanie.
Nie będziemy jeszcze patrzeć na kod; najpierw zobaczmy, jak wygląda jego uruchomienie.
2.1. Uruchom workflow i monitoruj wykonanie¶
W terminalu uruchom następujące polecenie:
Wyjście polecenia
Jeśli wyjście konsoli wygląda mniej więcej tak, to gratulacje, właśnie uruchomiłeś Swój pierwszy workflow Nextflow!
Najważniejsze wyjście tutaj to ostatnia linia, która jest podświetlona w powyższym wyjściu:
To mówi nam, że proces sayHello został pomyślnie wykonany raz (1 of 1 ✔).
Świetnie, ale możesz się zastanawiać: gdzie jest wyjście?
2.2. Znajdź plik wyjściowy w katalogu results¶
Ten workflow jest skonfigurowany do publikowania Swojego wyjścia w katalogu results.
Jeśli spojrzysz na Swój bieżący folder, zobaczysz nowo utworzony katalog results.
Wewnątrz znajduje się podkatalog 1-hello zawierający plik output.txt.
Otwórz plik; zawartość powinna odpowiadać ciągowi znaków, który podałeś w wierszu poleceń.
| results/1-hello/output.txt | |
|---|---|
Świetnie, nasz workflow zrobił to, co miał zrobić!
Jednak pamiętaj, że 'opublikowany' wynik jest kopią (lub w niektórych przypadkach dowiązaniem symbolicznym) rzeczywistego wyjścia wyprodukowanego przez Nextflow podczas wykonywania workflow'u.
Więc teraz zajrzymy pod maskę, aby zobaczyć, gdzie Nextflow faktycznie wykonał pracę.
Ostrzeżenie
Nie wszystkie workflow'y będą skonfigurowane do publikowania wyjść do katalogu results, i/lub nazwy katalogów i struktura mogą być inne. Trochę dalej w tej sekcji pokażemy, jak dowiedzieć się, gdzie to zachowanie jest określone.
2.3. Znajdź oryginalne wyjście i logi w katalogu work/¶
Gdy uruchamiasz workflow, Nextflow tworzy odrębny 'katalog zadania' dla każdego pojedynczego wywołania każdego procesu w workflow'ie (=każdego kroku w pipeline'ie). Dla każdego z nich przygotowuje niezbędne dane wejściowe i wykonuje odpowiednie instrukcje. Wyjścia i pliki dziennika są zapisywane w tym jednym folderze, który jest automatycznie nazywany przy użyciu skrótu hash, aby uczynić go unikalnym.
Wszystkie te katalogi zadań będą znajdować się w katalogu o nazwie work w bieżącym katalogu (skąd uruchamiasz polecenie).
To może brzmieć myląco, więc zobaczmy, jak to wygląda w praktyce.
Wracając do wyjścia konsoli dla workflow'u, który uruchomiliśmy wcześniej, mieliśmy tę linię:
Widzisz, jak linia zaczyna się od [a3/7be2fa]?
To jest skrócona forma ścieżki katalogu zadania dla tego jednego wywołania procesu i mówi, gdzie znaleźć wyjście wywołania procesu sayHello w ścieżce katalogu work/.
Możesz znaleźć pełną ścieżkę, wpisując następujące polecenie (zastępując a3/7be2fa tym, co widzisz w Twoim terminalu) i naciskając klawisz tab, aby automatycznie uzupełnić ścieżkę, lub dodając gwiazdkę:
To powinno dać pełną ścieżkę katalogu: work/a3/7be2fa7be2fad5e71e5f49998f795677fd68
Zobaczmy, co jest w środku.
Zawartość katalogu
Nie widzisz tego samego?
Dokładne nazwy podkatalogów będą inne w Twoim systemie.
Jeśli przeglądasz zawartość podkatalogu zadania w eksploratorze plików VSCode, zobaczysz wszystkie pliki od razu.
Jednak pliki dziennika są ustawione jako niewidoczne w terminalu, więc jeśli chcesz użyć ls lub tree do ich wyświetlenia, musisz ustawić odpowiednią opcję wyświetlania niewidocznych plików.
Powinieneś natychmiast rozpoznać plik output.txt, który jest w rzeczywistości oryginalnym wyjściem procesu sayHello, które zostało opublikowane do katalogu results.
Jeśli go otworzysz, znajdziesz ponownie powitanie Hello World!.
A co z wszystkimi tymi innymi plikami?
To są pliki pomocnicze i dziennika, które Nextflow zapisał jako część wykonania zadania:
.command.begin: Plik wartowniczy tworzony zaraz po uruchomieniu zadania..command.err: Komunikaty o błędach (stderr) emitowane przez wywołanie procesu.command.log: Kompletne wyjście dziennika emitowane przez wywołanie procesu.command.out: Zwykłe wyjście (stdout) przez wywołanie procesu.command.run: Pełny skrypt uruchomiony przez Nextflow do wykonania wywołania procesu.command.sh: Polecenie, które zostało faktycznie uruchomione przez wywołanie procesu.exitcode: Kod wyjścia wynikający z polecenia
Plik .command.sh jest szczególnie przydatny, ponieważ pokazuje główne polecenie, które wykonał Nextflow, nie włączając całej księgowości i konfiguracji zadania/środowiska.
#!/bin/bash -ue
echo 'Hello World!' > output.txt
To potwierdza, że workflow złożył to samo polecenie, które uruchomiliśmy bezpośrednio w wierszu poleceń wcześniej.
Gdy coś pójdzie nie tak, przydatne może być spojrzenie na skrypt command.sh.
Pozwala on sprawdzić dokładnie, jakie polecenie Nextflow złożył na podstawie instrukcji workflow'u, interpolacji zmiennych itd.
2.4. Uruchom ponownie workflow z różnymi powitaniami¶
Spróbuj uruchomić workflow kilka razy z różnymi wartościami argumentu --input, a następnie spójrz na katalogi zadań.
Zawartość katalogu
work
├── 0f
│ └── 52b7e07b0e274a80843fca48ed21b8
│ ├── .command.begin
│ ├── .command.err
│ ├── .command.log
│ ├── .command.out
│ ├── .command.run
│ ├── .command.sh
│ ├── .exitcode
│ └── output.txt
├── 67
│ ├── 134e6317f90726c6c17ad53234a32b
│ │ ├── .command.begin
│ │ ├── .command.err
│ │ ├── .command.log
│ │ ├── .command.out
│ │ ├── .command.run
│ │ ├── .command.sh
│ │ ├── .exitcode
│ │ └── output.txt
│ └── e029f2e75305874a9ab263d21ebc2c
│ ├── .command.begin
│ ├── .command.err
│ ├── .command.log
│ ├── .command.out
│ ├── .command.run
│ ├── .command.sh
│ ├── .exitcode
│ └── output.txt
├── 6c
│ └── d4fd787e0b01b3c82e85696c297500
│ ├── .command.begin
│ ├── .command.err
│ ├── .command.log
│ ├── .command.out
│ ├── .command.run
│ ├── .command.sh
│ ├── .exitcode
│ └── output.txt
└── e8
└── ab99fad46ade52905ec973ff39bb80
├── .command.begin
├── .command.err
├── .command.log
├── .command.out
├── .command.run
├── .command.sh
├── .exitcode
└── output.txt
Widzisz, że dla każdego uruchomienia został utworzony nowy podkatalog z kompletnym zestawem plików wyjściowych i dziennika.
W przeciwieństwie do tego, jeśli spojrzysz na katalog results, nadal jest tylko jeden zestaw wyników, a zawartość pliku wyjściowego odpowiada temu, co uruchomiłeś ostatnio.
To pokazuje, że opublikowane wyniki zostaną nadpisane przez kolejne wykonania, podczas gdy katalogi zadań w work/ są zachowane.
Podsumowanie¶
Wiesz, jak uruchomić prosty skrypt Nextflow, monitorować jego wykonanie i znajdować jego wyjścia.
Co dalej?¶
Naucz się czytać podstawowy skrypt Nextflow i identyfikować, jak jego komponenty odnoszą się do jego funkcjonalności.
3. Zbadaj skrypt startowy workflow'u Hello World¶
To, co tam zrobiliśmy, to w zasadzie traktowanie skryptu workflow'u jak czarnej skrzynki. Teraz, gdy widzieliśmy, co robi, otwórzmy skrzynkę i zajrzyjmy do środka.
Naszym celem tutaj nie jest zapamiętywanie składni kodu Nextflow, ale wyrobienie sobie podstawowej intuicji na temat tego, jakie są główne komponenty i jak są zorganizowane.
3.1. Zbadaj ogólną strukturę kodu¶
Znajdziesz skrypt 1-hello.nf w bieżącym katalogu, którym powinien być nextflow-run. Otwórz go w panelu edytora.
Pełny plik kodu
Skrypt workflow'u Nextflow zazwyczaj zawiera jedną lub więcej definicji procesu, sam workflow i kilka opcjonalnych bloków, takich jak params i output.
Każdy proces opisuje, jakie operacje powinien wykonać odpowiedni krok w pipeline'ie, podczas gdy workflow opisuje logikę przepływu danych, która łączy różne kroki.
Przyjrzyjmy się bliżej najpierw blokowi procesu, a potem spojrzymy na blok workflow.
3.2. Definicja process¶
Pierwszy blok kodu opisuje proces.
Definicja procesu zaczyna się od słowa kluczowego process, po którym następuje nazwa procesu, a na końcu ciało procesu ograniczone nawiasami klamrowymi.
Ciało procesu musi zawierać blok skryptu, który określa polecenie do uruchomienia, które może być czymkolwiek, co można by uruchomić w terminalu wiersza poleceń.
| 1-hello.nf | |
|---|---|
Tutaj mamy proces o nazwie sayHello, który przyjmuje zmienną input o nazwie greeting i zapisuje swoje output do pliku o nazwie output.txt.
To jest bardzo minimalna definicja procesu, która zawiera tylko definicję input, definicję output i script do wykonania.
Definicja input zawiera kwalifikator val, który mówi Nextflow, że oczekuje wartości jakiegoś rodzaju (może to być ciąg znaków, liczba, cokolwiek).
Definicja output zawiera kwalifikator path, który mówi Nextflow, że powinien to być traktowany jako ścieżka (obejmuje zarówno ścieżki katalogów, jak i pliki).
3.3. Definicja workflow¶
Drugi blok kodu opisuje sam workflow.
Definicja workflow zaczyna się od słowa kluczowego workflow, po którym następuje opcjonalna nazwa, a następnie ciało workflow ograniczone nawiasami klamrowymi.
Tutaj mamy workflow, który składa się z bloku main: i bloku publish:.
Blok main: jest głównym ciałem workflow'u, a blok publish: wymienia wyjścia, które powinny być opublikowane do katalogu results.
| 1-hello.nf | |
|---|---|
W tym przypadku blok main: zawiera wywołanie procesu sayHello i przekazuje mu dane wejściowe o nazwie params.input do użycia jako powitanie.
Jak omówimy bardziej szczegółowo za chwilę, params.input przechowuje wartość, którą podaliśmy parametrowi --input w naszym wierszu poleceń.
Blok publish: wymienia wyjście wywołania procesu sayHello(), które odnosi się jako sayHello.out i nadaje mu nazwę first_output (może to być cokolwiek, co chce autor workflow'u).
To jest bardzo minimalna definicja workflow. W rzeczywistym pipeline'ie workflow zazwyczaj zawiera wiele wywołań procesów połączonych przez kanały i mogą być ustawione wartości domyślne dla zmiennych wejściowych.
Zajmiemy się tym w Części 2 kursu. Na razie przyjrzyjmy się bliżej temu, jak nasz workflow obsługuje dane wejściowe i wyjściowe.
3.4. System parametrów wiersza poleceń params¶
params.input, który przekazujemy do wywołania procesu sayHello(), to zgrabny fragment kodu Nextflow i warto poświęcić mu dodatkową minutę.
Jak wspomniano powyżej, w ten sposób przekazujemy wartość parametru wiersza poleceń --input do wywołania procesu sayHello().
W rzeczywistości samo zadeklarowanie params.someParameterName wystarczy, aby dać workflow'owi parametr o nazwie --someParameterName z wiersza poleceń.
Tutaj sformalizowaliśmy tę deklarację parametru, konfigurując blok params, który określa typ danych wejściowych, jakich oczekuje workflow (Nextflow 25.10.2 i nowsze).
Obsługiwane typy obejmują String, Integer, Float, Boolean i Path.
Wskazówka
Parametry workflow'u zadeklarowane przy użyciu systemu params zawsze przyjmują dwa myślniki w wierszu poleceń (--).
To odróżnia je od parametrów poziomu Nextflow, które przyjmują tylko jeden myślnik (-).
3.5. Dyrektywa publish¶
Po drugiej stronie workflow, już rzuciliśmy okiem na blok publish:.
To jedna połowa systemu obsługi wyjść; druga połowa to blok output znajdujący się poniżej.
To określa, że wyjście first_output wymienione w bloku publish: powinno być skopiowane do podkatalogu o nazwie 1-hello w domyślnym katalogu wyjściowym results.
Linia mode 'copy' nadpisuje domyślne zachowanie systemu, które polega na tworzeniu dowiązania symbolicznego (lub symlinku) do oryginalnego pliku w katalogu work/ zamiast właściwej kopii.
Jest więcej opcji niż pokazano tutaj do kontrolowania zachowania publikowania; omówimy kilka później.
Zobaczysz również, że gdy workflow generuje wiele wyjść, każde z nich jest wymieniane w ten sposób w bloku output.
Starsza składnia publikowania wyjść przy użyciu publishDir
Aż do niedawna ustaloną metodą publikowania wyjść było robienie tego na poziomie każdego indywidualnego procesu przy użyciu dyrektywy publishDir.
Nadal znajdziesz ten wzorzec kodu wszędzie w starszych pipeline'ach Nextflow i modułach procesów, więc ważne jest, aby o nim wiedzieć.
Zamiast mieć blok publish: w workflow'ie i blok output na najwyższym poziomie, zobaczyłbyś linię publishDir w definicji procesu sayHello:
| Przykład składni | |
|---|---|
Jednak nie zalecamy używania tego w żadnej nowej pracy, ponieważ zostanie to ostatecznie zabronione w przyszłych wersjach języka Nextflow.
Podsumowanie¶
Teraz wiesz, jak prosty workflow Nextflow jest zbudowany i jak podstawowe komponenty odnoszą się do jego funkcjonalności.
Co dalej?¶
Naucz się wygodnie zarządzać wykonaniami workflow'ów.
4. Zarządzaj wykonaniami workflow'ów¶
Wiedza o tym, jak uruchamiać workflow'y i pobierać wyjścia, jest świetna, ale szybko odkryjesz, że jest kilka innych aspektów zarządzania workflow'ami, które ułatwią Ci życie.
Tutaj pokażemy, jak wykorzystać funkcję resume, gdy musisz ponownie uruchomić ten sam workflow, jak sprawdzić logi wykonania za pomocą nextflow log i jak usunąć starsze katalogi robocze za pomocą nextflow clean.
4.1. Ponownie uruchom workflow z -resume¶
Czasami będziesz chciał ponownie uruchomić pipeline, który już wcześniej uruchomiłeś, bez powtarzania pracy, która została już pomyślnie ukończona.
Nextflow ma opcję o nazwie -resume, która pozwala to zrobić.
Konkretnie, w tym trybie wszelkie zadania wykonane wcześniej z identycznym kodem, konfiguracją i wejściem zostaną pominięte.
Nextflow uruchomi tylko te, które dodałeś lub zmodyfikowałeś od ostatniego wykonania, lub do których przekazujesz nowe parametry.
Są dwie kluczowe zalety robienia tego:
- Jeśli jesteś w trakcie rozwijania pipeline'u, iteracja jest szybsza. Wystarczy przetestować tylko te procesy, nad którymi aktywnie pracujesz.
- Jeśli wykonujesz pipeline produkcyjnie i coś pójdzie nie tak, w wielu przypadkach wystarczy naprawić problem i wznowić wykonanie. Pipeline kontynuuje od punktu awarii, co oszczędza czas i zasoby obliczeniowe.
Aby go użyć, po prostu dodaj -resume do polecenia i uruchom je:
Wyjście polecenia
Wyjście konsoli powinno wyglądać znajomo, ale jest jedna rzecz, która jest trochę inna niż wcześniej.
Poszukaj fragmentu cached:, który został dodany w linii statusu procesu (linia 5), co oznacza, że Nextflow rozpoznał, że już wykonał tę pracę i po prostu ponownie użył wyniku z poprzedniego pomyślnego uruchomienia.
Możesz również zobaczyć, że hash podkatalogu roboczego jest taki sam jak w poprzednim uruchomieniu. Nextflow dosłownie wskazuje Ci poprzednie wykonanie i mówi "Już to zrobiłem tam".
Wskazówka
Gdy ponownie uruchamiasz pipeline z resume, Nextflow nie nadpisuje żadnych plików opublikowanych poza katalogiem roboczym przez jakiekolwiek wykonania, które zostały wcześniej pomyślnie uruchomione.
4.2. Sprawdź dziennik poprzednich wykonań¶
Za każdym razem, gdy uruchamiasz workflow Nextflow, linia jest zapisywana do pliku dziennika o nazwie history, w ukrytym katalogu o nazwie .nextflow w bieżącym katalogu roboczym.
Zawartość pliku
Ten plik zawiera znacznik czasu, nazwę uruchomienia, status, ID rewizji, ID sesji i pełne polecenie wiersza poleceń dla każdego uruchomienia Nextflow, które zostało uruchomione z bieżącego katalogu roboczego.
Wygodniejszym sposobem dostępu do tych informacji jest użycie polecenia nextflow log.
Wyjście polecenia
To wypisze zawartość pliku dziennika do terminala, wzbogaconą o linię nagłówka.
Zauważysz, że ID sesji zmienia się za każdym razem, gdy uruchamiasz nowe polecenie nextflow run, Z WYJĄTKIEM gdy używasz opcji -resume.
W takim przypadku ID sesji pozostaje takie samo.
Nextflow używa ID sesji do grupowania informacji o pamięci podręcznej uruchomienia w katalogu cache, również znajdującym się w .nextflow.
4.3. Usuń starsze katalogi robocze¶
Jeśli uruchamiasz dużo pipeline'ów, możesz zgromadzić bardzo wiele plików w wielu podkatalogach. Ponieważ podkatalogi są nazywane losowo, trudno jest powiedzieć po ich nazwach, które są starsze, a które nowsze.
Na szczęście Nextflow zawiera pomocne podpolecenie clean, które może automatycznie usuwać podkatalogi robocze dla poprzednich uruchomień, na których Ci już nie zależy.
4.3.1. Określ kryteria usuwania¶
Istnieje wiele opcji do określenia, co usunąć.
Tutaj pokazujemy przykład, który usuwa wszystkie podkatalogi z uruchomień przed danym uruchomieniem, określonym przy użyciu jego nazwy uruchomienia.
Znajdź najnowsze pomyślne uruchomienie, w którym nie użyłeś -resume; w naszym przypadku nazwa uruchomienia to backstabbing_swartz.
Nazwa uruchomienia to automatycznie generowany dwuczęściowy ciąg znaków pokazany w nawiasach kwadratowych w linii wyjścia konsoli Launching (...).
Możesz również użyć dziennika Nextflow, aby wyszukać uruchomienie na podstawie jego znacznika czasu i/lub wiersza poleceń.
4.3.2. Wykonaj próbne uruchomienie¶
Najpierw używamy flagi próbnego uruchomienia -n, aby sprawdzić, co zostanie usunięte przy danym poleceniu:
Wyjście polecenia
Twoje wyjście będzie miało inne nazwy katalogów zadań i może mieć inną liczbę linii, ale powinno wyglądać podobnie do przykładu.
Jeśli nie widzisz żadnych wypisanych linii, albo nie podałeś prawidłowej nazwy uruchomienia, albo nie ma poprzednich uruchomień do usunięcia. Upewnij się, że zmienisz backstabbing_swartz w przykładowym poleceniu na odpowiednią najnowszą nazwę uruchomienia w Twoim dzienniku.
4.3.3. Kontynuuj usuwanie¶
Jeśli wyjście wygląda zgodnie z oczekiwaniami i chcesz kontynuować usuwanie, uruchom ponownie polecenie z flagą -f zamiast -n:
Wyjście polecenia
Wyjście powinno być podobne do poprzedniego, ale teraz mówiące 'Removed' zamiast 'Would remove'.
Zauważ, że to nie usuwa dwuznakowych podkatalogów (jak eb/ powyżej), ale opróżnia ich zawartość.
Ostrzeżenie
Usuwanie podkatalogów roboczych z poprzednich uruchomień usuwa je z pamięci podręcznej Nextflow i kasuje wszelkie wyjścia, które były przechowywane w tych katalogach. To oznacza, że psuje zdolność Nextflow do wznowienia wykonania bez ponownego uruchamiania odpowiednich procesów.
Jesteś odpowiedzialny za zapisanie wszelkich wyjść, na których Ci zależy! To jest główny powód, dla którego wolimy używać trybu copy zamiast trybu symlink dla dyrektywy publish.
Podsumowanie¶
Wiesz, jak ponownie uruchomić pipeline bez powtarzania kroków, które były już uruchomione w identyczny sposób, sprawdzać dziennik wykonania i używać polecenia nextflow clean do czyszczenia starych katalogów roboczych.
Co dalej?¶
Zrób sobie małą przerwę! Właśnie przyswoiłeś podstawy składni Nextflow i podstawowe instrukcje użycia.
W następnej sekcji tego szkolenia przyjrzymy się czterem kolejnym, coraz bardziej realistycznym wersjom pipeline'u Hello World, które pokażą, jak Nextflow pozwala efektywnie przetwarzać wiele danych wejściowych, uruchamiać workflow'y złożone z wielu połączonych ze sobą kroków, wykorzystywać modułowe komponenty kodu i używać kontenerów dla większej odtwarzalności i przenośności.
Quiz¶
W linii wyjścia konsoli [a3/7be2fa] SAYHELLO | 1 of 1 ✔, co reprezentuje [a3/7be2fa]?
Jaki jest cel pliku .command.sh w katalogu zadania?
Co dzieje się z opublikowanymi wynikami, gdy ponownie uruchamiasz workflow bez -resume?
Gdzie Nextflow przechowuje historię wykonania, którą wyświetla polecenie nextflow log?
Jaki jest cel bloku params w pliku workflow'u?
Co robi mode 'copy' w bloku output workflow'u?
Jaka jest zalecana flaga do użycia z poleceniem nextflow clean przed faktycznym usunięciem plików?