Część 3: Hello Workflow¶
Tłumaczenie wspomagane przez AI - dowiedz się więcej i zasugeruj ulepszenia
Zobacz całą playlistę na kanale YouTube Nextflow.
Transkrypcja wideo jest dostępna tutaj.
Większość rzeczywistych workflow'ów składa się z więcej niż jednego kroku. W tym module szkoleniowym nauczysz się łączyć procesy w wieloetapowy workflow.
Poznasz sposób, w jaki Nextflow umożliwia osiągnięcie następujących celów:
- Przepływ danych z jednego procesu do następnego
- Zbieranie wyników z wielu wywołań procesu do pojedynczego wywołania
- Przekazywanie dodatkowych parametrów do procesu
- Obsługę wielu wyników wychodzących z procesu
Aby to zademonstrować, będziemy kontynuować rozbudowę niezależnego od dziedziny przykładu Hello World z części 1 i 2. Tym razem wprowadzimy następujące zmiany do naszego workflow'a, aby lepiej odzwierciedlić sposób, w jaki tworzy się rzeczywiste workflow'y:
- Dodamy drugi krok, który konwertuje powitanie na wielkie litery.
- Dodamy trzeci krok, który zbiera wszystkie przekształcone powitania i zapisuje je do jednego pliku.
- Dodamy parametr do nazwania końcowego pliku wyjściowego i przekażemy go jako drugie wejście do kroku zbierania.
- Sprawimy, że krok zbierania będzie również raportować prostą statystykę dotyczącą tego, co zostało przetworzone.
Jak zacząć od tej sekcji
Ta sekcja kursu zakłada, że ukończyłeś części 1-2 kursu Hello Nextflow, ale jeśli czujesz się komfortowo z podstawami omówionymi w tych sekcjach, możesz zacząć od tego miejsca bez żadnych specjalnych przygotowań.
0. Rozgrzewka: Uruchom hello-workflow.nf¶
Jako punkt wyjścia użyjemy skryptu workflow'a hello-workflow.nf.
Jest on równoważny skryptowi powstałemu w wyniku pracy nad częścią 2 tego kursu, z tym że usunęliśmy instrukcje view() i zmieniliśmy miejsce docelowe wyjścia:
Ten diagram podsumowuje obecne działanie workflow'a. Powinien wyglądać znajomo, z tym że teraz jawnie pokazujemy, że wyjścia procesu są pakowane w kanał, tak jak wejścia. Za chwilę wykorzystamy ten kanał wyjściowy.
Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian:
Wyjście polecenia
Jak poprzednio, pliki wyjściowe znajdziesz w lokalizacji określonej w bloku output.
W tym rozdziale jest to katalog results/hello_workflow/.
Zawartość katalogu
Jeśli to zadziałało, jesteś gotowy, aby nauczyć się składać wieloetapowy workflow.
1. Dodaj drugi krok do workflow'a¶
Dodamy krok konwertujący każde powitanie na wielkie litery.
W tym celu musimy wykonać trzy rzeczy:
- Zdefiniować polecenie, którego użyjemy do konwersji na wielkie litery.
- Napisać nowy proces opakowujący polecenie konwersji.
- Wywołać nowy proces w bloku
workflowi skonfigurować go tak, aby przyjmował wyjście procesusayHello()jako wejście.
1.1. Zdefiniuj polecenie konwersji i przetestuj je w terminalu¶
Do konwersji powitań na wielkie litery użyjemy klasycznego narzędzia UNIX o nazwie tr (od 'text replacement'), z następującą składnią:
To bardzo naiwna jednolinijkowa zamiana tekstu, która nie uwzględnia liter akcentowanych, więc na przykład 'Holà' stanie się 'HOLà', ale wystarczająco dobrze posłuży do zademonstrowania koncepcji Nextflow, a to się liczy.
Aby to przetestować, możemy uruchomić polecenie echo 'Hello World' i przekierować jego wyjście do polecenia tr:
Wyjściem jest plik tekstowy o nazwie UPPER-output.txt, który zawiera wersję ciągu Hello World zapisaną wielkimi literami.
To w zasadzie to, co będziemy próbować osiągnąć z naszym workflow'em.
1.2. Napisz krok konwersji jako proces Nextflow¶
Możemy wzorować nasz nowy proces na pierwszym, ponieważ chcemy użyć wszystkich tych samych komponentów.
Dodaj następującą definicję procesu do skryptu workflow'a, zaraz pod pierwszym procesem:
| hello-workflow.nf | |
|---|---|
W tym procesie komponujemy drugą nazwę pliku wyjściowego na podstawie nazwy pliku wejściowego, podobnie jak zrobiliśmy to pierwotnie dla wyjścia pierwszego procesu.
1.3. Dodaj wywołanie nowego procesu w bloku workflow¶
Teraz musimy powiedzieć Nextflow'owi, aby faktycznie wywołał proces, który właśnie zdefiniowaliśmy.
W bloku workflow wprowadź następującą zmianę kodu:
| hello-workflow.nf | |
|---|---|
To jeszcze nie jest funkcjonalne, ponieważ nie określiliśmy, co powinno być wejściem do procesu convertToUpper().
1.4. Przekaż wyjście pierwszego procesu do drugiego procesu¶
Teraz musimy sprawić, aby wyjście procesu sayHello() przepłynęło do procesu convertToUpper().
Wygodnie, Nextflow automatycznie pakuje wyjście procesu w kanał, jak pokazano na diagramie w sekcji rozgrzewki.
Możemy odwołać się do kanału wyjściowego procesu jako <proces>.out.
Zatem wyjście procesu sayHello to kanał o nazwie sayHello.out, który możemy podłączyć bezpośrednio do wywołania convertToUpper().
W bloku workflow wprowadź następującą zmianę kodu:
W prostym przypadku takim jak ten (jedno wyjście do jednego wejścia), to wszystko, co musimy zrobić, aby połączyć dwa procesy!
1.5. Skonfiguruj publikowanie wyjść workflow'a¶
Na koniec zaktualizujmy wyjścia workflow'a, aby publikować również wyniki z drugiego procesu.
1.5.1. Zaktualizuj sekcję publish: bloku workflow¶
W bloku workflow wprowadź następującą zmianę kodu:
Logika jest taka sama jak poprzednio.
1.5.2. Zaktualizuj blok output¶
W bloku output wprowadź następującą zmianę kodu:
Ponownie, logika jest taka sama jak wcześniej.
To pokazuje, że możesz kontrolować ustawienia wyjścia na bardzo szczegółowym poziomie, dla każdego indywidualnego wyjścia. Możesz spróbować zmienić ścieżki lub tryb publikowania dla jednego z procesów, aby zobaczyć, co się stanie.
Oczywiście oznacza to, że powtarzamy tutaj pewne informacje, co może stać się niewygodne, gdybyśmy chcieli zaktualizować lokalizację dla wszystkich wyjść w ten sam sposób. Później w kursie nauczysz się, jak konfigurować te ustawienia dla wielu wyjść w uporządkowany sposób.
1.6. Uruchom workflow z flagą -resume¶
Przetestujmy to używając flagi -resume, ponieważ już pomyślnie uruchomiliśmy pierwszy krok workflow'a.
Wyjście polecenia
W wyjściu konsoli jest teraz dodatkowa linia odpowiadająca nowemu procesowi, który właśnie dodaliśmy.
Wyjścia znajdziesz w katalogu results/hello_workflow, jak ustawiono w bloku output.
Zawartość katalogu
To wygodne! Ale warto też zajrzeć do katalogu roboczego jednego z wywołań drugiego procesu.
Zawartość katalogu
Zauważ, że są tam dwa pliki *-output: wyjście pierwszego procesu oraz wyjście drugiego.
Wyjście pierwszego procesu jest tam, ponieważ Nextflow przygotował je tam, aby mieć wszystko potrzebne do wykonania w tym samym podkatalogu.
Jest to jednak w rzeczywistości dowiązanie symboliczne wskazujące na oryginalny plik w podkatalogu pierwszego wywołania procesu. Domyślnie, podczas pracy na pojedynczej maszynie, jak robimy to tutaj, Nextflow używa dowiązań symbolicznych zamiast kopii do przygotowywania plików wejściowych i pośrednich.
Teraz, zanim przejdziesz dalej, pomyśl o tym, jak wszystko, co zrobiliśmy, to połączenie wyjścia sayHello z wejściem convertToUpper, a dwa procesy mogły być uruchomione szeregowo.
Nextflow wykonał za nas ciężką pracę obsługi poszczególnych plików wejściowych i wyjściowych oraz przekazywania ich między dwoma poleceniami.
To jeden z powodów, dla których kanały Nextflow są tak potężne: zajmują się pracą związaną z łączeniem kroków workflow'a.
Podsumowanie¶
Wiesz, jak łączyć procesy w łańcuch, przekazując wyjście jednego kroku jako wejście do następnego.
Co dalej?¶
Naucz się zbierać wyjścia z przetwarzanych wsadowo wywołań procesu i przekazywać je do pojedynczego procesu.
2. Dodaj trzeci krok do zbierania wszystkich powitań¶
Kiedy używamy procesu do zastosowania transformacji do każdego z elementów w kanale, jak robimy to tutaj z wieloma powitaniami, czasami chcemy zebrać elementy z kanału wyjściowego tego procesu i przekazać je do innego procesu, który wykonuje jakiś rodzaj analizy lub sumowania.
Aby to zademonstrować, dodamy nowy krok do naszego pipeline'u, który zbiera wszystkie powitania zapisane wielkimi literami wyprodukowane przez proces convertToUpper i zapisuje je do jednego pliku.
Nie chcąc zdradzać niespodzianki, ale będzie to wymagało bardzo użytecznego operatora.
2.1. Zdefiniuj polecenie zbierania i przetestuj je w terminalu¶
Krok zbierania, który chcemy dodać do naszego workflow'a, użyje polecenia cat do konkatenacji wielu powitań zapisanych wielkimi literami w jeden plik.
Uruchommy polecenie samo w terminalu, aby sprawdzić, czy działa zgodnie z oczekiwaniami, tak jak robiliśmy wcześniej.
Uruchom następujące polecenie w swoim terminalu:
echo 'Hello' | tr '[a-z]' '[A-Z]' > UPPER-Hello-output.txt
echo 'Bonjour' | tr '[a-z]' '[A-Z]' > UPPER-Bonjour-output.txt
echo 'Holà' | tr '[a-z]' '[A-Z]' > UPPER-Holà-output.txt
cat UPPER-Hello-output.txt UPPER-Bonjour-output.txt UPPER-Holà-output.txt > COLLECTED-output.txt
Wyjściem jest plik tekstowy o nazwie COLLECTED-output.txt, który zawiera wersje oryginalnych powitań zapisane wielkimi literami.
To jest wynik, który chcemy osiągnąć z naszym workflow'em.
2.2. Utwórz nowy proces do wykonania kroku zbierania¶
Stwórzmy nowy proces i nazwijmy go collectGreetings().
Możemy zacząć go pisać na podstawie tego, co widzieliśmy wcześniej.
2.2.1. Napisz 'oczywiste' części procesu¶
Dodaj następującą definicję procesu do skryptu workflow'a:
| hello-workflow.nf | |
|---|---|
To jest to, co możemy napisać z pewnością na podstawie tego, czego nauczyłeś się do tej pory. Ale to nie jest funkcjonalne! Pomija definicję wejścia (wejść) i pierwszą połowę polecenia skryptu, ponieważ musimy wymyślić, jak to napisać.
2.2.2. Zdefiniuj wejścia do collectGreetings()¶
Musimy zebrać powitania ze wszystkich wywołań procesu convertToUpper().
Co wiemy, że możemy otrzymać z poprzedniego kroku w workflow'ie?
Kanał wyjściowy z convertToUpper() będzie zawierał ścieżki do poszczególnych plików zawierających powitania zapisane wielkimi literami.
To stanowi jedno miejsce wejściowe; nazwijmy je input_files dla uproszczenia.
W bloku procesu wprowadź następującą zmianę kodu:
Zauważ, że używamy prefiksu path, mimo że spodziewamy się, że będzie to zawierać wiele plików.
2.2.3. Skomponuj polecenie konkatenacji¶
To jest miejsce, gdzie sprawy mogą się nieco skomplikować, ponieważ musimy być w stanie obsłużyć dowolną liczbę plików wejściowych. Konkretnie, nie możemy napisać polecenia z góry, więc musimy powiedzieć Nextflow'owi, jak je skomponować w czasie wykonania na podstawie tego, jakie wejścia wpływają do procesu.
Innymi słowy, jeśli mamy kanał wejściowy zawierający element [file1.txt, file2.txt, file3.txt], musimy, aby Nextflow przekształcił to w cat file1.txt file2.txt file3.txt.
Na szczęście Nextflow chętnie to dla nas zrobi, jeśli po prostu napiszemy cat ${input_files} w poleceniu skryptu.
W bloku procesu wprowadź następującą zmianę kodu:
W teorii powinno to obsłużyć dowolną liczbę plików wejściowych.
Wskazówka
Niektóre narzędzia wiersza poleceń wymagają podania argumentu (takiego jak -input) dla każdego pliku wejściowego.
W takim przypadku musielibyśmy wykonać trochę dodatkowej pracy, aby skomponować polecenie.
Przykład tego możesz zobaczyć w kursie szkoleniowym Nextflow for Genomics.
2.3. Dodaj krok zbierania do workflow'a¶
Teraz powinniśmy po prostu wywołać proces zbierania na wyjściu kroku konwersji na wielkie litery.
To również jest kanał, o nazwie convertToUpper.out.
2.3.1. Połącz wywołania procesów¶
W bloku workflow wprowadź następującą zmianę kodu:
To łączy wyjście convertToUpper() z wejściem collectGreetings().
2.3.2. Uruchom workflow z flagą -resume¶
Spróbujmy tego.
Wyjście polecenia
Uruchamia się pomyślnie, włączając trzeci krok.
Jednak spójrz na liczbę wywołań dla collectGreetings() w ostatniej linii.
Spodziewaliśmy się tylko jednego, ale są trzy.
Teraz spójrz na zawartość końcowego pliku wyjściowego.
O nie. Krok zbierania został uruchomiony indywidualnie dla każdego powitania, co NIE jest tym, czego chcieliśmy.
Musimy coś zrobić, aby wyraźnie powiedzieć Nextflow'owi, że chcemy, aby ten trzeci krok działał na wszystkich elementach w kanale wyjściowym z convertToUpper().
2.4. Użyj operatora do zebrania powitań w jedno wejście¶
Tak, ponownie odpowiedzią na nasz problem jest operator.
Konkretnie, użyjemy trafnie nazwanego operatora collect().
2.4.1. Dodaj operator collect()¶
Tym razem będzie to wyglądać nieco inaczej, ponieważ nie dodajemy operatora w kontekście fabryki kanałów; dodajemy go do kanału wyjściowego.
Bierzemy convertToUpper.out i dołączamy operator collect(), co daje nam convertToUpper.out.collect().
Możemy to podłączyć bezpośrednio do wywołania procesu collectGreetings().
W bloku workflow wprowadź następującą zmianę kodu:
2.4.2. Dodaj kilka instrukcji view()¶
Dodajmy również kilka instrukcji view(), aby zwizualizować stany kanału przed i po.
| hello-workflow.nf | |
|---|---|
Instrukcje view() mogą być umieszczone gdziekolwiek chcesz; umieściliśmy je zaraz po wywołaniu dla czytelności.
2.4.3. Uruchom workflow ponownie z flagą -resume¶
Spróbujmy tego:
Wyjście polecenia
N E X T F L O W ~ version 25.10.2
Launching `hello-workflow.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726
[d6/cdf466] sayHello (1) | 3 of 3, cached: 3 ✔
[99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔
[1e/83586c] collectGreetings | 1 of 1 ✔
Before collect: /workspaces/training/hello-nextflow/work/b3/d52708edba8b864024589285cb3445/UPPER-Bonjour-output.txt
Before collect: /workspaces/training/hello-nextflow/work/99/79394f549e3040dfc2440f69ede1fc/UPPER-Hello-output.txt
Before collect: /workspaces/training/hello-nextflow/work/aa/56bfe7cf00239dc5badc1d04b60ac4/UPPER-Holà-output.txt
After collect: [/workspaces/training/hello-nextflow/work/b3/d52708edba8b864024589285cb3445/UPPER-Bonjour-output.txt, /workspaces/training/hello-nextflow/work/99/79394f549e3040dfc2440f69ede1fc/UPPER-Hello-output.txt, /workspaces/training/hello-nextflow/work/aa/56bfe7cf00239dc5badc1d04b60ac4/UPPER-Holà-output.txt]
Uruchamia się pomyślnie, chociaż wyjście logów może wyglądać nieco bardziej chaotycznie (uporządkowaliśmy je dla czytelności).
Tym razem trzeci krok został wywołany tylko raz!
Patrząc na wyjście instrukcji view(), widzimy następujące:
- Trzy instrukcje
Przed collect:, po jednej dla każdego powitania: w tym momencie ścieżki plików są indywidualnymi elementami w kanale. - Pojedyncza instrukcja
Po collect:: trzy ścieżki plików są teraz spakowane w jeden element.
Możemy to podsumować następującym diagramem:
Na koniec możesz spojrzeć na zawartość pliku wyjściowego, aby upewnić się, że wszystko zadziałało poprawnie.
Tym razem mamy wszystkie trzy powitania w końcowym pliku wyjściowym. Sukces!
Uwaga
Jeśli uruchomisz to kilka razy bez -resume, zobaczysz, że kolejność powitań zmienia się z jednego uruchomienia na drugie.
To pokazuje, że kolejność, w jakiej elementy przepływają przez wywołania procesów, nie jest gwarantowana jako spójna.
2.4.4. Usuń instrukcje view() dla czytelności¶
Zanim przejdziesz do następnej sekcji, zalecamy usunięcie instrukcji view(), aby uniknąć zaśmiecania wyjścia konsoli.
| hello-workflow.nf | |
|---|---|
To jest w zasadzie operacja odwrotna do punktu 2.4.2.
Podsumowanie¶
Wiesz, jak zbierać wyjścia z partii wywołań procesu i przekazywać je do wspólnego kroku analizy lub sumowania.
Podsumowując, oto co zbudowałeś do tej pory:
Co dalej?¶
Naucz się przekazywać więcej niż jedno wejście do procesu.
3. Przekaż dodatkowe parametry do procesu¶
Chcemy móc nazwać końcowy plik wyjściowy czymś konkretnym, aby przetwarzać kolejne partie powitań bez nadpisywania końcowych wyników.
W tym celu wprowadzimy następujące udoskonalenia do workflow'a:
- Zmodyfikujemy proces zbierający, aby akceptował zdefiniowaną przez użytkownika nazwę pliku wyjściowego (
batch_name) - Dodamy parametr wiersza poleceń do workflow'a (
--batch) i przekażemy go do procesu zbierającego
3.1. Zmodyfikuj proces zbierający¶
Będziemy musieli zadeklarować dodatkowe wejście i zintegrować je z nazwą pliku wyjściowego.
3.1.1. Zadeklaruj dodatkowe wejście¶
Dobra wiadomość: możemy zadeklarować tyle zmiennych wejściowych, ile chcemy w definicji procesu.
Nazwijmy tę batch_name.
W bloku procesu wprowadź następującą zmianę kodu:
Możesz skonfigurować swoje procesy tak, aby oczekiwały tylu wejść, ile chcesz. W tej chwili wszystkie są ustawione jako wymagane wejścia; musisz podać wartość, aby workflow działał.
Nauczysz się, jak zarządzać wymaganymi i opcjonalnymi wejściami później w Twojej drodze z Nextflow.
3.1.2. Użyj zmiennej batch_name w nazwie pliku wyjściowego¶
Możemy wstawić zmienną do nazwy pliku wyjściowego w taki sam sposób, w jaki komponowaliśmy dynamiczne nazwy plików wcześniej.
W bloku procesu wprowadź następującą zmianę kodu:
To konfiguruje proces do używania wartości batch_name do generowania konkretnej nazwy pliku dla końcowego wyjścia workflow'a.
3.2. Dodaj parametr wiersza poleceń batch¶
Teraz potrzebujemy sposobu na dostarczenie wartości dla batch_name i przekazanie jej do wywołania procesu.
3.2.1. Użyj params do skonfigurowania parametru¶
Już wiesz, jak używać systemu params do deklarowania parametrów CLI.
Użyjmy tego do zadeklarowania parametru batch (z wartością domyślną, ponieważ jesteśmy leniwi).
W sekcji parametrów pipeline'u wprowadź następujące zmiany kodu:
Tak jak zademonstrowano dla --input, możesz nadpisać tę wartość domyślną, określając wartość za pomocą --batch w wierszu poleceń.
3.2.2. Przekaż parametr batch do procesu¶
Aby przekazać wartość parametru do procesu, musimy dodać ją w wywołaniu procesu.
W bloku workflow wprowadź następującą zmianę kodu:
Widzisz, że aby przekazać wiele wejść do procesu, po prostu wymieniasz je w nawiasach wywołania, oddzielone przecinkami.
Ostrzeżenie
MUSISZ przekazać wejścia do procesu w DOKŁADNIE TAKIEJ SAMEJ KOLEJNOŚCI, w jakiej są wymienione w bloku definicji wejścia procesu.
3.3. Uruchom workflow¶
Spróbujmy uruchomić to z nazwą partii w wierszu poleceń.
Wyjście polecenia
Uruchamia się pomyślnie i produkuje pożądane wyjście:
Teraz, dopóki odpowiednio określimy parametr, kolejne uruchomienia na innych partiach wejść nie nadpiszą poprzednich wyników.
Podsumowanie¶
Wiesz, jak przekazać więcej niż jedno wejście do procesu.
Co dalej?¶
Naucz się emitować wiele wyjść i wygodnie je obsługiwać.
4. Dodaj wyjście do kroku zbierającego¶
Do tej pory używaliśmy procesów, które produkowały tylko jedno wyjście każdy.
Mogliśmy bardzo wygodnie uzyskać dostęp do ich odpowiednich wyjść używając składni <proces>.out, której używaliśmy zarówno w kontekście przekazywania wyjścia do następnego procesu (np. convertToUpper(sayHello.out)), jak i w kontekście sekcji publish: (np. first_output = sayHello.out).
Co się dzieje, gdy proces produkuje więcej niż jedno wyjście? Jak obsługujemy wiele wyjść? Czy możemy wybrać i użyć konkretnego wyjścia?
Wszystkie doskonałe pytania, a krótka odpowiedź brzmi: tak, możemy!
Wiele wyjść zostanie spakowanych w oddzielne kanały. Możemy albo zdecydować się nadać tym kanałom wyjściowym nazwy, co ułatwia późniejsze odwoływanie się do nich indywidualnie, albo możemy odwoływać się do nich za pomocą indeksu.
W celach demonstracyjnych powiedzmy, że chcemy policzyć liczbę powitań zbieranych dla danej partii wejść i zgłosić to w pliku.
4.1. Zmodyfikuj proces, aby liczył i wypisywał liczbę powitań¶
Będzie to wymagało dwóch kluczowych zmian w definicji procesu: potrzebujemy sposobu na policzenie powitań i zapisanie pliku raportu, a następnie musimy dodać ten plik raportu do bloku output procesu.
4.1.1. Policz liczbę zebranych powitań¶
Wygodnie, Nextflow pozwala nam dodać dowolny kod w bloku script: definicji procesu, co jest naprawdę przydatne do robienia takich rzeczy.
Oznacza to, że możemy użyć wbudowanej funkcji Nextflow size(), aby uzyskać liczbę plików w tablicy input_files, i zapisać wynik do pliku za pomocą polecenia echo.
W bloku procesu collectGreetings wprowadź następujące zmiany kodu:
Zmienna count_greetings zostanie obliczona w czasie wykonania.
4.1.2. Wyemituj plik raportu i nazwij wyjścia¶
W zasadzie wszystko, co musimy zrobić, to dodać plik raportu do bloku output:.
Jednak przy okazji dodamy również tagi emit: do naszych deklaracji wyjść. Umożliwią nam one wybieranie wyjść po nazwie zamiast konieczności używania indeksów pozycyjnych.
W bloku procesu wprowadź następującą zmianę kodu:
Tagi emit: są opcjonalne i mogliśmy dodać tag tylko do jednego z wyjść.
Ale jak mówi powiedzenie, czemu nie oba?
Wskazówka
Jeśli nie nazwiesz wyjść procesu używając emit:, nadal możesz uzyskać do nich dostęp indywidualnie, używając ich odpowiedniego (zerowego) indeksu.
Na przykład użyłbyś <proces>.out[0], aby uzyskać pierwsze wyjście, <proces>.out[1], aby uzyskać drugie wyjście, i tak dalej.
Wolimy nazywać wyjścia, ponieważ w przeciwnym razie zbyt łatwo jest przez pomyłkę pobrać niewłaściwy indeks, szczególnie gdy proces produkuje wiele wyjść.
4.2. Zaktualizuj wyjścia workflow'a¶
Teraz, gdy mamy dwa wyjścia wychodzące z procesu collectGreetings, wyjście collectGreetings.out zawiera dwa kanały:
collectGreetings.out.outfilezawiera końcowy plik wyjściowycollectGreetings.out.reportzawiera plik raportu
Musimy odpowiednio zaktualizować wyjścia workflow'a.
4.2.1. Zaktualizuj sekcję publish:¶
W bloku workflow wprowadź następującą zmianę kodu:
Jak widzisz, odwoływanie się do konkretnych wyjść procesu jest teraz trywialne.
Kiedy dodamy jeszcze jeden krok do naszego pipeline'u w części 5 (Kontenery), będziemy mogli łatwo odwołać się do collectGreetings.out.outfile i przekazać go do nowego procesu (spoiler: nowy proces nazywa się cowpy).
Ale na razie dokończmy aktualizację wyjść na poziomie workflow'a.
4.2.2. Zaktualizuj blok output¶
W bloku output wprowadź następującą zmianę kodu:
Nie musimy aktualizować definicji wyjścia collected, ponieważ ta nazwa się nie zmieniła.
Musimy tylko dodać nowe wyjście.
4.3. Uruchom workflow¶
Spróbujmy uruchomić to z obecną partią powitań.
Wyjście polecenia
Jeśli zajrzysz do katalogu results/hello_workflow/, znajdziesz nowy plik raportu, trio-report.txt.
Otwórz go, aby sprawdzić, czy workflow poprawnie zgłosił liczbę przetworzonych powitań.
Możesz dodać więcej powitań do pliku CSV i przetestować, co się stanie.
Podsumowanie¶
Wiesz, jak sprawić, aby proces emitował wiele nazwanych wyjść i jak odpowiednio je obsługiwać na poziomie workflow'a.
Bardziej ogólnie, rozumiesz kluczowe zasady związane z łączeniem procesów w typowe sposoby.
Co dalej?¶
Zrób sobie ekstra długą przerwę, zasłużyłeś na to.
Kiedy będziesz gotowy, przejdź do Części 4: Hello Modules, aby nauczyć się, jak modularyzować swój kod dla lepszej łatwości utrzymania i efektywności kodu.
Quiz¶
Jak uzyskać dostęp do wyjścia procesu w bloku workflow?
Co określa kolejność wykonywania procesów w Nextflow?
Kiedy powinieneś użyć operatora collect()?
Jak uzyskać dostęp do nazwanego wyjścia z procesu?
Jaka jest poprawna składnia do nazwania wyjścia w procesie?
Podczas przekazywania wielu wejść do procesu, co musi być prawdą?