Teil 1: Hello World¶
KI-gestützte Übersetzung - mehr erfahren & Verbesserungen vorschlagen
Sieh dir die gesamte Playlist auf dem Nextflow YouTube-Kanal an.
Das Video-Transkript findest du hier.
Im ersten Teil des Hello Nextflow Trainings steigen wir mit einem sehr einfachen, domänenunabhängigen Hello World Beispiel ein, das wir schrittweise erweitern, um die Verwendung grundlegender Nextflow-Logik und -Komponenten zu demonstrieren.
Was ist ein Hello World Beispiel?
Ein "Hello World!" ist ein minimalistisches Beispiel, das die grundlegende Syntax und Struktur einer Programmiersprache oder eines Software-Frameworks demonstrieren soll. Das Beispiel besteht typischerweise darin, die Phrase "Hello, World!" auf einem Ausgabegerät wie der Konsole oder dem Terminal auszugeben oder in eine Datei zu schreiben.
0. Aufwärmen: Ein Hello World Beispiel direkt ausführen¶
Lass uns das mit einem einfachen Befehl demonstrieren, den wir direkt im Terminal ausführen, um zu zeigen, was er macht, bevor wir ihn in Nextflow einbinden.
Tipp
Denk daran, dass du dich jetzt im Verzeichnis hello-nextflow/ befinden solltest, wie auf der Seite Erste Schritte beschrieben.
0.1. Das Terminal zum Sprechen bringen¶
Führe den folgenden Befehl in deinem Terminal aus.
Dies gibt den Text 'Hello World' direkt im Terminal aus.
0.2. Die Ausgabe in eine Datei schreiben¶
Pipelines lesen hauptsächlich Daten aus Dateien und schreiben Ergebnisse in andere Dateien. Lass uns den Befehl daher so ändern, dass die Textausgabe in eine Datei geschrieben wird, um das Beispiel etwas relevanter zu machen.
Dies gibt nichts im Terminal aus.
0.3. Die Ausgabe finden¶
Der Text 'Hello World' sollte sich jetzt in der von uns angegebenen Ausgabedatei namens output.txt befinden.
Du kannst sie im Datei-Explorer öffnen oder über die Kommandozeile mit dem cat-Befehl, zum Beispiel.
Dateiinhalt
| output.txt | |
|---|---|
Das werden wir jetzt versuchen, mit unserem allerersten Nextflow-Workflow nachzubilden.
Fazit¶
Du weißt jetzt, wie du einen einfachen Befehl im Terminal ausführst, der Text ausgibt, und optional, wie du die Ausgabe in eine Datei schreiben lässt.
Wie geht es weiter?¶
Finde heraus, wie das als Nextflow-Workflow aussehen würde.
1. Das Skript untersuchen und ausführen¶
Wir stellen dir ein voll funktionsfähiges, wenn auch minimalistisches Workflow-Skript namens hello-world.nf zur Verfügung, das dasselbe tut wie zuvor (schreibt 'Hello World!'), aber mit Nextflow.
Zum Einstieg öffnen wir das Workflow-Skript, damit du ein Gefühl für seine Struktur bekommst. Dann führen wir es aus und suchen nach den Ausgaben.
1.1. Den Code untersuchen¶
Du findest das Skript hello-world.nf in deinem aktuellen Verzeichnis, das hello-nextflow sein sollte. Öffne es im Editor-Fenster.
Vollständige Code-Datei
| hello-world.nf | |
|---|---|
Ein Nextflow-Workflow-Skript enthält typischerweise eine oder mehrere process-Definitionen und den workflow selbst, plus einige optionale Blöcke (hier nicht vorhanden), die wir später einführen werden.
Jeder process beschreibt, welche Operation(en) der entsprechende Schritt in der Pipeline ausführen soll, während der workflow die Datenfluss-Logik beschreibt, die die verschiedenen Schritte verbindet.
Wir schauen uns zuerst den process-Block genauer an, dann den workflow-Block.
1.1.1. Die process-Definition¶
Der erste Codeblock beschreibt einen process.
Die Prozess-Definition beginnt mit dem Schlüsselwort process, gefolgt vom Prozessnamen und schließlich dem Prozess-Body, der durch geschweifte Klammern begrenzt wird.
Der Prozess-Body muss einen Script-Block enthalten, der den auszuführenden Befehl angibt, was alles sein kann, was du in einem Kommandozeilen-Terminal ausführen könntest.
| hello-world.nf | |
|---|---|
Hier haben wir einen process namens sayHello, der seine output in eine Datei namens output.txt schreibt.
Dies ist eine sehr minimale Prozess-Definition, die nur eine output-Definition und das auszuführende script enthält.
Die output-Definition enthält den Qualifier path, der Nextflow mitteilt, dass dies als Pfad behandelt werden soll (umfasst sowohl Verzeichnispfade als auch Dateien).
Ein anderer häufiger Qualifier ist val.
Wichtig ist, dass die Output-Definition nicht bestimmt, welche Ausgabe erstellt wird. Sie deklariert lediglich, was die erwartete Ausgabe ist, damit Nextflow danach suchen kann, sobald die Ausführung abgeschlossen ist. Dies ist notwendig, um zu überprüfen, dass der Befehl erfolgreich ausgeführt wurde, und um die Ausgabe bei Bedarf an nachfolgende Prozesse weiterzugeben. Ausgaben, die nicht mit dem übereinstimmen, was im Output-Block deklariert ist, werden nicht an nachfolgende Prozesse weitergegeben.
Warnung
Dieses Beispiel ist anfällig, weil wir den Ausgabedateinamen an zwei separaten Stellen fest codiert haben (im Script- und im Output-Block). Wenn wir das eine ändern, aber nicht das andere, wird das Skript fehlschlagen. Später lernst du Möglichkeiten kennen, Variablen zu verwenden, um dieses Problem zu vermeiden.
In einer realen Pipeline enthält ein Prozess normalerweise zusätzliche Blöcke wie Direktiven und Eingaben, die wir gleich einführen werden.
1.1.2. Die workflow-Definition¶
Der zweite Codeblock beschreibt den workflow selbst.
Die Workflow-Definition beginnt mit dem Schlüsselwort workflow, gefolgt von einem optionalen Namen, dann dem Workflow-Body, der durch geschweifte Klammern begrenzt wird.
Hier haben wir einen workflow, der aus einem main:-Block besteht (der sagt 'dies ist der Hauptteil des Workflows'), der einen Aufruf des sayHello-Prozesses enthält.
Dies ist eine sehr minimale workflow-Definition. In einer realen Pipeline enthält der Workflow typischerweise mehrere Aufrufe von processes, die durch channels verbunden sind, und die Prozesse erwarten eine oder mehrere variable input(s).
Du lernst später in diesem Trainingsmodul, wie du variable Eingaben hinzufügst; und du lernst in Teil 3 dieses Kurses, wie du weitere Prozesse hinzufügst und sie durch Kanäle verbindest.
Tipp
Technisch gesehen ist die Zeile main: für einfache Workflows wie diesen nicht erforderlich, daher kannst du auf Workflows stoßen, die sie nicht haben.
Aber wir werden sie brauchen, um Workflow-Level-Ausgaben nutzen zu können, also können wir sie gleich von Anfang an einbinden.
1.2. Den Workflow ausführen¶
Code anzuschauen ist nicht annähernd so unterhaltsam wie ihn auszuführen, also lass uns das in der Praxis ausprobieren.
1.2.1. Den Workflow starten und die Ausführung überwachen¶
Führe im Terminal den folgenden Befehl aus:
Befehlsausgabe
Wenn deine Konsolenausgabe ungefähr so aussieht, dann herzlichen Glückwunsch, du hast gerade deinen ersten Nextflow-Workflow ausgeführt!
Die wichtigste Ausgabe hier ist die letzte Zeile, die in der obigen Ausgabe hervorgehoben ist:
Dies sagt uns, dass der sayHello-Prozess erfolgreich einmal ausgeführt wurde (1 of 1 ✔).
Wichtig ist, dass diese Zeile dir auch sagt, wo du die Ausgabe des sayHello-Prozessaufrufs findest.
Schauen wir uns das jetzt an.
1.2.2. Die Ausgabe und Logs im work-Verzeichnis finden¶
Wenn du Nextflow zum ersten Mal in einem bestimmten Verzeichnis ausführst, erstellt es ein Verzeichnis namens work, in das es alle Dateien (und alle Symlinks) schreibt, die im Laufe der Ausführung generiert werden.
Innerhalb des work-Verzeichnisses organisiert Nextflow Ausgaben und Logs pro Prozessaufruf.
Für jeden Prozessaufruf erstellt Nextflow ein verschachteltes Unterverzeichnis, das mit einem Hash benannt wird, um es eindeutig zu machen, wo es alle notwendigen Eingaben bereitstellt (standardmäßig mit Symlinks), Hilfsdateien schreibt und Logs und alle Ausgaben des Prozesses ausgibt.
Der Pfad zu diesem Unterverzeichnis wird in gekürzter Form in eckigen Klammern in der Konsolenausgabe angezeigt.
Wenn wir uns ansehen, was wir für den oben gezeigten Lauf erhalten haben, beginnt die Konsolen-Log-Zeile für den sayHello-Prozess mit [65/7be2fa]. Das entspricht dem folgenden Verzeichnispfad: work/65/7be2fa7be2fad5e71e5f49998f795677fd68
Schauen wir uns an, was dort drin ist.
Verzeichnisinhalt
Siehst du nicht dasselbe?
Die genauen Unterverzeichnisnamen werden auf deinem System anders sein.
Wenn du den Inhalt des Task-Unterverzeichnisses im VSCode-Datei-Explorer durchsuchst, siehst du alle Dateien sofort.
Die Log-Dateien sind jedoch im Terminal auf unsichtbar gesetzt. Wenn du also ls oder tree verwenden möchtest, um sie anzuzeigen, musst du die entsprechende Option zum Anzeigen unsichtbarer Dateien setzen.
Das Erste, was du dir ansehen möchtest, ist die tatsächliche Ausgabe des Workflows, d.h. die output.txt-Datei, die vom sayHello-Prozess erzeugt wurde.
Öffne sie und du wirst die Hello World!-Begrüßung finden, die der Sinn unseres minimalistischen Workflows war.
Es hat funktioniert!
Zugegeben, das mag nach viel Wrapper-Code für ein so kleines Ergebnis erscheinen, aber der Wert all dieses Wrapper-Codes wird deutlicher, sobald wir anfangen, Eingabedateien zu lesen und mehrere Schritte miteinander zu verbinden.
Trotzdem schauen wir uns auch die anderen Dateien in diesem Verzeichnis an. Das sind Hilfs- und Log-Dateien, die von Nextflow als Teil der Task-Ausführung erzeugt wurden.
.command.begin: Metadaten zum Beginn der Ausführung des Prozessaufrufs.command.err: Fehlermeldungen (stderr), die vom Prozessaufruf ausgegeben wurden.command.log: Vollständige Log-Ausgabe des Prozessaufrufs.command.out: Reguläre Ausgabe (stdout) des Prozessaufrufs.command.run: Vollständiges Skript, das von Nextflow ausgeführt wurde, um den Prozessaufruf auszuführen.command.sh: Der Befehl, der tatsächlich vom Prozessaufruf ausgeführt wurde.exitcode: Der Exit-Code, der aus dem Befehl resultierte
Die Datei .command.sh ist besonders nützlich, weil sie dir den Hauptbefehl zeigt, den Nextflow ausgeführt hat, ohne die gesamte Buchhaltung und Task-/Umgebungseinrichtung.
Dies entspricht dem, was wir zuvor manuell ausgeführt haben.
In diesem Fall ist es sehr einfach, weil der Prozessbefehl fest codiert war, aber später im Kurs wirst du Prozessbefehle sehen, die eine Interpolation von Variablen beinhalten. Das macht es besonders wertvoll, genau sehen zu können, wie Nextflow den Code interpretiert hat und welcher Befehl erzeugt wurde, wenn du einen fehlgeschlagenen Lauf debuggst.
1.3. Den Workflow erneut ausführen¶
Versuche, den Workflow ein paar Mal erneut auszuführen, und schaue dir dann die Task-Verzeichnisse unter work/ an.
Verzeichnisinhalt
work
├── 0f
│ └── 52b7e07b0e274a80843fca48ed21b8
│ ├── .command.begin
│ ├── .command.err
│ ├── .command.log
│ ├── .command.out
│ ├── .command.run
│ ├── .command.sh
│ ├── .exitcode
│ └── output.txt
├── 65
└── 7be2fad5e71e5f49998f795677fd68
│ │ ├── .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
Du siehst, dass für jeden Lauf ein neues Unterverzeichnis mit einem vollständigen Satz von Ausgabe- und Log-Dateien erstellt wurde. Dies zeigt dir, dass das mehrfache Ausführen desselben Workflows die Ergebnisse früherer Läufe nicht überschreibt.
Fazit¶
Du weißt, wie du ein einfaches Nextflow-Skript entschlüsselst, es ausführst und die Ausgabe sowie relevante Log-Dateien im Work-Verzeichnis findest.
Wie geht es weiter?¶
Lerne, wie du die Workflow-Ausgaben an einem bequemeren Ort veröffentlichst.
2. Ausgaben veröffentlichen¶
Wie du gerade gelernt hast, ist die von unserer Pipeline erzeugte Ausgabe in einem Arbeitsverzeichnis mehrere Ebenen tief vergraben. Dies geschieht absichtlich; Nextflow hat die Kontrolle über dieses Verzeichnis und wir sollen nicht damit interagieren. Das macht es jedoch unpraktisch, Ausgaben abzurufen, die uns wichtig sind.
Glücklicherweise bietet Nextflow eine Möglichkeit, Ausgaben in einem bestimmten Verzeichnis zu veröffentlichen, indem Workflow-Output-Definitionen verwendet werden.
2.1. Grundlegende Verwendung¶
Dies erfordert zwei neue Code-Teile:
- Einen
publish:-Block innerhalb desworkflow-Bodys, der Prozess-Ausgaben deklariert. - Einen
output-Block im Skript, der Ausgabeoptionen wie Modus und Speicherort angibt.
2.1.1. Die Ausgabe des sayHello-Prozesses deklarieren¶
Wir müssen einen publish:-Block zum Workflow-Body hinzufügen (dieselbe Art von Code-Element wie der main:-Block) und die Ausgabe des sayHello()-Prozesses auflisten.
Füge in der Workflow-Skript-Datei hello-world.nf die folgenden Codezeilen hinzu:
Du siehst, dass wir auf die Ausgabe des Prozesses einfach mit sayHello().out verweisen und ihr einen beliebigen Namen zuweisen können, first_output.
2.1.2. Einen output:-Block zum Skript hinzufügen¶
Jetzt müssen wir nur noch den output:-Block hinzufügen, in dem der Ausgabeverzeichnispfad angegeben wird. Beachte, dass dieser neue Block außerhalb und unterhalb des workflow-Blocks im Skript steht.
Füge in der Workflow-Skript-Datei hello-world.nf die folgenden Codezeilen hinzu:
Wir können dies verwenden, um spezifische Pfade für alle im workflow-Block deklarierten Prozess-Ausgaben zuzuweisen.
Später lernst du Möglichkeiten kennen, ausgefeilte Ausgabeverzeichnisstrukturen zu generieren, aber vorerst codieren wir der Einfachheit halber nur einen minimalen Pfad fest.
2.1.3. Den Workflow ausführen¶
Führe jetzt das modifizierte Workflow-Skript aus:
Befehlsausgabe
Die Terminalausgabe sollte vertraut aussehen. Äußerlich hat sich nichts geändert.
Überprüfe jedoch deinen Datei-Explorer: Diesmal hat Nextflow ein neues Verzeichnis namens results/ erstellt.
Verzeichnisinhalt
.
├── greetings.csv
├── hello-channels.nf
├── hello-config.nf
├── hello-containers.nf
├── hello-modules.nf
├── hello-workflow.nf
├── hello-world.nf
├── nextflow.config
├── results
│ └── output.txt -> /workspaces/training/hello-nextflow/work/9f/48ef97f110b0dbd83635d7cbe288d2/output.txt
├── solutions
│ ├── 1-hello-world
│ ├── 2-hello-channels
│ ├── 3-hello-workflow
│ ├── 4-hello-modules
│ ├── 5-hello-containers
│ └── 6-hello-config
├── test-params.json
└── work
├── 65
└── 9f
Im results-Verzeichnis finden wir einen symbolischen Link zur output.txt, die im Work-Verzeichnis durch den gerade ausgeführten Befehl erzeugt wurde.
Dies ermöglicht es uns, Ausgabedateien einfach abzurufen, ohne durch das Work-Unterverzeichnis graben zu müssen.
2.2. Einen benutzerdefinierten Speicherort festlegen¶
Einen Standardspeicherort zu haben ist großartig, aber du möchtest vielleicht anpassen, wo die Ergebnisse gespeichert werden und wie sie organisiert sind.
Zum Beispiel möchtest du deine Ausgaben möglicherweise in Unterverzeichnissen organisieren. Der einfachste Weg, dies zu tun, besteht darin, für jede Ausgabe einen spezifischen Ausgabepfad zuzuweisen.
2.2.1. Den Ausgabepfad ändern¶
Auch hier ist das Ändern des Veröffentlichungsverhaltens für eine bestimmte Ausgabe wirklich unkompliziert.
Um einen benutzerdefinierten Speicherort festzulegen, bearbeite einfach den path entsprechend:
Da dies auf der Ebene der einzelnen Ausgabe festgelegt wird, kannst du verschiedene Speicherorte und Unterverzeichnisse nach deinen Bedürfnissen angeben.
2.2.2. Den Workflow erneut ausführen¶
Probieren wir es aus.
Befehlsausgabe
Diesmal wird das Ergebnis unter dem angegebenen Unterverzeichnis geschrieben.
Verzeichnisinhalt
Du siehst, dass das Ergebnis der vorherigen Ausführung noch da ist.
Du kannst so viele Verschachtelungsebenen verwenden, wie du möchtest.
Es ist auch möglich, den Prozessnamen oder andere Variablen zu verwenden, um die Verzeichnisse zu benennen, die zur Organisation der Ergebnisse verwendet werden, und es ist möglich, den Standardnamen des obersten Ausgabeverzeichnisses zu ändern (der durch das CLI-Flag -o oder die Konfigurationsvariable outputDir gesteuert wird).
Wir werden diese Optionen später im Training behandeln.
2.3. Den Veröffentlichungsmodus auf Kopieren setzen¶
Standardmäßig werden die Ausgaben als symbolische Links aus dem work-Verzeichnis veröffentlicht.
Das bedeutet, dass es nur eine einzige Datei im Dateisystem gibt.
Das ist großartig, wenn du mit sehr großen Dateien arbeitest, von denen du nicht mehrere Kopien speichern möchtest. Wenn du jedoch das Work-Verzeichnis irgendwann löschst (wir werden Aufräumoperationen in Kürze behandeln), verlierst du den Zugriff auf die Datei. Du musst also einen Plan haben, um Kopien aller wichtigen Dateien an einem sicheren Ort zu speichern.
Eine einfache Option ist, den Veröffentlichungsmodus für die Ausgaben, die dir wichtig sind, auf Kopieren umzustellen.
2.3.1. Die Modus-Direktive hinzufügen¶
Dieser Teil ist wirklich unkompliziert.
Füge einfach mode 'copy' zur entsprechenden Workflow-Level-Output-Definition hinzu:
Dies setzt den Veröffentlichungsmodus für diese spezifische Ausgabe.
2.3.2. Den Workflow erneut ausführen¶
Probieren wir es aus.
Befehlsausgabe
Diesmal ist die Datei, wenn du dir die Ergebnisse ansiehst, eine echte Kopie anstatt nur ein Symlink.
Verzeichnisinhalt
Da auch dies auf der Ebene der einzelnen Ausgabe festgelegt wird, ermöglicht es dir, den Veröffentlichungsmodus granular festzulegen. Dies wird besonders praktisch sein, wenn wir später zu mehrstufigen Pipelines übergehen, wo du beispielsweise nur finale Ausgaben kopieren und Zwischenausgaben als Symlinks belassen möchtest.
Wie bereits erwähnt, gibt es andere, ausgefeiltere Optionen zur Steuerung, wie Ausgaben veröffentlicht werden. Wir zeigen dir zu gegebener Zeit auf deiner Nextflow-Reise, wie du sie verwendest.
2.4. Hinweis zu prozess-level publishDir-Direktiven¶
Bis vor kurzem war die etablierte Methode zum Veröffentlichen von Ausgaben, dies auf der Ebene jedes einzelnen Prozesses mit einer publishDir-Direktive zu tun.
Um das zu erreichen, was wir gerade für die Ausgaben des sayHello-Prozesses getan haben, hätten wir stattdessen die folgende Zeile zur Prozess-Definition hinzugefügt:
| hello-world.nf | |
|---|---|
Du wirst dieses Code-Muster immer noch überall in älteren Nextflow-Pipelines und Prozess-Modulen finden, daher ist es wichtig, sich dessen bewusst zu sein. Wir empfehlen jedoch nicht, es in neuen Arbeiten zu verwenden, da es in zukünftigen Versionen der Nextflow-Sprache irgendwann nicht mehr erlaubt sein wird.
Fazit¶
Du weißt, wie du Workflow-Ausgaben an einem bequemeren Ort veröffentlichst.
Wie geht es weiter?¶
Lerne, eine variable Eingabe über einen Kommandozeilenparameter bereitzustellen und Standardwerte effektiv zu nutzen.
3. Eine variable Eingabe verwenden, die über die Kommandozeile übergeben wird¶
In seinem aktuellen Zustand verwendet unser Workflow eine Begrüßung, die fest in den Prozessbefehl codiert ist. Wir möchten etwas Flexibilität hinzufügen, indem wir eine Eingabevariable verwenden, damit wir die Begrüßung zur Laufzeit leichter ändern können.
Dies erfordert drei Änderungen an unserem Skript:
- Den Prozess ändern, um eine variable Eingabe zu erwarten
- Einen Kommandozeilenparameter einrichten, um Benutzereingaben zu erfassen
- Die Eingabe im Workflow-Body an den Prozess übergeben
Lass uns diese Änderungen nacheinander vornehmen.
3.1. Den sayHello-Prozess ändern, um eine variable Eingabe zu erwarten¶
Wir müssen die Prozess-Definition bearbeiten, um (1) eine Eingabevariable zu akzeptieren und (2) diese Variable in der Kommandozeile zu verwenden.
3.1.1. Einen Input-Block zur Prozess-Definition hinzufügen¶
Zuerst passen wir die Prozess-Definition an, um eine Eingabe namens greeting zu akzeptieren.
Nimm im Prozess-Block die folgende Code-Änderung vor:
Die Variable greeting ist mit val präfixiert, um Nextflow mitzuteilen, dass es sich um einen Wert handelt (nicht um einen Pfad).
3.1.2. Den Prozessbefehl bearbeiten, um die Eingabevariable zu verwenden¶
Jetzt tauschen wir den ursprünglichen fest codierten Wert gegen den Wert der Eingabevariable aus, die wir erwarten zu erhalten.
Nimm im Prozess-Block die folgende Code-Änderung vor:
Das $-Symbol und die geschweiften Klammern ({ }) sagen Nextflow, dass dies ein Variablenname ist, der durch den tatsächlichen Eingabewert ersetzt werden muss (=interpoliert).
Tipp
Die geschweiften Klammern ({ }) waren in früheren Versionen von Nextflow technisch optional, daher siehst du möglicherweise ältere Workflows, in denen dies als echo '$greeting' > output.txt geschrieben ist.
Jetzt, da der sayHello()-Prozess bereit ist, eine variable Eingabe zu akzeptieren, brauchen wir eine Möglichkeit, dem Prozessaufruf auf Workflow-Ebene einen Eingabewert bereitzustellen.
3.2. Einen Kommandozeilenparameter einrichten, um Benutzereingaben zu erfassen¶
Wir könnten einfach eine Eingabe direkt fest codieren, indem wir den Prozessaufruf sayHello('Hello World!') machen.
Wenn wir jedoch echte Arbeit mit unserem Workflow erledigen, möchten wir in der Lage sein, seine Eingaben von der Kommandozeile aus zu steuern, damit wir so etwas tun können:
Glücklicherweise hat Nextflow ein eingebautes Workflow-Parametersystem namens params, das es einfach macht, CLI-Parameter zu deklarieren und zu verwenden.
Die allgemeine Syntax besteht darin, params.<parameter_name> zu deklarieren, um Nextflow mitzuteilen, dass ein --<parameter_name>-Parameter auf der Kommandozeile erwartet wird.
Hier möchten wir einen Parameter namens --input erstellen, also müssen wir params.input irgendwo im Workflow deklarieren.
Prinzipiell können wir es überall schreiben; aber da wir es dem sayHello()-Prozessaufruf geben möchten, können wir es dort direkt einfügen, indem wir sayHello(params.input) schreiben.
Nimm im Workflow-Block die folgende Code-Änderung vor:
Dies sagt Nextflow, den sayHello-Prozess mit dem Wert auszuführen, der über den --input-Parameter bereitgestellt wird.
Tatsächlich haben wir die Schritte (2) und (3), die zu Beginn des Abschnitts skizziert wurden, in einem Rutsch erledigt.
3.3. Den Workflow-Befehl ausführen¶
Lass es uns ausführen!
Befehlsausgabe
Wenn du all diese Änderungen korrekt vorgenommen hast, solltest du eine weitere erfolgreiche Ausführung erhalten.
Stelle sicher, dass du die Ausgabedatei öffnest, um zu überprüfen, dass du jetzt die neue Version der Begrüßung hast.
Et voilà!
Beachte, wie die neue Ausführung die im results-Verzeichnis veröffentlichte Ausgabedatei überschrieben hat.
Die Ergebnisse der vorherigen Läufe sind jedoch immer noch in den Task-Verzeichnissen unter work erhalten.
Tipp
Du kannst Nextflow-Level-Parameter leicht von Pipeline-Level-Parametern unterscheiden.
- Parameter, die für eine Pipeline gelten, nehmen immer einen doppelten Bindestrich (
--). - Parameter, die eine Nextflow-Einstellung ändern, z.B. die
-resume-Funktion, die wir zuvor verwendet haben, nehmen einen einfachen Bindestrich (-).
3.4. Standardwerte für Kommandozeilenparameter verwenden¶
Ok, das war praktisch, aber in vielen Fällen macht es Sinn, einen Standardwert für einen bestimmten Parameter anzugeben, damit du ihn nicht bei jedem Lauf angeben musst.
3.4.1. Einen Standardwert für den CLI-Parameter festlegen¶
Geben wir dem input-Parameter einen Standardwert, indem wir ihn vor der Workflow-Definition deklarieren.
Wie du siehst, können wir den Typ der Eingabe angeben, den der Workflow erwartet (Nextflow 25.10.2 und später).
Die Syntax ist name: Type = default_value.
Unterstützte Typen sind String, Integer, Float, Boolean und Path.
Info
In älteren Workflows siehst du möglicherweise, dass der gesamte params-Block nur als input = 'Holà mundo!' geschrieben ist.
Wenn du deiner Pipeline weitere Parameter hinzufügst, solltest du sie alle zu diesem Block hinzufügen, unabhängig davon, ob du ihnen einen Standardwert geben musst oder nicht. Dies macht es einfach, alle konfigurierbaren Parameter auf einen Blick zu finden.
3.4.2. Den Workflow erneut ausführen, ohne den Parameter anzugeben¶
Jetzt, da du einen Standardwert festgelegt hast, kannst du den Workflow erneut ausführen, ohne einen Wert in der Kommandozeile angeben zu müssen.
Befehlsausgabe
Falls es nicht funktioniert hat
Wenn das mit einem Fehler fehlgeschlagen ist, der so aussieht:
ERROR ~ Script compilation error
- file : /workspaces/training/hello-nextflow/solutions/1-hello-world/hello-world-3.nf
- cause: you tried to assign a value to the class 'java.lang.String'
@ line 24, column 12.
input: String = 'Holà mundo!'
^
1 error
-- Check '.nextflow.log' file for details
Dann verwendest du wahrscheinlich den älteren v1 Nextflow-Sprach-Parser. Dies wurde zu Beginn des Kurses erwähnt, aber vielleicht hast du es verpasst. Schau dir das Hilfsmaterial zu Nextflow-Versionen an.
Kurz gesagt, wenn du Nextflow 25.10 verwendest, musst du den v2-Sprach-Parser aktivieren:
Die Ausgabe wird am selben Ort wie zuvor sein, aber der Inhalt sollte mit dem neuen Text aktualisiert sein.
Nextflow hat den Standardwert des Begrüßungsparameters verwendet, um die Ausgabe zu erstellen.
3.4.3. Den Standardwert überschreiben¶
Wenn du den Parameter auf der Kommandozeile angibst, überschreibt der CLI-Wert den Standardwert.
Probiere es aus:
Befehlsausgabe
Noch einmal solltest du die entsprechende aktualisierte Ausgabe in deinem Ergebnisverzeichnis finden.
Hinweis
In Nextflow gibt es mehrere Stellen, an denen du Werte für Parameter angeben kannst. Wenn derselbe Parameter an mehreren Stellen auf unterschiedliche Werte gesetzt wird, bestimmt Nextflow, welcher Wert verwendet werden soll, basierend auf der Rangfolge, die hier beschrieben ist.
Wir werden dies in Teil 6 (Konfiguration) ausführlicher behandeln.
Fazit¶
Du weißt, wie du eine einfache variable Eingabe verwendest, die zur Laufzeit über einen Kommandozeilenparameter bereitgestellt wird, sowie wie du Standardwerte einrichtest, verwendest und überschreibst.
Wie geht es weiter?¶
Lerne, wie du Ausführungen bequemer verwaltest.
4. Workflow-Ausführungen verwalten¶
Zu wissen, wie man Workflows startet und Ausgaben abruft, ist großartig, aber du wirst schnell feststellen, dass es einige andere Aspekte der Workflow-Verwaltung gibt, die dir das Leben erleichtern werden, besonders wenn du deine eigenen Workflows entwickelst.
Hier zeigen wir dir, wie du die -resume-Funktion verwendest, wenn du denselben Workflow erneut starten musst, wie du das Log vergangener Ausführungen mit nextflow log inspizierst und wie du ältere Work-Verzeichnisse mit nextflow clean löschst.
4.1. Einen Workflow mit -resume erneut starten¶
Manchmal möchtest du eine Pipeline erneut ausführen, die du bereits zuvor gestartet hast, ohne Schritte zu wiederholen, die bereits erfolgreich abgeschlossen wurden.
Nextflow hat eine Option namens -resume, die dir dies ermöglicht.
Konkret werden in diesem Modus alle Prozesse übersprungen, die bereits mit genau demselben Code, denselben Einstellungen und denselben Eingaben ausgeführt wurden.
Das bedeutet, dass Nextflow nur Prozesse ausführt, die du seit dem letzten Lauf hinzugefügt oder geändert hast, oder denen du neue Einstellungen oder Eingaben bereitstellst.
Es gibt zwei Hauptvorteile dabei:
- Wenn du mitten in der Entwicklung deiner Pipeline bist, kannst du schneller iterieren, da du nur den/die Prozess(e) ausführen musst, an dem/denen du aktiv arbeitest, um deine Änderungen zu testen.
- Wenn du eine Pipeline in Produktion ausführst und etwas schief geht, kannst du in vielen Fällen das Problem beheben und die Pipeline erneut starten, und sie wird ab dem Punkt des Fehlers fortgesetzt, was dir viel Zeit und Rechenleistung sparen kann.
Um es zu verwenden, füge einfach -resume zu deinem Befehl hinzu und führe ihn aus:
Befehlsausgabe
Die Konsolenausgabe sollte vertraut aussehen, aber es gibt eine Sache, die etwas anders ist als zuvor.
Suche nach dem cached:-Teil, der in der Prozess-Statuszeile (Zeile 5) hinzugefügt wurde, was bedeutet, dass Nextflow erkannt hat, dass es diese Arbeit bereits erledigt hat und einfach das Ergebnis des vorherigen erfolgreichen Laufs wiederverwendet.
Du kannst auch sehen, dass der Work-Unterverzeichnis-Hash derselbe ist wie beim vorherigen Lauf. Nextflow zeigt dir buchstäblich auf die vorherige Ausführung und sagt "Das habe ich dort drüben schon gemacht."
Tipp
Wenn du eine Pipeline mit resume erneut ausführst, überschreibt Nextflow keine Dateien, die außerhalb des Work-Verzeichnisses von Ausführungen veröffentlicht wurden, die zuvor erfolgreich ausgeführt wurden.
4.2. Das Log vergangener Ausführungen inspizieren¶
Ob du eine neue Pipeline entwickelst oder Pipelines in Produktion ausführst, irgendwann wirst du wahrscheinlich Informationen über vergangene Läufe nachschlagen müssen. So machst du das.
Wann immer du einen Nextflow-Workflow startest, wird eine Zeile in eine Log-Datei namens history geschrieben, die sich in einem versteckten Verzeichnis namens .nextflow im aktuellen Arbeitsverzeichnis befindet.
Dateiinhalt
Diese Datei gibt dir den Zeitstempel, den Laufnamen, den Status, die Revisions-ID, die Sitzungs-ID und die vollständige Kommandozeile für jeden Nextflow-Lauf, der aus dem aktuellen Arbeitsverzeichnis gestartet wurde.
Eine bequemere Möglichkeit, auf diese Informationen zuzugreifen, ist die Verwendung des Befehls nextflow log.
Befehlsausgabe
Dies gibt den Inhalt der Log-Datei im Terminal aus, ergänzt um eine Kopfzeile.
Du wirst bemerken, dass sich die Sitzungs-ID jedes Mal ändert, wenn du einen neuen nextflow run-Befehl ausführst, AUSSER wenn du die -resume-Option verwendest.
In diesem Fall bleibt die Sitzungs-ID gleich.
Nextflow verwendet die Sitzungs-ID, um Lauf-Caching-Informationen unter dem cache-Verzeichnis zu gruppieren, das sich ebenfalls unter .nextflow befindet.
4.3. Ältere Work-Verzeichnisse löschen¶
Während des Entwicklungsprozesses wirst du typischerweise deinen Entwurf der Pipeline viele Male ausführen, was zu einer Ansammlung vieler Dateien über viele Unterverzeichnisse hinweg führen kann.
Glücklicherweise enthält Nextflow einen hilfreichen clean-Unterbefehl, der automatisch die Work-Unterverzeichnisse für vergangene Läufe löschen kann, die dich nicht mehr interessieren.
4.3.1. Löschkriterien bestimmen¶
Es gibt mehrere Optionen, um zu bestimmen, was gelöscht werden soll.
Hier zeigen wir dir ein Beispiel, das alle Unterverzeichnisse von Läufen vor einem bestimmten Lauf löscht, der anhand seines Laufnamens angegeben wird.
Suche den letzten erfolgreichen Lauf, bei dem du -resume nicht verwendet hast; in unserem Fall war der Laufname golden_cantor.
Der Laufname ist die maschinell generierte zweiteilige Zeichenfolge, die in eckigen Klammern in der Launching (...)-Konsolenausgabezeile angezeigt wird.
Du kannst auch das Nextflow-Log verwenden, um einen Lauf anhand seines Zeitstempels und/oder seiner Kommandozeile nachzuschlagen.
4.3.2. Einen Testlauf durchführen¶
Zuerst verwenden wir das Testlauf-Flag -n, um zu überprüfen, was bei dem Befehl gelöscht wird:
Befehlsausgabe
Deine Ausgabe wird andere Task-Verzeichnisnamen haben und möglicherweise eine andere Anzahl von Zeilen, aber sie sollte ähnlich wie das Beispiel aussehen.
Wenn du keine Zeilen ausgegeben siehst, hast du entweder keinen gültigen Laufnamen angegeben oder es gibt keine vergangenen Läufe zum Löschen. Stelle sicher, dass du golden_cantor im Beispielbefehl durch den entsprechenden neuesten Laufnamen in deinem Log ersetzt.
4.3.3. Mit der Löschung fortfahren¶
Wenn die Ausgabe wie erwartet aussieht und du mit der Löschung fortfahren möchtest, führe den Befehl mit dem -f-Flag anstelle von -n erneut aus:
Die Ausgabe sollte ähnlich wie zuvor sein, aber jetzt mit 'Removed' anstelle von 'Would remove'.
Beachte, dass dies die zweistelligen Unterverzeichnisse (wie a3/ oben) nicht entfernt, aber deren Inhalt leert.
Warnung
Das Löschen von Work-Unterverzeichnissen aus vergangenen Läufen entfernt sie aus dem Cache von Nextflow und löscht alle Ausgaben, die in diesen Verzeichnissen gespeichert wurden. Das bedeutet, dass es die Fähigkeit von Nextflow unterbricht, die Ausführung fortzusetzen, ohne die entsprechenden Prozesse erneut auszuführen.
Du bist dafür verantwortlich, alle Ausgaben zu speichern, die dir wichtig sind oder auf die du dich verlassen möchtest! Das ist der Hauptgrund, warum wir es vorziehen, den copy-Modus anstelle des symlink-Modus für die publish-Direktive zu verwenden.
Fazit¶
Du weißt, wie du Ausgaben in einem bestimmten Verzeichnis veröffentlichst, eine Pipeline erneut startest, ohne Schritte zu wiederholen, die bereits auf identische Weise ausgeführt wurden, und den Befehl nextflow clean verwendest, um alte Work-Verzeichnisse aufzuräumen.
Allgemeiner weißt du, wie du einen einfachen Nextflow-Workflow interpretierst, seine Ausführung verwaltest und Ausgaben abrufst.
Wie geht es weiter?¶
Mach eine kleine Pause, du hast sie dir verdient!
Wenn du bereit bist, gehe weiter zu Teil 2: Hello Channels, um zu lernen, wie du Kanäle verwendest, um Eingaben in deinen Workflow einzuspeisen, was es dir ermöglicht, Nextflows eingebauten Datenfluss-Parallelismus und andere leistungsstarke Funktionen zu nutzen.
Quiz¶
Was sind die minimal erforderlichen Komponenten eines Nextflow-Prozesses?
Was ist der Zweck des Output-Blocks in einem Prozess?
Welcher Befehl wird verwendet, um einen Nextflow-Workflow auszuführen?
Was bewirkt das -resume-Flag?
Was ist der Standardmodus für die Veröffentlichung von Workflow-Ausgaben?
Wie übergibst du einen Parameterwert von der Kommandozeile an einen Nextflow-Workflow?
Wie referenzierst du eine Variable innerhalb eines Nextflow-Script-Blocks?